feat: support aliyun bailian platform api#9911
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds Aliyun as a new language model provider across backend components and starter templates: introduces Aliyun model constants, extends LanguageModelComponent to handle Aliyun (provider option, model list, API key label, base URL), and adds frontend Aliyun icon with eager/lazy registrations. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant UI as Langflow UI
participant LMC as LanguageModelComponent
participant AliyunAPI as Aliyun (OpenAI-compatible)
User->>UI: Select provider = "Aliyun"
UI->>LMC: update_build_config(provider="Aliyun")
LMC-->>UI: Set model_name options = ALIYUN_CHAT_MODEL_NAMES<br/>Set api_key label = "Aliyun API Key"
User->>UI: Run flow
UI->>LMC: build_model(provider="Aliyun", model_name, api_key)
LMC->>AliyunAPI: ChatOpenAI request (base=https://dashscope.aliyuncs.com/compatible-mode/v1)
AliyunAPI-->>LMC: Response
LMC-->>UI: Model instance / output
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull Request Overview
This PR adds support for Aliyun Bailian platform LLM models to the system. The change integrates Aliyun as a new provider option alongside existing providers like OpenAI, Anthropic, and Google.
- Adds Aliyun as a new model provider with support for Qwen models
- Implements provider selection UI and model configuration
- Includes appropriate icon support for the new provider
Reviewed Changes
Copilot reviewed 6 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lfx/src/lfx/components/models/language_model.py | Adds Aliyun provider option and model initialization logic |
| src/lfx/src/lfx/base/models/aliyun_constants.py | Defines available Aliyun models and their metadata |
| src/frontend/src/icons/lazyIconImports.ts | Adds lazy loading for Aliyun icon |
| src/frontend/src/icons/eagerIconImports.ts | Adds eager loading for Aliyun icon |
| src/frontend/src/icons/Aliyun/index.tsx | Creates Aliyun icon React component wrapper |
| src/frontend/src/icons/Aliyun/Aliyun.jsx | Implements the Aliyun SVG icon component |
Files not reviewed (1)
- src/frontend/package-lock.json: Language not supported
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| return ChatOpenAI( | ||
| model_name=model_name, | ||
| temperature=temperature, | ||
| streaming=stream, | ||
| openai_api_key=self.api_key, | ||
| openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", | ||
| ) |
There was a problem hiding this comment.
The hardcoded API base URL should be extracted to a constant in the aliyun_constants.py file for better maintainability and consistency with other provider implementations.
|
|
||
| export const AliyunIcon = forwardRef< | ||
| SVGSVGElement, | ||
| React.PropsWithChildren<{}> |
There was a problem hiding this comment.
The empty object type {} should be replaced with a more explicit interface or React.SVGProps<SVGSVGElement> to properly type the props that can be passed to the SVG component.
| React.PropsWithChildren<{}> | |
| React.PropsWithChildren<React.SVGProps<SVGSVGElement>> |
|
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (24)
src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json (1)
1078-1112: Provider dropdown in template is missing “Aliyun”.UI won’t expose the new provider despite the code supporting it.
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], - "options_metadata": [ - { "icon": "OpenAI" }, - { "icon": "Anthropic" }, - { "icon": "GoogleGenerativeAI" } - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], + "options_metadata": [ + { "icon": "OpenAI" }, + { "icon": "Anthropic" }, + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } + ],src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json (1)
1624-1659: Add “Aliyun” to all LanguageModelComponent provider dropdowns in this template.Without this, the new provider can’t be selected in the UI for any of the three model nodes.
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], @@ - "options_metadata": [ - { "icon": "OpenAI" }, - { "icon": "Anthropic" }, - { "icon": "Google" } - ], + "options_metadata": [ + { "icon": "OpenAI" }, + { "icon": "Anthropic" }, + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } + ],Apply the same change to all three LanguageModelComponent nodes (qFXT1, Wp3pC, gYAmH).
Also applies to: 1952-1987, 2280-2314
src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json (2)
1689-1724: UI mismatch: Aliyun missing from Provider dropdown options for this node.The code supports Aliyun, but this node’s
provider.optionsexcludes it, blocking selection in the template.Update this node’s template:
"options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ {"icon": "OpenAI"}, {"icon": "Anthropic"}, - {"icon": "Google"} + {"icon": "GoogleGenerativeAI"}, + {"icon": "Aliyun"} ]
2009-2044: Second Language Model node: add Aliyun to Provider dropdown here as well.Same issue as above; this node also omits Aliyun in
provider.options.Patch:
"options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ {"icon": "OpenAI"}, {"icon": "Anthropic"}, - {"icon": "Google"} + {"icon": "GoogleGenerativeAI"}, + {"icon": "Aliyun"} ]src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json (1)
1203-1238: Provider dropdown missing Aliyun in this template.Prevents users from selecting the new provider.
"options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ {"icon": "OpenAI"}, {"icon": "Anthropic"}, - {"icon": "Google"} + {"icon": "GoogleGenerativeAI"}, + {"icon": "Aliyun"} ]src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json (3)
3225-3399: Aliyun base URL should default to the correct region and be configurable; also set provider‑specific secret key name.
- DashScope has two OpenAI‑compatible endpoints: intl and China Mainland. Hardcoding the CN URL will fail for international users; default to the intl URL and allow override via env, and set the Aliyun secret key name to DASHSCOPE_API_KEY. (alibabacloud.com)
- ChatOpenAI supports passing the base URL via the alias openai_api_base (aka base_url), so this change is compatible with langchain_openai 0.3.x. (python.langchain.com)
Apply this patch inside both LanguageModelComponent code blocks:
@@ - if provider == "Aliyun": - if not self.api_key: - msg = "Aliyun API key is required when using Aliyun provider" - raise ValueError(msg) - return ChatOpenAI( - model_name=model_name, - temperature=temperature, - streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) + if provider == "Aliyun": + if not self.api_key: + msg = "Aliyun API key is required when using Aliyun provider" + raise ValueError(msg) + import os + base_url = os.getenv( + "DASHSCOPE_BASE_URL", + # Default to international endpoint; CN users can override via env + "https://dashscope-intl.aliyuncs.com/compatible-mode/v1", + ) + return ChatOpenAI( + model_name=model_name, + temperature=temperature, + streaming=stream, + openai_api_key=self.api_key, + openai_api_base=base_url, + ) @@ - elif field_value == "Aliyun": - build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES - build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] - build_config["api_key"]["display_name"] = "Aliyun API Key" + elif field_value == "Aliyun": + build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES + build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] + build_config["api_key"]["display_name"] = "Aliyun API Key" + # Use provider-specific secret name so stored creds auto-load + build_config["api_key"]["value"] = "DASHSCOPE_API_KEY"Also applies to: 3552-3725
3299-3326: Provider options in template omit Aliyun; users can’t select it.The instance template for provider still lists only OpenAI/Anthropic/Google. Add Aliyun and its icon to match the code.
"provider": { @@ - "options": [ - "OpenAI", - "Anthropic", - "Google" - ], - "options_metadata": [ - { "icon": "OpenAI" }, - { "icon": "Anthropic" }, - { "icon": "GoogleGenerativeAI" } - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], + "options_metadata": [ + { "icon": "OpenAI" }, + { "icon": "Anthropic" }, + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } + ],
3619-3653: Mirror the provider options fix for the second LanguageModelComponent.Add Aliyun to the provider options and icon list here as well to keep both nodes consistent.
"provider": { @@ - "options": [ - "OpenAI", - "Anthropic", - "Google" - ], - "options_metadata": [ - { "icon": "OpenAI" }, - { "icon": "Anthropic" }, - { "icon": "GoogleGenerativeAI" } - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], + "options_metadata": [ + { "icon": "OpenAI" }, + { "icon": "Anthropic" }, + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } + ],src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json (2)
1071-1244: Same Aliyun base URL and secret name adjustments needed here.Default to the intl endpoint (configurable via env) and set DASHSCOPE_API_KEY on provider switch to avoid failed calls for non‑CN users. (alibabacloud.com)
@@ - if provider == "Aliyun": - if not self.api_key: - msg = "Aliyun API key is required when using Aliyun provider" - raise ValueError(msg) - return ChatOpenAI( - model_name=model_name, - temperature=temperature, - streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) + if provider == "Aliyun": + if not self.api_key: + msg = "Aliyun API key is required when using Aliyun provider" + raise ValueError(msg) + import os + base_url = os.getenv( + "DASHSCOPE_BASE_URL", + "https://dashscope-intl.aliyuncs.com/compatible-mode/v1", + ) + return ChatOpenAI( + model_name=model_name, + temperature=temperature, + streaming=stream, + openai_api_key=self.api_key, + openai_api_base=base_url, + ) @@ - elif field_value == "Aliyun": - build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES - build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] - build_config["api_key"]["display_name"] = "Aliyun API Key" + elif field_value == "Aliyun": + build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES + build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] + build_config["api_key"]["display_name"] = "Aliyun API Key" + build_config["api_key"]["value"] = "DASHSCOPE_API_KEY"
1138-1172: Provider options in template also omit Aliyun here.Expose Aliyun and its icon so the dropdown matches the implementation.
"provider": { @@ - "options": [ - "OpenAI", - "Anthropic", - "Google" - ], - "options_metadata": [ - { "icon": "OpenAI" }, - { "icon": "Anthropic" }, - { "icon": "GoogleGenerativeAI" } - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], + "options_metadata": [ + { "icon": "OpenAI" }, + { "icon": "Anthropic" }, + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } + ],src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json (1)
1113-1148: Provider dropdown missing “Aliyun” and icon metadata.UI won’t expose the new provider in this starter. Add “Aliyun” and its icon to options/options_metadata to match the code.
Apply:
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "GoogleGenerativeAI" - } + "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" + } ],src/backend/base/langflow/initial_setup/starter_projects/Market Research.json (1)
1986-2021: Provider dropdown missing “Aliyun” and icon metadata.Users won’t be able to pick Aliyun here either.
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, - { "icon": "GoogleGenerativeAI" } + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } ],src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json (1)
1496-1531: Provider dropdown missing “Aliyun” and icon metadata.Expose the new provider in this starter’s UI.
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, - { "icon": "GoogleGenerativeAI" } + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } ],src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json (1)
2869-2895: Provider dropdown missing “Aliyun” in this node’s template (users can’t select it).UI options still list only OpenAI/Anthropic/Google. Add Aliyun so the starter works without manual edits.
Apply this minimal JSON diff in this section:
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], - "options_metadata": [ + "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, - { "icon": "GoogleGenerativeAI" } + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } ],src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json (2)
1418-1452: Provider dropdown missing “Aliyun” in initial options.UI won’t offer Aliyun on first render despite the Python code supporting it. Add Aliyun + icon here to match the code.
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], - "options_metadata": [ + "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "Google" + "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" } ],
1739-1774: Repeat the Aliyun option/icon fix in the second LanguageModelComponent.Keep both provider dropdowns in sync.
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], - "options_metadata": [ + "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, - { "icon": "Google" } + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } ],src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json (2)
2556-2591: Provider dropdown missing Aliyun in template (UI won’t show it)The template’s provider.options still list only OpenAI/Anthropic/Google, so users can’t select Aliyun despite the code supporting it. Add Aliyun and its icon.
Apply this diff:
"provider": { "_input_type": "DropdownInput", "advanced": false, "combobox": false, "dialog_inputs": {}, "display_name": "Model Provider", "dynamic": false, "info": "Select the model provider", "name": "provider", "options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" } ],
861-904: Agent provider list doesn’t include AliyunYT-Insight Agent’s “Model Provider” dropdown lacks Aliyun, preventing use of Aliyun for the agent in this starter flow.
Apply this diff:
"display_name": "Model Provider", "dynamic": false, "info": "The provider of the language model that the agent will use to generate responses.", "input_types": [], "name": "agent_llm", "options": [ - "Anthropic", - "Google Generative AI", - "Groq", - "OpenAI", - "Custom" + "Anthropic", + "Google Generative AI", + "Groq", + "OpenAI", + "Aliyun", + "Custom" ], "options_metadata": [ { "icon": "Anthropic" }, { "icon": "GoogleGenerativeAI" }, { "icon": "Groq" }, { "icon": "OpenAI" }, { "icon": "brain" + }, + { + "icon": "Aliyun" } ],src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json (1)
3176-3200: UI/provider mismatch: Aliyun not exposed in the dropdown templateThe LanguageModelComponent code adds "Aliyun", but the frontend template still lists only ["OpenAI","Anthropic","Google"]. Aliyun won’t be selectable in the UI.
Apply this diff to the template section:
"options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "GoogleGenerativeAI" + "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" } ],src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json (1)
2127-2161: Provider dropdown in template missing “Aliyun” (UI cannot select new provider)The backend code supports provider="Aliyun", but this node’s template options don’t list it, so users can’t pick Aliyun from the starter UI.
Patch the provider field:
"options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "Google" + "icon": "Google" + }, + { + "icon": "Aliyun" } ],src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json (1)
1563-1597: Template provider options don’t include “Aliyun”Backend supports it; UI won’t. Add “Aliyun” and icon to keep this starter usable.
Patch:
"options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "Google" + "icon": "Google" + }, + { + "icon": "Aliyun" } ],src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json (2)
2109-2110: Second node also hides Aliyun in provider dropdown and has invalid defaults.
- Provider options omit “Aliyun”.
model_name.valueisclaude-3-5-sonnet-latestbut the options are OpenAI models.- Provider default is “Anthropic”; mismatch with model list.
Apply:
- "value": "claude-3-5-sonnet-latest" + "value": "gpt-4o-mini" @@ - "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": ["OpenAI","Anthropic","Google","Aliyun"], "options_metadata": [ {"icon": "OpenAI"}, {"icon": "Anthropic"}, - {"icon": "GoogleGenerativeAI"} + {"icon": "GoogleGenerativeAI"}, + {"icon": "Aliyun"} ], - "value": "Anthropic" + "value": "OpenAI"Also applies to: 2119-2146
1691-1707: Fix inconsistent provider/model/API-key defaults in starter template (critical)File: src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json — issues at lines 1691–1707, 1750–1789, 1791–1815 (also duplicated ~2014–2125).
- api_key: display_name = "OpenAI API Key" but value = "ANTHROPIC_API_KEY" (1693–1706). Set value -> "OPENAI_API_KEY" OR change display_name -> "Anthropic API Key" to match provider.
- model_name: options list contains OpenAI models but value = "claude-3-5-sonnet-latest" (1758–1788). Set default to an OpenAI model (e.g., "gpt-4o-mini") OR add Anthropic models to the options.
- provider: options omit "Aliyun" and value = "Anthropic" (1790–1825). Add "Aliyun" to options/options_metadata if intended, and/or set provider.value -> "OpenAI" to align with OpenAI defaults.
- Apply identical fixes to the duplicate template blocks found later in the file (~2014–2125).
- Confirm whether update_build_config/template loader overwrites these defaults on first render and make the authoritative choice consistent.
src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json (1)
1578-1604: Expose Aliyun in the provider dropdown (and use consistent icon key).Add “Aliyun” to
optionsand its icon tooptions_metadata. Also, for consistency with other files, prefer"GoogleGenerativeAI"icon key, not"Google".- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": ["OpenAI","Anthropic","Google","Aliyun"], "options_metadata": [ {"icon": "OpenAI"}, {"icon": "Anthropic"}, - {"icon": "Google"} + {"icon": "GoogleGenerativeAI"}, + {"icon": "Aliyun"} ],
♻️ Duplicate comments (3)
src/lfx/src/lfx/components/models/language_model.py (1)
127-137: Use a shared base URL constant and confirm ChatOpenAI arg name.Extract the base to
ALIYUN_OPENAI_BASEand import it; also confirmopenai_api_baseis valid for your installed langchain_openai version (some versions usebase_url).-from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES +from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES, ALIYUN_OPENAI_BASE @@ if provider == "Aliyun": if not self.api_key: msg = "Aliyun API key is required when using Aliyun provider" raise ValueError(msg) return ChatOpenAI( model_name=model_name, temperature=temperature, streaming=stream, openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", + openai_api_base=ALIYUN_OPENAI_BASE, )Run this quick check to ensure we’re using the correct kwarg name across the repo:
#!/bin/bash rg -n --type=py -C2 '\bChatOpenAI\s*\(' rg -n --type=py -C1 'openai_api_base|base_url'If your pinned version requires
base_url, swap the kwarg accordingly.src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json (2)
3190-3217: Second LanguageModelComponent also missing “Aliyun” in provider options.Mirror the same options/options_metadata update here to expose Aliyun in the UI.
3116-3117: Same ChatOpenAI kwarg issue in the second LanguageModelComponent block.Apply the same
model/api_key/base_urlchanges here as in the earlier block to keep both nodes consistent.
🧹 Nitpick comments (45)
src/lfx/src/lfx/base/models/aliyun_constants.py (1)
1-3: Export the base URL as a constant to avoid string duplication.Define a single constant here and reuse it in builders.
from .model_metadata import create_model_metadata +# OpenAI-compatible base for DashScope +ALIYUN_OPENAI_BASE = "https://dashscope.aliyuncs.com/compatible-mode/v1" + # Unified model metadata - single source of truth ALIYUN_MODELS_DETAILED = [ @@ # Backwards compatibility MODEL_NAMES = ALIYUN_CHAT_MODEL_NAMES ALIYUN_MODEL_NAMES = ALIYUN_CHAT_MODEL_NAMESAlso applies to: 44-53
src/frontend/src/icons/Aliyun/index.tsx (1)
5-9: AddisDarkto the public props type for consistency with icon guidelines.You already forward all props; expose
isDarkin the type.-export const AliyunIcon = forwardRef< - SVGSVGElement, - React.PropsWithChildren<{}> ->((props, ref) => { +export const AliyunIcon = forwardRef< + SVGSVGElement, + React.PropsWithChildren<{ isDark?: boolean }> +>(({ isDark, ...rest }, ref) => { - return <SvgAliyun ref={ref} {...props} />; + return <SvgAliyun ref={ref} isDark={isDark} {...rest} />; });src/frontend/src/icons/Aliyun/Aliyun.jsx (1)
1-46: Support dark mode and forward standard SVG props.Currently props aren’t spread onto the , and
isDarkisn’t handled. Spread props and add a minimal dark‑mode treatment.-const SvgAliyun = (props) => ( - <svg +const SvgAliyun = ({ isDark = false, style, ...rest }) => ( + <svg data-name="layer1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 76 76" - > + role="img" + style={{ ...(style || {}), filter: isDark ? "brightness(0.92) contrast(1.05)" : undefined }} + {...rest} + >If you prefer precise palettes over filters, swap fills conditionally by
isDark.src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json (1)
861-868: Update note copy to reflect multiple providers.Currently says “Add your OpenAI API key”.
- "description": "### 💡 Add your OpenAI API key here", + "description": "### 💡 Add your model provider API key here (OpenAI / Anthropic / Google / Aliyun)",src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json (1)
1346-1370: Notes still reference “OpenAI API key”.Generalize the copy to cover all providers.
-"description": "### 💡 Add your OpenAI API key here 👇", +"description": "### 💡 Add your model provider API key here (OpenAI / Anthropic / Google / Aliyun) 👇",Also applies to: 1375-1396, 1401-1415
src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json (2)
847-855: Docs note still references only OpenAI.Minor copy tweak to reflect Aliyun support.
- * [OpenAI API Key](https://platform.openai.com/) + * OpenAI or Aliyun API key
1623-1670: Prefer canonical ChatOpenAI kwargs (model / api_key / base_url) — optional refactorlangchain_openai 0.3.23 exposes model/api_key/base_url as the canonical constructor args; model_name/openai_api_key/openai_api_base are still present as aliases, so the current code will work, but switching improves clarity and forward compatibility. Apply inside the Aliyun branch (and mirror the OpenAI branch if desired) in src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json.
- return ChatOpenAI( - model_name=model_name, - temperature=temperature, - streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) + return ChatOpenAI( + model=model_name, + temperature=temperature, + streaming=stream, + api_key=self.api_key, + base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", + )src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json (3)
1137-1197: Aliyun constructor kwargs: align with langchain_openai 0.3.x.Same as the other template: prefer
model/api_key/base_urlover legacy aliases to avoid surprises.- return ChatOpenAI( - model_name=model_name, - temperature=temperature, - streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) + return ChatOpenAI( + model=model_name, + temperature=temperature, + streaming=stream, + api_key=self.api_key, + base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", + )
780-804: Note text: broaden API key instruction.Tiny UX polish to acknowledge multiple providers.
-### 💡 Add your OpenAI API key here +### 💡 Add your model provider API key here (OpenAI, Aliyun, etc.)
1101-1161: Optional: preselect Aliyun model list on provider change.You’ve implemented this in
update_build_config; good. Consider also updating Secret input default env name when switching providers for better OOTB DX.If your platform supports it, set provider-specific defaults:
elif field_value == "Aliyun": build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] build_config["api_key"]["display_name"] = "Aliyun API Key" + # Optional if supported by SecretStrInput: default env var name + build_config["api_key"]["value"] = "DASHSCOPE_API_KEY"Please confirm
SecretStrInputallows updating the default env var key at runtime.src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json (4)
2465-2518: Update notes to reflect Aliyun support.Replace “Add your OpenAI API key here” with “Add your OpenAI or Aliyun API key here” to avoid misleading users.
- "description": "### 💡 Add your OpenAI API key here", + "description": "### 💡 Add your OpenAI or Aliyun API key here",Also applies to: 2494-2518
3751-3761: Description mentions OpenAI only.Suggest broadening to “OpenAI (or Aliyun)” so the starter matches capabilities.
- "description": "An AI-powered meeting summary generator that transcribes and summarizes meetings using AssemblyAI and OpenAI for quick insights.", + "description": "An AI-powered meeting summary generator that transcribes and summarizes meetings using AssemblyAI and OpenAI (or Aliyun) for quick insights.",
3191-3208: Optional: Rename default env key when Aliyun is selected.Initial template still defaults to OPENAI_API_KEY. With the code change above, switching provider sets the correct “DASHSCOPE_API_KEY”, but consider setting a provider-agnostic placeholder like “MODEL_PROVIDER_API_KEY” for clarity.
3225-3399: Optional: Expose “Base URL” (advanced) for Aliyun.Some teams use CN vs intl regions. Consider adding an advanced text input to override base URL instead of only env.
Would you like a small patch adding an optional advanced “Base URL” field that’s used only when provider == "Aliyun"?
Also applies to: 3552-3725
src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json (2)
748-754: Prerequisites note mentions OpenAI only.Recommend mentioning Aliyun (and that intl vs CN endpoints differ) to reduce confusion. (alibabacloud.com)
- "description": "# Document Q&A\n\nThis flow loads a file and uses an LLM to answer questions based on content from the loaded document. \n\n## Prerequisites\n\n* An [OpenAI API key](https://platform.openai.com/)\n\n## Quickstart\n\n1. Paste your OpenAI API key in the **OpenAI** model component.\n2. In the **File** component, select a file you want to load.\n3. Open the **Playground** and chat with your document.", + "description": "# Document Q&A\n\nThis flow loads a file and uses an LLM to answer questions based on the loaded document. \n\n## Prerequisites\n\n* An [OpenAI API key](https://platform.openai.com/) or an [Aliyun (DashScope) API key](https://bailian.console.aliyun.com/)\n\nNote: Aliyun’s OpenAI‑compatible base URL differs for international vs. China regions.\n\n## Quickstart\n\n1. Paste your API key in the **Language Model** component (choose provider OpenAI or Aliyun).\n2. In the **File** component, select a file you want to load.\n3. Open the **Playground** and chat with your document.",
301-302: Nit: fix prompt text grammar.- "value": "What is this document is about?" + "value": "What is this document about?"src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json (2)
561-566: Copy tweak: avoid “OpenAI API key” hardcoding in note.Generalize to “Model API Key” or mention Aliyun explicitly to reduce user confusion.
- "description": "### 💡 Add your OpenAI API key here 👇", + "description": "### 💡 Add your model API key here (OpenAI, Aliyun, …) 👇",
1247-1247: Description still says “OpenAI model”.Consider “language model” to reflect multi‑provider support.
- "description": "Perform basic prompting with an OpenAI model.", + "description": "Perform basic prompting with a language model.",src/backend/base/langflow/initial_setup/starter_projects/Market Research.json (3)
805-811: Prereqs/quickstart text only references OpenAI.Mention Aliyun as an alternative to match the new provider.
- - **[OpenAI API Key](https://platform.openai.com/)** + - **OpenAI or Aliyun API Key**
2151-2169: Agent provider list excludes Aliyun.Optional: if Agents should also support Aliyun in this template, add it to MODEL_PROVIDERS_LIST and UI options; otherwise consider leaving as‑is intentionally.
1920-1920: Prefer ChatOpenAI(model=..., api_key=..., base_url=...) for Aliyun branchChatOpenAI exposes aliases (model_name↔model, openai_api_key↔api_key, openai_api_base↔base_url); current code will work, but switch to model/api_key/base_url for consistency with langchain_openai usage. (api.python.langchain.com)
- return ChatOpenAI( - model_name=model_name, - temperature=temperature, - streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) + return ChatOpenAI( + model=model_name, + temperature=temperature, + streaming=stream, + api_key=self.api_key, + base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", + )src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json (1)
765-772: Quickstart note hardcodes OpenAI.Generalize to reflect Aliyun support.
-1. In the **Language Model** component, add your OpenAI API key, or select a different provider and model. +1. In the **Language Model** component, add your API key (OpenAI, Aliyun, …), or select a different provider and model.src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json (2)
2163-2196: Agent provider list doesn’t include Aliyun (flow uses Agent).If Aliyun is intended for Agent in this starter, add it to
agent_llmoptions and icon metadata; otherwise users can’t route the Agent via Aliyun even if the backend supports it.- "options": ["Anthropic","Google Generative AI","Groq","OpenAI","Custom"], + "options": ["Anthropic","Google Generative AI","Groq","OpenAI","Aliyun","Custom"], @@ - "options_metadata": [ + "options_metadata": [ {"icon":"Anthropic"}, {"icon":"GoogleGenerativeAI"}, {"icon":"Groq"}, - {"icon":"OpenAI"}, + {"icon":"OpenAI"}, + {"icon":"Aliyun"}, {"icon":"brain"} ],
1562-1569: README note: broaden API key wording.Change “Add your OpenAI API Key” to “Add your API Key (OpenAI, Aliyun, …)” to reflect new provider.
- - Add your **OpenAI API Key** to the **Agent** and **Language Model** components or change the provider and add your credentials. + - Add your **API Key** (OpenAI, Aliyun, etc.) to the **Agent** and **Language Model** components or change the provider and add your credentials.src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json (3)
1351-1352: Set provider‑specific env var keys (not only display names).update_build_config changes the API key label but not the stored key name. Suggest setting a dedicated env alias when provider switches to Aliyun to avoid clobbering OPENAI_API_KEY.
if field_value == "OpenAI": build_config["model_name"]["options"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES build_config["model_name"]["value"] = OPENAI_CHAT_MODEL_NAMES[0] build_config["api_key"]["display_name"] = "OpenAI API Key" + build_config["api_key"]["value"] = "OPENAI_API_KEY" @@ elif field_value == "Aliyun": build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] build_config["api_key"]["display_name"] = "Aliyun API Key" + build_config["api_key"]["value"] = "ALIYUN_API_KEY" # or "DASHSCOPE_API_KEY"Also applies to: 1673-1674
1351-1352: DRY: avoid duplicating the entire LanguageModelComponent code blob twice.If both nodes must share the same component, reference the same class/versioned module rather than embedding two near‑identical code strings to reduce drift.
Also applies to: 1673-1674
2170-2176: Update prerequisites copy to include Aliyun.Mention that users can supply an Aliyun API key when selecting that provider.
-* An [OpenAI API key](https://platform.openai.com/) +* An [OpenAI API key](https://platform.openai.com/) or an [Aliyun (DashScope) API key](https://bailian.console.aliyun.com/)src/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.json (1)
2697-2698: Nit: Consistent icon key for Google.In code you use "GoogleGenerativeAI", elsewhere template uses "Google". Pick one.
src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json (2)
2152-2160: README note should mention Aliyun keysStarter README only mentions OpenAI. Add Aliyun to reduce confusion.
- - Add your **OpenAI API Key** to the **Language Model** and **YT-Insight** Agent Component + - Add your **OpenAI or Aliyun API Key** to the **Language Model** and **YT-Insight** Agent Component
1146-1164: Optional: Rename “OpenAI API Base” label when using other providersFor clarity, consider dynamically renaming/hiding this field per provider (e.g., “API Base” or hide for providers that don’t use it).
src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json (2)
3076-3092: Generic key label for multi‑provider UXDefaulting the field label to “OpenAI API Key” is confusing when provider changes. Consider a neutral default (“Model Provider API Key”); you already relabel dynamically in update_build_config.
- "display_name": "OpenAI API Key", + "display_name": "Model Provider API Key",
4927-4932: Tag the template with aliyun for discoverabilityAdd "aliyun" to tags so users can find the new provider in starter search.
"tags": [ - "openai", + "openai", + "aliyun", "astradb", "rag", "q-a" ]src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json (2)
2028-2044: Optional: Also toggle API key placeholder per providerYou already change display_name to “Aliyun API Key” in update_build_config. Consider switching placeholder/value to ALIYUN_API_KEY when provider == "Aliyun" for clearer env wiring.
Example inside update_build_config:
elif field_value == "Aliyun": build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] build_config["api_key"]["display_name"] = "Aliyun API Key" + build_config["api_key"]["placeholder"] = "ALIYUN_API_KEY" + build_config["api_key"]["value"] = "ALIYUN_API_KEY"
2061-2062: Use canonical ChatOpenAI kwargs: replace openai_api_base with base_urllangchain_openai 0.3.23 documents api_key and base_url as the constructor kwargs; openai_api_base/openai_api_key are backward-compatible aliases. Change openai_api_base → base_url (api_key rename optional for consistency).
- return ChatOpenAI( - model_name=model_name, - temperature=temperature, - streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) + return ChatOpenAI( + model_name=model_name, + temperature=temperature, + streaming=stream, + openai_api_key=self.api_key, + base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", + )src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json (2)
1617-1640: Minor: System message formatting typo“...structured formatReturn...” is missing space/newline, which can degrade prompt quality.
- "value": "Translate to Portuguese and output in structured formatReturn only the JSON and no additional text." + "value": "Translate to Portuguese and output in structured format. Return only the JSON and no additional text."
1174-1197: Parser template defaults are inconsistent with mode=Stringifymode is “Stringify”, but pattern remains required/show=true; it’s unused and can confuse users.
"name": "pattern", "placeholder": "", - "required": true, - "show": true, + "required": false, + "show": false,src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json (3)
1724-1724: Set provider‑specific default secret name at runtime.
update_build_configupdates only the label; set the default secret key too to avoid confusing env lookups.
Apply:if field_name == "provider": if field_value == "OpenAI": build_config["model_name"]["options"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES build_config["model_name"]["value"] = OPENAI_CHAT_MODEL_NAMES[0] build_config["api_key"]["display_name"] = "OpenAI API Key" + build_config["api_key"]["value"] = "OPENAI_API_KEY" elif field_value == "Anthropic": build_config["model_name"]["options"] = ANTHROPIC_MODELS build_config["model_name"]["value"] = ANTHROPIC_MODELS[0] build_config["api_key"]["display_name"] = "Anthropic API Key" + build_config["api_key"]["value"] = "ANTHROPIC_API_KEY" elif field_value == "Google": build_config["model_name"]["options"] = GOOGLE_GENERATIVE_AI_MODELS build_config["model_name"]["value"] = GOOGLE_GENERATIVE_AI_MODELS[0] build_config["api_key"]["display_name"] = "Google API Key" + build_config["api_key"]["value"] = "GOOGLE_API_KEY" elif field_value == "Aliyun": build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] build_config["api_key"]["display_name"] = "Aliyun API Key" + build_config["api_key"]["value"] = "ALIYUN_API_KEY"
2045-2045: Duplicate code block: apply the same param/name fixes as above.Mirror the same
model/api_key/base_urlchanges and add provider‑specific secret defaults inside this second LanguageModelComponent block.Repeat the diffs from the first block for:
- ChatOpenAI, ChatAnthropic, ChatGoogleGenerativeAI constructors
update_build_configadditions forapi_key.value
1690-1707: Nit: keep secret placeholder coherent with provider default.If you keep OpenAI as the default provider, keep
api_key.valueasOPENAI_API_KEY. If you change default provider dynamically in this template later, ensure theupdate_build_confighook sets both display_name and value.src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json (1)
1537-1568: Default model mismatch.
model_name.valueisgpt-4o-mini, which is fine if provider starts as OpenAI. If you change provider by default here, ensuremodel_name.options/valueare reset on first render viaupdate_build_config. Otherwise keep OpenAI as the default provider.src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json (2)
2109-2110: Aliyun branch is correct; preferapi_key/base_urlover aliases.
- Using ChatOpenAI with DashScope compatible base is correct. Endpoint: https://dashscope.aliyuncs.com/compatible-mode/v1. (help.aliyun.com)
- LangChain’s ChatOpenAI supports
api_key/base_url(aliases exist foropenai_api_key/openai_api_base, but current docs show the new names). Consider switching for forward compatibility. (python.langchain.com)Suggested tweak inside this code block:
- return ChatOpenAI( - model_name=model_name, - temperature=temperature, - streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) + return ChatOpenAI( + model_name=model_name, + temperature=temperature, + streaming=stream, + api_key=self.api_key, + base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", + )
2430-2431: Duplicate Aliyun branch — same nits apply.
- Keep the DashScope base; switch to
api_key/base_urlfor consistency (see prior comment). (python.langchain.com)Apply the same diff in this block as above.
src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json (3)
1354-1355: Aliyun support is wired correctly; adopt current param names.
- Using ChatOpenAI with DashScope’s OpenAI‑compatible base is right. (help.aliyun.com)
- Prefer
api_key/base_urloveropenai_api_key/openai_api_baseper latest LangChain docs. (python.langchain.com)Patch in this code block:
- return ChatOpenAI( - model_name=model_name, - temperature=temperature, - streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) + return ChatOpenAI( + model_name=model_name, + temperature=temperature, + streaming=stream, + api_key=self.api_key, + base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", + )
1676-1677: Same Aliyun integration; make param names consistent with docs.Repeat the
api_key/base_urlswitch in this block. (python.langchain.com)
1997-1998: Third occurrence: correct endpoint; update arg names for forward‑compat.Keep DashScope base; use
api_key/base_url. (help.aliyun.com)
| "title_case": false, | ||
| "type": "code", | ||
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[{\"icon\": \"OpenAI\"}, {\"icon\": \"Anthropic\"}, {\"icon\": \"GoogleGenerativeAI\"}],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | ||
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" |
There was a problem hiding this comment.
🛠️ Refactor suggestion
🧩 Analysis chain
Align to current LangChain constructor params and add provider‑specific secret defaults.
Same rationale as the other template: use model/api_key/base_url and set api_key.value per provider in update_build_config.
Apply:
- return ChatOpenAI(
- model_name=model_name,
+ return ChatOpenAI(
+ model=model_name,
temperature=temperature,
streaming=stream,
- openai_api_key=self.api_key,
+ api_key=self.api_key,
)
@@
- return ChatAnthropic(
+ return ChatAnthropic(
model=model_name,
temperature=temperature,
streaming=stream,
- anthropic_api_key=self.api_key,
+ api_key=self.api_key,
)
@@
- return ChatGoogleGenerativeAI(
+ return ChatGoogleGenerativeAI(
model=model_name,
temperature=temperature,
streaming=stream,
- google_api_key=self.api_key,
+ api_key=self.api_key,
)
@@
- return ChatOpenAI(
- model_name=model_name,
+ return ChatOpenAI(
+ model=model_name,
temperature=temperature,
streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
@@
if field_name == "provider":
if field_value == "OpenAI":
...
build_config["api_key"]["display_name"] = "OpenAI API Key"
+ build_config["api_key"]["value"] = "OPENAI_API_KEY"
elif field_value == "Anthropic":
...
build_config["api_key"]["display_name"] = "Anthropic API Key"
+ build_config["api_key"]["value"] = "ANTHROPIC_API_KEY"
elif field_value == "Google":
...
build_config["api_key"]["display_name"] = "Google API Key"
+ build_config["api_key"]["value"] = "GOOGLE_API_KEY"
elif field_value == "Aliyun":
...
build_config["api_key"]["display_name"] = "Aliyun API Key"
+ build_config["api_key"]["value"] = "ALIYUN_API_KEY"To ensure no other starter templates kept legacy param names, run:
🏁 Script executed:
#!/bin/bash
rg -nP 'openai_api_base|openai_api_key|anthropic_api_key|google_api_key|model_name=' \
-g 'src/**/starter_projects/*.json' -C2Length of output: 276624
Align LangChain constructor params and add provider-specific secret defaults across starter_projects
LangChain chat model constructors expect unified params (model / api_key, and base_url for OpenAI-compatible endpoints) — update ChatOpenAI/ChatAnthropic/ChatGoogleGenerativeAI usages and set provider-specific api_key defaults in update_build_config. (api.python.langchain.com)
Apply the following changes (repeat across starter_projects templates):
- return ChatOpenAI(
- model_name=model_name,
+ return ChatOpenAI(
+ model=model_name,
temperature=temperature,
streaming=stream,
- openai_api_key=self.api_key,
+ api_key=self.api_key,
)
@@
- return ChatAnthropic(
+ return ChatAnthropic(
model=model_name,
temperature=temperature,
streaming=stream,
- anthropic_api_key=self.api_key,
+ api_key=self.api_key,
)
@@
- return ChatGoogleGenerativeAI(
+ return ChatGoogleGenerativeAI(
model=model_name,
temperature=temperature,
streaming=stream,
- google_api_key=self.api_key,
+ api_key=self.api_key,
)
@@
- return ChatOpenAI(
- model_name=model_name,
+ return ChatOpenAI(
+ model=model_name,
temperature=temperature,
streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
@@
if field_name == "provider":
if field_value == "OpenAI":
...
build_config["api_key"]["display_name"] = "OpenAI API Key"
+ build_config["api_key"]["value"] = "OPENAI_API_KEY"
elif field_value == "Anthropic":
...
build_config["api_key"]["display_name"] = "Anthropic API Key"
+ build_config["api_key"]["value"] = "ANTHROPIC_API_KEY"
elif field_value == "Google":
...
build_config["api_key"]["display_name"] = "Google API Key"
+ build_config["api_key"]["value"] = "GOOGLE_API_KEY"
elif field_value == "Aliyun":
...
build_config["api_key"]["display_name"] = "Aliyun API Key"
+ build_config["api_key"]["value"] = "ALIYUN_API_KEY"Run/apply across src/backend/base/langflow/initial_setup/starter_projects/*.json — rg already found these templates (examples: Blog Writer.json, Youtube Analysis.json, Vector Store RAG.json, Research Agent.json, SaaS Pricing.json, Meeting Summary.json).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | |
| from typing import Any | |
| from langchain_anthropic import ChatAnthropic | |
| from langchain_google_genai import ChatGoogleGenerativeAI | |
| from langchain_openai import ChatOpenAI | |
| from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES | |
| from lfx.base.models.anthropic_constants import ANTHROPIC_MODELS | |
| from lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS | |
| from lfx.base.models.model import LCModelComponent | |
| from lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES | |
| from lfx.field_typing import LanguageModel | |
| from lfx.field_typing.range_spec import RangeSpec | |
| from lfx.inputs.inputs import BoolInput | |
| from lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput | |
| from lfx.schema.dotdict import dotdict | |
| class LanguageModelComponent(LCModelComponent): | |
| display_name = "Language Model" | |
| description = "Runs a language model given a specified provider." | |
| documentation: str = "https://docs.langflow.org/components-models" | |
| icon = "brain-circuit" | |
| category = "models" | |
| priority = 0 # Set priority to 0 to make it appear first | |
| inputs = [ | |
| DropdownInput( | |
| name="provider", | |
| display_name="Model Provider", | |
| options=["OpenAI", "Anthropic", "Google", "Aliyun"], | |
| value="OpenAI", | |
| info="Select the model provider", | |
| real_time_refresh=True, | |
| options_metadata=[ | |
| {"icon": "OpenAI"}, | |
| {"icon": "Anthropic"}, | |
| {"icon": "GoogleGenerativeAI"}, | |
| {"icon": "Aliyun"}, | |
| ], | |
| ), | |
| DropdownInput( | |
| name="model_name", | |
| display_name="Model Name", | |
| options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES, | |
| value=OPENAI_CHAT_MODEL_NAMES[0], | |
| info="Select the model to use", | |
| real_time_refresh=True, | |
| ), | |
| SecretStrInput( | |
| name="api_key", | |
| display_name="OpenAI API Key", | |
| info="Model Provider API key", | |
| required=False, | |
| show=True, | |
| real_time_refresh=True, | |
| ), | |
| MessageInput( | |
| name="input_value", | |
| display_name="Input", | |
| info="The input text to send to the model", | |
| ), | |
| MultilineInput( | |
| name="system_message", | |
| display_name="System Message", | |
| info="A system message that helps set the behavior of the assistant", | |
| advanced=False, | |
| ), | |
| BoolInput( | |
| name="stream", | |
| display_name="Stream", | |
| info="Whether to stream the response", | |
| value=False, | |
| advanced=True, | |
| ), | |
| SliderInput( | |
| name="temperature", | |
| display_name="Temperature", | |
| value=0.1, | |
| info="Controls randomness in responses", | |
| range_spec=RangeSpec(min=0, max=1, step=0.01), | |
| advanced=True, | |
| ), | |
| ] | |
| def build_model(self) -> LanguageModel: | |
| provider = self.provider | |
| model_name = self.model_name | |
| temperature = self.temperature | |
| stream = self.stream | |
| if provider == "OpenAI": | |
| if not self.api_key: | |
| msg = "OpenAI API key is required when using OpenAI provider" | |
| raise ValueError(msg) | |
| if model_name in OPENAI_REASONING_MODEL_NAMES: | |
| # reasoning models do not support temperature (yet) | |
| temperature = None | |
| return ChatOpenAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| api_key=self.api_key, | |
| ) | |
| if provider == "Anthropic": | |
| if not self.api_key: | |
| msg = "Anthropic API key is required when using Anthropic provider" | |
| raise ValueError(msg) | |
| return ChatAnthropic( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| api_key=self.api_key, | |
| ) | |
| if provider == "Google": | |
| if not self.api_key: | |
| msg = "Google API key is required when using Google provider" | |
| raise ValueError(msg) | |
| return ChatGoogleGenerativeAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| api_key=self.api_key, | |
| ) | |
| if provider == "Aliyun": | |
| if not self.api_key: | |
| msg = "Aliyun API key is required when using Aliyun provider" | |
| raise ValueError(msg) | |
| return ChatOpenAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| api_key=self.api_key, | |
| base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", | |
| ) | |
| msg = f"Unknown provider: {provider}" | |
| raise ValueError(msg) | |
| def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict: | |
| if field_name == "provider": | |
| if field_value == "OpenAI": | |
| build_config["model_name"]["options"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES | |
| build_config["model_name"]["value"] = OPENAI_CHAT_MODEL_NAMES[0] | |
| build_config["api_key"]["display_name"] = "OpenAI API Key" | |
| build_config["api_key"]["value"] = "OPENAI_API_KEY" | |
| elif field_value == "Anthropic": | |
| build_config["model_name"]["options"] = ANTHROPIC_MODELS | |
| build_config["model_name"]["value"] = ANTHROPIC_MODELS[0] | |
| build_config["api_key"]["display_name"] = "Anthropic API Key" | |
| build_config["api_key"]["value"] = "ANTHROPIC_API_KEY" | |
| elif field_value == "Google": | |
| build_config["model_name"]["options"] = GOOGLE_GENERATIVE_AI_MODELS | |
| build_config["model_name"]["value"] = GOOGLE_GENERATIVE_AI_MODELS[0] | |
| build_config["api_key"]["display_name"] = "Google API Key" | |
| build_config["api_key"]["value"] = "GOOGLE_API_KEY" | |
| elif field_value == "Aliyun": | |
| build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES | |
| build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] | |
| build_config["api_key"]["display_name"] = "Aliyun API Key" | |
| build_config["api_key"]["value"] = "ALIYUN_API_KEY" | |
| elif field_name == "model_name" and field_value.startswith("o1") and self.provider == "OpenAI": | |
| # Hide system_message for o1 models - currently unsupported | |
| if "system_message" in build_config: | |
| build_config["system_message"]["show"] = False | |
| elif field_name == "model_name" and not field_value.startswith("o1") and "system_message" in build_config: | |
| build_config["system_message"]["show"] = True | |
| return build_config |
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
Ensure provider switch also updates secret key slot (env name).
update_build_config only changes api_key display_name; the SecretStrInput default value remains "ANTHROPIC_API_KEY". Users choosing OpenAI/Google/Aliyun won’t auto-pick their stored secrets. Set a provider-specific default.
Apply this diff inside update_build_config:
if field_name == "provider":
if field_value == "OpenAI":
build_config["model_name"]["options"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES
build_config["model_name"]["value"] = OPENAI_CHAT_MODEL_NAMES[0]
build_config["api_key"]["display_name"] = "OpenAI API Key"
+ build_config["api_key"]["value"] = "OPENAI_API_KEY"
elif field_value == "Anthropic":
build_config["model_name"]["options"] = ANTHROPIC_MODELS
build_config["model_name"]["value"] = ANTHROPIC_MODELS[0]
build_config["api_key"]["display_name"] = "Anthropic API Key"
+ build_config["api_key"]["value"] = "ANTHROPIC_API_KEY"
elif field_value == "Google":
build_config["model_name"]["options"] = GOOGLE_GENERATIVE_AI_MODELS
build_config["model_name"]["value"] = GOOGLE_GENERATIVE_AI_MODELS[0]
build_config["api_key"]["display_name"] = "Google API Key"
+ build_config["api_key"]["value"] = "GOOGLE_API_KEY"
elif field_value == "Aliyun":
build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES
build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0]
build_config["api_key"]["display_name"] = "Aliyun API Key"
+ build_config["api_key"]["value"] = "ALIYUN_API_KEY"🏁 Script executed:
#!/bin/bash
# Inspect other components for how they map provider -> default secret names
rg -n -C2 'SecretStrInput\(|display_name\"\:\s*\".*API Key\"|_API_KEY\"' --type=py --type=jsonLength of output: 155
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Searching repository for SecretStrInput usages and provider API key defaults..."
rg -n -C2 --hidden -S 'SecretStrInput\(' || true
rg -n -C2 --hidden -S '"API Key"' || true
rg -n -C2 --hidden -S '_API_KEY' || true
rg -n -C2 --hidden -S '"api_key"' || true
rg -n -C2 --hidden -S 'OPENAI_API_KEY|ANTHROPIC_API_KEY|GOOGLE_API_KEY|ALIYUN_API_KEY' || trueLength of output: 288821
Set provider-specific secret default (env var) when provider changes
update_build_config only updates api_key display_name; also set build_config["api_key"]["value"] to the provider-specific env var so the secret slot auto-populates.
if field_name == "provider":
if field_value == "OpenAI":
build_config["model_name"]["options"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES
build_config["model_name"]["value"] = OPENAI_CHAT_MODEL_NAMES[0]
build_config["api_key"]["display_name"] = "OpenAI API Key"
+ build_config["api_key"]["value"] = "OPENAI_API_KEY"
elif field_value == "Anthropic":
build_config["model_name"]["options"] = ANTHROPIC_MODELS
build_config["model_name"]["value"] = ANTHROPIC_MODELS[0]
build_config["api_key"]["display_name"] = "Anthropic API Key"
+ build_config["api_key"]["value"] = "ANTHROPIC_API_KEY"
elif field_value == "Google":
build_config["model_name"]["options"] = GOOGLE_GENERATIVE_AI_MODELS
build_config["model_name"]["value"] = GOOGLE_GENERATIVE_AI_MODELS[0]
build_config["api_key"]["display_name"] = "Google API Key"
+ build_config["api_key"]["value"] = "GOOGLE_API_KEY"
elif field_value == "Aliyun":
build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES
build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0]
build_config["api_key"]["display_name"] = "Aliyun API Key"
+ build_config["api_key"]["value"] = "ALIYUN_API_KEY"Apply this change to the LanguageModelComponent update_build_config in the starter_projects templates (src/backend/base/langflow/initial_setup/starter_projects/*.json).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | |
| }, | |
| from typing import Any | |
| from langchain_anthropic import ChatAnthropic | |
| from langchain_google_genai import ChatGoogleGenerativeAI | |
| from langchain_openai import ChatOpenAI | |
| from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES | |
| from lfx.base.models.anthropic_constants import ANTHROPIC_MODELS | |
| from lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS | |
| from lfx.base.models.model import LCModelComponent | |
| from lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES | |
| from lfx.field_typing import LanguageModel | |
| from lfx.field_typing.range_spec import RangeSpec | |
| from lfx.inputs.inputs import BoolInput | |
| from lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput | |
| from lfx.schema.dotdict import dotdict | |
| class LanguageModelComponent(LCModelComponent): | |
| display_name = "Language Model" | |
| description = "Runs a language model given a specified provider." | |
| documentation: str = "https://docs.langflow.org/components-models" | |
| icon = "brain-circuit" | |
| category = "models" | |
| priority = 0 # Set priority to 0 to make it appear first | |
| inputs = [ | |
| DropdownInput( | |
| name="provider", | |
| display_name="Model Provider", | |
| options=["OpenAI", "Anthropic", "Google", "Aliyun"], | |
| value="OpenAI", | |
| info="Select the model provider", | |
| real_time_refresh=True, | |
| options_metadata=[ | |
| {"icon": "OpenAI"}, | |
| {"icon": "Anthropic"}, | |
| {"icon": "GoogleGenerativeAI"}, | |
| {"icon": "Aliyun"}, | |
| ], | |
| ), | |
| DropdownInput( | |
| name="model_name", | |
| display_name="Model Name", | |
| options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES, | |
| value=OPENAI_CHAT_MODEL_NAMES[0], | |
| info="Select the model to use", | |
| real_time_refresh=True, | |
| ), | |
| SecretStrInput( | |
| name="api_key", | |
| display_name="OpenAI API Key", | |
| info="Model Provider API key", | |
| required=False, | |
| show=True, | |
| real_time_refresh=True, | |
| ), | |
| MessageInput( | |
| name="input_value", | |
| display_name="Input", | |
| info="The input text to send to the model", | |
| ), | |
| MultilineInput( | |
| name="system_message", | |
| display_name="System Message", | |
| info="A system message that helps set the behavior of the assistant", | |
| advanced=False, | |
| ), | |
| BoolInput( | |
| name="stream", | |
| display_name="Stream", | |
| info="Whether to stream the response", | |
| value=False, | |
| advanced=True, | |
| ), | |
| SliderInput( | |
| name="temperature", | |
| display_name="Temperature", | |
| value=0.1, | |
| info="Controls randomness in responses", | |
| range_spec=RangeSpec(min=0, max=1, step=0.01), | |
| advanced=True, | |
| ), | |
| ] | |
| def build_model(self) -> LanguageModel: | |
| provider = self.provider | |
| model_name = self.model_name | |
| temperature = self.temperature | |
| stream = self.stream | |
| if provider == "OpenAI": | |
| if not self.api_key: | |
| msg = "OpenAI API key is required when using OpenAI provider" | |
| raise ValueError(msg) | |
| if model_name in OPENAI_REASONING_MODEL_NAMES: | |
| # reasoning models do not support temperature (yet) | |
| temperature = None | |
| return ChatOpenAI( | |
| model_name=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| openai_api_key=self.api_key, | |
| ) | |
| if provider == "Anthropic": | |
| if not self.api_key: | |
| msg = "Anthropic API key is required when using Anthropic provider" | |
| raise ValueError(msg) | |
| return ChatAnthropic( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| anthropic_api_key=self.api_key, | |
| ) | |
| if provider == "Google": | |
| if not self.api_key: | |
| msg = "Google API key is required when using Google provider" | |
| raise ValueError(msg) | |
| return ChatGoogleGenerativeAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| google_api_key=self.api_key, | |
| ) | |
| if provider == "Aliyun": | |
| if not self.api_key: | |
| msg = "Aliyun API key is required when using Aliyun provider" | |
| raise ValueError(msg) | |
| return ChatOpenAI( | |
| model_name=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| openai_api_key=self.api_key, | |
| openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", | |
| ) | |
| msg = f"Unknown provider: {provider}" | |
| raise ValueError(msg) | |
| def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict: | |
| if field_name == "provider": | |
| if field_value == "OpenAI": | |
| build_config["model_name"]["options"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES | |
| build_config["model_name"]["value"] = OPENAI_CHAT_MODEL_NAMES[0] | |
| build_config["api_key"]["display_name"] = "OpenAI API Key" | |
| build_config["api_key"]["value"] = "OPENAI_API_KEY" | |
| elif field_value == "Anthropic": | |
| build_config["model_name"]["options"] = ANTHROPIC_MODELS | |
| build_config["model_name"]["value"] = ANTHROPIC_MODELS[0] | |
| build_config["api_key"]["display_name"] = "Anthropic API Key" | |
| build_config["api_key"]["value"] = "ANTHROPIC_API_KEY" | |
| elif field_value == "Google": | |
| build_config["model_name"]["options"] = GOOGLE_GENERATIVE_AI_MODELS | |
| build_config["model_name"]["value"] = GOOGLE_GENERATIVE_AI_MODELS[0] | |
| build_config["api_key"]["display_name"] = "Google API Key" | |
| build_config["api_key"]["value"] = "GOOGLE_API_KEY" | |
| elif field_value == "Aliyun": | |
| build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES | |
| build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] | |
| build_config["api_key"]["display_name"] = "Aliyun API Key" | |
| build_config["api_key"]["value"] = "ALIYUN_API_KEY" | |
| elif field_name == "model_name" and field_value.startswith("o1") and self.provider == "OpenAI": | |
| # Hide system_message for o1 models - currently unsupported | |
| if "system_message" in build_config: | |
| build_config["system_message"]["show"] = False | |
| elif field_name == "model_name" and not field_value.startswith("o1") and "system_message" in build_config: | |
| build_config["system_message"]["show"] = True | |
| return build_config |
🤖 Prompt for AI Agents
In src/backend/base/langflow/initial_setup/starter_projects/Custom Component
Generator.json around lines 2697-2698, the update_build_config handler only
updates api_key display_name when provider changes—add setting
build_config["api_key"]["value"] to the provider-specific environment variable
so the secret input auto-populates (e.g., set to "${OPENAI_API_KEY}" for OpenAI,
"${ANTHROPIC_API_KEY}" for Anthropic, "${GOOGLE_API_KEY}" for Google, and
"${ALIYUN_API_KEY}" for Aliyun) and apply the same change to the other
starter_projects JSON templates' LanguageModelComponent update_build_config
implementations.
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
Aliyun: use base_url (not openai_api_base) with ChatOpenAI.
langchain_openai ≥0.3 expects base_url; openai_api_base may be ignored. This would silently route calls to OpenAI and fail with Aliyun keys. Replace the kwarg in both LanguageModelComponent code blocks.
Apply:
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
- )
+ return ChatOpenAI(
+ model_name=model_name,
+ temperature=temperature,
+ streaming=stream,
+ openai_api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ )Run to confirm other sites don’t rely on the deprecated kwarg and to verify the pinned version:
🏁 Script executed:
#!/bin/bash
fd -a "pyproject.toml|requirements*.txt|poetry.lock|uv.lock" | xargs -I{} rg -n "langchain_openai" {}
rg -n "ChatOpenAI\(" -A3 -B3
rg -n "openai_api_base\s*=" -nLength of output: 262934
Replace openai_api_base with base_url for Aliyun ChatOpenAI calls (critical)
poetry/lock shows langchain_openai >=0.3.x (0.3.32 present) and the repo contains multiple Aliyun branches passing openai_api_base to ChatOpenAI (e.g. src/lfx/src/lfx/components/models/language_model.py and starter project JSONs under src/backend/base/langflow/initial_setup/starter_projects/) — update to base_url so Aliyun requests are routed correctly.
Apply:
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
- )
+ return ChatOpenAI(
+ model_name=model_name,
+ temperature=temperature,
+ streaming=stream,
+ openai_api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ )Files to fix: src/lfx/src/lfx/components/models/language_model.py and all starter project templates under src/backend/base/langflow/initial_setup/starter_projects/ that set openai_api_base.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | |
| }, | |
| if provider == "Aliyun": | |
| if not self.api_key: | |
| msg = "Aliyun API key is required when using Aliyun provider" | |
| raise ValueError(msg) | |
| return ChatOpenAI( | |
| model_name=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| openai_api_key=self.api_key, | |
| base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", | |
| ) |
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | ||
| }, |
There was a problem hiding this comment.
Same fix needed here.
Duplicate LanguageModelComponent block also uses openai_api_base. Apply the same base_url change.
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | |
| }, | |
| from typing import Any | |
| from langchain_anthropic import ChatAnthropic | |
| from langchain_google_genai import ChatGoogleGenerativeAI | |
| from langchain_openai import ChatOpenAI | |
| from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES | |
| from lfx.base.models.anthropic_constants import ANTHROPIC_MODELS | |
| from lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS | |
| from lfx.base.models.model import LCModelComponent | |
| from lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES | |
| from lfx.field_typing import LanguageModel | |
| from lfx.field_typing.range_spec import RangeSpec | |
| from lfx.inputs.inputs import BoolInput | |
| from lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput | |
| from lfx.schema.dotdict import dotdict | |
| class LanguageModelComponent(LCModelComponent): | |
| display_name = "Language Model" | |
| description = "Runs a language model given a specified provider." | |
| documentation: str = "https://docs.langflow.org/components-models" | |
| icon = "brain-circuit" | |
| category = "models" | |
| priority = 0 # Set priority to 0 to make it appear first | |
| inputs = [ | |
| DropdownInput( | |
| name="provider", | |
| display_name="Model Provider", | |
| options=["OpenAI", "Anthropic", "Google", "Aliyun"], | |
| value="OpenAI", | |
| info="Select the model provider", | |
| real_time_refresh=True, | |
| options_metadata=[ | |
| {"icon": "OpenAI"}, | |
| {"icon": "Anthropic"}, | |
| {"icon": "GoogleGenerativeAI"}, | |
| {"icon": "Aliyun"}, | |
| ], | |
| ), | |
| DropdownInput( | |
| name="model_name", | |
| display_name="Model Name", | |
| options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES, | |
| value=OPENAI_CHAT_MODEL_NAMES[0], | |
| info="Select the model to use", | |
| real_time_refresh=True, | |
| ), | |
| SecretStrInput( | |
| name="api_key", | |
| display_name="OpenAI API Key", | |
| info="Model Provider API key", | |
| required=False, | |
| show=True, | |
| real_time_refresh=True, | |
| ), | |
| MessageInput( | |
| name="input_value", | |
| display_name="Input", | |
| info="The input text to send to the model", | |
| ), | |
| MultilineInput( | |
| name="system_message", | |
| display_name="System Message", | |
| info="A system message that helps set the behavior of the assistant", | |
| advanced=False, | |
| ), | |
| BoolInput( | |
| name="stream", | |
| display_name="Stream", | |
| info="Whether to stream the response", | |
| value=False, | |
| advanced=True, | |
| ), | |
| SliderInput( | |
| name="temperature", | |
| display_name="Temperature", | |
| value=0.1, | |
| info="Controls randomness in responses", | |
| range_spec=RangeSpec(min=0, max=1, step=0.01), | |
| advanced=True, | |
| ), | |
| ] | |
| def build_model(self) -> LanguageModel: | |
| provider = self.provider | |
| model_name = self.model_name | |
| temperature = self.temperature | |
| stream = self.stream | |
| if provider == "OpenAI": | |
| if not self.api_key: | |
| msg = "OpenAI API key is required when using OpenAI provider" | |
| raise ValueError(msg) | |
| if model_name in OPENAI_REASONING_MODEL_NAMES: | |
| # reasoning models do not support temperature (yet) | |
| temperature = None | |
| return ChatOpenAI( | |
| model_name=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| openai_api_key=self.api_key, | |
| ) | |
| if provider == "Anthropic": | |
| if not self.api_key: | |
| msg = "Anthropic API key is required when using Anthropic provider" | |
| raise ValueError(msg) | |
| return ChatAnthropic( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| anthropic_api_key=self.api_key, | |
| ) | |
| if provider == "Google": | |
| if not self.api_key: | |
| msg = "Google API key is required when using Google provider" | |
| raise ValueError(msg) | |
| return ChatGoogleGenerativeAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| google_api_key=self.api_key, | |
| ) | |
| if provider == "Aliyun": | |
| if not self.api_key: | |
| msg = "Aliyun API key is required when using Aliyun provider" | |
| raise ValueError(msg) | |
| return ChatOpenAI( | |
| model_name=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| openai_api_key=self.api_key, | |
| base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", | |
| ) | |
| msg = f"Unknown provider: {provider}" | |
| raise ValueError(msg) | |
| def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict: | |
| if field_name == "provider": | |
| if field_value == "OpenAI": | |
| build_config["model_name"]["options"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES | |
| build_config["model_name"]["value"] = OPENAI_CHAT_MODEL_NAMES[0] | |
| build_config["api_key"]["display_name"] = "OpenAI API Key" | |
| elif field_value == "Anthropic": | |
| build_config["model_name"]["options"] = ANTHROPIC_MODELS | |
| build_config["model_name"]["value"] = ANTHROPIC_MODELS[0] | |
| build_config["api_key"]["display_name"] = "Anthropic API Key" | |
| elif field_value == "Google": | |
| build_config["model_name"]["options"] = GOOGLE_GENERATIVE_AI_MODELS | |
| build_config["model_name"]["value"] = GOOGLE_GENERATIVE_AI_MODELS[0] | |
| build_config["api_key"]["display_name"] = "Google API Key" | |
| elif field_value == "Aliyun": | |
| build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES | |
| build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] | |
| build_config["api_key"]["display_name"] = "Aliyun API Key" | |
| elif field_name == "model_name" and field_value.startswith("o1") and self.provider == "OpenAI": | |
| # Hide system_message for o1 models - currently unsupported | |
| if "system_message" in build_config: | |
| build_config["system_message"]["show"] = False | |
| elif field_name == "model_name" and not field_value.startswith("o1") and "system_message" in build_config: | |
| build_config["system_message"]["show"] = True | |
| return build_config |
🤖 Prompt for AI Agents
In src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search
RAG.json around lines 1673-1674, the duplicate LanguageModelComponent returns a
ChatOpenAI using the deprecated/openai-specific kwarg openai_api_base; replace
that kwarg with base_url set to
"https://dashscope.aliyuncs.com/compatible-mode/v1" so the ChatOpenAI
constructor uses base_url instead of openai_api_base (keep all other params the
same).
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
Fix ChatOpenAI kwargs to match langchain_openai 0.3.x (avoid runtime errors).
In both OpenAI and Aliyun branches you pass model_name, openai_api_key, and (for Aliyun) openai_api_base. With langchain_openai 0.3.x the correct kwargs are model, api_key, and base_url. Keeping the legacy names will raise validation errors at runtime.
Apply this diff inside the LanguageModelComponent code block:
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ )
@@
- if provider == "Aliyun":
+ if provider == "Aliyun":
if not self.api_key:
msg = "Aliyun API key is required when using Aliyun provider"
raise ValueError(msg)
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ )Run to confirm lib version and other call sites:
🏁 Script executed:
#!/bin/bash
# 1) Confirm declared langchain_openai version
rg -nP --glob '!**/node_modules/**' 'langchain_openai' -C2
# 2) Find all ChatOpenAI instantiations and show kwargs used
rg -nP --type=py -C2 'ChatOpenAI\s*\('
# 3) Grep for legacy kwargs to fix them repo‑wide
rg -nP --type=py -C1 '\b(openai_api_key|openai_api_base|model_name)\s*='Length of output: 36827
Fix ChatOpenAI kwargs to langchain_openai 0.3.x (use model / api_key / base_url).
Replace model_name→model, openai_api_key→api_key, openai_api_base→base_url; repo currently mixes old/new kwargs — update all call sites or add a compatibility adapter.
- Key locations to change:
- src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json (LanguageModelComponent snippet in this PR)
- src/lfx/src/lfx/components/models/language_model.py (uses model_name / openai_api_key / openai_api_base)
- src/lfx/src/lfx/components/openai/openai_chat_model.py (ChatOpenAI(**parameters) — normalize parameter keys before calling)
- src/lfx/src/lfx/components/openrouter/openrouter.py (ChatOpenAI(**kwargs) — same)
- src/backend/tests/unit/components/languagemodels/test_openai_model.py (tests assert openai_api_base; update tests or mapping)
Apply this diff in the LanguageModelComponent block:
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ )
@@
- if provider == "Aliyun":
+ if provider == "Aliyun":
if not self.api_key:
msg = "Aliyun API key is required when using Aliyun provider"
raise ValueError(msg)
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ )📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | |
| }, | |
| from typing import Any | |
| from langchain_anthropic import ChatAnthropic | |
| from langchain_google_genai import ChatGoogleGenerativeAI | |
| from langchain_openai import ChatOpenAI | |
| from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES | |
| from lfx.base.models.anthropic_constants import ANTHROPIC_MODELS | |
| from lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS | |
| from lfx.base.models.model import LCModelComponent | |
| from lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES | |
| from lfx.field_typing import LanguageModel | |
| from lfx.field_typing.range_spec import RangeSpec | |
| from lfx.inputs.inputs import BoolInput | |
| from lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput | |
| from lfx.schema.dotdict import dotdict | |
| class LanguageModelComponent(LCModelComponent): | |
| display_name = "Language Model" | |
| description = "Runs a language model given a specified provider." | |
| documentation: str = "https://docs.langflow.org/components-models" | |
| icon = "brain-circuit" | |
| category = "models" | |
| priority = 0 # Set priority to 0 to make it appear first | |
| inputs = [ | |
| DropdownInput( | |
| name="provider", | |
| display_name="Model Provider", | |
| options=["OpenAI", "Anthropic", "Google", "Aliyun"], | |
| value="OpenAI", | |
| info="Select the model provider", | |
| real_time_refresh=True, | |
| options_metadata=[ | |
| {"icon": "OpenAI"}, | |
| {"icon": "Anthropic"}, | |
| {"icon": "GoogleGenerativeAI"}, | |
| {"icon": "Aliyun"}, | |
| ], | |
| ), | |
| DropdownInput( | |
| name="model_name", | |
| display_name="Model Name", | |
| options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES, | |
| value=OPENAI_CHAT_MODEL_NAMES[0], | |
| info="Select the model to use", | |
| real_time_refresh=True, | |
| ), | |
| SecretStrInput( | |
| name="api_key", | |
| display_name="OpenAI API Key", | |
| info="Model Provider API key", | |
| required=False, | |
| show=True, | |
| real_time_refresh=True, | |
| ), | |
| MessageInput( | |
| name="input_value", | |
| display_name="Input", | |
| info="The input text to send to the model", | |
| ), | |
| MultilineInput( | |
| name="system_message", | |
| display_name="System Message", | |
| info="A system message that helps set the behavior of the assistant", | |
| advanced=False, | |
| ), | |
| BoolInput( | |
| name="stream", | |
| display_name="Stream", | |
| info="Whether to stream the response", | |
| value=False, | |
| advanced=True, | |
| ), | |
| SliderInput( | |
| name="temperature", | |
| display_name="Temperature", | |
| value=0.1, | |
| info="Controls randomness in responses", | |
| range_spec=RangeSpec(min=0, max=1, step=0.01), | |
| advanced=True, | |
| ), | |
| ] | |
| def build_model(self) -> LanguageModel: | |
| provider = self.provider | |
| model_name = self.model_name | |
| temperature = self.temperature | |
| stream = self.stream | |
| if provider == "OpenAI": | |
| if not self.api_key: | |
| msg = "OpenAI API key is required when using OpenAI provider" | |
| raise ValueError(msg) | |
| if model_name in OPENAI_REASONING_MODEL_NAMES: | |
| # reasoning models do not support temperature (yet) | |
| temperature = None | |
| return ChatOpenAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| api_key=self.api_key, | |
| ) | |
| if provider == "Anthropic": | |
| if not self.api_key: | |
| msg = "Anthropic API key is required when using Anthropic provider" | |
| raise ValueError(msg) | |
| return ChatAnthropic( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| anthropic_api_key=self.api_key, | |
| ) | |
| if provider == "Google": | |
| if not self.api_key: | |
| msg = "Google API key is required when using Google provider" | |
| raise ValueError(msg) | |
| return ChatGoogleGenerativeAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| google_api_key=self.api_key, | |
| ) | |
| if provider == "Aliyun": | |
| if not self.api_key: | |
| msg = "Aliyun API key is required when using Aliyun provider" | |
| raise ValueError(msg) | |
| return ChatOpenAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| api_key=self.api_key, | |
| base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", | |
| ) | |
| msg = f"Unknown provider: {provider}" | |
| raise ValueError(msg) | |
| def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict: | |
| if field_name == "provider": | |
| if field_value == "OpenAI": | |
| build_config["model_name"]["options"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES | |
| build_config["model_name"]["value"] = OPENAI_CHAT_MODEL_NAMES[0] | |
| build_config["api_key"]["display_name"] = "OpenAI API Key" | |
| elif field_value == "Anthropic": | |
| build_config["model_name"]["options"] = ANTHROPIC_MODELS | |
| build_config["model_name"]["value"] = ANTHROPIC_MODELS[0] | |
| build_config["api_key"]["display_name"] = "Anthropic API Key" | |
| elif field_value == "Google": | |
| build_config["model_name"]["options"] = GOOGLE_GENERATIVE_AI_MODELS | |
| build_config["model_name"]["value"] = GOOGLE_GENERATIVE_AI_MODELS[0] | |
| build_config["api_key"]["display_name"] = "Google API Key" | |
| elif field_value == "Aliyun": | |
| build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES | |
| build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] | |
| build_config["api_key"]["display_name"] = "Aliyun API Key" | |
| elif field_name == "model_name" and field_value.startswith("o1") and self.provider == "OpenAI": | |
| # Hide system_message for o1 models - currently unsupported | |
| if "system_message" in build_config: | |
| build_config["system_message"]["show"] = False | |
| elif field_name == "model_name" and not field_value.startswith("o1") and "system_message" in build_config: | |
| build_config["system_message"]["show"] = True | |
| return build_config |
🤖 Prompt for AI Agents
In src/backend/base/langflow/initial_setup/starter_projects/Instagram
Copywriter.json around lines 2794-2795, the ChatOpenAI calls use old kwargs
(model_name, openai_api_key, openai_api_base); update these calls to use the
langchain_openai 0.3.x parameter names by replacing model_name→model,
openai_api_key→api_key, and openai_api_base→base_url for both OpenAI and Aliyun
branches, and ensure streaming/temperature args remain; additionally align or
add a small compatibility mapping in the listed locations
(src/lfx/.../language_model.py, openai_chat_model.py, openrouter.py) and update
tests that assert openai_api_base to expect base_url or use the adapter so all
call sites use the new keys consistently.
| "title_case": false, | ||
| "type": "code", | ||
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[{\"icon\": \"OpenAI\"}, {\"icon\": \"Anthropic\"}, {\"icon\": \"GoogleGenerativeAI\"}],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | ||
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" |
There was a problem hiding this comment.
🛠️ Refactor suggestion
🧩 Analysis chain
Use current LangChain params: model/api_key/base_url (and Anthropic/Google api_key).
langchain_openai>=0.1 maps legacy names but the canonical (and forward‑compatible) params are model, api_key, and base_url. Likewise, ChatAnthropic and ChatGoogleGenerativeAI accept api_key. Update all branches accordingly.
Apply:
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ )
@@
- return ChatAnthropic(
- model=model_name,
- temperature=temperature,
- streaming=stream,
- anthropic_api_key=self.api_key,
- )
+ return ChatAnthropic(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ )
@@
- return ChatGoogleGenerativeAI(
- model=model_name,
- temperature=temperature,
- streaming=stream,
- google_api_key=self.api_key,
- )
+ return ChatGoogleGenerativeAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ )
@@
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ )Please confirm these signatures against the pinned versions in this template:
🌐 Web query:
What constructor parameters do these classes use in the pinned versions?
- langchain_openai ChatOpenAI 0.3.x
- langchain_anthropic ChatAnthropic 0.3.14
- langchain_google_genai ChatGoogleGenerativeAI 2.0.6
💡 Result:
-
langchain_openai ChatOpenAI (0.3.x)
- Constructor: ChatOpenAI(fields?: any, configuration?: ClientOptions & LegacyOpenAIInput)
- Common/used params: model, modelName, temperature, max_tokens / maxTokens, n, frequency_penalty, openai_api_key / api_key (or use OPENAI_API_KEY env var), use_responses_api, output_version, plus any OpenAI create-call parameters. [1][2]
-
langchain_anthropic ChatAnthropic (0.3.14)
- Constructor: ChatAnthropic(...fields) — common params include model, anthropic_api_key (or ANTHROPIC_API_KEY env var), betas (e.g., ["code-execution-..."]), mcp_servers (list), and other Anthropic-specific options; supports binding tools and runnable interface options. [3]
-
langchain_google_genai ChatGoogleGenerativeAI (2.0.6)
- Constructor: new ChatGoogleGenerativeAI(fields?: GoogleGenerativeAIChatInput)
- Common/used params: model (e.g., "gemini-pro"), maxOutputTokens / max_output_tokens, safetySettings, apiKey / GOOGLE_API_KEY env var, and other Google GenAI SDK chat input fields. [4][5]
Sources:
- langchain-openai (PyPI) package page (0.3.0) — ChatOpenAI usage. [turn2search0]
- LangChain OpenAI integration docs — ChatOpenAI notes and params. [turn2search3]
- LangChain Anthropic integration docs (features & constructor examples, web search / code-execution / MCP examples; references to 0.3.14). [turn1search0]
- langchain-google-genai (PyPI) 2.0.6 package page — ChatGoogleGenerativeAI usage. [turn1search11]
- ChatGoogleGenerativeAI docs / examples (constructor fields: model, maxOutputTokens, safetySettings). [turn1search4]
Use canonical LangChain constructor params: model / api_key / base_url (Google uses google_api_key)
- OpenAI: use model, api_key (alias openai_api_key) and base_url (alias openai_api_base). (python.langchain.com)
- Anthropic: use model and api_key. (python.langchain.com)
- Google: use model and google_api_key (do NOT replace with a generic api_key). (python.langchain.com)
Update instantiations in src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json accordingly.
🤖 Prompt for AI Agents
In src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website
Code Generator.json around line 1724, the LangChain model constructors use
non-canonical parameter names; update them to the canonical params: for OpenAI
use model=<model_name>, api_key=<self.api_key> (alias of openai_api_key) and
base_url=<openai_api_base> (alias of openai_api_base) instead of
model_name/openai_api_key/openai_api_base; for Anthropic call ChatAnthropic with
model=<model_name> and api_key=<self.api_key> (not anthropic_api_key); for
Google use ChatGoogleGenerativeAI with model=<model_name> and
google_api_key=<self.api_key> (keep google_api_key param name); for the Aliyun
branch (which reuses ChatOpenAI) pass model, api_key and
base_url=\"https://dashscope.aliyuncs.com/compatible-mode/v1\"; keep the
temperature/stream handling and reasoning-model temperature override as-is.
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
Template/UI mismatch: provider dropdown doesn’t list “Aliyun” for this node.
The component code supports Aliyun, but the template for this node’s provider field still only shows OpenAI/Anthropic/Google, so users can’t select Aliyun in this starter flow. Please add "Aliyun" and its icon to the provider options/options_metadata for this node.
Minimal JSON patch (apply to this node’s template.provider object):
- "options": ["OpenAI", "Anthropic", "Google"],
+ "options": ["OpenAI", "Anthropic", "Google", "Aliyun"],
- "options_metadata": [
- {"icon":"OpenAI"}, {"icon":"Anthropic"}, {"icon":"GoogleGenerativeAI"}
- ],
+ "options_metadata": [
+ {"icon":"OpenAI"}, {"icon":"Anthropic"}, {"icon":"GoogleGenerativeAI"}, {"icon":"Aliyun"}
+ ],Run to find other starter files with missing Aliyun in provider dropdowns:
🏁 Script executed:
#!/bin/bash
fd -a --extension json src/backend/base/langflow/initial_setup/starter_projects \
| xargs -I{} python - <<'PY'
import json,sys
p=sys.argv[1]
with open(p,encoding="utf-8") as f:
j=json.load(f)
missing=[]
for n in j.get("data",{}).get("nodes",[]):
tpl = n.get("data",{}).get("node",{}).get("template",{})
prov = tpl.get("provider") or tpl.get("agent_llm")
if isinstance(prov,dict):
opts = prov.get("options",[])
if "Aliyun" not in opts:
missing.append((n.get("id"), n.get("data",{}).get("node",{}).get("display_name")))
if missing:
print(p, "-> missing Aliyun in:", missing)
PY
{}Length of output: 571
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ROOT="src/backend/base/langflow/initial_setup/starter_projects"
if [ ! -d "$ROOT" ]; then
echo "Directory not found: $ROOT" >&2
exit 0
fi
find "$ROOT" -type f -name "*.json" -print0 | while IFS= read -r -d '' file; do
python - "$file" <<'PY'
import json,sys
p=sys.argv[1]
try:
with open(p, encoding="utf-8") as f:
j=json.load(f)
except Exception as e:
print(p, "-> JSON parse error:", e)
sys.exit(0)
missing=[]
nodes = j.get("data", {}).get("nodes", [])
for n in nodes:
tpl = n.get("data", {}).get("node", {}).get("template", {})
if isinstance(tpl, dict):
prov = tpl.get("provider") or tpl.get("agent_llm")
if isinstance(prov, dict):
opts = prov.get("options", [])
if "Aliyun" not in opts:
missing.append((n.get("id"), n.get("data", {}).get("node", {}).get("display_name")))
if missing:
print(p, "-> missing Aliyun in:", missing)
else:
print(p, "OK")
PY
doneLength of output: 5579
Template/UI mismatch: provider dropdown missing "Aliyun" in starter project templates
LanguageModel supports Aliyun but many starter JSON node templates omit "Aliyun" from provider.options and options_metadata — add "Aliyun" and its icon to each affected node's provider (or agent_llm) template.
Minimal JSON patch (apply to the node's template.provider / template.agent_llm object):
- "options": ["OpenAI", "Anthropic", "Google"],
+ "options": ["OpenAI", "Anthropic", "Google", "Aliyun"],
- "options_metadata": [
- {"icon":"OpenAI"}, {"icon":"Anthropic"}, {"icon":"GoogleGenerativeAI"}
- ],
+ "options_metadata": [
+ {"icon":"OpenAI"}, {"icon":"Anthropic"}, {"icon":"GoogleGenerativeAI"}, {"icon":"Aliyun"}
+ ],Affected files / nodes:
- src/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.json (Agent-CBCVT — "Agent")
- src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json (Agent-9FjKL — "Agent")
- src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json (Agent-9dON7 — "Agent"; EmbeddingModel-X6URU — "Embedding Model")
- src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json (Agent-R27kt — "Agent")
- src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json (Agent-03SGo — "Agent")
- src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json (Agent-bNGtH — "Agent")
- src/backend/base/langflow/initial_setup/starter_projects/Search agent.json (Agent-9JGgQ — "Agent")
- src/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.json (Agent-EQcU8 — "Finance Agent"; Agent-X1iAT — "Analysis & Editor Agent"; Agent-b7nmW — "Researcher Agent")
- src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json (Agent-D0Kx2 — "Agent")
- src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json (Agent-0vMrI — "Agent")
- src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json (Agent-RTpIN — "City Selection Agent"; Agent-9tDeE — "Local Expert Agent"; Agent-C8zRS — "Travel Concierge Agent")
- src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json (LanguageModelComponent-kPnuV; LanguageModelComponent-k0SIV; LanguageModelComponent-sPFGT — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json (LanguageModelComponent-kBOja — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json (LanguageModelComponent-1gwua — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.json (LanguageModelComponent-SCqm9 — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json (LanguageModelComponent-htMuI — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json (LanguageModelComponent-jtKdb — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json (LanguageModelComponent-CRZxx; LanguageModelComponent-MD9V5 — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json (LanguageModelComponent-t4Dhl; LanguageModelComponent-1KtUQ — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json (Agent-DYPjp — "Agent"; LanguageModelComponent-CWWr8; LanguageModelComponent-JhaTG — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Market Research.json (LanguageModelComponent-06zGA — "Language Model"; Agent-rpeeh — "Agent")
- src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json (LanguageModelComponent-cPCaH; LanguageModelComponent-mMKmF — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json (LanguageModelComponent-n8KRg — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json (LanguageModelComponent-HrqxT; LanguageModelComponent-QdlJs — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json (LanguageModelComponent-TZiUW; LanguageModelComponent-80mt4 — "Language Model"; Agent-mIgZ5 — "Agent")
- src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json (LanguageModelComponent-ze4nq — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json (LanguageModelComponent-zY7m0 — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json (LanguageModelComponent-qFXT1; LanguageModelComponent-Wp3pC; LanguageModelComponent-gYAmH — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json (LanguageModelComponent-URKKz — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json (LanguageModelComponent-nQYc0 — "Language Model")
- src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json (Agent-JRSRu — "YT-Insight"; LanguageModelComponent-OvIt5 — "Language Model")
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json
around lines 2109-2110, the provider dropdown in the template is missing the
"Aliyun" option and its icon metadata; update the template.provider (and any
template.agent_llm objects listed in the review) to include "Aliyun" in the
options array and add a corresponding entry in options_metadata (e.g.
{"icon":"Aliyun"}) so the provider list and icons match the LanguageModel
implementation; apply the same minimal change to each affected starter project
file/node named in the review.
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
Aliyun base URL kwarg: prefer base_url over openai_api_base
Same as the other starter: switch to base_url to match langchain_openai 0.3.x and avoid constructor errors.
Apply within the Aliyun branch:
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
- )
+ return ChatOpenAI(
+ model_name=model_name,
+ temperature=temperature,
+ streaming=stream,
+ openai_api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ )🌐 Web query:
Confirm ChatOpenAI kwargs in langchain_openai 0.3.23: is `base_url` the correct parameter? Are `openai_api_base` / `openai_api_key` deprecated?
💡 Result:
Short answer: Use base_url (and api_key) in langchain_openai 0.3.23 — the old names openai_api_base and openai_api_key are present as aliases (not removed) for backwards compatibility.
Details / sources:
- ChatOpenAI param docs show openai_api_base has alias 'base_url' and openai_api_key has alias 'api_key' (so base_url/api_key are the primary kwargs; the openai_api_* names remain supported). [1][2]
Sources:
[1] LangChain ChatOpenAI docs (params: openai_api_base alias 'base_url', openai_api_key alias 'api_key'). (python.langchain.com)
[2] langchain_openai chat_models base module (examples using base_url / api_key and alias docs). (python.langchain.com)
Citations:
- 1: https://python.langchain.com/api_reference/openai/chat_models/langchain_openai.chat_models.base.ChatOpenAI.html?utm_source=openai
- 2: https://python.langchain.com/api_reference/_modules/langchain_openai/chat_models/base.html?utm_source=openai
Aliyun base URL kwarg: prefer base_url over openai_api_base
Langchain 0.3.x uses base_url/api_key as the primary kwargs; replace openai_api_base with base_url to avoid constructor errors.
Apply within the Aliyun branch:
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
- )
+ return ChatOpenAI(
+ model_name=model_name,
+ temperature=temperature,
+ streaming=stream,
+ openai_api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ )📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | |
| }, | |
| from typing import Any | |
| from langchain_anthropic import ChatAnthropic | |
| from langchain_google_genai import ChatGoogleGenerativeAI | |
| from langchain_openai import ChatOpenAI | |
| from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES | |
| from lfx.base.models.anthropic_constants import ANTHROPIC_MODELS | |
| from lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS | |
| from lfx.base.models.model import LCModelComponent | |
| from lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES | |
| from lfx.field_typing import LanguageModel | |
| from lfx.field_typing.range_spec import RangeSpec | |
| from lfx.inputs.inputs import BoolInput | |
| from lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput | |
| from lfx.schema.dotdict import dotdict | |
| class LanguageModelComponent(LCModelComponent): | |
| display_name = "Language Model" | |
| description = "Runs a language model given a specified provider." | |
| documentation: str = "https://docs.langflow.org/components-models" | |
| icon = "brain-circuit" | |
| category = "models" | |
| priority = 0 # Set priority to 0 to make it appear first | |
| inputs = [ | |
| DropdownInput( | |
| name="provider", | |
| display_name="Model Provider", | |
| options=["OpenAI", "Anthropic", "Google", "Aliyun"], | |
| value="OpenAI", | |
| info="Select the model provider", | |
| real_time_refresh=True, | |
| options_metadata=[ | |
| {"icon": "OpenAI"}, | |
| {"icon": "Anthropic"}, | |
| {"icon": "GoogleGenerativeAI"}, | |
| {"icon": "Aliyun"}, | |
| ], | |
| ), | |
| DropdownInput( | |
| name="model_name", | |
| display_name="Model Name", | |
| options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES, | |
| value=OPENAI_CHAT_MODEL_NAMES[0], | |
| info="Select the model to use", | |
| real_time_refresh=True, | |
| ), | |
| SecretStrInput( | |
| name="api_key", | |
| display_name="OpenAI API Key", | |
| info="Model Provider API key", | |
| required=False, | |
| show=True, | |
| real_time_refresh=True, | |
| ), | |
| MessageInput( | |
| name="input_value", | |
| display_name="Input", | |
| info="The input text to send to the model", | |
| ), | |
| MultilineInput( | |
| name="system_message", | |
| display_name="System Message", | |
| info="A system message that helps set the behavior of the assistant", | |
| advanced=False, | |
| ), | |
| BoolInput( | |
| name="stream", | |
| display_name="Stream", | |
| info="Whether to stream the response", | |
| value=False, | |
| advanced=True, | |
| ), | |
| SliderInput( | |
| name="temperature", | |
| display_name="Temperature", | |
| value=0.1, | |
| info="Controls randomness in responses", | |
| range_spec=RangeSpec(min=0, max=1, step=0.01), | |
| advanced=True, | |
| ), | |
| ] | |
| def build_model(self) -> LanguageModel: | |
| provider = self.provider | |
| model_name = self.model_name | |
| temperature = self.temperature | |
| stream = self.stream | |
| if provider == "OpenAI": | |
| if not self.api_key: | |
| msg = "OpenAI API key is required when using OpenAI provider" | |
| raise ValueError(msg) | |
| if model_name in OPENAI_REASONING_MODEL_NAMES: | |
| # reasoning models do not support temperature (yet) | |
| temperature = None | |
| return ChatOpenAI( | |
| model_name=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| openai_api_key=self.api_key, | |
| ) | |
| if provider == "Anthropic": | |
| if not self.api_key: | |
| msg = "Anthropic API key is required when using Anthropic provider" | |
| raise ValueError(msg) | |
| return ChatAnthropic( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| anthropic_api_key=self.api_key, | |
| ) | |
| if provider == "Google": | |
| if not self.api_key: | |
| msg = "Google API key is required when using Google provider" | |
| raise ValueError(msg) | |
| return ChatGoogleGenerativeAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| google_api_key=self.api_key, | |
| ) | |
| if provider == "Aliyun": | |
| if not self.api_key: | |
| msg = "Aliyun API key is required when using Aliyun provider" | |
| raise ValueError(msg) | |
| return ChatOpenAI( | |
| model_name=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| openai_api_key=self.api_key, | |
| base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", | |
| ) | |
| msg = f"Unknown provider: {provider}" | |
| raise ValueError(msg) | |
| def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict: | |
| if field_name == "provider": | |
| if field_value == "OpenAI": | |
| build_config["model_name"]["options"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES | |
| build_config["model_name"]["value"] = OPENAI_CHAT_MODEL_NAMES[0] | |
| build_config["api_key"]["display_name"] = "OpenAI API Key" | |
| elif field_value == "Anthropic": | |
| build_config["model_name"]["options"] = ANTHROPIC_MODELS | |
| build_config["model_name"]["value"] = ANTHROPIC_MODELS[0] | |
| build_config["api_key"]["display_name"] = "Anthropic API Key" | |
| elif field_value == "Google": | |
| build_config["model_name"]["options"] = GOOGLE_GENERATIVE_AI_MODELS | |
| build_config["model_name"]["value"] = GOOGLE_GENERATIVE_AI_MODELS[0] | |
| build_config["api_key"]["display_name"] = "Google API Key" | |
| elif field_value == "Aliyun": | |
| build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES | |
| build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] | |
| build_config["api_key"]["display_name"] = "Aliyun API Key" | |
| elif field_name == "model_name" and field_value.startswith("o1") and self.provider == "OpenAI": | |
| # Hide system_message for o1 models - currently unsupported | |
| if "system_message" in build_config: | |
| build_config["system_message"]["show"] = False | |
| elif field_name == "model_name" and not field_value.startswith("o1") and "system_message" in build_config: | |
| build_config["system_message"]["show"] = True | |
| return build_config |
🤖 Prompt for AI Agents
In src/backend/base/langflow/initial_setup/starter_projects/Research Translation
Loop.json around lines 1496-1497, update the Aliyun branch in build_model to use
LangChain 0.3.x kwargs: replace openai_api_base with base_url and openai_api_key
with api_key when constructing the ChatOpenAI instance (keep model_name,
temperature, streaming as-is and set base_url to
"https://dashscope.aliyuncs.com/compatible-mode/v1").
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (28)
src/frontend/src/icons/Aliyun/Aliyun.jsx (1)
1-46: Support dark mode and forward common SVG props.
- The icon doesn’t use the required
isDarkprop.- Props aren’t forwarded to
<svg>, soclassName,width, etc., won’t work.Apply this diff (palette can be tweaked to match brand in dark mode):
-const SvgAliyun = (props) => ( - <svg +const SvgAliyun = ({ isDark = false, ...rest }) => { + const palette = isDark + ? { a: "#87a8ff", b: "#d4ccff", c: "#33e6d4", d: "#2cd0c8", e: "#a98ffe", f: "#6b7cff" } + : { a: "#1c54e3", b: "#aa9aff", c: "#00ead1", d: "#00cec9", e: "#7347ff", f: "#0423da" }; + return ( + <svg data-name="layer1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 76 76" - > + {...rest} + > <g data-name="layer1" transform="translate(4, 0)"> <g> <g> <polygon - fill="#1c54e3" + fill={palette.a} points="16.93 28.29 16.93 47.84 16.93 47.84 33.86 38.06 33.86 38.06 16.93 28.29" /> <path - fill="#aa9aff" + fill={palette.b} d="M64.71,16.77s-.02-.02-.03-.02l-13.88-8.02L16.93,28.29l16.93,9.78,30.78-17.77.05-.03c.61-.35,1.02-1,1.02-1.75s-.4-1.39-1-1.74Z" /> <path - fill="#00ead1" + fill={palette.c} d="M65.71,39.54c-.37,0-.71.1-1,.27,0,0-.02,0-.03.01,0,0,0,0,0,0l-13.88,8.02h0l16.02,9.25h.02c.56-.96.89-2.09.89-3.3,0-.02,0-.03,0-.05,0-.01,0-.03,0-.04v-12.14c0-1.11-.9-2.02-2.02-2.02Z" /> <path - fill="#00cec9" + fill={palette.d} d="M66.82,57.09l-16.02-9.25-33.86,19.55h0s13.55,7.82,13.55,7.82h0s.05.02.07.04c.98.57,2.11.89,3.32.89s2.34-.33,3.32-.89c.02-.01.05-.02.07-.04h0s27.09-15.64,27.09-15.64c.01,0,.02-.01.03-.02,1.02-.58,1.87-1.43,2.46-2.45h-.02Z" /> <path - fill="#00ead1" + fill={palette.c} d="M33.86,38.06h0s-16.93,9.78-16.93,9.78l-4.58,2.64L.91,57.09h-.02c.55.96,1.32,1.76,2.25,2.34l.25.14s0,0,0,0l.05.03.06.04,13.43,7.75h0s0,0,0,0h0s33.86-19.55,33.86-19.55h0l-16.93-9.78Z" /> <path - fill="#7347ff" + fill={palette.e} d="M37.25.91c-.32-.19-.66-.34-1-.47-.06-.02-.12-.05-.18-.07-.03-.01-.06-.02-.1-.03-.66-.22-1.38-.35-2.12-.35s-1.45.12-2.12.35c-.03.01-.06.02-.1.03-.06.02-.12.04-.18.07-.34.13-.67.28-1 .47h0L3.39,16.56s-.01,0-.02.01c-1.03.58-1.88,1.43-2.48,2.45h.02s16.02,9.26,16.02,9.26h0S50.8,8.74,50.8,8.74L37.25.91Z" /> <path - fill="#0423da" + fill={palette.f} d="M.91,19.03h-.02c-.56.96-.89,2.09-.89,3.3v31.46c0,1.2.32,2.33.89,3.31h.02s16.02-9.26,16.02-9.26h0v-19.55h0S.91,19.03.91,19.03Z" /> </g> </g> </g> </svg> -); + ); +};src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json (1)
1558-1732: Add Aliyun base_url input, set Aliyun API key default, and sync static templates
- Add StrInput import and an advanced StrInput named "base_url" (default "https://dashscope.aliyuncs.com/compatible-mode/v1") to the component inputs and use getattr(self, "base_url", None) (with the same fallback URL) when constructing ChatOpenAI for provider == "Aliyun".
- In update_build_config when field_value == "Aliyun": set build_config["api_key"]["value"] = "ALIYUN_API_KEY" and, if "base_url" exists in build_config, set build_config["base_url"]["show"] = True.
- Update static JSON templates under src/backend/base/langflow/initial_setup/starter_projects/*.json where provider.options currently list ["OpenAI","Anthropic","Google"] to include "Aliyun" and add the corresponding options_metadata entry {"icon":"Aliyun"} so the UI matches runtime behavior.
- References: runtime already supports Aliyun in src/lfx/src/lfx/components/models/language_model.py; StrInput is defined at src/lfx/src/lfx/inputs/inputs.py.
src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json (3)
1791-1825: Aliyun not selectable in UI provider dropdown.The component code supports Aliyun, but this provider list omits it; users cannot select Aliyun.
Update the node template:
- "options": ["OpenAI","Anthropic","Google"], + "options": ["OpenAI","Anthropic","Google","Aliyun"], @@ - "options_metadata": [{"icon":"OpenAI"},{"icon":"Anthropic"},{"icon":"GoogleGenerativeAI"}] + "options_metadata": [{"icon":"OpenAI"},{"icon":"Anthropic"},{"icon":"GoogleGenerativeAI"},{"icon":"Aliyun"}]
2112-2146: Second LanguageModelComponent also missing Aliyun in provider dropdown.Same issue as above; add Aliyun here too.
Apply the same options/options_metadata additions for this node.
1750-1789: Model default value not in options.
value: "claude-3-5-sonnet-latest"isn’t present in the provided options (GPT/o* only). This breaks selection/rendering.Set a valid default or leave blank:
- "value": "claude-3-5-sonnet-latest" + "value": "gpt-4o-mini"Alternatively, switch provider default to Anthropic and populate Anthropic models up front.
src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json (2)
1570-1604: Provider dropdown missing Aliyun.UI won’t expose Aliyun without adding it here.
- "options": ["OpenAI","Anthropic","Google"], + "options": ["OpenAI","Anthropic","Google","Aliyun"], @@ - "options_metadata": [{"icon":"OpenAI"},{"icon":"Anthropic"},{"icon":"Google"}] + "options_metadata": [{"icon":"OpenAI"},{"icon":"Anthropic"},{"icon":"GoogleGenerativeAI"},{"icon":"Aliyun"}]
1-1710: Centralize Aliyun API base — remove hardcoded DashScope URL.
- Provider dropdowns already include "Aliyun" (no missing entries found).
- Hardcoded openai_api_base = "https://dashscope.aliyuncs.com/compatible-mode/v1" found in:
- src/lfx/src/lfx/components/models/language_model.py:136
- src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json
- src/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.json
- src/backend/base/langflow/initial_setup/starter_projects/Market Research.json
- src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json
- src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json
- src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json
- src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json
- src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json
- src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json
- src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json
- src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json
- src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json
- src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json
- src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json
- src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json
- src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json
- src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json
- src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json
- src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json
- src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json
Action: replace each hardcoded URL with a single central constant (e.g., define ALIYUN_API_BASE in lfx.base.models.aliyun_constants and import/use it), then update the templates/JSONs to reference that constant.
src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json (2)
1698-1713: Provider dropdown missing “Aliyun” in the UI template.The UI won’t expose Aliyun because the template options still list only OpenAI/Anthropic/Google. Add "Aliyun" and its icon.
Apply this diff:
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], - "options_metadata": [ - { - "icon": "OpenAI" - }, - { - "icon": "Anthropic" - }, - { - "icon": "Google" - } - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], + "options_metadata": [ + { "icon": "OpenAI" }, + { "icon": "Anthropic" }, + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } + ],
2018-2033: Second provider dropdown also missing “Aliyun”.Mirror the change to include "Aliyun" and its icon here as well.
Apply this diff:
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], - "options_metadata": [ - { "icon": "OpenAI" }, - { "icon": "Anthropic" }, - { "icon": "Google" } - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], + "options_metadata": [ + { "icon": "OpenAI" }, + { "icon": "Anthropic" }, + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } + ],src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json (1)
1203-1238: Provider dropdown doesn’t include “Aliyun”.Without updating this template, users can’t pick Aliyun in this starter.
Apply this diff:
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], - "options_metadata": [ - { - "icon": "OpenAI" - }, - { - "icon": "Anthropic" - }, - { - "icon": "Google" - } - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], + "options_metadata": [ + { "icon": "OpenAI" }, + { "icon": "Anthropic" }, + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } + ],src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json (1)
3175-3210: Provider dropdown template missing “Aliyun”.The backend code exposes Aliyun, but the saved template’s provider.options and options_metadata omit it, blocking selection in the starter until a refresh hook runs.
Apply this minimal patch to the template block:
"options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "GoogleGenerativeAI" + "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" } ],src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json (3)
2490-2663: Aliyun base URL param name is wrong; usebase_url(notopenai_api_base) in ChatOpenAI.
langchain_openai.ChatOpenAIexpectsbase_urlfor OpenAI‑compatible endpoints. Passingopenai_api_basewill be ignored/invalid with 0.3.x and the model will try the default OpenAI URL. Fix the Aliyun branch call. (api.python.langchain.com)Apply this diff inside the LanguageModelComponent code block:
- return ChatOpenAI( - model_name=model_name, - temperature=temperature, - streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) + return ChatOpenAI( + model_name=model_name, + temperature=temperature, + streaming=stream, + openai_api_key=self.api_key, + base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", + )
2490-2663: Consider defaulting Aliyun to the international endpoint or making it configurable.US users often need the international base URL
https://dashscope-intl.aliyuncs.com/compatible-mode/v1. Either default to this for broader compatibility or add an advanced “Base URL” input to override. (alibabacloud.com)Example minimal change:
- base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", + base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",Or expose a
StrInput(advanced) to allow overriding and set region‑specific defaults inupdate_build_config.
2556-2591: Provider dropdown in this node’s template still omits “Aliyun”. Users can’t select it in this flow.The component code supports Aliyun, but this instance’s
provider.optionsonly lists OpenAI/Anthropic/Google. Add “Aliyun” and its icon to keep UI consistent with the implementation.Apply this JSON diff in the node template:
"provider": { "_input_type": "DropdownInput", "advanced": false, "combobox": false, "dialog_inputs": {}, "display_name": "Model Provider", "dynamic": false, "info": "Select the model provider", "name": "provider", "options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" } ], "placeholder": "", "real_time_refresh": true, "required": false, "show": true, "title_case": false, "toggle": false, "tool_mode": false, "trace_as_metadata": true, "type": "str", "value": "OpenAI" },src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json (2)
2860-2895: Provider dropdown missing Aliyun (UI won’t show the new option).Mirror the code changes in the template UI for this node.
Same diff as above “options”/“options_metadata” addition applies here.
2794-2968: Expose Aliyun in starter templates; centralize DashScope URL; openai_api_base is correct
- build_model/update_build_config already include Aliyun — no behavior changes needed.
- UI bug: 31 starter JSONs still omit "Aliyun" in the provider dropdowns. Update provider "options" (add "Aliyun") and options_metadata (add {"icon":"Aliyun"}) in these files:
- src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json
- src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json
- src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json
- src/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.json
- src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json
- src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json
- src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json
- src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json
- src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json
- src/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.json
- src/backend/base/langflow/initial_setup/starter_projects/Market Research.json
- src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json
- src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json
- src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json
- src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json
- src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json
- src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json
- src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json
- src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json
- src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json
- src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json
- src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json
- src/backend/base/langflow/initial_setup/starter_projects/Search agent.json
- src/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.json
- src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json
- src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json
- src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json
- src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json
- src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json
- src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json
- src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json
- Recommended refactor: extract "https://dashscope.aliyuncs.com/compatible-mode/v1" to a constant ALIYUN_OPENAI_COMPAT_BASE in lfx.base.models.aliyun_constants and import it where used (currently set as openai_api_base in src/lfx/src/lfx/components/models/language_model.py at ~line 136).
- Verified: LangChain Python ChatOpenAI accepts openai_api_base (alias base_url) — keep using openai_api_base.
src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json (1)
1430-1603: Expose Aliyun in provider dropdowns & remove misleading OPENAI_API_KEY defaults
- Provider UI: add "Aliyun" (+icon) to the provider dropdown in the Memory Chatbot starter and any other starter JSONs missing it. Apply diff below.
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { "icon": "GoogleGenerativeAI" - } + }, + { + "icon": "Aliyun" + } ],
- Default API key: remove the hardcoded "OPENAI_API_KEY" default across starter projects (set value to empty string). Example diff:
- "value": "OPENAI_API_KEY" + "value": ""
Scope: update all files under src/backend/base/langflow/initial_setup/starter_projects/*. Several files (e.g., Memory Chatbot.json, Vector Store RAG.json, YouTube Analysis.json, Twitter Thread Generator.json, Text Sentiment Analysis.json, etc.) contain OPENAI_API_KEY defaults — clear them.
Optional: centralize the Aliyun OpenAI-compat base URL into a shared ALIYUN_OPENAI_COMPAT_BASE constant and reference it (avoid hardcoded strings).
src/backend/base/langflow/initial_setup/starter_projects/Market Research.json (2)
1987-2010: Provider dropdown in template is missing “Aliyun” — users can’t select it.The static template options exclude Aliyun, so the UI can’t trigger your dynamic update_build_config path. Add Aliyun and its icon.
"name": "provider", "options": [ "OpenAI", "Anthropic", - "Google" + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "GoogleGenerativeAI" - } + "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" + } ],
1920-1991: Update ChatOpenAI constructor args for LangChain v0.3.23 compatibility
- LangChain ChatOpenAI v0.3.23 uses model=... (not model_name) and api_key=... (not openai_api_key).
- There is no top-level streaming/stream param — use stream_usage=True or pass stream options via model_kwargs/stream_options.
- Change the ChatOpenAI calls in src/backend/base/langflow/initial_setup/starter_projects/Market Research.json (build_model, ~lines 1920–1991): replace model_name=model_name → model=model_name, openai_api_key=self.api_key → api_key=self.api_key, and adjust streaming handling; or pin LangChain to a version that accepts the older arg names.
src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json (2)
1563-1597: Provider UI doesn’t expose Aliyun in this starter’s nodeThe node’s
provider.optionsomit "Aliyun" (and icon), so users can’t select it even though the code supports it.Apply:
"options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "Google" + "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" } ],
1496-1670: Fix Aliyun ChatOpenAI args to use api_key/base_urlVerified: langchain-openai 0.3.x ChatOpenAI expects api_key and base_url (not openai_api_key/openai_api_base). Update the Aliyun branch in src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json (lines 1496-1670):
- return ChatOpenAI( - model_name=model_name, - temperature=temperature, - streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) + return ChatOpenAI( + model_name=model_name, + temperature=temperature, + streaming=stream, + api_key=self.api_key, + base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", + )Also replace other ChatOpenAI calls that pass openai_api_key (e.g., the OpenAI provider branch) with api_key to avoid constructor errors.
src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json (2)
1354-1677: Usebase_url/api_keyin Aliyun branchSame issue as the other file; switch Aliyun branch to
base_urlandapi_key.Apply:
- return ChatOpenAI( - model_name=model_name, - temperature=temperature, - streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) + return ChatOpenAI( + model_name=model_name, + temperature=temperature, + streaming=stream, + api_key=self.api_key, + base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", + )
1429-1455: Expose Aliyun in provider dropdown for all three LLM nodesAll three LanguageModelComponent nodes omit "Aliyun" (and icon) in
provider.options. Add it to match the code.Example patch (apply to each shown block):
"options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "GoogleGenerativeAI" + "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" } ],Also applies to: 1752-1777, 2072-2097
src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json (2)
1047-1221: Aliyun ChatOpenAI param namesSwitch to
base_url/api_keyin the Aliyun branch to align with ChatOpenAI v0.3.x.- return ChatOpenAI( - model_name=model_name, - temperature=temperature, - streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", - ) + return ChatOpenAI( + model_name=model_name, + temperature=temperature, + streaming=stream, + api_key=self.api_key, + base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", + )
1113-1148: Provider dropdown missing AliyunAdd "Aliyun" and its icon to the
provideroptions to make the new provider selectable."options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "GoogleGenerativeAI" + "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" } ],src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json (3)
3299-3315: Aliyun missing from provider dropdown/options metadata (UI won’t expose new provider).The template still lists only OpenAI/Anthropic/Google, so users can’t select Aliyun in the UI even though the component code supports it.
Apply this diff to add Aliyun and its icon:
"options": [ "OpenAI", "Anthropic", - "Google" + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "GoogleGenerativeAI" - } + "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" + } ],
3624-3645: Repeat: provider dropdown/options metadata also missing Aliyun in this node.Same blocker as above for the second LanguageModelComponent instance.
"options": [ "OpenAI", "Anthropic", - "Google" + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "GoogleGenerativeAI" - } + "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" + } ],
3225-3230: Usebase_urlinstead ofopenai_api_basefor Aliyun ChatOpenAI calls
TheChatOpenAIconstructor in langchain_openai v0.3.23 expectsbase_url(notopenai_api_base) when overriding the endpoint. Update the Aliyun branch inbuild_model()to passbase_url="https://dashscope.aliyuncs.com/compatible-mode/v1".
♻️ Duplicate comments (5)
src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json (2)
1886-2059: Same adjustments as above for this duplicate component.
2213-2386: Same adjustments as above for this duplicate component.src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json (1)
1673-1674: Repeat the ChatOpenAI kwargs fix in the second LanguageModelComponentSame constructor/kwargs issue as above; apply the same
model/api_key/base_urlchanges here.src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json (1)
3116-3291: Duplicate LanguageModelComponent: apply the same provider dropdown fix here.This block repeats the Aliyun integration. Ensure this node’s provider template also lists Aliyun and icon.
Apply the same “options”/“options_metadata” diff as in the first node.
src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json (1)
3552-3558: Same param verification for second node.Ensure the base URL kwarg matches the installed langchain_openai version.
🧹 Nitpick comments (42)
src/frontend/src/icons/Aliyun/index.tsx (1)
5-10: Type the dark-mode prop for better DX.Expose
isDark?: booleanin the icon’s prop type; props are already forwarded.Apply:
-export const AliyunIcon = forwardRef< - SVGSVGElement, - React.PropsWithChildren<{}> ->((props, ref) => { +export const AliyunIcon = forwardRef< + SVGSVGElement, + React.PropsWithChildren<{ isDark?: boolean }> +>((props, ref) => { return <SvgAliyun ref={ref} {...props} />; });src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json (1)
2061-2234: Aliyun provider wiring: expose base URL, fix default key, sync UI.Mirror the improvements suggested for Text Sentiment Analysis:
- Add
base_urlinput (advanced, hidden unless provider == Aliyun) and use it in the Aliyun branch.- Set
api_key.value = "ALIYUN_API_KEY"when provider == Aliyun.- Update this flow’s static provider template (outside the code string) to include “Aliyun” in
optionsand{ "icon": "Aliyun" }inoptions_metadata. Consider updating instructional notes that still mention “OpenAI” only.src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json (2)
1418-1452: Provider dropdown not updated to include AliyunUI still lists only OpenAI/Anthropic/Google; add Aliyun and its icon to match code.
"options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "Google" + "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" } ],
1749-1774: Second provider dropdown also missing AliyunMirror the options/metadata fix here.
"options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { - "icon": "Google" + "icon": "GoogleGenerativeAI" + }, + { + "icon": "Aliyun" } ],src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json (3)
1078-1112: Provider dropdown/UI icons not updated for AliyunAdd Aliyun and icon; keep Google icon consistent with other places.
"options": [ - "OpenAI", - "Anthropic", - "Google" + "OpenAI", + "Anthropic", + "Google", + "Aliyun" ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, - { "icon": "GoogleGenerativeAI" } + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } ],
861-867: Note still says “Add your OpenAI API key”Make this provider-agnostic to reflect new Aliyun support.
- "description": "### 💡 Add your OpenAI API key here", + "description": "### 💡 Add your model provider API key here (OpenAI / Anthropic / Google / Aliyun)",
1046-1076: Optional: Hide system_message for all OpenAI “o” reasoning models*Currently only checks
startswith("o1"). Consider coveringo2/o3/o4families to match capabilities.- elif field_name == "model_name" and field_value.startswith("o1") and self.provider == "OpenAI": + elif field_name == "model_name" and field_value.startswith("o") and self.provider == "OpenAI":src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json (4)
1724-1725: Avoid hardcoded DashScope base; switch to a constant and usebase_urlkwarg.Use a constant from
aliyun_constantsand passbase_url(preferred inlangchain_openai>=0.3.x) instead ofopenai_api_base. This prevents drift and aligns with other providers.Apply inside the embedded code block:
-from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES +from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES, ALIYUN_OPENAI_COMPAT_BASE_URL @@ - if provider == "Aliyun": + if provider == "Aliyun": if not self.api_key: msg = "Aliyun API key is required when using Aliyun provider" raise ValueError(msg) return ChatOpenAI( model_name=model_name, temperature=temperature, streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", + openai_api_key=self.api_key, + base_url=ALIYUN_OPENAI_COMPAT_BASE_URL, )Please confirm
ChatOpenAIin your pinnedlangchain_openaiversion acceptsbase_url(and whetheropenai_api_baseis still aliased). If not, we can gate by version.
2045-2046: Repeat the Aliyun base refactor in the second LanguageModelComponent.Mirror the same constant +
base_urlchange in this duplicated component code block to avoid divergence.Same diff pattern as above within this block.
1691-1707: API key label/value mismatch.Display name says “OpenAI API Key” but the default env value is “ANTHROPIC_API_KEY”. Inconsistent and confusing.
- "display_name": "OpenAI API Key", - "value": "ANTHROPIC_API_KEY" + "display_name": "OpenAI API Key", + "value": "OPENAI_API_KEY"Note: the dynamic relabel in
update_build_configwill still adjust per provider.
709-737: Notes still reference Anthropic only.Minor UX nit: notes instruct “Add your Anthropic API key” even when Aliyun/OpenAI/Google may be used.
Make the note generic (“Add your provider API key here”) or provider‑aware.
src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json (3)
1503-1504: Unify Aliyun base handling: use constant +base_urlkwarg.Same refactor as other templates to avoid hardcoding and ensure compatibility.
Within the embedded code:
-from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES +from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES, ALIYUN_OPENAI_COMPAT_BASE_URL @@ - if provider == "Aliyun": + if provider == "Aliyun": if not self.api_key: msg = "Aliyun API key is required when using Aliyun provider" raise ValueError(msg) return ChatOpenAI( model_name=model_name, temperature=temperature, streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", + openai_api_key=self.api_key, + base_url=ALIYUN_OPENAI_COMPAT_BASE_URL, )Confirm
ChatOpenAIsupportsbase_urlfor your pinned version; if not, we’ll use the accepted kwarg for that version.
452-507: Field order key drift (store_messagevsshould_store_message).
field_orderusesstore_messagewhile the input is namedshould_store_message. Causes ordering/visibility quirks.Rename the field in
field_ordertoshould_store_message.
759-792: Docs note still mentions OpenAI only.Minor clarity nit; suggest generic provider instructions now that Aliyun is supported.
Update text to “Paste your API key in the Language Model component (OpenAI/Anthropic/Google/Aliyun).”
src/lfx/src/lfx/components/models/language_model.py (1)
127-137: Extract the Aliyun DashScope base URL into a constant;openai_api_baseis still supported (usebase_urlif preferred)LangChain 0.3.x accepts openai_api_base (alias base_url). Extract the hardcoded "https://dashscope.aliyuncs.com/compatible-mode/v1" into lfx.base.models.aliyun_constants as ALIYUN_OPENAI_COMPAT_BASE_URL and pass it (base_url preferred for clarity). (openai>=1.0.0 can introduce Azure-specific params/warnings.)
-from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES +from lfx.base.models.aliyuncs import ALIYUN_CHAT_MODEL_NAMES, ALIYUN_OPENAI_COMPAT_BASE_URL @@ - if provider == "Aliyun": + if provider == "Aliyun": if not self.api_key: msg = "Aliyun API key is required when using Aliyun provider" raise ValueError(msg) return ChatOpenAI( model_name=model_name, temperature=temperature, streaming=stream, - openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", + openai_api_key=self.api_key, + base_url=ALIYUN_OPENAI_COMPAT_BASE_URL, )src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json (4)
1137-1172: Provider dropdown JSON template still lacks AliyunThe static template options/metadata don’t include Aliyun, which causes a mismatch before dynamic refresh. Add Aliyun + icon for a consistent initial UI.
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, { "icon": "GoogleGenerativeAI" - } + }, + { + "icon": "Aliyun" + } ],
748-755: README note mentions only OpenAIBroaden the prerequisites to reflect new provider support.
- * An [OpenAI API key](https://platform.openai.com/) + * An API key for your chosen provider (OpenAI, Anthropic, Google, or Aliyun)
1562-1565: Tags: include AliyunAdd "aliyun" to improve discoverability.
"tags": [ "rag", "q-a", - "openai" + "openai", + "aliyun" ]
1071-1071: Aliyun: prefer base_url and align secret alias to ALIYUN_API_KEYLangChain Python ChatOpenAI (v0.3.x) documents base_url (openai_api_base is an alias). Replace openai_api_base with base_url="https://dashscope.aliyuncs.com/compatible-mode/v1" in the Aliyun ChatOpenAI call, and set build_config["api_key"]["value"] = "ALIYUN_API_KEY" in update_build_config when provider == "Aliyun".
Location: src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json — Aliyun branch in build_model and update_build_config.src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json (5)
2175-2210: Provider dropdown template missing AliyunMirror runtime options in the static template for initial render parity.
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, - { "icon": "GoogleGenerativeAI" } + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } ],
2430-2431: Duplicate LLM component: apply same Aliyun fixesReplicate the base URL kwarg verification and api_key alias update here as well.
- if provider == "Aliyun": + if provider == "Aliyun": if not self.api_key: msg = "Aliyun API key is required when using Aliyun provider" raise ValueError(msg) return ChatOpenAI( model_name=model_name, temperature=temperature, streaming=stream, openai_api_key=self.api_key, - openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", + openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", ) @@ - elif field_value == "Aliyun": + elif field_value == "Aliyun": build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] build_config["api_key"]["display_name"] = "Aliyun API Key" + if "value" in build_config["api_key"]: + build_config["api_key"]["value"] = "ALIYUN_API_KEY"
2496-2531: Second template block: add Aliyun to provider options/metadataKeep both Language Model nodes consistent.
- "options": [ - "OpenAI", - "Anthropic", - "Google" - ], + "options": [ + "OpenAI", + "Anthropic", + "Google", + "Aliyun" + ], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, - { "icon": "GoogleGenerativeAI" } + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } ],
941-949: README typo and provider wording
- Typo: “coimponent” → “component”.
- Mention multiple providers, not only OpenAI.
- - Add your **OpenAI API Key** to the **Language Model**s and **Agent** Components or change the provider and add your credentials. - - Add your **Tavily API Key** to the Tavily AI Search coimponent. + - Add your API key to the chosen **Language Model** provider (OpenAI, Anthropic, Google, or Aliyun) and to the **Agent** if applicable. + - Add your **Tavily API Key** to the Tavily AI Search component.
2109-2110: Aliyun integration — openai_api_base/base_url and secret alias
- langchain_openai.ChatOpenAI v0.3.x accepts openai_api_base (primary) and base_url as an alias; no change required to the current openai_api_base usage.
- Add provider-specific secret alias: when provider == "Aliyun" set build_config["api_key"]["value"] = "ALIYUN_API_KEY".
src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json (1)
850-850: Instruction note mentions only OpenAI—generalize for all providers.Apply this diff:
- "description": "# Image Sentiment Analysis\nClassify images uploaded to the Playground by sentiment.\n\n## Prerequisites\n\n* [OpenAI API Key](https://platform.openai.com/)\n\n## Quickstart\n\n1. In the **Language Model** component, add your OpenAI API key.\n\n2. Open the **Playground**, and then submit an image to the chat. \n\nThe LLM analyzes the image. The sentiment is output into a structured table according to the **Structured Output** component's Output Schema, and then parsed into a message for the Playground to display.", + "description": "# Image Sentiment Analysis\nClassify images uploaded to the Playground by sentiment.\n\n## Prerequisites\n\n* An API key for your selected provider (OpenAI/Anthropic/Google/Aliyun)\n\n## Quickstart\n\n1. In the **Language Model** component, choose a provider and add its API key.\n\n2. Open the **Playground**, and then submit an image to the chat.\n\nThe LLM analyzes the image. The sentiment is output into a structured table according to the **Structured Output** component's Output Schema, and then parsed into a message for the Playground to display.",src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json (2)
809-809: Note text: broaden from OpenAI-only to generic provider guidance.- "description": "### 💡 Add your OpenAI API key here", + "description": "### 💡 Add your API key for the selected provider here",
1067-1138: Minor: consider defaulting env var name per provider.Secret field defaults to "OPENAI_API_KEY". If the platform supports per‑provider secret keys, consider swapping to provider‑specific defaults (e.g., ALIYUN_API_KEY) in update_build_config.
- build_config["api_key"]["display_name"] = "Aliyun API Key" + build_config["api_key"]["display_name"] = "Aliyun API Key" + build_config["api_key"]["value"] = "ALIYUN_API_KEY"src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json (2)
2405-2476: Notes still say “OpenAI API key”. Generalize for multi‑provider.User guidance should not be OpenAI‑specific now that Aliyun is supported.
- "description": "### 💡 Add your OpenAI API key here 👇", + "description": "### 💡 Add your model API key here 👇",Apply to note-Sk1It, note-qmLAt, and note-UCSuM.
Also applies to: 2437-2463, 2469-2495
4927-4932: Add “aliyun” tag for discoverability."tags": [ - "openai", + "openai", + "aliyun", "astradb", "rag", "q-a" ]src/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.json (3)
2751-2764: Frontend template drift: provider/options/icons don’t include Aliyun and differ from code defaults.The serialized template still shows provider options ["OpenAI","Anthropic","Google"] with Google icon "Google" (not "GoogleGenerativeAI"), and default provider "Anthropic". The code declares options ["OpenAI","Anthropic","Google","Aliyun"] and icon "GoogleGenerativeAI". This will cause UI inconsistency.
Apply this minimal sync in the JSON template section:
"provider": { ... - "options": ["OpenAI","Anthropic","Google"], + "options": ["OpenAI","Anthropic","Google","Aliyun"], "options_metadata": [ { "icon": "OpenAI" }, { "icon": "Anthropic" }, - { "icon": "Google" } + { "icon": "GoogleGenerativeAI" }, + { "icon": "Aliyun" } ], ... - "value": "Anthropic" + "value": "OpenAI" }Optionally also update model_name/options to match initial provider or leave them to be corrected via update_build_config on first change.
2664-2680: API key label default mismatches provider default.Template sets display_name "Anthropic API Key" while the intended default provider (after sync) is "OpenAI". Either set a neutral label or align with the chosen default to reduce UX confusion.
- "display_name": "Anthropic API Key", + "display_name": "OpenAI API Key",Or: "API Key" if you prefer provider-agnostic.
2697-2698: Optional: expose a base_url override input for Aliyun/OpenAI‑compatible providers.Some Bailian tenants/regions may require custom endpoints. Consider adding a hidden/advanced text input (e.g., api_base) and wiring it to ChatOpenAI(base_url=...).
src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json (1)
2455-2473: Optional: Rename API key label/value when switching to Aliyun for clearer secrets management.
update_build_configchanges the display name to “Aliyun API Key” but keeps the stored env key value asOPENAI_API_KEY. Consider also swapping the default value (e.g.,DASHSCOPE_API_KEY) on Aliyun selection to reduce confusion for users setting secrets. Aliyun docs refer to configuring API key specifically for DashScope. (help.aliyun.com)Example tweak inside
update_build_configAliyun branch:elif field_value == "Aliyun": build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] build_config["api_key"]["display_name"] = "Aliyun API Key" + build_config["api_key"]["value"] = "DASHSCOPE_API_KEY"src/backend/base/langflow/initial_setup/starter_projects/Market Research.json (3)
805-807: Prerequisites note not updated for Aliyun.Add Aliyun API key and adjust quickstart so users know they can choose either provider.
- - **[OpenAI API Key](https://platform.openai.com/)** + - **[OpenAI API Key](https://platform.openai.com/)** or **[Aliyun Bailian (DashScope) API Key](https://bailian.console.aliyun.com/)** @@ -1. Add your **OpenAI API key** to the **OpenAI** model and **Agent** components. +1. Add your **OpenAI** or **Aliyun** API key to the **Language Model** and **Agent** components (select the matching provider).
2243-2286: Agent provider list doesn’t offer Aliyun.If Aliyun is supported in MODEL_PROVIDERS_DICT, expose it here to keep parity with LanguageModelComponent.
- MODEL_PROVIDERS_LIST = ["Anthropic", "Google Generative AI", "Groq", "OpenAI"] + MODEL_PROVIDERS_LIST = ["Anthropic", "Google Generative AI", "Groq", "OpenAI", "Aliyun"]"options": [ "Anthropic", "Google Generative AI", "Groq", - "OpenAI", + "OpenAI", + "Aliyun", "Custom" ], "options_metadata": [ { "icon": "Anthropic" }, { "icon": "GoogleGenerativeAI" }, { "icon": "Groq" }, - { "icon": "OpenAI" }, + { "icon": "OpenAI" }, + { "icon": "Aliyun" }, { "icon": "brain" } ],If Aliyun isn’t yet present in MODEL_PROVIDERS_DICT, skip this change to avoid a broken UI.
1886-1903: Optional: neutral default label for API key.Since display_name is updated dynamically per provider, consider a neutral default like “Model API Key” to avoid initial OpenAI bias in the starter.
- "display_name": "OpenAI API Key", + "display_name": "Model API Key",src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json (1)
1031-1053: Doc note still hardcodes OpenAIOptional: make this readme/provider note provider‑agnostic now that Aliyun is supported.
src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json (1)
2224-2233: Starter description mentions chaining; consider noting multi‑provider supportOptional copy tweak to reflect Aliyun support.
src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json (1)
1247-1256: Description still says “OpenAI model.”Optional: generalize to “Language Model” now that provider is selectable.
src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json (3)
3225-3230: Set provider‑specific default env var for API key in update_build_config.You change the display_name but not the default secret key name. Set it per provider for better DX.
if field_name == "provider": if field_value == "OpenAI": build_config["model_name"]["options"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES build_config["model_name"]["value"] = OPENAI_CHAT_MODEL_NAMES[0] build_config["api_key"]["display_name"] = "OpenAI API Key" + build_config["api_key"]["value"] = "OPENAI_API_KEY" elif field_value == "Anthropic": build_config["model_name"]["options"] = ANTHROPIC_MODELS build_config["model_name"]["value"] = ANTHROPIC_MODELS[0] build_config["api_key"]["display_name"] = "Anthropic API Key" + build_config["api_key"]["value"] = "ANTHROPIC_API_KEY" elif field_value == "Google": build_config["model_name"]["options"] = GOOGLE_GENERATIVE_AI_MODELS build_config["model_name"]["value"] = GOOGLE_GENERATIVE_AI_MODELS[0] build_config["api_key"]["display_name"] = "Google API Key" + build_config["api_key"]["value"] = "GOOGLE_API_KEY" elif field_value == "Aliyun": build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] build_config["api_key"]["display_name"] = "Aliyun API Key" + build_config["api_key"]["value"] = "ALIYUN_API_KEY"
2468-2469: Update notes to reflect Aliyun support.Minor UX polish so users know Aliyun keys are valid here too.
- "description": "### 💡 Add your OpenAI API key here", + "description": "### 💡 Add your OpenAI or Aliyun API key here",Also applies to: 2497-2499
3751-3752: Keep description in sync with new provider.Mention Aliyun so the starter reads accurately.
- "description": "An AI-powered meeting summary generator that transcribes and summarizes meetings using AssemblyAI and OpenAI for quick insights.", + "description": "An AI-powered meeting summary generator that transcribes and summarizes meetings using AssemblyAI and your chosen LLM provider (OpenAI/Aliyun) for quick insights.",
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
Fix ChatOpenAI kwargs for langchain_openai 0.3.x
Use model/api_key/base_url instead of legacy model_name/openai_api_key/openai_api_base to avoid runtime errors and ensure Aliyun works.
Apply this diff inside the embedded LanguageModelComponent code block:
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ )
...
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ )🌐 Web query:
Confirm ChatOpenAI (langchain_openai 0.3.23) constructor kwargs for API key and base URL. Also confirm DashScope OpenAI-compatible base URL.
💡 Result:
Short answer:
-
LangChain (langchain_openai v0.3.23) ChatOpenAI accepts api_key and base_url as constructor kwargs (if omitted it reads OPENAI_API_KEY / OPENAI_ORG_ID from env). Example (Python):
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o", api_key="sk-...", base_url="https://your.proxy.or.base.url", organization="org-id")
(You can also pass other OpenAI params; base_url is used when proxying/emulator is required). [1] -
In JS/langchain the OpenAI/ChatOpenAI client accepts a configuration object with baseURL (configuration.baseURL) and you can supply custom headers for API key if needed. [2]
-
DashScope (Alibaba Model Studio / “DashScope”) OpenAI-compatible base URLs:
- Singapore (international): https://dashscope-intl.aliyuncs.com/compatible-mode/v1
- China (Beijing / 华北2): https://dashscope.aliyuncs.com/compatible-mode/v1
Use these as your base_url (and supply the DashScope API key as api_key). [3][4]
Sources:
[1] LangChain ChatOpenAI docs. (api.python.langchain.com)
[2] LangChain JS ChatOpenAI custom URL docs. (js.langchain.com)
[3] Alibaba Cloud — How to call Qwen models using OpenAI interface (Model Studio / DashScope). (alibabacloud.com)
[4] Alibaba Cloud DashScope OpenAI-compatible embedding/chat docs. (help.aliyun.com)
Citations:
- 1: https://api.python.langchain.com/en/latest/openai/chat_models/langchain_openai.chat_models.base.ChatOpenAI.html?utm_source=openai
- 2: https://js.langchain.com/docs/integrations/chat/openai/?utm_source=openai
- 3: https://www.alibabacloud.com/help/en/model-studio/compatibility-of-openai-with-dashscope?utm_source=openai
- 4: https://help.aliyun.com/zh/dashscope/developer-reference/openai-embedding-interface?utm_source=openai
Fix ChatOpenAI kwargs for langchain_openai 0.3.x — use model / api_key / base_url
Replace legacy model_name / openai_api_key / openai_api_base to avoid runtime errors and enable DashScope/Aliyun.
File: src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json — LanguageModelComponent.build_model()
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ )
...
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ )📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | |
| }, | |
| def build_model(self) -> LanguageModel: | |
| provider = self.provider | |
| model_name = self.model_name | |
| temperature = self.temperature | |
| stream = self.stream | |
| if provider == "OpenAI": | |
| if not self.api_key: | |
| msg = "OpenAI API key is required when using OpenAI provider" | |
| raise ValueError(msg) | |
| if model_name in OPENAI_REASONING_MODEL_NAMES: | |
| # reasoning models do not support temperature (yet) | |
| temperature = None | |
| return ChatOpenAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| api_key=self.api_key, | |
| ) | |
| if provider == "Aliyun": | |
| if not self.api_key: | |
| msg = "Aliyun API key is required when using Aliyun provider" | |
| raise ValueError(msg) | |
| return ChatOpenAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| api_key=self.api_key, | |
| base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", | |
| ) | |
| # ... other providers unchanged |
🤖 Prompt for AI Agents
In src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search
RAG.json around lines 1351-1352, ChatOpenAI is constructed with legacy kwargs
(model_name, openai_api_key, openai_api_base) that are incompatible with
langchain_openai 0.3.x; update both ChatOpenAI calls (the OpenAI provider branch
and the Aliyun branch) to use the current kwarg names: model instead of
model_name, api_key instead of openai_api_key, and base_url instead of
openai_api_base (leave other args like temperature/streaming unchanged).
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | ||
| }, |
There was a problem hiding this comment.
🛠️ Refactor suggestion
🧩 Analysis chain
Aliyun wiring looks good; please verify ChatOpenAI kwarg names against langchain_openai 0.3.23.
In recent langchain_openai, ChatOpenAI typically expects api_key/base_url and model (vs openai_api_key/openai_api_base and model_name). To avoid runtime mismatches, consider aligning args; if aliases aren’t guaranteed, this can break provider selection.
Proposed tweak inside the code block for LanguageModelComponent:
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ )
...
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ )If you prefer to keep current kwargs, please confirm they’re valid aliases in 0.3.23.
To double‑check quickly:
🌐 Web query:
Does langchain_openai 0.3.23 ChatOpenAI use `api_key`/`base_url` and `model` (not `openai_api_key`/`openai_api_base` and `model_name`)?
💡 Result:
Yes. In the modern langchain_openai ChatOpenAI (including the 0.3.x line) the constructor uses api_key and base_url for client credentials and model for the model name (the older openai_api_key / openai_api_base and model_name signatures are legacy/backwards-compatible in some modules). [1][2][3]
Sources:
- LangChain Python OpenAI ChatOpenAI docs (client params: api_key, base_url; key init arg: model). [1]
- LangChain v0.1 Python docs showing model and api_key usage. [2]
- LangChain JS docs noting unified params (model, apiKey). [3]
Update ChatOpenAI kwargs to model / api_key / base_url
langchain_openai 0.3.23 expects model, api_key and base_url — replace legacy openai_api_key/openai_api_base/model_name in LanguageModelComponent.build_model (file: src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json — OpenAI and Aliyun branches).
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ )
...
- return ChatOpenAI(
- model_name=model_name,
- temperature=temperature,
- streaming=stream,
- openai_api_key=self.api_key,
- openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
- )
+ return ChatOpenAI(
+ model=model_name,
+ temperature=temperature,
+ streaming=stream,
+ api_key=self.api_key,
+ base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
+ )📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES\nfrom lfx.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom lfx.base.models.model import LCModelComponent\nfrom lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES\nfrom lfx.field_typing import LanguageModel\nfrom lfx.field_typing.range_spec import RangeSpec\nfrom lfx.inputs.inputs import BoolInput\nfrom lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom lfx.schema.dotdict import dotdict\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 priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\", \"Aliyun\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[\n {\"icon\": \"OpenAI\"},\n {\"icon\": \"Anthropic\"},\n {\"icon\": \"GoogleGenerativeAI\"},\n {\"icon\": \"Aliyun\"},\n ],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_CHAT_MODEL_NAMES[0],\n info=\"Select the model to use\",\n real_time_refresh=True,\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\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 ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n\n if model_name in OPENAI_REASONING_MODEL_NAMES:\n # reasoning models do not support temperature (yet)\n temperature = None\n\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n if provider == \"Aliyun\":\n if not self.api_key:\n msg = \"Aliyun API key is required when using Aliyun provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n elif field_value == \"Aliyun\":\n build_config[\"model_name\"][\"options\"] = ALIYUN_CHAT_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = ALIYUN_CHAT_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"Aliyun API Key\"\n elif field_name == \"model_name\" and field_value.startswith(\"o1\") and self.provider == \"OpenAI\":\n # Hide system_message for o1 models - currently unsupported\n if \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = False\n elif field_name == \"model_name\" and not field_value.startswith(\"o1\") and \"system_message\" in build_config:\n build_config[\"system_message\"][\"show\"] = True\n return build_config\n" | |
| }, | |
| from typing import Any | |
| from langchain_anthropic import ChatAnthropic | |
| from langchain_google_genai import ChatGoogleGenerativeAI | |
| from langchain_openai import ChatOpenAI | |
| from lfx.base.models.aliyun_constants import ALIYUN_CHAT_MODEL_NAMES | |
| from lfx.base.models.anthropic_constants import ANTHROPIC_MODELS | |
| from lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS | |
| from lfx.base.models.model import LCModelComponent | |
| from lfx.base.models.openai_constants import OPENAI_CHAT_MODEL_NAMES, OPENAI_REASONING_MODEL_NAMES | |
| from lfx.field_typing import LanguageModel | |
| from lfx.field_typing.range_spec import RangeSpec | |
| from lfx.inputs.inputs import BoolInput | |
| from lfx.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput | |
| from lfx.schema.dotdict import dotdict | |
| class LanguageModelComponent(LCModelComponent): | |
| display_name = "Language Model" | |
| description = "Runs a language model given a specified provider." | |
| documentation: str = "https://docs.langflow.org/components-models" | |
| icon = "brain-circuit" | |
| category = "models" | |
| priority = 0 # Set priority to 0 to make it appear first | |
| inputs = [ | |
| DropdownInput( | |
| name="provider", | |
| display_name="Model Provider", | |
| options=["OpenAI", "Anthropic", "Google", "Aliyun"], | |
| value="OpenAI", | |
| info="Select the model provider", | |
| real_time_refresh=True, | |
| options_metadata=[ | |
| {"icon": "OpenAI"}, | |
| {"icon": "Anthropic"}, | |
| {"icon": "GoogleGenerativeAI"}, | |
| {"icon": "Aliyun"}, | |
| ], | |
| ), | |
| DropdownInput( | |
| name="model_name", | |
| display_name="Model Name", | |
| options=OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES, | |
| value=OPENAI_CHAT_MODEL_NAMES[0], | |
| info="Select the model to use", | |
| real_time_refresh=True, | |
| ), | |
| SecretStrInput( | |
| name="api_key", | |
| display_name="OpenAI API Key", | |
| info="Model Provider API key", | |
| required=False, | |
| show=True, | |
| real_time_refresh=True, | |
| ), | |
| MessageInput( | |
| name="input_value", | |
| display_name="Input", | |
| info="The input text to send to the model", | |
| ), | |
| MultilineInput( | |
| name="system_message", | |
| display_name="System Message", | |
| info="A system message that helps set the behavior of the assistant", | |
| advanced=False, | |
| ), | |
| BoolInput( | |
| name="stream", | |
| display_name="Stream", | |
| info="Whether to stream the response", | |
| value=False, | |
| advanced=True, | |
| ), | |
| SliderInput( | |
| name="temperature", | |
| display_name="Temperature", | |
| value=0.1, | |
| info="Controls randomness in responses", | |
| range_spec=RangeSpec(min=0, max=1, step=0.01), | |
| advanced=True, | |
| ), | |
| ] | |
| def build_model(self) -> LanguageModel: | |
| provider = self.provider | |
| model_name = self.model_name | |
| temperature = self.temperature | |
| stream = self.stream | |
| if provider == "OpenAI": | |
| if not self.api_key: | |
| msg = "OpenAI API key is required when using OpenAI provider" | |
| raise ValueError(msg) | |
| if model_name in OPENAI_REASONING_MODEL_NAMES: | |
| # reasoning models do not support temperature (yet) | |
| temperature = None | |
| return ChatOpenAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| api_key=self.api_key, | |
| ) | |
| if provider == "Anthropic": | |
| if not self.api_key: | |
| msg = "Anthropic API key is required when using Anthropic provider" | |
| raise ValueError(msg) | |
| return ChatAnthropic( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| anthropic_api_key=self.api_key, | |
| ) | |
| if provider == "Google": | |
| if not self.api_key: | |
| msg = "Google API key is required when using Google provider" | |
| raise ValueError(msg) | |
| return ChatGoogleGenerativeAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| google_api_key=self.api_key, | |
| ) | |
| if provider == "Aliyun": | |
| if not self.api_key: | |
| msg = "Aliyun API key is required when using Aliyun provider" | |
| raise ValueError(msg) | |
| return ChatOpenAI( | |
| model=model_name, | |
| temperature=temperature, | |
| streaming=stream, | |
| api_key=self.api_key, | |
| base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", | |
| ) | |
| msg = f"Unknown provider: {provider}" | |
| raise ValueError(msg) | |
| def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict: | |
| if field_name == "provider": | |
| if field_value == "OpenAI": | |
| build_config["model_name"]["options"] = OPENAI_CHAT_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES | |
| build_config["model_name"]["value"] = OPENAI_CHAT_MODEL_NAMES[0] | |
| build_config["api_key"]["display_name"] = "OpenAI API Key" | |
| elif field_value == "Anthropic": | |
| build_config["model_name"]["options"] = ANTHROPIC_MODELS | |
| build_config["model_name"]["value"] = ANTHROPIC_MODELS[0] | |
| build_config["api_key"]["display_name"] = "Anthropic API Key" | |
| elif field_value == "Google": | |
| build_config["model_name"]["options"] = GOOGLE_GENERATIVE_AI_MODELS | |
| build_config["model_name"]["value"] = GOOGLE_GENERATIVE_AI_MODELS[0] | |
| build_config["api_key"]["display_name"] = "Google API Key" | |
| elif field_value == "Aliyun": | |
| build_config["model_name"]["options"] = ALIYUN_CHAT_MODEL_NAMES | |
| build_config["model_name"]["value"] = ALIYUN_CHAT_MODEL_NAMES[0] | |
| build_config["api_key"]["display_name"] = "Aliyun API Key" | |
| elif field_name == "model_name" and field_value.startswith("o1") and self.provider == "OpenAI": | |
| # Hide system_message for o1 models - currently unsupported | |
| if "system_message" in build_config: | |
| build_config["system_message"]["show"] = False | |
| elif field_name == "model_name" and not field_value.startswith("o1") and "system_message" in build_config: | |
| build_config["system_message"]["show"] = True | |
| return build_config |
🤖 Prompt for AI Agents
In src/backend/base/langflow/initial_setup/starter_projects/Vector Store
RAG.json around lines 3109-3110, the ChatOpenAI constructor uses legacy kwargs
(model_name, openai_api_key, openai_api_base); update the OpenAI and Aliyun
branches in LanguageModelComponent.build_model to pass model=<model_name value>,
api_key=<self.api_key>, and base_url=<base_url value> (replace
model_name->model, openai_api_key->api_key, openai_api_base->base_url) while
keeping other params (temperature, streaming) unchanged.
| @@ -0,0 +1,53 @@ | |||
| from .model_metadata import create_model_metadata | |||
There was a problem hiding this comment.
Fix import path: likely wrong module name.
Project references point to metadata.py, but this file imports from .model_metadata. This will crash at import time if model_metadata.py doesn’t exist.
Apply this diff:
-from .model_metadata import create_model_metadata
+from .metadata import create_model_metadata📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| from .model_metadata import create_model_metadata | |
| from .metadata import create_model_metadata |
🤖 Prompt for AI Agents
In src/lfx/src/lfx/base/models/aliyun_constants.py around line 1, the import
from .model_metadata is incorrect because the project uses metadata.py; update
the import to reference .metadata instead (e.g., from .metadata import
create_model_metadata) and ensure the symbol name matches what metadata.py
exports; run a quick import test or unit test to confirm the module loads.



Support Aliyun Bailian platform LLM models: https://bailian.console.aliyun.com/
Summary by CodeRabbit
New Features
Style
Chores