fix: update Google embedding models to use non-deprecated gemini-embedding-001#12613
fix: update Google embedding models to use non-deprecated gemini-embedding-001#12613octo-patch wants to merge 4 commits into
Conversation
…dding-001 (fixes langflow-ai#12277) Replace deprecated text-embedding-004 and embedding-001 models with the current gemini-embedding-001 model in the constants list and set it as the new default. Legacy models are retained as deprecated entries for backward compatibility.
WalkthroughThis PR standardizes data type handling across 26 starter project flows and updates Google Generative AI embedding models. All starter projects remove "JSON" and "Table" from ChatOutput input types, restricting accepted inputs to "Data", "DataFrame", and "Message". Related components output types are updated from "Table" to "DataFrame" and "JSON" to "Data". The Google embedding model defaults to the current Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested reviewers
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 2 warnings)
✅ Passed checks (6 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (8)
src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json (1)
55-60:⚠️ Potential issue | 🟡 MinorRefresh the serialized edge
idtoo.Line 60 updates the
targetHandle, but Line 55 still encodes the old["Data","JSON","DataFrame","Table","Message"]input types. That leaves the saved flow internally inconsistent and can break consumers that key edge identity off the serialized handle payload.🔧 Proposed fix
- "id": "reactflow__edge-Agent-9dON7{œdataTypeœ:œAgentœ,œidœ:œAgent-9dON7œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-o3obj{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-o3objœ,œinputTypesœ:[œDataœ,œJSONœ,œDataFrameœ,œTableœ,œMessageœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-Agent-9dON7{œdataTypeœ:œAgentœ,œidœ:œAgent-9dON7œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-o3obj{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-o3objœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Nvidia` Remix.json around lines 55 - 60, The serialized edge "id" string (the value starting with reactflow__edge-Agent-9dON7{…}-ChatOutput-o3obj) still encodes the old target handle inputTypes (including "JSON" and "Table") making the edge inconsistent with the updated "targetHandle" property; update that "id" value to match the new targetHandle inputTypes array (remove "JSON" and "Table" so it matches ["Data","DataFrame","Message"]) so the serialized identity and the "targetHandle" payload are consistent (ensure the embedded JSON-like fragment in the id exactly mirrors the updated targetHandle structure).src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json (1)
767-884:⚠️ Potential issue | 🟠 MajorUnwrap
Datain_process_headers()before advertisingheadersas["Data"].Line 937 narrows
headerstoData, but the embeddedAPIRequestComponent._process_headers()still only accepts rawdict/list. Any connectedDataobject will be dropped and sent as{}, so wired headers silently stop working.💡 Proposed fix
def _process_headers(self, headers: Any) -> dict: """Process the headers input into a valid dictionary.""" if headers is None: return {} + if hasattr(headers, "data"): + headers = headers.data if isinstance(headers, dict): return headers if isinstance(headers, list): return {item["key"]: item["value"] for item in headers if self._is_valid_key_value_item(item)} return {}Also applies to: 930-938
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Pokédex` Agent.json around lines 767 - 884, The headers input is declared as Data (inputs TableInput name="headers" input_types=["Data"]) but _process_headers(...) only handles dict/list and ignores Data objects; update _process_headers to unwrap Data objects (check hasattr(headers, "data") and set headers = headers.data) before processing so connected Data values aren't dropped, then continue with existing dict/list handling and validation in APIRequestComponent._process_headers.src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json (1)
111-116:⚠️ Potential issue | 🟡 MinorRegenerate this edge id to match the new handle contract.
Line 111 still embeds the old
["Data","JSON","DataFrame","Table","Message"]payload insideid, while Line 116 and the actual handle config now use["Data","DataFrame","Message"]. That leaves the saved graph internally inconsistent and can cause duplicate/recreated edges when the flow is reserialized.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Social` Media Agent.json around lines 111 - 116, The edge object's "id" value (the reactflow__edge string that references Agent-0vMrI and ChatOutput-Lgpwq) embeds an outdated handle payload including ["Data","JSON","DataFrame","Table","Message"]; regenerate this "id" to match the current handle contract used in "sourceHandle" and "targetHandle" (i.e., remove "JSON" and "Table" so the payload lists ["Data","DataFrame","Message"]) so the saved graph stays consistent and prevents duplicate/recreated edges on reserialize.src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json (1)
248-253:⚠️ Potential issue | 🟡 MinorUpdate the persisted edge id here as well.
Line 248 still contains the old
JSON/Table-inclusiveinputTypesserialization, but Line 253 narrows the actualtargetHandleto["Data","DataFrame","Message"]. Please regenerate this edge so the identifier and handle metadata stay in sync.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Twitter` Thread Generator.json around lines 248 - 253, The persisted edge id and its serialized handle are out of sync: regenerate the edge connecting LanguageModelComponent-URKKz -> ChatOutput-GgTGu so the edge identifier (e.g., the id starting with "xy-edge__LanguageModelComponent-URKKz...ChatOutput-GgTGu") reflects the updated targetHandle inputTypes of ["Data","DataFrame","Message"] instead of the old JSON/Table-inclusive list; update the "id" string and the "sourceHandle"/"targetHandle" serialization to match the narrowed inputTypes so identifier metadata and handle metadata remain consistent for the LanguageModelComponent-URKKz -> ChatOutput-GgTGu edge.src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json (1)
43-61:⚠️ Potential issue | 🟡 MinorUpdate the parser-facing copy after the
Data/DataFramemigration.These edges and outputs now expose
Data/DataFrame, but the connectedparser.input_datafield still says"JSON or Table"at Line 964 and still advertisesJSON/Tablein its allowed types. The flow should still run, but the starter project now shows stale guidance right next to the migrated wiring.Also applies to: 1133-1150
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Image` Sentiment Analysis.json around lines 43 - 61, The parser-facing label and allowed types for the parser node need updating: find the parser node with id "parser-IFSS9" and fieldName "input_data" (edges connected from "StructuredOutput-e4qlS") and change its human-facing copy from "JSON or Table" to reflect the migrated types (e.g., "Data or DataFrame"), and update the allowed inputTypes array to include "Data" and "DataFrame" instead of "JSON" and "Table" so the UI/copy matches the actual wiring; make the same change for the other parser instances that reference parser.* input_data fields connected to StructuredOutput nodes.src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json (1)
70-88:⚠️ Potential issue | 🟡 MinorUpdate the downstream Parser snapshot to the same contract.
This handoff now emits
Data, but the Parser node metadata later in the file still showsdisplay_name: "JSON or Table"and accepts["DataFrame", "Table", "Data", "JSON"]at Lines 2900-2908. That means the starter Flow still exposes the deprecated types even after this migration.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Meeting` Summary.json around lines 70 - 88, The Parser node snapshot (parser-6bJ9b / display_name "JSON or Table") still lists deprecated types ["DataFrame","Table","Data","JSON"] while the upstream AssemblyAITranscriptionJobPoller now emits only "Data"; update the Parser node metadata (parser-6bJ9b) to match the new contract by changing its display_name and inputTypes to accept the "Data" type (and any other currently supported canonical type if needed) so the starter Flow no longer exposes the deprecated types.src/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.json (1)
171-176:⚠️ Potential issue | 🟡 MinorRegenerate this edge id to match the narrowed
targetHandlemetadata.The edge at line 171 still encodes the old
inputTypes(Data,JSON,DataFrame,Table,Message) in itsidpayload, while line 176 anddata.targetHandlenow advertise onlyData,DataFrame,Message. This creates an internal inconsistency where the serialized edge identity no longer matches the handle metadata. To keep this starter project asset properly synchronized, please re-export it so all three fields stay in sync.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Custom` Component Generator.json around lines 171 - 176, The serialized edge "id" for the edge connecting source LanguageModelComponent-SCqm9 to target ChatOutput-VoIob must be regenerated so its embedded payload's inputTypes matches the narrowed targetHandle metadata (Data, DataFrame, Message); update/re-export the edge so the "id" string, the "targetHandle" object and any "data.targetHandle" all encode the same inputTypes and fieldName/ids (refer to the existing id string that embeds the payload and the sourceHandle/targetHandle entries for LanguageModelComponent-SCqm9 and ChatOutput-VoIob) and re-export the starter project asset so these three locations remain synchronized.src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json (1)
139-144:⚠️ Potential issue | 🟡 MinorEdge ID contains stale inputTypes metadata.
The edge
idat line 139 still encodes the old type list includingJSONandTable:...œinputTypesœ:[œDataœ,œJSONœ,œDataFrameœ,œTableœ,œMessageœ]...However, the actual
targetHandlefield (line 144) anddata.targetHandle.inputTypes(lines 131-135) have been correctly updated to["Data", "DataFrame", "Message"].This inconsistency could cause issues with edge matching or validation logic that relies on the encoded ID content. Consider regenerating the edge ID to match the updated metadata.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Travel` Planning Agents.json around lines 139 - 144, The edge id string for the edge with id starting "reactflow__edge-Agent-C8zRS{…}-ChatOutput-TzFZY" contains stale encoded metadata (inputTypes includes JSON and Table) that no longer matches the updated targetHandle/data.targetHandle.inputTypes (["Data","DataFrame","Message"]); update/regenerate that edge id so its embedded metadata reflects the current targetHandle.inputTypes—either reconstruct the id value to use the same inputTypes ordering and values as data.targetHandle/inputTypes or call the same ID-generation routine used elsewhere so the encoded metadata and the targetHandle/data.targetHandle.inputTypes are identical.
🧹 Nitpick comments (6)
src/lfx/src/lfx/components/google/google_generative_ai_embeddings.py (1)
32-32: Centralize the default embedding model to avoid drift.Please consider sourcing this default from
src/lfx/src/lfx/base/models/google_generative_ai_constants.py(the metadata entry withdefault=True) instead of hardcoding the string here. This prevents future mismatch between constants and component defaults.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lfx/src/lfx/components/google/google_generative_ai_embeddings.py` at line 32, Replace the hardcoded default string in MessageTextInput(name="model_name", ...) with the centralized default from the constants module: import the embedding-model default defined in google_generative_ai_constants.py (the metadata entry marked default=True) and use that constant as the value for the model_name input so the component reads its default from the shared constant instead of a literal.src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json (1)
88-88: Keep edge metadata fully consistent after input-type edits.Line 88 updates
targetHandle, but Line 83’s edgeidstill embeds the oldJSON/Tableinput types. Please regenerate this edge ID string to match current handle metadata.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Basic` Prompting.json at line 88, The edge metadata is inconsistent: the targetHandle value was updated to include inputTypes [Data, DataFrame, Message] but the corresponding edge "id" still encodes the old JSON/Table types; update/regenerate the edge "id" string so it encodes the same handle metadata as targetHandle (i.e., reflect œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ]) and ensure any embedded fieldName/input_value/type fragments match exactly; locate the JSON object with keys "targetHandle" and the edge "id" in Basic Prompting.json and replace the old id token (e.g., ChatOutput-yK0AU) with a regenerated id that serializes the current handle metadata.src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json (1)
111-116: Regenerate the serialized edge IDs to match the new handle types.Line 111 and Line 169 still embed the old
JSON/Tablehandle signature even though the updatedtargetHandlestrings no longer do. That leaves the same edge serialized inconsistently and makes future import/export or diff logic brittle.Also applies to: 169-174
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Text` Sentiment Analysis.json around lines 111 - 116, The serialized edge id values embed an outdated handle signature (including JSON/Table) and must be regenerated to match the updated handle strings; locate the edge entries whose id begins with "reactflow__edge-LanguageModelComponent-ZLKtg" (the same edge that references source "LanguageModelComponent-ZLKtg" and target "ChatOutput-h5fAd") and update their "id" fields so the embedded handle payload matches the current "sourceHandle" and "targetHandle" strings (remove JSON/Table from the embedded inputTypes and output_types to reflect the new handles), and make the identical change for the duplicate occurrences around the second block noted (the entries around the same reactflow__edge... pattern at the later section).src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json (1)
960-967: Use the canonicalDataFramecasing for the Message History output label.The output type is
DataFrame, but the visible label isDataframe. Keeping the label consistent avoids a small but recurring mismatch in the starter flow UI.Also applies to: 992-992
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Memory` Chatbot.json around lines 960 - 967, The visible label for the Message History output uses the wrong casing ("Dataframe"); update the "display_name" value to the canonical "DataFrame" wherever the node has "name": "dataframe" or "method": "retrieve_messages_dataframe" (including the other occurrence noted) so the UI label matches the "selected": "DataFrame" output type.src/backend/base/langflow/initial_setup/starter_projects/Market Research.json (2)
1921-1926: Consider updatingbase_classesfor consistency.The
base_classesarray still includes"JSON"and"Table"types, while the actual output types (lines 1977-1996) have been updated to only"Data"and"DataFrame".If these legacy types are kept for backward compatibility with existing flows, this is fine. Otherwise, consider aligning
base_classeswith the updated output types.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Market` Research.json around lines 1921 - 1926, The "base_classes" array still contains legacy entries ("JSON", "Table") that don't match the updated output types in this JSON object; update the "base_classes" field to only include the current output types ("Data" and "DataFrame") to keep them consistent (or explicitly document/retain the legacy entries if backward compatibility is required). Locate the "base_classes" property in this starter project JSON and either remove "JSON" and "Table" or add a short comment/flag indicating compatibility if you must keep them.
83-88: Minor inconsistency: Edge ID contains stale type references.The edge
idat line 83 still referencesJSONandTabletypes, while the actualtargetHandleat line 88 has been correctly updated to["Data", "DataFrame", "Message"]. The same pattern occurs at line 140 vs lines 143-145.This doesn't affect functionality since React Flow uses the actual handle data for connections, but creates a mismatch between the ID string and the current state.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/backend/base/langflow/initial_setup/starter_projects/Market` Research.json around lines 83 - 88, Edge id strings for the connections between ParserComponent-8lfAE and ChatOutput-tjFWM contain stale type names ("JSON", "Table") that no longer match the actual sourceHandle/targetHandle inputTypes; update the edge "id" values (the strings like xy-edge__ParserComponent-8lfAE{...}-ChatOutput-tjFWM{...}) to reflect the current handle contents (use ["Data","DataFrame","Message"] and remove "JSON"/"Table") for both occurrences involving ParserComponent-8lfAE and ChatOutput-tjFWM so the id string matches the sourceHandle/targetHandle payloads.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/backend/base/langflow/initial_setup/starter_projects/Blog` Writer.json:
- Around line 71-89: The serialized edge IDs still embed old handle metadata
(e.g., the edge id starting with
"reactflow__edge-URLComponent-DFXG5...-ParserComponent-YRRd0" and the
corresponding "sourceHandle" and "targetHandle" entries) that reference
Table/JSON; regenerate those edge id strings to reflect the current handle types
(DataFrame and Data) so the id, sourceHandle and targetHandle are consistent;
update any other similar edge entries (the other occurrence referenced around
the same block) so no saved graph contains conflicting type metadata.
- Around line 880-890: update_build_config in ParserComponent uses self.mode and
a truthy check on field_value so UI lags and clean_data gets added for both
"Parser" and "Stringify"; change it to explicitly compare field_value to
"Parser" (e.g., is_parser = field_value == "Parser") and use is_parser to set
build_config["pattern"]["show"] and ["required"] as well as to add or pop the
clean_data BoolInput; ensure when field_value is not "Parser" you
pop("clean_data", None) so the clean_data input is removed when switching to
"Stringify".
In `@src/backend/base/langflow/initial_setup/starter_projects/Financial` Report
Parser.json:
- Line 89: The serialized metadata for ChatOutput.input_value and the connected
edge targetHandle are out of date: update the persisted field block for
ChatOutput.input_value (currently showing _input_type: "MessageInput" and type:
"str") to reflect the new HandleInput(["Data","DataFrame","Message"]) shape (set
the input type to the widened handle and set type to "other" where appropriate),
and regenerate the connected edge metadata so targetHandle.type becomes other
instead of str; search for occurrences of ChatOutput.input_value, targetHandle,
and any _input_type: "MessageInput" entries in the JSON and replace them with
the regenerated metadata matching HandleInput(["Data","DataFrame","Message"]).
In `@src/backend/base/langflow/initial_setup/starter_projects/Instagram`
Copywriter.json:
- Line 61: The ChatOutput node snapshot is inconsistent: the embedded code was
changed to use HandleInput(["Data","DataFrame","Message"]) but serialized
metadata still treats input_value as MessageInput/str in fields like
targetHandle and other occurrences (e.g., the serialized entries around
ChatOutput, input_value at lines referenced); regenerate the ChatOutput snapshot
so all serialized metadata (targetHandle, input_value, and any other stored
field types) reflect the new HandleInput accepted types end-to-end, ensuring the
node’s stored contract matches the new handler and replacing outdated
MessageInput/str typings throughout the JSON for the ChatOutput node.
In `@src/backend/base/langflow/initial_setup/starter_projects/Meeting`
Summary.json:
- Around line 57-59: The exported edge metadata has mismatched IDs after
handle-type changes: update the encoded id strings inside the
sourceHandle/targetHandle payloads so they reflect the new Data/DataFrame handle
types (e.g., replace old JSON/Table signatures embedded in the ids for
AssemblyAITranscriptionJobCreator-Nu1dV and
AssemblyAITranscriptionJobPoller-sCJsy and the other listed node ids) to match
the current handle type encoding; regenerate the edge ids for each affected edge
(those referencing sourceHandle/targetHandle entries at the noted lines) so the
id value's signature portion matches its handle's output_types/inputTypes
(Data/DataFrame) to remove the contradictory metadata.
In `@src/backend/base/langflow/initial_setup/starter_projects/Price` Deal
Finder.json:
- Line 104: The ChatOutput snapshot is out of sync: update the full ChatOutput
JSON (not just the targetHandle string) so its structured metadata matches the
new connector contract; specifically, regenerate the ChatOutput object so
targetHandle reflects {fieldName: "input_value", id: "ChatOutput-ykhew",
inputTypes: ["Data","DataFrame","Message"], type: "other"} and ensure
ChatOutput.template.input_value is switched from a serialized MessageInput/str
to a HandleInput/other representation consistent with the new
["Data","DataFrame","Message"] contract (update any related edge metadata
entries and IDs in the Price Deal Finder JSON to match the regenerated
ChatOutput).
In `@src/backend/base/langflow/initial_setup/starter_projects/Search` agent.json:
- Line 29: The starter-project flow narrowed ChatOutput.input_value to only
Data/DataFrame/Message but the source component ChatOutput (in
src/lfx/src/lfx/components/input_output/chat_output.py) still declares JSON and
Table as accepted types; to keep them aligned either update the source
ChatOutput to remove JSON and Table from its accepted input types (so the
component's contract matches the starter project's targetHandle) or revert the
starter-project metadata to include the full five-type contract until the source
component is migrated; locate the ChatOutput class in chat_output.py and change
its input type list (the component contract used by setup.py's template["code"]
refresh) to match the starter-project, and ensure any references to targetHandle
in the starter-project JSON remain consistent.
In `@src/backend/base/langflow/initial_setup/starter_projects/SEO` Keyword
Generator.json:
- Line 60: The serialized targetHandle value is malformed because it uses œ
characters instead of standard double quotes; locate the property named
"targetHandle" in the SEO Keyword Generator starter project and replace the œ
characters with standard double quotes to produce valid JSON (e.g.,
"{\"fieldName\": \"input_value\", \"id\": \"ChatOutput-S7Bzs\", \"inputTypes\":
[\"Data\", \"DataFrame\", \"Message\"], \"type\": \"str\"}") so the string is
proper JSON and can be parsed/deserialized correctly.
In `@src/backend/base/langflow/initial_setup/starter_projects/Sequential` Tasks
Agents.json:
- Line 3032: The starter project JSON is out of sync with updated component
exports: embedded outputs were renamed to Data/DataFrame but earlier snapshots
still advertise JSON/Table and the source components still export old labels;
update the source components that define the outputs (e.g., the
classes/components that previously exposed JSON/Table) to export the new
Data/DataFrame names, update any export lists or identifiers in those modules,
then regenerate the Sequential Tasks Agents.json snapshot so the embedded
outputs in YfinanceComponent (YfinanceComponent.outputs,
fetch_content_dataframe, fetch_content, _yahoo_finance_tool) and related
components reflect Data/DataFrame consistently across the file and the source
modules; finally re-run the exporter that produces the starter project JSON to
produce a consistent snapshot.
---
Outside diff comments:
In `@src/backend/base/langflow/initial_setup/starter_projects/Custom` Component
Generator.json:
- Around line 171-176: The serialized edge "id" for the edge connecting source
LanguageModelComponent-SCqm9 to target ChatOutput-VoIob must be regenerated so
its embedded payload's inputTypes matches the narrowed targetHandle metadata
(Data, DataFrame, Message); update/re-export the edge so the "id" string, the
"targetHandle" object and any "data.targetHandle" all encode the same inputTypes
and fieldName/ids (refer to the existing id string that embeds the payload and
the sourceHandle/targetHandle entries for LanguageModelComponent-SCqm9 and
ChatOutput-VoIob) and re-export the starter project asset so these three
locations remain synchronized.
In `@src/backend/base/langflow/initial_setup/starter_projects/Image` Sentiment
Analysis.json:
- Around line 43-61: The parser-facing label and allowed types for the parser
node need updating: find the parser node with id "parser-IFSS9" and fieldName
"input_data" (edges connected from "StructuredOutput-e4qlS") and change its
human-facing copy from "JSON or Table" to reflect the migrated types (e.g.,
"Data or DataFrame"), and update the allowed inputTypes array to include "Data"
and "DataFrame" instead of "JSON" and "Table" so the UI/copy matches the actual
wiring; make the same change for the other parser instances that reference
parser.* input_data fields connected to StructuredOutput nodes.
In `@src/backend/base/langflow/initial_setup/starter_projects/Meeting`
Summary.json:
- Around line 70-88: The Parser node snapshot (parser-6bJ9b / display_name "JSON
or Table") still lists deprecated types ["DataFrame","Table","Data","JSON"]
while the upstream AssemblyAITranscriptionJobPoller now emits only "Data";
update the Parser node metadata (parser-6bJ9b) to match the new contract by
changing its display_name and inputTypes to accept the "Data" type (and any
other currently supported canonical type if needed) so the starter Flow no
longer exposes the deprecated types.
In `@src/backend/base/langflow/initial_setup/starter_projects/Nvidia` Remix.json:
- Around line 55-60: The serialized edge "id" string (the value starting with
reactflow__edge-Agent-9dON7{…}-ChatOutput-o3obj) still encodes the old target
handle inputTypes (including "JSON" and "Table") making the edge inconsistent
with the updated "targetHandle" property; update that "id" value to match the
new targetHandle inputTypes array (remove "JSON" and "Table" so it matches
["Data","DataFrame","Message"]) so the serialized identity and the
"targetHandle" payload are consistent (ensure the embedded JSON-like fragment in
the id exactly mirrors the updated targetHandle structure).
In `@src/backend/base/langflow/initial_setup/starter_projects/Pokédex` Agent.json:
- Around line 767-884: The headers input is declared as Data (inputs TableInput
name="headers" input_types=["Data"]) but _process_headers(...) only handles
dict/list and ignores Data objects; update _process_headers to unwrap Data
objects (check hasattr(headers, "data") and set headers = headers.data) before
processing so connected Data values aren't dropped, then continue with existing
dict/list handling and validation in APIRequestComponent._process_headers.
In `@src/backend/base/langflow/initial_setup/starter_projects/Social` Media
Agent.json:
- Around line 111-116: The edge object's "id" value (the reactflow__edge string
that references Agent-0vMrI and ChatOutput-Lgpwq) embeds an outdated handle
payload including ["Data","JSON","DataFrame","Table","Message"]; regenerate this
"id" to match the current handle contract used in "sourceHandle" and
"targetHandle" (i.e., remove "JSON" and "Table" so the payload lists
["Data","DataFrame","Message"]) so the saved graph stays consistent and prevents
duplicate/recreated edges on reserialize.
In `@src/backend/base/langflow/initial_setup/starter_projects/Travel` Planning
Agents.json:
- Around line 139-144: The edge id string for the edge with id starting
"reactflow__edge-Agent-C8zRS{…}-ChatOutput-TzFZY" contains stale encoded
metadata (inputTypes includes JSON and Table) that no longer matches the updated
targetHandle/data.targetHandle.inputTypes (["Data","DataFrame","Message"]);
update/regenerate that edge id so its embedded metadata reflects the current
targetHandle.inputTypes—either reconstruct the id value to use the same
inputTypes ordering and values as data.targetHandle/inputTypes or call the same
ID-generation routine used elsewhere so the encoded metadata and the
targetHandle/data.targetHandle.inputTypes are identical.
In `@src/backend/base/langflow/initial_setup/starter_projects/Twitter` Thread
Generator.json:
- Around line 248-253: The persisted edge id and its serialized handle are out
of sync: regenerate the edge connecting LanguageModelComponent-URKKz ->
ChatOutput-GgTGu so the edge identifier (e.g., the id starting with
"xy-edge__LanguageModelComponent-URKKz...ChatOutput-GgTGu") reflects the updated
targetHandle inputTypes of ["Data","DataFrame","Message"] instead of the old
JSON/Table-inclusive list; update the "id" string and the
"sourceHandle"/"targetHandle" serialization to match the narrowed inputTypes so
identifier metadata and handle metadata remain consistent for the
LanguageModelComponent-URKKz -> ChatOutput-GgTGu edge.
---
Nitpick comments:
In `@src/backend/base/langflow/initial_setup/starter_projects/Basic`
Prompting.json:
- Line 88: The edge metadata is inconsistent: the targetHandle value was updated
to include inputTypes [Data, DataFrame, Message] but the corresponding edge "id"
still encodes the old JSON/Table types; update/regenerate the edge "id" string
so it encodes the same handle metadata as targetHandle (i.e., reflect
œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ]) and ensure any embedded
fieldName/input_value/type fragments match exactly; locate the JSON object with
keys "targetHandle" and the edge "id" in Basic Prompting.json and replace the
old id token (e.g., ChatOutput-yK0AU) with a regenerated id that serializes the
current handle metadata.
In `@src/backend/base/langflow/initial_setup/starter_projects/Market`
Research.json:
- Around line 1921-1926: The "base_classes" array still contains legacy entries
("JSON", "Table") that don't match the updated output types in this JSON object;
update the "base_classes" field to only include the current output types ("Data"
and "DataFrame") to keep them consistent (or explicitly document/retain the
legacy entries if backward compatibility is required). Locate the "base_classes"
property in this starter project JSON and either remove "JSON" and "Table" or
add a short comment/flag indicating compatibility if you must keep them.
- Around line 83-88: Edge id strings for the connections between
ParserComponent-8lfAE and ChatOutput-tjFWM contain stale type names ("JSON",
"Table") that no longer match the actual sourceHandle/targetHandle inputTypes;
update the edge "id" values (the strings like
xy-edge__ParserComponent-8lfAE{...}-ChatOutput-tjFWM{...}) to reflect the
current handle contents (use ["Data","DataFrame","Message"] and remove
"JSON"/"Table") for both occurrences involving ParserComponent-8lfAE and
ChatOutput-tjFWM so the id string matches the sourceHandle/targetHandle
payloads.
In `@src/backend/base/langflow/initial_setup/starter_projects/Memory`
Chatbot.json:
- Around line 960-967: The visible label for the Message History output uses the
wrong casing ("Dataframe"); update the "display_name" value to the canonical
"DataFrame" wherever the node has "name": "dataframe" or "method":
"retrieve_messages_dataframe" (including the other occurrence noted) so the UI
label matches the "selected": "DataFrame" output type.
In `@src/backend/base/langflow/initial_setup/starter_projects/Text` Sentiment
Analysis.json:
- Around line 111-116: The serialized edge id values embed an outdated handle
signature (including JSON/Table) and must be regenerated to match the updated
handle strings; locate the edge entries whose id begins with
"reactflow__edge-LanguageModelComponent-ZLKtg" (the same edge that references
source "LanguageModelComponent-ZLKtg" and target "ChatOutput-h5fAd") and update
their "id" fields so the embedded handle payload matches the current
"sourceHandle" and "targetHandle" strings (remove JSON/Table from the embedded
inputTypes and output_types to reflect the new handles), and make the identical
change for the duplicate occurrences around the second block noted (the entries
around the same reactflow__edge... pattern at the later section).
In `@src/lfx/src/lfx/components/google/google_generative_ai_embeddings.py`:
- Line 32: Replace the hardcoded default string in
MessageTextInput(name="model_name", ...) with the centralized default from the
constants module: import the embedding-model default defined in
google_generative_ai_constants.py (the metadata entry marked default=True) and
use that constant as the value for the model_name input so the component reads
its default from the shared constant instead of a literal.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 3d5b9152-37cc-4ebc-ad45-9e3274212640
📒 Files selected for processing (32)
src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Blog Writer.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Document Q&A.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Market Research.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.jsonsrc/backend/base/langflow/initial_setup/starter_projects/News Aggregator.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Research Agent.jsonsrc/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.jsonsrc/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Search agent.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Simple Agent.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.jsonsrc/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.jsonsrc/lfx/src/lfx/_assets/component_index.jsonsrc/lfx/src/lfx/base/models/google_generative_ai_constants.pysrc/lfx/src/lfx/components/google/google_generative_ai_embeddings.py
| "DataFrame" | ||
| ] | ||
| }, | ||
| "targetHandle": { | ||
| "fieldName": "input_data", | ||
| "id": "ParserComponent-YRRd0", | ||
| "inputTypes": [ | ||
| "DataFrame", | ||
| "Table", | ||
| "Data", | ||
| "JSON" | ||
| "Data" | ||
| ], | ||
| "type": "other" | ||
| } | ||
| }, | ||
| "id": "reactflow__edge-URLComponent-DFXG5{œdataTypeœ:œURLComponentœ,œidœ:œURLComponent-DFXG5œ,œnameœ:œpage_resultsœ,œoutput_typesœ:[œTableœ]}-ParserComponent-YRRd0{œfieldNameœ:œinput_dataœ,œidœ:œParserComponent-YRRd0œ,œinputTypesœ:[œDataFrameœ,œTableœ,œDataœ,œJSONœ],œtypeœ:œotherœ}", | ||
| "selected": false, | ||
| "source": "URLComponent-DFXG5", | ||
| "sourceHandle": "{œdataTypeœ: œURLComponentœ, œidœ: œURLComponent-DFXG5œ, œnameœ: œpage_resultsœ, œoutput_typesœ: [œTableœ]}", | ||
| "sourceHandle": "{œdataTypeœ: œURLComponentœ, œidœ: œURLComponent-DFXG5œ, œnameœ: œpage_resultsœ, œoutput_typesœ: [œDataFrameœ]}", | ||
| "target": "ParserComponent-YRRd0", | ||
| "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œParserComponent-YRRd0œ, œinputTypesœ: [œDataFrameœ, œTableœ, œDataœ, œJSONœ], œtypeœ: œotherœ}" | ||
| "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œParserComponent-YRRd0œ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" |
There was a problem hiding this comment.
Regenerate the serialized edge IDs after changing handle types.
Line 84 and Line 142 still embed the old Table/JSON handle metadata even though the persisted sourceHandle/targetHandle objects now advertise DataFrame/Data only. Please rewrite those IDs so the saved graph does not carry conflicting type information.
Also applies to: 134-147
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/backend/base/langflow/initial_setup/starter_projects/Blog` Writer.json
around lines 71 - 89, The serialized edge IDs still embed old handle metadata
(e.g., the edge id starting with
"reactflow__edge-URLComponent-DFXG5...-ParserComponent-YRRd0" and the
corresponding "sourceHandle" and "targetHandle" entries) that reference
Table/JSON; regenerate those edge id strings to reflect the current handle types
(DataFrame and Data) so the id, sourceHandle and targetHandle are consistent;
update any other similar edge entries (the other occurrence referenced around
the same block) so no saved graph contains conflicting type metadata.
| "value": "from lfx.custom.custom_component.component import Component\nfrom lfx.helpers.data import safe_convert\nfrom lfx.inputs.inputs import BoolInput, HandleInput, MessageTextInput, MultilineInput, TabInput\nfrom lfx.schema.data import Data\nfrom lfx.schema.dataframe import DataFrame\nfrom lfx.schema.message import Message\nfrom lfx.template.field.base import Output\n\n\nclass ParserComponent(Component):\n display_name = \"Parser\"\n description = \"Extracts text using a template.\"\n documentation: str = \"https://docs.langflow.org/parser\"\n icon = \"braces\"\n\n inputs = [\n HandleInput(\n name=\"input_data\",\n display_name=\"Data or DataFrame\",\n input_types=[\"DataFrame\", \"Data\"],\n info=\"Accepts either a DataFrame or a Data object.\",\n required=True,\n ),\n TabInput(\n name=\"mode\",\n display_name=\"Mode\",\n options=[\"Parser\", \"Stringify\"],\n value=\"Parser\",\n info=\"Convert into raw string instead of using a template.\",\n real_time_refresh=True,\n ),\n MultilineInput(\n name=\"pattern\",\n display_name=\"Template\",\n info=(\n \"Use variables within curly brackets to extract column values for DataFrames \"\n \"or key values for Data.\"\n \"For example: `Name: {Name}, Age: {Age}, Country: {Country}`\"\n ),\n value=\"Text: {text}\", # Example default\n dynamic=True,\n show=True,\n required=True,\n ),\n MessageTextInput(\n name=\"sep\",\n display_name=\"Separator\",\n advanced=True,\n value=\"\\n\",\n info=\"String used to separate rows/items.\",\n ),\n ]\n\n outputs = [\n Output(\n display_name=\"Parsed Text\",\n name=\"parsed_text\",\n info=\"Formatted text output.\",\n method=\"parse_combined_text\",\n ),\n ]\n\n def update_build_config(self, build_config, field_value, field_name=None):\n \"\"\"Dynamically hide/show `template` and enforce requirement based on `stringify`.\"\"\"\n if field_name == \"mode\":\n build_config[\"pattern\"][\"show\"] = self.mode == \"Parser\"\n build_config[\"pattern\"][\"required\"] = self.mode == \"Parser\"\n if field_value:\n clean_data = BoolInput(\n name=\"clean_data\",\n display_name=\"Clean Data\",\n info=(\n \"Enable to clean the data by removing empty rows and lines \"\n \"in each cell of the DataFrame/ Data object.\"\n ),\n value=True,\n advanced=True,\n required=False,\n )\n build_config[\"clean_data\"] = clean_data.to_dict()\n else:\n build_config.pop(\"clean_data\", None)\n\n return build_config\n\n def _clean_args(self):\n \"\"\"Prepare arguments based on input type.\"\"\"\n input_data = self.input_data\n\n match input_data:\n case list() if all(isinstance(item, Data) for item in input_data):\n msg = \"List of Data objects is not supported.\"\n raise ValueError(msg)\n case DataFrame():\n return input_data, None\n case Data():\n return None, input_data\n case dict() if \"data\" in input_data:\n try:\n if \"columns\" in input_data: # Likely a DataFrame\n return DataFrame.from_dict(input_data), None\n # Likely a Data object\n return None, Data(**input_data)\n except (TypeError, ValueError, KeyError) as e:\n msg = f\"Invalid structured input provided: {e!s}\"\n raise ValueError(msg) from e\n case _:\n msg = f\"Unsupported input type: {type(input_data)}. Expected DataFrame or Data.\"\n raise ValueError(msg)\n\n def parse_combined_text(self) -> Message:\n \"\"\"Parse all rows/items into a single text or convert input to string if `stringify` is enabled.\"\"\"\n # Early return for stringify option\n if self.mode == \"Stringify\":\n return self.convert_to_string()\n\n df, data = self._clean_args()\n\n lines = []\n if df is not None:\n for _, row in df.iterrows():\n formatted_text = self.pattern.format(**row.to_dict())\n lines.append(formatted_text)\n elif data is not None:\n # Use format_map with a dict that returns default_value for missing keys\n class DefaultDict(dict):\n def __missing__(self, key):\n return data.default_value or \"\"\n\n formatted_text = self.pattern.format_map(DefaultDict(data.data))\n lines.append(formatted_text)\n\n combined_text = self.sep.join(lines)\n self.status = combined_text\n return Message(text=combined_text)\n\n def convert_to_string(self) -> Message:\n \"\"\"Convert input data to string with proper error handling.\"\"\"\n result = \"\"\n if isinstance(self.input_data, list):\n result = \"\\n\".join([safe_convert(item, clean_data=self.clean_data or False) for item in self.input_data])\n else:\n result = safe_convert(self.input_data or False)\n self.log(f\"Converted to string with length: {len(result)}\")\n\n message = Message(text=result)\n self.status = message\n return message\n" | ||
| }, | ||
| "input_data": { | ||
| "_input_type": "HandleInput", | ||
| "advanced": false, | ||
| "display_name": "JSON or Table", | ||
| "display_name": "Data or DataFrame", | ||
| "dynamic": false, | ||
| "info": "Accepts either a DataFrame or a Data object.", | ||
| "input_types": [ | ||
| "DataFrame", | ||
| "Table", | ||
| "Data", | ||
| "JSON" | ||
| "Data" |
There was a problem hiding this comment.
Fix mode handling in the embedded ParserComponent.
update_build_config treats field_value as a generic truthy check, so clean_data is added for both "Parser" and "Stringify". It also keys pattern.show/required off self.mode instead of the just-selected field_value, which can leave the UI one step behind.
Suggested fix
def update_build_config(self, build_config, field_value, field_name=None):
"""Dynamically hide/show `template` and enforce requirement based on `stringify`."""
if field_name == "mode":
- build_config["pattern"]["show"] = self.mode == "Parser"
- build_config["pattern"]["required"] = self.mode == "Parser"
- if field_value:
+ is_parser = field_value == "Parser"
+ build_config["pattern"]["show"] = is_parser
+ build_config["pattern"]["required"] = is_parser
+ if field_value == "Stringify":
clean_data = BoolInput(
name="clean_data",
display_name="Clean Data",
info=(
"Enable to clean the data by removing empty rows and lines "
"in each cell of the DataFrame/ Data object."
),
value=True,
advanced=True,
required=False,
)
build_config["clean_data"] = clean_data.to_dict()
else:
build_config.pop("clean_data", None)
return build_config📝 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 lfx.custom.custom_component.component import Component\nfrom lfx.helpers.data import safe_convert\nfrom lfx.inputs.inputs import BoolInput, HandleInput, MessageTextInput, MultilineInput, TabInput\nfrom lfx.schema.data import Data\nfrom lfx.schema.dataframe import DataFrame\nfrom lfx.schema.message import Message\nfrom lfx.template.field.base import Output\n\n\nclass ParserComponent(Component):\n display_name = \"Parser\"\n description = \"Extracts text using a template.\"\n documentation: str = \"https://docs.langflow.org/parser\"\n icon = \"braces\"\n\n inputs = [\n HandleInput(\n name=\"input_data\",\n display_name=\"Data or DataFrame\",\n input_types=[\"DataFrame\", \"Data\"],\n info=\"Accepts either a DataFrame or a Data object.\",\n required=True,\n ),\n TabInput(\n name=\"mode\",\n display_name=\"Mode\",\n options=[\"Parser\", \"Stringify\"],\n value=\"Parser\",\n info=\"Convert into raw string instead of using a template.\",\n real_time_refresh=True,\n ),\n MultilineInput(\n name=\"pattern\",\n display_name=\"Template\",\n info=(\n \"Use variables within curly brackets to extract column values for DataFrames \"\n \"or key values for Data.\"\n \"For example: `Name: {Name}, Age: {Age}, Country: {Country}`\"\n ),\n value=\"Text: {text}\", # Example default\n dynamic=True,\n show=True,\n required=True,\n ),\n MessageTextInput(\n name=\"sep\",\n display_name=\"Separator\",\n advanced=True,\n value=\"\\n\",\n info=\"String used to separate rows/items.\",\n ),\n ]\n\n outputs = [\n Output(\n display_name=\"Parsed Text\",\n name=\"parsed_text\",\n info=\"Formatted text output.\",\n method=\"parse_combined_text\",\n ),\n ]\n\n def update_build_config(self, build_config, field_value, field_name=None):\n \"\"\"Dynamically hide/show `template` and enforce requirement based on `stringify`.\"\"\"\n if field_name == \"mode\":\n build_config[\"pattern\"][\"show\"] = self.mode == \"Parser\"\n build_config[\"pattern\"][\"required\"] = self.mode == \"Parser\"\n if field_value:\n clean_data = BoolInput(\n name=\"clean_data\",\n display_name=\"Clean Data\",\n info=(\n \"Enable to clean the data by removing empty rows and lines \"\n \"in each cell of the DataFrame/ Data object.\"\n ),\n value=True,\n advanced=True,\n required=False,\n )\n build_config[\"clean_data\"] = clean_data.to_dict()\n else:\n build_config.pop(\"clean_data\", None)\n\n return build_config\n\n def _clean_args(self):\n \"\"\"Prepare arguments based on input type.\"\"\"\n input_data = self.input_data\n\n match input_data:\n case list() if all(isinstance(item, Data) for item in input_data):\n msg = \"List of Data objects is not supported.\"\n raise ValueError(msg)\n case DataFrame():\n return input_data, None\n case Data():\n return None, input_data\n case dict() if \"data\" in input_data:\n try:\n if \"columns\" in input_data: # Likely a DataFrame\n return DataFrame.from_dict(input_data), None\n # Likely a Data object\n return None, Data(**input_data)\n except (TypeError, ValueError, KeyError) as e:\n msg = f\"Invalid structured input provided: {e!s}\"\n raise ValueError(msg) from e\n case _:\n msg = f\"Unsupported input type: {type(input_data)}. Expected DataFrame or Data.\"\n raise ValueError(msg)\n\n def parse_combined_text(self) -> Message:\n \"\"\"Parse all rows/items into a single text or convert input to string if `stringify` is enabled.\"\"\"\n # Early return for stringify option\n if self.mode == \"Stringify\":\n return self.convert_to_string()\n\n df, data = self._clean_args()\n\n lines = []\n if df is not None:\n for _, row in df.iterrows():\n formatted_text = self.pattern.format(**row.to_dict())\n lines.append(formatted_text)\n elif data is not None:\n # Use format_map with a dict that returns default_value for missing keys\n class DefaultDict(dict):\n def __missing__(self, key):\n return data.default_value or \"\"\n\n formatted_text = self.pattern.format_map(DefaultDict(data.data))\n lines.append(formatted_text)\n\n combined_text = self.sep.join(lines)\n self.status = combined_text\n return Message(text=combined_text)\n\n def convert_to_string(self) -> Message:\n \"\"\"Convert input data to string with proper error handling.\"\"\"\n result = \"\"\n if isinstance(self.input_data, list):\n result = \"\\n\".join([safe_convert(item, clean_data=self.clean_data or False) for item in self.input_data])\n else:\n result = safe_convert(self.input_data or False)\n self.log(f\"Converted to string with length: {len(result)}\")\n\n message = Message(text=result)\n self.status = message\n return message\n" | |
| }, | |
| "input_data": { | |
| "_input_type": "HandleInput", | |
| "advanced": false, | |
| "display_name": "JSON or Table", | |
| "display_name": "Data or DataFrame", | |
| "dynamic": false, | |
| "info": "Accepts either a DataFrame or a Data object.", | |
| "input_types": [ | |
| "DataFrame", | |
| "Table", | |
| "Data", | |
| "JSON" | |
| "Data" | |
| "value": "from lfx.custom.custom_component.component import Component\nfrom lfx.helpers.data import safe_convert\nfrom lfx.inputs.inputs import BoolInput, HandleInput, MessageTextInput, MultilineInput, TabInput\nfrom lfx.schema.data import Data\nfrom lfx.schema.dataframe import DataFrame\nfrom lfx.schema.message import Message\nfrom lfx.template.field.base import Output\n\n\nclass ParserComponent(Component):\n display_name = \"Parser\"\n description = \"Extracts text using a template.\"\n documentation: str = \"https://docs.langflow.org/parser\"\n icon = \"braces\"\n\n inputs = [\n HandleInput(\n name=\"input_data\",\n display_name=\"Data or DataFrame\",\n input_types=[\"DataFrame\", \"Data\"],\n info=\"Accepts either a DataFrame or a Data object.\",\n required=True,\n ),\n TabInput(\n name=\"mode\",\n display_name=\"Mode\",\n options=[\"Parser\", \"Stringify\"],\n value=\"Parser\",\n info=\"Convert into raw string instead of using a template.\",\n real_time_refresh=True,\n ),\n MultilineInput(\n name=\"pattern\",\n display_name=\"Template\",\n info=(\n \"Use variables within curly brackets to extract column values for DataFrames \"\n \"or key values for Data.\"\n \"For example: `Name: {Name}, Age: {Age}, Country: {Country}`\"\n ),\n value=\"Text: {text}\", # Example default\n dynamic=True,\n show=True,\n required=True,\n ),\n MessageTextInput(\n name=\"sep\",\n display_name=\"Separator\",\n advanced=True,\n value=\"\\n\",\n info=\"String used to separate rows/items.\",\n ),\n ]\n\n outputs = [\n Output(\n display_name=\"Parsed Text\",\n name=\"parsed_text\",\n info=\"Formatted text output.\",\n method=\"parse_combined_text\",\n ),\n ]\n\n def update_build_config(self, build_config, field_value, field_name=None):\n \"\"\"Dynamically hide/show `template` and enforce requirement based on `stringify`.\"\"\"\n if field_name == \"mode\":\n is_parser = field_value == \"Parser\"\n build_config[\"pattern\"][\"show\"] = is_parser\n build_config[\"pattern\"][\"required\"] = is_parser\n if field_value == \"Stringify\":\n clean_data = BoolInput(\n name=\"clean_data\",\n display_name=\"Clean Data\",\n info=(\n \"Enable to clean the data by removing empty rows and lines \"\n \"in each cell of the DataFrame/ Data object.\"\n ),\n value=True,\n advanced=True,\n required=False,\n )\n build_config[\"clean_data\"] = clean_data.to_dict()\n else:\n build_config.pop(\"clean_data\", None)\n\n return build_config\n\n def _clean_args(self):\n \"\"\"Prepare arguments based on input type.\"\"\"\n input_data = self.input_data\n\n match input_data:\n case list() if all(isinstance(item, Data) for item in input_data):\n msg = \"List of Data objects is not supported.\"\n raise ValueError(msg)\n case DataFrame():\n return input_data, None\n case Data():\n return None, input_data\n case dict() if \"data\" in input_data:\n try:\n if \"columns\" in input_data: # Likely a DataFrame\n return DataFrame.from_dict(input_data), None\n # Likely a Data object\n return None, Data(**input_data)\n except (TypeError, ValueError, KeyError) as e:\n msg = f\"Invalid structured input provided: {e!s}\"\n raise ValueError(msg) from e\n case _:\n msg = f\"Unsupported input type: {type(input_data)}. Expected DataFrame or Data.\"\n raise ValueError(msg)\n\n def parse_combined_text(self) -> Message:\n \"\"\"Parse all rows/items into a single text or convert input to string if `stringify` is enabled.\"\"\"\n # Early return for stringify option\n if self.mode == \"Stringify\":\n return self.convert_to_string()\n\n df, data = self._clean_args()\n\n lines = []\n if df is not None:\n for _, row in df.iterrows():\n formatted_text = self.pattern.format(**row.to_dict())\n lines.append(formatted_text)\n elif data is not None:\n # Use format_map with a dict that returns default_value for missing keys\n class DefaultDict(dict):\n def __missing__(self, key):\n return data.default_value or \"\"\n\n formatted_text = self.pattern.format_map(DefaultDict(data.data))\n lines.append(formatted_text)\n\n combined_text = self.sep.join(lines)\n self.status = combined_text\n return Message(text=combined_text)\n\n def convert_to_string(self) -> Message:\n \"\"\"Convert input data to string with proper error handling.\"\"\"\n result = \"\"\n if isinstance(self.input_data, list):\n result = \"\\n\".join([safe_convert(item, clean_data=self.clean_data or False) for item in self.input_data])\n else:\n result = safe_convert(self.input_data or False)\n self.log(f\"Converted to string with length: {len(result)}\")\n\n message = Message(text=result)\n self.status = message\n return message\n" | |
| }, | |
| "input_data": { | |
| "_input_type": "HandleInput", | |
| "advanced": false, | |
| "display_name": "Data or DataFrame", | |
| "dynamic": false, | |
| "info": "Accepts either a DataFrame or a Data object.", | |
| "input_types": [ | |
| "DataFrame", | |
| "Data" |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/backend/base/langflow/initial_setup/starter_projects/Blog` Writer.json
around lines 880 - 890, update_build_config in ParserComponent uses self.mode
and a truthy check on field_value so UI lags and clean_data gets added for both
"Parser" and "Stringify"; change it to explicitly compare field_value to
"Parser" (e.g., is_parser = field_value == "Parser") and use is_parser to set
build_config["pattern"]["show"] and ["required"] as well as to add or pop the
clean_data BoolInput; ensure when field_value is not "Parser" you
pop("clean_data", None) so the clean_data input is removed when switching to
"Stringify".
| "sourceHandle": "{œdataTypeœ: œParserComponentœ, œidœ: œParserComponent-pxQmgœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", | ||
| "target": "ChatOutput-RZUAi", | ||
| "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-RZUAiœ, œinputTypesœ: [œDataœ, œJSONœ, œDataFrameœ, œTableœ, œMessageœ], œtypeœ: œstrœ}" | ||
| "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-RZUAiœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" |
There was a problem hiding this comment.
Regenerate the serialized ChatOutput.input_value metadata.
The embedded code now switches input_value to HandleInput(["Data", "DataFrame", "Message"]), but the persisted field block still says _input_type: "MessageInput" / type: "str" on Lines 248-271, and this edge still targets a str handle on Line 81. That leaves this starter flow half-migrated: the editor will still treat ChatOutput as a message-only socket instead of the widened Data/DataFrame handle you intended.
Suggested serialized metadata updates
- "type": "str"
+ "type": "other"
- "_input_type": "MessageInput"
+ "_input_type": "HandleInput"Apply the same regeneration to the connected edge metadata so targetHandle.type also becomes other.
Also applies to: 124-200
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/backend/base/langflow/initial_setup/starter_projects/Financial` Report
Parser.json at line 89, The serialized metadata for ChatOutput.input_value and
the connected edge targetHandle are out of date: update the persisted field
block for ChatOutput.input_value (currently showing _input_type: "MessageInput"
and type: "str") to reflect the new HandleInput(["Data","DataFrame","Message"])
shape (set the input type to the widened handle and set type to "other" where
appropriate), and regenerate the connected edge metadata so targetHandle.type
becomes other instead of str; search for occurrences of ChatOutput.input_value,
targetHandle, and any _input_type: "MessageInput" entries in the JSON and
replace them with the regenerated metadata matching
HandleInput(["Data","DataFrame","Message"]).
| "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-vj0Efœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", | ||
| "target": "ChatOutput-xm3UQ", | ||
| "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-xm3UQœ, œinputTypesœ: [œDataœ, œJSONœ, œDataFrameœ, œTableœ, œMessageœ], œtypeœ: œstrœ}" | ||
| "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-xm3UQœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" |
There was a problem hiding this comment.
Regenerate the ChatOutput snapshot completely.
This update changes the embedded code to HandleInput(["Data", "DataFrame", "Message"]), but the same node still serializes input_value as MessageInput/str elsewhere in the snapshot (for example, Line 1242 and Line 1261). If the starter flow is hydrated from the serialized template metadata, this project can keep the old contract despite the code blob change. Please regenerate this node so the stored field metadata matches the new handle type end-to-end.
Also applies to: 1194-1194
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/backend/base/langflow/initial_setup/starter_projects/Instagram`
Copywriter.json at line 61, The ChatOutput node snapshot is inconsistent: the
embedded code was changed to use HandleInput(["Data","DataFrame","Message"]) but
serialized metadata still treats input_value as MessageInput/str in fields like
targetHandle and other occurrences (e.g., the serialized entries around
ChatOutput, input_value at lines referenced); regenerate the ChatOutput snapshot
so all serialized metadata (targetHandle, input_value, and any other stored
field types) reflect the new HandleInput accepted types end-to-end, ensuring the
node’s stored contract matches the new handler and replacing outdated
MessageInput/str typings throughout the JSON for the ChatOutput node.
| "sourceHandle": "{œdataTypeœ: œAssemblyAITranscriptionJobCreatorœ, œidœ: œAssemblyAITranscriptionJobCreator-Nu1dVœ, œnameœ: œtranscript_idœ, œoutput_typesœ: [œDataœ]}", | ||
| "target": "AssemblyAITranscriptionJobPoller-sCJsy", | ||
| "targetHandle": "{œfieldNameœ: œtranscript_idœ, œidœ: œAssemblyAITranscriptionJobPoller-sCJsyœ, œinputTypesœ: [œDataœ, œJSONœ], œtypeœ: œotherœ}" | ||
| "targetHandle": "{œfieldNameœ: œtranscript_idœ, œidœ: œAssemblyAITranscriptionJobPoller-sCJsyœ, œinputTypesœ: [œDataœ], œtypeœ: œotherœ}" |
There was a problem hiding this comment.
Regenerate these edge IDs after the handle-type changes.
The updated sourceHandle/targetHandle payloads now encode Data/DataFrame, but the matching id fields still encode the old JSON/Table signatures at Lines 54, 85, 144, 202, and 260. That leaves contradictory edge metadata in the same export and can cause churn the next time this Flow is re-saved or reconnected.
Also applies to: 88-88, 149-149, 207-207, 265-265
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/backend/base/langflow/initial_setup/starter_projects/Meeting`
Summary.json around lines 57 - 59, The exported edge metadata has mismatched IDs
after handle-type changes: update the encoded id strings inside the
sourceHandle/targetHandle payloads so they reflect the new Data/DataFrame handle
types (e.g., replace old JSON/Table signatures embedded in the ids for
AssemblyAITranscriptionJobCreator-Nu1dV and
AssemblyAITranscriptionJobPoller-sCJsy and the other listed node ids) to match
the current handle type encoding; regenerate the edge ids for each affected edge
(those referencing sourceHandle/targetHandle entries at the noted lines) so the
id value's signature portion matches its handle's output_types/inputTypes
(Data/DataFrame) to remove the contradictory metadata.
| "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-03SGoœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", | ||
| "target": "ChatOutput-ykhew", | ||
| "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-ykhewœ, œinputTypesœ: [œDataœ, œJSONœ, œDataFrameœ, œTableœ, œMessageœ], œtypeœ: œstrœ}" | ||
| "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-ykhewœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" |
There was a problem hiding this comment.
Regenerate the full ChatOutput snapshot here.
Line 104 updates only the stringified handle. The structured edge metadata still says type: "str", and the ChatOutput.template.input_value later in this file is still serialized as MessageInput/str instead of HandleInput/other. That leaves this starter flow out of sync with the new ["Data", "DataFrame", "Message"] contract and can import with stale connector metadata.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/backend/base/langflow/initial_setup/starter_projects/Price` Deal
Finder.json at line 104, The ChatOutput snapshot is out of sync: update the full
ChatOutput JSON (not just the targetHandle string) so its structured metadata
matches the new connector contract; specifically, regenerate the ChatOutput
object so targetHandle reflects {fieldName: "input_value", id:
"ChatOutput-ykhew", inputTypes: ["Data","DataFrame","Message"], type: "other"}
and ensure ChatOutput.template.input_value is switched from a serialized
MessageInput/str to a HandleInput/other representation consistent with the new
["Data","DataFrame","Message"] contract (update any related edge metadata
entries and IDs in the Price Deal Finder JSON to match the regenerated
ChatOutput).
| "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-9JGgQœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", | ||
| "target": "ChatOutput-Pygov", | ||
| "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-Pygovœ, œinputTypesœ: [œDataœ, œJSONœ, œDataFrameœ, œTableœ, œMessageœ], œtypeœ: œotherœ}" | ||
| "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-Pygovœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}" |
There was a problem hiding this comment.
Keep the starter-project ChatOutput contract aligned with the source component.
This flow now narrows ChatOutput.input_value to Data/DataFrame/Message, but the real component in src/lfx/src/lfx/components/input_output/chat_output.py still accepts JSON and Table at Line 35. Since src/backend/base/langflow/initial_setup/setup.py only refreshes starter-project template["code"] from the source component at Lines 131-179, the next sync will restore the broader source code while leaving this flow metadata narrowed. Please update the source ChatOutput definition as part of this change, or keep the starter-project metadata on the current five-type contract until the source component is migrated too.
Also applies to: 642-700
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/backend/base/langflow/initial_setup/starter_projects/Search` agent.json
at line 29, The starter-project flow narrowed ChatOutput.input_value to only
Data/DataFrame/Message but the source component ChatOutput (in
src/lfx/src/lfx/components/input_output/chat_output.py) still declares JSON and
Table as accepted types; to keep them aligned either update the source
ChatOutput to remove JSON and Table from its accepted input types (so the
component's contract matches the starter project's targetHandle) or revert the
starter-project metadata to include the full five-type contract until the source
component is migrated; locate the ChatOutput class in chat_output.py and change
its input type list (the component contract used by setup.py's template["code"]
refresh) to match the starter-project, and ensure any references to targetHandle
in the starter-project JSON remain consistent.
| "sourceHandle": "{\"dataType\": \"LanguageModelComponent\", \"id\": \"LanguageModelComponent-zY7m0\", \"name\": \"text_output\", \"output_types\": [\"Message\"]}", | ||
| "target": "ChatOutput-S7Bzs", | ||
| "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-S7Bzsœ, œinputTypesœ: [œDataœ, œJSONœ, œDataFrameœ, œTableœ, œMessageœ], œtypeœ: œstrœ}" | ||
| "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-S7Bzsœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" |
There was a problem hiding this comment.
Fix malformed serialized targetHandle payload (invalid JSON string).
Line 60 uses œ characters instead of standard JSON quoting, which can break edge-handle parsing/deserialization.
🐛 Proposed fix
- "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-S7Bzsœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}"
+ "targetHandle": "{\"fieldName\": \"input_value\", \"id\": \"ChatOutput-S7Bzs\", \"inputTypes\": [\"Data\", \"DataFrame\", \"Message\"], \"type\": \"str\"}"📝 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.
| "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-S7Bzsœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" | |
| "targetHandle": "{\"fieldName\": \"input_value\", \"id\": \"ChatOutput-S7Bzs\", \"inputTypes\": [\"Data\", \"DataFrame\", \"Message\"], \"type\": \"str\"}" |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/backend/base/langflow/initial_setup/starter_projects/SEO` Keyword
Generator.json at line 60, The serialized targetHandle value is malformed
because it uses œ characters instead of standard double quotes; locate the
property named "targetHandle" in the SEO Keyword Generator starter project and
replace the œ characters with standard double quotes to produce valid JSON
(e.g., "{\"fieldName\": \"input_value\", \"id\": \"ChatOutput-S7Bzs\",
\"inputTypes\": [\"Data\", \"DataFrame\", \"Message\"], \"type\": \"str\"}") so
the string is proper JSON and can be parsed/deserialized correctly.
| "title_case": false, | ||
| "type": "code", | ||
| "value": "import ast\nimport pprint\nfrom enum import Enum\n\nimport yfinance as yf\nfrom langchain_core.tools import ToolException\nfrom pydantic import BaseModel, Field\n\nfrom lfx.custom.custom_component.component import Component\nfrom lfx.inputs.inputs import DropdownInput, IntInput, MessageTextInput\nfrom lfx.io import Output\nfrom lfx.log.logger import logger\nfrom lfx.schema.data import Data\nfrom lfx.schema.dataframe import DataFrame\n\n\nclass YahooFinanceMethod(Enum):\n GET_INFO = \"get_info\"\n GET_NEWS = \"get_news\"\n GET_ACTIONS = \"get_actions\"\n GET_ANALYSIS = \"get_analysis\"\n GET_BALANCE_SHEET = \"get_balance_sheet\"\n GET_CALENDAR = \"get_calendar\"\n GET_CASHFLOW = \"get_cashflow\"\n GET_INSTITUTIONAL_HOLDERS = \"get_institutional_holders\"\n GET_RECOMMENDATIONS = \"get_recommendations\"\n GET_SUSTAINABILITY = \"get_sustainability\"\n GET_MAJOR_HOLDERS = \"get_major_holders\"\n GET_MUTUALFUND_HOLDERS = \"get_mutualfund_holders\"\n GET_INSIDER_PURCHASES = \"get_insider_purchases\"\n GET_INSIDER_TRANSACTIONS = \"get_insider_transactions\"\n GET_INSIDER_ROSTER_HOLDERS = \"get_insider_roster_holders\"\n GET_DIVIDENDS = \"get_dividends\"\n GET_CAPITAL_GAINS = \"get_capital_gains\"\n GET_SPLITS = \"get_splits\"\n GET_SHARES = \"get_shares\"\n GET_FAST_INFO = \"get_fast_info\"\n GET_SEC_FILINGS = \"get_sec_filings\"\n GET_RECOMMENDATIONS_SUMMARY = \"get_recommendations_summary\"\n GET_UPGRADES_DOWNGRADES = \"get_upgrades_downgrades\"\n GET_EARNINGS = \"get_earnings\"\n GET_INCOME_STMT = \"get_income_stmt\"\n\n\nclass YahooFinanceSchema(BaseModel):\n symbol: str = Field(..., description=\"The stock symbol to retrieve data for.\")\n method: YahooFinanceMethod = Field(YahooFinanceMethod.GET_INFO, description=\"The type of data to retrieve.\")\n num_news: int | None = Field(5, description=\"The number of news articles to retrieve.\")\n\n\nclass YfinanceComponent(Component):\n display_name = \"Yahoo! Finance\"\n description = \"\"\"Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) \\\nto access financial data and market information from Yahoo! Finance.\"\"\"\n icon = \"trending-up\"\n\n inputs = [\n MessageTextInput(\n name=\"symbol\",\n display_name=\"Stock Symbol\",\n info=\"The stock symbol to retrieve data for (e.g., AAPL, GOOG).\",\n tool_mode=True,\n ),\n DropdownInput(\n name=\"method\",\n display_name=\"Data Method\",\n info=\"The type of data to retrieve.\",\n options=list(YahooFinanceMethod),\n value=\"get_news\",\n ),\n IntInput(\n name=\"num_news\",\n display_name=\"Number of News\",\n info=\"The number of news articles to retrieve (only applicable for get_news).\",\n value=5,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Table\", name=\"dataframe\", method=\"fetch_content_dataframe\"),\n ]\n\n def run_model(self) -> DataFrame:\n return self.fetch_content_dataframe()\n\n def _fetch_yfinance_data(self, ticker: yf.Ticker, method: YahooFinanceMethod, num_news: int | None) -> str:\n try:\n if method == YahooFinanceMethod.GET_INFO:\n result = ticker.info\n elif method == YahooFinanceMethod.GET_NEWS:\n result = ticker.news[:num_news]\n else:\n result = getattr(ticker, method.value)()\n return pprint.pformat(result)\n except Exception as e:\n error_message = f\"Error retrieving data: {e}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n\n def fetch_content(self) -> list[Data]:\n try:\n return self._yahoo_finance_tool(\n self.symbol,\n YahooFinanceMethod(self.method),\n self.num_news,\n )\n except ToolException:\n raise\n except Exception as e:\n error_message = f\"Unexpected error: {e}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n\n def _yahoo_finance_tool(\n self,\n symbol: str,\n method: YahooFinanceMethod,\n num_news: int | None = 5,\n ) -> list[Data]:\n ticker = yf.Ticker(symbol)\n result = self._fetch_yfinance_data(ticker, method, num_news)\n\n if method == YahooFinanceMethod.GET_NEWS:\n data_list = [\n Data(text=f\"{article['title']}: {article['link']}\", data=article)\n for article in ast.literal_eval(result)\n ]\n else:\n data_list = [Data(text=result, data={\"result\": result})]\n\n return data_list\n\n def fetch_content_dataframe(self) -> DataFrame:\n data = self.fetch_content()\n return DataFrame(data)\n" | ||
| "value": "import ast\nimport pprint\nfrom enum import Enum\n\nimport yfinance as yf\nfrom langchain_core.tools import ToolException\nfrom pydantic import BaseModel, Field\n\nfrom lfx.custom.custom_component.component import Component\nfrom lfx.inputs.inputs import DropdownInput, IntInput, MessageTextInput\nfrom lfx.io import Output\nfrom lfx.log.logger import logger\nfrom lfx.schema.data import Data\nfrom lfx.schema.dataframe import DataFrame\n\n\nclass YahooFinanceMethod(Enum):\n GET_INFO = \"get_info\"\n GET_NEWS = \"get_news\"\n GET_ACTIONS = \"get_actions\"\n GET_ANALYSIS = \"get_analysis\"\n GET_BALANCE_SHEET = \"get_balance_sheet\"\n GET_CALENDAR = \"get_calendar\"\n GET_CASHFLOW = \"get_cashflow\"\n GET_INSTITUTIONAL_HOLDERS = \"get_institutional_holders\"\n GET_RECOMMENDATIONS = \"get_recommendations\"\n GET_SUSTAINABILITY = \"get_sustainability\"\n GET_MAJOR_HOLDERS = \"get_major_holders\"\n GET_MUTUALFUND_HOLDERS = \"get_mutualfund_holders\"\n GET_INSIDER_PURCHASES = \"get_insider_purchases\"\n GET_INSIDER_TRANSACTIONS = \"get_insider_transactions\"\n GET_INSIDER_ROSTER_HOLDERS = \"get_insider_roster_holders\"\n GET_DIVIDENDS = \"get_dividends\"\n GET_CAPITAL_GAINS = \"get_capital_gains\"\n GET_SPLITS = \"get_splits\"\n GET_SHARES = \"get_shares\"\n GET_FAST_INFO = \"get_fast_info\"\n GET_SEC_FILINGS = \"get_sec_filings\"\n GET_RECOMMENDATIONS_SUMMARY = \"get_recommendations_summary\"\n GET_UPGRADES_DOWNGRADES = \"get_upgrades_downgrades\"\n GET_EARNINGS = \"get_earnings\"\n GET_INCOME_STMT = \"get_income_stmt\"\n\n\nclass YahooFinanceSchema(BaseModel):\n symbol: str = Field(..., description=\"The stock symbol to retrieve data for.\")\n method: YahooFinanceMethod = Field(YahooFinanceMethod.GET_INFO, description=\"The type of data to retrieve.\")\n num_news: int | None = Field(5, description=\"The number of news articles to retrieve.\")\n\n\nclass YfinanceComponent(Component):\n display_name = \"Yahoo! Finance\"\n description = \"\"\"Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) \\\nto access financial data and market information from Yahoo! Finance.\"\"\"\n icon = \"trending-up\"\n\n inputs = [\n MessageTextInput(\n name=\"symbol\",\n display_name=\"Stock Symbol\",\n info=\"The stock symbol to retrieve data for (e.g., AAPL, GOOG).\",\n tool_mode=True,\n ),\n DropdownInput(\n name=\"method\",\n display_name=\"Data Method\",\n info=\"The type of data to retrieve.\",\n options=list(YahooFinanceMethod),\n value=\"get_news\",\n ),\n IntInput(\n name=\"num_news\",\n display_name=\"Number of News\",\n info=\"The number of news articles to retrieve (only applicable for get_news).\",\n value=5,\n ),\n ]\n\n outputs = [\n Output(display_name=\"DataFrame\", name=\"dataframe\", method=\"fetch_content_dataframe\"),\n ]\n\n def run_model(self) -> DataFrame:\n return self.fetch_content_dataframe()\n\n def _fetch_yfinance_data(self, ticker: yf.Ticker, method: YahooFinanceMethod, num_news: int | None) -> str:\n try:\n if method == YahooFinanceMethod.GET_INFO:\n result = ticker.info\n elif method == YahooFinanceMethod.GET_NEWS:\n result = ticker.news[:num_news]\n else:\n result = getattr(ticker, method.value)()\n return pprint.pformat(result)\n except Exception as e:\n error_message = f\"Error retrieving data: {e}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n\n def fetch_content(self) -> list[Data]:\n try:\n return self._yahoo_finance_tool(\n self.symbol,\n YahooFinanceMethod(self.method),\n self.num_news,\n )\n except ToolException:\n raise\n except Exception as e:\n error_message = f\"Unexpected error: {e}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n\n def _yahoo_finance_tool(\n self,\n symbol: str,\n method: YahooFinanceMethod,\n num_news: int | None = 5,\n ) -> list[Data]:\n ticker = yf.Ticker(symbol)\n result = self._fetch_yfinance_data(ticker, method, num_news)\n\n if method == YahooFinanceMethod.GET_NEWS:\n data_list = [\n Data(text=f\"{article['title']}: {article['link']}\", data=article)\n for article in ast.literal_eval(result)\n ]\n else:\n data_list = [Data(text=result, data={\"result\": result})]\n\n return data_list\n\n def fetch_content_dataframe(self) -> DataFrame:\n data = self.fetch_content()\n return DataFrame(data)\n" |
There was a problem hiding this comment.
Regenerate these component snapshots from updated source modules.
Line 3257 and Line 3467 rename the embedded outputs to Data/DataFrame, but the same node snapshots still advertise old JSON/Table base classes earlier in this file at Lines 3184-3187, 2945-2950, and 3345-3348. The referenced source modules also still export the old labels in src/lfx/src/lfx/components/utilities/calculator_core.py and src/lfx/src/lfx/components/tavily/tavily_search.py. That leaves this starter project internally inconsistent and easy to drift back on the next regeneration or refresh. Update the source components first, then re-export the starter project JSON.
Also applies to: 3257-3257, 3467-3467
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/backend/base/langflow/initial_setup/starter_projects/Sequential` Tasks
Agents.json at line 3032, The starter project JSON is out of sync with updated
component exports: embedded outputs were renamed to Data/DataFrame but earlier
snapshots still advertise JSON/Table and the source components still export old
labels; update the source components that define the outputs (e.g., the
classes/components that previously exposed JSON/Table) to export the new
Data/DataFrame names, update any export lists or identifiers in those modules,
then regenerate the Sequential Tasks Agents.json snapshot so the embedded
outputs in YfinanceComponent (YfinanceComponent.outputs,
fetch_content_dataframe, fetch_content, _yahoo_finance_tool) and related
components reflect Data/DataFrame consistently across the file and the source
modules; finally re-run the exporter that produces the starter project JSON to
produce a consistent snapshot.
Fixes #12277
Problem
The Google Generative AI embedding models list (
GOOGLE_GENERATIVE_AI_EMBEDDING_MODELS) contained only deprecated models (models/text-embedding-004andmodels/embedding-001), which return a404 models/text-embedding-004 is not found for API version v1betaerror. This made knowledge base ingestion with Google embedding models impossible.Solution
GOOGLE_GENERATIVE_AI_EMBEDDING_MODELS_DETAILEDto use explicitcreate_model_metadatacalls (consistent with how LLM models are defined)models/gemini-embedding-001as the current supported model (marked as default)models/text-embedding-004andmodels/embedding-001as deprecated entries for backward compatibilityGoogleGenerativeAIEmbeddingsComponentfrommodels/text-embedding-004tomodels/gemini-embedding-001Testing
Summary by CodeRabbit
Release Notes