Skip to content

fix: update Google embedding models to use non-deprecated gemini-embedding-001#12613

Open
octo-patch wants to merge 4 commits into
langflow-ai:mainfrom
octo-patch:fix/issue-12277-update-google-embedding-models
Open

fix: update Google embedding models to use non-deprecated gemini-embedding-001#12613
octo-patch wants to merge 4 commits into
langflow-ai:mainfrom
octo-patch:fix/issue-12277-update-google-embedding-models

Conversation

@octo-patch
Copy link
Copy Markdown

@octo-patch octo-patch commented Apr 10, 2026

Fixes #12277

Problem

The Google Generative AI embedding models list (GOOGLE_GENERATIVE_AI_EMBEDDING_MODELS) contained only deprecated models (models/text-embedding-004 and models/embedding-001), which return a 404 models/text-embedding-004 is not found for API version v1beta error. This made knowledge base ingestion with Google embedding models impossible.

Solution

  • Restructured GOOGLE_GENERATIVE_AI_EMBEDDING_MODELS_DETAILED to use explicit create_model_metadata calls (consistent with how LLM models are defined)
  • Added models/gemini-embedding-001 as the current supported model (marked as default)
  • Retained models/text-embedding-004 and models/embedding-001 as deprecated entries for backward compatibility
  • Updated the default model value in GoogleGenerativeAIEmbeddingsComponent from models/text-embedding-004 to models/gemini-embedding-001

Testing

  • Verified the constants file imports and model list generation logic are correct
  • Existing tests pass as they reference model names explicitly and do not validate against the constants list

Summary by CodeRabbit

Release Notes

  • Updates
    • Standardized data type handling across starter workflows for improved consistency and compatibility.
    • Updated default Google Generative AI embedding model for better performance and availability.
    • Refined component input/output type configurations to streamline data flow in workflows.

…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.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 10, 2026

Walkthrough

This 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 models/gemini-embedding-001 model instead of deprecated alternatives.

Changes

Cohort / File(s) Summary
ChatOutput Input Type Standardization
Basic Prompt Chaining.json, Basic Prompting.json, SEO Keyword Generator.json, Social Media Agent.json, Twitter Thread Generator.json
Updated ChatOutput input_value handle to remove "JSON" and "Table" from input_types, restricting to ["Data", "DataFrame", "Message"]. Updated edge targetHandle metadata and embedded component code accordingly. Updated code_hash values.
Comprehensive Component Type Updates
Blog Writer.json, Market Research.json, Financial Report Parser.json, Pokédex Agent.json, Sequential Tasks Agents.json
Removed "JSON" and "Table" from ChatOutput inputs. Updated ParserComponent, URLComponent, CalculatorComponent, and other components to use "DataFrame" instead of "Table" and "Data" instead of "JSON". Updated component templates, code_hash values, and display names. Changed pydantic dependency from 2.12.5 to 2.11.10 in multiple components.
ChatOutput and Helper Component Updates
Custom Component Generator.json, Image Sentiment Analysis.json, Instagram Copywriter.json, Invoice Summarizer.json, Memory Chatbot.json, Nvidia Remix.json, Research Agent.json, SaaS Pricing.json, Search agent.json, Simple Agent.json, Text Sentiment Analysis.json, Travel Planning Agents.json, Youtube Analysis.json
Updated ChatOutput to restrict input_types to ["Data", "DataFrame", "Message"]. Updated component display names and output types for helper components (TavilySearchComponent, MemoryComponent, CalculatorComponent, etc.) from "Table"/"JSON" to "DataFrame"/"Data". Updated embedded code templates and code_hash values. Downgraded pydantic dependency in applicable node metadata.
Output Selection and Configuration Changes
Document Q&A.json, Hybrid Search RAG.json
Updated ChatOutput input type restrictions and output selection metadata. For Document Q&A, removed "JSON" from File component's file_path handle. For Hybrid Search RAG, updated output selected fields for Astra DB and Structured Output nodes.
Google Generative AI Model Configuration
google_generative_ai_constants.py, google_generative_ai_embeddings.py
Restructured embedding models metadata to explicitly define the current default model models/gemini-embedding-001 (marked default=True) and deprecated models models/text-embedding-004 and models/embedding-001 (marked deprecated=True). Updated default model_name in GoogleGenerativeAIEmbeddingsComponent from models/text-embedding-004 to models/gemini-embedding-001.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • Adam-Aghili

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error PR modifies Google embedding model components but includes no new test files or test coverage for the changes. Add test files (test_google_generative_ai_embeddings.py, test_google_generative_ai_constants.py) with unit tests for model selection logic and integration tests for the updated default model and deprecation handling.
Out of Scope Changes check ⚠️ Warning The PR contains large JSON file updates unrelated to the core issue: 27 starter project files have ChatOutput/component type changes unrelated to embedding models. Remove unrelated starter project JSON modifications and focus only on the embedding models constants and component default changes required by issue #12277.
Test Quality And Coverage ⚠️ Warning PR modifies Google embedding model constants and defaults but lacks unit tests validating the restructured metadata, derived model list, and updated component default. Add unit tests to validate metadata structure, derived model names, component default value, and absence of deprecated models in active list.
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: updating Google embedding models to use the non-deprecated gemini-embedding-001 model.
Linked Issues check ✅ Passed The PR directly addresses issue #12277 by adding gemini-embedding-001 as default while keeping deprecated models for backward compatibility, matching the expected outcome.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Test File Naming And Structure ✅ Passed This PR does not include test files; changes focus on JSON configurations and two source files. No test file patterns or structures to verify.
Excessive Mock Usage Warning ✅ Passed Test files demonstrate appropriate selective mock usage to isolate external dependencies while testing real component logic, with reasonable mock counts and no excessive mocking concerns introduced by the PR.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the bug Something isn't working label Apr 10, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 10, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 10, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Apr 10, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 | 🟡 Minor

