* Update Vector Store RAG.json * fix: make starter projects auto refactor not remove selected output (#8400) * Fixed bug where starter projects were refactored incorrectly * fix: improve handling of selected outputs in custom component template builder - Added checks to ensure selected output is valid before attempting to set its state. - Enhanced code readability with comments explaining the logic for selecting outputs. * Set selected output as the previous selected output * Update base.py --------- Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org> Co-authored-by: Edwin Jose <edwin.jose@datastax.com> * fix: made clean edges clean after changing dropdown of output (#8460) fixed output considering all outputs not just selected one * refactor(docker): remove --extra deploy flag from uv sync commands (#8485) 🔧 (build_and_push_with_extras.Dockerfile): remove unnecessary uv sync command options to improve build efficiency and reduce redundancy Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org> * fix: refactor mcp and freeze tests to be less prone to flaky results (#8486) * Fixed mcp test to be less prone to errors * Fix freeze spec * fix: made button disabled state more congruent, made edit flow details submit on enter (#8339) * Changed textarea classes * Changed flowsettingscomponent to use form * changed edit flow settings to use form and to submit on enter * Reset form data on close * Updated disabled state to have lower opacity instead of to have set background * Fixed loading state of button * Fix: chat memory store issue and fix output types (#8463) * fix chat memory * update template * update update outputs * update update outputs --------- Co-authored-by: Edwin Jose <edwin.jose@datastax.com> * ci: update setup-uv to possibly fix caching (#8490) * update templates * update templates * First round of template updates * Update templates * fix: Update SaaS, Social Media, and YouTube json file (#8441) * update SaaS, Social Media, and YouTube json file * fix: make starter projects auto refactor not remove selected output (#8400) * Fixed bug where starter projects were refactored incorrectly * fix: improve handling of selected outputs in custom component template builder - Added checks to ensure selected output is valid before attempting to set its state. - Enhanced code readability with comments explaining the logic for selecting outputs. * Set selected output as the previous selected output * Update base.py --------- Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org> Co-authored-by: Edwin Jose <edwin.jose@datastax.com> * fix: made clean edges clean after changing dropdown of output (#8460) fixed output considering all outputs not just selected one * refactor(docker): remove --extra deploy flag from uv sync commands (#8485) 🔧 (build_and_push_with_extras.Dockerfile): remove unnecessary uv sync command options to improve build efficiency and reduce redundancy Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org> * fix: refactor mcp and freeze tests to be less prone to flaky results (#8486) * Fixed mcp test to be less prone to errors * Fix freeze spec * fix: made button disabled state more congruent, made edit flow details submit on enter (#8339) * Changed textarea classes * Changed flowsettingscomponent to use form * changed edit flow settings to use form and to submit on enter * Reset form data on close * Updated disabled state to have lower opacity instead of to have set background * Fixed loading state of button * Fix: chat memory store issue and fix output types (#8463) * fix chat memory * update template * update update outputs * update update outputs --------- Co-authored-by: Edwin Jose <edwin.jose@datastax.com> * ci: update setup-uv to possibly fix caching (#8490) * update json * fix custom component * revert change --------- Co-authored-by: Lucas Oliveira <62335616+lucaseduoli@users.noreply.github.com> Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org> Co-authored-by: Edwin Jose <edwin.jose@datastax.com> Co-authored-by: Cristhian Zanforlin Lousa <cristhian.lousa@gmail.com> * fix: templates (#8499) * basic-prompting-template-updated * show-system-message * names * blog-writer-tested * financial-report-parser * image-sentiment-analysis * seo-keyword-generator * seo-keyword-generator * Merge branch 'fix-vector-search-template' into mendons-template-branch --------- Co-authored-by: Eric Hare <ericrhare@gmail.com> * Update Basic Prompting.json * Update Blog Writer.json * Further template updates * Update Image Sentiment Analysis.json * Update templates * Update Financial Report Parser.json * Update Market Research.json * Update Market Research.json * update several templates * Update Image Sentiment Analysis.json * Update Market Research.json * Update image sentiment analysis template * Update Market Research.json * Update Custom Component Maker.json * Update Custom Component Maker.json * Update Hybrid Search RAG.json * Update Hybrid Search RAG.json * Update Hybrid Search RAG.json * More template updates * Update Financial Report Parser.json * updated templates * change custom component maker * Update Twitter Thread Generator.json * updates from main * change model * Update Research Translation Loop.json * expanded output component to fix tests * update template * autofix * fix error * fix change back * change back * ci: Skip truncated values test for refactoring (#8670) * refactor: simplify init target by removing cache cleanup and adding pre-commit hook (#8590) * build: add pyyaml dependency * refactor: simplify init command by removing cache cleaning and langflow run call * refactor: simplify init target by removing cache cleanup and adding pre-commit hook * refactor: update langchain_core.prompts import paths to use specific modules --------- Co-authored-by: Edwin Jose <edwin.jose@datastax.com> * feat: update structured output to multiline input and revise system prompt (#8585) * Update structured_output.py * [autofix.ci] apply automated fixes * Update structured_output.py * [autofix.ci] apply automated fixes * [autofix.ci] apply automated fixes (attempt 2/3) * update to prompt * template updates * Update src/backend/base/langflow/components/processing/structured_output.py * [autofix.ci] apply automated fixes * Update src/backend/base/langflow/components/processing/structured_output.py * Update src/backend/base/langflow/components/processing/structured_output.py * Update src/backend/base/langflow/components/processing/structured_output.py * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> * feat: add sessions endpoint with session management enhancements (#8596) * 📝 (monitor.py): Add endpoint to get sessions and handle session_id encoding for API requests 📝 (use-get-messages-mutation.ts): Implement a mutation function to fetch messages with query parameters and handle session_id encoding for API requests 📝 (use-get-messages-polling.ts): Ensure proper encoding of session_id for API requests in polling mutation 📝 (use-get-messages.ts): Handle session_id encoding for API requests in messages query 📝 (new-modal.tsx): Implement functions to handle session deletion and proper encoding of session_id for API requests 📝 (utils.ts): Add functions to encode, decode, validate, format, and prepare session IDs for API requests * 📝 (constants.ts): Add SESSIONS constant to API URLs for monitoring sessions 🔧 (use-delete-messages.ts): Add queryClient to UseRequestProcessor to invalidate sessions query ✨ (use-get-sessions-from-flow.ts): Introduce useGetSessionsFromFlowQuery to fetch sessions from flow 🔧 (use-rename-session.ts): Change refetchQueries to invalidateQueries for useGetSessionsFromFlowQuery 🔧 (custom-new-modal.tsx): Update import path for IOModal to playground-modal 🔧 (session-selector.tsx): Add setActiveSession function to handle setting active session 🔧 (sidebar-open-view.tsx): Add setActiveSession function to handle setting active session ♻️ (new-modal.tsx): Refactor IOModal into playground-modal and update functionality ♻️ (playground-modal.tsx): Refactor IOModal to handle playground-specific functionality ⬆️ (flowStore.ts): Add newChatOnPlayground state and setNewChatOnPlayground function ⬆️ (index.ts): Update FlowStoreType to include newChatOnPlayground and setNewChatOnPlayground * 🔧 (pyproject.toml): update testpaths to point to the correct directory for tests ✨ (test_session_endpoint.py): add unit tests for sessions endpoint with flow_id filtering ♻️ (session-selector.tsx): refactor to trim editedSession before setting it ♻️ (sidebar-open-view.tsx): refactor to set visibleSession instead of activeSession * ✨ (use-get-sessions-from-flow.ts): Always include the flow ID as the default session if it's not already present ♻️ (playground-modal.tsx): Refactor setting sessions to include currentFlowId as the default session if not present, and handle visibility of sessions more efficiently * ♻️ (use-get-messages-mutation.ts): remove unused imports and refactor code for better readability and maintainability * ✨ (test_session_endpoint.py): refactor test function names for better clarity and consistency * ✨ (create-new-session-name.ts): add function to generate a new session name based on the current date and time 🔧 (playground-modal.tsx): import createNewSessionName function to dynamically set a new session name when no session is visible * [autofix.ci] apply automated fixes * ✨ (monitor.py): rename get_sessions endpoint to get_message_sessions for clarity and consistency 🔧 (constants.ts): remove unused SESSIONS constant from API URLs 🔧 (use-delete-messages.ts): remove commented out code and unnecessary comments ✨ (use-delete-sessions.ts): add functionality to delete sessions in frontend 🔧 (use-get-sessions-from-flow.ts): update API endpoint for getting sessions to match backend changes 🔧 (playground-modal.tsx): add functionality to delete sessions and associated messages in the UI, update UI optimistically, and handle errors appropriately * [autofix.ci] apply automated fixes * 🐛 (monitor.py): Fix type hinting issue in delete_messages function 📝 (monitor.py): Add comments and improve readability in test_messages_endpoints.py 📝 (session_endpoint.py): Update endpoint paths for consistency and clarity in test_session_endpoint.py * [autofix.ci] apply automated fixes * fix: update SQL statement to use col() for session_id filtering in get_message_sessions function --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org> * fix: implemented cached values and temporary MCP servers on MCP component (#8628) * Added actionCount to fetch only servers without actionCount * Updated queries and uses to use servers without action data first, and then to fetch them * removed comment * updated constants * Added loading dropdown * Make options persist * Implemented new value format for McpComponent and implemented saving and removing temp Mcp Server if config is existent * Changed value type * Implemented cache and saving the server config * Fixed mcp server test * fix backend formatting * fixed lint * Added await * Fixed save button not appearing when no servers are available * added condition to only show save button when options is not null * template autofix * change template * update text sentiment analysis * change basic prompt back * change image sentiment back * update text sentiment and twitter * Update Twitter Thread Generator.json * Add back the input for the chat * add change * fix text sentiment * update research translation * Update Research Translation Loop.json --------- Co-authored-by: Eric Hare <ericrhare@gmail.com> Co-authored-by: Edwin Jose <edwin.jose@datastax.com> Co-authored-by: Lucas Oliveira <62335616+lucaseduoli@users.noreply.github.com> Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org> Co-authored-by: Cristhian Zanforlin Lousa <cristhian.lousa@gmail.com> Co-authored-by: Mendon Kissling <59585235+mendonk@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1889 lines
No EOL
103 KiB
JSON
1889 lines
No EOL
103 KiB
JSON
{
|
||
"data": {
|
||
"edges": [
|
||
{
|
||
"animated": false,
|
||
"className": "",
|
||
"data": {
|
||
"sourceHandle": {
|
||
"dataType": "ChatInput",
|
||
"id": "ChatInput-OF2vZ",
|
||
"name": "message",
|
||
"output_types": [
|
||
"Message"
|
||
]
|
||
},
|
||
"targetHandle": {
|
||
"fieldName": "search_query",
|
||
"id": "ArXivComponent-WxSYF",
|
||
"inputTypes": [
|
||
"Message"
|
||
],
|
||
"type": "str"
|
||
}
|
||
},
|
||
"id": "reactflow__edge-ChatInput-OF2vZ{œdataTypeœ:œChatInputœ,œidœ:œChatInput-OF2vZœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-ArXivComponent-WxSYF{œfieldNameœ:œsearch_queryœ,œidœ:œArXivComponent-WxSYFœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}",
|
||
"selected": false,
|
||
"source": "ChatInput-OF2vZ",
|
||
"sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-OF2vZœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}",
|
||
"target": "ArXivComponent-WxSYF",
|
||
"targetHandle": "{œfieldNameœ: œsearch_queryœ, œidœ: œArXivComponent-WxSYFœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}"
|
||
},
|
||
{
|
||
"animated": false,
|
||
"className": "",
|
||
"data": {
|
||
"sourceHandle": {
|
||
"dataType": "ArXivComponent",
|
||
"id": "ArXivComponent-WxSYF",
|
||
"name": "dataframe",
|
||
"output_types": [
|
||
"DataFrame"
|
||
]
|
||
},
|
||
"targetHandle": {
|
||
"fieldName": "data",
|
||
"id": "LoopComponent-zuKTL",
|
||
"inputTypes": [
|
||
"DataFrame"
|
||
],
|
||
"type": "other"
|
||
}
|
||
},
|
||
"id": "reactflow__edge-ArXivComponent-WxSYF{œdataTypeœ:œArXivComponentœ,œidœ:œArXivComponent-WxSYFœ,œnameœ:œdataframeœ,œoutput_typesœ:[œDataFrameœ]}-LoopComponent-zuKTL{œfieldNameœ:œdataœ,œidœ:œLoopComponent-zuKTLœ,œinputTypesœ:[œDataFrameœ],œtypeœ:œotherœ}",
|
||
"selected": false,
|
||
"source": "ArXivComponent-WxSYF",
|
||
"sourceHandle": "{œdataTypeœ: œArXivComponentœ, œidœ: œArXivComponent-WxSYFœ, œnameœ: œdataframeœ, œoutput_typesœ: [œDataFrameœ]}",
|
||
"target": "LoopComponent-zuKTL",
|
||
"targetHandle": "{œfieldNameœ: œdataœ, œidœ: œLoopComponent-zuKTLœ, œinputTypesœ: [œDataFrameœ], œtypeœ: œotherœ}"
|
||
},
|
||
{
|
||
"animated": false,
|
||
"className": "",
|
||
"data": {
|
||
"sourceHandle": {
|
||
"dataType": "LoopComponent",
|
||
"id": "LoopComponent-zuKTL",
|
||
"name": "item",
|
||
"output_types": [
|
||
"Data"
|
||
]
|
||
},
|
||
"targetHandle": {
|
||
"fieldName": "input_data",
|
||
"id": "ParserComponent-2OCL9",
|
||
"inputTypes": [
|
||
"DataFrame",
|
||
"Data"
|
||
],
|
||
"type": "other"
|
||
}
|
||
},
|
||
"id": "reactflow__edge-LoopComponent-zuKTL{œdataTypeœ:œLoopComponentœ,œidœ:œLoopComponent-zuKTLœ,œnameœ:œitemœ,œoutput_typesœ:[œDataœ]}-ParserComponent-2OCL9{œfieldNameœ:œinput_dataœ,œidœ:œParserComponent-2OCL9œ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}",
|
||
"selected": false,
|
||
"source": "LoopComponent-zuKTL",
|
||
"sourceHandle": "{œdataTypeœ: œLoopComponentœ, œidœ: œLoopComponent-zuKTLœ, œnameœ: œitemœ, œoutput_typesœ: [œDataœ]}",
|
||
"target": "ParserComponent-2OCL9",
|
||
"targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œParserComponent-2OCL9œ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}"
|
||
},
|
||
{
|
||
"animated": false,
|
||
"className": "",
|
||
"data": {
|
||
"sourceHandle": {
|
||
"dataType": "LoopComponent",
|
||
"id": "LoopComponent-zuKTL",
|
||
"name": "done",
|
||
"output_types": [
|
||
"DataFrame"
|
||
]
|
||
},
|
||
"targetHandle": {
|
||
"fieldName": "input_data",
|
||
"id": "TypeConverterComponent-mWgMR",
|
||
"inputTypes": [
|
||
"Message",
|
||
"Data",
|
||
"DataFrame"
|
||
],
|
||
"type": "other"
|
||
}
|
||
},
|
||
"id": "reactflow__edge-LoopComponent-zuKTL{œdataTypeœ:œLoopComponentœ,œidœ:œLoopComponent-zuKTLœ,œnameœ:œdoneœ,œoutput_typesœ:[œDataFrameœ]}-TypeConverterComponent-mWgMR{œfieldNameœ:œinput_dataœ,œidœ:œTypeConverterComponent-mWgMRœ,œinputTypesœ:[œMessageœ,œDataœ,œDataFrameœ],œtypeœ:œotherœ}",
|
||
"selected": false,
|
||
"source": "LoopComponent-zuKTL",
|
||
"sourceHandle": "{œdataTypeœ: œLoopComponentœ, œidœ: œLoopComponent-zuKTLœ, œnameœ: œdoneœ, œoutput_typesœ: [œDataFrameœ]}",
|
||
"target": "TypeConverterComponent-mWgMR",
|
||
"targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œTypeConverterComponent-mWgMRœ, œinputTypesœ: [œMessageœ, œDataœ, œDataFrameœ], œtypeœ: œotherœ}"
|
||
},
|
||
{
|
||
"animated": false,
|
||
"className": "",
|
||
"data": {
|
||
"sourceHandle": {
|
||
"dataType": "TypeConverterComponent",
|
||
"id": "TypeConverterComponent-mWgMR",
|
||
"name": "message_output",
|
||
"output_types": [
|
||
"Message"
|
||
]
|
||
},
|
||
"targetHandle": {
|
||
"fieldName": "input_value",
|
||
"id": "ChatOutput-ylHrO",
|
||
"inputTypes": [
|
||
"Data",
|
||
"DataFrame",
|
||
"Message"
|
||
],
|
||
"type": "other"
|
||
}
|
||
},
|
||
"id": "reactflow__edge-TypeConverterComponent-mWgMR{œdataTypeœ:œTypeConverterComponentœ,œidœ:œTypeConverterComponent-mWgMRœ,œnameœ:œmessage_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-ylHrO{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-ylHrOœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}",
|
||
"selected": false,
|
||
"source": "TypeConverterComponent-mWgMR",
|
||
"sourceHandle": "{œdataTypeœ: œTypeConverterComponentœ, œidœ: œTypeConverterComponent-mWgMRœ, œnameœ: œmessage_outputœ, œoutput_typesœ: [œMessageœ]}",
|
||
"target": "ChatOutput-ylHrO",
|
||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-ylHrOœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}"
|
||
},
|
||
{
|
||
"animated": false,
|
||
"className": "",
|
||
"data": {
|
||
"sourceHandle": {
|
||
"dataType": "ParserComponent",
|
||
"id": "ParserComponent-2OCL9",
|
||
"name": "parsed_text",
|
||
"output_types": [
|
||
"Message"
|
||
]
|
||
},
|
||
"targetHandle": {
|
||
"fieldName": "input_value",
|
||
"id": "LanguageModelComponent-Te29P",
|
||
"inputTypes": [
|
||
"Message"
|
||
],
|
||
"type": "str"
|
||
}
|
||
},
|
||
"id": "reactflow__edge-ParserComponent-2OCL9{œdataTypeœ:œParserComponentœ,œidœ:œParserComponent-2OCL9œ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-Te29P{œfieldNameœ:œinput_valueœ,œidœ:œLanguageModelComponent-Te29Pœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}",
|
||
"selected": false,
|
||
"source": "ParserComponent-2OCL9",
|
||
"sourceHandle": "{œdataTypeœ: œParserComponentœ, œidœ: œParserComponent-2OCL9œ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}",
|
||
"target": "LanguageModelComponent-Te29P",
|
||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œLanguageModelComponent-Te29Pœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}"
|
||
},
|
||
{
|
||
"animated": false,
|
||
"className": "",
|
||
"data": {
|
||
"sourceHandle": {
|
||
"dataType": "LanguageModelComponent",
|
||
"id": "LanguageModelComponent-Te29P",
|
||
"name": "text_output",
|
||
"output_types": [
|
||
"Message"
|
||
]
|
||
},
|
||
"targetHandle": {
|
||
"fieldName": "message",
|
||
"id": "MessagetoData-IbO6b",
|
||
"inputTypes": [
|
||
"Message"
|
||
],
|
||
"type": "str"
|
||
}
|
||
},
|
||
"id": "reactflow__edge-LanguageModelComponent-Te29P{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-Te29Pœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-MessagetoData-IbO6b{œfieldNameœ:œmessageœ,œidœ:œMessagetoData-IbO6bœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}",
|
||
"selected": false,
|
||
"source": "LanguageModelComponent-Te29P",
|
||
"sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-Te29Pœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}",
|
||
"target": "MessagetoData-IbO6b",
|
||
"targetHandle": "{œfieldNameœ: œmessageœ, œidœ: œMessagetoData-IbO6bœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}"
|
||
},
|
||
{
|
||
"animated": false,
|
||
"className": "",
|
||
"data": {
|
||
"sourceHandle": {
|
||
"dataType": "MessagetoData",
|
||
"id": "MessagetoData-IbO6b",
|
||
"name": "data",
|
||
"output_types": [
|
||
"Data"
|
||
]
|
||
},
|
||
"targetHandle": {
|
||
"dataType": "LoopComponent",
|
||
"id": "LoopComponent-zuKTL",
|
||
"name": "item",
|
||
"output_types": [
|
||
"Data"
|
||
]
|
||
}
|
||
},
|
||
"id": "reactflow__edge-MessagetoData-IbO6b{œdataTypeœ:œMessagetoDataœ,œidœ:œMessagetoData-IbO6bœ,œnameœ:œdataœ,œoutput_typesœ:[œDataœ]}-LoopComponent-zuKTL{œdataTypeœ:œLoopComponentœ,œidœ:œLoopComponent-zuKTLœ,œnameœ:œitemœ,œoutput_typesœ:[œDataœ]}",
|
||
"selected": false,
|
||
"source": "MessagetoData-IbO6b",
|
||
"sourceHandle": "{œdataTypeœ: œMessagetoDataœ, œidœ: œMessagetoData-IbO6bœ, œnameœ: œdataœ, œoutput_typesœ: [œDataœ]}",
|
||
"target": "LoopComponent-zuKTL",
|
||
"targetHandle": "{œdataTypeœ: œLoopComponentœ, œidœ: œLoopComponent-zuKTLœ, œnameœ: œitemœ, œoutput_typesœ: [œDataœ]}"
|
||
}
|
||
],
|
||
"nodes": [
|
||
{
|
||
"data": {
|
||
"id": "ArXivComponent-WxSYF",
|
||
"node": {
|
||
"base_classes": [
|
||
"DataFrame"
|
||
],
|
||
"beta": false,
|
||
"conditional_paths": [],
|
||
"custom_fields": {},
|
||
"description": "Search and retrieve papers from arXiv.org",
|
||
"display_name": "arXiv",
|
||
"documentation": "",
|
||
"edited": false,
|
||
"field_order": [
|
||
"search_query",
|
||
"search_type",
|
||
"max_results"
|
||
],
|
||
"frozen": false,
|
||
"icon": "arXiv",
|
||
"legacy": false,
|
||
"lf_version": "1.4.3",
|
||
"metadata": {},
|
||
"minimized": false,
|
||
"output_types": [],
|
||
"outputs": [
|
||
{
|
||
"allows_loop": false,
|
||
"cache": true,
|
||
"display_name": "DataFrame",
|
||
"group_outputs": false,
|
||
"method": "search_papers_dataframe",
|
||
"name": "dataframe",
|
||
"selected": "DataFrame",
|
||
"tool_mode": true,
|
||
"types": [
|
||
"DataFrame"
|
||
],
|
||
"value": "__UNDEFINED__"
|
||
}
|
||
],
|
||
"pinned": false,
|
||
"template": {
|
||
"_type": "Component",
|
||
"code": {
|
||
"advanced": true,
|
||
"dynamic": true,
|
||
"fileTypes": [],
|
||
"file_path": "",
|
||
"info": "",
|
||
"list": false,
|
||
"load_from_db": false,
|
||
"multiline": true,
|
||
"name": "code",
|
||
"password": false,
|
||
"placeholder": "",
|
||
"required": true,
|
||
"show": true,
|
||
"title_case": false,
|
||
"type": "code",
|
||
"value": "import urllib.request\nfrom urllib.parse import urlparse\nfrom xml.etree.ElementTree import Element\n\nfrom defusedxml.ElementTree import fromstring\n\nfrom langflow.custom.custom_component.component import Component\nfrom langflow.io import DropdownInput, IntInput, MessageTextInput, Output\nfrom langflow.schema.data import Data\nfrom langflow.schema.dataframe import DataFrame\n\n\nclass ArXivComponent(Component):\n display_name = \"arXiv\"\n description = \"Search and retrieve papers from arXiv.org\"\n icon = \"arXiv\"\n\n inputs = [\n MessageTextInput(\n name=\"search_query\",\n display_name=\"Search Query\",\n info=\"The search query for arXiv papers (e.g., 'quantum computing')\",\n tool_mode=True,\n ),\n DropdownInput(\n name=\"search_type\",\n display_name=\"Search Field\",\n info=\"The field to search in\",\n options=[\"all\", \"title\", \"abstract\", \"author\", \"cat\"], # cat is for category\n value=\"all\",\n ),\n IntInput(\n name=\"max_results\",\n display_name=\"Max Results\",\n info=\"Maximum number of results to return\",\n value=10,\n ),\n ]\n\n outputs = [\n Output(display_name=\"DataFrame\", name=\"dataframe\", method=\"search_papers_dataframe\"),\n ]\n\n def build_query_url(self) -> str:\n \"\"\"Build the arXiv API query URL.\"\"\"\n base_url = \"http://export.arxiv.org/api/query?\"\n\n # Build the search query\n search_query = f\"{self.search_type}:{self.search_query}\"\n\n # URL parameters\n params = {\n \"search_query\": search_query,\n \"max_results\": str(self.max_results),\n }\n\n # Convert params to URL query string\n query_string = \"&\".join([f\"{k}={urllib.parse.quote(str(v))}\" for k, v in params.items()])\n\n return base_url + query_string\n\n def parse_atom_response(self, response_text: str) -> list[dict]:\n \"\"\"Parse the Atom XML response from arXiv.\"\"\"\n # Parse XML safely using defusedxml\n root = fromstring(response_text)\n\n # Define namespace dictionary for XML parsing\n ns = {\"atom\": \"http://www.w3.org/2005/Atom\", \"arxiv\": \"http://arxiv.org/schemas/atom\"}\n\n papers = []\n # Process each entry (paper)\n for entry in root.findall(\"atom:entry\", ns):\n paper = {\n \"id\": self._get_text(entry, \"atom:id\", ns),\n \"title\": self._get_text(entry, \"atom:title\", ns),\n \"summary\": self._get_text(entry, \"atom:summary\", ns),\n \"published\": self._get_text(entry, \"atom:published\", ns),\n \"updated\": self._get_text(entry, \"atom:updated\", ns),\n \"authors\": [author.find(\"atom:name\", ns).text for author in entry.findall(\"atom:author\", ns)],\n \"arxiv_url\": self._get_link(entry, \"alternate\", ns),\n \"pdf_url\": self._get_link(entry, \"related\", ns),\n \"comment\": self._get_text(entry, \"arxiv:comment\", ns),\n \"journal_ref\": self._get_text(entry, \"arxiv:journal_ref\", ns),\n \"primary_category\": self._get_category(entry, ns),\n \"categories\": [cat.get(\"term\") for cat in entry.findall(\"atom:category\", ns)],\n }\n papers.append(paper)\n\n return papers\n\n def _get_text(self, element: Element, path: str, ns: dict) -> str | None:\n \"\"\"Safely extract text from an XML element.\"\"\"\n el = element.find(path, ns)\n return el.text.strip() if el is not None and el.text else None\n\n def _get_link(self, element: Element, rel: str, ns: dict) -> str | None:\n \"\"\"Get link URL based on relation type.\"\"\"\n for link in element.findall(\"atom:link\", ns):\n if link.get(\"rel\") == rel:\n return link.get(\"href\")\n return None\n\n def _get_category(self, element: Element, ns: dict) -> str | None:\n \"\"\"Get primary category.\"\"\"\n cat = element.find(\"arxiv:primary_category\", ns)\n return cat.get(\"term\") if cat is not None else None\n\n def run_model(self) -> DataFrame:\n return self.search_papers_dataframe()\n\n def search_papers(self) -> list[Data]:\n \"\"\"Search arXiv and return results.\"\"\"\n try:\n # Build the query URL\n url = self.build_query_url()\n\n # Validate URL scheme and host\n parsed_url = urlparse(url)\n if parsed_url.scheme not in {\"http\", \"https\"}:\n error_msg = f\"Invalid URL scheme: {parsed_url.scheme}\"\n raise ValueError(error_msg)\n if parsed_url.hostname != \"export.arxiv.org\":\n error_msg = f\"Invalid host: {parsed_url.hostname}\"\n raise ValueError(error_msg)\n\n # Create a custom opener that only allows http/https schemes\n class RestrictedHTTPHandler(urllib.request.HTTPHandler):\n def http_open(self, req):\n return super().http_open(req)\n\n class RestrictedHTTPSHandler(urllib.request.HTTPSHandler):\n def https_open(self, req):\n return super().https_open(req)\n\n # Build opener with restricted handlers\n opener = urllib.request.build_opener(RestrictedHTTPHandler, RestrictedHTTPSHandler)\n urllib.request.install_opener(opener)\n\n # Make the request with validated URL using restricted opener\n response = opener.open(url)\n response_text = response.read().decode(\"utf-8\")\n\n # Parse the response\n papers = self.parse_atom_response(response_text)\n\n # Convert to Data objects\n results = [Data(data=paper) for paper in papers]\n self.status = results\n except (urllib.error.URLError, ValueError) as e:\n error_data = Data(data={\"error\": f\"Request error: {e!s}\"})\n self.status = error_data\n return [error_data]\n else:\n return results\n\n def search_papers_dataframe(self) -> DataFrame:\n \"\"\"Convert the Arxiv search results to a DataFrame.\n\n Returns:\n DataFrame: A DataFrame containing the search results.\n \"\"\"\n data = self.search_papers()\n return DataFrame(data)\n"
|
||
},
|
||
"max_results": {
|
||
"_input_type": "IntInput",
|
||
"advanced": false,
|
||
"display_name": "Max Results",
|
||
"dynamic": false,
|
||
"info": "Maximum number of results to return",
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "max_results",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_metadata": true,
|
||
"type": "int",
|
||
"value": 3
|
||
},
|
||
"search_query": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": false,
|
||
"display_name": "Search Query",
|
||
"dynamic": false,
|
||
"info": "The search query for arXiv papers (e.g., 'quantum computing')",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "search_query",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": true,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": ""
|
||
},
|
||
"search_type": {
|
||
"_input_type": "DropdownInput",
|
||
"advanced": false,
|
||
"combobox": false,
|
||
"dialog_inputs": {},
|
||
"display_name": "Search Field",
|
||
"dynamic": false,
|
||
"info": "The field to search in",
|
||
"name": "search_type",
|
||
"options": [
|
||
"all",
|
||
"title",
|
||
"abstract",
|
||
"author",
|
||
"cat"
|
||
],
|
||
"options_metadata": [],
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"toggle": false,
|
||
"tool_mode": false,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": "all"
|
||
}
|
||
},
|
||
"tool_mode": false
|
||
},
|
||
"showNode": true,
|
||
"type": "ArXivComponent"
|
||
},
|
||
"dragging": false,
|
||
"id": "ArXivComponent-WxSYF",
|
||
"measured": {
|
||
"height": 368,
|
||
"width": 320
|
||
},
|
||
"position": {
|
||
"x": 81.59312530546094,
|
||
"y": 3.9397854556273906
|
||
},
|
||
"selected": false,
|
||
"type": "genericNode"
|
||
},
|
||
{
|
||
"data": {
|
||
"id": "ChatOutput-ylHrO",
|
||
"node": {
|
||
"base_classes": [
|
||
"Message"
|
||
],
|
||
"beta": false,
|
||
"conditional_paths": [],
|
||
"custom_fields": {},
|
||
"description": "Display a chat message in the Playground.",
|
||
"display_name": "Chat Output",
|
||
"documentation": "",
|
||
"edited": false,
|
||
"field_order": [
|
||
"input_value",
|
||
"should_store_message",
|
||
"sender",
|
||
"sender_name",
|
||
"session_id",
|
||
"data_template",
|
||
"background_color",
|
||
"chat_icon",
|
||
"text_color",
|
||
"clean_data"
|
||
],
|
||
"frozen": false,
|
||
"icon": "MessagesSquare",
|
||
"legacy": false,
|
||
"lf_version": "1.4.3",
|
||
"metadata": {},
|
||
"minimized": true,
|
||
"output_types": [],
|
||
"outputs": [
|
||
{
|
||
"allows_loop": false,
|
||
"cache": true,
|
||
"display_name": "Output Message",
|
||
"group_outputs": false,
|
||
"method": "message_response",
|
||
"name": "message",
|
||
"selected": "Message",
|
||
"tool_mode": true,
|
||
"types": [
|
||
"Message"
|
||
],
|
||
"value": "__UNDEFINED__"
|
||
}
|
||
],
|
||
"pinned": false,
|
||
"template": {
|
||
"_type": "Component",
|
||
"background_color": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": true,
|
||
"display_name": "Background Color",
|
||
"dynamic": false,
|
||
"info": "The background color of the icon.",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "background_color",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": ""
|
||
},
|
||
"chat_icon": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": true,
|
||
"display_name": "Icon",
|
||
"dynamic": false,
|
||
"info": "The icon of the message.",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "chat_icon",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": ""
|
||
},
|
||
"clean_data": {
|
||
"_input_type": "BoolInput",
|
||
"advanced": true,
|
||
"display_name": "Basic Clean Data",
|
||
"dynamic": false,
|
||
"info": "Whether to clean the data",
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"name": "clean_data",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_metadata": true,
|
||
"type": "bool",
|
||
"value": true
|
||
},
|
||
"code": {
|
||
"advanced": true,
|
||
"dynamic": true,
|
||
"fileTypes": [],
|
||
"file_path": "",
|
||
"info": "",
|
||
"list": false,
|
||
"load_from_db": false,
|
||
"multiline": true,
|
||
"name": "code",
|
||
"password": false,
|
||
"placeholder": "",
|
||
"required": true,
|
||
"show": true,
|
||
"title_case": false,
|
||
"type": "code",
|
||
"value": "from collections.abc import Generator\nfrom typing import Any\n\nimport orjson\nfrom fastapi.encoders import jsonable_encoder\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.helpers.data import safe_convert\nfrom langflow.inputs.inputs import BoolInput, DropdownInput, HandleInput, MessageTextInput\nfrom langflow.schema.data import Data\nfrom langflow.schema.dataframe import DataFrame\nfrom langflow.schema.message import Message\nfrom langflow.schema.properties import Source\nfrom langflow.template.field.base import Output\nfrom langflow.utils.constants import (\n MESSAGE_SENDER_AI,\n MESSAGE_SENDER_NAME_AI,\n MESSAGE_SENDER_USER,\n)\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"MessagesSquare\"\n name = \"ChatOutput\"\n minimized = True\n\n inputs = [\n HandleInput(\n name=\"input_value\",\n display_name=\"Inputs\",\n info=\"Message to be passed as output.\",\n input_types=[\"Data\", \"DataFrame\", \"Message\"],\n required=True,\n ),\n BoolInput(\n name=\"should_store_message\",\n display_name=\"Store Messages\",\n info=\"Store the message in the history.\",\n value=True,\n advanced=True,\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER],\n value=MESSAGE_SENDER_AI,\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=MESSAGE_SENDER_NAME_AI,\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"The session ID of the chat. If empty, the current session ID parameter will be used.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n MessageTextInput(\n name=\"background_color\",\n display_name=\"Background Color\",\n info=\"The background color of the icon.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"chat_icon\",\n display_name=\"Icon\",\n info=\"The icon of the message.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"text_color\",\n display_name=\"Text Color\",\n info=\"The text color of the name\",\n advanced=True,\n ),\n BoolInput(\n name=\"clean_data\",\n display_name=\"Basic Clean Data\",\n value=True,\n info=\"Whether to clean the data\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(\n display_name=\"Output Message\",\n name=\"message\",\n method=\"message_response\",\n ),\n ]\n\n def _build_source(self, id_: str | None, display_name: str | None, source: str | None) -> Source:\n source_dict = {}\n if id_:\n source_dict[\"id\"] = id_\n if display_name:\n source_dict[\"display_name\"] = display_name\n if source:\n # Handle case where source is a ChatOpenAI object\n if hasattr(source, \"model_name\"):\n source_dict[\"source\"] = source.model_name\n elif hasattr(source, \"model\"):\n source_dict[\"source\"] = str(source.model)\n else:\n source_dict[\"source\"] = str(source)\n return Source(**source_dict)\n\n async def message_response(self) -> Message:\n # First convert the input to string if needed\n text = self.convert_to_string()\n\n # Get source properties\n source, icon, display_name, source_id = self.get_properties_from_source_component()\n background_color = self.background_color\n text_color = self.text_color\n if self.chat_icon:\n icon = self.chat_icon\n\n # Create or use existing Message object\n if isinstance(self.input_value, Message):\n message = self.input_value\n # Update message properties\n message.text = text\n else:\n message = Message(text=text)\n\n # Set message properties\n message.sender = self.sender\n message.sender_name = self.sender_name\n message.session_id = self.session_id\n message.flow_id = self.graph.flow_id if hasattr(self, \"graph\") else None\n message.properties.source = self._build_source(source_id, display_name, source)\n message.properties.icon = icon\n message.properties.background_color = background_color\n message.properties.text_color = text_color\n\n # Store message if needed\n if self.session_id and self.should_store_message:\n stored_message = await self.send_message(message)\n self.message.value = stored_message\n message = stored_message\n\n self.status = message\n return message\n\n def _serialize_data(self, data: Data) -> str:\n \"\"\"Serialize Data object to JSON string.\"\"\"\n # Convert data.data to JSON-serializable format\n serializable_data = jsonable_encoder(data.data)\n # Serialize with orjson, enabling pretty printing with indentation\n json_bytes = orjson.dumps(serializable_data, option=orjson.OPT_INDENT_2)\n # Convert bytes to string and wrap in Markdown code blocks\n return \"```json\\n\" + json_bytes.decode(\"utf-8\") + \"\\n```\"\n\n def _validate_input(self) -> None:\n \"\"\"Validate the input data and raise ValueError if invalid.\"\"\"\n if self.input_value is None:\n msg = \"Input data cannot be None\"\n raise ValueError(msg)\n if isinstance(self.input_value, list) and not all(\n isinstance(item, Message | Data | DataFrame | str) for item in self.input_value\n ):\n invalid_types = [\n type(item).__name__\n for item in self.input_value\n if not isinstance(item, Message | Data | DataFrame | str)\n ]\n msg = f\"Expected Data or DataFrame or Message or str, got {invalid_types}\"\n raise TypeError(msg)\n if not isinstance(\n self.input_value,\n Message | Data | DataFrame | str | list | Generator | type(None),\n ):\n type_name = type(self.input_value).__name__\n msg = f\"Expected Data or DataFrame or Message or str, Generator or None, got {type_name}\"\n raise TypeError(msg)\n\n def convert_to_string(self) -> str | Generator[Any, None, None]:\n \"\"\"Convert input data to string with proper error handling.\"\"\"\n self._validate_input()\n if isinstance(self.input_value, list):\n return \"\\n\".join([safe_convert(item, clean_data=self.clean_data) for item in self.input_value])\n if isinstance(self.input_value, Generator):\n return self.input_value\n return safe_convert(self.input_value)\n"
|
||
},
|
||
"data_template": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": true,
|
||
"display_name": "Data Template",
|
||
"dynamic": false,
|
||
"info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "data_template",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": "{text}"
|
||
},
|
||
"input_value": {
|
||
"_input_type": "HandleInput",
|
||
"advanced": false,
|
||
"display_name": "Inputs",
|
||
"dynamic": false,
|
||
"info": "Message to be passed as output.",
|
||
"input_types": [
|
||
"Data",
|
||
"DataFrame",
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"name": "input_value",
|
||
"placeholder": "",
|
||
"required": true,
|
||
"show": true,
|
||
"title_case": false,
|
||
"trace_as_metadata": true,
|
||
"type": "other",
|
||
"value": ""
|
||
},
|
||
"sender": {
|
||
"_input_type": "DropdownInput",
|
||
"advanced": true,
|
||
"combobox": false,
|
||
"dialog_inputs": {},
|
||
"display_name": "Sender Type",
|
||
"dynamic": false,
|
||
"info": "Type of sender.",
|
||
"name": "sender",
|
||
"options": [
|
||
"Machine",
|
||
"User"
|
||
],
|
||
"options_metadata": [],
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"toggle": false,
|
||
"tool_mode": false,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": "Machine"
|
||
},
|
||
"sender_name": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": true,
|
||
"display_name": "Sender Name",
|
||
"dynamic": false,
|
||
"info": "Name of the sender.",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "sender_name",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": "AI"
|
||
},
|
||
"session_id": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": true,
|
||
"display_name": "Session ID",
|
||
"dynamic": false,
|
||
"info": "The session ID of the chat. If empty, the current session ID parameter will be used.",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "session_id",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": ""
|
||
},
|
||
"should_store_message": {
|
||
"_input_type": "BoolInput",
|
||
"advanced": true,
|
||
"display_name": "Store Messages",
|
||
"dynamic": false,
|
||
"info": "Store the message in the history.",
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"name": "should_store_message",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_metadata": true,
|
||
"type": "bool",
|
||
"value": true
|
||
},
|
||
"text_color": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": true,
|
||
"display_name": "Text Color",
|
||
"dynamic": false,
|
||
"info": "The text color of the name",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "text_color",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": ""
|
||
}
|
||
},
|
||
"tool_mode": false
|
||
},
|
||
"showNode": false,
|
||
"type": "ChatOutput"
|
||
},
|
||
"dragging": false,
|
||
"id": "ChatOutput-ylHrO",
|
||
"measured": {
|
||
"height": 48,
|
||
"width": 192
|
||
},
|
||
"position": {
|
||
"x": 1340.6435418555936,
|
||
"y": 570.8905972487661
|
||
},
|
||
"selected": false,
|
||
"type": "genericNode"
|
||
},
|
||
{
|
||
"data": {
|
||
"id": "ChatInput-OF2vZ",
|
||
"node": {
|
||
"base_classes": [
|
||
"Message"
|
||
],
|
||
"beta": false,
|
||
"conditional_paths": [],
|
||
"custom_fields": {},
|
||
"description": "Get chat inputs from the Playground.",
|
||
"display_name": "Chat Input",
|
||
"documentation": "",
|
||
"edited": false,
|
||
"field_order": [
|
||
"input_value",
|
||
"should_store_message",
|
||
"sender",
|
||
"sender_name",
|
||
"session_id",
|
||
"files",
|
||
"background_color",
|
||
"chat_icon",
|
||
"text_color"
|
||
],
|
||
"frozen": false,
|
||
"icon": "MessagesSquare",
|
||
"legacy": false,
|
||
"lf_version": "1.4.3",
|
||
"metadata": {},
|
||
"minimized": true,
|
||
"output_types": [],
|
||
"outputs": [
|
||
{
|
||
"allows_loop": false,
|
||
"cache": true,
|
||
"display_name": "Chat Message",
|
||
"group_outputs": false,
|
||
"method": "message_response",
|
||
"name": "message",
|
||
"selected": "Message",
|
||
"tool_mode": true,
|
||
"types": [
|
||
"Message"
|
||
],
|
||
"value": "__UNDEFINED__"
|
||
}
|
||
],
|
||
"pinned": false,
|
||
"template": {
|
||
"_type": "Component",
|
||
"background_color": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": true,
|
||
"display_name": "Background Color",
|
||
"dynamic": false,
|
||
"info": "The background color of the icon.",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "background_color",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": ""
|
||
},
|
||
"chat_icon": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": true,
|
||
"display_name": "Icon",
|
||
"dynamic": false,
|
||
"info": "The icon of the message.",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "chat_icon",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": ""
|
||
},
|
||
"code": {
|
||
"advanced": true,
|
||
"dynamic": true,
|
||
"fileTypes": [],
|
||
"file_path": "",
|
||
"info": "",
|
||
"list": false,
|
||
"load_from_db": false,
|
||
"multiline": true,
|
||
"name": "code",
|
||
"password": false,
|
||
"placeholder": "",
|
||
"required": true,
|
||
"show": true,
|
||
"title_case": false,
|
||
"type": "code",
|
||
"value": "from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.inputs.inputs import BoolInput\nfrom langflow.io import (\n DropdownInput,\n FileInput,\n MessageTextInput,\n MultilineInput,\n Output,\n)\nfrom langflow.schema.message import Message\nfrom langflow.utils.constants import (\n MESSAGE_SENDER_AI,\n MESSAGE_SENDER_NAME_USER,\n MESSAGE_SENDER_USER,\n)\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"MessagesSquare\"\n name = \"ChatInput\"\n minimized = True\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n input_types=[],\n ),\n BoolInput(\n name=\"should_store_message\",\n display_name=\"Store Messages\",\n info=\"Store the message in the history.\",\n value=True,\n advanced=True,\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER],\n value=MESSAGE_SENDER_USER,\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=MESSAGE_SENDER_NAME_USER,\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"The session ID of the chat. If empty, the current session ID parameter will be used.\",\n advanced=True,\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n temp_file=True,\n ),\n MessageTextInput(\n name=\"background_color\",\n display_name=\"Background Color\",\n info=\"The background color of the icon.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"chat_icon\",\n display_name=\"Icon\",\n info=\"The icon of the message.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"text_color\",\n display_name=\"Text Color\",\n info=\"The text color of the name\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Chat Message\", name=\"message\", method=\"message_response\"),\n ]\n\n async def message_response(self) -> Message:\n background_color = self.background_color\n text_color = self.text_color\n icon = self.chat_icon\n\n message = await Message.create(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n properties={\n \"background_color\": background_color,\n \"text_color\": text_color,\n \"icon\": icon,\n },\n )\n if self.session_id and isinstance(message, Message) and self.should_store_message:\n stored_message = await self.send_message(\n message,\n )\n self.message.value = stored_message\n message = stored_message\n\n self.status = message\n return message\n"
|
||
},
|
||
"files": {
|
||
"_input_type": "FileInput",
|
||
"advanced": true,
|
||
"display_name": "Files",
|
||
"dynamic": false,
|
||
"fileTypes": [
|
||
"txt",
|
||
"md",
|
||
"mdx",
|
||
"csv",
|
||
"json",
|
||
"yaml",
|
||
"yml",
|
||
"xml",
|
||
"html",
|
||
"htm",
|
||
"pdf",
|
||
"docx",
|
||
"py",
|
||
"sh",
|
||
"sql",
|
||
"js",
|
||
"ts",
|
||
"tsx",
|
||
"jpg",
|
||
"jpeg",
|
||
"png",
|
||
"bmp",
|
||
"image"
|
||
],
|
||
"file_path": "",
|
||
"info": "Files to be sent with the message.",
|
||
"list": true,
|
||
"list_add_label": "Add More",
|
||
"name": "files",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"temp_file": true,
|
||
"title_case": false,
|
||
"trace_as_metadata": true,
|
||
"type": "file",
|
||
"value": ""
|
||
},
|
||
"input_value": {
|
||
"_input_type": "MultilineInput",
|
||
"advanced": false,
|
||
"copy_field": false,
|
||
"display_name": "Input Text",
|
||
"dynamic": false,
|
||
"info": "Message to be passed as input.",
|
||
"input_types": [],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"multiline": true,
|
||
"name": "input_value",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": "ai"
|
||
},
|
||
"sender": {
|
||
"_input_type": "DropdownInput",
|
||
"advanced": true,
|
||
"combobox": false,
|
||
"dialog_inputs": {},
|
||
"display_name": "Sender Type",
|
||
"dynamic": false,
|
||
"info": "Type of sender.",
|
||
"name": "sender",
|
||
"options": [
|
||
"Machine",
|
||
"User"
|
||
],
|
||
"options_metadata": [],
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"toggle": false,
|
||
"tool_mode": false,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": "User"
|
||
},
|
||
"sender_name": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": true,
|
||
"display_name": "Sender Name",
|
||
"dynamic": false,
|
||
"info": "Name of the sender.",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "sender_name",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": "User"
|
||
},
|
||
"session_id": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": true,
|
||
"display_name": "Session ID",
|
||
"dynamic": false,
|
||
"info": "The session ID of the chat. If empty, the current session ID parameter will be used.",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "session_id",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": ""
|
||
},
|
||
"should_store_message": {
|
||
"_input_type": "BoolInput",
|
||
"advanced": true,
|
||
"display_name": "Store Messages",
|
||
"dynamic": false,
|
||
"info": "Store the message in the history.",
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"name": "should_store_message",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_metadata": true,
|
||
"type": "bool",
|
||
"value": true
|
||
},
|
||
"text_color": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": true,
|
||
"display_name": "Text Color",
|
||
"dynamic": false,
|
||
"info": "The text color of the name",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "text_color",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": ""
|
||
}
|
||
},
|
||
"tool_mode": false
|
||
},
|
||
"showNode": true,
|
||
"type": "ChatInput"
|
||
},
|
||
"dragging": false,
|
||
"id": "ChatInput-OF2vZ",
|
||
"measured": {
|
||
"height": 203,
|
||
"width": 320
|
||
},
|
||
"position": {
|
||
"x": -333.65585758816223,
|
||
"y": 107.75353484470551
|
||
},
|
||
"selected": false,
|
||
"type": "genericNode"
|
||
},
|
||
{
|
||
"data": {
|
||
"id": "note-uG7pK",
|
||
"node": {
|
||
"description": "### 💡 Add your Anthropic API key here 👇",
|
||
"display_name": "",
|
||
"documentation": "",
|
||
"template": {
|
||
"backgroundColor": "transparent"
|
||
}
|
||
},
|
||
"type": "note"
|
||
},
|
||
"dragging": false,
|
||
"height": 324,
|
||
"id": "note-uG7pK",
|
||
"measured": {
|
||
"height": 324,
|
||
"width": 359
|
||
},
|
||
"position": {
|
||
"x": 1479.4278434913201,
|
||
"y": -274.26903478612456
|
||
},
|
||
"resizing": false,
|
||
"selected": false,
|
||
"type": "noteNode",
|
||
"width": 359
|
||
},
|
||
{
|
||
"data": {
|
||
"id": "note-F4Ff1",
|
||
"node": {
|
||
"description": "# **Langflow Loop Component Template - ArXiv search result Translator** \nThis template translates research paper summaries on ArXiv into Portuguese and summarizes them. \n Using **Langflow’s looping mechanism**, the template iterates through multiple research papers, translates them with the **OpenAI** model component, and outputs an aggregated version of all translated papers. \n\n## Quickstart \n 1. Add your OpenAI API key to the **Language Model** component. \n2. In the **Playground**, enter a query related to a research topic (for example, “Quantum Computing Advancements”). \n\n The flow fetches a list of research papers from ArXiv matching the query. Each paper in the retrieved list is processed one-by-one using the Langflow **Loop component**. \n\n The abstract of each paper is translated into Portuguese by the **OpenAI** model component. \n\n Once all papers are translated, the system aggregates them into a **single structured output**.",
|
||
"display_name": "",
|
||
"documentation": "",
|
||
"template": {}
|
||
},
|
||
"type": "note"
|
||
},
|
||
"dragging": false,
|
||
"height": 647,
|
||
"id": "note-F4Ff1",
|
||
"measured": {
|
||
"height": 647,
|
||
"width": 576
|
||
},
|
||
"position": {
|
||
"x": -890.9006297459302,
|
||
"y": -233.44894493951168
|
||
},
|
||
"resizing": false,
|
||
"selected": false,
|
||
"type": "noteNode",
|
||
"width": 576
|
||
},
|
||
{
|
||
"data": {
|
||
"id": "ParserComponent-2OCL9",
|
||
"node": {
|
||
"base_classes": [
|
||
"Message"
|
||
],
|
||
"beta": false,
|
||
"conditional_paths": [],
|
||
"custom_fields": {},
|
||
"description": "Extracts text using a template.",
|
||
"display_name": "Parser",
|
||
"documentation": "",
|
||
"edited": false,
|
||
"field_order": [
|
||
"input_data",
|
||
"mode",
|
||
"pattern",
|
||
"sep"
|
||
],
|
||
"frozen": false,
|
||
"icon": "braces",
|
||
"legacy": false,
|
||
"metadata": {},
|
||
"minimized": false,
|
||
"output_types": [],
|
||
"outputs": [
|
||
{
|
||
"allows_loop": false,
|
||
"cache": true,
|
||
"display_name": "Parsed Text",
|
||
"group_outputs": false,
|
||
"method": "parse_combined_text",
|
||
"name": "parsed_text",
|
||
"selected": "Message",
|
||
"tool_mode": true,
|
||
"types": [
|
||
"Message"
|
||
],
|
||
"value": "__UNDEFINED__"
|
||
}
|
||
],
|
||
"pinned": false,
|
||
"template": {
|
||
"_type": "Component",
|
||
"code": {
|
||
"advanced": true,
|
||
"dynamic": true,
|
||
"fileTypes": [],
|
||
"file_path": "",
|
||
"info": "",
|
||
"list": false,
|
||
"load_from_db": false,
|
||
"multiline": true,
|
||
"name": "code",
|
||
"password": false,
|
||
"placeholder": "",
|
||
"required": true,
|
||
"show": true,
|
||
"title_case": false,
|
||
"type": "code",
|
||
"value": "from langflow.custom.custom_component.component import Component\nfrom langflow.helpers.data import safe_convert\nfrom langflow.inputs.inputs import BoolInput, HandleInput, MessageTextInput, MultilineInput, TabInput\nfrom langflow.schema.data import Data\nfrom langflow.schema.dataframe import DataFrame\nfrom langflow.schema.message import Message\nfrom langflow.template.field.base import Output\n\n\nclass ParserComponent(Component):\n display_name = \"Parser\"\n description = \"Extracts text using a template.\"\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 formatted_text = self.pattern.format(**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"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"name": "input_data",
|
||
"placeholder": "",
|
||
"required": true,
|
||
"show": true,
|
||
"title_case": false,
|
||
"trace_as_metadata": true,
|
||
"type": "other",
|
||
"value": ""
|
||
},
|
||
"mode": {
|
||
"_input_type": "TabInput",
|
||
"advanced": false,
|
||
"display_name": "Mode",
|
||
"dynamic": false,
|
||
"info": "Convert into raw string instead of using a template.",
|
||
"load_from_db": false,
|
||
"name": "mode",
|
||
"options": [
|
||
"Parser",
|
||
"Stringify"
|
||
],
|
||
"placeholder": "",
|
||
"real_time_refresh": true,
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_metadata": true,
|
||
"type": "tab",
|
||
"value": "Stringify"
|
||
},
|
||
"pattern": {
|
||
"_input_type": "MultilineInput",
|
||
"advanced": false,
|
||
"copy_field": false,
|
||
"display_name": "Template",
|
||
"dynamic": true,
|
||
"info": "Use variables within curly brackets to extract column values for DataFrames or key values for Data.For example: `Name: {Name}, Age: {Age}, Country: {Country}`",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"multiline": true,
|
||
"name": "pattern",
|
||
"placeholder": "",
|
||
"required": true,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": "Text: {dt}"
|
||
},
|
||
"sep": {
|
||
"_input_type": "MessageTextInput",
|
||
"advanced": true,
|
||
"display_name": "Separator",
|
||
"dynamic": false,
|
||
"info": "String used to separate rows/items.",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "sep",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": "\n"
|
||
}
|
||
},
|
||
"tool_mode": false
|
||
},
|
||
"showNode": true,
|
||
"type": "ParserComponent"
|
||
},
|
||
"dragging": false,
|
||
"id": "ParserComponent-2OCL9",
|
||
"measured": {
|
||
"height": 328,
|
||
"width": 320
|
||
},
|
||
"position": {
|
||
"x": 971.3987248215344,
|
||
"y": -186.6658506576822
|
||
},
|
||
"selected": false,
|
||
"type": "genericNode"
|
||
},
|
||
{
|
||
"data": {
|
||
"id": "LoopComponent-zuKTL",
|
||
"node": {
|
||
"base_classes": [
|
||
"Data",
|
||
"DataFrame"
|
||
],
|
||
"beta": false,
|
||
"conditional_paths": [],
|
||
"custom_fields": {},
|
||
"description": "Iterates over a list of Data objects, outputting one item at a time and aggregating results from loop inputs.",
|
||
"display_name": "Loop",
|
||
"documentation": "",
|
||
"edited": false,
|
||
"field_order": [
|
||
"data"
|
||
],
|
||
"frozen": false,
|
||
"icon": "infinity",
|
||
"legacy": false,
|
||
"lf_version": "1.4.3",
|
||
"metadata": {},
|
||
"minimized": false,
|
||
"output_types": [],
|
||
"outputs": [
|
||
{
|
||
"allows_loop": true,
|
||
"cache": true,
|
||
"display_name": "Item",
|
||
"group_outputs": true,
|
||
"method": "item_output",
|
||
"name": "item",
|
||
"selected": "Data",
|
||
"tool_mode": true,
|
||
"types": [
|
||
"Data"
|
||
],
|
||
"value": "__UNDEFINED__"
|
||
},
|
||
{
|
||
"allows_loop": false,
|
||
"cache": true,
|
||
"display_name": "Done",
|
||
"group_outputs": true,
|
||
"method": "done_output",
|
||
"name": "done",
|
||
"selected": "DataFrame",
|
||
"tool_mode": true,
|
||
"types": [
|
||
"DataFrame"
|
||
],
|
||
"value": "__UNDEFINED__"
|
||
}
|
||
],
|
||
"pinned": false,
|
||
"template": {
|
||
"_type": "Component",
|
||
"code": {
|
||
"advanced": true,
|
||
"dynamic": true,
|
||
"fileTypes": [],
|
||
"file_path": "",
|
||
"info": "",
|
||
"list": false,
|
||
"load_from_db": false,
|
||
"multiline": true,
|
||
"name": "code",
|
||
"password": false,
|
||
"placeholder": "",
|
||
"required": true,
|
||
"show": true,
|
||
"title_case": false,
|
||
"type": "code",
|
||
"value": "from langflow.custom.custom_component.component import Component\nfrom langflow.inputs.inputs import HandleInput\nfrom langflow.schema.data import Data\nfrom langflow.schema.dataframe import DataFrame\nfrom langflow.template.field.base import Output\n\n\nclass LoopComponent(Component):\n display_name = \"Loop\"\n description = (\n \"Iterates over a list of Data objects, outputting one item at a time and aggregating results from loop inputs.\"\n )\n icon = \"infinity\"\n\n inputs = [\n HandleInput(\n name=\"data\",\n display_name=\"Inputs\",\n info=\"The initial list of Data objects or DataFrame to iterate over.\",\n input_types=[\"DataFrame\"],\n ),\n ]\n\n outputs = [\n Output(display_name=\"Item\", name=\"item\", method=\"item_output\", allows_loop=True, group_outputs=True),\n Output(display_name=\"Done\", name=\"done\", method=\"done_output\", group_outputs=True),\n ]\n\n def initialize_data(self) -> None:\n \"\"\"Initialize the data list, context index, and aggregated list.\"\"\"\n if self.ctx.get(f\"{self._id}_initialized\", False):\n return\n\n # Ensure data is a list of Data objects\n data_list = self._validate_data(self.data)\n\n # Store the initial data and context variables\n self.update_ctx(\n {\n f\"{self._id}_data\": data_list,\n f\"{self._id}_index\": 0,\n f\"{self._id}_aggregated\": [],\n f\"{self._id}_initialized\": True,\n }\n )\n\n def _validate_data(self, data):\n \"\"\"Validate and return a list of Data objects.\"\"\"\n if isinstance(data, DataFrame):\n return data.to_data_list()\n if isinstance(data, Data):\n return [data]\n if isinstance(data, list) and all(isinstance(item, Data) for item in data):\n return data\n msg = \"The 'data' input must be a DataFrame, a list of Data objects, or a single Data object.\"\n raise TypeError(msg)\n\n def evaluate_stop_loop(self) -> bool:\n \"\"\"Evaluate whether to stop item or done output.\"\"\"\n current_index = self.ctx.get(f\"{self._id}_index\", 0)\n data_length = len(self.ctx.get(f\"{self._id}_data\", []))\n return current_index > data_length\n\n def item_output(self) -> Data:\n \"\"\"Output the next item in the list or stop if done.\"\"\"\n self.initialize_data()\n current_item = Data(text=\"\")\n\n if self.evaluate_stop_loop():\n self.stop(\"item\")\n else:\n # Get data list and current index\n data_list, current_index = self.loop_variables()\n if current_index < len(data_list):\n # Output current item and increment index\n try:\n current_item = data_list[current_index]\n except IndexError:\n current_item = Data(text=\"\")\n self.aggregated_output()\n self.update_ctx({f\"{self._id}_index\": current_index + 1})\n\n # Now we need to update the dependencies for the next run\n self.update_dependency()\n return current_item\n\n def update_dependency(self):\n item_dependency_id = self.get_incoming_edge_by_target_param(\"item\")\n\n self.graph.run_manager.run_predecessors[self._id].append(item_dependency_id)\n\n def done_output(self) -> DataFrame:\n \"\"\"Trigger the done output when iteration is complete.\"\"\"\n self.initialize_data()\n\n if self.evaluate_stop_loop():\n self.stop(\"item\")\n self.start(\"done\")\n\n aggregated = self.ctx.get(f\"{self._id}_aggregated\", [])\n\n return DataFrame(aggregated)\n self.stop(\"done\")\n return DataFrame([])\n\n def loop_variables(self):\n \"\"\"Retrieve loop variables from context.\"\"\"\n return (\n self.ctx.get(f\"{self._id}_data\", []),\n self.ctx.get(f\"{self._id}_index\", 0),\n )\n\n def aggregated_output(self) -> list[Data]:\n \"\"\"Return the aggregated list once all items are processed.\"\"\"\n self.initialize_data()\n\n # Get data list and aggregated list\n data_list = self.ctx.get(f\"{self._id}_data\", [])\n aggregated = self.ctx.get(f\"{self._id}_aggregated\", [])\n loop_input = self.item\n if loop_input is not None and not isinstance(loop_input, str) and len(aggregated) <= len(data_list):\n aggregated.append(loop_input)\n self.update_ctx({f\"{self._id}_aggregated\": aggregated})\n return aggregated\n"
|
||
},
|
||
"data": {
|
||
"_input_type": "HandleInput",
|
||
"advanced": false,
|
||
"display_name": "Inputs",
|
||
"dynamic": false,
|
||
"info": "The initial list of Data objects or DataFrame to iterate over.",
|
||
"input_types": [
|
||
"DataFrame"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"name": "data",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"trace_as_metadata": true,
|
||
"type": "other",
|
||
"value": ""
|
||
}
|
||
},
|
||
"tool_mode": false
|
||
},
|
||
"showNode": true,
|
||
"type": "LoopComponent"
|
||
},
|
||
"dragging": false,
|
||
"id": "LoopComponent-zuKTL",
|
||
"measured": {
|
||
"height": 241,
|
||
"width": 320
|
||
},
|
||
"position": {
|
||
"x": 541.1188345961908,
|
||
"y": 181.38181401206583
|
||
},
|
||
"selected": false,
|
||
"type": "genericNode"
|
||
},
|
||
{
|
||
"data": {
|
||
"id": "TypeConverterComponent-mWgMR",
|
||
"node": {
|
||
"base_classes": [
|
||
"Message"
|
||
],
|
||
"beta": false,
|
||
"category": "processing",
|
||
"conditional_paths": [],
|
||
"custom_fields": {},
|
||
"description": "Convert between different types (Message, Data, DataFrame)",
|
||
"display_name": "Type Convert",
|
||
"documentation": "",
|
||
"edited": false,
|
||
"field_order": [
|
||
"input_data",
|
||
"output_type"
|
||
],
|
||
"frozen": false,
|
||
"icon": "repeat",
|
||
"key": "TypeConverterComponent",
|
||
"legacy": false,
|
||
"lf_version": "1.4.3",
|
||
"metadata": {},
|
||
"minimized": false,
|
||
"output_types": [],
|
||
"outputs": [
|
||
{
|
||
"allows_loop": false,
|
||
"cache": true,
|
||
"display_name": "Message Output",
|
||
"group_outputs": false,
|
||
"method": "convert_to_message",
|
||
"name": "message_output",
|
||
"selected": "Message",
|
||
"tool_mode": true,
|
||
"types": [
|
||
"Message"
|
||
],
|
||
"value": "__UNDEFINED__"
|
||
}
|
||
],
|
||
"pinned": false,
|
||
"score": 0.008834292878014125,
|
||
"template": {
|
||
"_type": "Component",
|
||
"code": {
|
||
"advanced": true,
|
||
"dynamic": true,
|
||
"fileTypes": [],
|
||
"file_path": "",
|
||
"info": "",
|
||
"list": false,
|
||
"load_from_db": false,
|
||
"multiline": true,
|
||
"name": "code",
|
||
"password": false,
|
||
"placeholder": "",
|
||
"required": true,
|
||
"show": true,
|
||
"title_case": false,
|
||
"type": "code",
|
||
"value": "from typing import Any\n\nfrom langflow.custom import Component\nfrom langflow.io import HandleInput, Output, TabInput\nfrom langflow.schema import Data, DataFrame, Message\n\n\ndef convert_to_message(v) -> Message:\n \"\"\"Convert input to Message type.\n\n Args:\n v: Input to convert (Message, Data, DataFrame, or dict)\n\n Returns:\n Message: Converted Message object\n \"\"\"\n return v if isinstance(v, Message) else v.to_message()\n\n\ndef convert_to_data(v: DataFrame | Data | Message | dict) -> Data:\n \"\"\"Convert input to Data type.\n\n Args:\n v: Input to convert (Message, Data, DataFrame, or dict)\n\n Returns:\n Data: Converted Data object\n \"\"\"\n if isinstance(v, dict):\n return Data(v)\n return v if isinstance(v, Data) else v.to_data()\n\n\ndef convert_to_dataframe(v: DataFrame | Data | Message | dict) -> DataFrame:\n \"\"\"Convert input to DataFrame type.\n\n Args:\n v: Input to convert (Message, Data, DataFrame, or dict)\n\n Returns:\n DataFrame: Converted DataFrame object\n \"\"\"\n if isinstance(v, dict):\n return DataFrame([v])\n return v if isinstance(v, DataFrame) else v.to_dataframe()\n\n\nclass TypeConverterComponent(Component):\n display_name = \"Type Convert\"\n description = \"Convert between different types (Message, Data, DataFrame)\"\n icon = \"repeat\"\n\n inputs = [\n HandleInput(\n name=\"input_data\",\n display_name=\"Input\",\n input_types=[\"Message\", \"Data\", \"DataFrame\"],\n info=\"Accept Message, Data or DataFrame as input\",\n required=True,\n ),\n TabInput(\n name=\"output_type\",\n display_name=\"Output Type\",\n options=[\"Message\", \"Data\", \"DataFrame\"],\n info=\"Select the desired output data type\",\n real_time_refresh=True,\n value=\"Message\",\n ),\n ]\n\n outputs = [\n Output(\n display_name=\"Message Output\",\n name=\"message_output\",\n method=\"convert_to_message\",\n )\n ]\n\n def update_outputs(self, frontend_node: dict, field_name: str, field_value: Any) -> dict:\n \"\"\"Dynamically show only the relevant output based on the selected output type.\"\"\"\n if field_name == \"output_type\":\n # Start with empty outputs\n frontend_node[\"outputs\"] = []\n\n # Add only the selected output type\n if field_value == \"Message\":\n frontend_node[\"outputs\"].append(\n Output(\n display_name=\"Message Output\",\n name=\"message_output\",\n method=\"convert_to_message\",\n ).to_dict()\n )\n elif field_value == \"Data\":\n frontend_node[\"outputs\"].append(\n Output(\n display_name=\"Data Output\",\n name=\"data_output\",\n method=\"convert_to_data\",\n ).to_dict()\n )\n elif field_value == \"DataFrame\":\n frontend_node[\"outputs\"].append(\n Output(\n display_name=\"DataFrame Output\",\n name=\"dataframe_output\",\n method=\"convert_to_dataframe\",\n ).to_dict()\n )\n\n return frontend_node\n\n def convert_to_message(self) -> Message:\n \"\"\"Convert input to Message type.\"\"\"\n input_value = self.input_data[0] if isinstance(self.input_data, list) else self.input_data\n\n # Handle string input by converting to Message first\n if isinstance(input_value, str):\n input_value = Message(text=input_value)\n\n result = convert_to_message(input_value)\n self.status = result\n return result\n\n def convert_to_data(self) -> Data:\n \"\"\"Convert input to Data type.\"\"\"\n input_value = self.input_data[0] if isinstance(self.input_data, list) else self.input_data\n\n # Handle string input by converting to Message first\n if isinstance(input_value, str):\n input_value = Message(text=input_value)\n\n result = convert_to_data(input_value)\n self.status = result\n return result\n\n def convert_to_dataframe(self) -> DataFrame:\n \"\"\"Convert input to DataFrame type.\"\"\"\n input_value = self.input_data[0] if isinstance(self.input_data, list) else self.input_data\n\n # Handle string input by converting to Message first\n if isinstance(input_value, str):\n input_value = Message(text=input_value)\n\n result = convert_to_dataframe(input_value)\n self.status = result\n return result\n"
|
||
},
|
||
"input_data": {
|
||
"_input_type": "HandleInput",
|
||
"advanced": false,
|
||
"display_name": "Input",
|
||
"dynamic": false,
|
||
"info": "Accept Message, Data or DataFrame as input",
|
||
"input_types": [
|
||
"Message",
|
||
"Data",
|
||
"DataFrame"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"name": "input_data",
|
||
"placeholder": "",
|
||
"required": true,
|
||
"show": true,
|
||
"title_case": false,
|
||
"trace_as_metadata": true,
|
||
"type": "other",
|
||
"value": ""
|
||
},
|
||
"output_type": {
|
||
"_input_type": "TabInput",
|
||
"advanced": false,
|
||
"display_name": "Output Type",
|
||
"dynamic": false,
|
||
"info": "Select the desired output data type",
|
||
"name": "output_type",
|
||
"options": [
|
||
"Message",
|
||
"Data",
|
||
"DataFrame"
|
||
],
|
||
"placeholder": "",
|
||
"real_time_refresh": true,
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_metadata": true,
|
||
"type": "tab",
|
||
"value": "Message"
|
||
}
|
||
},
|
||
"tool_mode": false
|
||
},
|
||
"showNode": true,
|
||
"type": "TypeConverterComponent"
|
||
},
|
||
"dragging": false,
|
||
"id": "TypeConverterComponent-mWgMR",
|
||
"measured": {
|
||
"height": 262,
|
||
"width": 320
|
||
},
|
||
"position": {
|
||
"x": 949.5742678542961,
|
||
"y": 469.18776022439897
|
||
},
|
||
"selected": false,
|
||
"type": "genericNode"
|
||
},
|
||
{
|
||
"data": {
|
||
"id": "LanguageModelComponent-Te29P",
|
||
"node": {
|
||
"base_classes": [
|
||
"LanguageModel",
|
||
"Message"
|
||
],
|
||
"beta": false,
|
||
"conditional_paths": [],
|
||
"custom_fields": {},
|
||
"description": "Runs a language model given a specified provider. ",
|
||
"display_name": "Language Model",
|
||
"documentation": "",
|
||
"edited": false,
|
||
"field_order": [
|
||
"provider",
|
||
"model_name",
|
||
"api_key",
|
||
"input_value",
|
||
"system_message",
|
||
"stream",
|
||
"temperature"
|
||
],
|
||
"frozen": false,
|
||
"icon": "brain-circuit",
|
||
"legacy": false,
|
||
"metadata": {
|
||
"keywords": [
|
||
"model",
|
||
"llm",
|
||
"language model",
|
||
"large language model"
|
||
]
|
||
},
|
||
"minimized": false,
|
||
"output_types": [],
|
||
"outputs": [
|
||
{
|
||
"allows_loop": false,
|
||
"cache": true,
|
||
"display_name": "Model Response",
|
||
"group_outputs": false,
|
||
"method": "text_response",
|
||
"name": "text_output",
|
||
"selected": "Message",
|
||
"tool_mode": true,
|
||
"types": [
|
||
"Message"
|
||
],
|
||
"value": "__UNDEFINED__"
|
||
},
|
||
{
|
||
"allows_loop": false,
|
||
"cache": true,
|
||
"display_name": "Language Model",
|
||
"group_outputs": false,
|
||
"method": "build_model",
|
||
"name": "model_output",
|
||
"selected": "LanguageModel",
|
||
"tool_mode": true,
|
||
"types": [
|
||
"LanguageModel"
|
||
],
|
||
"value": "__UNDEFINED__"
|
||
}
|
||
],
|
||
"pinned": false,
|
||
"priority": 0,
|
||
"template": {
|
||
"_type": "Component",
|
||
"api_key": {
|
||
"_input_type": "SecretStrInput",
|
||
"advanced": false,
|
||
"display_name": "OpenAI API Key",
|
||
"dynamic": false,
|
||
"info": "Model Provider API key",
|
||
"input_types": [],
|
||
"load_from_db": true,
|
||
"name": "api_key",
|
||
"password": true,
|
||
"placeholder": "",
|
||
"real_time_refresh": true,
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"type": "str",
|
||
"value": "OPENAI_API_KEY"
|
||
},
|
||
"code": {
|
||
"advanced": true,
|
||
"dynamic": true,
|
||
"fileTypes": [],
|
||
"file_path": "",
|
||
"info": "",
|
||
"list": false,
|
||
"load_from_db": false,
|
||
"multiline": true,
|
||
"name": "code",
|
||
"password": false,
|
||
"placeholder": "",
|
||
"required": true,
|
||
"show": true,
|
||
"title_case": false,
|
||
"type": "code",
|
||
"value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom langflow.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom langflow.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import OPENAI_MODEL_NAMES\nfrom langflow.field_typing import LanguageModel\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.inputs.inputs import BoolInput\nfrom langflow.io import DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput\nfrom langflow.schema.dotdict import dotdict\n\n\nclass LanguageModelComponent(LCModelComponent):\n display_name = \"Language Model\"\n description = \"Runs a language model given a specified provider. \"\n icon = \"brain-circuit\"\n category = \"models\"\n priority = 0 # Set priority to 0 to make it appear first\n\n inputs = [\n DropdownInput(\n name=\"provider\",\n display_name=\"Model Provider\",\n options=[\"OpenAI\", \"Anthropic\", \"Google\"],\n value=\"OpenAI\",\n info=\"Select the model provider\",\n real_time_refresh=True,\n options_metadata=[{\"icon\": \"OpenAI\"}, {\"icon\": \"Anthropic\"}, {\"icon\": \"GoogleGenerativeAI\"}],\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n options=OPENAI_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[0],\n info=\"Select the model to use\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"Model Provider API key\",\n required=False,\n show=True,\n real_time_refresh=True,\n ),\n MessageInput(\n name=\"input_value\",\n display_name=\"Input\",\n info=\"The input text to send to the model\",\n ),\n MultilineInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"A system message that helps set the behavior of the assistant\",\n advanced=True,\n ),\n BoolInput(\n name=\"stream\",\n display_name=\"Stream\",\n info=\"Whether to stream the response\",\n value=False,\n advanced=True,\n ),\n SliderInput(\n name=\"temperature\",\n display_name=\"Temperature\",\n value=0.1,\n info=\"Controls randomness in responses\",\n range_spec=RangeSpec(min=0, max=1, step=0.01),\n advanced=True,\n ),\n ]\n\n def build_model(self) -> LanguageModel:\n provider = self.provider\n model_name = self.model_name\n temperature = self.temperature\n stream = self.stream\n\n if provider == \"OpenAI\":\n if not self.api_key:\n msg = \"OpenAI API key is required when using OpenAI provider\"\n raise ValueError(msg)\n return ChatOpenAI(\n model_name=model_name,\n temperature=temperature,\n streaming=stream,\n openai_api_key=self.api_key,\n )\n if provider == \"Anthropic\":\n if not self.api_key:\n msg = \"Anthropic API key is required when using Anthropic provider\"\n raise ValueError(msg)\n return ChatAnthropic(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n anthropic_api_key=self.api_key,\n )\n if provider == \"Google\":\n if not self.api_key:\n msg = \"Google API key is required when using Google provider\"\n raise ValueError(msg)\n return ChatGoogleGenerativeAI(\n model=model_name,\n temperature=temperature,\n streaming=stream,\n google_api_key=self.api_key,\n )\n msg = f\"Unknown provider: {provider}\"\n raise ValueError(msg)\n\n def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:\n if field_name == \"provider\":\n if field_value == \"OpenAI\":\n build_config[\"model_name\"][\"options\"] = OPENAI_MODEL_NAMES\n build_config[\"model_name\"][\"value\"] = OPENAI_MODEL_NAMES[0]\n build_config[\"api_key\"][\"display_name\"] = \"OpenAI API Key\"\n elif field_value == \"Anthropic\":\n build_config[\"model_name\"][\"options\"] = ANTHROPIC_MODELS\n build_config[\"model_name\"][\"value\"] = ANTHROPIC_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Anthropic API Key\"\n elif field_value == \"Google\":\n build_config[\"model_name\"][\"options\"] = GOOGLE_GENERATIVE_AI_MODELS\n build_config[\"model_name\"][\"value\"] = GOOGLE_GENERATIVE_AI_MODELS[0]\n build_config[\"api_key\"][\"display_name\"] = \"Google API Key\"\n return build_config\n"
|
||
},
|
||
"input_value": {
|
||
"_input_type": "MessageInput",
|
||
"advanced": false,
|
||
"display_name": "Input",
|
||
"dynamic": false,
|
||
"info": "The input text to send to the model",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "input_value",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": ""
|
||
},
|
||
"model_name": {
|
||
"_input_type": "DropdownInput",
|
||
"advanced": false,
|
||
"combobox": false,
|
||
"dialog_inputs": {},
|
||
"display_name": "Model Name",
|
||
"dynamic": false,
|
||
"info": "Select the model to use",
|
||
"name": "model_name",
|
||
"options": [
|
||
"gpt-4o-mini",
|
||
"gpt-4o",
|
||
"gpt-4.1",
|
||
"gpt-4.1-mini",
|
||
"gpt-4.1-nano",
|
||
"gpt-4.5-preview",
|
||
"gpt-4-turbo",
|
||
"gpt-4-turbo-preview",
|
||
"gpt-4",
|
||
"gpt-3.5-turbo"
|
||
],
|
||
"options_metadata": [],
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"toggle": false,
|
||
"tool_mode": false,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": "gpt-4o-mini"
|
||
},
|
||
"provider": {
|
||
"_input_type": "DropdownInput",
|
||
"advanced": false,
|
||
"combobox": false,
|
||
"dialog_inputs": {},
|
||
"display_name": "Model Provider",
|
||
"dynamic": false,
|
||
"info": "Select the model provider",
|
||
"name": "provider",
|
||
"options": [
|
||
"OpenAI",
|
||
"Anthropic",
|
||
"Google"
|
||
],
|
||
"options_metadata": [
|
||
{
|
||
"icon": "Anthropic"
|
||
},
|
||
{
|
||
"icon": "OpenAI"
|
||
},
|
||
{
|
||
"icon": "Google"
|
||
}
|
||
],
|
||
"placeholder": "",
|
||
"real_time_refresh": true,
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"toggle": false,
|
||
"tool_mode": false,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": "OpenAI"
|
||
},
|
||
"stream": {
|
||
"_input_type": "BoolInput",
|
||
"advanced": true,
|
||
"display_name": "Stream",
|
||
"dynamic": false,
|
||
"info": "Whether to stream the response",
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"name": "stream",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_metadata": true,
|
||
"type": "bool",
|
||
"value": false
|
||
},
|
||
"system_message": {
|
||
"_input_type": "MultilineInput",
|
||
"advanced": false,
|
||
"copy_field": false,
|
||
"display_name": "System Message",
|
||
"dynamic": false,
|
||
"info": "A system message that helps set the behavior of the assistant",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"multiline": true,
|
||
"name": "system_message",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": "Translate to Portuguese and output in structured formatReturn only the JSON and no additional text."
|
||
},
|
||
"temperature": {
|
||
"_input_type": "SliderInput",
|
||
"advanced": true,
|
||
"display_name": "Temperature",
|
||
"dynamic": false,
|
||
"info": "Controls randomness in responses",
|
||
"max_label": "",
|
||
"max_label_icon": "",
|
||
"min_label": "",
|
||
"min_label_icon": "",
|
||
"name": "temperature",
|
||
"placeholder": "",
|
||
"range_spec": {
|
||
"max": 1,
|
||
"min": 0,
|
||
"step": 0.01,
|
||
"step_type": "float"
|
||
},
|
||
"required": false,
|
||
"show": true,
|
||
"slider_buttons": false,
|
||
"slider_buttons_options": [],
|
||
"slider_input": false,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"type": "slider",
|
||
"value": 0.1
|
||
}
|
||
},
|
||
"tool_mode": false
|
||
},
|
||
"showNode": true,
|
||
"type": "LanguageModelComponent"
|
||
},
|
||
"dragging": false,
|
||
"id": "LanguageModelComponent-Te29P",
|
||
"measured": {
|
||
"height": 532,
|
||
"width": 320
|
||
},
|
||
"position": {
|
||
"x": 1472.0991866325971,
|
||
"y": -182.4108205734875
|
||
},
|
||
"selected": false,
|
||
"type": "genericNode"
|
||
},
|
||
{
|
||
"data": {
|
||
"id": "MessagetoData-IbO6b",
|
||
"node": {
|
||
"base_classes": [
|
||
"Data"
|
||
],
|
||
"beta": true,
|
||
"category": "processing",
|
||
"conditional_paths": [],
|
||
"custom_fields": {},
|
||
"description": "Convert a Message object to a Data object",
|
||
"display_name": "Message to Data",
|
||
"documentation": "",
|
||
"edited": false,
|
||
"field_order": [
|
||
"message"
|
||
],
|
||
"frozen": false,
|
||
"icon": "message-square-share",
|
||
"key": "MessagetoData",
|
||
"legacy": true,
|
||
"metadata": {},
|
||
"minimized": false,
|
||
"output_types": [],
|
||
"outputs": [
|
||
{
|
||
"allows_loop": false,
|
||
"cache": true,
|
||
"display_name": "Data",
|
||
"group_outputs": false,
|
||
"method": "convert_message_to_data",
|
||
"name": "data",
|
||
"selected": "Data",
|
||
"tool_mode": true,
|
||
"types": [
|
||
"Data"
|
||
],
|
||
"value": "__UNDEFINED__"
|
||
}
|
||
],
|
||
"pinned": false,
|
||
"score": 0.008222426499470714,
|
||
"template": {
|
||
"_type": "Component",
|
||
"code": {
|
||
"advanced": true,
|
||
"dynamic": true,
|
||
"fileTypes": [],
|
||
"file_path": "",
|
||
"info": "",
|
||
"list": false,
|
||
"load_from_db": false,
|
||
"multiline": true,
|
||
"name": "code",
|
||
"password": false,
|
||
"placeholder": "",
|
||
"required": true,
|
||
"show": true,
|
||
"title_case": false,
|
||
"type": "code",
|
||
"value": "from loguru import logger\n\nfrom langflow.custom.custom_component.component import Component\nfrom langflow.io import MessageInput, Output\nfrom langflow.schema.data import Data\nfrom langflow.schema.message import Message\n\n\nclass MessageToDataComponent(Component):\n display_name = \"Message to Data\"\n description = \"Convert a Message object to a Data object\"\n icon = \"message-square-share\"\n beta = True\n name = \"MessagetoData\"\n legacy = True\n\n inputs = [\n MessageInput(\n name=\"message\",\n display_name=\"Message\",\n info=\"The Message object to convert to a Data object\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"convert_message_to_data\"),\n ]\n\n def convert_message_to_data(self) -> Data:\n if isinstance(self.message, Message):\n # Convert Message to Data\n return Data(data=self.message.data)\n\n msg = \"Error converting Message to Data: Input must be a Message object\"\n logger.opt(exception=True).debug(msg)\n self.status = msg\n return Data(data={\"error\": msg})\n"
|
||
},
|
||
"message": {
|
||
"_input_type": "MessageInput",
|
||
"advanced": false,
|
||
"display_name": "Message",
|
||
"dynamic": false,
|
||
"info": "The Message object to convert to a Data object",
|
||
"input_types": [
|
||
"Message"
|
||
],
|
||
"list": false,
|
||
"list_add_label": "Add More",
|
||
"load_from_db": false,
|
||
"name": "message",
|
||
"placeholder": "",
|
||
"required": false,
|
||
"show": true,
|
||
"title_case": false,
|
||
"tool_mode": false,
|
||
"trace_as_input": true,
|
||
"trace_as_metadata": true,
|
||
"type": "str",
|
||
"value": ""
|
||
}
|
||
},
|
||
"tool_mode": false
|
||
},
|
||
"showNode": true,
|
||
"type": "MessagetoData"
|
||
},
|
||
"dragging": false,
|
||
"id": "MessagetoData-IbO6b",
|
||
"measured": {
|
||
"height": 203,
|
||
"width": 320
|
||
},
|
||
"position": {
|
||
"x": 1836.3049922790483,
|
||
"y": 411.76970008520357
|
||
},
|
||
"selected": false,
|
||
"type": "genericNode"
|
||
}
|
||
],
|
||
"viewport": {
|
||
"x": 718.2366665584553,
|
||
"y": 264.2875075099402,
|
||
"zoom": 0.46271902027504264
|
||
}
|
||
},
|
||
"description": "This template iterates over search results using LoopComponent and translates each result into Portuguese automatically. 🚀",
|
||
"endpoint_name": null,
|
||
"id": "00674d9d-d897-4c75-aedd-dcca1c8e8d9d",
|
||
"is_component": false,
|
||
"last_tested_version": "1.4.3",
|
||
"name": "Research Translation Loop",
|
||
"tags": [
|
||
"chatbots",
|
||
"content-generation"
|
||
]
|
||
} |