Skip to content

Commit 0eb8532

Browse files
authored
Merge branch 'release-1.8.1' into dk/le-558
2 parents 5b966f3 + 1e9be16 commit 0eb8532

56 files changed

Lines changed: 1198 additions & 642 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docker/build_and_push.Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ RUN apt-get update \
8181
&& apt-get install --no-install-recommends -y curl git libpq5 gnupg xz-utils \
8282
&& apt-get clean \
8383
&& rm -rf /var/lib/apt/lists/*
84+
COPY --from=builder /usr/local/bin/uv /usr/local/bin/uv
85+
COPY --from=builder /usr/local/bin/uvx /usr/local/bin/uvx
8486
RUN ARCH=$(dpkg --print-architecture) \
8587
&& if [ "$ARCH" = "amd64" ]; then NODE_ARCH="x64"; \
8688
elif [ "$ARCH" = "arm64" ]; then NODE_ARCH="arm64"; \

docker/build_and_push_backend.Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ RUN apt-get update \
5555
xz-utils \
5656
&& apt-get clean \
5757
&& rm -rf /var/lib/apt/lists/*
58-
58+
COPY --from=builder /usr/local/bin/uv /usr/local/bin/uv
59+
COPY --from=builder /usr/local/bin/uvx /usr/local/bin/uvx
5960
# Install Node.js (required for npx-based MCP stdio servers)
6061
RUN ARCH=$(dpkg --print-architecture) \
6162
&& if [ "$ARCH" = "amd64" ]; then NODE_ARCH="x64"; \

docker/build_and_push_base.Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ RUN apt-get update \
8282
&& apt-get install --no-install-recommends -y curl git libpq5 gnupg xz-utils \
8383
&& apt-get clean \
8484
&& rm -rf /var/lib/apt/lists/*
85+
COPY --from=builder /usr/local/bin/uv /usr/local/bin/uv
86+
COPY --from=builder /usr/local/bin/uvx /usr/local/bin/uvx
8587
RUN ARCH=$(dpkg --print-architecture) \
8688
&& if [ "$ARCH" = "amd64" ]; then NODE_ARCH="x64"; \
8789
elif [ "$ARCH" = "arm64" ]; then NODE_ARCH="arm64"; \

docker/build_and_push_ep.Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ RUN apt-get update \
7777
&& apt-get install --no-install-recommends -y curl git libpq5 gnupg xz-utils \
7878
&& apt-get clean \
7979
&& rm -rf /var/lib/apt/lists/*
80+
COPY --from=builder /usr/local/bin/uv /usr/local/bin/uv
81+
COPY --from=builder /usr/local/bin/uvx /usr/local/bin/uvx
8082
RUN ARCH=$(dpkg --print-architecture) \
8183
&& if [ "$ARCH" = "amd64" ]; then NODE_ARCH="x64"; \
8284
elif [ "$ARCH" = "arm64" ]; then NODE_ARCH="arm64"; \

docker/build_and_push_with_extras.Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ RUN apt-get update \
7878
&& apt-get install --no-install-recommends -y curl git libpq5 gnupg xz-utils \
7979
&& apt-get clean \
8080
&& rm -rf /var/lib/apt/lists/*
81+
COPY --from=builder /usr/local/bin/uv /usr/local/bin/uv
82+
COPY --from=builder /usr/local/bin/uvx /usr/local/bin/uvx
8183
RUN ARCH=$(dpkg --print-architecture) \
8284
&& if [ "$ARCH" = "amd64" ]; then NODE_ARCH="x64"; \
8385
elif [ "$ARCH" = "arm64" ]; then NODE_ARCH="arm64"; \

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "langflow"
3-
version = "1.8.0"
3+
version = "1.8.1"
44
description = "A Python package with a built-in web application"
55
requires-python = ">=3.10,<3.14"
66
license = "MIT"
@@ -17,7 +17,7 @@ maintainers = [
1717
]
1818
# Define your main dependencies here
1919
dependencies = [
20-
"langflow-base[complete]~=0.8.0",
20+
"langflow-base[complete]~=0.8.1",
2121
]
2222

2323

src/backend/base/langflow/api/utils/core.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ def has_api_terms(word: str):
6868
return "api" in word and ("key" in word or ("token" in word and "tokens" not in word))
6969

7070

71+
def _get_provider_from_template(template: dict) -> str | None:
72+
"""Return provider name from template's model field, if any."""
73+
model_field = template.get("model")
74+
if not isinstance(model_field, dict):
75+
return None
76+
raw = model_field.get("value")
77+
if isinstance(raw, list) and len(raw) > 0 and isinstance(raw[0], dict):
78+
return raw[0].get("provider")
79+
return None
80+
81+
7182
def remove_api_keys(flow: dict):
7283
"""Remove api keys from flow data."""
7384
for node in flow.get("data", {}).get("nodes", []):

src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json

Lines changed: 3 additions & 3 deletions
Large diffs are not rendered by default.

src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,7 @@
10331033
"show": true,
10341034
"title_case": false,
10351035
"type": "code",
1036-
"value": "from lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.unified_models import (\n apply_provider_variable_config_to_build_config,\n get_language_model_options,\n get_llm,\n update_model_options_in_build_config,\n)\nfrom lfx.base.models.watsonx_constants import IBM_WATSONX_URLS\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput, DropdownInput, StrInput\nfrom lfx.io import IntInput, MessageInput, ModelInput, MultilineInput, SecretStrInput, SliderInput\n\nDEFAULT_OLLAMA_URL = \"http://localhost:11434\"\n\n\nclass LanguageModelComponent(LCModelComponent):\n display_name = \"Language Model\"\n description = \"Runs a language model given a specified provider.\"\n documentation: str = \"https://docs.langflow.org/components-models\"\n icon = \"brain-circuit\"\n category = \"models\"\n\n inputs = [\n ModelInput(\n name=\"model\",\n display_name=\"Language Model\",\n info=\"Select your model provider\",\n real_time_refresh=True,\n required=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\n real_time_refresh=True,\n advanced=True,\n ),\n DropdownInput(\n name=\"base_url_ibm_watsonx\",\n display_name=\"watsonx API Endpoint\",\n info=\"The base URL of the API (IBM watsonx.ai only)\",\n options=IBM_WATSONX_URLS,\n value=IBM_WATSONX_URLS[0],\n show=False,\n real_time_refresh=True,\n ),\n StrInput(\n name=\"project_id\",\n display_name=\"watsonx Project ID\",\n info=\"The project ID associated with the foundation model (IBM watsonx.ai only)\",\n show=False,\n required=False,\n ),\n StrInput(\n name=\"ollama_base_url\",\n display_name=\"Ollama API URL\",\n info=f\"Endpoint of the Ollama API (Ollama only). Defaults to {DEFAULT_OLLAMA_URL}\",\n value=DEFAULT_OLLAMA_URL,\n show=False,\n real_time_refresh=True,\n ),\n MessageInput(\n name=\"input_value\",\n display_name=\"Input\",\n info=\"The input text to send to the model\",\n ),\n MultilineInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"A system message that helps set the behavior of the assistant\",\n advanced=False,\n ),\n BoolInput(\n name=\"stream\",\n display_name=\"Stream\",\n info=\"Whether to stream the response\",\n value=False,\n advanced=True,\n ),\n SliderInput(\n name=\"temperature\",\n display_name=\"Temperature\",\n value=0.1,\n info=\"Controls randomness in responses\",\n range_spec=RangeSpec(min=0, max=1, step=0.01),\n advanced=True,\n ),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n info=\"Maximum number of tokens to generate. Field name varies by provider.\",\n advanced=True,\n range_spec=RangeSpec(min=1, max=128000, step=1, step_type=\"int\"),\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n return get_llm(\n model=self.model,\n user_id=self.user_id,\n api_key=self.api_key,\n temperature=self.temperature,\n stream=self.stream,\n max_tokens=getattr(self, \"max_tokens\", None),\n watsonx_url=getattr(self, \"base_url_ibm_watsonx\", None),\n watsonx_project_id=getattr(self, \"project_id\", None),\n ollama_base_url=getattr(self, \"ollama_base_url\", None),\n )\n\n def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None):\n \"\"\"Dynamically update build config with user-filtered model options.\"\"\"\n # Update model options\n build_config = update_model_options_in_build_config(\n component=self,\n build_config=build_config,\n cache_key_prefix=\"language_model_options\",\n get_options_func=get_language_model_options,\n field_name=field_name,\n field_value=field_value,\n )\n\n # Hide all provider-specific fields by default\n for field in [\"api_key\", \"base_url_ibm_watsonx\", \"project_id\", \"ollama_base_url\"]:\n if field in build_config:\n build_config[field][\"show\"] = False\n build_config[field][\"required\"] = False\n\n # Show/configure provider-specific fields based on selected model\n # Get current model value - from field_value if model is being changed, otherwise from build_config\n current_model_value = field_value if field_name == \"model\" else build_config.get(\"model\", {}).get(\"value\")\n if isinstance(current_model_value, list) and len(current_model_value) > 0:\n selected_model = current_model_value[0]\n provider = selected_model.get(\"provider\", \"\")\n\n if provider:\n # Apply provider variable configuration (required_for_component, advanced, env var fallback)\n build_config = apply_provider_variable_config_to_build_config(build_config, provider)\n\n return build_config\n"
1036+
"value": "from lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.unified_models import (\n apply_provider_variable_config_to_build_config,\n get_language_model_options,\n get_llm,\n get_provider_for_model_name,\n update_model_options_in_build_config,\n)\nfrom lfx.base.models.watsonx_constants import IBM_WATSONX_URLS\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput, DropdownInput, StrInput\nfrom lfx.io import IntInput, MessageInput, ModelInput, MultilineInput, SecretStrInput, SliderInput\n\nDEFAULT_OLLAMA_URL = \"http://localhost:11434\"\n\n\nclass LanguageModelComponent(LCModelComponent):\n display_name = \"Language Model\"\n description = \"Runs a language model given a specified provider.\"\n documentation: str = \"https://docs.langflow.org/components-models\"\n icon = \"brain-circuit\"\n category = \"models\"\n\n inputs = [\n ModelInput(\n name=\"model\",\n display_name=\"Language Model\",\n info=\"Select your model provider\",\n real_time_refresh=True,\n required=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\n real_time_refresh=True,\n advanced=True,\n ),\n DropdownInput(\n name=\"base_url_ibm_watsonx\",\n display_name=\"watsonx API Endpoint\",\n info=\"The base URL of the API (IBM watsonx.ai only)\",\n options=IBM_WATSONX_URLS,\n value=IBM_WATSONX_URLS[0],\n show=False,\n real_time_refresh=True,\n ),\n StrInput(\n name=\"project_id\",\n display_name=\"watsonx Project ID\",\n info=\"The project ID associated with the foundation model (IBM watsonx.ai only)\",\n show=False,\n required=False,\n ),\n StrInput(\n name=\"ollama_base_url\",\n display_name=\"Ollama API URL\",\n info=f\"Endpoint of the Ollama API (Ollama only). Defaults to {DEFAULT_OLLAMA_URL}\",\n value=DEFAULT_OLLAMA_URL,\n show=False,\n real_time_refresh=True,\n ),\n MessageInput(\n name=\"input_value\",\n display_name=\"Input\",\n info=\"The input text to send to the model\",\n ),\n MultilineInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"A system message that helps set the behavior of the assistant\",\n advanced=False,\n ),\n BoolInput(\n name=\"stream\",\n display_name=\"Stream\",\n info=\"Whether to stream the response\",\n value=False,\n advanced=True,\n ),\n SliderInput(\n name=\"temperature\",\n display_name=\"Temperature\",\n value=0.1,\n info=\"Controls randomness in responses\",\n range_spec=RangeSpec(min=0, max=1, step=0.01),\n advanced=True,\n ),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n info=\"Maximum number of tokens to generate. Field name varies by provider.\",\n advanced=True,\n range_spec=RangeSpec(min=1, max=128000, step=1, step_type=\"int\"),\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n return get_llm(\n model=self.model,\n user_id=self.user_id,\n api_key=self.api_key,\n temperature=self.temperature,\n stream=self.stream,\n max_tokens=getattr(self, \"max_tokens\", None),\n watsonx_url=getattr(self, \"base_url_ibm_watsonx\", None),\n watsonx_project_id=getattr(self, \"project_id\", None),\n ollama_base_url=getattr(self, \"ollama_base_url\", None),\n )\n\n def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None):\n \"\"\"Dynamically update build config with user-filtered model options.\"\"\"\n # Update model options\n build_config = update_model_options_in_build_config(\n component=self,\n build_config=build_config,\n cache_key_prefix=\"language_model_options\",\n get_options_func=get_language_model_options,\n field_name=field_name,\n field_value=field_value,\n )\n\n current_model_value = field_value if field_name == \"model\" else build_config.get(\"model\", {}).get(\"value\")\n provider = \"\"\n if isinstance(current_model_value, list) and current_model_value:\n selected_model = current_model_value[0]\n provider = (selected_model.get(\"provider\") or \"\").strip()\n if not provider and selected_model.get(\"name\"):\n provider = get_provider_for_model_name(str(selected_model[\"name\"]))\n\n if provider:\n build_config = apply_provider_variable_config_to_build_config(build_config, provider)\n\n return build_config\n"
10371037
},
10381038
"input_value": {
10391039
"_input_type": "MessageInput",

0 commit comments

Comments
 (0)