Refresh the serialized edge id too.

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 | 🟠 Major

Unwrap Data in _process_headers() before advertising headers as ["Data"].

Line 937 narrows headers to Data, but the embedded APIRequestComponent._process_headers() still only accepts raw dict/list. Any connected Data object 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 | 🟡 Minor

Regenerate this edge id to match the new handle contract.

Line 111 still embeds the old ["Data","JSON","DataFrame","Table","Message"] payload inside id, 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 | 🟡 Minor

Update the persisted edge id here as well.

Line 248 still contains the old JSON/Table-inclusive inputTypes serialization, but Line 253 narrows the actual targetHandle to ["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 | 🟡 Minor

Update the parser-facing copy after the Data/DataFrame migration.

These edges and outputs now expose Data/DataFrame, but the connected parser.input_data field still says "JSON or Table" at Line 964 and still advertises JSON/Table in 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 | 🟡 Minor

Update the downstream Parser snapshot to the same contract.

This handoff now emits Data, but the Parser node metadata later in the file still shows display_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 | 🟡 Minor

Regenerate this edge id to match the narrowed targetHandle metadata.

The edge at line 171 still encodes the old inputTypes (Data, JSON, DataFrame, Table, Message) in its id payload, while line 176 and data.targetHandle now advertise only Data, 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 | 🟡 Minor

Edge ID contains stale inputTypes metadata.

The edge id at line 139 still encodes the old type list including JSON and Table:

...œinputTypesœ:[œDataœ,œJSONœ,œDataFrameœ,œTableœ,œMessageœ]...

However, the actual targetHandle field (line 144) and data.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 with default=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 edge id still embeds the old JSON/Table input 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/Table handle signature even though the updated targetHandle strings 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 canonical DataFrame casing for the Message History output label.

The output type is DataFrame, but the visible label is Dataframe. 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 updating base_classes for consistency.

The base_classes array 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_classes with 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 id at line 83 still references JSON and Table types, while the actual targetHandle at 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

📥 Commits

Reviewing files that changed from the base of the PR and between 1e61ac4 and 5a07963.

📒 Files selected for processing (32)
  • 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/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/Youtube Analysis.json
  • src/lfx/src/lfx/_assets/component_index.json
  • src/lfx/src/lfx/base/models/google_generative_ai_constants.py
  • src/lfx/src/lfx/components/google/google_generative_ai_embeddings.py

Comment on lines +71 to +89
"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œ}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

Comment on lines +880 to +890
"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"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

Suggested change
"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œ}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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œ}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Comment on lines +57 to +59
"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œ}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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œ}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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œ}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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œ}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

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.

Suggested change
"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"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Knowledge base: ingestion not possible with Google embedding models

1 participant