diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json index d107e731d..6e2bb8209 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json @@ -2,65 +2,12 @@ "data": { "edges": [ { + "animated": false, "className": "", "data": { "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-f1f2v", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "system_message", - "id": "OpenAIModel-lL9HA", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-f1f2v{œdataTypeœ:œPromptœ,œidœ:œPrompt-f1f2vœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-lL9HA{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-lL9HAœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "Prompt-f1f2v", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-f1f2vœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-lL9HA", - "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œOpenAIModel-lL9HAœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-GyBUF", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-lL9HA", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-GyBUF{œdataTypeœ:œChatInputœ,œidœ:œChatInput-GyBUFœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-lL9HA{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-lL9HAœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ChatInput-GyBUF", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-GyBUFœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-lL9HA", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-lL9HAœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-lL9HA", + "dataType": "LanguageModelComponent", + "id": "LanguageModelComponent-AsaOP", "name": "text_output", "output_types": [ "Message" @@ -68,26 +15,27 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "OpenAIModel-JieGw", + "id": "LanguageModelComponent-uV35f", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-OpenAIModel-lL9HA{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-lL9HAœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-JieGw{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-JieGwœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "xy-edge__LanguageModelComponent-AsaOP{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-AsaOPœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-uV35f{œfieldNameœ:œinput_valueœ,œidœ:œLanguageModelComponent-uV35fœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "OpenAIModel-lL9HA", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-lL9HAœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-JieGw", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-JieGwœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "LanguageModelComponent-AsaOP", + "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-AsaOPœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-uV35f", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œLanguageModelComponent-uV35fœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { + "animated": false, "className": "", "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-4IOgm", + "id": "Prompt-F9fZA", "name": "prompt", "output_types": [ "Message" @@ -95,53 +43,27 @@ }, "targetHandle": { "fieldName": "system_message", - "id": "OpenAIModel-JieGw", + "id": "LanguageModelComponent-uV35f", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-4IOgm{œdataTypeœ:œPromptœ,œidœ:œPrompt-4IOgmœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-JieGw{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-JieGwœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "xy-edge__Prompt-F9fZA{œdataTypeœ:œPromptœ,œidœ:œPrompt-F9fZAœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-uV35f{œfieldNameœ:œsystem_messageœ,œidœ:œLanguageModelComponent-uV35fœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-4IOgm", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-4IOgmœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-JieGw", - "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œOpenAIModel-JieGwœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-JieGw", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-dXMRv", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-JieGw{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-JieGwœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-dXMRv{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-dXMRvœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "OpenAIModel-JieGw", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-JieGwœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-dXMRv", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-dXMRvœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-F9fZA", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-F9fZAœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-uV35f", + "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œLanguageModelComponent-uV35fœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { + "animated": false, "className": "", "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-FRjO8", + "id": "Prompt-jnSgC", "name": "prompt", "output_types": [ "Message" @@ -149,26 +71,27 @@ }, "targetHandle": { "fieldName": "system_message", - "id": "OpenAIModel-dXMRv", + "id": "LanguageModelComponent-AsaOP", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-FRjO8{œdataTypeœ:œPromptœ,œidœ:œPrompt-FRjO8œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-dXMRv{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-dXMRvœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "xy-edge__Prompt-jnSgC{œdataTypeœ:œPromptœ,œidœ:œPrompt-jnSgCœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-AsaOP{œfieldNameœ:œsystem_messageœ,œidœ:œLanguageModelComponent-AsaOPœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-FRjO8", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-FRjO8œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-dXMRv", - "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œOpenAIModel-dXMRvœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-jnSgC", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-jnSgCœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-AsaOP", + "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œLanguageModelComponent-AsaOPœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { + "animated": false, "className": "", "data": { "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-dXMRv", + "dataType": "LanguageModelComponent", + "id": "LanguageModelComponent-uV35f", "name": "text_output", "output_types": [ "Message" @@ -176,7 +99,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-KXQMh", + "id": "ChatOutput-bnf9c", "inputTypes": [ "Data", "DataFrame", @@ -185,12 +108,96 @@ "type": "str" } }, - "id": "reactflow__edge-OpenAIModel-dXMRv{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-dXMRvœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-KXQMh{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-KXQMhœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "xy-edge__LanguageModelComponent-uV35f{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-uV35fœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-bnf9c{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-bnf9cœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "OpenAIModel-dXMRv", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-dXMRvœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-KXQMh", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-KXQMhœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" + "source": "LanguageModelComponent-uV35f", + "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-uV35fœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-bnf9c", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-bnf9cœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-E1Lwc", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "LanguageModelComponent-OVCTy", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "xy-edge__ChatInput-E1Lwc{œdataTypeœ:œChatInputœ,œidœ:œChatInput-E1Lwcœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-OVCTy{œfieldNameœ:œinput_valueœ,œidœ:œLanguageModelComponent-OVCTyœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "ChatInput-E1Lwc", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-E1Lwcœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-OVCTy", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œLanguageModelComponent-OVCTyœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-kNwlW", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "system_message", + "id": "LanguageModelComponent-OVCTy", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "xy-edge__Prompt-kNwlW{œdataTypeœ:œPromptœ,œidœ:œPrompt-kNwlWœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-OVCTy{œfieldNameœ:œsystem_messageœ,œidœ:œLanguageModelComponent-OVCTyœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "Prompt-kNwlW", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-kNwlWœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-OVCTy", + "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œLanguageModelComponent-OVCTyœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "LanguageModelComponent", + "id": "LanguageModelComponent-OVCTy", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "LanguageModelComponent-AsaOP", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "xy-edge__LanguageModelComponent-OVCTy{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-OVCTyœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-AsaOP{œfieldNameœ:œinput_valueœ,œidœ:œLanguageModelComponent-AsaOPœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "LanguageModelComponent-OVCTy", + "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-OVCTyœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-AsaOP", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œLanguageModelComponent-AsaOPœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" } ], "nodes": [ @@ -198,7 +205,7 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-4IOgm", + "id": "Prompt-jnSgC", "node": { "base_classes": [ "Message" @@ -218,7 +225,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -306,14 +313,14 @@ }, "dragging": false, "height": 260, - "id": "Prompt-4IOgm", + "id": "Prompt-jnSgC", "measured": { "height": 260, "width": 320 }, "position": { - "x": 1921.9168573384, - "y": 1162.4082184281983 + "x": 1933.9451134281053, + "y": 989.0706980544699 }, "positionAbsolute": { "x": 1921.9168573384, @@ -325,7 +332,7 @@ }, { "data": { - "id": "ChatInput-GyBUF", + "id": "ChatInput-E1Lwc", "node": { "base_classes": [ "Message" @@ -353,7 +360,7 @@ "icon": "MessagesSquare", "key": "ChatInput", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -604,14 +611,14 @@ }, "dragging": false, "height": 234, - "id": "ChatInput-GyBUF", + "id": "ChatInput-E1Lwc", "measured": { "height": 234, "width": 320 }, "position": { - "x": 1178.0239685549568, - "y": 879.9087836229152 + "x": 1515.8142893180777, + "y": 511.98346649699556 }, "positionAbsolute": { "x": 1178.0239685549568, @@ -625,7 +632,7 @@ "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-KXQMh", + "id": "ChatOutput-bnf9c", "node": { "base_classes": [ "Message" @@ -651,7 +658,7 @@ "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -908,14 +915,14 @@ }, "dragging": false, "height": 234, - "id": "ChatOutput-KXQMh", + "id": "ChatOutput-bnf9c", "measured": { "height": 234, "width": 320 }, "position": { - "x": 3389.8335347035913, - "y": 1185.8259442119552 + "x": 3372.7401089499594, + "y": 681.9385927784625 }, "positionAbsolute": { "x": 3363.868906129255, @@ -929,7 +936,7 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-FRjO8", + "id": "Prompt-F9fZA", "node": { "base_classes": [ "Message" @@ -949,7 +956,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -1037,14 +1044,14 @@ }, "dragging": false, "height": 260, - "id": "Prompt-FRjO8", + "id": "Prompt-F9fZA", "measured": { "height": 260, "width": 320 }, "position": { - "x": 2647.8305106628454, - "y": 1161.2328062686402 + "x": 2449.240273618089, + "y": 998.5590279612616 }, "positionAbsolute": { "x": 2647.8305106628454, @@ -1058,7 +1065,7 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-f1f2v", + "id": "Prompt-kNwlW", "node": { "base_classes": [ "Message" @@ -1078,7 +1085,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -1166,14 +1173,14 @@ }, "dragging": false, "height": 260, - "id": "Prompt-f1f2v", + "id": "Prompt-kNwlW", "measured": { "height": 260, "width": 320 }, "position": { - "x": 1178.7099500302636, - "y": 1167.8586867404465 + "x": 1480.5655849711331, + "y": 943.8455975825916 }, "positionAbsolute": { "x": 1178.7099500302636, @@ -1185,1263 +1192,905 @@ }, { "data": { - "id": "note-UUVIc", + "id": "LanguageModelComponent-AsaOP", "node": { - "description": "### Input Examples\n1.\n \"The growing demand for personalized, AI-driven mental health support tools that can provide real-time interventions and track long-term emotional well-being.\"\n\n\n2. \n \"The increasing need for secure and user-friendly decentralized finance (DeFi) platforms that make cryptocurrency investments accessible to non-tech-savvy users.\"\n \n\n3. \n \"The rising popularity of immersive, augmented reality (AR) experiences for remote collaboration and virtual team-building in distributed workforces.\"\n\n\n4. \n \"The expanding market for smart, IoT-enabled urban farming solutions that allow city dwellers to grow their own food efficiently in small spaces.\"\n\n\n5. \n \"The emerging demand for AI-powered personal styling and shopping assistants that consider sustainability, body positivity, and individual style preferences.\"\n\n", + "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, + "lf_version": "1.4.2", + "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": false, + "name": "api_key", + "password": true, + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, + "title_case": false, + "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 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\": \"Google\"}],\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": "MessageTextInput", + "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": "OpenAI" + }, + { + "icon": "Anthropic" + }, + { + "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": "MessageTextInput", + "advanced": true, + "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, + "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": "" + }, + "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-AsaOP", + "measured": { + "height": 534, + "width": 320 + }, + "position": { + "x": 2417.5170722121943, + "y": 383.1664476071964 + }, + "selected": false, + "type": "genericNode" + }, + { + "data": { + "id": "LanguageModelComponent-uV35f", + "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, + "lf_version": "1.4.2", + "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": false, + "name": "api_key", + "password": true, + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, + "title_case": false, + "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 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\": \"Google\"}],\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": "MessageTextInput", + "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": "OpenAI" + }, + { + "icon": "Anthropic" + }, + { + "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": "MessageTextInput", + "advanced": true, + "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, + "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": "" + }, + "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-uV35f", + "measured": { + "height": 534, + "width": 320 + }, + "position": { + "x": 2892.417146179941, + "y": 413.60768769085433 + }, + "selected": false, + "type": "genericNode" + }, + { + "data": { + "id": "LanguageModelComponent-OVCTy", + "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, + "lf_version": "1.4.2", + "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": false, + "name": "api_key", + "password": true, + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, + "title_case": false, + "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 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\": \"Google\"}],\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": "MessageTextInput", + "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": "OpenAI" + }, + { + "icon": "Anthropic" + }, + { + "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": "MessageTextInput", + "advanced": true, + "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, + "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": "" + }, + "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-OVCTy", + "measured": { + "height": 534, + "width": 320 + }, + "position": { + "x": 1957.3510719326769, + "y": 406.3911300579277 + }, + "selected": false, + "type": "genericNode" + }, + { + "data": { + "id": "note-mhQH6", + "node": { + "description": "# Prompt chaining\n\nThis flow demonstrates chaining three prompts and three language models.\nEach prompt is specifically designed to process previous output, with each LLM call building upon previous results\n\n\n## Prerequisites\n\n* [OpenAI API Key](https://platform.openai.com/)\n\n## Quickstart\n\n1. In all **Language Model** components, add your OpenAI API key.\n2. To run the flow, open the **Playground*. An example input is provided, with other suggestions listed below.\n\n \"The increasing need for secure and user-friendly decentralized finance (DeFi) platforms that make cryptocurrency investments accessible to non-tech-savvy users.\"\n\n \"The rising popularity of immersive, augmented reality (AR) experiences for remote collaboration and virtual team-building in distributed workforces.\"\n\n \"The expanding market for smart, IoT-enabled urban farming solutions that allow city dwellers to grow their own food efficiently in small spaces.\"\n\n \"The emerging demand for AI-powered personal styling and shopping assistants that consider sustainability, body positivity, and individual style preferences.\"\n\n", "display_name": "", "documentation": "", - "template": { - "backgroundColor": "emerald" - } + "template": {} }, "type": "note" }, "dragging": false, - "height": 324, - "id": "note-UUVIc", + "height": 920, + "id": "note-mhQH6", "measured": { - "height": 324, - "width": 324 + "height": 920, + "width": 522 }, "position": { - "x": 528.0392006831054, - "y": 973.781986567496 - }, - "positionAbsolute": { - "x": 528.0392006831054, - "y": 973.781986567496 + "x": 845.3254638400961, + "y": 367.1115872280161 }, "resizing": false, "selected": false, - "style": { - "height": 324, - "width": 324 - }, "type": "noteNode", - "width": 324 - }, - { - "data": { - "id": "note-DqpAx", - "node": { - "description": "### Prompt Chaining\n\nThis flow demonstrates fundamental prompt chaining principles:\n\n1. **Chain Structure**\n • User input → First Prompt → LLM\n • First output → Second Prompt → LLM\n • Second output → Final Prompt → LLM\n • Final output\n\n2. **Key Technique Elements**\n • Each prompt is specifically designed to process previous output\n • Output formatting ensures clean handoff between stages\n • Context flows naturally through the chain\n • Each LLM call builds upon previous results\n\n3. **Technical Implementation**\n • Multiple prompt templates working in sequence\n • Strategic input/output connections\n • Consistent message handling between stages\n • Progressive refinement through the chain\n\nThis pattern can be adapted for any use case by modifying the prompt templates while keeping the same chaining structure.", - "display_name": "", - "documentation": "", - "template": { - "backgroundColor": "blue" - } - }, - "type": "note" - }, - "dragging": false, - "height": 324, - "id": "note-DqpAx", - "measured": { - "height": 324, - "width": 324 - }, - "position": { - "x": 892.4280059782889, - "y": 406.2411111617474 - }, - "positionAbsolute": { - "x": 892.4280059782889, - "y": 406.2411111617474 - }, - "resizing": false, - "selected": false, - "style": { - "height": 324, - "width": 324 - }, - "type": "noteNode", - "width": 324 - }, - { - "data": { - "id": "OpenAIModel-lL9HA", - "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], - "beta": false, - "category": "models", - "conditional_paths": [], - "custom_fields": {}, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "system_message", - "stream", - "max_tokens", - "model_kwargs", - "json_mode", - "model_name", - "openai_api_base", - "api_key", - "temperature", - "seed" - ], - "frozen": false, - "icon": "OpenAI", - "key": "OpenAIModel", - "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, - "score": 0.14285714285714285, - "template": { - "_type": "Component", - "api_key": { - "_input_type": "SecretStrInput", - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], - "load_from_db": true, - "name": "api_key", - "password": true, - "placeholder": "", - "required": true, - "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_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import (\n OPENAI_MODEL_NAMES,\n OPENAI_REASONING_MODEL_NAMES,\n)\nfrom langflow.field_typing import LanguageModel\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.inputs.inputs import BoolInput, DictInput, DropdownInput, IntInput, SecretStrInput, SliderInput, StrInput\nfrom langflow.logging import logger\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n name = \"OpenAIModel\"\n\n inputs = [\n *LCModelComponent._base_inputs,\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n range_spec=RangeSpec(min=0, max=128000),\n ),\n DictInput(\n name=\"model_kwargs\",\n display_name=\"Model Kwargs\",\n advanced=True,\n info=\"Additional keyword arguments to pass to the model.\",\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n advanced=False,\n options=OPENAI_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[1],\n combobox=True,\n real_time_refresh=True,\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. \"\n \"Defaults to https://api.openai.com/v1. \"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n required=True,\n ),\n SliderInput(\n name=\"temperature\",\n display_name=\"Temperature\",\n value=0.1,\n range_spec=RangeSpec(min=0, max=1, step=0.01),\n show=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n IntInput(\n name=\"max_retries\",\n display_name=\"Max Retries\",\n info=\"The maximum number of retries to make when generating.\",\n advanced=True,\n value=5,\n ),\n IntInput(\n name=\"timeout\",\n display_name=\"Timeout\",\n info=\"The timeout for requests to OpenAI completion API.\",\n advanced=True,\n value=700,\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n parameters = {\n \"api_key\": SecretStr(self.api_key).get_secret_value() if self.api_key else None,\n \"model_name\": self.model_name,\n \"max_tokens\": self.max_tokens or None,\n \"model_kwargs\": self.model_kwargs or {},\n \"base_url\": self.openai_api_base or \"https://api.openai.com/v1\",\n \"seed\": self.seed,\n \"max_retries\": self.max_retries,\n \"timeout\": self.timeout,\n \"temperature\": self.temperature if self.temperature is not None else 0.1,\n }\n\n logger.info(f\"Model name: {self.model_name}\")\n if self.model_name in OPENAI_REASONING_MODEL_NAMES:\n logger.info(\"Getting reasoning model parameters\")\n parameters.pop(\"temperature\")\n parameters.pop(\"seed\")\n output = ChatOpenAI(**parameters)\n if self.json_mode:\n output = output.bind(response_format={\"type\": \"json_object\"})\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"Get a message from an OpenAI exception.\n\n Args:\n e (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n try:\n from openai import BadRequestError\n except ImportError:\n return None\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\")\n if message:\n return message\n return None\n\n def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None) -> dict:\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_REASONING_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = False\n build_config[\"seed\"][\"show\"] = False\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = True\n build_config[\"seed\"][\"show\"] = True\n return build_config\n" - }, - "input_value": { - "_input_type": "MessageInput", - "advanced": false, - "display_name": "Input", - "dynamic": false, - "info": "", - "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": "" - }, - "json_mode": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "JSON Mode", - "dynamic": false, - "info": "If True, it will output JSON regardless of passing a schema.", - "list": false, - "list_add_label": "Add More", - "name": "json_mode", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "max_retries": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Retries", - "dynamic": false, - "info": "The maximum number of retries to make when generating.", - "list": false, - "list_add_label": "Add More", - "name": "max_retries", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 5 - }, - "max_tokens": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "list_add_label": "Add More", - "name": "max_tokens", - "placeholder": "", - "range_spec": { - "max": 128000, - "min": 0, - "step": 0.1, - "step_type": "float" - }, - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "model_kwargs": { - "_input_type": "DictInput", - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "Additional keyword arguments to pass to the model.", - "list": false, - "list_add_label": "Add More", - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "model_name": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": true, - "dialog_inputs": {}, - "display_name": "Model Name", - "dynamic": false, - "info": "", - "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", - "o1" - ], - "options_metadata": [], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "gpt-4.1-mini" - }, - "openai_api_base": { - "_input_type": "StrInput", - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "openai_api_base", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "seed": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Seed", - "dynamic": false, - "info": "The seed controls the reproducibility of the job.", - "list": false, - "list_add_label": "Add More", - "name": "seed", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 1 - }, - "stream": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", - "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, - "display_name": "System Message", - "dynamic": false, - "info": "System message to pass to the model.", - "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": "" - }, - "temperature": { - "_input_type": "SliderInput", - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "info": "", - "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 - }, - "timeout": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Timeout", - "dynamic": false, - "info": "The timeout for requests to OpenAI completion API.", - "list": false, - "list_add_label": "Add More", - "name": "timeout", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 700 - } - }, - "tool_mode": false - }, - "showNode": true, - "type": "OpenAIModel", - "selected_output": "text_output" - }, - "dragging": false, - "id": "OpenAIModel-lL9HA", - "measured": { - "height": 653, - "width": 320 - }, - "position": { - "x": 1563.1591714154865, - "y": 811.7524000203542 - }, - "selected": false, - "type": "genericNode" - }, - { - "data": { - "id": "OpenAIModel-JieGw", - "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], - "beta": false, - "category": "models", - "conditional_paths": [], - "custom_fields": {}, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "system_message", - "stream", - "max_tokens", - "model_kwargs", - "json_mode", - "model_name", - "openai_api_base", - "api_key", - "temperature", - "seed" - ], - "frozen": false, - "icon": "OpenAI", - "key": "OpenAIModel", - "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, - "score": 0.14285714285714285, - "template": { - "_type": "Component", - "api_key": { - "_input_type": "SecretStrInput", - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], - "load_from_db": true, - "name": "api_key", - "password": true, - "placeholder": "", - "required": true, - "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_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import (\n OPENAI_MODEL_NAMES,\n OPENAI_REASONING_MODEL_NAMES,\n)\nfrom langflow.field_typing import LanguageModel\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.inputs.inputs import BoolInput, DictInput, DropdownInput, IntInput, SecretStrInput, SliderInput, StrInput\nfrom langflow.logging import logger\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n name = \"OpenAIModel\"\n\n inputs = [\n *LCModelComponent._base_inputs,\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n range_spec=RangeSpec(min=0, max=128000),\n ),\n DictInput(\n name=\"model_kwargs\",\n display_name=\"Model Kwargs\",\n advanced=True,\n info=\"Additional keyword arguments to pass to the model.\",\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n advanced=False,\n options=OPENAI_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[1],\n combobox=True,\n real_time_refresh=True,\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. \"\n \"Defaults to https://api.openai.com/v1. \"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n required=True,\n ),\n SliderInput(\n name=\"temperature\",\n display_name=\"Temperature\",\n value=0.1,\n range_spec=RangeSpec(min=0, max=1, step=0.01),\n show=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n IntInput(\n name=\"max_retries\",\n display_name=\"Max Retries\",\n info=\"The maximum number of retries to make when generating.\",\n advanced=True,\n value=5,\n ),\n IntInput(\n name=\"timeout\",\n display_name=\"Timeout\",\n info=\"The timeout for requests to OpenAI completion API.\",\n advanced=True,\n value=700,\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n parameters = {\n \"api_key\": SecretStr(self.api_key).get_secret_value() if self.api_key else None,\n \"model_name\": self.model_name,\n \"max_tokens\": self.max_tokens or None,\n \"model_kwargs\": self.model_kwargs or {},\n \"base_url\": self.openai_api_base or \"https://api.openai.com/v1\",\n \"seed\": self.seed,\n \"max_retries\": self.max_retries,\n \"timeout\": self.timeout,\n \"temperature\": self.temperature if self.temperature is not None else 0.1,\n }\n\n logger.info(f\"Model name: {self.model_name}\")\n if self.model_name in OPENAI_REASONING_MODEL_NAMES:\n logger.info(\"Getting reasoning model parameters\")\n parameters.pop(\"temperature\")\n parameters.pop(\"seed\")\n output = ChatOpenAI(**parameters)\n if self.json_mode:\n output = output.bind(response_format={\"type\": \"json_object\"})\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"Get a message from an OpenAI exception.\n\n Args:\n e (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n try:\n from openai import BadRequestError\n except ImportError:\n return None\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\")\n if message:\n return message\n return None\n\n def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None) -> dict:\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_REASONING_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = False\n build_config[\"seed\"][\"show\"] = False\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = True\n build_config[\"seed\"][\"show\"] = True\n return build_config\n" - }, - "input_value": { - "_input_type": "MessageInput", - "advanced": false, - "display_name": "Input", - "dynamic": false, - "info": "", - "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": "" - }, - "json_mode": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "JSON Mode", - "dynamic": false, - "info": "If True, it will output JSON regardless of passing a schema.", - "list": false, - "list_add_label": "Add More", - "name": "json_mode", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "max_retries": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Retries", - "dynamic": false, - "info": "The maximum number of retries to make when generating.", - "list": false, - "list_add_label": "Add More", - "name": "max_retries", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 5 - }, - "max_tokens": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "list_add_label": "Add More", - "name": "max_tokens", - "placeholder": "", - "range_spec": { - "max": 128000, - "min": 0, - "step": 0.1, - "step_type": "float" - }, - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "model_kwargs": { - "_input_type": "DictInput", - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "Additional keyword arguments to pass to the model.", - "list": false, - "list_add_label": "Add More", - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "model_name": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": true, - "dialog_inputs": {}, - "display_name": "Model Name", - "dynamic": false, - "info": "", - "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", - "o1" - ], - "options_metadata": [], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "gpt-4.1-mini" - }, - "openai_api_base": { - "_input_type": "StrInput", - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "openai_api_base", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "seed": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Seed", - "dynamic": false, - "info": "The seed controls the reproducibility of the job.", - "list": false, - "list_add_label": "Add More", - "name": "seed", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 1 - }, - "stream": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", - "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, - "display_name": "System Message", - "dynamic": false, - "info": "System message to pass to the model.", - "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": "" - }, - "temperature": { - "_input_type": "SliderInput", - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "info": "", - "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 - }, - "timeout": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Timeout", - "dynamic": false, - "info": "The timeout for requests to OpenAI completion API.", - "list": false, - "list_add_label": "Add More", - "name": "timeout", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 700 - } - }, - "tool_mode": false - }, - "showNode": true, - "type": "OpenAIModel", - "selected_output": "text_output" - }, - "dragging": false, - "id": "OpenAIModel-JieGw", - "measured": { - "height": 653, - "width": 320 - }, - "position": { - "x": 2289.2925714867265, - "y": 849.5992204058788 - }, - "selected": false, - "type": "genericNode" - }, - { - "data": { - "id": "OpenAIModel-dXMRv", - "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], - "beta": false, - "category": "models", - "conditional_paths": [], - "custom_fields": {}, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "system_message", - "stream", - "max_tokens", - "model_kwargs", - "json_mode", - "model_name", - "openai_api_base", - "api_key", - "temperature", - "seed" - ], - "frozen": false, - "icon": "OpenAI", - "key": "OpenAIModel", - "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, - "score": 0.14285714285714285, - "template": { - "_type": "Component", - "api_key": { - "_input_type": "SecretStrInput", - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], - "load_from_db": true, - "name": "api_key", - "password": true, - "placeholder": "", - "required": true, - "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_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import (\n OPENAI_MODEL_NAMES,\n OPENAI_REASONING_MODEL_NAMES,\n)\nfrom langflow.field_typing import LanguageModel\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.inputs.inputs import BoolInput, DictInput, DropdownInput, IntInput, SecretStrInput, SliderInput, StrInput\nfrom langflow.logging import logger\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n name = \"OpenAIModel\"\n\n inputs = [\n *LCModelComponent._base_inputs,\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n range_spec=RangeSpec(min=0, max=128000),\n ),\n DictInput(\n name=\"model_kwargs\",\n display_name=\"Model Kwargs\",\n advanced=True,\n info=\"Additional keyword arguments to pass to the model.\",\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n advanced=False,\n options=OPENAI_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[1],\n combobox=True,\n real_time_refresh=True,\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. \"\n \"Defaults to https://api.openai.com/v1. \"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n required=True,\n ),\n SliderInput(\n name=\"temperature\",\n display_name=\"Temperature\",\n value=0.1,\n range_spec=RangeSpec(min=0, max=1, step=0.01),\n show=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n IntInput(\n name=\"max_retries\",\n display_name=\"Max Retries\",\n info=\"The maximum number of retries to make when generating.\",\n advanced=True,\n value=5,\n ),\n IntInput(\n name=\"timeout\",\n display_name=\"Timeout\",\n info=\"The timeout for requests to OpenAI completion API.\",\n advanced=True,\n value=700,\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n parameters = {\n \"api_key\": SecretStr(self.api_key).get_secret_value() if self.api_key else None,\n \"model_name\": self.model_name,\n \"max_tokens\": self.max_tokens or None,\n \"model_kwargs\": self.model_kwargs or {},\n \"base_url\": self.openai_api_base or \"https://api.openai.com/v1\",\n \"seed\": self.seed,\n \"max_retries\": self.max_retries,\n \"timeout\": self.timeout,\n \"temperature\": self.temperature if self.temperature is not None else 0.1,\n }\n\n logger.info(f\"Model name: {self.model_name}\")\n if self.model_name in OPENAI_REASONING_MODEL_NAMES:\n logger.info(\"Getting reasoning model parameters\")\n parameters.pop(\"temperature\")\n parameters.pop(\"seed\")\n output = ChatOpenAI(**parameters)\n if self.json_mode:\n output = output.bind(response_format={\"type\": \"json_object\"})\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"Get a message from an OpenAI exception.\n\n Args:\n e (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n try:\n from openai import BadRequestError\n except ImportError:\n return None\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\")\n if message:\n return message\n return None\n\n def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None) -> dict:\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_REASONING_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = False\n build_config[\"seed\"][\"show\"] = False\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = True\n build_config[\"seed\"][\"show\"] = True\n return build_config\n" - }, - "input_value": { - "_input_type": "MessageInput", - "advanced": false, - "display_name": "Input", - "dynamic": false, - "info": "", - "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": "" - }, - "json_mode": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "JSON Mode", - "dynamic": false, - "info": "If True, it will output JSON regardless of passing a schema.", - "list": false, - "list_add_label": "Add More", - "name": "json_mode", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "max_retries": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Retries", - "dynamic": false, - "info": "The maximum number of retries to make when generating.", - "list": false, - "list_add_label": "Add More", - "name": "max_retries", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 5 - }, - "max_tokens": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "list_add_label": "Add More", - "name": "max_tokens", - "placeholder": "", - "range_spec": { - "max": 128000, - "min": 0, - "step": 0.1, - "step_type": "float" - }, - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "model_kwargs": { - "_input_type": "DictInput", - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "Additional keyword arguments to pass to the model.", - "list": false, - "list_add_label": "Add More", - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "model_name": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": true, - "dialog_inputs": {}, - "display_name": "Model Name", - "dynamic": false, - "info": "", - "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", - "o1" - ], - "options_metadata": [], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "gpt-4.1-mini" - }, - "openai_api_base": { - "_input_type": "StrInput", - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "openai_api_base", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "seed": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Seed", - "dynamic": false, - "info": "The seed controls the reproducibility of the job.", - "list": false, - "list_add_label": "Add More", - "name": "seed", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 1 - }, - "stream": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", - "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, - "display_name": "System Message", - "dynamic": false, - "info": "System message to pass to the model.", - "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": "" - }, - "temperature": { - "_input_type": "SliderInput", - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "info": "", - "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 - }, - "timeout": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Timeout", - "dynamic": false, - "info": "The timeout for requests to OpenAI completion API.", - "list": false, - "list_add_label": "Add More", - "name": "timeout", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 700 - } - }, - "tool_mode": false - }, - "showNode": true, - "type": "OpenAIModel", - "selected_output": "text_output" - }, - "dragging": false, - "id": "OpenAIModel-dXMRv", - "measured": { - "height": 653, - "width": 320 - }, - "position": { - "x": 3018.8917918926063, - "y": 844.6876489700377 - }, - "selected": false, - "type": "genericNode" + "width": 521 } ], "viewport": { - "x": -659.8399794180846, - "y": -252.56300712780512, - "zoom": 0.5391950807198421 + "x": -400.8533008879997, + "y": 142.36253504700537, + "zoom": 0.4763932486920123 } }, "description": "Connect multiple prompts in sequence where each output becomes the next stage's input, enabling step-by-step text processing.", "endpoint_name": null, - "gradient": "0", - "icon": "Link", - "id": "b5b0c252-95ae-4b07-8211-67c8b12ea60e", + "id": "eaaa2f42-a548-4241-a121-d43a71659651", "is_component": false, - "last_tested_version": "1.0.19.post2", - "name": "Prompt Chaining", + "last_tested_version": "1.4.2", + "name": "Basic Prompt Chaining", "tags": [ "chatbots" ] diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json index 830617f62..6c4516c39 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json @@ -7,7 +7,7 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-Z1IXr", + "id": "Prompt-qrgXn", "name": "prompt", "output_types": [ "Message" @@ -15,19 +15,19 @@ }, "targetHandle": { "fieldName": "system_message", - "id": "LanguageModelComponent-UcEoU", + "id": "LanguageModelComponent-UrOQf", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "xy-edge__Prompt-Z1IXr{œdataTypeœ:œPromptœ,œidœ:œPrompt-Z1IXrœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-UcEoU{œfieldNameœ:œsystem_messageœ,œidœ:œLanguageModelComponent-UcEoUœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "xy-edge__Prompt-qrgXn{œdataTypeœ:œPromptœ,œidœ:œPrompt-qrgXnœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-UrOQf{œfieldNameœ:œsystem_messageœ,œidœ:œLanguageModelComponent-UrOQfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-Z1IXr", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-Z1IXrœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "LanguageModelComponent-UcEoU", - "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œLanguageModelComponent-UcEoUœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-qrgXn", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-qrgXnœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-UrOQf", + "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œLanguageModelComponent-UrOQfœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -35,7 +35,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-9e2tW", + "id": "ChatInput-9rvSS", "name": "message", "output_types": [ "Message" @@ -43,19 +43,19 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "LanguageModelComponent-UcEoU", + "id": "LanguageModelComponent-UrOQf", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "xy-edge__ChatInput-9e2tW{œdataTypeœ:œChatInputœ,œidœ:œChatInput-9e2tWœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-UcEoU{œfieldNameœ:œinput_valueœ,œidœ:œLanguageModelComponent-UcEoUœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "xy-edge__ChatInput-9rvSS{œdataTypeœ:œChatInputœ,œidœ:œChatInput-9rvSSœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-UrOQf{œfieldNameœ:œinput_valueœ,œidœ:œLanguageModelComponent-UrOQfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-9e2tW", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-9e2tWœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "LanguageModelComponent-UcEoU", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œLanguageModelComponent-UcEoUœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatInput-9rvSS", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-9rvSSœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-UrOQf", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œLanguageModelComponent-UrOQfœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -63,7 +63,7 @@ "data": { "sourceHandle": { "dataType": "LanguageModelComponent", - "id": "LanguageModelComponent-UcEoU", + "id": "LanguageModelComponent-UrOQf", "name": "text_output", "output_types": [ "Message" @@ -71,21 +71,21 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-7q74v", + "id": "ChatOutput-AyRuN", "inputTypes": [ "Data", "DataFrame", "Message" ], - "type": "other" + "type": "str" } }, - "id": "xy-edge__LanguageModelComponent-UcEoU{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-UcEoUœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-7q74v{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-7q74vœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}", + "id": "xy-edge__LanguageModelComponent-UrOQf{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-UrOQfœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-AyRuN{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-AyRuNœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "LanguageModelComponent-UcEoU", - "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-UcEoUœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-7q74v", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-7q74vœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}" + "source": "LanguageModelComponent-UrOQf", + "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-UrOQfœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-AyRuN", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-AyRuNœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" } ], "nodes": [ @@ -93,7 +93,7 @@ "data": { "description": "Get chat inputs from the Playground.", "display_name": "Chat Input", - "id": "ChatInput-9e2tW", + "id": "ChatInput-9rvSS", "node": { "base_classes": [ "Message" @@ -116,7 +116,7 @@ "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.4.3", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -148,14 +148,12 @@ "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", @@ -171,14 +169,12 @@ "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", @@ -203,7 +199,6 @@ "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, @@ -235,7 +230,6 @@ "file_path": "", "info": "Files to be sent with the message.", "list": true, - "list_add_label": "Add More", "name": "files", "placeholder": "", "required": false, @@ -247,15 +241,12 @@ "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", @@ -263,17 +254,13 @@ "required": false, "show": true, "title_case": false, - "tool_mode": false, "trace_as_input": true, "trace_as_metadata": true, "type": "str", "value": "Hello" }, "sender": { - "_input_type": "DropdownInput", "advanced": true, - "combobox": false, - "dialog_inputs": {}, "display_name": "Sender Type", "dynamic": false, "info": "Type of sender.", @@ -282,19 +269,15 @@ "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, @@ -303,21 +286,18 @@ "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, @@ -326,14 +306,12 @@ "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", @@ -346,13 +324,11 @@ "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 @@ -367,14 +343,12 @@ "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", @@ -387,7 +361,7 @@ }, "dragging": false, "height": 234, - "id": "ChatInput-9e2tW", + "id": "ChatInput-9rvSS", "measured": { "height": 234, "width": 320 @@ -408,7 +382,7 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-Z1IXr", + "id": "Prompt-qrgXn", "node": { "base_classes": [ "Message" @@ -428,7 +402,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.4.3", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -475,7 +449,6 @@ "dynamic": false, "info": "", "list": false, - "list_add_label": "Add More", "load_from_db": false, "name": "template", "placeholder": "", @@ -497,7 +470,6 @@ "Message" ], "list": false, - "list_add_label": "Add More", "load_from_db": false, "name": "tool_placeholder", "placeholder": "", @@ -518,14 +490,14 @@ }, "dragging": false, "height": 260, - "id": "Prompt-Z1IXr", + "id": "Prompt-qrgXn", "measured": { "height": 260, "width": 320 }, "position": { - "x": 690.2015147036818, - "y": 1040.6625705470924 + "x": 688.9222183027662, + "y": 1044.5004597498394 }, "positionAbsolute": { "x": 690.2015147036818, @@ -537,9 +509,9 @@ }, { "data": { - "id": "undefined-9ON0z", + "id": "undefined-x1gke", "node": { - "description": "## 📖 README\n\nPerform basic prompting with an OpenAI model.\n\n#### Quick Start\n- Add your **OpenAI API key** to the **OpenAI Model**\n- Open the **Playground** to chat with your bot.\n\n#### Next steps:\n Experiment by changing the prompt and the OpenAI model temperature to see how the bot's responses change.", + "description": "## 📖 README\n\nPerform basic prompting with a Language model component.\n\n#### Quick Start\n- Add your **OpenAI API key** to the **Language Model** component.\n- Open the **Playground** to chat with your bot.\n\n#### Next steps:\nExperiment by changing the prompt and the Language model temperature to see how the bot's responses change.", "display_name": "Read Me", "documentation": "", "template": { @@ -548,15 +520,15 @@ } }, "dragging": false, - "height": 332, - "id": "undefined-9ON0z", + "height": 403, + "id": "undefined-x1gke", "measured": { - "height": 332, - "width": 325 + "height": 403, + "width": 324 }, "position": { - "x": 133.95771636602308, - "y": 753.6499167055161 + "x": 309.22132329147314, + "y": 803.5424763412283 }, "positionAbsolute": { "x": 66.38770028934243, @@ -573,7 +545,7 @@ }, { "data": { - "id": "note-gMO7f", + "id": "note-YJtLA", "node": { "description": "### 💡 Add your OpenAI API key here 👇", "display_name": "", @@ -586,14 +558,14 @@ }, "dragging": false, "height": 324, - "id": "note-gMO7f", + "id": "note-YJtLA", "measured": { "height": 324, "width": 324 }, "position": { - "x": 1075.829573520873, - "y": 657.2057655038416 + "x": 1080.9467591245357, + "y": 744.1979207661088 }, "positionAbsolute": { "x": 1075.829573520873, @@ -610,7 +582,7 @@ }, { "data": { - "id": "ChatOutput-7q74v", + "id": "ChatOutput-AyRuN", "node": { "base_classes": [ "Message" @@ -636,7 +608,7 @@ "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.4.3", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -668,7 +640,6 @@ "Message" ], "list": false, - "list_add_label": "Add More", "load_from_db": false, "name": "background_color", "placeholder": "", @@ -691,7 +662,6 @@ "Message" ], "list": false, - "list_add_label": "Add More", "load_from_db": false, "name": "chat_icon", "placeholder": "", @@ -750,7 +720,6 @@ "Message" ], "list": false, - "list_add_label": "Add More", "load_from_db": false, "name": "data_template", "placeholder": "", @@ -764,7 +733,7 @@ "value": "{text}" }, "input_value": { - "_input_type": "HandleInput", + "_input_type": "MessageInput", "advanced": false, "display_name": "Inputs", "dynamic": false, @@ -775,7 +744,6 @@ "Message" ], "list": false, - "list_add_label": "Add More", "load_from_db": false, "name": "input_value", "placeholder": "", @@ -784,14 +752,13 @@ "title_case": false, "trace_as_input": true, "trace_as_metadata": true, - "type": "other", + "type": "str", "value": "" }, "sender": { "_input_type": "DropdownInput", "advanced": true, "combobox": false, - "dialog_inputs": {}, "display_name": "Sender Type", "dynamic": false, "info": "Type of sender.", @@ -800,12 +767,10 @@ "Machine", "User" ], - "options_metadata": [], "placeholder": "", "required": false, "show": true, "title_case": false, - "toggle": false, "tool_mode": false, "trace_as_metadata": true, "type": "str", @@ -821,7 +786,6 @@ "Message" ], "list": false, - "list_add_label": "Add More", "load_from_db": false, "name": "sender_name", "placeholder": "", @@ -844,7 +808,6 @@ "Message" ], "list": false, - "list_add_label": "Add More", "load_from_db": false, "name": "session_id", "placeholder": "", @@ -864,13 +827,11 @@ "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 @@ -885,7 +846,6 @@ "Message" ], "list": false, - "list_add_label": "Add More", "load_from_db": false, "name": "text_color", "placeholder": "", @@ -905,7 +865,7 @@ }, "dragging": false, "height": 234, - "id": "ChatOutput-7q74v", + "id": "ChatOutput-AyRuN", "measured": { "height": 234, "width": 320 @@ -918,20 +878,19 @@ "x": 1444.936881624563, "y": 872.7273956769025 }, - "selected": true, + "selected": false, "type": "genericNode", "width": 320 }, { "data": { - "id": "LanguageModelComponent-UcEoU", + "id": "LanguageModelComponent-UrOQf", "node": { "base_classes": [ "LanguageModel", "Message" ], "beta": false, - "category": "models", "conditional_paths": [], "custom_fields": {}, "description": "Runs a language model given a specified provider. ", @@ -949,9 +908,8 @@ ], "frozen": false, "icon": "brain-circuit", - "key": "LanguageModelComponent", "legacy": false, - "lf_version": "1.4.3", + "lf_version": "1.4.2", "metadata": { "keywords": [ "model", @@ -994,7 +952,6 @@ ], "pinned": false, "priority": 0, - "score": 0.28173906304863156, "template": { "_type": "Component", "api_key": { @@ -1004,7 +961,7 @@ "dynamic": false, "info": "Model Provider API key", "input_types": [], - "load_from_db": true, + "load_from_db": false, "name": "api_key", "password": true, "placeholder": "", @@ -1200,30 +1157,30 @@ "type": "LanguageModelComponent" }, "dragging": false, - "id": "LanguageModelComponent-UcEoU", + "id": "LanguageModelComponent-UrOQf", "measured": { "height": 534, "width": 320 }, "position": { - "x": 1082.9866975141738, - "y": 746.0923075286877 + "x": 1085.7542386472996, + "y": 795.0399905192078 }, "selected": false, "type": "genericNode" } ], "viewport": { - "x": -37.23013572397235, - "y": -311.67320873395806, - "zoom": 0.74075714647776 + "x": -38.712024727138214, + "y": -377.46660457274356, + "zoom": 0.7816796789893417 } }, "description": "Perform basic prompting with an OpenAI model.", "endpoint_name": null, - "id": "c04a179a-a582-402e-9628-4af37767208c", + "id": "f0994431-652b-4fd1-940e-e5bfa1416fcc", "is_component": false, - "last_tested_version": "1.4.3", + "last_tested_version": "1.4.2", "name": "Basic Prompting", "tags": [ "chatbots" diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json index 845a4a800..f3e3a0175 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json @@ -7,7 +7,7 @@ "data": { "sourceHandle": { "dataType": "TextInput", - "id": "TextInput-6vRbp", + "id": "TextInput-mM5Wa", "name": "text", "output_types": [ "Message" @@ -15,7 +15,7 @@ }, "targetHandle": { "fieldName": "instructions", - "id": "Prompt-xzxes", + "id": "Prompt-BlL2w", "inputTypes": [ "Message", "Text" @@ -23,12 +23,70 @@ "type": "str" } }, - "id": "reactflow__edge-TextInput-6vRbp{œdataTypeœ:œTextInputœ,œidœ:œTextInput-6vRbpœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-xzxes{œfieldNameœ:œinstructionsœ,œidœ:œPrompt-xzxesœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-TextInput-mM5Wa{œdataTypeœ:œTextInputœ,œidœ:œTextInput-mM5Waœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-BlL2w{œfieldNameœ:œinstructionsœ,œidœ:œPrompt-BlL2wœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", "selected": false, - "source": "TextInput-6vRbp", - "sourceHandle": "{œdataTypeœ: œTextInputœ, œidœ: œTextInput-6vRbpœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-xzxes", - "targetHandle": "{œfieldNameœ: œinstructionsœ, œidœ: œPrompt-xzxesœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + "source": "TextInput-mM5Wa", + "sourceHandle": "{œdataTypeœ: œTextInputœ, œidœ: œTextInput-mM5Waœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-BlL2w", + "targetHandle": "{œfieldNameœ: œinstructionsœ, œidœ: œPrompt-BlL2wœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ParserComponent", + "id": "ParserComponent-YRRd0", + "name": "parsed_text", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "references", + "id": "Prompt-BlL2w", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ParserComponent-YRRd0{œdataTypeœ:œParserComponentœ,œidœ:œParserComponent-YRRd0œ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-Prompt-BlL2w{œfieldNameœ:œreferencesœ,œidœ:œPrompt-BlL2wœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "selected": false, + "source": "ParserComponent-YRRd0", + "sourceHandle": "{œdataTypeœ: œParserComponentœ, œidœ: œParserComponent-YRRd0œ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-BlL2w", + "targetHandle": "{œfieldNameœ: œreferencesœ, œidœ: œPrompt-BlL2wœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "URLComponent", + "id": "URLComponent-DFXG5", + "name": "page_results", + "output_types": [ + "DataFrame" + ] + }, + "targetHandle": { + "fieldName": "input_data", + "id": "ParserComponent-YRRd0", + "inputTypes": [ + "DataFrame", + "Data" + ], + "type": "other" + } + }, + "id": "reactflow__edge-URLComponent-DFXG5{œdataTypeœ:œURLComponentœ,œidœ:œURLComponent-DFXG5œ,œnameœ:œpage_resultsœ,œoutput_typesœ:[œDataFrameœ]}-ParserComponent-YRRd0{œfieldNameœ:œinput_dataœ,œidœ:œParserComponent-YRRd0œ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", + "selected": false, + "source": "URLComponent-DFXG5", + "sourceHandle": "{œdataTypeœ: œURLComponentœ, œidœ: œURLComponent-DFXG5œ, œnameœ: œpage_resultsœ, œoutput_typesœ: [œDataFrameœ]}", + "target": "ParserComponent-YRRd0", + "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œParserComponent-YRRd0œ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -36,7 +94,7 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-xzxes", + "id": "Prompt-BlL2w", "name": "prompt", "output_types": [ "Message" @@ -44,27 +102,27 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "OpenAIModel-Qq8W6", + "id": "LanguageModelComponent-1gwua", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-xzxes{œdataTypeœ:œPromptœ,œidœ:œPrompt-xzxesœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-Qq8W6{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-Qq8W6œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "xy-edge__Prompt-BlL2w{œdataTypeœ:œPromptœ,œidœ:œPrompt-BlL2wœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-1gwua{œfieldNameœ:œinput_valueœ,œidœ:œLanguageModelComponent-1gwuaœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-xzxes", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-xzxesœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-Qq8W6", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-Qq8W6œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-BlL2w", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-BlL2wœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-1gwua", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œLanguageModelComponent-1gwuaœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, "className": "", "data": { "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-Qq8W6", + "dataType": "LanguageModelComponent", + "id": "LanguageModelComponent-1gwua", "name": "text_output", "output_types": [ "Message" @@ -72,7 +130,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-17Dtd", + "id": "ChatOutput-GOjXV", "inputTypes": [ "Data", "DataFrame", @@ -81,70 +139,12 @@ "type": "str" } }, - "id": "reactflow__edge-OpenAIModel-Qq8W6{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-Qq8W6œ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-17Dtd{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-17Dtdœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", + "id": "xy-edge__LanguageModelComponent-1gwua{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-1gwuaœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-GOjXV{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-GOjXVœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "OpenAIModel-Qq8W6", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-Qq8W6œ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-17Dtd", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-17Dtdœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ParserComponent", - "id": "ParserComponent-KlzCE", - "name": "parsed_text", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "references", - "id": "Prompt-xzxes", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "xy-edge__ParserComponent-KlzCE{œdataTypeœ:œParserComponentœ,œidœ:œParserComponent-KlzCEœ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-Prompt-xzxes{œfieldNameœ:œreferencesœ,œidœ:œPrompt-xzxesœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ParserComponent-KlzCE", - "sourceHandle": "{œdataTypeœ: œParserComponentœ, œidœ: œParserComponent-KlzCEœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-xzxes", - "targetHandle": "{œfieldNameœ: œreferencesœ, œidœ: œPrompt-xzxesœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "URLComponent", - "id": "URLComponent-KZ1r5", - "name": "page_results", - "output_types": [ - "DataFrame" - ] - }, - "targetHandle": { - "fieldName": "input_data", - "id": "ParserComponent-KlzCE", - "inputTypes": [ - "DataFrame", - "Data" - ], - "type": "other" - } - }, - "id": "xy-edge__URLComponent-KZ1r5{œdataTypeœ:œURLComponentœ,œidœ:œURLComponent-KZ1r5œ,œnameœ:œpage_resultsœ,œoutput_typesœ:[œDataFrameœ]}-ParserComponent-KlzCE{œfieldNameœ:œinput_dataœ,œidœ:œParserComponent-KlzCEœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", - "selected": false, - "source": "URLComponent-KZ1r5", - "sourceHandle": "{œdataTypeœ: œURLComponentœ, œidœ: œURLComponent-KZ1r5œ, œnameœ: œpage_resultsœ, œoutput_typesœ: [œDataFrameœ]}", - "target": "ParserComponent-KlzCE", - "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œParserComponent-KlzCEœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" + "source": "LanguageModelComponent-1gwua", + "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-1gwuaœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-GOjXV", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-GOjXVœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" } ], "nodes": [ @@ -152,7 +152,7 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-xzxes", + "id": "Prompt-BlL2w", "node": { "base_classes": [ "Message" @@ -175,7 +175,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.2.0", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -308,7 +308,7 @@ }, "dragging": false, "height": 433, - "id": "Prompt-xzxes", + "id": "Prompt-BlL2w", "measured": { "height": 433, "width": 320 @@ -329,7 +329,7 @@ "data": { "description": "Get text inputs from the Playground.", "display_name": "Instructions", - "id": "TextInput-6vRbp", + "id": "TextInput-mM5Wa", "node": { "base_classes": [ "Message" @@ -347,7 +347,7 @@ "frozen": false, "icon": "type", "legacy": false, - "lf_version": "1.2.0", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -416,7 +416,7 @@ }, "dragging": false, "height": 234, - "id": "TextInput-6vRbp", + "id": "TextInput-mM5Wa", "measured": { "height": 234, "width": 320 @@ -437,7 +437,7 @@ "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-17Dtd", + "id": "ChatOutput-GOjXV", "node": { "base_classes": [ "Message" @@ -460,7 +460,7 @@ "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.2.0", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -703,7 +703,7 @@ }, "dragging": false, "height": 234, - "id": "ChatOutput-17Dtd", + "id": "ChatOutput-GOjXV", "measured": { "height": 234, "width": 320 @@ -722,9 +722,9 @@ }, { "data": { - "id": "note-iizz3", + "id": "note-OB8Tz", "node": { - "description": "# Blog Writing Flow Overview\n\nCreate a blog post by using content fetched from URLs and user-provided instructions.\n\n## Prerequisites\n\n* An [OpenAI API key](https://platform.openai.com/)\n\n## Quickstart\n\n1. Paste your OpenAI API key in the **OpenAI** model component.\n2. In the **URL** component, enter URLs you want to fetch content from. Ensure they start with `http://` or `https://`.\n3. Open the **Playground**. A blog post is written from the content fetched by the **URL** component.", + "description": "# Blog Writing Flow Overview\n\nCreate a blog post by using content fetched from URLs and user-provided instructions.\n\n## Prerequisites\n\n* An [OpenAI API key](https://platform.openai.com/)\n\n## Quickstart\n\n1. Paste your OpenAI API key in the **Language Model** model component.\n2. In the **URL** component, enter URLs you want to fetch content from. Ensure they start with `http://` or `https://`.\n3. Open the **Playground**. A blog post is written from the content fetched by the **URL** component.", "display_name": "", "documentation": "", "template": {} @@ -733,7 +733,7 @@ }, "dragging": false, "height": 582, - "id": "note-iizz3", + "id": "note-OB8Tz", "measured": { "height": 582, "width": 508 @@ -757,398 +757,7 @@ }, { "data": { - "id": "OpenAIModel-Qq8W6", - "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], - "beta": false, - "category": "models", - "conditional_paths": [], - "custom_fields": {}, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "system_message", - "stream", - "max_tokens", - "model_kwargs", - "json_mode", - "model_name", - "openai_api_base", - "api_key", - "temperature", - "seed" - ], - "frozen": false, - "icon": "OpenAI", - "key": "OpenAIModel", - "legacy": false, - "lf_version": "1.2.0", - "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, - "score": 0.001, - "template": { - "_type": "Component", - "api_key": { - "_input_type": "SecretStrInput", - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], - "load_from_db": true, - "name": "api_key", - "password": true, - "placeholder": "", - "required": true, - "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_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import (\n OPENAI_MODEL_NAMES,\n OPENAI_REASONING_MODEL_NAMES,\n)\nfrom langflow.field_typing import LanguageModel\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.inputs.inputs import BoolInput, DictInput, DropdownInput, IntInput, SecretStrInput, SliderInput, StrInput\nfrom langflow.logging import logger\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n name = \"OpenAIModel\"\n\n inputs = [\n *LCModelComponent._base_inputs,\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n range_spec=RangeSpec(min=0, max=128000),\n ),\n DictInput(\n name=\"model_kwargs\",\n display_name=\"Model Kwargs\",\n advanced=True,\n info=\"Additional keyword arguments to pass to the model.\",\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n advanced=False,\n options=OPENAI_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[1],\n combobox=True,\n real_time_refresh=True,\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. \"\n \"Defaults to https://api.openai.com/v1. \"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n required=True,\n ),\n SliderInput(\n name=\"temperature\",\n display_name=\"Temperature\",\n value=0.1,\n range_spec=RangeSpec(min=0, max=1, step=0.01),\n show=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n IntInput(\n name=\"max_retries\",\n display_name=\"Max Retries\",\n info=\"The maximum number of retries to make when generating.\",\n advanced=True,\n value=5,\n ),\n IntInput(\n name=\"timeout\",\n display_name=\"Timeout\",\n info=\"The timeout for requests to OpenAI completion API.\",\n advanced=True,\n value=700,\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n parameters = {\n \"api_key\": SecretStr(self.api_key).get_secret_value() if self.api_key else None,\n \"model_name\": self.model_name,\n \"max_tokens\": self.max_tokens or None,\n \"model_kwargs\": self.model_kwargs or {},\n \"base_url\": self.openai_api_base or \"https://api.openai.com/v1\",\n \"seed\": self.seed,\n \"max_retries\": self.max_retries,\n \"timeout\": self.timeout,\n \"temperature\": self.temperature if self.temperature is not None else 0.1,\n }\n\n logger.info(f\"Model name: {self.model_name}\")\n if self.model_name in OPENAI_REASONING_MODEL_NAMES:\n logger.info(\"Getting reasoning model parameters\")\n parameters.pop(\"temperature\")\n parameters.pop(\"seed\")\n output = ChatOpenAI(**parameters)\n if self.json_mode:\n output = output.bind(response_format={\"type\": \"json_object\"})\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"Get a message from an OpenAI exception.\n\n Args:\n e (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n try:\n from openai import BadRequestError\n except ImportError:\n return None\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\")\n if message:\n return message\n return None\n\n def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None) -> dict:\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_REASONING_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = False\n build_config[\"seed\"][\"show\"] = False\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = True\n build_config[\"seed\"][\"show\"] = True\n return build_config\n" - }, - "input_value": { - "_input_type": "MessageInput", - "advanced": false, - "display_name": "Input", - "dynamic": false, - "info": "", - "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": "" - }, - "json_mode": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "JSON Mode", - "dynamic": false, - "info": "If True, it will output JSON regardless of passing a schema.", - "list": false, - "list_add_label": "Add More", - "name": "json_mode", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "max_retries": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Retries", - "dynamic": false, - "info": "The maximum number of retries to make when generating.", - "list": false, - "list_add_label": "Add More", - "name": "max_retries", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 5 - }, - "max_tokens": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "list_add_label": "Add More", - "name": "max_tokens", - "placeholder": "", - "range_spec": { - "max": 128000, - "min": 0, - "step": 0.1, - "step_type": "float" - }, - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "model_kwargs": { - "_input_type": "DictInput", - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "Additional keyword arguments to pass to the model.", - "list": false, - "list_add_label": "Add More", - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "model_name": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": true, - "dialog_inputs": {}, - "display_name": "Model Name", - "dynamic": false, - "info": "", - "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", - "o1" - ], - "options_metadata": [], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "gpt-4.1-mini" - }, - "openai_api_base": { - "_input_type": "StrInput", - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "openai_api_base", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "seed": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Seed", - "dynamic": false, - "info": "The seed controls the reproducibility of the job.", - "list": false, - "list_add_label": "Add More", - "name": "seed", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 1 - }, - "stream": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", - "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, - "display_name": "System Message", - "dynamic": false, - "info": "System message to pass to the model.", - "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": "" - }, - "temperature": { - "_input_type": "SliderInput", - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "info": "", - "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 - }, - "timeout": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Timeout", - "dynamic": false, - "info": "The timeout for requests to OpenAI completion API.", - "list": false, - "list_add_label": "Add More", - "name": "timeout", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 700 - } - }, - "tool_mode": false - }, - "selected_output": "text_output", - "showNode": true, - "type": "OpenAIModel" - }, - "dragging": false, - "id": "OpenAIModel-Qq8W6", - "measured": { - "height": 540, - "width": 320 - }, - "position": { - "x": 1715.4141756503298, - "y": 434.13478201304184 - }, - "selected": false, - "type": "genericNode" - }, - { - "data": { - "id": "ParserComponent-KlzCE", + "id": "ParserComponent-YRRd0", "node": { "base_classes": [ "Message" @@ -1311,21 +920,21 @@ "type": "ParserComponent" }, "dragging": false, - "id": "ParserComponent-KlzCE", + "id": "ParserComponent-YRRd0", "measured": { - "height": 361, + "height": 329, "width": 320 }, "position": { "x": 947.8993250761185, "y": 715.4566338975391 }, - "selected": true, + "selected": false, "type": "genericNode" }, { "data": { - "id": "URLComponent-KZ1r5", + "id": "URLComponent-DFXG5", "node": { "base_classes": [ "DataFrame" @@ -1679,7 +1288,7 @@ "type": "URLComponent" }, "dragging": false, - "id": "URLComponent-KZ1r5", + "id": "URLComponent-DFXG5", "measured": { "height": 316, "width": 320 @@ -1690,17 +1299,304 @@ }, "selected": false, "type": "genericNode" + }, + { + "data": { + "id": "LanguageModelComponent-1gwua", + "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, + "lf_version": "1.4.2", + "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": false, + "name": "api_key", + "password": true, + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, + "title_case": false, + "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 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\": \"Google\"}],\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": "MessageTextInput", + "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": "OpenAI" + }, + { + "icon": "Anthropic" + }, + { + "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": "MessageTextInput", + "advanced": true, + "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, + "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": "" + }, + "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-1gwua", + "measured": { + "height": 451, + "width": 320 + }, + "position": { + "x": 1722.2853754935447, + "y": 428.7881401477365 + }, + "selected": true, + "type": "genericNode" } ], "viewport": { - "x": 43.53287922422828, - "y": -74.37771085008922, - "zoom": 0.7226628919196559 + "x": 110.2780234785389, + "y": 60.25829919022374, + "zoom": 0.5264644230411742 } }, "description": "Auto-generate a customized blog post from instructions and referenced articles.", "endpoint_name": null, - "id": "c08170f6-6665-4b10-8153-94f3c84fa437", + "id": "428f69c6-43ea-4ea3-83cf-0032b5aab816", "is_component": false, "last_tested_version": "1.4.2", "name": "Blog Writer", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Financial Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Financial Agent.json index 7d0fa52ad..86b11f742 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Financial Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Financial Agent.json @@ -7,7 +7,7 @@ "data": { "sourceHandle": { "dataType": "SambaNovaModel", - "id": "SambaNovaModel-NEyqD", + "id": "SambaNovaModel-8WRTL", "name": "text_output", "output_types": [ "Message" @@ -15,7 +15,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-XjOH3", + "id": "ChatOutput-Cvbe8", "inputTypes": [ "Data", "DataFrame", @@ -24,12 +24,12 @@ "type": "str" } }, - "id": "reactflow__edge-SambaNovaModel-NEyqD{œdataTypeœ:œSambaNovaModelœ,œidœ:œSambaNovaModel-NEyqDœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-XjOH3{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-XjOH3œ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-SambaNovaModel-8WRTL{œdataTypeœ:œSambaNovaModelœ,œidœ:œSambaNovaModel-8WRTLœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-Cvbe8{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-Cvbe8œ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "SambaNovaModel-NEyqD", - "sourceHandle": "{œdataTypeœ: œSambaNovaModelœ, œidœ: œSambaNovaModel-NEyqDœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-XjOH3", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-XjOH3œ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" + "source": "SambaNovaModel-8WRTL", + "sourceHandle": "{œdataTypeœ: œSambaNovaModelœ, œidœ: œSambaNovaModel-8WRTLœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-Cvbe8", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-Cvbe8œ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -37,7 +37,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-X83ni", + "id": "ChatInput-qozug", "name": "message", "output_types": [ "Message" @@ -45,19 +45,19 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "Agent-cGZsD", + "id": "Agent-J7aBZ", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ChatInput-X83ni{œdataTypeœ:œChatInputœ,œidœ:œChatInput-X83niœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-cGZsD{œfieldNameœ:œinput_valueœ,œidœ:œAgent-cGZsDœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-qozug{œdataTypeœ:œChatInputœ,œidœ:œChatInput-qozugœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-J7aBZ{œfieldNameœ:œinput_valueœ,œidœ:œAgent-J7aBZœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-X83ni", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-X83niœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-cGZsD", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-cGZsDœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatInput-qozug", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-qozugœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-J7aBZ", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-J7aBZœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -65,7 +65,7 @@ "data": { "sourceHandle": { "dataType": "TavilySearchComponent", - "id": "TavilySearchComponent-7Y3yy", + "id": "TavilySearchComponent-5hDm1", "name": "component_as_tool", "output_types": [ "Tool" @@ -73,19 +73,19 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-cGZsD", + "id": "Agent-J7aBZ", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "reactflow__edge-TavilySearchComponent-7Y3yy{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-7Y3yyœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-cGZsD{œfieldNameœ:œtoolsœ,œidœ:œAgent-cGZsDœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-TavilySearchComponent-5hDm1{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-5hDm1œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-J7aBZ{œfieldNameœ:œtoolsœ,œidœ:œAgent-J7aBZœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", "selected": false, - "source": "TavilySearchComponent-7Y3yy", - "sourceHandle": "{œdataTypeœ: œTavilySearchComponentœ, œidœ: œTavilySearchComponent-7Y3yyœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-cGZsD", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-cGZsDœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "source": "TavilySearchComponent-5hDm1", + "sourceHandle": "{œdataTypeœ: œTavilySearchComponentœ, œidœ: œTavilySearchComponent-5hDm1œ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-J7aBZ", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-J7aBZœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -93,7 +93,7 @@ "data": { "sourceHandle": { "dataType": "URL", - "id": "URL-N9CXl", + "id": "URL-mbCdn", "name": "component_as_tool", "output_types": [ "Tool" @@ -101,19 +101,19 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-wqbpC", + "id": "Agent-oCAnt", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "reactflow__edge-URL-N9CXl{œdataTypeœ:œURLœ,œidœ:œURL-N9CXlœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-wqbpC{œfieldNameœ:œtoolsœ,œidœ:œAgent-wqbpCœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-URL-mbCdn{œdataTypeœ:œURLœ,œidœ:œURL-mbCdnœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-oCAnt{œfieldNameœ:œtoolsœ,œidœ:œAgent-oCAntœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", "selected": false, - "source": "URL-N9CXl", - "sourceHandle": "{œdataTypeœ: œURLœ, œidœ: œURL-N9CXlœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-wqbpC", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-wqbpCœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "source": "URL-mbCdn", + "sourceHandle": "{œdataTypeœ: œURLœ, œidœ: œURL-mbCdnœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-oCAnt", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-oCAntœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -121,7 +121,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-X83ni", + "id": "ChatInput-qozug", "name": "message", "output_types": [ "Message" @@ -129,19 +129,19 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "Agent-wqbpC", + "id": "Agent-oCAnt", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ChatInput-X83ni{œdataTypeœ:œChatInputœ,œidœ:œChatInput-X83niœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-wqbpC{œfieldNameœ:œinput_valueœ,œidœ:œAgent-wqbpCœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-qozug{œdataTypeœ:œChatInputœ,œidœ:œChatInput-qozugœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-oCAnt{œfieldNameœ:œinput_valueœ,œidœ:œAgent-oCAntœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-X83ni", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-X83niœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-wqbpC", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-wqbpCœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatInput-qozug", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-qozugœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-oCAnt", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-oCAntœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -149,7 +149,7 @@ "data": { "sourceHandle": { "dataType": "Agent", - "id": "Agent-wqbpC", + "id": "Agent-oCAnt", "name": "response", "output_types": [ "Message" @@ -157,19 +157,19 @@ }, "targetHandle": { "fieldName": "first_text", - "id": "Prompt-er8QV", + "id": "Prompt-GCeTu", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Agent-wqbpC{œdataTypeœ:œAgentœ,œidœ:œAgent-wqbpCœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-er8QV{œfieldNameœ:œfirst_textœ,œidœ:œPrompt-er8QVœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Agent-oCAnt{œdataTypeœ:œAgentœ,œidœ:œAgent-oCAntœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-GCeTu{œfieldNameœ:œfirst_textœ,œidœ:œPrompt-GCeTuœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Agent-wqbpC", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-wqbpCœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-er8QV", - "targetHandle": "{œfieldNameœ: œfirst_textœ, œidœ: œPrompt-er8QVœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Agent-oCAnt", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-oCAntœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-GCeTu", + "targetHandle": "{œfieldNameœ: œfirst_textœ, œidœ: œPrompt-GCeTuœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -177,7 +177,7 @@ "data": { "sourceHandle": { "dataType": "Agent", - "id": "Agent-cGZsD", + "id": "Agent-J7aBZ", "name": "response", "output_types": [ "Message" @@ -185,19 +185,19 @@ }, "targetHandle": { "fieldName": "second_text", - "id": "Prompt-er8QV", + "id": "Prompt-GCeTu", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Agent-cGZsD{œdataTypeœ:œAgentœ,œidœ:œAgent-cGZsDœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-er8QV{œfieldNameœ:œsecond_textœ,œidœ:œPrompt-er8QVœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Agent-J7aBZ{œdataTypeœ:œAgentœ,œidœ:œAgent-J7aBZœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-GCeTu{œfieldNameœ:œsecond_textœ,œidœ:œPrompt-GCeTuœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Agent-cGZsD", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-cGZsDœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-er8QV", - "targetHandle": "{œfieldNameœ: œsecond_textœ, œidœ: œPrompt-er8QVœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Agent-J7aBZ", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-J7aBZœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-GCeTu", + "targetHandle": "{œfieldNameœ: œsecond_textœ, œidœ: œPrompt-GCeTuœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -205,7 +205,7 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-er8QV", + "id": "Prompt-GCeTu", "name": "prompt", "output_types": [ "Message" @@ -213,19 +213,19 @@ }, "targetHandle": { "fieldName": "second_text", - "id": "Prompt-AdpTy", + "id": "Prompt-BghS1", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-er8QV{œdataTypeœ:œPromptœ,œidœ:œPrompt-er8QVœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Prompt-AdpTy{œfieldNameœ:œsecond_textœ,œidœ:œPrompt-AdpTyœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Prompt-GCeTu{œdataTypeœ:œPromptœ,œidœ:œPrompt-GCeTuœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Prompt-BghS1{œfieldNameœ:œsecond_textœ,œidœ:œPrompt-BghS1œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-er8QV", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-er8QVœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-AdpTy", - "targetHandle": "{œfieldNameœ: œsecond_textœ, œidœ: œPrompt-AdpTyœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-GCeTu", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-GCeTuœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-BghS1", + "targetHandle": "{œfieldNameœ: œsecond_textœ, œidœ: œPrompt-BghS1œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -233,7 +233,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-X83ni", + "id": "ChatInput-qozug", "name": "message", "output_types": [ "Message" @@ -241,19 +241,19 @@ }, "targetHandle": { "fieldName": "first_text", - "id": "Prompt-AdpTy", + "id": "Prompt-BghS1", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ChatInput-X83ni{œdataTypeœ:œChatInputœ,œidœ:œChatInput-X83niœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-AdpTy{œfieldNameœ:œfirst_textœ,œidœ:œPrompt-AdpTyœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-qozug{œdataTypeœ:œChatInputœ,œidœ:œChatInput-qozugœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-BghS1{œfieldNameœ:œfirst_textœ,œidœ:œPrompt-BghS1œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-X83ni", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-X83niœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-AdpTy", - "targetHandle": "{œfieldNameœ: œfirst_textœ, œidœ: œPrompt-AdpTyœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatInput-qozug", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-qozugœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-BghS1", + "targetHandle": "{œfieldNameœ: œfirst_textœ, œidœ: œPrompt-BghS1œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -261,7 +261,7 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-AdpTy", + "id": "Prompt-BghS1", "name": "prompt", "output_types": [ "Message" @@ -269,26 +269,27 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "SambaNovaModel-NEyqD", + "id": "SambaNovaModel-8WRTL", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-AdpTy{œdataTypeœ:œPromptœ,œidœ:œPrompt-AdpTyœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-SambaNovaModel-NEyqD{œfieldNameœ:œinput_valueœ,œidœ:œSambaNovaModel-NEyqDœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Prompt-BghS1{œdataTypeœ:œPromptœ,œidœ:œPrompt-BghS1œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-SambaNovaModel-8WRTL{œfieldNameœ:œinput_valueœ,œidœ:œSambaNovaModel-8WRTLœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-AdpTy", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-AdpTyœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "SambaNovaModel-NEyqD", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œSambaNovaModel-NEyqDœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-BghS1", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-BghS1œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "SambaNovaModel-8WRTL", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œSambaNovaModel-8WRTLœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, + "className": "", "data": { "sourceHandle": { "dataType": "YfinanceComponent", - "id": "YfinanceComponent-KpeWR", + "id": "YfinanceComponent-XI4d2", "name": "component_as_tool", "output_types": [ "Tool" @@ -296,25 +297,25 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-wqbpC", + "id": "Agent-oCAnt", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "xy-edge__YfinanceComponent-KpeWR{œdataTypeœ:œYfinanceComponentœ,œidœ:œYfinanceComponent-KpeWRœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-wqbpC{œfieldNameœ:œtoolsœ,œidœ:œAgent-wqbpCœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-YfinanceComponent-XI4d2{œdataTypeœ:œYfinanceComponentœ,œidœ:œYfinanceComponent-XI4d2œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-oCAnt{œfieldNameœ:œtoolsœ,œidœ:œAgent-oCAntœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", "selected": false, - "source": "YfinanceComponent-KpeWR", - "sourceHandle": "{œdataTypeœ: œYfinanceComponentœ, œidœ: œYfinanceComponent-KpeWRœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-wqbpC", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-wqbpCœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "source": "YfinanceComponent-XI4d2", + "sourceHandle": "{œdataTypeœ: œYfinanceComponentœ, œidœ: œYfinanceComponent-XI4d2œ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-oCAnt", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-oCAntœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" } ], "nodes": [ { "data": { - "id": "ChatInput-X83ni", + "id": "ChatInput-qozug", "node": { "base_classes": [ "Message" @@ -340,7 +341,7 @@ "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.2.0", + "lf_version": "1.4.3", "metadata": {}, "minimized": true, "output_types": [], @@ -611,9 +612,9 @@ "type": "ChatInput" }, "dragging": false, - "id": "ChatInput-X83ni", + "id": "ChatInput-qozug", "measured": { - "height": 66, + "height": 48, "width": 192 }, "position": { @@ -625,7 +626,7 @@ }, { "data": { - "id": "TavilySearchComponent-7Y3yy", + "id": "TavilySearchComponent-5hDm1", "node": { "base_classes": [ "Data", @@ -651,7 +652,7 @@ "frozen": false, "icon": "TavilyIcon", "legacy": false, - "lf_version": "1.2.0", + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "output_types": [], @@ -660,9 +661,11 @@ "allows_loop": false, "cache": true, "display_name": "Toolset", + "group_outputs": false, "hidden": false, "method": "to_toolkit", "name": "component_as_tool", + "options": null, "required_inputs": null, "selected": "Tool", "tool_mode": true, @@ -682,7 +685,7 @@ "dynamic": false, "info": "Your Tavily API Key.", "input_types": [], - "load_from_db": false, + "load_from_db": true, "name": "api_key", "password": true, "placeholder": "", @@ -690,7 +693,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "TAVILY_API_KEY" }, "chunks_per_source": { "_input_type": "IntInput", @@ -935,11 +938,11 @@ "type": "str" }, "tools_metadata": { - "_input_type": "TableInput", + "_input_type": "ToolsInput", "advanced": false, - "display_name": "Edit tools", + "display_name": "Actions", "dynamic": false, - "info": "", + "info": "Modify tool names and descriptions to help agents understand when to use each tool.", "is_list": true, "list_add_label": "Add More", "name": "tools_metadata", @@ -947,102 +950,28 @@ "real_time_refresh": true, "required": false, "show": true, - "table_icon": "Hammer", - "table_options": { - "block_add": true, - "block_delete": true, - "block_edit": true, - "block_filter": true, - "block_hide": true, - "block_select": true, - "block_sort": true, - "description": "Modify tool names and descriptions to help agents understand when to use each tool.", - "field_parsers": { - "commands": "commands", - "name": [ - "snake_case", - "no_blank" - ] - }, - "hide_options": true - }, - "table_schema": { - "columns": [ - { - "default": "None", - "description": "Specify the name of the tool.", - "disable_edit": false, - "display_name": "Tool Name", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "hidden": false, - "name": "name", - "sortable": false, - "type": "str" - }, - { - "default": "None", - "description": "Describe the purpose of the tool.", - "disable_edit": false, - "display_name": "Tool Description", - "edit_mode": "popover", - "filterable": false, - "formatter": "text", - "hidden": false, - "name": "description", - "sortable": false, - "type": "str" - }, - { - "default": "None", - "description": "The default identifiers for the tools and cannot be changed.", - "disable_edit": true, - "display_name": "Tool Identifiers", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "hidden": true, - "name": "tags", - "sortable": false, - "type": "str" - }, - { - "default": true, - "description": "Indicates whether the tool is currently active. Set to True to activate this tool.", - "disable_edit": false, - "display_name": "Enable", - "edit_mode": "popover", - "filterable": true, - "formatter": "boolean", - "hidden": false, - "name": "status", - "sortable": true, - "type": "boolean" - } - ] - }, "title_case": false, "tool_mode": false, "trace_as_metadata": true, - "trigger_icon": "Hammer", - "trigger_text": "", - "type": "table", + "type": "tools", "value": [ { - "description": "fetch_content(api_key: Message) - **Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", - "name": "TavilySearchComponent-fetch_content", + "args": { + "query": { + "default": "", + "description": "The search query you want to execute with Tavily.", + "title": "Query", + "type": "string" + } + }, + "description": "**Tavily Search** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", + "display_description": "**Tavily Search** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", + "display_name": "fetch_content_dataframe", + "name": "fetch_content_dataframe", + "readonly": false, "status": true, "tags": [ - "TavilySearchComponent-fetch_content" - ] - }, - { - "description": "fetch_content_text(api_key: Message) - **Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", - "name": "TavilySearchComponent-fetch_content_text", - "status": true, - "tags": [ - "TavilySearchComponent-fetch_content_text" + "fetch_content_dataframe" ] } ] @@ -1078,9 +1007,9 @@ "type": "TavilySearchComponent" }, "dragging": false, - "id": "TavilySearchComponent-7Y3yy", + "id": "TavilySearchComponent-5hDm1", "measured": { - "height": 354, + "height": 316, "width": 320 }, "position": { @@ -1094,7 +1023,7 @@ "data": { "description": "Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", "display_name": "Yahoo Finance", - "id": "YfinanceComponent-KpeWR", + "id": "YfinanceComponent-XI4d2", "node": { "base_classes": [ "Data", @@ -1116,6 +1045,7 @@ "frozen": false, "icon": "trending-up", "legacy": false, + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "output_types": [], @@ -1124,6 +1054,7 @@ "allows_loop": false, "cache": true, "display_name": "Toolset", + "group_outputs": false, "hidden": false, "method": "to_toolkit", "name": "component_as_tool", @@ -1273,49 +1204,14 @@ "type": "string" } }, - "description": "YfinanceComponent. fetch_content() - Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", - "display_description": "YfinanceComponent. fetch_content() - Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", - "display_name": "fetch_content", - "name": "fetch_content", + "description": "Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", + "display_description": "Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", + "display_name": "fetch_content_dataframe", + "name": "fetch_content_dataframe", + "readonly": false, "status": true, "tags": [ - "fetch_content" - ] - }, - { - "args": { - "symbol": { - "default": "", - "description": "The stock symbol to retrieve data for (e.g., AAPL, GOOG).", - "title": "Symbol", - "type": "string" - } - }, - "description": "YfinanceComponent. fetch_content_text() - Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", - "display_description": "YfinanceComponent. fetch_content_text() - Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", - "display_name": "fetch_content_text", - "name": "fetch_content_text", - "status": true, - "tags": [ - "fetch_content_text" - ] - }, - { - "args": { - "symbol": { - "default": "", - "description": "The stock symbol to retrieve data for (e.g., AAPL, GOOG).", - "title": "Symbol", - "type": "string" - } - }, - "description": "YfinanceComponent. as_dataframe() - Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", - "display_description": "YfinanceComponent. as_dataframe() - Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", - "display_name": "as_dataframe", - "name": "as_dataframe", - "status": true, - "tags": [ - "as_dataframe" + "fetch_content_dataframe" ] } ] @@ -1328,9 +1224,9 @@ "type": "YfinanceComponent" }, "dragging": false, - "id": "YfinanceComponent-KpeWR", + "id": "YfinanceComponent-XI4d2", "measured": { - "height": 461, + "height": 398, "width": 320 }, "position": { @@ -1342,7 +1238,7 @@ }, { "data": { - "id": "ChatOutput-XjOH3", + "id": "ChatOutput-Cvbe8", "node": { "base_classes": [ "Message" @@ -1368,7 +1264,7 @@ "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.2.0", + "lf_version": "1.4.3", "metadata": {}, "minimized": true, "output_types": [], @@ -1638,9 +1534,9 @@ "type": "ChatOutput" }, "dragging": false, - "id": "ChatOutput-XjOH3", + "id": "ChatOutput-Cvbe8", "measured": { - "height": 66, + "height": 48, "width": 192 }, "position": { @@ -1652,7 +1548,7 @@ }, { "data": { - "id": "URL-N9CXl", + "id": "URL-mbCdn", "node": { "base_classes": [ "Data", @@ -1675,7 +1571,7 @@ "frozen": false, "icon": "layout-template", "legacy": false, - "lf_version": "1.2.0", + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "output_types": [], @@ -1684,6 +1580,7 @@ "allows_loop": false, "cache": true, "display_name": "Toolset", + "group_outputs": false, "hidden": null, "method": "to_toolkit", "name": "component_as_tool", @@ -1886,9 +1783,9 @@ "name": "max_depth", "placeholder": "", "range_spec": { - "max": 5.0, - "min": 1.0, - "step": 1.0, + "max": 5, + "min": 1, + "step": 1, "step_type": "float" }, "required": false, @@ -1959,7 +1856,7 @@ "args": { "urls": { "default": "", - "description": "", + "description": "Enter one or more URLs to crawl recursively, by clicking the '+' button.", "items": { "type": "string" }, @@ -1967,10 +1864,11 @@ "type": "array" } }, - "description": "URL. fetch_content() - Load and retrieve data from specified URLs. Supports output in plain text, raw HTML, or JSON, with options for cleaning and separating multiple outputs.", - "display_description": "URL. fetch_content() - Load and retrieve data from specified URLs. Supports output in plain text, raw HTML, or JSON, with options for cleaning and separating multiple outputs.", + "description": "Fetch content from one or more web pages, following links recursively.", + "display_description": "Fetch content from one or more web pages, following links recursively.", "display_name": "fetch_content", "name": "fetch_content", + "readonly": false, "status": true, "tags": [ "fetch_content" @@ -1980,7 +1878,7 @@ "args": { "urls": { "default": "", - "description": "", + "description": "Enter one or more URLs to crawl recursively, by clicking the '+' button.", "items": { "type": "string" }, @@ -1988,34 +1886,14 @@ "type": "array" } }, - "description": "URL. fetch_content_text() - Load and retrieve data from specified URLs. Supports output in plain text, raw HTML, or JSON, with options for cleaning and separating multiple outputs.", - "display_description": "URL. fetch_content_text() - Load and retrieve data from specified URLs. Supports output in plain text, raw HTML, or JSON, with options for cleaning and separating multiple outputs.", - "display_name": "fetch_content_text", - "name": "fetch_content_text", + "description": "Fetch content from one or more web pages, following links recursively.", + "display_description": "Fetch content from one or more web pages, following links recursively.", + "display_name": "as_message", + "name": "as_message", + "readonly": false, "status": true, "tags": [ - "fetch_content_text" - ] - }, - { - "args": { - "urls": { - "default": "", - "description": "", - "items": { - "type": "string" - }, - "title": "Urls", - "type": "array" - } - }, - "description": "URL. as_dataframe() - Load and retrieve data from specified URLs. Supports output in plain text, raw HTML, or JSON, with options for cleaning and separating multiple outputs.", - "display_description": "URL. as_dataframe() - Load and retrieve data from specified URLs. Supports output in plain text, raw HTML, or JSON, with options for cleaning and separating multiple outputs.", - "display_name": "as_dataframe", - "name": "as_dataframe", - "status": true, - "tags": [ - "as_dataframe" + "as_message" ] } ] @@ -2067,9 +1945,9 @@ "type": "URL" }, "dragging": false, - "id": "URL-N9CXl", + "id": "URL-mbCdn", "measured": { - "height": 523, + "height": 290, "width": 320 }, "position": { @@ -2081,7 +1959,7 @@ }, { "data": { - "id": "note-tZG9P", + "id": "note-yhn5a", "node": { "description": "# Financial Assistant Agents \n\nThe Financial Assistant Agent retrieves content and writes reports about financial queries.\n\n## Prerequisites\n\n* [Tavily AI Search key](https://docs.tavily.com/welcome)\n* [SambaNova API key](https://cloud.sambanova.ai/) \n\n## Quickstart\n\n1. In both **Agent** components and **SambaNova** component, add your SambaNova API key. \nIn the **Model Provider** field, select **Sambanova**, and select a model.\n3. In the **Tavily Search** component, add your **Tavily API key**.\n4. Click the **Playground** and ask `Why did Nvidia stock drop in January?`", "display_name": "", @@ -2094,10 +1972,10 @@ }, "dragging": false, "height": 630, - "id": "note-tZG9P", + "id": "note-yhn5a", "measured": { "height": 630, - "width": 479 + "width": 478 }, "position": { "x": -1119.9423274254439, @@ -2110,7 +1988,7 @@ }, { "data": { - "id": "SambaNovaModel-NEyqD", + "id": "SambaNovaModel-8WRTL", "node": { "base_classes": [ "LanguageModel", @@ -2137,7 +2015,7 @@ "frozen": false, "icon": "SambaNova", "legacy": false, - "lf_version": "1.2.0", + "lf_version": "1.4.3", "metadata": { "keywords": [ "model", @@ -2417,9 +2295,9 @@ "type": "SambaNovaModel" }, "dragging": false, - "id": "SambaNovaModel-NEyqD", + "id": "SambaNovaModel-8WRTL", "measured": { - "height": 525, + "height": 450, "width": 320 }, "position": { @@ -2431,7 +2309,7 @@ }, { "data": { - "id": "Agent-cGZsD", + "id": "Agent-J7aBZ", "node": { "base_classes": [ "Message" @@ -2476,7 +2354,7 @@ "icon": "bot", "key": "Agent", "legacy": false, - "lf_version": "1.2.0", + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "output_types": [], @@ -2485,8 +2363,11 @@ "allows_loop": false, "cache": true, "display_name": "Response", + "group_outputs": false, "method": "message_response", "name": "response", + "options": null, + "required_inputs": null, "selected": "Message", "tool_mode": true, "types": [ @@ -2614,6 +2495,7 @@ "name": "api_key", "password": true, "placeholder": "", + "real_time_refresh": true, "required": true, "show": true, "title_case": false, @@ -2803,6 +2685,7 @@ "display_name": "Mode", "dynamic": false, "info": "Operation mode: Store messages or Retrieve messages.", + "input_types": [], "name": "mode", "options": [ "Retrieve", @@ -3009,6 +2892,7 @@ "display_name": "Sender Type", "dynamic": false, "info": "Filter by sender type.", + "input_types": [], "name": "sender_type", "options": [ "Machine", @@ -3193,21 +3077,21 @@ "type": "Agent" }, "dragging": false, - "id": "Agent-cGZsD", + "id": "Agent-J7aBZ", "measured": { - "height": 624, + "height": 593, "width": 320 }, "position": { "x": -114.7705455447527, "y": 395.9726937371793 }, - "selected": true, + "selected": false, "type": "genericNode" }, { "data": { - "id": "Agent-wqbpC", + "id": "Agent-oCAnt", "node": { "base_classes": [ "Message" @@ -3252,7 +3136,7 @@ "icon": "bot", "key": "Agent", "legacy": false, - "lf_version": "1.2.0", + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "output_types": [], @@ -3261,8 +3145,11 @@ "allows_loop": false, "cache": true, "display_name": "Response", + "group_outputs": false, "method": "message_response", "name": "response", + "options": null, + "required_inputs": null, "selected": "Message", "tool_mode": true, "types": [ @@ -3390,6 +3277,7 @@ "name": "api_key", "password": true, "placeholder": "", + "real_time_refresh": true, "required": true, "show": true, "title_case": false, @@ -3579,6 +3467,7 @@ "display_name": "Mode", "dynamic": false, "info": "Operation mode: Store messages or Retrieve messages.", + "input_types": [], "name": "mode", "options": [ "Retrieve", @@ -3785,6 +3674,7 @@ "display_name": "Sender Type", "dynamic": false, "info": "Filter by sender type.", + "input_types": [], "name": "sender_type", "options": [ "Machine", @@ -3969,9 +3859,9 @@ "type": "Agent" }, "dragging": false, - "id": "Agent-wqbpC", + "id": "Agent-oCAnt", "measured": { - "height": 624, + "height": 593, "width": 320 }, "position": { @@ -3983,7 +3873,7 @@ }, { "data": { - "id": "Prompt-er8QV", + "id": "Prompt-GCeTu", "node": { "base_classes": [ "Message" @@ -4012,6 +3902,7 @@ "is_input": null, "is_output": null, "legacy": false, + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "name": "", @@ -4147,9 +4038,9 @@ "type": "Prompt" }, "dragging": false, - "id": "Prompt-er8QV", + "id": "Prompt-GCeTu", "measured": { - "height": 433, + "height": 386, "width": 320 }, "position": { @@ -4161,7 +4052,7 @@ }, { "data": { - "id": "Prompt-AdpTy", + "id": "Prompt-BghS1", "node": { "base_classes": [ "Message" @@ -4190,6 +4081,7 @@ "is_input": null, "is_output": null, "legacy": false, + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "name": "", @@ -4325,9 +4217,9 @@ "type": "Prompt" }, "dragging": false, - "id": "Prompt-AdpTy", + "id": "Prompt-BghS1", "measured": { - "height": 433, + "height": 386, "width": 320 }, "position": { @@ -4339,15 +4231,16 @@ } ], "viewport": { - "x": 402.8529727761044, - "y": 359.62391032755147, - "zoom": 0.5103514759965421 + "x": 443.41452386254014, + "y": 287.7203359909025, + "zoom": 0.3828602258274036 } }, "description": "Financial assistant chatbot that uses specialized agents to research for financial information", "endpoint_name": null, + "id": "45fad7d2-2a24-4049-ad1b-6d800f5cc4c6", "is_component": false, - "last_tested_version": "1.3.4", + "last_tested_version": "1.4.3", "name": "Financial Agent", "tags": [ "assistants", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json b/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json index ac92da745..f0d7b98ec 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json @@ -1,41 +1,13 @@ { "data": { "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-fK2C2", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "StructuredOutput-uvBkm", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-fK2C2{œdataTypeœ:œChatInputœ,œidœ:œChatInput-fK2C2œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-StructuredOutput-uvBkm{œfieldNameœ:œinput_valueœ,œidœ:œStructuredOutput-uvBkmœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ChatInput-fK2C2", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-fK2C2œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "StructuredOutput-uvBkm", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œStructuredOutput-uvBkmœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, { "animated": false, "className": "", "data": { "sourceHandle": { "dataType": "parser", - "id": "parser-YBMuU", + "id": "parser-ZMjjt", "name": "parsed_text", "output_types": [ "Message" @@ -43,7 +15,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-19sYN", + "id": "ChatOutput-DHgU9", "inputTypes": [ "Data", "DataFrame", @@ -52,49 +24,20 @@ "type": "str" } }, - "id": "reactflow__edge-parser-YBMuU{œdataTypeœ:œparserœ,œidœ:œparser-YBMuUœ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-19sYN{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-19sYNœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-parser-ZMjjt{œdataTypeœ:œparserœ,œidœ:œparser-ZMjjtœ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-DHgU9{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-DHgU9œ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "parser-YBMuU", - "sourceHandle": "{œdataTypeœ: œparserœ, œidœ: œparser-YBMuUœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-19sYN", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-19sYNœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" + "source": "parser-ZMjjt", + "sourceHandle": "{œdataTypeœ: œparserœ, œidœ: œparser-ZMjjtœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-DHgU9", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-DHgU9œ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, "className": "", "data": { "sourceHandle": { - "dataType": "StructuredOutput", - "id": "StructuredOutput-uvBkm", - "name": "structured_output", - "output_types": [ - "Data" - ] - }, - "targetHandle": { - "fieldName": "input_data", - "id": "parser-YBMuU", - "inputTypes": [ - "DataFrame", - "Data" - ], - "type": "other" - } - }, - "id": "reactflow__edge-StructuredOutput-uvBkm{œdataTypeœ:œStructuredOutputœ,œidœ:œStructuredOutput-uvBkmœ,œnameœ:œstructured_outputœ,œoutput_typesœ:[œDataœ]}-parser-YBMuU{œfieldNameœ:œinput_dataœ,œidœ:œparser-YBMuUœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", - "selected": false, - "source": "StructuredOutput-uvBkm", - "sourceHandle": "{œdataTypeœ: œStructuredOutputœ, œidœ: œStructuredOutput-uvBkmœ, œnameœ: œstructured_outputœ, œoutput_typesœ: [œDataœ]}", - "target": "parser-YBMuU", - "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œparser-YBMuUœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-rgotA", + "dataType": "LanguageModelComponent", + "id": "LanguageModelComponent-jtKdb", "name": "model_output", "output_types": [ "LanguageModel" @@ -102,418 +45,82 @@ }, "targetHandle": { "fieldName": "llm", - "id": "StructuredOutput-uvBkm", + "id": "StructuredOutput-2t0FB", "inputTypes": [ "LanguageModel" ], "type": "other" } }, - "id": "reactflow__edge-OpenAIModel-rgotA{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-rgotAœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}-StructuredOutput-uvBkm{œfieldNameœ:œllmœ,œidœ:œStructuredOutput-uvBkmœ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-LanguageModelComponent-jtKdb{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-jtKdbœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}-StructuredOutput-2t0FB{œfieldNameœ:œllmœ,œidœ:œStructuredOutput-2t0FBœ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}", "selected": false, - "source": "OpenAIModel-rgotA", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-rgotAœ, œnameœ: œmodel_outputœ, œoutput_typesœ: [œLanguageModelœ]}", - "target": "StructuredOutput-uvBkm", - "targetHandle": "{œfieldNameœ: œllmœ, œidœ: œStructuredOutput-uvBkmœ, œinputTypesœ: [œLanguageModelœ], œtypeœ: œotherœ}" + "source": "LanguageModelComponent-jtKdb", + "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-jtKdbœ, œnameœ: œmodel_outputœ, œoutput_typesœ: [œLanguageModelœ]}", + "target": "StructuredOutput-2t0FB", + "targetHandle": "{œfieldNameœ: œllmœ, œidœ: œStructuredOutput-2t0FBœ, œinputTypesœ: [œLanguageModelœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-VaLgK", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "StructuredOutput-2t0FB", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-VaLgK{œdataTypeœ:œChatInputœ,œidœ:œChatInput-VaLgKœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-StructuredOutput-2t0FB{œfieldNameœ:œinput_valueœ,œidœ:œStructuredOutput-2t0FBœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "ChatInput-VaLgK", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-VaLgKœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "StructuredOutput-2t0FB", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œStructuredOutput-2t0FBœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "StructuredOutput", + "id": "StructuredOutput-2t0FB", + "name": "structured_output", + "output_types": [ + "Data" + ] + }, + "targetHandle": { + "fieldName": "input_data", + "id": "parser-ZMjjt", + "inputTypes": [ + "DataFrame", + "Data" + ], + "type": "other" + } + }, + "id": "reactflow__edge-StructuredOutput-2t0FB{œdataTypeœ:œStructuredOutputœ,œidœ:œStructuredOutput-2t0FBœ,œnameœ:œstructured_outputœ,œoutput_typesœ:[œDataœ]}-parser-ZMjjt{œfieldNameœ:œinput_dataœ,œidœ:œparser-ZMjjtœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", + "selected": false, + "source": "StructuredOutput-2t0FB", + "sourceHandle": "{œdataTypeœ: œStructuredOutputœ, œidœ: œStructuredOutput-2t0FBœ, œnameœ: œstructured_outputœ, œoutput_typesœ: [œDataœ]}", + "target": "parser-ZMjjt", + "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œparser-ZMjjtœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" } ], "nodes": [ { "data": { - "id": "OpenAIModel-rgotA", - "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], - "beta": false, - "category": "models", - "conditional_paths": [], - "custom_fields": {}, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "system_message", - "stream", - "max_tokens", - "model_kwargs", - "json_mode", - "model_name", - "openai_api_base", - "api_key", - "temperature", - "seed", - "max_retries", - "timeout" - ], - "frozen": false, - "icon": "OpenAI", - "key": "OpenAIModel", - "legacy": false, - "lf_version": "1.2.0", - "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": null, - "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, - "score": 0.001, - "template": { - "_type": "Component", - "api_key": { - "_input_type": "SecretStrInput", - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], - "load_from_db": true, - "name": "api_key", - "password": true, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "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 typing import Any\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import (\n OPENAI_MODEL_NAMES,\n OPENAI_REASONING_MODEL_NAMES,\n)\nfrom langflow.field_typing import LanguageModel\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.inputs.inputs import BoolInput, DictInput, DropdownInput, IntInput, SecretStrInput, SliderInput, StrInput\nfrom langflow.logging import logger\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n name = \"OpenAIModel\"\n\n inputs = [\n *LCModelComponent._base_inputs,\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n range_spec=RangeSpec(min=0, max=128000),\n ),\n DictInput(\n name=\"model_kwargs\",\n display_name=\"Model Kwargs\",\n advanced=True,\n info=\"Additional keyword arguments to pass to the model.\",\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n advanced=False,\n options=OPENAI_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[1],\n combobox=True,\n real_time_refresh=True,\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. \"\n \"Defaults to https://api.openai.com/v1. \"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n required=True,\n ),\n SliderInput(\n name=\"temperature\",\n display_name=\"Temperature\",\n value=0.1,\n range_spec=RangeSpec(min=0, max=1, step=0.01),\n show=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n IntInput(\n name=\"max_retries\",\n display_name=\"Max Retries\",\n info=\"The maximum number of retries to make when generating.\",\n advanced=True,\n value=5,\n ),\n IntInput(\n name=\"timeout\",\n display_name=\"Timeout\",\n info=\"The timeout for requests to OpenAI completion API.\",\n advanced=True,\n value=700,\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n parameters = {\n \"api_key\": SecretStr(self.api_key).get_secret_value() if self.api_key else None,\n \"model_name\": self.model_name,\n \"max_tokens\": self.max_tokens or None,\n \"model_kwargs\": self.model_kwargs or {},\n \"base_url\": self.openai_api_base or \"https://api.openai.com/v1\",\n \"seed\": self.seed,\n \"max_retries\": self.max_retries,\n \"timeout\": self.timeout,\n \"temperature\": self.temperature if self.temperature is not None else 0.1,\n }\n\n logger.info(f\"Model name: {self.model_name}\")\n if self.model_name in OPENAI_REASONING_MODEL_NAMES:\n logger.info(\"Getting reasoning model parameters\")\n parameters.pop(\"temperature\")\n parameters.pop(\"seed\")\n output = ChatOpenAI(**parameters)\n if self.json_mode:\n output = output.bind(response_format={\"type\": \"json_object\"})\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"Get a message from an OpenAI exception.\n\n Args:\n e (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n try:\n from openai import BadRequestError\n except ImportError:\n return None\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\")\n if message:\n return message\n return None\n\n def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None) -> dict:\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_REASONING_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = False\n build_config[\"seed\"][\"show\"] = False\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = True\n build_config[\"seed\"][\"show\"] = True\n return build_config\n" - }, - "input_value": { - "_input_type": "MessageInput", - "advanced": false, - "display_name": "Input", - "dynamic": false, - "info": "", - "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": "" - }, - "json_mode": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "JSON Mode", - "dynamic": false, - "info": "If True, it will output JSON regardless of passing a schema.", - "list": false, - "list_add_label": "Add More", - "name": "json_mode", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "max_retries": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Retries", - "dynamic": false, - "info": "The maximum number of retries to make when generating.", - "list": false, - "list_add_label": "Add More", - "name": "max_retries", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 5 - }, - "max_tokens": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "list_add_label": "Add More", - "name": "max_tokens", - "placeholder": "", - "range_spec": { - "max": 128000, - "min": 0, - "step": 0.1, - "step_type": "float" - }, - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "model_kwargs": { - "_input_type": "DictInput", - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "Additional keyword arguments to pass to the model.", - "list": false, - "list_add_label": "Add More", - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "model_name": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": true, - "dialog_inputs": {}, - "display_name": "Model Name", - "dynamic": false, - "info": "", - "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", - "o1" - ], - "options_metadata": [], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "gpt-4.1-mini" - }, - "openai_api_base": { - "_input_type": "StrInput", - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "openai_api_base", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "seed": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Seed", - "dynamic": false, - "info": "The seed controls the reproducibility of the job.", - "list": false, - "list_add_label": "Add More", - "name": "seed", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 1 - }, - "stream": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", - "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, - "display_name": "System Message", - "dynamic": false, - "info": "System message to pass to the model.", - "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": "" - }, - "temperature": { - "_input_type": "SliderInput", - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "info": "", - "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 - }, - "timeout": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Timeout", - "dynamic": false, - "info": "The timeout for requests to OpenAI completion API.", - "list": false, - "list_add_label": "Add More", - "name": "timeout", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 700 - } - }, - "tool_mode": false - }, - "selected_output": "model_output", - "showNode": true, - "type": "OpenAIModel" - }, - "dragging": false, - "id": "OpenAIModel-rgotA", - "measured": { - "height": 540, - "width": 320 - }, - "position": { - "x": 929.32546849971, - "y": -379.0571813289482 - }, - "selected": false, - "type": "genericNode" - }, - { - "data": { - "id": "ChatOutput-19sYN", + "id": "ChatOutput-DHgU9", "node": { "base_classes": [ "Message" @@ -541,7 +148,7 @@ "icon": "MessagesSquare", "key": "ChatOutput", "legacy": false, - "lf_version": "1.2.0", + "lf_version": "1.4.3", "metadata": {}, "minimized": true, "output_types": [], @@ -811,7 +418,7 @@ "showNode": false, "type": "ChatOutput" }, - "id": "ChatOutput-19sYN", + "id": "ChatOutput-DHgU9", "measured": { "height": 48, "width": 192 @@ -825,7 +432,7 @@ }, { "data": { - "id": "ChatInput-fK2C2", + "id": "ChatInput-VaLgK", "node": { "base_classes": [ "Message" @@ -853,7 +460,7 @@ "icon": "MessagesSquare", "key": "ChatInput", "legacy": false, - "lf_version": "1.2.0", + "lf_version": "1.4.3", "metadata": {}, "minimized": true, "output_types": [], @@ -1125,7 +732,7 @@ "type": "ChatInput" }, "dragging": false, - "id": "ChatInput-fK2C2", + "id": "ChatInput-VaLgK", "measured": { "height": 48, "width": 192 @@ -1139,7 +746,7 @@ }, { "data": { - "id": "note-FQnS7", + "id": "note-O8fhi", "node": { "description": "### 💡 Add your OpenAI API key here", "display_name": "", @@ -1151,23 +758,23 @@ "type": "note" }, "dragging": false, - "id": "note-FQnS7", + "id": "note-O8fhi", "measured": { "height": 324, "width": 324 }, "position": { - "x": 903.4968193095694, - "y": -432.3984534767629 + "x": 905.0310846743869, + "y": -389.43902326187924 }, "selected": false, "type": "noteNode" }, { "data": { - "id": "note-WcFYD", + "id": "note-2715s", "node": { - "description": "\n# Financial Report Parser\n\nThis template extracts key financial metrics from a given financial report text using OpenAI's GPT-4o-mini model. The extracted data is structured and formatted for chat consumption.\n\n## Prerequisites\n\n- **[OpenAI API Key](https://platform.openai.com/)**\n\n## Quickstart\n\n1. Add your OpenAI API key to the OpenAI model.\n2. To run the flow, click **Playground**.\nThe **Chat Input** component in this template is pre-loaded with a sample financial report for demonstrating how structured data is extracted.\n\n* The **OpenAI** model component identifies and retrieves Gross Profit, EBITDA, Net Income, and Operating Expenses from the financial report.\n* The **Structured Output** component formats extracted data into a structured format for better readability and further processing.\n* The **Parser** component converts extracted data into formatted messages for chat consumption.\n\n\n\n\n\n", + "description": "\n# Financial Report Parser\n\nThis template extracts key financial metrics from a given financial report text using OpenAI's GPT-4o-mini model. The extracted data is structured and formatted for chat consumption.\n\n## Prerequisites\n\n- **[OpenAI API Key](https://platform.openai.com/)**\n\n## Quickstart\n\n1. Add your OpenAI API key to the Language model.\n2. To run the flow, click **Playground**.\nThe **Chat Input** component in this template is pre-loaded with a sample financial report for demonstrating how structured data is extracted.\n\n* The **Language Model** model component identifies and retrieves Gross Profit, EBITDA, Net Income, and Operating Expenses from the financial report.\n* The **Structured Output** component formats extracted data into a structured format for better readability and further processing.\n* The **Parser** component converts extracted data into formatted messages for chat consumption.\n\n\n\n\n\n", "display_name": "", "documentation": "", "template": {} @@ -1176,7 +783,7 @@ }, "dragging": false, "height": 688, - "id": "note-WcFYD", + "id": "note-2715s", "measured": { "height": 688, "width": 620 @@ -1192,280 +799,7 @@ }, { "data": { - "id": "StructuredOutput-uvBkm", - "node": { - "base_classes": [ - "Data", - "DataFrame" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Uses an LLM to generate structured data. Ideal for extraction and consistency.", - "display_name": "Structured Output", - "documentation": "", - "edited": false, - "field_order": [ - "llm", - "input_value", - "system_prompt", - "schema_name", - "output_schema" - ], - "frozen": false, - "icon": "braces", - "legacy": false, - "lf_version": "1.2.0", - "metadata": {}, - "minimized": false, - "output_types": [], - "outputs": [ - { - "allows_loop": false, - "cache": true, - "display_name": "Structured Output", - "group_outputs": false, - "method": "build_structured_output", - "name": "structured_output", - "selected": "Data", - "tool_mode": true, - "types": [ - "Data" - ], - "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 pydantic import BaseModel, Field, create_model\nfrom trustcall import create_extractor\n\nfrom langflow.base.models.chat_result import get_chat_result\nfrom langflow.custom.custom_component.component import Component\nfrom langflow.helpers.base_model import build_model_from_schema\nfrom langflow.io import (\n HandleInput,\n MessageTextInput,\n MultilineInput,\n Output,\n TableInput,\n)\nfrom langflow.schema.data import Data\nfrom langflow.schema.table import EditMode\n\n\nclass StructuredOutputComponent(Component):\n display_name = \"Structured Output\"\n description = \"Uses an LLM to generate structured data. Ideal for extraction and consistency.\"\n name = \"StructuredOutput\"\n icon = \"braces\"\n\n inputs = [\n HandleInput(\n name=\"llm\",\n display_name=\"Language Model\",\n info=\"The language model to use to generate the structured output.\",\n input_types=[\"LanguageModel\"],\n required=True,\n ),\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input Message\",\n info=\"The input message to the language model.\",\n tool_mode=True,\n required=True,\n ),\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"Format Instructions\",\n info=\"The instructions to the language model for formatting the output.\",\n value=(\n \"You are an AI that extracts one structured JSON object from unstructured text. \"\n \"Use a predefined schema with expected types (str, int, float, bool, dict). \"\n \"If multiple structures exist, extract only the first most complete one. \"\n \"Fill missing or ambiguous values with defaults: null for missing values. \"\n \"Ignore duplicates and partial repeats. \"\n \"Always return one valid JSON, never throw errors or return multiple objects.\"\n \"Output: A single well-formed JSON object, and nothing else.\"\n ),\n required=True,\n advanced=True,\n ),\n MessageTextInput(\n name=\"schema_name\",\n display_name=\"Schema Name\",\n info=\"Provide a name for the output data schema.\",\n advanced=True,\n ),\n TableInput(\n name=\"output_schema\",\n display_name=\"Output Schema\",\n info=\"Define the structure and data types for the model's output.\",\n required=True,\n # TODO: remove deault value\n table_schema=[\n {\n \"name\": \"name\",\n \"display_name\": \"Name\",\n \"type\": \"str\",\n \"description\": \"Specify the name of the output field.\",\n \"default\": \"field\",\n \"edit_mode\": EditMode.INLINE,\n },\n {\n \"name\": \"description\",\n \"display_name\": \"Description\",\n \"type\": \"str\",\n \"description\": \"Describe the purpose of the output field.\",\n \"default\": \"description of field\",\n \"edit_mode\": EditMode.POPOVER,\n },\n {\n \"name\": \"type\",\n \"display_name\": \"Type\",\n \"type\": \"str\",\n \"edit_mode\": EditMode.INLINE,\n \"description\": (\"Indicate the data type of the output field (e.g., str, int, float, bool, dict).\"),\n \"options\": [\"str\", \"int\", \"float\", \"bool\", \"dict\"],\n \"default\": \"str\",\n },\n {\n \"name\": \"multiple\",\n \"display_name\": \"As List\",\n \"type\": \"boolean\",\n \"description\": \"Set to True if this output field should be a list of the specified type.\",\n \"default\": \"False\",\n \"edit_mode\": EditMode.INLINE,\n },\n ],\n value=[\n {\n \"name\": \"field\",\n \"description\": \"description of field\",\n \"type\": \"str\",\n \"multiple\": \"False\",\n }\n ],\n ),\n ]\n\n outputs = [\n Output(\n name=\"structured_output\",\n display_name=\"Structured Output\",\n method=\"build_structured_output\",\n ),\n ]\n\n def build_structured_output_base(self):\n schema_name = self.schema_name or \"OutputModel\"\n\n if not hasattr(self.llm, \"with_structured_output\"):\n msg = \"Language model does not support structured output.\"\n raise TypeError(msg)\n if not self.output_schema:\n msg = \"Output schema cannot be empty\"\n raise ValueError(msg)\n\n output_model_ = build_model_from_schema(self.output_schema)\n\n output_model = create_model(\n schema_name,\n __doc__=f\"A list of {schema_name}.\",\n objects=(list[output_model_], Field(description=f\"A list of {schema_name}.\")), # type: ignore[valid-type]\n )\n\n try:\n llm_with_structured_output = create_extractor(self.llm, tools=[output_model])\n except NotImplementedError as exc:\n msg = f\"{self.llm.__class__.__name__} does not support structured output.\"\n raise TypeError(msg) from exc\n\n config_dict = {\n \"run_name\": self.display_name,\n \"project_name\": self.get_project_name(),\n \"callbacks\": self.get_langchain_callbacks(),\n }\n result = get_chat_result(\n runnable=llm_with_structured_output,\n system_message=self.system_prompt,\n input_value=self.input_value,\n config=config_dict,\n )\n\n # OPTIMIZATION NOTE: Simplified processing based on trustcall response structure\n # Handle non-dict responses (shouldn't happen with trustcall, but defensive)\n if not isinstance(result, dict):\n return result\n\n # Extract first response and convert BaseModel to dict\n responses = result.get(\"responses\", [])\n if not responses:\n return result\n\n # Convert BaseModel to dict (creates the \"objects\" key)\n first_response = responses[0]\n structured_data = first_response.model_dump() if isinstance(first_response, BaseModel) else first_response\n\n # Extract the objects array (guaranteed to exist due to our Pydantic model structure)\n return structured_data.get(\"objects\", structured_data)\n\n def build_structured_output(self) -> Data:\n output = self.build_structured_output_base()\n if not isinstance(output, list) or not output:\n # handle empty or unexpected type case\n msg = \"No structured output returned\"\n raise ValueError(msg)\n if len(output) != 1:\n msg = \"Multiple structured outputs returned\"\n raise ValueError(msg)\n return Data(data=output[0])\n" - }, - "input_value": { - "_input_type": "MessageTextInput", - "advanced": false, - "display_name": "Input Message", - "dynamic": false, - "info": "The input message to the language model.", - "input_types": [ - "Message" - ], - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "tool_mode": true, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "llm": { - "_input_type": "HandleInput", - "advanced": false, - "display_name": "Language Model", - "dynamic": false, - "info": "The language model to use to generate the structured output.", - "input_types": [ - "LanguageModel" - ], - "list": false, - "list_add_label": "Add More", - "name": "llm", - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "other", - "value": "" - }, - "output_schema": { - "_input_type": "TableInput", - "advanced": false, - "display_name": "Output Schema", - "dynamic": false, - "info": "Define the structure and data types for the model's output.", - "is_list": true, - "list_add_label": "Add More", - "load_from_db": false, - "name": "output_schema", - "placeholder": "", - "required": true, - "show": true, - "table_icon": "Table", - "table_schema": { - "columns": [ - { - "default": "field", - "description": "Specify the name of the output field.", - "disable_edit": false, - "display_name": "Name", - "edit_mode": "inline", - "filterable": true, - "formatter": "text", - "hidden": false, - "name": "name", - "sortable": true, - "type": "text" - }, - { - "default": "description of field", - "description": "Describe the purpose of the output field.", - "disable_edit": false, - "display_name": "Description", - "edit_mode": "popover", - "filterable": true, - "formatter": "text", - "hidden": false, - "name": "description", - "sortable": true, - "type": "text" - }, - { - "default": "text", - "description": "Indicate the data type of the output field (e.g., str, int, float, bool, list, dict).", - "disable_edit": false, - "display_name": "Type", - "edit_mode": "inline", - "filterable": true, - "formatter": "text", - "hidden": false, - "name": "type", - "sortable": true, - "type": "text" - }, - { - "default": "False", - "description": "Set to True if this output field should be a list of the specified type.", - "disable_edit": false, - "display_name": "Multiple", - "edit_mode": "inline", - "filterable": true, - "formatter": "text", - "hidden": false, - "name": "multiple", - "sortable": true, - "type": "boolean" - } - ] - }, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "trigger_icon": "Table", - "trigger_text": "Open table", - "type": "table", - "value": [ - { - "description": "description of field", - "multiple": "False", - "name": "EBITDA", - "type": "text" - }, - { - "description": "description of field", - "multiple": "False", - "name": "NET_INCOME", - "type": "text" - }, - { - "description": "description of field", - "multiple": "False", - "name": "GROSS_PROFIT", - "type": "text" - } - ] - }, - "schema_name": { - "_input_type": "MessageTextInput", - "advanced": true, - "display_name": "Schema Name", - "dynamic": false, - "info": "Provide a name for the output data schema.", - "input_types": [ - "Message" - ], - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "schema_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "system_prompt": { - "_input_type": "MultilineInput", - "advanced": true, - "display_name": "Format Instructions", - "dynamic": false, - "info": "The instructions to the language model for formatting the output.", - "input_types": [ - "Message" - ], - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "multiline": true, - "name": "system_prompt", - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "You are an AI system designed to extract structured information from unstructured text.Given the input_text, return a JSON object with predefined keys based on the expected structure.Extract values accurately and format them according to the specified type (e.g., string, integer, float, date).If a value is missing or cannot be determined, return a default (e.g., null, 0, or 'N/A').If multiple instances of the expected structure exist within the input_text, stream each as a separate JSON object." - } - }, - "tool_mode": false - }, - "selected_output": "structured_output_dataframe", - "showNode": true, - "type": "StructuredOutput" - }, - "dragging": false, - "id": "StructuredOutput-uvBkm", - "measured": { - "height": 349, - "width": 320 - }, - "position": { - "x": 1378.7263469848428, - "y": 167.37722508100572 - }, - "selected": false, - "type": "genericNode" - }, - { - "data": { - "id": "parser-YBMuU", + "id": "parser-ZMjjt", "node": { "base_classes": [ "Message" @@ -1488,6 +822,7 @@ "icon": "braces", "key": "parser", "legacy": false, + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "output_types": [], @@ -1622,33 +957,599 @@ }, "tool_mode": false }, - "selected_output": "parsed_text", "showNode": true, "type": "parser" }, "dragging": false, - "id": "parser-YBMuU", + "id": "parser-ZMjjt", "measured": { - "height": 361, + "height": 360, "width": 320 }, "position": { "x": 1765.290752395121, "y": 164.78283431885177 }, + "selected": true, + "type": "genericNode" + }, + { + "data": { + "id": "LanguageModelComponent-jtKdb", + "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, + "lf_version": "1.4.3", + "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": null, + "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\": \"Google\"}],\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": "MessageTextInput", + "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": "OpenAI" + }, + { + "icon": "Anthropic" + }, + { + "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": "MessageTextInput", + "advanced": true, + "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, + "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": "" + }, + "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 + }, + "selected_output": "model_output", + "showNode": true, + "type": "LanguageModelComponent" + }, + "dragging": false, + "id": "LanguageModelComponent-jtKdb", + "measured": { + "height": 450, + "width": 320 + }, + "position": { + "x": 912.2321256553546, + "y": -350.4215686841271 + }, + "selected": false, + "type": "genericNode" + }, + { + "data": { + "id": "StructuredOutput-2t0FB", + "node": { + "base_classes": [ + "Data" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Uses an LLM to generate structured data. Ideal for extraction and consistency.", + "display_name": "Structured Output", + "documentation": "", + "edited": false, + "field_order": [ + "llm", + "input_value", + "system_prompt", + "schema_name", + "output_schema" + ], + "frozen": false, + "icon": "braces", + "legacy": false, + "lf_version": "1.4.3", + "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "allows_loop": false, + "cache": true, + "display_name": "Structured Output", + "group_outputs": false, + "method": "build_structured_output", + "name": "structured_output", + "selected": "Data", + "tool_mode": true, + "types": [ + "Data" + ], + "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 pydantic import BaseModel, Field, create_model\nfrom trustcall import create_extractor\n\nfrom langflow.base.models.chat_result import get_chat_result\nfrom langflow.custom.custom_component.component import Component\nfrom langflow.helpers.base_model import build_model_from_schema\nfrom langflow.io import (\n HandleInput,\n MessageTextInput,\n MultilineInput,\n Output,\n TableInput,\n)\nfrom langflow.schema.data import Data\nfrom langflow.schema.table import EditMode\n\n\nclass StructuredOutputComponent(Component):\n display_name = \"Structured Output\"\n description = \"Uses an LLM to generate structured data. Ideal for extraction and consistency.\"\n name = \"StructuredOutput\"\n icon = \"braces\"\n\n inputs = [\n HandleInput(\n name=\"llm\",\n display_name=\"Language Model\",\n info=\"The language model to use to generate the structured output.\",\n input_types=[\"LanguageModel\"],\n required=True,\n ),\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input Message\",\n info=\"The input message to the language model.\",\n tool_mode=True,\n required=True,\n ),\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"Format Instructions\",\n info=\"The instructions to the language model for formatting the output.\",\n value=(\n \"You are an AI that extracts one structured JSON object from unstructured text. \"\n \"Use a predefined schema with expected types (str, int, float, bool, dict). \"\n \"If multiple structures exist, extract only the first most complete one. \"\n \"Fill missing or ambiguous values with defaults: null for missing values. \"\n \"Ignore duplicates and partial repeats. \"\n \"Always return one valid JSON, never throw errors or return multiple objects.\"\n \"Output: A single well-formed JSON object, and nothing else.\"\n ),\n required=True,\n advanced=True,\n ),\n MessageTextInput(\n name=\"schema_name\",\n display_name=\"Schema Name\",\n info=\"Provide a name for the output data schema.\",\n advanced=True,\n ),\n TableInput(\n name=\"output_schema\",\n display_name=\"Output Schema\",\n info=\"Define the structure and data types for the model's output.\",\n required=True,\n # TODO: remove deault value\n table_schema=[\n {\n \"name\": \"name\",\n \"display_name\": \"Name\",\n \"type\": \"str\",\n \"description\": \"Specify the name of the output field.\",\n \"default\": \"field\",\n \"edit_mode\": EditMode.INLINE,\n },\n {\n \"name\": \"description\",\n \"display_name\": \"Description\",\n \"type\": \"str\",\n \"description\": \"Describe the purpose of the output field.\",\n \"default\": \"description of field\",\n \"edit_mode\": EditMode.POPOVER,\n },\n {\n \"name\": \"type\",\n \"display_name\": \"Type\",\n \"type\": \"str\",\n \"edit_mode\": EditMode.INLINE,\n \"description\": (\"Indicate the data type of the output field (e.g., str, int, float, bool, dict).\"),\n \"options\": [\"str\", \"int\", \"float\", \"bool\", \"dict\"],\n \"default\": \"str\",\n },\n {\n \"name\": \"multiple\",\n \"display_name\": \"As List\",\n \"type\": \"boolean\",\n \"description\": \"Set to True if this output field should be a list of the specified type.\",\n \"default\": \"False\",\n \"edit_mode\": EditMode.INLINE,\n },\n ],\n value=[\n {\n \"name\": \"field\",\n \"description\": \"description of field\",\n \"type\": \"str\",\n \"multiple\": \"False\",\n }\n ],\n ),\n ]\n\n outputs = [\n Output(\n name=\"structured_output\",\n display_name=\"Structured Output\",\n method=\"build_structured_output\",\n ),\n ]\n\n def build_structured_output_base(self):\n schema_name = self.schema_name or \"OutputModel\"\n\n if not hasattr(self.llm, \"with_structured_output\"):\n msg = \"Language model does not support structured output.\"\n raise TypeError(msg)\n if not self.output_schema:\n msg = \"Output schema cannot be empty\"\n raise ValueError(msg)\n\n output_model_ = build_model_from_schema(self.output_schema)\n\n output_model = create_model(\n schema_name,\n __doc__=f\"A list of {schema_name}.\",\n objects=(list[output_model_], Field(description=f\"A list of {schema_name}.\")), # type: ignore[valid-type]\n )\n\n try:\n llm_with_structured_output = create_extractor(self.llm, tools=[output_model])\n except NotImplementedError as exc:\n msg = f\"{self.llm.__class__.__name__} does not support structured output.\"\n raise TypeError(msg) from exc\n\n config_dict = {\n \"run_name\": self.display_name,\n \"project_name\": self.get_project_name(),\n \"callbacks\": self.get_langchain_callbacks(),\n }\n result = get_chat_result(\n runnable=llm_with_structured_output,\n system_message=self.system_prompt,\n input_value=self.input_value,\n config=config_dict,\n )\n\n # OPTIMIZATION NOTE: Simplified processing based on trustcall response structure\n # Handle non-dict responses (shouldn't happen with trustcall, but defensive)\n if not isinstance(result, dict):\n return result\n\n # Extract first response and convert BaseModel to dict\n responses = result.get(\"responses\", [])\n if not responses:\n return result\n\n # Convert BaseModel to dict (creates the \"objects\" key)\n first_response = responses[0]\n structured_data = first_response.model_dump() if isinstance(first_response, BaseModel) else first_response\n\n # Extract the objects array (guaranteed to exist due to our Pydantic model structure)\n return structured_data.get(\"objects\", structured_data)\n\n def build_structured_output(self) -> Data:\n output = self.build_structured_output_base()\n if not isinstance(output, list) or not output:\n # handle empty or unexpected type case\n msg = \"No structured output returned\"\n raise ValueError(msg)\n if len(output) != 1:\n msg = \"Multiple structured outputs returned\"\n raise ValueError(msg)\n return Data(data=output[0])\n" + }, + "input_value": { + "_input_type": "MessageTextInput", + "advanced": false, + "display_name": "Input Message", + "dynamic": false, + "info": "The input message to the language model.", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "tool_mode": true, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "llm": { + "_input_type": "HandleInput", + "advanced": false, + "display_name": "Language Model", + "dynamic": false, + "info": "The language model to use to generate the structured output.", + "input_types": [ + "LanguageModel" + ], + "list": false, + "list_add_label": "Add More", + "name": "llm", + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "other", + "value": "" + }, + "output_schema": { + "_input_type": "TableInput", + "advanced": false, + "display_name": "Output Schema", + "dynamic": false, + "info": "Define the structure and data types for the model's output.", + "is_list": true, + "list_add_label": "Add More", + "name": "output_schema", + "placeholder": "", + "required": true, + "show": true, + "table_icon": "Table", + "table_schema": { + "columns": [ + { + "default": "field", + "description": "Specify the name of the output field.", + "disable_edit": false, + "display_name": "Name", + "edit_mode": "inline", + "filterable": true, + "formatter": "text", + "hidden": false, + "name": "name", + "sortable": true, + "type": "str" + }, + { + "default": "description of field", + "description": "Describe the purpose of the output field.", + "disable_edit": false, + "display_name": "Description", + "edit_mode": "popover", + "filterable": true, + "formatter": "text", + "hidden": false, + "name": "description", + "sortable": true, + "type": "str" + }, + { + "default": "str", + "description": "Indicate the data type of the output field (e.g., str, int, float, bool, dict).", + "disable_edit": false, + "display_name": "Type", + "edit_mode": "inline", + "filterable": true, + "formatter": "text", + "hidden": false, + "name": "type", + "options": [ + "str", + "int", + "float", + "bool", + "dict" + ], + "sortable": true, + "type": "str" + }, + { + "default": false, + "description": "Set to True if this output field should be a list of the specified type.", + "disable_edit": false, + "display_name": "As List", + "edit_mode": "inline", + "filterable": true, + "formatter": "boolean", + "hidden": false, + "name": "multiple", + "sortable": true, + "type": "boolean" + } + ] + }, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "trigger_icon": "Table", + "trigger_text": "Open table", + "type": "table", + "value": [ + { + "description": "description of field", + "multiple": "False", + "name": "EBITDA", + "type": "str" + }, + { + "description": "description of field", + "multiple": false, + "name": "NET_INCOME", + "type": "str" + }, + { + "description": "description of field", + "multiple": false, + "name": "GROSS_PROFIT", + "type": "str" + } + ] + }, + "schema_name": { + "_input_type": "MessageTextInput", + "advanced": true, + "display_name": "Schema Name", + "dynamic": false, + "info": "Provide a name for the output data schema.", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "schema_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "system_prompt": { + "_input_type": "MultilineInput", + "advanced": true, + "copy_field": false, + "display_name": "Format Instructions", + "dynamic": false, + "info": "The instructions to the language model for formatting the output.", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "multiline": true, + "name": "system_prompt", + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "You are an AI system designed to extract structured information from unstructured text.Given the input_text, return a JSON object with predefined keys based on the expected structure.Extract values accurately and format them according to the specified type (e.g., string, integer, float, date).If a value is missing or cannot be determined, return a default (e.g., null, 0, or 'N/A').If multiple instances of the expected structure exist within the input_text, stream each as a separate JSON object." + } + }, + "tool_mode": false + }, + "selected_output": "parsed_text", + "showNode": true, + "type": "StructuredOutput" + }, + "dragging": false, + "id": "StructuredOutput-2t0FB", + "measured": { + "height": 348, + "width": 320 + }, + "position": { + "x": 1365.3538332076944, + "y": 156.68214734917737 + }, "selected": false, "type": "genericNode" } ], "viewport": { - "x": -275.9882952608343, - "y": 250.87377864647806, - "zoom": 0.5793112052990664 + "x": -287.9400172575938, + "y": 302.4551039081521, + "zoom": 0.6307952275474222 } }, "description": "Extracts key financial metrics like Gross Profit, EBITDA, and Net Income from financial reports and structures them for easy analysis, using Structured Output Component", "endpoint_name": null, - "id": "8e7bfce3-68ab-4bb9-ab2a-590c71e4456a", + "id": "f63a6251-214d-4f5f-8b20-20e354463908", "is_component": false, "last_tested_version": "1.4.3", "name": "Financial Report Parser", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json b/src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json index c43a639f8..ed7423726 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json @@ -1,209 +1,13 @@ { "data": { "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-GHbvP", - "name": "model_output", - "output_types": [ - "LanguageModel" - ] - }, - "targetHandle": { - "fieldName": "llm", - "id": "StructuredOutput-hj1IZ", - "inputTypes": [ - "LanguageModel" - ], - "type": "other" - } - }, - "id": "reactflow__edge-OpenAIModel-GHbvP{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-GHbvPœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}-StructuredOutput-hj1IZ{œfieldNameœ:œllmœ,œidœ:œStructuredOutput-hj1IZœ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}", - "selected": false, - "source": "OpenAIModel-GHbvP", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-GHbvPœ, œnameœ: œmodel_outputœ, œoutput_typesœ: [œLanguageModelœ]}", - "target": "StructuredOutput-hj1IZ", - "targetHandle": "{œfieldNameœ: œllmœ, œidœ: œStructuredOutput-hj1IZœ, œinputTypesœ: [œLanguageModelœ], œtypeœ: œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-MsFJG", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "search_query", - "id": "AstraDB-zZztw", - "inputTypes": [ - "Message" - ], - "type": "query" - } - }, - "id": "reactflow__edge-ChatInput-MsFJG{œdataTypeœ:œChatInputœ,œidœ:œChatInput-MsFJGœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-AstraDB-zZztw{œfieldNameœ:œsearch_queryœ,œidœ:œAstraDB-zZztwœ,œinputTypesœ:[œMessageœ],œtypeœ:œqueryœ}", - "selected": false, - "source": "ChatInput-MsFJG", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-MsFJGœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "AstraDB-zZztw", - "targetHandle": "{œfieldNameœ: œsearch_queryœ, œidœ: œAstraDB-zZztwœ, œinputTypesœ: [œMessageœ], œtypeœ: œqueryœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-GHbvP", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "StructuredOutput-hj1IZ", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-GHbvP{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-GHbvPœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-StructuredOutput-hj1IZ{œfieldNameœ:œinput_valueœ,œidœ:œStructuredOutput-hj1IZœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "OpenAIModel-GHbvP", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-GHbvPœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "StructuredOutput-hj1IZ", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œStructuredOutput-hj1IZœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "StructuredOutput", - "id": "StructuredOutput-hj1IZ", - "name": "structured_output_dataframe", - "output_types": [] - }, - "targetHandle": { - "fieldName": "input_data", - "id": "ParserComponent-9FGat", - "inputTypes": [ - "DataFrame", - "Data" - ], - "type": "other" - } - }, - "id": "reactflow__edge-StructuredOutput-hj1IZ{œdataTypeœ:œStructuredOutputœ,œidœ:œStructuredOutput-hj1IZœ,œnameœ:œstructured_output_dataframeœ,œoutput_typesœ:[œDataFrameœ]}-ParserComponent-9FGat{œfieldNameœ:œinput_dataœ,œidœ:œParserComponent-9FGatœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", - "selected": false, - "source": "StructuredOutput-hj1IZ", - "sourceHandle": "{œdataTypeœ: œStructuredOutputœ, œidœ: œStructuredOutput-hj1IZœ, œnameœ: œstructured_output_dataframeœ, œoutput_typesœ: []}", - "target": "ParserComponent-9FGat", - "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œParserComponent-9FGatœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" - }, { "animated": false, "className": "", "data": { "sourceHandle": { "dataType": "ParserComponent", - "id": "ParserComponent-9FGat", - "name": "parsed_text", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "lexical_terms", - "id": "AstraDB-zZztw", - "inputTypes": [ - "Message" - ], - "type": "query" - } - }, - "id": "reactflow__edge-ParserComponent-9FGat{œdataTypeœ:œParserComponentœ,œidœ:œParserComponent-9FGatœ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-AstraDB-zZztw{œfieldNameœ:œlexical_termsœ,œidœ:œAstraDB-zZztwœ,œinputTypesœ:[œMessageœ],œtypeœ:œqueryœ}", - "selected": false, - "source": "ParserComponent-9FGat", - "sourceHandle": "{œdataTypeœ: œParserComponentœ, œidœ: œParserComponent-9FGatœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", - "target": "AstraDB-zZztw", - "targetHandle": "{œfieldNameœ: œlexical_termsœ, œidœ: œAstraDB-zZztwœ, œinputTypesœ: [œMessageœ], œtypeœ: œqueryœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-MsFJG", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-GHbvP", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-MsFJG{œdataTypeœ:œChatInputœ,œidœ:œChatInput-MsFJGœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-GHbvP{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-GHbvPœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ChatInput-MsFJG", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-MsFJGœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-GHbvP", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-GHbvPœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "AstraDB", - "id": "AstraDB-zZztw", - "name": "dataframe", - "output_types": [ - "DataFrame" - ] - }, - "targetHandle": { - "fieldName": "input_data", - "id": "ParserComponent-AzBHA", - "inputTypes": [ - "DataFrame", - "Data" - ], - "type": "other" - } - }, - "id": "xy-edge__AstraDB-zZztw{œdataTypeœ:œAstraDBœ,œidœ:œAstraDB-zZztwœ,œnameœ:œdataframeœ,œoutput_typesœ:[œDataFrameœ]}-ParserComponent-AzBHA{œfieldNameœ:œinput_dataœ,œidœ:œParserComponent-AzBHAœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", - "selected": false, - "source": "AstraDB-zZztw", - "sourceHandle": "{œdataTypeœ: œAstraDBœ, œidœ: œAstraDB-zZztwœ, œnameœ: œdataframeœ, œoutput_typesœ: [œDataFrameœ]}", - "target": "ParserComponent-AzBHA", - "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œParserComponent-AzBHAœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ParserComponent", - "id": "ParserComponent-AzBHA", + "id": "ParserComponent-3Xb72", "name": "parsed_text", "output_types": [ "Message" @@ -211,7 +15,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-qOr04", + "id": "ChatOutput-HL6J1", "inputTypes": [ "Data", "DataFrame", @@ -220,18 +24,160 @@ "type": "other" } }, - "id": "xy-edge__ParserComponent-AzBHA{œdataTypeœ:œParserComponentœ,œidœ:œParserComponent-AzBHAœ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-qOr04{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-qOr04œ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-ParserComponent-3Xb72{œdataTypeœ:œParserComponentœ,œidœ:œParserComponent-3Xb72œ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-HL6J1{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-HL6J1œ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}", "selected": false, - "source": "ParserComponent-AzBHA", - "sourceHandle": "{œdataTypeœ: œParserComponentœ, œidœ: œParserComponent-AzBHAœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-qOr04", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-qOr04œ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}" + "source": "ParserComponent-3Xb72", + "sourceHandle": "{œdataTypeœ: œParserComponentœ, œidœ: œParserComponent-3Xb72œ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-HL6J1", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-HL6J1œ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-nObH7", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "search_query", + "id": "AstraDB-8MbYw", + "inputTypes": [ + "Message" + ], + "type": "query" + } + }, + "id": "reactflow__edge-ChatInput-nObH7{œdataTypeœ:œChatInputœ,œidœ:œChatInput-nObH7œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-AstraDB-8MbYw{œfieldNameœ:œsearch_queryœ,œidœ:œAstraDB-8MbYwœ,œinputTypesœ:[œMessageœ],œtypeœ:œqueryœ}", + "selected": false, + "source": "ChatInput-nObH7", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-nObH7œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "AstraDB-8MbYw", + "targetHandle": "{œfieldNameœ: œsearch_queryœ, œidœ: œAstraDB-8MbYwœ, œinputTypesœ: [œMessageœ], œtypeœ: œqueryœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "AstraDB", + "id": "AstraDB-8MbYw", + "name": "dataframe", + "output_types": [ + "DataFrame" + ] + }, + "targetHandle": { + "fieldName": "input_data", + "id": "ParserComponent-3Xb72", + "inputTypes": [ + "DataFrame", + "Data" + ], + "type": "other" + } + }, + "id": "reactflow__edge-AstraDB-8MbYw{œdataTypeœ:œAstraDBœ,œidœ:œAstraDB-8MbYwœ,œnameœ:œdataframeœ,œoutput_typesœ:[œDataFrameœ]}-ParserComponent-3Xb72{œfieldNameœ:œinput_dataœ,œidœ:œParserComponent-3Xb72œ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", + "selected": false, + "source": "AstraDB-8MbYw", + "sourceHandle": "{œdataTypeœ: œAstraDBœ, œidœ: œAstraDB-8MbYwœ, œnameœ: œdataframeœ, œoutput_typesœ: [œDataFrameœ]}", + "target": "ParserComponent-3Xb72", + "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œParserComponent-3Xb72œ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "LanguageModelComponent", + "id": "LanguageModelComponent-CXvuM", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "StructuredOutput-38AOi", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "xy-edge__LanguageModelComponent-CXvuM{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-CXvuMœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-StructuredOutput-38AOi{œfieldNameœ:œinput_valueœ,œidœ:œStructuredOutput-38AOiœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "LanguageModelComponent-CXvuM", + "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-CXvuMœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "StructuredOutput-38AOi", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œStructuredOutput-38AOiœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "StructuredOutput", + "id": "StructuredOutput-38AOi", + "name": "structured_output", + "output_types": [ + "Data" + ] + }, + "targetHandle": { + "fieldName": "input_data", + "id": "ParserComponent-MDCBV", + "inputTypes": [ + "DataFrame", + "Data" + ], + "type": "other" + } + }, + "id": "xy-edge__StructuredOutput-38AOi{œdataTypeœ:œStructuredOutputœ,œidœ:œStructuredOutput-38AOiœ,œnameœ:œstructured_outputœ,œoutput_typesœ:[œDataœ]}-ParserComponent-MDCBV{œfieldNameœ:œinput_dataœ,œidœ:œParserComponent-MDCBVœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", + "selected": false, + "source": "StructuredOutput-38AOi", + "sourceHandle": "{œdataTypeœ: œStructuredOutputœ, œidœ: œStructuredOutput-38AOiœ, œnameœ: œstructured_outputœ, œoutput_typesœ: [œDataœ]}", + "target": "ParserComponent-MDCBV", + "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œParserComponent-MDCBVœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "LanguageModelComponent", + "id": "LanguageModelComponent-3anZE", + "name": "model_output", + "output_types": [ + "LanguageModel" + ] + }, + "targetHandle": { + "fieldName": "llm", + "id": "StructuredOutput-38AOi", + "inputTypes": [ + "LanguageModel" + ], + "type": "other" + } + }, + "id": "xy-edge__LanguageModelComponent-3anZE{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-3anZEœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}-StructuredOutput-38AOi{œfieldNameœ:œllmœ,œidœ:œStructuredOutput-38AOiœ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}", + "selected": false, + "source": "LanguageModelComponent-3anZE", + "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-3anZEœ, œnameœ: œmodel_outputœ, œoutput_typesœ: [œLanguageModelœ]}", + "target": "StructuredOutput-38AOi", + "targetHandle": "{œfieldNameœ: œllmœ, œidœ: œStructuredOutput-38AOiœ, œinputTypesœ: [œLanguageModelœ], œtypeœ: œotherœ}" } ], "nodes": [ { "data": { - "id": "ChatInput-MsFJG", + "id": "ChatInput-nObH7", "node": { "base_classes": [ "Message" @@ -257,7 +203,7 @@ "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.3.2", + "lf_version": "1.4.3", "metadata": {}, "minimized": true, "output_types": [], @@ -529,9 +475,9 @@ "type": "ChatInput" }, "dragging": false, - "id": "ChatInput-MsFJG", + "id": "ChatInput-nObH7", "measured": { - "height": 66, + "height": 48, "width": 192 }, "position": { @@ -543,1458 +489,7 @@ }, { "data": { - "id": "StructuredOutput-hj1IZ", - "node": { - "base_classes": [ - "Data", - "DataFrame" - ], - "beta": false, - "category": "helpers", - "conditional_paths": [], - "custom_fields": {}, - "description": "Uses an LLM to generate structured data. Ideal for extraction and consistency.", - "display_name": "Structured Output", - "documentation": "", - "edited": false, - "field_order": [ - "llm", - "input_value", - "system_prompt", - "schema_name", - "output_schema", - "multiple" - ], - "frozen": false, - "icon": "braces", - "key": "StructuredOutput", - "legacy": false, - "lf_version": "1.3.2", - "metadata": {}, - "minimized": false, - "output_types": [], - "outputs": [ - { - "allows_loop": false, - "cache": true, - "display_name": "Structured Output", - "group_outputs": false, - "method": "build_structured_output", - "name": "structured_output", - "selected": "Data", - "tool_mode": true, - "types": [ - "Data" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "score": 0.007568328950209746, - "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 pydantic import BaseModel, Field, create_model\nfrom trustcall import create_extractor\n\nfrom langflow.base.models.chat_result import get_chat_result\nfrom langflow.custom.custom_component.component import Component\nfrom langflow.helpers.base_model import build_model_from_schema\nfrom langflow.io import (\n HandleInput,\n MessageTextInput,\n MultilineInput,\n Output,\n TableInput,\n)\nfrom langflow.schema.data import Data\nfrom langflow.schema.table import EditMode\n\n\nclass StructuredOutputComponent(Component):\n display_name = \"Structured Output\"\n description = \"Uses an LLM to generate structured data. Ideal for extraction and consistency.\"\n name = \"StructuredOutput\"\n icon = \"braces\"\n\n inputs = [\n HandleInput(\n name=\"llm\",\n display_name=\"Language Model\",\n info=\"The language model to use to generate the structured output.\",\n input_types=[\"LanguageModel\"],\n required=True,\n ),\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input Message\",\n info=\"The input message to the language model.\",\n tool_mode=True,\n required=True,\n ),\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"Format Instructions\",\n info=\"The instructions to the language model for formatting the output.\",\n value=(\n \"You are an AI that extracts one structured JSON object from unstructured text. \"\n \"Use a predefined schema with expected types (str, int, float, bool, dict). \"\n \"If multiple structures exist, extract only the first most complete one. \"\n \"Fill missing or ambiguous values with defaults: null for missing values. \"\n \"Ignore duplicates and partial repeats. \"\n \"Always return one valid JSON, never throw errors or return multiple objects.\"\n \"Output: A single well-formed JSON object, and nothing else.\"\n ),\n required=True,\n advanced=True,\n ),\n MessageTextInput(\n name=\"schema_name\",\n display_name=\"Schema Name\",\n info=\"Provide a name for the output data schema.\",\n advanced=True,\n ),\n TableInput(\n name=\"output_schema\",\n display_name=\"Output Schema\",\n info=\"Define the structure and data types for the model's output.\",\n required=True,\n # TODO: remove deault value\n table_schema=[\n {\n \"name\": \"name\",\n \"display_name\": \"Name\",\n \"type\": \"str\",\n \"description\": \"Specify the name of the output field.\",\n \"default\": \"field\",\n \"edit_mode\": EditMode.INLINE,\n },\n {\n \"name\": \"description\",\n \"display_name\": \"Description\",\n \"type\": \"str\",\n \"description\": \"Describe the purpose of the output field.\",\n \"default\": \"description of field\",\n \"edit_mode\": EditMode.POPOVER,\n },\n {\n \"name\": \"type\",\n \"display_name\": \"Type\",\n \"type\": \"str\",\n \"edit_mode\": EditMode.INLINE,\n \"description\": (\"Indicate the data type of the output field (e.g., str, int, float, bool, dict).\"),\n \"options\": [\"str\", \"int\", \"float\", \"bool\", \"dict\"],\n \"default\": \"str\",\n },\n {\n \"name\": \"multiple\",\n \"display_name\": \"As List\",\n \"type\": \"boolean\",\n \"description\": \"Set to True if this output field should be a list of the specified type.\",\n \"default\": \"False\",\n \"edit_mode\": EditMode.INLINE,\n },\n ],\n value=[\n {\n \"name\": \"field\",\n \"description\": \"description of field\",\n \"type\": \"str\",\n \"multiple\": \"False\",\n }\n ],\n ),\n ]\n\n outputs = [\n Output(\n name=\"structured_output\",\n display_name=\"Structured Output\",\n method=\"build_structured_output\",\n ),\n ]\n\n def build_structured_output_base(self):\n schema_name = self.schema_name or \"OutputModel\"\n\n if not hasattr(self.llm, \"with_structured_output\"):\n msg = \"Language model does not support structured output.\"\n raise TypeError(msg)\n if not self.output_schema:\n msg = \"Output schema cannot be empty\"\n raise ValueError(msg)\n\n output_model_ = build_model_from_schema(self.output_schema)\n\n output_model = create_model(\n schema_name,\n __doc__=f\"A list of {schema_name}.\",\n objects=(list[output_model_], Field(description=f\"A list of {schema_name}.\")), # type: ignore[valid-type]\n )\n\n try:\n llm_with_structured_output = create_extractor(self.llm, tools=[output_model])\n except NotImplementedError as exc:\n msg = f\"{self.llm.__class__.__name__} does not support structured output.\"\n raise TypeError(msg) from exc\n\n config_dict = {\n \"run_name\": self.display_name,\n \"project_name\": self.get_project_name(),\n \"callbacks\": self.get_langchain_callbacks(),\n }\n result = get_chat_result(\n runnable=llm_with_structured_output,\n system_message=self.system_prompt,\n input_value=self.input_value,\n config=config_dict,\n )\n\n # OPTIMIZATION NOTE: Simplified processing based on trustcall response structure\n # Handle non-dict responses (shouldn't happen with trustcall, but defensive)\n if not isinstance(result, dict):\n return result\n\n # Extract first response and convert BaseModel to dict\n responses = result.get(\"responses\", [])\n if not responses:\n return result\n\n # Convert BaseModel to dict (creates the \"objects\" key)\n first_response = responses[0]\n structured_data = first_response.model_dump() if isinstance(first_response, BaseModel) else first_response\n\n # Extract the objects array (guaranteed to exist due to our Pydantic model structure)\n return structured_data.get(\"objects\", structured_data)\n\n def build_structured_output(self) -> Data:\n output = self.build_structured_output_base()\n if not isinstance(output, list) or not output:\n # handle empty or unexpected type case\n msg = \"No structured output returned\"\n raise ValueError(msg)\n if len(output) != 1:\n msg = \"Multiple structured outputs returned\"\n raise ValueError(msg)\n return Data(data=output[0])\n" - }, - "input_value": { - "_input_type": "MessageTextInput", - "advanced": false, - "display_name": "Input Message", - "dynamic": false, - "info": "The input message to the language model.", - "input_types": [ - "Message" - ], - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "input_value", - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "tool_mode": true, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "llm": { - "_input_type": "HandleInput", - "advanced": false, - "display_name": "Language Model", - "dynamic": false, - "info": "The language model to use to generate the structured output.", - "input_types": [ - "LanguageModel" - ], - "list": false, - "list_add_label": "Add More", - "name": "llm", - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "other", - "value": "" - }, - "output_schema": { - "_input_type": "TableInput", - "advanced": false, - "display_name": "Output Schema", - "dynamic": false, - "info": "Define the structure and data types for the model's output.", - "is_list": true, - "list_add_label": "Add More", - "name": "output_schema", - "placeholder": "", - "required": true, - "show": true, - "table_icon": "Table", - "table_schema": { - "columns": [ - { - "default": "field", - "description": "Specify the name of the output field.", - "disable_edit": false, - "display_name": "Name", - "edit_mode": "inline", - "filterable": true, - "formatter": "text", - "hidden": false, - "name": "name", - "sortable": true, - "type": "str" - }, - { - "default": "description of field", - "description": "Describe the purpose of the output field.", - "disable_edit": false, - "display_name": "Description", - "edit_mode": "popover", - "filterable": true, - "formatter": "text", - "hidden": false, - "name": "description", - "sortable": true, - "type": "str" - }, - { - "default": "str", - "description": "Indicate the data type of the output field (e.g., str, int, float, bool, list, dict).", - "disable_edit": false, - "display_name": "Type", - "edit_mode": "inline", - "filterable": true, - "formatter": "text", - "hidden": false, - "name": "type", - "options": [ - "str", - "int", - "float", - "bool", - "list", - "dict" - ], - "sortable": true, - "type": "str" - }, - { - "default": false, - "description": "Set to True if this output field should be a list of the specified type.", - "disable_edit": false, - "display_name": "Multiple", - "edit_mode": "inline", - "filterable": true, - "formatter": "boolean", - "hidden": false, - "name": "multiple", - "sortable": true, - "type": "boolean" - } - ] - }, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "trigger_icon": "Table", - "trigger_text": "Open table", - "type": "table", - "value": [ - { - "description": "The keywords associated with the question the user wants to answer", - "multiple": false, - "name": "keywords", - "type": "str" - }, - { - "description": "The question the user has asked", - "multiple": false, - "name": "question", - "type": "str" - } - ] - }, - "schema_name": { - "_input_type": "MessageTextInput", - "advanced": true, - "display_name": "Schema Name", - "dynamic": false, - "info": "Provide a name for the output data schema.", - "input_types": [ - "Message" - ], - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "schema_name", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "system_prompt": { - "_input_type": "MultilineInput", - "advanced": true, - "copy_field": false, - "display_name": "Format Instructions", - "dynamic": false, - "info": "The instructions to the language model for formatting the output.", - "input_types": [ - "Message" - ], - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "multiline": true, - "name": "system_prompt", - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "You are an AI system designed to extract structured information from unstructured text.Given the input_text, return a JSON object with predefined keys based on the expected structure.Extract values accurately and format them according to the specified type (e.g., string, integer, float, date).If a value is missing or cannot be determined, return a default (e.g., null, 0, or 'N/A').If multiple instances of the expected structure exist within the input_text, stream each as a separate JSON object." - } - }, - "tool_mode": false - }, - "selected_output": "structured_output_dataframe", - "showNode": true, - "type": "StructuredOutput" - }, - "dragging": false, - "id": "StructuredOutput-hj1IZ", - "measured": { - "height": 447, - "width": 320 - }, - "position": { - "x": 733.8781789848654, - "y": 385.5224237870112 - }, - "selected": false, - "type": "genericNode" - }, - { - "data": { - "id": "OpenAIModel-GHbvP", - "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], - "beta": false, - "category": "models", - "conditional_paths": [], - "custom_fields": {}, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "edited": false, - "field_order": [ - "input_value", - "system_message", - "stream", - "max_tokens", - "model_kwargs", - "json_mode", - "model_name", - "openai_api_base", - "api_key", - "temperature", - "seed", - "max_retries", - "timeout" - ], - "frozen": false, - "icon": "OpenAI", - "key": "OpenAIModel", - "legacy": false, - "lf_version": "1.3.2", - "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, - "score": 0.001, - "template": { - "_type": "Component", - "api_key": { - "_input_type": "SecretStrInput", - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [], - "load_from_db": true, - "name": "api_key", - "password": true, - "placeholder": "", - "required": true, - "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_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import (\n OPENAI_MODEL_NAMES,\n OPENAI_REASONING_MODEL_NAMES,\n)\nfrom langflow.field_typing import LanguageModel\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.inputs.inputs import BoolInput, DictInput, DropdownInput, IntInput, SecretStrInput, SliderInput, StrInput\nfrom langflow.logging import logger\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n name = \"OpenAIModel\"\n\n inputs = [\n *LCModelComponent._base_inputs,\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n range_spec=RangeSpec(min=0, max=128000),\n ),\n DictInput(\n name=\"model_kwargs\",\n display_name=\"Model Kwargs\",\n advanced=True,\n info=\"Additional keyword arguments to pass to the model.\",\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n advanced=False,\n options=OPENAI_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[1],\n combobox=True,\n real_time_refresh=True,\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. \"\n \"Defaults to https://api.openai.com/v1. \"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n required=True,\n ),\n SliderInput(\n name=\"temperature\",\n display_name=\"Temperature\",\n value=0.1,\n range_spec=RangeSpec(min=0, max=1, step=0.01),\n show=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n IntInput(\n name=\"max_retries\",\n display_name=\"Max Retries\",\n info=\"The maximum number of retries to make when generating.\",\n advanced=True,\n value=5,\n ),\n IntInput(\n name=\"timeout\",\n display_name=\"Timeout\",\n info=\"The timeout for requests to OpenAI completion API.\",\n advanced=True,\n value=700,\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n parameters = {\n \"api_key\": SecretStr(self.api_key).get_secret_value() if self.api_key else None,\n \"model_name\": self.model_name,\n \"max_tokens\": self.max_tokens or None,\n \"model_kwargs\": self.model_kwargs or {},\n \"base_url\": self.openai_api_base or \"https://api.openai.com/v1\",\n \"seed\": self.seed,\n \"max_retries\": self.max_retries,\n \"timeout\": self.timeout,\n \"temperature\": self.temperature if self.temperature is not None else 0.1,\n }\n\n logger.info(f\"Model name: {self.model_name}\")\n if self.model_name in OPENAI_REASONING_MODEL_NAMES:\n logger.info(\"Getting reasoning model parameters\")\n parameters.pop(\"temperature\")\n parameters.pop(\"seed\")\n output = ChatOpenAI(**parameters)\n if self.json_mode:\n output = output.bind(response_format={\"type\": \"json_object\"})\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"Get a message from an OpenAI exception.\n\n Args:\n e (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n try:\n from openai import BadRequestError\n except ImportError:\n return None\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\")\n if message:\n return message\n return None\n\n def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None) -> dict:\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_REASONING_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = False\n build_config[\"seed\"][\"show\"] = False\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = True\n build_config[\"seed\"][\"show\"] = True\n return build_config\n" - }, - "input_value": { - "_input_type": "MessageInput", - "advanced": false, - "display_name": "Input", - "dynamic": false, - "info": "", - "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": "" - }, - "json_mode": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "JSON Mode", - "dynamic": false, - "info": "If True, it will output JSON regardless of passing a schema.", - "list": false, - "list_add_label": "Add More", - "name": "json_mode", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "max_retries": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Retries", - "dynamic": false, - "info": "The maximum number of retries to make when generating.", - "list": false, - "list_add_label": "Add More", - "name": "max_retries", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 5 - }, - "max_tokens": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "list_add_label": "Add More", - "name": "max_tokens", - "placeholder": "", - "range_spec": { - "max": 128000, - "min": 0, - "step": 0.1, - "step_type": "float" - }, - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "model_kwargs": { - "_input_type": "DictInput", - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "Additional keyword arguments to pass to the model.", - "list": false, - "list_add_label": "Add More", - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, - "model_name": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": true, - "dialog_inputs": {}, - "display_name": "Model Name", - "dynamic": false, - "info": "", - "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", - "o1" - ], - "options_metadata": [], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "gpt-4.1-mini" - }, - "openai_api_base": { - "_input_type": "StrInput", - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "openai_api_base", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "seed": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Seed", - "dynamic": false, - "info": "The seed controls the reproducibility of the job.", - "list": false, - "list_add_label": "Add More", - "name": "seed", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 1 - }, - "stream": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", - "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": "System message to pass to the model.", - "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": "You are a database query planner that takes a user request, and converts to a search against the subject matter in question.\nYou should convert the query into:\n1. A list of keywords to use against a Lucene text analyzer index, no more than 4. Strictly unigrams.\n2. A question to use as the basis for a QA embedding engine\nAvoid common keywords associated with the user's subject matter." - }, - "temperature": { - "_input_type": "SliderInput", - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "info": "", - "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 - }, - "timeout": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Timeout", - "dynamic": false, - "info": "The timeout for requests to OpenAI completion API.", - "list": false, - "list_add_label": "Add More", - "name": "timeout", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 700 - } - }, - "tool_mode": false - }, - "selected_output": "text_output", - "showNode": true, - "type": "OpenAIModel" - }, - "dragging": false, - "id": "OpenAIModel-GHbvP", - "measured": { - "height": 525, - "width": 320 - }, - "position": { - "x": 304.51139592185973, - "y": 394.2308341314179 - }, - "selected": false, - "type": "genericNode" - }, - { - "data": { - "id": "AstraDB-zZztw", - "node": { - "base_classes": [ - "Data", - "DataFrame", - "VectorStore" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Ingest and search documents in Astra DB", - "display_name": "Astra DB", - "documentation": "https://docs.datastax.com/en/langflow/astra-components.html", - "edited": false, - "field_order": [ - "token", - "environment", - "database_name", - "api_endpoint", - "keyspace", - "collection_name", - "embedding_model", - "ingest_data", - "search_query", - "should_cache_vector_store", - "search_method", - "reranker", - "lexical_terms", - "number_of_results", - "search_type", - "search_score_threshold", - "advanced_search_filter", - "autodetect_collection", - "content_field", - "deletion_field", - "ignore_invalid_documents", - "astradb_vectorstore_kwargs" - ], - "frozen": false, - "icon": "AstraDB", - "legacy": false, - "lf_version": "1.3.2", - "metadata": {}, - "minimized": false, - "output_types": [], - "outputs": [ - { - "allows_loop": false, - "cache": true, - "display_name": "Search Results", - "group_outputs": false, - "method": "search_documents", - "name": "search_results", - "selected": "Data", - "tool_mode": true, - "types": [ - "Data" - ], - "value": "__UNDEFINED__" - }, - { - "allows_loop": false, - "cache": true, - "display_name": "DataFrame", - "group_outputs": false, - "method": "as_dataframe", - "name": "dataframe", - "selected": "DataFrame", - "tool_mode": true, - "types": [ - "DataFrame" - ], - "value": "__UNDEFINED__" - }, - { - "allows_loop": false, - "cache": true, - "display_name": "Vector Store Connection", - "group_outputs": false, - "hidden": true, - "method": "as_vector_store", - "name": "vectorstoreconnection", - "selected": "VectorStore", - "tool_mode": true, - "types": [ - "VectorStore" - ], - "value": "__UNDEFINED__" - } - ], - "pinned": false, - "template": { - "_type": "Component", - "advanced_search_filter": { - "_input_type": "NestedDictInput", - "advanced": true, - "display_name": "Search Metadata Filter", - "dynamic": false, - "info": "Optional dictionary of filters to apply to the search query.", - "list": false, - "list_add_label": "Add More", - "name": "advanced_search_filter", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "NestedDict", - "value": {} - }, - "api_endpoint": { - "_input_type": "StrInput", - "advanced": false, - "display_name": "Astra DB API Endpoint", - "dynamic": false, - "info": "The API Endpoint for the Astra DB instance. Supercedes database selection.", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "api_endpoint", - "placeholder": "", - "required": false, - "show": false, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "https://38c3f4b9-fc82-42f6-a1b7-058be7fa8497-us-central1.apps.astra-dev.datastax.com" - }, - "astradb_vectorstore_kwargs": { - "_input_type": "NestedDictInput", - "advanced": true, - "display_name": "AstraDBVectorStore Parameters", - "dynamic": false, - "info": "Optional dictionary of additional parameters for the AstraDBVectorStore.", - "list": false, - "list_add_label": "Add More", - "name": "astradb_vectorstore_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "NestedDict", - "value": {} - }, - "autodetect_collection": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "Autodetect Collection", - "dynamic": false, - "info": "Boolean flag to determine whether to autodetect the collection.", - "list": false, - "list_add_label": "Add More", - "name": "autodetect_collection", - "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": "import re\nfrom collections import defaultdict\nfrom dataclasses import asdict, dataclass, field\n\nfrom astrapy import DataAPIClient, Database\nfrom astrapy.data.info.reranking import RerankServiceOptions\nfrom astrapy.info import CollectionDescriptor, CollectionLexicalOptions, CollectionRerankOptions\nfrom langchain_astradb import AstraDBVectorStore, VectorServiceOptions\nfrom langchain_astradb.utils.astradb import HybridSearchMode, _AstraDBCollectionEnvironment\n\nfrom langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store\nfrom langflow.base.vectorstores.vector_store_connection_decorator import vector_store_connection\nfrom langflow.helpers.data import docs_to_data\nfrom langflow.inputs.inputs import FloatInput, NestedDictInput\nfrom langflow.io import (\n BoolInput,\n DropdownInput,\n HandleInput,\n IntInput,\n QueryInput,\n SecretStrInput,\n StrInput,\n)\nfrom langflow.schema.data import Data\nfrom langflow.utils.version import get_version_info\n\n\n@vector_store_connection\nclass AstraDBVectorStoreComponent(LCVectorStoreComponent):\n display_name: str = \"Astra DB\"\n description: str = \"Ingest and search documents in Astra DB\"\n documentation: str = \"https://docs.datastax.com/en/langflow/astra-components.html\"\n name = \"AstraDB\"\n icon: str = \"AstraDB\"\n\n _cached_vector_store: AstraDBVectorStore | None = None\n\n @dataclass\n class NewDatabaseInput:\n functionality: str = \"create\"\n fields: dict[str, dict] = field(\n default_factory=lambda: {\n \"data\": {\n \"node\": {\n \"name\": \"create_database\",\n \"description\": \"Please allow several minutes for creation to complete.\",\n \"display_name\": \"Create new database\",\n \"field_order\": [\"01_new_database_name\", \"02_cloud_provider\", \"03_region\"],\n \"template\": {\n \"01_new_database_name\": StrInput(\n name=\"new_database_name\",\n display_name=\"Name\",\n info=\"Name of the new database to create in Astra DB.\",\n required=True,\n ),\n \"02_cloud_provider\": DropdownInput(\n name=\"cloud_provider\",\n display_name=\"Cloud provider\",\n info=\"Cloud provider for the new database.\",\n options=[],\n required=True,\n real_time_refresh=True,\n ),\n \"03_region\": DropdownInput(\n name=\"region\",\n display_name=\"Region\",\n info=\"Region for the new database.\",\n options=[],\n required=True,\n ),\n },\n },\n }\n }\n )\n\n @dataclass\n class NewCollectionInput:\n functionality: str = \"create\"\n fields: dict[str, dict] = field(\n default_factory=lambda: {\n \"data\": {\n \"node\": {\n \"name\": \"create_collection\",\n \"description\": \"Please allow several seconds for creation to complete.\",\n \"display_name\": \"Create new collection\",\n \"field_order\": [\n \"01_new_collection_name\",\n \"02_embedding_generation_provider\",\n \"03_embedding_generation_model\",\n \"04_dimension\",\n ],\n \"template\": {\n \"01_new_collection_name\": StrInput(\n name=\"new_collection_name\",\n display_name=\"Name\",\n info=\"Name of the new collection to create in Astra DB.\",\n required=True,\n ),\n \"02_embedding_generation_provider\": DropdownInput(\n name=\"embedding_generation_provider\",\n display_name=\"Embedding generation method\",\n info=\"Provider to use for generating embeddings.\",\n helper_text=(\n \"To create collections with more embedding provider options, go to \"\n 'your database in Astra DB'\n ),\n real_time_refresh=True,\n required=True,\n options=[],\n ),\n \"03_embedding_generation_model\": DropdownInput(\n name=\"embedding_generation_model\",\n display_name=\"Embedding model\",\n info=\"Model to use for generating embeddings.\",\n real_time_refresh=True,\n options=[],\n ),\n \"04_dimension\": IntInput(\n name=\"dimension\",\n display_name=\"Dimensions\",\n info=\"Dimensions of the embeddings to generate.\",\n value=None,\n ),\n },\n },\n }\n }\n )\n\n inputs = [\n SecretStrInput(\n name=\"token\",\n display_name=\"Astra DB Application Token\",\n info=\"Authentication token for accessing Astra DB.\",\n value=\"ASTRA_DB_APPLICATION_TOKEN\",\n required=True,\n real_time_refresh=True,\n input_types=[],\n ),\n DropdownInput(\n name=\"environment\",\n display_name=\"Environment\",\n info=\"The environment for the Astra DB API Endpoint.\",\n options=[\"prod\", \"test\", \"dev\"],\n value=\"prod\",\n advanced=True,\n real_time_refresh=True,\n combobox=True,\n ),\n DropdownInput(\n name=\"database_name\",\n display_name=\"Database\",\n info=\"The Database name for the Astra DB instance.\",\n required=True,\n refresh_button=True,\n real_time_refresh=True,\n dialog_inputs=asdict(NewDatabaseInput()),\n combobox=True,\n ),\n StrInput(\n name=\"api_endpoint\",\n display_name=\"Astra DB API Endpoint\",\n info=\"The API Endpoint for the Astra DB instance. Supercedes database selection.\",\n show=False,\n ),\n DropdownInput(\n name=\"keyspace\",\n display_name=\"Keyspace\",\n info=\"Optional keyspace within Astra DB to use for the collection.\",\n advanced=True,\n options=[],\n real_time_refresh=True,\n ),\n DropdownInput(\n name=\"collection_name\",\n display_name=\"Collection\",\n info=\"The name of the collection within Astra DB where the vectors will be stored.\",\n required=True,\n refresh_button=True,\n real_time_refresh=True,\n dialog_inputs=asdict(NewCollectionInput()),\n combobox=True,\n show=False,\n ),\n HandleInput(\n name=\"embedding_model\",\n display_name=\"Embedding Model\",\n input_types=[\"Embeddings\"],\n info=\"Specify the Embedding Model. Not required for Astra Vectorize collections.\",\n required=False,\n show=False,\n ),\n *LCVectorStoreComponent.inputs,\n DropdownInput(\n name=\"search_method\",\n display_name=\"Search Method\",\n info=(\n \"Determine how your content is matched: Vector finds semantic similarity, \"\n \"and Hybrid Search (suggested) combines both approaches \"\n \"with a reranker.\"\n ),\n options=[\"Hybrid Search\", \"Vector Search\"], # TODO: Restore Lexical Search?\n options_metadata=[{\"icon\": \"SearchHybrid\"}, {\"icon\": \"SearchVector\"}],\n value=\"Vector Search\",\n advanced=True,\n real_time_refresh=True,\n ),\n DropdownInput(\n name=\"reranker\",\n display_name=\"Reranker\",\n info=\"Post-retrieval model that re-scores results for optimal relevance ranking.\",\n show=False,\n toggle=True,\n ),\n QueryInput(\n name=\"lexical_terms\",\n display_name=\"Lexical Terms\",\n info=\"Add additional terms/keywords to augment search precision.\",\n placeholder=\"Enter terms to search...\",\n separator=\" \",\n show=False,\n value=\"\",\n advanced=True,\n ),\n IntInput(\n name=\"number_of_results\",\n display_name=\"Number of Search Results\",\n info=\"Number of search results to return.\",\n advanced=True,\n value=4,\n ),\n DropdownInput(\n name=\"search_type\",\n display_name=\"Search Type\",\n info=\"Search type to use\",\n options=[\"Similarity\", \"Similarity with score threshold\", \"MMR (Max Marginal Relevance)\"],\n value=\"Similarity\",\n advanced=True,\n ),\n FloatInput(\n name=\"search_score_threshold\",\n display_name=\"Search Score Threshold\",\n info=\"Minimum similarity score threshold for search results. \"\n \"(when using 'Similarity with score threshold')\",\n value=0,\n advanced=True,\n ),\n NestedDictInput(\n name=\"advanced_search_filter\",\n display_name=\"Search Metadata Filter\",\n info=\"Optional dictionary of filters to apply to the search query.\",\n advanced=True,\n ),\n BoolInput(\n name=\"autodetect_collection\",\n display_name=\"Autodetect Collection\",\n info=\"Boolean flag to determine whether to autodetect the collection.\",\n advanced=True,\n value=True,\n ),\n StrInput(\n name=\"content_field\",\n display_name=\"Content Field\",\n info=\"Field to use as the text content field for the vector store.\",\n advanced=True,\n ),\n StrInput(\n name=\"deletion_field\",\n display_name=\"Deletion Based On Field\",\n info=\"When this parameter is provided, documents in the target collection with \"\n \"metadata field values matching the input metadata field value will be deleted \"\n \"before new data is loaded.\",\n advanced=True,\n ),\n BoolInput(\n name=\"ignore_invalid_documents\",\n display_name=\"Ignore Invalid Documents\",\n info=\"Boolean flag to determine whether to ignore invalid documents at runtime.\",\n advanced=True,\n ),\n NestedDictInput(\n name=\"astradb_vectorstore_kwargs\",\n display_name=\"AstraDBVectorStore Parameters\",\n info=\"Optional dictionary of additional parameters for the AstraDBVectorStore.\",\n advanced=True,\n ),\n ]\n\n @classmethod\n def map_cloud_providers(cls):\n # TODO: Programmatically fetch the regions for each cloud provider\n return {\n \"dev\": {\n \"Amazon Web Services\": {\n \"id\": \"aws\",\n \"regions\": [\"us-west-2\"],\n },\n \"Google Cloud Platform\": {\n \"id\": \"gcp\",\n \"regions\": [\"us-central1\", \"europe-west4\"],\n },\n },\n \"test\": {\n \"Google Cloud Platform\": {\n \"id\": \"gcp\",\n \"regions\": [\"us-central1\"],\n },\n },\n \"prod\": {\n \"Amazon Web Services\": {\n \"id\": \"aws\",\n \"regions\": [\"us-east-2\", \"ap-south-1\", \"eu-west-1\"],\n },\n \"Google Cloud Platform\": {\n \"id\": \"gcp\",\n \"regions\": [\"us-east1\"],\n },\n \"Microsoft Azure\": {\n \"id\": \"azure\",\n \"regions\": [\"westus3\"],\n },\n },\n }\n\n @classmethod\n def get_vectorize_providers(cls, token: str, environment: str | None = None, api_endpoint: str | None = None):\n try:\n # Get the admin object\n client = DataAPIClient(environment=environment)\n admin_client = client.get_admin()\n db_admin = admin_client.get_database_admin(api_endpoint, token=token)\n\n # Get the list of embedding providers\n embedding_providers = db_admin.find_embedding_providers()\n\n vectorize_providers_mapping = {}\n # Map the provider display name to the provider key and models\n for provider_key, provider_data in embedding_providers.embedding_providers.items():\n # Get the provider display name and models\n display_name = provider_data.display_name\n models = [model.name for model in provider_data.models]\n\n # Build our mapping\n vectorize_providers_mapping[display_name] = [provider_key, models]\n\n # Sort the resulting dictionary\n return defaultdict(list, dict(sorted(vectorize_providers_mapping.items())))\n except Exception as _: # noqa: BLE001\n return {}\n\n @classmethod\n async def create_database_api(\n cls,\n new_database_name: str,\n cloud_provider: str,\n region: str,\n token: str,\n environment: str | None = None,\n keyspace: str | None = None,\n ):\n client = DataAPIClient(environment=environment)\n\n # Get the admin object\n admin_client = client.get_admin(token=token)\n\n # Get the environment, set to prod if null like\n my_env = environment or \"prod\"\n\n # Raise a value error if name isn't provided\n if not new_database_name:\n msg = \"Database name is required to create a new database.\"\n raise ValueError(msg)\n\n # Call the create database function\n return await admin_client.async_create_database(\n name=new_database_name,\n cloud_provider=cls.map_cloud_providers()[my_env][cloud_provider][\"id\"],\n region=region,\n keyspace=keyspace,\n wait_until_active=False,\n )\n\n @classmethod\n async def create_collection_api(\n cls,\n new_collection_name: str,\n token: str,\n api_endpoint: str,\n environment: str | None = None,\n keyspace: str | None = None,\n dimension: int | None = None,\n embedding_generation_provider: str | None = None,\n embedding_generation_model: str | None = None,\n reranker: str | None = None,\n ):\n # Build vectorize options, if needed\n vectorize_options = None\n if not dimension:\n providers = cls.get_vectorize_providers(token=token, environment=environment, api_endpoint=api_endpoint)\n vectorize_options = VectorServiceOptions(\n provider=providers.get(embedding_generation_provider, [None, []])[0],\n model_name=embedding_generation_model,\n )\n\n # Raise a value error if name isn't provided\n if not new_collection_name:\n msg = \"Collection name is required to create a new collection.\"\n raise ValueError(msg)\n\n # Define the base arguments being passed to the create collection function\n base_args = {\n \"collection_name\": new_collection_name,\n \"token\": token,\n \"api_endpoint\": api_endpoint,\n \"keyspace\": keyspace,\n \"environment\": environment,\n \"embedding_dimension\": dimension,\n \"collection_vector_service_options\": vectorize_options,\n }\n\n # Add optional arguments if the reranker is set\n if reranker:\n # Split the reranker field into a provider a model name\n provider, _ = reranker.split(\"/\")\n base_args[\"collection_rerank\"] = CollectionRerankOptions(\n service=RerankServiceOptions(provider=provider, model_name=reranker),\n )\n base_args[\"collection_lexical\"] = CollectionLexicalOptions(analyzer=\"STANDARD\")\n\n _AstraDBCollectionEnvironment(**base_args)\n\n @classmethod\n def get_database_list_static(cls, token: str, environment: str | None = None):\n client = DataAPIClient(environment=environment)\n\n # Get the admin object\n admin_client = client.get_admin(token=token)\n\n # Get the list of databases\n db_list = admin_client.list_databases()\n\n # Generate the api endpoint for each database\n db_info_dict = {}\n for db in db_list:\n try:\n # Get the API endpoint for the database\n api_endpoint = db.regions[0].api_endpoint\n\n # Get the number of collections\n try:\n # Get the number of collections in the database\n num_collections = len(\n client.get_database(\n api_endpoint,\n token=token,\n ).list_collection_names()\n )\n except Exception: # noqa: BLE001\n if db.status != \"PENDING\":\n continue\n num_collections = 0\n\n # Add the database to the dictionary\n db_info_dict[db.name] = {\n \"api_endpoint\": api_endpoint,\n \"keyspaces\": db.keyspaces,\n \"collections\": num_collections,\n \"status\": db.status if db.status != \"ACTIVE\" else None,\n \"org_id\": db.org_id if db.org_id else None,\n }\n except Exception: # noqa: BLE001, S110\n pass\n\n return db_info_dict\n\n def get_database_list(self):\n return self.get_database_list_static(\n token=self.token,\n environment=self.environment,\n )\n\n @classmethod\n def get_api_endpoint_static(\n cls,\n token: str,\n environment: str | None = None,\n api_endpoint: str | None = None,\n database_name: str | None = None,\n ):\n # If the api_endpoint is set, return it\n if api_endpoint:\n return api_endpoint\n\n # Check if the database_name is like a url\n if database_name and database_name.startswith(\"https://\"):\n return database_name\n\n # If the database is not set, nothing we can do.\n if not database_name:\n return None\n\n # Grab the database object\n db = cls.get_database_list_static(token=token, environment=environment).get(database_name)\n if not db:\n return None\n\n # Otherwise, get the URL from the database list\n return db.get(\"api_endpoint\")\n\n def get_api_endpoint(self):\n return self.get_api_endpoint_static(\n token=self.token,\n environment=self.environment,\n api_endpoint=self.api_endpoint,\n database_name=self.database_name,\n )\n\n @classmethod\n def get_database_id_static(cls, api_endpoint: str) -> str | None:\n # Pattern matches standard UUID format: 8-4-4-4-12 hexadecimal characters\n uuid_pattern = r\"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\"\n match = re.search(uuid_pattern, api_endpoint)\n\n return match.group(0) if match else None\n\n def get_database_id(self):\n return self.get_database_id_static(api_endpoint=self.get_api_endpoint())\n\n def get_keyspace(self):\n keyspace = self.keyspace\n\n if keyspace:\n return keyspace.strip()\n\n return \"default_keyspace\"\n\n def get_database_object(self, api_endpoint: str | None = None):\n try:\n client = DataAPIClient(environment=self.environment)\n\n return client.get_database(\n api_endpoint or self.get_api_endpoint(),\n token=self.token,\n keyspace=self.get_keyspace(),\n )\n except Exception as e:\n msg = f\"Error fetching database object: {e}\"\n raise ValueError(msg) from e\n\n def collection_data(self, collection_name: str, database: Database | None = None):\n try:\n if not database:\n client = DataAPIClient(environment=self.environment)\n\n database = client.get_database(\n self.get_api_endpoint(),\n token=self.token,\n keyspace=self.get_keyspace(),\n )\n\n collection = database.get_collection(collection_name)\n\n return collection.estimated_document_count()\n except Exception as e: # noqa: BLE001\n self.log(f\"Error checking collection data: {e}\")\n\n return None\n\n def _initialize_database_options(self):\n try:\n return [\n {\n \"name\": name,\n \"status\": info[\"status\"],\n \"collections\": info[\"collections\"],\n \"api_endpoint\": info[\"api_endpoint\"],\n \"keyspaces\": info[\"keyspaces\"],\n \"org_id\": info[\"org_id\"],\n }\n for name, info in self.get_database_list().items()\n ]\n except Exception as e:\n msg = f\"Error fetching database options: {e}\"\n raise ValueError(msg) from e\n\n @classmethod\n def get_provider_icon(cls, collection: CollectionDescriptor | None = None, provider_name: str | None = None) -> str:\n # Get the provider name from the collection\n provider_name = provider_name or (\n collection.definition.vector.service.provider\n if (\n collection\n and collection.definition\n and collection.definition.vector\n and collection.definition.vector.service\n )\n else None\n )\n\n # If there is no provider, use the vector store icon\n if not provider_name or provider_name.lower() == \"bring your own\":\n return \"vectorstores\"\n\n # Map provider casings\n case_map = {\n \"nvidia\": \"NVIDIA\",\n \"openai\": \"OpenAI\",\n \"amazon bedrock\": \"AmazonBedrockEmbeddings\",\n \"azure openai\": \"AzureOpenAiEmbeddings\",\n \"cohere\": \"Cohere\",\n \"jina ai\": \"JinaAI\",\n \"mistral ai\": \"MistralAI\",\n \"upstage\": \"Upstage\",\n \"voyage ai\": \"VoyageAI\",\n }\n\n # Adjust the casing on some like nvidia\n return case_map[provider_name.lower()] if provider_name.lower() in case_map else provider_name.title()\n\n def _initialize_collection_options(self, api_endpoint: str | None = None):\n # Nothing to generate if we don't have an API endpoint yet\n api_endpoint = api_endpoint or self.get_api_endpoint()\n if not api_endpoint:\n return []\n\n # Retrieve the database object\n database = self.get_database_object(api_endpoint=api_endpoint)\n\n # Get the list of collections\n collection_list = database.list_collections(keyspace=self.get_keyspace())\n\n # Return the list of collections and metadata associated\n return [\n {\n \"name\": col.name,\n \"records\": self.collection_data(collection_name=col.name, database=database),\n \"provider\": (\n col.definition.vector.service.provider\n if col.definition.vector and col.definition.vector.service\n else None\n ),\n \"icon\": self.get_provider_icon(collection=col),\n \"model\": (\n col.definition.vector.service.model_name\n if col.definition.vector and col.definition.vector.service\n else None\n ),\n }\n for col in collection_list\n ]\n\n def reset_provider_options(self, build_config: dict) -> dict:\n \"\"\"Reset provider options and related configurations in the build_config dictionary.\"\"\"\n # Extract template path for cleaner access\n template = build_config[\"collection_name\"][\"dialog_inputs\"][\"fields\"][\"data\"][\"node\"][\"template\"]\n\n # Get vectorize providers\n vectorize_providers_api = self.get_vectorize_providers(\n token=self.token,\n environment=self.environment,\n api_endpoint=build_config[\"api_endpoint\"][\"value\"],\n )\n\n # Create a new dictionary with \"Bring your own\" first\n vectorize_providers: dict[str, list[list[str]]] = {\"Bring your own\": [[], []]}\n\n # Add the remaining items (only Nvidia) from the original dictionary\n vectorize_providers.update(\n {\n k: v\n for k, v in vectorize_providers_api.items()\n if k.lower() in [\"nvidia\"] # TODO: Eventually support more\n }\n )\n\n # Set provider options\n provider_field = \"02_embedding_generation_provider\"\n template[provider_field][\"options\"] = list(vectorize_providers.keys())\n\n # Add metadata for each provider option\n template[provider_field][\"options_metadata\"] = [\n {\"icon\": self.get_provider_icon(provider_name=provider)} for provider in template[provider_field][\"options\"]\n ]\n\n # Get selected embedding provider\n embedding_provider = template[provider_field][\"value\"]\n is_bring_your_own = embedding_provider and embedding_provider == \"Bring your own\"\n\n # Configure embedding model field\n model_field = \"03_embedding_generation_model\"\n template[model_field].update(\n {\n \"options\": vectorize_providers.get(embedding_provider, [[], []])[1],\n \"placeholder\": \"Bring your own\" if is_bring_your_own else None,\n \"readonly\": is_bring_your_own,\n \"required\": not is_bring_your_own,\n \"value\": None,\n }\n )\n\n # If this is a bring your own, set dimensions to 0\n return self.reset_dimension_field(build_config)\n\n def reset_dimension_field(self, build_config: dict) -> dict:\n \"\"\"Reset dimension field options based on provided configuration.\"\"\"\n # Extract template path for cleaner access\n template = build_config[\"collection_name\"][\"dialog_inputs\"][\"fields\"][\"data\"][\"node\"][\"template\"]\n\n # Get selected embedding model\n provider_field = \"02_embedding_generation_provider\"\n embedding_provider = template[provider_field][\"value\"]\n is_bring_your_own = embedding_provider and embedding_provider == \"Bring your own\"\n\n # Configure dimension field\n dimension_field = \"04_dimension\"\n dimension_value = 1024 if not is_bring_your_own else None # TODO: Dynamically figure this out\n template[dimension_field].update(\n {\n \"placeholder\": dimension_value,\n \"value\": dimension_value,\n \"readonly\": not is_bring_your_own,\n \"required\": is_bring_your_own,\n }\n )\n\n return build_config\n\n def reset_collection_list(self, build_config: dict) -> dict:\n \"\"\"Reset collection list options based on provided configuration.\"\"\"\n # Get collection options\n collection_options = self._initialize_collection_options(api_endpoint=build_config[\"api_endpoint\"][\"value\"])\n # Update collection configuration\n collection_config = build_config[\"collection_name\"]\n collection_config.update(\n {\n \"options\": [col[\"name\"] for col in collection_options],\n \"options_metadata\": [{k: v for k, v in col.items() if k != \"name\"} for col in collection_options],\n }\n )\n\n # Reset selected collection if not in options\n if collection_config[\"value\"] not in collection_config[\"options\"]:\n collection_config[\"value\"] = \"\"\n\n # Set advanced status based on database selection\n collection_config[\"show\"] = bool(build_config[\"database_name\"][\"value\"])\n\n return build_config\n\n def reset_database_list(self, build_config: dict) -> dict:\n \"\"\"Reset database list options and related configurations.\"\"\"\n # Get database options\n database_options = self._initialize_database_options()\n\n # Update cloud provider options\n env = self.environment\n template = build_config[\"database_name\"][\"dialog_inputs\"][\"fields\"][\"data\"][\"node\"][\"template\"]\n template[\"02_cloud_provider\"][\"options\"] = list(self.map_cloud_providers()[env].keys())\n\n # Update database configuration\n database_config = build_config[\"database_name\"]\n database_config.update(\n {\n \"options\": [db[\"name\"] for db in database_options],\n \"options_metadata\": [{k: v for k, v in db.items() if k != \"name\"} for db in database_options],\n }\n )\n\n # Reset selections if value not in options\n if database_config[\"value\"] not in database_config[\"options\"]:\n database_config[\"value\"] = \"\"\n build_config[\"api_endpoint\"][\"value\"] = \"\"\n build_config[\"collection_name\"][\"show\"] = False\n\n # Set advanced status based on token presence\n database_config[\"show\"] = bool(build_config[\"token\"][\"value\"])\n\n return build_config\n\n def reset_build_config(self, build_config: dict) -> dict:\n \"\"\"Reset all build configuration options to default empty state.\"\"\"\n # Reset database configuration\n database_config = build_config[\"database_name\"]\n database_config.update({\"options\": [], \"options_metadata\": [], \"value\": \"\", \"show\": False})\n build_config[\"api_endpoint\"][\"value\"] = \"\"\n\n # Reset collection configuration\n collection_config = build_config[\"collection_name\"]\n collection_config.update({\"options\": [], \"options_metadata\": [], \"value\": \"\", \"show\": False})\n\n return build_config\n\n def _handle_hybrid_search_options(self, build_config: dict) -> dict:\n \"\"\"Set hybrid search options in the build configuration.\"\"\"\n # Detect what hybrid options are available\n # Get the admin object\n client = DataAPIClient(environment=self.environment)\n admin_client = client.get_admin()\n db_admin = admin_client.get_database_admin(self.get_api_endpoint(), token=self.token)\n\n # We will try to get the reranking providers to see if its hybrid emabled\n try:\n providers = db_admin.find_reranking_providers()\n build_config[\"reranker\"][\"options\"] = [\n model.name for provider_data in providers.reranking_providers.values() for model in provider_data.models\n ]\n build_config[\"reranker\"][\"options_metadata\"] = [\n {\"icon\": self.get_provider_icon(provider_name=model.name.split(\"/\")[0])}\n for provider in providers.reranking_providers.values()\n for model in provider.models\n ]\n build_config[\"reranker\"][\"value\"] = build_config[\"reranker\"][\"options\"][0]\n\n # Set the default search field to hybrid search\n build_config[\"search_method\"][\"show\"] = True\n build_config[\"search_method\"][\"options\"] = [\"Hybrid Search\", \"Vector Search\"]\n build_config[\"search_method\"][\"value\"] = \"Hybrid Search\"\n except Exception as _: # noqa: BLE001\n build_config[\"reranker\"][\"options\"] = []\n build_config[\"reranker\"][\"options_metadata\"] = []\n\n # Set the default search field to vector search\n build_config[\"search_method\"][\"show\"] = False\n build_config[\"search_method\"][\"options\"] = [\"Vector Search\"]\n build_config[\"search_method\"][\"value\"] = \"Vector Search\"\n\n # Set reranker and lexical terms options based on search method\n build_config[\"reranker\"][\"toggle_value\"] = True\n build_config[\"reranker\"][\"show\"] = build_config[\"search_method\"][\"value\"] == \"Hybrid Search\"\n build_config[\"reranker\"][\"toggle_disable\"] = build_config[\"search_method\"][\"value\"] == \"Hybrid Search\"\n if build_config[\"reranker\"][\"show\"]:\n build_config[\"search_type\"][\"value\"] = \"Similarity\"\n\n return build_config\n\n async def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None) -> dict:\n \"\"\"Update build configuration based on field name and value.\"\"\"\n # Early return if no token provided\n if not self.token:\n return self.reset_build_config(build_config)\n\n # Database creation callback\n if field_name == \"database_name\" and isinstance(field_value, dict):\n if \"01_new_database_name\" in field_value:\n await self._create_new_database(build_config, field_value)\n return self.reset_collection_list(build_config)\n return self._update_cloud_regions(build_config, field_value)\n\n # Collection creation callback\n if field_name == \"collection_name\" and isinstance(field_value, dict):\n # Case 1: New collection creation\n if \"01_new_collection_name\" in field_value:\n await self._create_new_collection(build_config, field_value)\n return build_config\n\n # Case 2: Update embedding provider options\n if \"02_embedding_generation_provider\" in field_value:\n return self.reset_provider_options(build_config)\n\n # Case 3: Update dimension field\n if \"03_embedding_generation_model\" in field_value:\n return self.reset_dimension_field(build_config)\n\n # Initial execution or token/environment change\n first_run = field_name == \"collection_name\" and not field_value and not build_config[\"database_name\"][\"options\"]\n if first_run or field_name in {\"token\", \"environment\"}:\n return self.reset_database_list(build_config)\n\n # Database selection change\n if field_name == \"database_name\" and not isinstance(field_value, dict):\n return self._handle_database_selection(build_config, field_value)\n\n # Keyspace selection change\n if field_name == \"keyspace\":\n return self.reset_collection_list(build_config)\n\n # Collection selection change\n if field_name == \"collection_name\" and not isinstance(field_value, dict):\n return self._handle_collection_selection(build_config, field_value)\n\n # Search method selection change\n if field_name == \"search_method\":\n is_vector_search = field_value == \"Vector Search\"\n is_autodetect = build_config[\"autodetect_collection\"][\"value\"]\n\n # Configure lexical terms (same for both cases)\n build_config[\"lexical_terms\"][\"show\"] = not is_vector_search\n build_config[\"lexical_terms\"][\"value\"] = \"\" if is_vector_search else build_config[\"lexical_terms\"][\"value\"]\n\n # Disable reranker disabling if hybrid search is selected\n build_config[\"reranker\"][\"toggle_disable\"] = not is_vector_search\n build_config[\"reranker\"][\"toggle_value\"] = True\n build_config[\"reranker\"][\"value\"] = build_config[\"reranker\"][\"options\"][0]\n\n # Toggle search type and score threshold based on search method\n build_config[\"search_type\"][\"show\"] = is_vector_search\n build_config[\"search_score_threshold\"][\"show\"] = is_vector_search\n\n # Make sure the search_type is set to \"Similarity\"\n if not is_vector_search or is_autodetect:\n build_config[\"search_type\"][\"value\"] = \"Similarity\"\n\n return build_config\n\n async def _create_new_database(self, build_config: dict, field_value: dict) -> None:\n \"\"\"Create a new database and update build config options.\"\"\"\n try:\n await self.create_database_api(\n new_database_name=field_value[\"01_new_database_name\"],\n token=self.token,\n keyspace=self.get_keyspace(),\n environment=self.environment,\n cloud_provider=field_value[\"02_cloud_provider\"],\n region=field_value[\"03_region\"],\n )\n except Exception as e:\n msg = f\"Error creating database: {e}\"\n raise ValueError(msg) from e\n\n build_config[\"database_name\"][\"options\"].append(field_value[\"01_new_database_name\"])\n build_config[\"database_name\"][\"options_metadata\"].append(\n {\n \"status\": \"PENDING\",\n \"collections\": 0,\n \"api_endpoint\": None,\n \"keyspaces\": [self.get_keyspace()],\n \"org_id\": None,\n }\n )\n\n def _update_cloud_regions(self, build_config: dict, field_value: dict) -> dict:\n \"\"\"Update cloud provider regions in build config.\"\"\"\n env = self.environment\n cloud_provider = field_value[\"02_cloud_provider\"]\n\n # Update the region options based on the selected cloud provider\n template = build_config[\"database_name\"][\"dialog_inputs\"][\"fields\"][\"data\"][\"node\"][\"template\"]\n template[\"03_region\"][\"options\"] = self.map_cloud_providers()[env][cloud_provider][\"regions\"]\n\n # Reset the the 03_region value if it's not in the new options\n if template[\"03_region\"][\"value\"] not in template[\"03_region\"][\"options\"]:\n template[\"03_region\"][\"value\"] = None\n\n return build_config\n\n async def _create_new_collection(self, build_config: dict, field_value: dict) -> None:\n \"\"\"Create a new collection and update build config options.\"\"\"\n embedding_provider = field_value.get(\"02_embedding_generation_provider\")\n try:\n await self.create_collection_api(\n new_collection_name=field_value[\"01_new_collection_name\"],\n token=self.token,\n api_endpoint=build_config[\"api_endpoint\"][\"value\"],\n environment=self.environment,\n keyspace=self.get_keyspace(),\n dimension=field_value.get(\"04_dimension\") if embedding_provider == \"Bring your own\" else None,\n embedding_generation_provider=embedding_provider,\n embedding_generation_model=field_value.get(\"03_embedding_generation_model\"),\n reranker=self.reranker,\n )\n except Exception as e:\n msg = f\"Error creating collection: {e}\"\n raise ValueError(msg) from e\n\n provider = embedding_provider.lower() if embedding_provider and embedding_provider != \"Bring your own\" else None\n build_config[\"collection_name\"].update(\n {\n \"value\": field_value[\"01_new_collection_name\"],\n \"options\": build_config[\"collection_name\"][\"options\"] + [field_value[\"01_new_collection_name\"]],\n }\n )\n build_config[\"embedding_model\"][\"show\"] = not bool(provider)\n build_config[\"embedding_model\"][\"required\"] = not bool(provider)\n build_config[\"collection_name\"][\"options_metadata\"].append(\n {\n \"records\": 0,\n \"provider\": provider,\n \"icon\": self.get_provider_icon(provider_name=provider),\n \"model\": field_value.get(\"03_embedding_generation_model\"),\n }\n )\n\n # Make sure we always show the reranker options if the collection is hybrid enabled\n # And right now they always are\n build_config[\"lexical_terms\"][\"show\"] = True\n\n def _handle_database_selection(self, build_config: dict, field_value: str) -> dict:\n \"\"\"Handle database selection and update related configurations.\"\"\"\n build_config = self.reset_database_list(build_config)\n\n # Reset collection list if database selection changes\n if field_value not in build_config[\"database_name\"][\"options\"]:\n build_config[\"database_name\"][\"value\"] = \"\"\n return build_config\n\n # Get the api endpoint for the selected database\n index = build_config[\"database_name\"][\"options\"].index(field_value)\n build_config[\"api_endpoint\"][\"value\"] = build_config[\"database_name\"][\"options_metadata\"][index][\"api_endpoint\"]\n\n # Get the org_id for the selected database\n org_id = build_config[\"database_name\"][\"options_metadata\"][index][\"org_id\"]\n if not org_id:\n return build_config\n\n # Update the list of keyspaces based on the db info\n build_config[\"keyspace\"][\"options\"] = build_config[\"database_name\"][\"options_metadata\"][index][\"keyspaces\"]\n build_config[\"keyspace\"][\"value\"] = (\n build_config[\"keyspace\"][\"options\"] and build_config[\"keyspace\"][\"options\"][0]\n if build_config[\"keyspace\"][\"value\"] not in build_config[\"keyspace\"][\"options\"]\n else build_config[\"keyspace\"][\"value\"]\n )\n\n # Get the database id for the selected database\n db_id = self.get_database_id_static(api_endpoint=build_config[\"api_endpoint\"][\"value\"])\n keyspace = self.get_keyspace()\n\n # Update the helper text for the embedding provider field\n template = build_config[\"collection_name\"][\"dialog_inputs\"][\"fields\"][\"data\"][\"node\"][\"template\"]\n template[\"02_embedding_generation_provider\"][\"helper_text\"] = (\n \"To create collections with more embedding provider options, go to \"\n f''\n \"your database in Astra DB.\"\n )\n\n # Reset provider options\n build_config = self.reset_provider_options(build_config)\n\n # Handle hybrid search options\n build_config = self._handle_hybrid_search_options(build_config)\n\n return self.reset_collection_list(build_config)\n\n def _handle_collection_selection(self, build_config: dict, field_value: str) -> dict:\n \"\"\"Handle collection selection and update embedding options.\"\"\"\n build_config[\"autodetect_collection\"][\"value\"] = True\n build_config = self.reset_collection_list(build_config)\n\n # Reset embedding model if collection selection changes\n if field_value and field_value not in build_config[\"collection_name\"][\"options\"]:\n build_config[\"collection_name\"][\"options\"].append(field_value)\n build_config[\"collection_name\"][\"options_metadata\"].append(\n {\n \"records\": 0,\n \"provider\": None,\n \"icon\": \"vectorstores\",\n \"model\": None,\n }\n )\n build_config[\"autodetect_collection\"][\"value\"] = False\n\n if not field_value:\n return build_config\n\n # Get the selected collection index\n index = build_config[\"collection_name\"][\"options\"].index(field_value)\n\n # Set the provider of the selected collection\n provider = build_config[\"collection_name\"][\"options_metadata\"][index][\"provider\"]\n build_config[\"embedding_model\"][\"show\"] = not bool(provider)\n build_config[\"embedding_model\"][\"required\"] = not bool(provider)\n\n # Grab the collection object\n database = self.get_database_object(api_endpoint=build_config[\"api_endpoint\"][\"value\"])\n collection = database.get_collection(\n name=field_value,\n keyspace=build_config[\"keyspace\"][\"value\"],\n )\n\n # Check if hybrid and lexical are enabled\n col_options = collection.options()\n hyb_enabled = col_options.rerank and col_options.rerank.enabled\n lex_enabled = col_options.lexical and col_options.lexical.enabled\n user_hyb_enabled = build_config[\"search_method\"][\"value\"] == \"Hybrid Search\"\n\n # Show lexical terms if the collection is hybrid enabled\n build_config[\"lexical_terms\"][\"show\"] = hyb_enabled and lex_enabled and user_hyb_enabled\n\n return build_config\n\n @check_cached_vector_store\n def build_vector_store(self):\n try:\n from langchain_astradb import AstraDBVectorStore\n except ImportError as e:\n msg = (\n \"Could not import langchain Astra DB integration package. \"\n \"Please install it with `pip install langchain-astradb`.\"\n )\n raise ImportError(msg) from e\n\n # Get the embedding model and additional params\n embedding_params = {\"embedding\": self.embedding_model} if self.embedding_model else {}\n\n # Get the additional parameters\n additional_params = self.astradb_vectorstore_kwargs or {}\n\n # Get Langflow version and platform information\n __version__ = get_version_info()[\"version\"]\n langflow_prefix = \"\"\n # if os.getenv(\"AWS_EXECUTION_ENV\") == \"AWS_ECS_FARGATE\": # TODO: More precise way of detecting\n # langflow_prefix = \"ds-\"\n\n # Get the database object\n database = self.get_database_object()\n autodetect = self.collection_name in database.list_collection_names() and self.autodetect_collection\n\n # Bundle up the auto-detect parameters\n autodetect_params = {\n \"autodetect_collection\": autodetect,\n \"content_field\": (\n self.content_field\n if self.content_field and embedding_params\n else (\n \"page_content\"\n if embedding_params\n and self.collection_data(collection_name=self.collection_name, database=database) == 0\n else None\n )\n ),\n \"ignore_invalid_documents\": self.ignore_invalid_documents,\n }\n\n # Choose HybridSearchMode based on the selected param\n hybrid_search_mode = HybridSearchMode.DEFAULT if self.search_method == \"Hybrid Search\" else HybridSearchMode.OFF\n\n # Attempt to build the Vector Store object\n try:\n vector_store = AstraDBVectorStore(\n # Astra DB Authentication Parameters\n token=self.token,\n api_endpoint=database.api_endpoint,\n namespace=database.keyspace,\n collection_name=self.collection_name,\n environment=self.environment,\n # Hybrid Search Parameters\n hybrid_search=hybrid_search_mode,\n # Astra DB Usage Tracking Parameters\n ext_callers=[(f\"{langflow_prefix}langflow\", __version__)],\n # Astra DB Vector Store Parameters\n **autodetect_params,\n **embedding_params,\n **additional_params,\n )\n except Exception as e:\n msg = f\"Error initializing AstraDBVectorStore: {e}\"\n raise ValueError(msg) from e\n\n # Add documents to the vector store\n self._add_documents_to_vector_store(vector_store)\n\n return vector_store\n\n def _add_documents_to_vector_store(self, vector_store) -> None:\n self.ingest_data = self._prepare_ingest_data()\n\n documents = []\n for _input in self.ingest_data or []:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n else:\n msg = \"Vector Store Inputs must be Data objects.\"\n raise TypeError(msg)\n\n if documents and self.deletion_field:\n self.log(f\"Deleting documents where {self.deletion_field}\")\n try:\n database = self.get_database_object()\n collection = database.get_collection(self.collection_name, keyspace=database.keyspace)\n delete_values = list({doc.metadata[self.deletion_field] for doc in documents})\n self.log(f\"Deleting documents where {self.deletion_field} matches {delete_values}.\")\n collection.delete_many({f\"metadata.{self.deletion_field}\": {\"$in\": delete_values}})\n except Exception as e:\n msg = f\"Error deleting documents from AstraDBVectorStore based on '{self.deletion_field}': {e}\"\n raise ValueError(msg) from e\n\n if documents:\n self.log(f\"Adding {len(documents)} documents to the Vector Store.\")\n try:\n vector_store.add_documents(documents)\n except Exception as e:\n msg = f\"Error adding documents to AstraDBVectorStore: {e}\"\n raise ValueError(msg) from e\n else:\n self.log(\"No documents to add to the Vector Store.\")\n\n def _map_search_type(self) -> str:\n search_type_mapping = {\n \"Similarity with score threshold\": \"similarity_score_threshold\",\n \"MMR (Max Marginal Relevance)\": \"mmr\",\n }\n\n return search_type_mapping.get(self.search_type, \"similarity\")\n\n def _build_search_args(self):\n # Clean up the search query\n query = self.search_query if isinstance(self.search_query, str) and self.search_query.strip() else None\n lexical_terms = self.lexical_terms or None\n\n # Check if we have a search query, and if so set the args\n if query:\n args = {\n \"query\": query,\n \"search_type\": self._map_search_type(),\n \"k\": self.number_of_results,\n \"score_threshold\": self.search_score_threshold,\n \"lexical_query\": lexical_terms,\n }\n elif self.advanced_search_filter:\n args = {\n \"n\": self.number_of_results,\n }\n else:\n return {}\n\n filter_arg = self.advanced_search_filter or {}\n if filter_arg:\n args[\"filter\"] = filter_arg\n\n return args\n\n def search_documents(self, vector_store=None) -> list[Data]:\n vector_store = vector_store or self.build_vector_store()\n\n self.log(f\"Search input: {self.search_query}\")\n self.log(f\"Search type: {self.search_type}\")\n self.log(f\"Number of results: {self.number_of_results}\")\n self.log(f\"store.hybrid_search: {vector_store.hybrid_search}\")\n self.log(f\"Lexical terms: {self.lexical_terms}\")\n self.log(f\"Reranker: {self.reranker}\")\n\n try:\n search_args = self._build_search_args()\n except Exception as e:\n msg = f\"Error in AstraDBVectorStore._build_search_args: {e}\"\n raise ValueError(msg) from e\n\n if not search_args:\n self.log(\"No search input or filters provided. Skipping search.\")\n return []\n\n docs = []\n search_method = \"search\" if \"query\" in search_args else \"metadata_search\"\n\n try:\n self.log(f\"Calling vector_store.{search_method} with args: {search_args}\")\n docs = getattr(vector_store, search_method)(**search_args)\n except Exception as e:\n msg = f\"Error performing {search_method} in AstraDBVectorStore: {e}\"\n raise ValueError(msg) from e\n\n self.log(f\"Retrieved documents: {len(docs)}\")\n\n data = docs_to_data(docs)\n self.log(f\"Converted documents to data: {len(data)}\")\n self.status = data\n\n return data\n\n def get_retriever_kwargs(self):\n search_args = self._build_search_args()\n\n return {\n \"search_type\": self._map_search_type(),\n \"search_kwargs\": search_args,\n }\n" - }, - "collection_name": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": true, - "dialog_inputs": { - "fields": { - "data": { - "node": { - "description": "Please allow several seconds for creation to complete.", - "display_name": "Create new collection", - "field_order": [ - "01_new_collection_name", - "02_embedding_generation_provider", - "03_embedding_generation_model", - "04_dimension" - ], - "name": "create_collection", - "template": { - "01_new_collection_name": { - "_input_type": "StrInput", - "advanced": false, - "display_name": "Name", - "dynamic": false, - "info": "Name of the new collection to create in Astra DB.", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "new_collection_name", - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "02_embedding_generation_provider": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": false, - "dialog_inputs": {}, - "display_name": "Embedding generation method", - "dynamic": false, - "helper_text": "To create collections with more embedding provider options, go to your database in Astra DB.", - "info": "Provider to use for generating embeddings.", - "name": "embedding_generation_provider", - "options": [ - "Bring your own", - "Nvidia" - ], - "options_metadata": [ - { - "icon": "vectorstores" - }, - { - "icon": "NVIDIA" - } - ], - "placeholder": "", - "real_time_refresh": true, - "required": true, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "03_embedding_generation_model": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": false, - "dialog_inputs": {}, - "display_name": "Embedding model", - "dynamic": false, - "info": "Model to use for generating embeddings.", - "name": "embedding_generation_model", - "options": [], - "options_metadata": [], - "placeholder": null, - "readonly": "", - "real_time_refresh": true, - "required": true, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": null - }, - "04_dimension": { - "_input_type": "IntInput", - "advanced": false, - "display_name": "Dimensions", - "dynamic": false, - "info": "Dimensions of the embeddings to generate.", - "list": false, - "list_add_label": "Add More", - "name": "dimension", - "placeholder": 1024, - "readonly": true, - "required": "", - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 1024 - } - } - } - } - }, - "functionality": "create" - }, - "display_name": "Collection", - "dynamic": false, - "info": "The name of the collection within Astra DB where the vectors will be stored.", - "name": "collection_name", - "options": [], - "options_metadata": [], - "placeholder": "", - "real_time_refresh": true, - "refresh_button": true, - "required": true, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "content_field": { - "_input_type": "StrInput", - "advanced": true, - "display_name": "Content Field", - "dynamic": false, - "info": "Field to use as the text content field for the vector store.", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "content_field", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "database_name": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": true, - "dialog_inputs": { - "fields": { - "data": { - "node": { - "description": "Please allow several minutes for creation to complete.", - "display_name": "Create new database", - "field_order": [ - "01_new_database_name", - "02_cloud_provider", - "03_region" - ], - "name": "create_database", - "template": { - "01_new_database_name": { - "_input_type": "StrInput", - "advanced": false, - "display_name": "Name", - "dynamic": false, - "info": "Name of the new database to create in Astra DB.", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "new_database_name", - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "02_cloud_provider": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": false, - "dialog_inputs": {}, - "display_name": "Cloud provider", - "dynamic": false, - "info": "Cloud provider for the new database.", - "name": "cloud_provider", - "options": [ - "Amazon Web Services", - "Google Cloud Platform" - ], - "options_metadata": [], - "placeholder": "", - "real_time_refresh": true, - "required": true, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "03_region": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": false, - "dialog_inputs": {}, - "display_name": "Region", - "dynamic": false, - "info": "Region for the new database.", - "name": "region", - "options": [], - "options_metadata": [], - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - } - } - } - } - }, - "functionality": "create" - }, - "display_name": "Database", - "dynamic": false, - "info": "The Database name for the Astra DB instance.", - "name": "database_name", - "options": [], - "options_metadata": [], - "placeholder": "", - "real_time_refresh": true, - "refresh_button": true, - "required": true, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "deletion_field": { - "_input_type": "StrInput", - "advanced": true, - "display_name": "Deletion Based On Field", - "dynamic": false, - "info": "When this parameter is provided, documents in the target collection with metadata field values matching the input metadata field value will be deleted before new data is loaded.", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "deletion_field", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "" - }, - "embedding_model": { - "_input_type": "HandleInput", - "advanced": false, - "display_name": "Embedding Model", - "dynamic": false, - "info": "Specify the Embedding Model. Not required for Astra Vectorize collections.", - "input_types": [ - "Embeddings" - ], - "list": false, - "list_add_label": "Add More", - "name": "embedding_model", - "placeholder": "", - "required": false, - "show": false, - "title_case": false, - "trace_as_metadata": true, - "type": "other", - "value": "" - }, - "environment": { - "_input_type": "DropdownInput", - "advanced": true, - "combobox": true, - "dialog_inputs": {}, - "display_name": "Environment", - "dynamic": false, - "info": "The environment for the Astra DB API Endpoint.", - "name": "environment", - "options": [ - "prod", - "test", - "dev" - ], - "options_metadata": [], - "placeholder": "", - "real_time_refresh": true, - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "prod" - }, - "ignore_invalid_documents": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "Ignore Invalid Documents", - "dynamic": false, - "info": "Boolean flag to determine whether to ignore invalid documents at runtime.", - "list": false, - "list_add_label": "Add More", - "name": "ignore_invalid_documents", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "ingest_data": { - "_input_type": "HandleInput", - "advanced": false, - "display_name": "Ingest Data", - "dynamic": false, - "info": "", - "input_types": [ - "Data", - "DataFrame" - ], - "list": true, - "list_add_label": "Add More", - "name": "ingest_data", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "other", - "value": "" - }, - "keyspace": { - "_input_type": "DropdownInput", - "advanced": true, - "combobox": false, - "dialog_inputs": {}, - "display_name": "Keyspace", - "dynamic": false, - "info": "Optional keyspace within Astra DB to use for the collection.", - "name": "keyspace", - "options": [], - "options_metadata": [], - "placeholder": "", - "real_time_refresh": true, - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "default_keyspace" - }, - "lexical_terms": { - "_input_type": "QueryInput", - "advanced": true, - "display_name": "Lexical Terms", - "dynamic": false, - "info": "Add additional terms/keywords to augment search precision.", - "input_types": [ - "Message" - ], - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "lexical_terms", - "placeholder": "Enter terms to search...", - "required": false, - "separator": " ", - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "query", - "value": "" - }, - "number_of_results": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Number of Search Results", - "dynamic": false, - "info": "Number of search results to return.", - "list": false, - "list_add_label": "Add More", - "name": "number_of_results", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 20 - }, - "reranker": { - "_input_type": "DropdownInput", - "advanced": false, - "combobox": false, - "dialog_inputs": {}, - "display_name": "Reranker", - "dynamic": false, - "info": "Post-retrieval model that re-scores results for optimal relevance ranking.", - "name": "reranker", - "options": [], - "options_metadata": [ - { - "icon": "NVIDIA" - } - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "nvidia/llama-3.2-nv-rerankqa-1b-v2" - }, - "search_method": { - "_input_type": "DropdownInput", - "advanced": true, - "combobox": false, - "dialog_inputs": {}, - "display_name": "Search Method", - "dynamic": false, - "info": "Determine how your content is matched: Vector finds semantic similarity, and Hybrid Search (suggested) combines both approaches with a reranker.", - "name": "search_method", - "options": [ - "Hybrid Search", - "Vector Search" - ], - "options_metadata": [], - "placeholder": "", - "real_time_refresh": true, - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "Hybrid Search" - }, - "search_query": { - "_input_type": "QueryInput", - "advanced": false, - "display_name": "Search Query", - "dynamic": false, - "info": "Enter a query to run a similarity search.", - "input_types": [ - "Message" - ], - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "search_query", - "placeholder": "Enter a query...", - "required": false, - "show": true, - "title_case": false, - "tool_mode": true, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "query", - "value": "" - }, - "search_score_threshold": { - "_input_type": "FloatInput", - "advanced": true, - "display_name": "Search Score Threshold", - "dynamic": false, - "info": "Minimum similarity score threshold for search results. (when using 'Similarity with score threshold')", - "list": false, - "list_add_label": "Add More", - "name": "search_score_threshold", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "float", - "value": 0 - }, - "search_type": { - "_input_type": "DropdownInput", - "advanced": true, - "combobox": false, - "dialog_inputs": {}, - "display_name": "Search Type", - "dynamic": false, - "info": "Search type to use", - "name": "search_type", - "options": [ - "Similarity", - "Similarity with score threshold", - "MMR (Max Marginal Relevance)" - ], - "options_metadata": [], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "Similarity" - }, - "should_cache_vector_store": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "Cache Vector Store", - "dynamic": false, - "info": "If True, the vector store will be cached for the current build of the component. This is useful for components that have multiple output methods and want to share the same vector store.", - "list": false, - "list_add_label": "Add More", - "name": "should_cache_vector_store", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "bool", - "value": true - }, - "token": { - "_input_type": "SecretStrInput", - "advanced": false, - "display_name": "Astra DB Application Token", - "dynamic": false, - "info": "Authentication token for accessing Astra DB.", - "input_types": [], - "load_from_db": true, - "name": "token", - "password": true, - "placeholder": "", - "real_time_refresh": true, - "required": true, - "show": true, - "title_case": false, - "type": "str", - "value": "ASTRA_DB_APPLICATION_TOKEN" - } - }, - "tool_mode": false - }, - "selected_output": "dataframe", - "showNode": true, - "type": "AstraDB" - }, - "dragging": false, - "id": "AstraDB-zZztw", - "measured": { - "height": 652, - "width": 320 - }, - "position": { - "x": 1552.667819377255, - "y": 297.7553185181558 - }, - "selected": false, - "type": "genericNode" - }, - { - "data": { - "id": "ParserComponent-9FGat", + "id": "ParserComponent-MDCBV", "node": { "base_classes": [ "Message" @@ -2015,7 +510,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.3.2", + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "output_types": [], @@ -2149,14 +644,13 @@ }, "tool_mode": false }, - "selected_output": "parsed_text", "showNode": true, "type": "ParserComponent" }, "dragging": false, - "id": "ParserComponent-9FGat", + "id": "ParserComponent-MDCBV", "measured": { - "height": 395, + "height": 328, "width": 320 }, "position": { @@ -2168,7 +662,7 @@ }, { "data": { - "id": "ChatOutput-qOr04", + "id": "ChatOutput-HL6J1", "node": { "base_classes": [ "Message" @@ -2195,7 +689,7 @@ "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.3.2", + "lf_version": "1.4.3", "metadata": {}, "minimized": true, "output_types": [], @@ -2462,21 +956,21 @@ "type": "ChatOutput" }, "dragging": false, - "id": "ChatOutput-qOr04", + "id": "ChatOutput-HL6J1", "measured": { - "height": 66, + "height": 48, "width": 192 }, "position": { - "x": 2471.8270408811427, - "y": 580.4589514794443 + "x": 2377.917336576097, + "y": 549.8362218147556 }, "selected": false, "type": "genericNode" }, { "data": { - "id": "ParserComponent-AzBHA", + "id": "ParserComponent-3Xb72", "node": { "base_classes": [ "Message" @@ -2497,7 +991,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.3.2", + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "output_types": [], @@ -2631,35 +1125,1680 @@ }, "tool_mode": false }, - "selected_output": "parsed_text", "showNode": true, "type": "ParserComponent" }, "dragging": false, - "id": "ParserComponent-AzBHA", + "id": "ParserComponent-3Xb72", "measured": { - "height": 312, + "height": 246, "width": 320 }, "position": { "x": 1962.927032788925, "y": 446.0325342475379 }, - "selected": true, + "selected": false, + "type": "genericNode" + }, + { + "data": { + "id": "AstraDB-8MbYw", + "node": { + "base_classes": [ + "Data", + "DataFrame", + "VectorStore" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Ingest and search documents in Astra DB", + "display_name": "Astra DB", + "documentation": "https://docs.datastax.com/en/langflow/astra-components.html", + "edited": false, + "field_order": [ + "token", + "environment", + "database_name", + "api_endpoint", + "keyspace", + "collection_name", + "embedding_model", + "ingest_data", + "search_query", + "should_cache_vector_store", + "search_method", + "reranker", + "lexical_terms", + "number_of_results", + "search_type", + "search_score_threshold", + "advanced_search_filter", + "autodetect_collection", + "content_field", + "deletion_field", + "ignore_invalid_documents", + "astradb_vectorstore_kwargs" + ], + "frozen": false, + "icon": "AstraDB", + "legacy": false, + "lf_version": "1.4.3", + "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "allows_loop": false, + "cache": true, + "display_name": "Search Results", + "group_outputs": false, + "method": "search_documents", + "name": "search_results", + "selected": "Data", + "tool_mode": true, + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + }, + { + "allows_loop": false, + "cache": true, + "display_name": "DataFrame", + "group_outputs": false, + "method": "as_dataframe", + "name": "dataframe", + "selected": "DataFrame", + "tool_mode": true, + "types": [ + "DataFrame" + ], + "value": "__UNDEFINED__" + }, + { + "allows_loop": false, + "cache": true, + "display_name": "Vector Store Connection", + "group_outputs": false, + "hidden": true, + "method": "as_vector_store", + "name": "vectorstoreconnection", + "selected": "VectorStore", + "tool_mode": true, + "types": [ + "VectorStore" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "advanced_search_filter": { + "_input_type": "NestedDictInput", + "advanced": true, + "display_name": "Search Metadata Filter", + "dynamic": false, + "info": "Optional dictionary of filters to apply to the search query.", + "list": false, + "list_add_label": "Add More", + "name": "advanced_search_filter", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "NestedDict", + "value": {} + }, + "api_endpoint": { + "_input_type": "StrInput", + "advanced": false, + "display_name": "Astra DB API Endpoint", + "dynamic": false, + "info": "The API Endpoint for the Astra DB instance. Supercedes database selection.", + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "api_endpoint", + "placeholder": "", + "required": false, + "show": false, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "https://f3166ac4-3e2f-4b32-880c-231d1f9e3f3e-us-east-2.apps.astra.datastax.com" + }, + "astradb_vectorstore_kwargs": { + "_input_type": "NestedDictInput", + "advanced": true, + "display_name": "AstraDBVectorStore Parameters", + "dynamic": false, + "info": "Optional dictionary of additional parameters for the AstraDBVectorStore.", + "list": false, + "list_add_label": "Add More", + "name": "astradb_vectorstore_kwargs", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "NestedDict", + "value": {} + }, + "autodetect_collection": { + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Autodetect Collection", + "dynamic": false, + "info": "Boolean flag to determine whether to autodetect the collection.", + "list": false, + "list_add_label": "Add More", + "name": "autodetect_collection", + "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": "import re\nfrom collections import defaultdict\nfrom dataclasses import asdict, dataclass, field\n\nfrom astrapy import DataAPIClient, Database\nfrom astrapy.data.info.reranking import RerankServiceOptions\nfrom astrapy.info import CollectionDescriptor, CollectionLexicalOptions, CollectionRerankOptions\nfrom langchain_astradb import AstraDBVectorStore, VectorServiceOptions\nfrom langchain_astradb.utils.astradb import HybridSearchMode, _AstraDBCollectionEnvironment\n\nfrom langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store\nfrom langflow.base.vectorstores.vector_store_connection_decorator import vector_store_connection\nfrom langflow.helpers.data import docs_to_data\nfrom langflow.inputs.inputs import FloatInput, NestedDictInput\nfrom langflow.io import (\n BoolInput,\n DropdownInput,\n HandleInput,\n IntInput,\n QueryInput,\n SecretStrInput,\n StrInput,\n)\nfrom langflow.schema.data import Data\nfrom langflow.utils.version import get_version_info\n\n\n@vector_store_connection\nclass AstraDBVectorStoreComponent(LCVectorStoreComponent):\n display_name: str = \"Astra DB\"\n description: str = \"Ingest and search documents in Astra DB\"\n documentation: str = \"https://docs.datastax.com/en/langflow/astra-components.html\"\n name = \"AstraDB\"\n icon: str = \"AstraDB\"\n\n _cached_vector_store: AstraDBVectorStore | None = None\n\n @dataclass\n class NewDatabaseInput:\n functionality: str = \"create\"\n fields: dict[str, dict] = field(\n default_factory=lambda: {\n \"data\": {\n \"node\": {\n \"name\": \"create_database\",\n \"description\": \"Please allow several minutes for creation to complete.\",\n \"display_name\": \"Create new database\",\n \"field_order\": [\"01_new_database_name\", \"02_cloud_provider\", \"03_region\"],\n \"template\": {\n \"01_new_database_name\": StrInput(\n name=\"new_database_name\",\n display_name=\"Name\",\n info=\"Name of the new database to create in Astra DB.\",\n required=True,\n ),\n \"02_cloud_provider\": DropdownInput(\n name=\"cloud_provider\",\n display_name=\"Cloud provider\",\n info=\"Cloud provider for the new database.\",\n options=[],\n required=True,\n real_time_refresh=True,\n ),\n \"03_region\": DropdownInput(\n name=\"region\",\n display_name=\"Region\",\n info=\"Region for the new database.\",\n options=[],\n required=True,\n ),\n },\n },\n }\n }\n )\n\n @dataclass\n class NewCollectionInput:\n functionality: str = \"create\"\n fields: dict[str, dict] = field(\n default_factory=lambda: {\n \"data\": {\n \"node\": {\n \"name\": \"create_collection\",\n \"description\": \"Please allow several seconds for creation to complete.\",\n \"display_name\": \"Create new collection\",\n \"field_order\": [\n \"01_new_collection_name\",\n \"02_embedding_generation_provider\",\n \"03_embedding_generation_model\",\n \"04_dimension\",\n ],\n \"template\": {\n \"01_new_collection_name\": StrInput(\n name=\"new_collection_name\",\n display_name=\"Name\",\n info=\"Name of the new collection to create in Astra DB.\",\n required=True,\n ),\n \"02_embedding_generation_provider\": DropdownInput(\n name=\"embedding_generation_provider\",\n display_name=\"Embedding generation method\",\n info=\"Provider to use for generating embeddings.\",\n helper_text=(\n \"To create collections with more embedding provider options, go to \"\n 'your database in Astra DB'\n ),\n real_time_refresh=True,\n required=True,\n options=[],\n ),\n \"03_embedding_generation_model\": DropdownInput(\n name=\"embedding_generation_model\",\n display_name=\"Embedding model\",\n info=\"Model to use for generating embeddings.\",\n real_time_refresh=True,\n options=[],\n ),\n \"04_dimension\": IntInput(\n name=\"dimension\",\n display_name=\"Dimensions\",\n info=\"Dimensions of the embeddings to generate.\",\n value=None,\n ),\n },\n },\n }\n }\n )\n\n inputs = [\n SecretStrInput(\n name=\"token\",\n display_name=\"Astra DB Application Token\",\n info=\"Authentication token for accessing Astra DB.\",\n value=\"ASTRA_DB_APPLICATION_TOKEN\",\n required=True,\n real_time_refresh=True,\n input_types=[],\n ),\n DropdownInput(\n name=\"environment\",\n display_name=\"Environment\",\n info=\"The environment for the Astra DB API Endpoint.\",\n options=[\"prod\", \"test\", \"dev\"],\n value=\"prod\",\n advanced=True,\n real_time_refresh=True,\n combobox=True,\n ),\n DropdownInput(\n name=\"database_name\",\n display_name=\"Database\",\n info=\"The Database name for the Astra DB instance.\",\n required=True,\n refresh_button=True,\n real_time_refresh=True,\n dialog_inputs=asdict(NewDatabaseInput()),\n combobox=True,\n ),\n StrInput(\n name=\"api_endpoint\",\n display_name=\"Astra DB API Endpoint\",\n info=\"The API Endpoint for the Astra DB instance. Supercedes database selection.\",\n show=False,\n ),\n DropdownInput(\n name=\"keyspace\",\n display_name=\"Keyspace\",\n info=\"Optional keyspace within Astra DB to use for the collection.\",\n advanced=True,\n options=[],\n real_time_refresh=True,\n ),\n DropdownInput(\n name=\"collection_name\",\n display_name=\"Collection\",\n info=\"The name of the collection within Astra DB where the vectors will be stored.\",\n required=True,\n refresh_button=True,\n real_time_refresh=True,\n dialog_inputs=asdict(NewCollectionInput()),\n combobox=True,\n show=False,\n ),\n HandleInput(\n name=\"embedding_model\",\n display_name=\"Embedding Model\",\n input_types=[\"Embeddings\"],\n info=\"Specify the Embedding Model. Not required for Astra Vectorize collections.\",\n required=False,\n show=False,\n ),\n *LCVectorStoreComponent.inputs,\n DropdownInput(\n name=\"search_method\",\n display_name=\"Search Method\",\n info=(\n \"Determine how your content is matched: Vector finds semantic similarity, \"\n \"and Hybrid Search (suggested) combines both approaches \"\n \"with a reranker.\"\n ),\n options=[\"Hybrid Search\", \"Vector Search\"], # TODO: Restore Lexical Search?\n options_metadata=[{\"icon\": \"SearchHybrid\"}, {\"icon\": \"SearchVector\"}],\n value=\"Vector Search\",\n advanced=True,\n real_time_refresh=True,\n ),\n DropdownInput(\n name=\"reranker\",\n display_name=\"Reranker\",\n info=\"Post-retrieval model that re-scores results for optimal relevance ranking.\",\n show=False,\n toggle=True,\n ),\n QueryInput(\n name=\"lexical_terms\",\n display_name=\"Lexical Terms\",\n info=\"Add additional terms/keywords to augment search precision.\",\n placeholder=\"Enter terms to search...\",\n separator=\" \",\n show=False,\n value=\"\",\n advanced=True,\n ),\n IntInput(\n name=\"number_of_results\",\n display_name=\"Number of Search Results\",\n info=\"Number of search results to return.\",\n advanced=True,\n value=4,\n ),\n DropdownInput(\n name=\"search_type\",\n display_name=\"Search Type\",\n info=\"Search type to use\",\n options=[\"Similarity\", \"Similarity with score threshold\", \"MMR (Max Marginal Relevance)\"],\n value=\"Similarity\",\n advanced=True,\n ),\n FloatInput(\n name=\"search_score_threshold\",\n display_name=\"Search Score Threshold\",\n info=\"Minimum similarity score threshold for search results. \"\n \"(when using 'Similarity with score threshold')\",\n value=0,\n advanced=True,\n ),\n NestedDictInput(\n name=\"advanced_search_filter\",\n display_name=\"Search Metadata Filter\",\n info=\"Optional dictionary of filters to apply to the search query.\",\n advanced=True,\n ),\n BoolInput(\n name=\"autodetect_collection\",\n display_name=\"Autodetect Collection\",\n info=\"Boolean flag to determine whether to autodetect the collection.\",\n advanced=True,\n value=True,\n ),\n StrInput(\n name=\"content_field\",\n display_name=\"Content Field\",\n info=\"Field to use as the text content field for the vector store.\",\n advanced=True,\n ),\n StrInput(\n name=\"deletion_field\",\n display_name=\"Deletion Based On Field\",\n info=\"When this parameter is provided, documents in the target collection with \"\n \"metadata field values matching the input metadata field value will be deleted \"\n \"before new data is loaded.\",\n advanced=True,\n ),\n BoolInput(\n name=\"ignore_invalid_documents\",\n display_name=\"Ignore Invalid Documents\",\n info=\"Boolean flag to determine whether to ignore invalid documents at runtime.\",\n advanced=True,\n ),\n NestedDictInput(\n name=\"astradb_vectorstore_kwargs\",\n display_name=\"AstraDBVectorStore Parameters\",\n info=\"Optional dictionary of additional parameters for the AstraDBVectorStore.\",\n advanced=True,\n ),\n ]\n\n @classmethod\n def map_cloud_providers(cls):\n # TODO: Programmatically fetch the regions for each cloud provider\n return {\n \"dev\": {\n \"Amazon Web Services\": {\n \"id\": \"aws\",\n \"regions\": [\"us-west-2\"],\n },\n \"Google Cloud Platform\": {\n \"id\": \"gcp\",\n \"regions\": [\"us-central1\", \"europe-west4\"],\n },\n },\n \"test\": {\n \"Google Cloud Platform\": {\n \"id\": \"gcp\",\n \"regions\": [\"us-central1\"],\n },\n },\n \"prod\": {\n \"Amazon Web Services\": {\n \"id\": \"aws\",\n \"regions\": [\"us-east-2\", \"ap-south-1\", \"eu-west-1\"],\n },\n \"Google Cloud Platform\": {\n \"id\": \"gcp\",\n \"regions\": [\"us-east1\"],\n },\n \"Microsoft Azure\": {\n \"id\": \"azure\",\n \"regions\": [\"westus3\"],\n },\n },\n }\n\n @classmethod\n def get_vectorize_providers(cls, token: str, environment: str | None = None, api_endpoint: str | None = None):\n try:\n # Get the admin object\n client = DataAPIClient(environment=environment)\n admin_client = client.get_admin()\n db_admin = admin_client.get_database_admin(api_endpoint, token=token)\n\n # Get the list of embedding providers\n embedding_providers = db_admin.find_embedding_providers()\n\n vectorize_providers_mapping = {}\n # Map the provider display name to the provider key and models\n for provider_key, provider_data in embedding_providers.embedding_providers.items():\n # Get the provider display name and models\n display_name = provider_data.display_name\n models = [model.name for model in provider_data.models]\n\n # Build our mapping\n vectorize_providers_mapping[display_name] = [provider_key, models]\n\n # Sort the resulting dictionary\n return defaultdict(list, dict(sorted(vectorize_providers_mapping.items())))\n except Exception as _: # noqa: BLE001\n return {}\n\n @classmethod\n async def create_database_api(\n cls,\n new_database_name: str,\n cloud_provider: str,\n region: str,\n token: str,\n environment: str | None = None,\n keyspace: str | None = None,\n ):\n client = DataAPIClient(environment=environment)\n\n # Get the admin object\n admin_client = client.get_admin(token=token)\n\n # Get the environment, set to prod if null like\n my_env = environment or \"prod\"\n\n # Raise a value error if name isn't provided\n if not new_database_name:\n msg = \"Database name is required to create a new database.\"\n raise ValueError(msg)\n\n # Call the create database function\n return await admin_client.async_create_database(\n name=new_database_name,\n cloud_provider=cls.map_cloud_providers()[my_env][cloud_provider][\"id\"],\n region=region,\n keyspace=keyspace,\n wait_until_active=False,\n )\n\n @classmethod\n async def create_collection_api(\n cls,\n new_collection_name: str,\n token: str,\n api_endpoint: str,\n environment: str | None = None,\n keyspace: str | None = None,\n dimension: int | None = None,\n embedding_generation_provider: str | None = None,\n embedding_generation_model: str | None = None,\n reranker: str | None = None,\n ):\n # Build vectorize options, if needed\n vectorize_options = None\n if not dimension:\n providers = cls.get_vectorize_providers(token=token, environment=environment, api_endpoint=api_endpoint)\n vectorize_options = VectorServiceOptions(\n provider=providers.get(embedding_generation_provider, [None, []])[0],\n model_name=embedding_generation_model,\n )\n\n # Raise a value error if name isn't provided\n if not new_collection_name:\n msg = \"Collection name is required to create a new collection.\"\n raise ValueError(msg)\n\n # Define the base arguments being passed to the create collection function\n base_args = {\n \"collection_name\": new_collection_name,\n \"token\": token,\n \"api_endpoint\": api_endpoint,\n \"keyspace\": keyspace,\n \"environment\": environment,\n \"embedding_dimension\": dimension,\n \"collection_vector_service_options\": vectorize_options,\n }\n\n # Add optional arguments if the reranker is set\n if reranker:\n # Split the reranker field into a provider a model name\n provider, _ = reranker.split(\"/\")\n base_args[\"collection_rerank\"] = CollectionRerankOptions(\n service=RerankServiceOptions(provider=provider, model_name=reranker),\n )\n base_args[\"collection_lexical\"] = CollectionLexicalOptions(analyzer=\"STANDARD\")\n\n _AstraDBCollectionEnvironment(**base_args)\n\n @classmethod\n def get_database_list_static(cls, token: str, environment: str | None = None):\n client = DataAPIClient(environment=environment)\n\n # Get the admin object\n admin_client = client.get_admin(token=token)\n\n # Get the list of databases\n db_list = admin_client.list_databases()\n\n # Generate the api endpoint for each database\n db_info_dict = {}\n for db in db_list:\n try:\n # Get the API endpoint for the database\n api_endpoint = db.regions[0].api_endpoint\n\n # Get the number of collections\n try:\n # Get the number of collections in the database\n num_collections = len(\n client.get_database(\n api_endpoint,\n token=token,\n ).list_collection_names()\n )\n except Exception: # noqa: BLE001\n if db.status != \"PENDING\":\n continue\n num_collections = 0\n\n # Add the database to the dictionary\n db_info_dict[db.name] = {\n \"api_endpoint\": api_endpoint,\n \"keyspaces\": db.keyspaces,\n \"collections\": num_collections,\n \"status\": db.status if db.status != \"ACTIVE\" else None,\n \"org_id\": db.org_id if db.org_id else None,\n }\n except Exception: # noqa: BLE001, S110\n pass\n\n return db_info_dict\n\n def get_database_list(self):\n return self.get_database_list_static(\n token=self.token,\n environment=self.environment,\n )\n\n @classmethod\n def get_api_endpoint_static(\n cls,\n token: str,\n environment: str | None = None,\n api_endpoint: str | None = None,\n database_name: str | None = None,\n ):\n # If the api_endpoint is set, return it\n if api_endpoint:\n return api_endpoint\n\n # Check if the database_name is like a url\n if database_name and database_name.startswith(\"https://\"):\n return database_name\n\n # If the database is not set, nothing we can do.\n if not database_name:\n return None\n\n # Grab the database object\n db = cls.get_database_list_static(token=token, environment=environment).get(database_name)\n if not db:\n return None\n\n # Otherwise, get the URL from the database list\n return db.get(\"api_endpoint\")\n\n def get_api_endpoint(self):\n return self.get_api_endpoint_static(\n token=self.token,\n environment=self.environment,\n api_endpoint=self.api_endpoint,\n database_name=self.database_name,\n )\n\n @classmethod\n def get_database_id_static(cls, api_endpoint: str) -> str | None:\n # Pattern matches standard UUID format: 8-4-4-4-12 hexadecimal characters\n uuid_pattern = r\"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\"\n match = re.search(uuid_pattern, api_endpoint)\n\n return match.group(0) if match else None\n\n def get_database_id(self):\n return self.get_database_id_static(api_endpoint=self.get_api_endpoint())\n\n def get_keyspace(self):\n keyspace = self.keyspace\n\n if keyspace:\n return keyspace.strip()\n\n return \"default_keyspace\"\n\n def get_database_object(self, api_endpoint: str | None = None):\n try:\n client = DataAPIClient(environment=self.environment)\n\n return client.get_database(\n api_endpoint or self.get_api_endpoint(),\n token=self.token,\n keyspace=self.get_keyspace(),\n )\n except Exception as e:\n msg = f\"Error fetching database object: {e}\"\n raise ValueError(msg) from e\n\n def collection_data(self, collection_name: str, database: Database | None = None):\n try:\n if not database:\n client = DataAPIClient(environment=self.environment)\n\n database = client.get_database(\n self.get_api_endpoint(),\n token=self.token,\n keyspace=self.get_keyspace(),\n )\n\n collection = database.get_collection(collection_name)\n\n return collection.estimated_document_count()\n except Exception as e: # noqa: BLE001\n self.log(f\"Error checking collection data: {e}\")\n\n return None\n\n def _initialize_database_options(self):\n try:\n return [\n {\n \"name\": name,\n \"status\": info[\"status\"],\n \"collections\": info[\"collections\"],\n \"api_endpoint\": info[\"api_endpoint\"],\n \"keyspaces\": info[\"keyspaces\"],\n \"org_id\": info[\"org_id\"],\n }\n for name, info in self.get_database_list().items()\n ]\n except Exception as e:\n msg = f\"Error fetching database options: {e}\"\n raise ValueError(msg) from e\n\n @classmethod\n def get_provider_icon(cls, collection: CollectionDescriptor | None = None, provider_name: str | None = None) -> str:\n # Get the provider name from the collection\n provider_name = provider_name or (\n collection.definition.vector.service.provider\n if (\n collection\n and collection.definition\n and collection.definition.vector\n and collection.definition.vector.service\n )\n else None\n )\n\n # If there is no provider, use the vector store icon\n if not provider_name or provider_name.lower() == \"bring your own\":\n return \"vectorstores\"\n\n # Map provider casings\n case_map = {\n \"nvidia\": \"NVIDIA\",\n \"openai\": \"OpenAI\",\n \"amazon bedrock\": \"AmazonBedrockEmbeddings\",\n \"azure openai\": \"AzureOpenAiEmbeddings\",\n \"cohere\": \"Cohere\",\n \"jina ai\": \"JinaAI\",\n \"mistral ai\": \"MistralAI\",\n \"upstage\": \"Upstage\",\n \"voyage ai\": \"VoyageAI\",\n }\n\n # Adjust the casing on some like nvidia\n return case_map[provider_name.lower()] if provider_name.lower() in case_map else provider_name.title()\n\n def _initialize_collection_options(self, api_endpoint: str | None = None):\n # Nothing to generate if we don't have an API endpoint yet\n api_endpoint = api_endpoint or self.get_api_endpoint()\n if not api_endpoint:\n return []\n\n # Retrieve the database object\n database = self.get_database_object(api_endpoint=api_endpoint)\n\n # Get the list of collections\n collection_list = database.list_collections(keyspace=self.get_keyspace())\n\n # Return the list of collections and metadata associated\n return [\n {\n \"name\": col.name,\n \"records\": self.collection_data(collection_name=col.name, database=database),\n \"provider\": (\n col.definition.vector.service.provider\n if col.definition.vector and col.definition.vector.service\n else None\n ),\n \"icon\": self.get_provider_icon(collection=col),\n \"model\": (\n col.definition.vector.service.model_name\n if col.definition.vector and col.definition.vector.service\n else None\n ),\n }\n for col in collection_list\n ]\n\n def reset_provider_options(self, build_config: dict) -> dict:\n \"\"\"Reset provider options and related configurations in the build_config dictionary.\"\"\"\n # Extract template path for cleaner access\n template = build_config[\"collection_name\"][\"dialog_inputs\"][\"fields\"][\"data\"][\"node\"][\"template\"]\n\n # Get vectorize providers\n vectorize_providers_api = self.get_vectorize_providers(\n token=self.token,\n environment=self.environment,\n api_endpoint=build_config[\"api_endpoint\"][\"value\"],\n )\n\n # Create a new dictionary with \"Bring your own\" first\n vectorize_providers: dict[str, list[list[str]]] = {\"Bring your own\": [[], []]}\n\n # Add the remaining items (only Nvidia) from the original dictionary\n vectorize_providers.update(\n {\n k: v\n for k, v in vectorize_providers_api.items()\n if k.lower() in [\"nvidia\"] # TODO: Eventually support more\n }\n )\n\n # Set provider options\n provider_field = \"02_embedding_generation_provider\"\n template[provider_field][\"options\"] = list(vectorize_providers.keys())\n\n # Add metadata for each provider option\n template[provider_field][\"options_metadata\"] = [\n {\"icon\": self.get_provider_icon(provider_name=provider)} for provider in template[provider_field][\"options\"]\n ]\n\n # Get selected embedding provider\n embedding_provider = template[provider_field][\"value\"]\n is_bring_your_own = embedding_provider and embedding_provider == \"Bring your own\"\n\n # Configure embedding model field\n model_field = \"03_embedding_generation_model\"\n template[model_field].update(\n {\n \"options\": vectorize_providers.get(embedding_provider, [[], []])[1],\n \"placeholder\": \"Bring your own\" if is_bring_your_own else None,\n \"readonly\": is_bring_your_own,\n \"required\": not is_bring_your_own,\n \"value\": None,\n }\n )\n\n # If this is a bring your own, set dimensions to 0\n return self.reset_dimension_field(build_config)\n\n def reset_dimension_field(self, build_config: dict) -> dict:\n \"\"\"Reset dimension field options based on provided configuration.\"\"\"\n # Extract template path for cleaner access\n template = build_config[\"collection_name\"][\"dialog_inputs\"][\"fields\"][\"data\"][\"node\"][\"template\"]\n\n # Get selected embedding model\n provider_field = \"02_embedding_generation_provider\"\n embedding_provider = template[provider_field][\"value\"]\n is_bring_your_own = embedding_provider and embedding_provider == \"Bring your own\"\n\n # Configure dimension field\n dimension_field = \"04_dimension\"\n dimension_value = 1024 if not is_bring_your_own else None # TODO: Dynamically figure this out\n template[dimension_field].update(\n {\n \"placeholder\": dimension_value,\n \"value\": dimension_value,\n \"readonly\": not is_bring_your_own,\n \"required\": is_bring_your_own,\n }\n )\n\n return build_config\n\n def reset_collection_list(self, build_config: dict) -> dict:\n \"\"\"Reset collection list options based on provided configuration.\"\"\"\n # Get collection options\n collection_options = self._initialize_collection_options(api_endpoint=build_config[\"api_endpoint\"][\"value\"])\n # Update collection configuration\n collection_config = build_config[\"collection_name\"]\n collection_config.update(\n {\n \"options\": [col[\"name\"] for col in collection_options],\n \"options_metadata\": [{k: v for k, v in col.items() if k != \"name\"} for col in collection_options],\n }\n )\n\n # Reset selected collection if not in options\n if collection_config[\"value\"] not in collection_config[\"options\"]:\n collection_config[\"value\"] = \"\"\n\n # Set advanced status based on database selection\n collection_config[\"show\"] = bool(build_config[\"database_name\"][\"value\"])\n\n return build_config\n\n def reset_database_list(self, build_config: dict) -> dict:\n \"\"\"Reset database list options and related configurations.\"\"\"\n # Get database options\n database_options = self._initialize_database_options()\n\n # Update cloud provider options\n env = self.environment\n template = build_config[\"database_name\"][\"dialog_inputs\"][\"fields\"][\"data\"][\"node\"][\"template\"]\n template[\"02_cloud_provider\"][\"options\"] = list(self.map_cloud_providers()[env].keys())\n\n # Update database configuration\n database_config = build_config[\"database_name\"]\n database_config.update(\n {\n \"options\": [db[\"name\"] for db in database_options],\n \"options_metadata\": [{k: v for k, v in db.items() if k != \"name\"} for db in database_options],\n }\n )\n\n # Reset selections if value not in options\n if database_config[\"value\"] not in database_config[\"options\"]:\n database_config[\"value\"] = \"\"\n build_config[\"api_endpoint\"][\"value\"] = \"\"\n build_config[\"collection_name\"][\"show\"] = False\n\n # Set advanced status based on token presence\n database_config[\"show\"] = bool(build_config[\"token\"][\"value\"])\n\n return build_config\n\n def reset_build_config(self, build_config: dict) -> dict:\n \"\"\"Reset all build configuration options to default empty state.\"\"\"\n # Reset database configuration\n database_config = build_config[\"database_name\"]\n database_config.update({\"options\": [], \"options_metadata\": [], \"value\": \"\", \"show\": False})\n build_config[\"api_endpoint\"][\"value\"] = \"\"\n\n # Reset collection configuration\n collection_config = build_config[\"collection_name\"]\n collection_config.update({\"options\": [], \"options_metadata\": [], \"value\": \"\", \"show\": False})\n\n return build_config\n\n def _handle_hybrid_search_options(self, build_config: dict) -> dict:\n \"\"\"Set hybrid search options in the build configuration.\"\"\"\n # Detect what hybrid options are available\n # Get the admin object\n client = DataAPIClient(environment=self.environment)\n admin_client = client.get_admin()\n db_admin = admin_client.get_database_admin(self.get_api_endpoint(), token=self.token)\n\n # We will try to get the reranking providers to see if its hybrid emabled\n try:\n providers = db_admin.find_reranking_providers()\n build_config[\"reranker\"][\"options\"] = [\n model.name for provider_data in providers.reranking_providers.values() for model in provider_data.models\n ]\n build_config[\"reranker\"][\"options_metadata\"] = [\n {\"icon\": self.get_provider_icon(provider_name=model.name.split(\"/\")[0])}\n for provider in providers.reranking_providers.values()\n for model in provider.models\n ]\n build_config[\"reranker\"][\"value\"] = build_config[\"reranker\"][\"options\"][0]\n\n # Set the default search field to hybrid search\n build_config[\"search_method\"][\"show\"] = True\n build_config[\"search_method\"][\"options\"] = [\"Hybrid Search\", \"Vector Search\"]\n build_config[\"search_method\"][\"value\"] = \"Hybrid Search\"\n except Exception as _: # noqa: BLE001\n build_config[\"reranker\"][\"options\"] = []\n build_config[\"reranker\"][\"options_metadata\"] = []\n\n # Set the default search field to vector search\n build_config[\"search_method\"][\"show\"] = False\n build_config[\"search_method\"][\"options\"] = [\"Vector Search\"]\n build_config[\"search_method\"][\"value\"] = \"Vector Search\"\n\n # Set reranker and lexical terms options based on search method\n build_config[\"reranker\"][\"toggle_value\"] = True\n build_config[\"reranker\"][\"show\"] = build_config[\"search_method\"][\"value\"] == \"Hybrid Search\"\n build_config[\"reranker\"][\"toggle_disable\"] = build_config[\"search_method\"][\"value\"] == \"Hybrid Search\"\n if build_config[\"reranker\"][\"show\"]:\n build_config[\"search_type\"][\"value\"] = \"Similarity\"\n\n return build_config\n\n async def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None) -> dict:\n \"\"\"Update build configuration based on field name and value.\"\"\"\n # Early return if no token provided\n if not self.token:\n return self.reset_build_config(build_config)\n\n # Database creation callback\n if field_name == \"database_name\" and isinstance(field_value, dict):\n if \"01_new_database_name\" in field_value:\n await self._create_new_database(build_config, field_value)\n return self.reset_collection_list(build_config)\n return self._update_cloud_regions(build_config, field_value)\n\n # Collection creation callback\n if field_name == \"collection_name\" and isinstance(field_value, dict):\n # Case 1: New collection creation\n if \"01_new_collection_name\" in field_value:\n await self._create_new_collection(build_config, field_value)\n return build_config\n\n # Case 2: Update embedding provider options\n if \"02_embedding_generation_provider\" in field_value:\n return self.reset_provider_options(build_config)\n\n # Case 3: Update dimension field\n if \"03_embedding_generation_model\" in field_value:\n return self.reset_dimension_field(build_config)\n\n # Initial execution or token/environment change\n first_run = field_name == \"collection_name\" and not field_value and not build_config[\"database_name\"][\"options\"]\n if first_run or field_name in {\"token\", \"environment\"}:\n return self.reset_database_list(build_config)\n\n # Database selection change\n if field_name == \"database_name\" and not isinstance(field_value, dict):\n return self._handle_database_selection(build_config, field_value)\n\n # Keyspace selection change\n if field_name == \"keyspace\":\n return self.reset_collection_list(build_config)\n\n # Collection selection change\n if field_name == \"collection_name\" and not isinstance(field_value, dict):\n return self._handle_collection_selection(build_config, field_value)\n\n # Search method selection change\n if field_name == \"search_method\":\n is_vector_search = field_value == \"Vector Search\"\n is_autodetect = build_config[\"autodetect_collection\"][\"value\"]\n\n # Configure lexical terms (same for both cases)\n build_config[\"lexical_terms\"][\"show\"] = not is_vector_search\n build_config[\"lexical_terms\"][\"value\"] = \"\" if is_vector_search else build_config[\"lexical_terms\"][\"value\"]\n\n # Disable reranker disabling if hybrid search is selected\n build_config[\"reranker\"][\"toggle_disable\"] = not is_vector_search\n build_config[\"reranker\"][\"toggle_value\"] = True\n build_config[\"reranker\"][\"value\"] = build_config[\"reranker\"][\"options\"][0]\n\n # Toggle search type and score threshold based on search method\n build_config[\"search_type\"][\"show\"] = is_vector_search\n build_config[\"search_score_threshold\"][\"show\"] = is_vector_search\n\n # Make sure the search_type is set to \"Similarity\"\n if not is_vector_search or is_autodetect:\n build_config[\"search_type\"][\"value\"] = \"Similarity\"\n\n return build_config\n\n async def _create_new_database(self, build_config: dict, field_value: dict) -> None:\n \"\"\"Create a new database and update build config options.\"\"\"\n try:\n await self.create_database_api(\n new_database_name=field_value[\"01_new_database_name\"],\n token=self.token,\n keyspace=self.get_keyspace(),\n environment=self.environment,\n cloud_provider=field_value[\"02_cloud_provider\"],\n region=field_value[\"03_region\"],\n )\n except Exception as e:\n msg = f\"Error creating database: {e}\"\n raise ValueError(msg) from e\n\n build_config[\"database_name\"][\"options\"].append(field_value[\"01_new_database_name\"])\n build_config[\"database_name\"][\"options_metadata\"].append(\n {\n \"status\": \"PENDING\",\n \"collections\": 0,\n \"api_endpoint\": None,\n \"keyspaces\": [self.get_keyspace()],\n \"org_id\": None,\n }\n )\n\n def _update_cloud_regions(self, build_config: dict, field_value: dict) -> dict:\n \"\"\"Update cloud provider regions in build config.\"\"\"\n env = self.environment\n cloud_provider = field_value[\"02_cloud_provider\"]\n\n # Update the region options based on the selected cloud provider\n template = build_config[\"database_name\"][\"dialog_inputs\"][\"fields\"][\"data\"][\"node\"][\"template\"]\n template[\"03_region\"][\"options\"] = self.map_cloud_providers()[env][cloud_provider][\"regions\"]\n\n # Reset the the 03_region value if it's not in the new options\n if template[\"03_region\"][\"value\"] not in template[\"03_region\"][\"options\"]:\n template[\"03_region\"][\"value\"] = None\n\n return build_config\n\n async def _create_new_collection(self, build_config: dict, field_value: dict) -> None:\n \"\"\"Create a new collection and update build config options.\"\"\"\n embedding_provider = field_value.get(\"02_embedding_generation_provider\")\n try:\n await self.create_collection_api(\n new_collection_name=field_value[\"01_new_collection_name\"],\n token=self.token,\n api_endpoint=build_config[\"api_endpoint\"][\"value\"],\n environment=self.environment,\n keyspace=self.get_keyspace(),\n dimension=field_value.get(\"04_dimension\") if embedding_provider == \"Bring your own\" else None,\n embedding_generation_provider=embedding_provider,\n embedding_generation_model=field_value.get(\"03_embedding_generation_model\"),\n reranker=self.reranker,\n )\n except Exception as e:\n msg = f\"Error creating collection: {e}\"\n raise ValueError(msg) from e\n\n provider = embedding_provider.lower() if embedding_provider and embedding_provider != \"Bring your own\" else None\n build_config[\"collection_name\"].update(\n {\n \"value\": field_value[\"01_new_collection_name\"],\n \"options\": build_config[\"collection_name\"][\"options\"] + [field_value[\"01_new_collection_name\"]],\n }\n )\n build_config[\"embedding_model\"][\"show\"] = not bool(provider)\n build_config[\"embedding_model\"][\"required\"] = not bool(provider)\n build_config[\"collection_name\"][\"options_metadata\"].append(\n {\n \"records\": 0,\n \"provider\": provider,\n \"icon\": self.get_provider_icon(provider_name=provider),\n \"model\": field_value.get(\"03_embedding_generation_model\"),\n }\n )\n\n # Make sure we always show the reranker options if the collection is hybrid enabled\n # And right now they always are\n build_config[\"lexical_terms\"][\"show\"] = True\n\n def _handle_database_selection(self, build_config: dict, field_value: str) -> dict:\n \"\"\"Handle database selection and update related configurations.\"\"\"\n build_config = self.reset_database_list(build_config)\n\n # Reset collection list if database selection changes\n if field_value not in build_config[\"database_name\"][\"options\"]:\n build_config[\"database_name\"][\"value\"] = \"\"\n return build_config\n\n # Get the api endpoint for the selected database\n index = build_config[\"database_name\"][\"options\"].index(field_value)\n build_config[\"api_endpoint\"][\"value\"] = build_config[\"database_name\"][\"options_metadata\"][index][\"api_endpoint\"]\n\n # Get the org_id for the selected database\n org_id = build_config[\"database_name\"][\"options_metadata\"][index][\"org_id\"]\n if not org_id:\n return build_config\n\n # Update the list of keyspaces based on the db info\n build_config[\"keyspace\"][\"options\"] = build_config[\"database_name\"][\"options_metadata\"][index][\"keyspaces\"]\n build_config[\"keyspace\"][\"value\"] = (\n build_config[\"keyspace\"][\"options\"] and build_config[\"keyspace\"][\"options\"][0]\n if build_config[\"keyspace\"][\"value\"] not in build_config[\"keyspace\"][\"options\"]\n else build_config[\"keyspace\"][\"value\"]\n )\n\n # Get the database id for the selected database\n db_id = self.get_database_id_static(api_endpoint=build_config[\"api_endpoint\"][\"value\"])\n keyspace = self.get_keyspace()\n\n # Update the helper text for the embedding provider field\n template = build_config[\"collection_name\"][\"dialog_inputs\"][\"fields\"][\"data\"][\"node\"][\"template\"]\n template[\"02_embedding_generation_provider\"][\"helper_text\"] = (\n \"To create collections with more embedding provider options, go to \"\n f''\n \"your database in Astra DB.\"\n )\n\n # Reset provider options\n build_config = self.reset_provider_options(build_config)\n\n # Handle hybrid search options\n build_config = self._handle_hybrid_search_options(build_config)\n\n return self.reset_collection_list(build_config)\n\n def _handle_collection_selection(self, build_config: dict, field_value: str) -> dict:\n \"\"\"Handle collection selection and update embedding options.\"\"\"\n build_config[\"autodetect_collection\"][\"value\"] = True\n build_config = self.reset_collection_list(build_config)\n\n # Reset embedding model if collection selection changes\n if field_value and field_value not in build_config[\"collection_name\"][\"options\"]:\n build_config[\"collection_name\"][\"options\"].append(field_value)\n build_config[\"collection_name\"][\"options_metadata\"].append(\n {\n \"records\": 0,\n \"provider\": None,\n \"icon\": \"vectorstores\",\n \"model\": None,\n }\n )\n build_config[\"autodetect_collection\"][\"value\"] = False\n\n if not field_value:\n return build_config\n\n # Get the selected collection index\n index = build_config[\"collection_name\"][\"options\"].index(field_value)\n\n # Set the provider of the selected collection\n provider = build_config[\"collection_name\"][\"options_metadata\"][index][\"provider\"]\n build_config[\"embedding_model\"][\"show\"] = not bool(provider)\n build_config[\"embedding_model\"][\"required\"] = not bool(provider)\n\n # Grab the collection object\n database = self.get_database_object(api_endpoint=build_config[\"api_endpoint\"][\"value\"])\n collection = database.get_collection(\n name=field_value,\n keyspace=build_config[\"keyspace\"][\"value\"],\n )\n\n # Check if hybrid and lexical are enabled\n col_options = collection.options()\n hyb_enabled = col_options.rerank and col_options.rerank.enabled\n lex_enabled = col_options.lexical and col_options.lexical.enabled\n user_hyb_enabled = build_config[\"search_method\"][\"value\"] == \"Hybrid Search\"\n\n # Show lexical terms if the collection is hybrid enabled\n build_config[\"lexical_terms\"][\"show\"] = hyb_enabled and lex_enabled and user_hyb_enabled\n\n return build_config\n\n @check_cached_vector_store\n def build_vector_store(self):\n try:\n from langchain_astradb import AstraDBVectorStore\n except ImportError as e:\n msg = (\n \"Could not import langchain Astra DB integration package. \"\n \"Please install it with `pip install langchain-astradb`.\"\n )\n raise ImportError(msg) from e\n\n # Get the embedding model and additional params\n embedding_params = {\"embedding\": self.embedding_model} if self.embedding_model else {}\n\n # Get the additional parameters\n additional_params = self.astradb_vectorstore_kwargs or {}\n\n # Get Langflow version and platform information\n __version__ = get_version_info()[\"version\"]\n langflow_prefix = \"\"\n # if os.getenv(\"AWS_EXECUTION_ENV\") == \"AWS_ECS_FARGATE\": # TODO: More precise way of detecting\n # langflow_prefix = \"ds-\"\n\n # Get the database object\n database = self.get_database_object()\n autodetect = self.collection_name in database.list_collection_names() and self.autodetect_collection\n\n # Bundle up the auto-detect parameters\n autodetect_params = {\n \"autodetect_collection\": autodetect,\n \"content_field\": (\n self.content_field\n if self.content_field and embedding_params\n else (\n \"page_content\"\n if embedding_params\n and self.collection_data(collection_name=self.collection_name, database=database) == 0\n else None\n )\n ),\n \"ignore_invalid_documents\": self.ignore_invalid_documents,\n }\n\n # Choose HybridSearchMode based on the selected param\n hybrid_search_mode = HybridSearchMode.DEFAULT if self.search_method == \"Hybrid Search\" else HybridSearchMode.OFF\n\n # Attempt to build the Vector Store object\n try:\n vector_store = AstraDBVectorStore(\n # Astra DB Authentication Parameters\n token=self.token,\n api_endpoint=database.api_endpoint,\n namespace=database.keyspace,\n collection_name=self.collection_name,\n environment=self.environment,\n # Hybrid Search Parameters\n hybrid_search=hybrid_search_mode,\n # Astra DB Usage Tracking Parameters\n ext_callers=[(f\"{langflow_prefix}langflow\", __version__)],\n # Astra DB Vector Store Parameters\n **autodetect_params,\n **embedding_params,\n **additional_params,\n )\n except Exception as e:\n msg = f\"Error initializing AstraDBVectorStore: {e}\"\n raise ValueError(msg) from e\n\n # Add documents to the vector store\n self._add_documents_to_vector_store(vector_store)\n\n return vector_store\n\n def _add_documents_to_vector_store(self, vector_store) -> None:\n self.ingest_data = self._prepare_ingest_data()\n\n documents = []\n for _input in self.ingest_data or []:\n if isinstance(_input, Data):\n documents.append(_input.to_lc_document())\n else:\n msg = \"Vector Store Inputs must be Data objects.\"\n raise TypeError(msg)\n\n if documents and self.deletion_field:\n self.log(f\"Deleting documents where {self.deletion_field}\")\n try:\n database = self.get_database_object()\n collection = database.get_collection(self.collection_name, keyspace=database.keyspace)\n delete_values = list({doc.metadata[self.deletion_field] for doc in documents})\n self.log(f\"Deleting documents where {self.deletion_field} matches {delete_values}.\")\n collection.delete_many({f\"metadata.{self.deletion_field}\": {\"$in\": delete_values}})\n except Exception as e:\n msg = f\"Error deleting documents from AstraDBVectorStore based on '{self.deletion_field}': {e}\"\n raise ValueError(msg) from e\n\n if documents:\n self.log(f\"Adding {len(documents)} documents to the Vector Store.\")\n try:\n vector_store.add_documents(documents)\n except Exception as e:\n msg = f\"Error adding documents to AstraDBVectorStore: {e}\"\n raise ValueError(msg) from e\n else:\n self.log(\"No documents to add to the Vector Store.\")\n\n def _map_search_type(self) -> str:\n search_type_mapping = {\n \"Similarity with score threshold\": \"similarity_score_threshold\",\n \"MMR (Max Marginal Relevance)\": \"mmr\",\n }\n\n return search_type_mapping.get(self.search_type, \"similarity\")\n\n def _build_search_args(self):\n # Clean up the search query\n query = self.search_query if isinstance(self.search_query, str) and self.search_query.strip() else None\n lexical_terms = self.lexical_terms or None\n\n # Check if we have a search query, and if so set the args\n if query:\n args = {\n \"query\": query,\n \"search_type\": self._map_search_type(),\n \"k\": self.number_of_results,\n \"score_threshold\": self.search_score_threshold,\n \"lexical_query\": lexical_terms,\n }\n elif self.advanced_search_filter:\n args = {\n \"n\": self.number_of_results,\n }\n else:\n return {}\n\n filter_arg = self.advanced_search_filter or {}\n if filter_arg:\n args[\"filter\"] = filter_arg\n\n return args\n\n def search_documents(self, vector_store=None) -> list[Data]:\n vector_store = vector_store or self.build_vector_store()\n\n self.log(f\"Search input: {self.search_query}\")\n self.log(f\"Search type: {self.search_type}\")\n self.log(f\"Number of results: {self.number_of_results}\")\n self.log(f\"store.hybrid_search: {vector_store.hybrid_search}\")\n self.log(f\"Lexical terms: {self.lexical_terms}\")\n self.log(f\"Reranker: {self.reranker}\")\n\n try:\n search_args = self._build_search_args()\n except Exception as e:\n msg = f\"Error in AstraDBVectorStore._build_search_args: {e}\"\n raise ValueError(msg) from e\n\n if not search_args:\n self.log(\"No search input or filters provided. Skipping search.\")\n return []\n\n docs = []\n search_method = \"search\" if \"query\" in search_args else \"metadata_search\"\n\n try:\n self.log(f\"Calling vector_store.{search_method} with args: {search_args}\")\n docs = getattr(vector_store, search_method)(**search_args)\n except Exception as e:\n msg = f\"Error performing {search_method} in AstraDBVectorStore: {e}\"\n raise ValueError(msg) from e\n\n self.log(f\"Retrieved documents: {len(docs)}\")\n\n data = docs_to_data(docs)\n self.log(f\"Converted documents to data: {len(data)}\")\n self.status = data\n\n return data\n\n def get_retriever_kwargs(self):\n search_args = self._build_search_args()\n\n return {\n \"search_type\": self._map_search_type(),\n \"search_kwargs\": search_args,\n }\n" + }, + "collection_name": { + "_input_type": "DropdownInput", + "advanced": false, + "combobox": true, + "dialog_inputs": { + "fields": { + "data": { + "node": { + "description": "Please allow several seconds for creation to complete.", + "display_name": "Create new collection", + "field_order": [ + "01_new_collection_name", + "02_embedding_generation_provider", + "03_embedding_generation_model", + "04_dimension" + ], + "name": "create_collection", + "template": { + "01_new_collection_name": { + "_input_type": "StrInput", + "advanced": false, + "display_name": "Name", + "dynamic": false, + "info": "Name of the new collection to create in Astra DB.", + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "new_collection_name", + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "02_embedding_generation_provider": { + "_input_type": "DropdownInput", + "advanced": false, + "combobox": false, + "dialog_inputs": {}, + "display_name": "Embedding generation method", + "dynamic": false, + "helper_text": "To create collections with more embedding provider options, go to your database in Astra DB.", + "info": "Provider to use for generating embeddings.", + "name": "embedding_generation_provider", + "options": [ + "Bring your own", + "Nvidia" + ], + "options_metadata": [ + { + "icon": "vectorstores" + }, + { + "icon": "NVIDIA" + } + ], + "placeholder": "", + "real_time_refresh": true, + "required": true, + "show": true, + "title_case": false, + "toggle": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "03_embedding_generation_model": { + "_input_type": "DropdownInput", + "advanced": false, + "combobox": false, + "dialog_inputs": {}, + "display_name": "Embedding model", + "dynamic": false, + "info": "Model to use for generating embeddings.", + "name": "embedding_generation_model", + "options": [], + "options_metadata": [], + "placeholder": null, + "readonly": "", + "real_time_refresh": true, + "required": true, + "show": true, + "title_case": false, + "toggle": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": null + }, + "04_dimension": { + "_input_type": "IntInput", + "advanced": false, + "display_name": "Dimensions", + "dynamic": false, + "info": "Dimensions of the embeddings to generate.", + "list": false, + "list_add_label": "Add More", + "name": "dimension", + "placeholder": 1024, + "readonly": true, + "required": "", + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "int", + "value": 1024 + } + } + } + } + }, + "functionality": "create" + }, + "display_name": "Collection", + "dynamic": false, + "info": "The name of the collection within Astra DB where the vectors will be stored.", + "load_from_db": false, + "name": "collection_name", + "options": [], + "options_metadata": [], + "placeholder": "", + "real_time_refresh": true, + "refresh_button": true, + "required": true, + "show": true, + "title_case": false, + "toggle": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "content_field": { + "_input_type": "StrInput", + "advanced": true, + "display_name": "Content Field", + "dynamic": false, + "info": "Field to use as the text content field for the vector store.", + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "content_field", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "database_name": { + "_input_type": "DropdownInput", + "advanced": false, + "combobox": true, + "dialog_inputs": { + "fields": { + "data": { + "node": { + "description": "Please allow several minutes for creation to complete.", + "display_name": "Create new database", + "field_order": [ + "01_new_database_name", + "02_cloud_provider", + "03_region" + ], + "name": "create_database", + "template": { + "01_new_database_name": { + "_input_type": "StrInput", + "advanced": false, + "display_name": "Name", + "dynamic": false, + "info": "Name of the new database to create in Astra DB.", + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "new_database_name", + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "02_cloud_provider": { + "_input_type": "DropdownInput", + "advanced": false, + "combobox": false, + "dialog_inputs": {}, + "display_name": "Cloud provider", + "dynamic": false, + "info": "Cloud provider for the new database.", + "name": "cloud_provider", + "options": [ + "Amazon Web Services", + "Google Cloud Platform", + "Microsoft Azure" + ], + "options_metadata": [], + "placeholder": "", + "real_time_refresh": true, + "required": true, + "show": true, + "title_case": false, + "toggle": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "03_region": { + "_input_type": "DropdownInput", + "advanced": false, + "combobox": false, + "dialog_inputs": {}, + "display_name": "Region", + "dynamic": false, + "info": "Region for the new database.", + "name": "region", + "options": [], + "options_metadata": [], + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "toggle": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + } + } + } + } + }, + "functionality": "create" + }, + "display_name": "Database", + "dynamic": false, + "info": "The Database name for the Astra DB instance.", + "load_from_db": false, + "name": "database_name", + "options": [], + "options_metadata": [], + "placeholder": "", + "real_time_refresh": true, + "refresh_button": true, + "required": true, + "show": true, + "title_case": false, + "toggle": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "deletion_field": { + "_input_type": "StrInput", + "advanced": true, + "display_name": "Deletion Based On Field", + "dynamic": false, + "info": "When this parameter is provided, documents in the target collection with metadata field values matching the input metadata field value will be deleted before new data is loaded.", + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "deletion_field", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "embedding_model": { + "_input_type": "HandleInput", + "advanced": false, + "display_name": "Embedding Model", + "dynamic": false, + "info": "Specify the Embedding Model. Not required for Astra Vectorize collections.", + "input_types": [ + "Embeddings" + ], + "list": false, + "list_add_label": "Add More", + "name": "embedding_model", + "placeholder": "", + "required": false, + "show": false, + "title_case": false, + "trace_as_metadata": true, + "type": "other", + "value": "" + }, + "environment": { + "_input_type": "DropdownInput", + "advanced": true, + "combobox": true, + "dialog_inputs": {}, + "display_name": "Environment", + "dynamic": false, + "info": "The environment for the Astra DB API Endpoint.", + "name": "environment", + "options": [ + "prod", + "test", + "dev" + ], + "options_metadata": [], + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, + "title_case": false, + "toggle": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "prod" + }, + "ignore_invalid_documents": { + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Ignore Invalid Documents", + "dynamic": false, + "info": "Boolean flag to determine whether to ignore invalid documents at runtime.", + "list": false, + "list_add_label": "Add More", + "name": "ignore_invalid_documents", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "ingest_data": { + "_input_type": "HandleInput", + "advanced": false, + "display_name": "Ingest Data", + "dynamic": false, + "info": "", + "input_types": [ + "Data", + "DataFrame" + ], + "list": true, + "list_add_label": "Add More", + "name": "ingest_data", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "other", + "value": "" + }, + "keyspace": { + "_input_type": "DropdownInput", + "advanced": true, + "combobox": false, + "dialog_inputs": {}, + "display_name": "Keyspace", + "dynamic": false, + "info": "Optional keyspace within Astra DB to use for the collection.", + "load_from_db": false, + "name": "keyspace", + "options": [], + "options_metadata": [], + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, + "title_case": false, + "toggle": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "default_keyspace" + }, + "lexical_terms": { + "_input_type": "QueryInput", + "advanced": false, + "display_name": "Lexical Terms", + "dynamic": false, + "info": "Add additional terms/keywords to augment search precision.", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "lexical_terms", + "placeholder": "Enter terms to search...", + "required": false, + "separator": " ", + "show": false, + "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "query", + "value": "" + }, + "number_of_results": { + "_input_type": "IntInput", + "advanced": true, + "display_name": "Number of Search Results", + "dynamic": false, + "info": "Number of search results to return.", + "list": false, + "list_add_label": "Add More", + "name": "number_of_results", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "int", + "value": 4 + }, + "reranker": { + "_input_type": "DropdownInput", + "advanced": false, + "combobox": false, + "dialog_inputs": {}, + "display_name": "Reranker", + "dynamic": false, + "info": "Post-retrieval model that re-scores results for optimal relevance ranking.", + "load_from_db": false, + "name": "reranker", + "options": [], + "options_metadata": [ + { + "icon": "NVIDIA" + } + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "toggle": true, + "toggle_disable": true, + "toggle_value": true, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "nvidia/llama-3.2-nv-rerankqa-1b-v2" + }, + "search_method": { + "_input_type": "DropdownInput", + "advanced": true, + "combobox": false, + "dialog_inputs": {}, + "display_name": "Search Method", + "dynamic": false, + "info": "Determine how your content is matched: Vector finds semantic similarity, and Hybrid Search (suggested) combines both approaches with a reranker.", + "load_from_db": false, + "name": "search_method", + "options": [ + "Hybrid Search", + "Vector Search" + ], + "options_metadata": [ + { + "icon": "SearchHybrid" + }, + { + "icon": "SearchVector" + } + ], + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, + "title_case": false, + "toggle": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "Hybrid Search" + }, + "search_query": { + "_input_type": "QueryInput", + "advanced": false, + "display_name": "Search Query", + "dynamic": false, + "info": "Enter a query to run a similarity search.", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "search_query", + "placeholder": "Enter a query...", + "required": false, + "show": true, + "title_case": false, + "tool_mode": true, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "query", + "value": "" + }, + "search_score_threshold": { + "_input_type": "FloatInput", + "advanced": true, + "display_name": "Search Score Threshold", + "dynamic": false, + "info": "Minimum similarity score threshold for search results. (when using 'Similarity with score threshold')", + "list": false, + "list_add_label": "Add More", + "name": "search_score_threshold", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "float", + "value": 0 + }, + "search_type": { + "_input_type": "DropdownInput", + "advanced": true, + "combobox": false, + "dialog_inputs": {}, + "display_name": "Search Type", + "dynamic": false, + "info": "Search type to use", + "name": "search_type", + "options": [ + "Similarity", + "Similarity with score threshold", + "MMR (Max Marginal Relevance)" + ], + "options_metadata": [], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "toggle": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "Similarity" + }, + "should_cache_vector_store": { + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Cache Vector Store", + "dynamic": false, + "info": "If True, the vector store will be cached for the current build of the component. This is useful for components that have multiple output methods and want to share the same vector store.", + "list": false, + "list_add_label": "Add More", + "name": "should_cache_vector_store", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "bool", + "value": true + }, + "token": { + "_input_type": "SecretStrInput", + "advanced": false, + "display_name": "Astra DB Application Token", + "dynamic": false, + "info": "Authentication token for accessing Astra DB.", + "input_types": [], + "load_from_db": true, + "name": "token", + "password": true, + "placeholder": "", + "real_time_refresh": true, + "required": true, + "show": true, + "title_case": false, + "type": "str", + "value": "ASTRA_DB_APPLICATION_TOKEN" + } + }, + "tool_mode": false + }, + "selected_output": "dataframe", + "showNode": true, + "type": "AstraDB" + }, + "dragging": false, + "id": "AstraDB-8MbYw", + "measured": { + "height": 603, + "width": 320 + }, + "position": { + "x": 1548.269269836593, + "y": 162.5619344372189 + }, + "selected": false, + "type": "genericNode" + }, + { + "data": { + "id": "LanguageModelComponent-CXvuM", + "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\": \"Google\"}],\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": "You are an AI system designed to extract structured information from unstructured text.Given the input_text, return a JSON object with predefined keys based on the expected structure.Extract values accurately and format them according to the specified type (e.g., string, integer, float, date).If a value is missing or cannot be determined, return a default (e.g., null, 0, or 'N/A').If multiple instances of the expected structure exist within the input_text, stream each as a separate JSON object." + }, + "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": "OpenAI" + }, + { + "icon": "Anthropic" + }, + { + "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": true, + "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": "" + }, + "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-CXvuM", + "measured": { + "height": 450, + "width": 320 + }, + "position": { + "x": 320.756607335245, + "y": 486.0770655861057 + }, + "selected": false, + "type": "genericNode" + }, + { + "data": { + "id": "LanguageModelComponent-3anZE", + "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\": \"Google\"}],\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": "OpenAI" + }, + { + "icon": "Anthropic" + }, + { + "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": true, + "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": "" + }, + "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 + }, + "selected_output": "model_output", + "showNode": true, + "type": "LanguageModelComponent" + }, + "dragging": false, + "id": "LanguageModelComponent-3anZE", + "measured": { + "height": 450, + "width": 320 + }, + "position": { + "x": 322.5971643968167, + "y": -36.64113990031162 + }, + "selected": false, + "type": "genericNode" + }, + { + "data": { + "id": "StructuredOutput-38AOi", + "node": { + "base_classes": [ + "Data" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Uses an LLM to generate structured data. Ideal for extraction and consistency.", + "display_name": "Structured Output", + "documentation": "", + "edited": false, + "field_order": [ + "llm", + "input_value", + "system_prompt", + "schema_name", + "output_schema" + ], + "frozen": false, + "icon": "braces", + "legacy": false, + "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "allows_loop": false, + "cache": true, + "display_name": "Structured Output", + "group_outputs": false, + "method": "build_structured_output", + "name": "structured_output", + "selected": "Data", + "tool_mode": true, + "types": [ + "Data" + ], + "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 pydantic import BaseModel, Field, create_model\nfrom trustcall import create_extractor\n\nfrom langflow.base.models.chat_result import get_chat_result\nfrom langflow.custom.custom_component.component import Component\nfrom langflow.helpers.base_model import build_model_from_schema\nfrom langflow.io import (\n HandleInput,\n MessageTextInput,\n MultilineInput,\n Output,\n TableInput,\n)\nfrom langflow.schema.data import Data\nfrom langflow.schema.table import EditMode\n\n\nclass StructuredOutputComponent(Component):\n display_name = \"Structured Output\"\n description = \"Uses an LLM to generate structured data. Ideal for extraction and consistency.\"\n name = \"StructuredOutput\"\n icon = \"braces\"\n\n inputs = [\n HandleInput(\n name=\"llm\",\n display_name=\"Language Model\",\n info=\"The language model to use to generate the structured output.\",\n input_types=[\"LanguageModel\"],\n required=True,\n ),\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input Message\",\n info=\"The input message to the language model.\",\n tool_mode=True,\n required=True,\n ),\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"Format Instructions\",\n info=\"The instructions to the language model for formatting the output.\",\n value=(\n \"You are an AI that extracts one structured JSON object from unstructured text. \"\n \"Use a predefined schema with expected types (str, int, float, bool, dict). \"\n \"If multiple structures exist, extract only the first most complete one. \"\n \"Fill missing or ambiguous values with defaults: null for missing values. \"\n \"Ignore duplicates and partial repeats. \"\n \"Always return one valid JSON, never throw errors or return multiple objects.\"\n \"Output: A single well-formed JSON object, and nothing else.\"\n ),\n required=True,\n advanced=True,\n ),\n MessageTextInput(\n name=\"schema_name\",\n display_name=\"Schema Name\",\n info=\"Provide a name for the output data schema.\",\n advanced=True,\n ),\n TableInput(\n name=\"output_schema\",\n display_name=\"Output Schema\",\n info=\"Define the structure and data types for the model's output.\",\n required=True,\n # TODO: remove deault value\n table_schema=[\n {\n \"name\": \"name\",\n \"display_name\": \"Name\",\n \"type\": \"str\",\n \"description\": \"Specify the name of the output field.\",\n \"default\": \"field\",\n \"edit_mode\": EditMode.INLINE,\n },\n {\n \"name\": \"description\",\n \"display_name\": \"Description\",\n \"type\": \"str\",\n \"description\": \"Describe the purpose of the output field.\",\n \"default\": \"description of field\",\n \"edit_mode\": EditMode.POPOVER,\n },\n {\n \"name\": \"type\",\n \"display_name\": \"Type\",\n \"type\": \"str\",\n \"edit_mode\": EditMode.INLINE,\n \"description\": (\"Indicate the data type of the output field (e.g., str, int, float, bool, dict).\"),\n \"options\": [\"str\", \"int\", \"float\", \"bool\", \"dict\"],\n \"default\": \"str\",\n },\n {\n \"name\": \"multiple\",\n \"display_name\": \"As List\",\n \"type\": \"boolean\",\n \"description\": \"Set to True if this output field should be a list of the specified type.\",\n \"default\": \"False\",\n \"edit_mode\": EditMode.INLINE,\n },\n ],\n value=[\n {\n \"name\": \"field\",\n \"description\": \"description of field\",\n \"type\": \"str\",\n \"multiple\": \"False\",\n }\n ],\n ),\n ]\n\n outputs = [\n Output(\n name=\"structured_output\",\n display_name=\"Structured Output\",\n method=\"build_structured_output\",\n ),\n ]\n\n def build_structured_output_base(self):\n schema_name = self.schema_name or \"OutputModel\"\n\n if not hasattr(self.llm, \"with_structured_output\"):\n msg = \"Language model does not support structured output.\"\n raise TypeError(msg)\n if not self.output_schema:\n msg = \"Output schema cannot be empty\"\n raise ValueError(msg)\n\n output_model_ = build_model_from_schema(self.output_schema)\n\n output_model = create_model(\n schema_name,\n __doc__=f\"A list of {schema_name}.\",\n objects=(list[output_model_], Field(description=f\"A list of {schema_name}.\")), # type: ignore[valid-type]\n )\n\n try:\n llm_with_structured_output = create_extractor(self.llm, tools=[output_model])\n except NotImplementedError as exc:\n msg = f\"{self.llm.__class__.__name__} does not support structured output.\"\n raise TypeError(msg) from exc\n\n config_dict = {\n \"run_name\": self.display_name,\n \"project_name\": self.get_project_name(),\n \"callbacks\": self.get_langchain_callbacks(),\n }\n result = get_chat_result(\n runnable=llm_with_structured_output,\n system_message=self.system_prompt,\n input_value=self.input_value,\n config=config_dict,\n )\n\n # OPTIMIZATION NOTE: Simplified processing based on trustcall response structure\n # Handle non-dict responses (shouldn't happen with trustcall, but defensive)\n if not isinstance(result, dict):\n return result\n\n # Extract first response and convert BaseModel to dict\n responses = result.get(\"responses\", [])\n if not responses:\n return result\n\n # Convert BaseModel to dict (creates the \"objects\" key)\n first_response = responses[0]\n structured_data = first_response.model_dump() if isinstance(first_response, BaseModel) else first_response\n\n # Extract the objects array (guaranteed to exist due to our Pydantic model structure)\n return structured_data.get(\"objects\", structured_data)\n\n def build_structured_output(self) -> Data:\n output = self.build_structured_output_base()\n if not isinstance(output, list) or not output:\n # handle empty or unexpected type case\n msg = \"No structured output returned\"\n raise ValueError(msg)\n if len(output) != 1:\n msg = \"Multiple structured outputs returned\"\n raise ValueError(msg)\n return Data(data=output[0])\n" + }, + "input_value": { + "_input_type": "MessageTextInput", + "advanced": false, + "display_name": "Input Message", + "dynamic": false, + "info": "The input message to the language model.", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "input_value", + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "tool_mode": true, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "llm": { + "_input_type": "HandleInput", + "advanced": false, + "display_name": "Language Model", + "dynamic": false, + "info": "The language model to use to generate the structured output.", + "input_types": [ + "LanguageModel" + ], + "list": false, + "list_add_label": "Add More", + "name": "llm", + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "other", + "value": "" + }, + "output_schema": { + "_input_type": "TableInput", + "advanced": false, + "display_name": "Output Schema", + "dynamic": false, + "info": "Define the structure and data types for the model's output.", + "is_list": true, + "list_add_label": "Add More", + "name": "output_schema", + "placeholder": "", + "required": true, + "show": true, + "table_icon": "Table", + "table_schema": { + "columns": [ + { + "default": "field", + "description": "Specify the name of the output field.", + "disable_edit": false, + "display_name": "Name", + "edit_mode": "inline", + "filterable": true, + "formatter": "text", + "hidden": false, + "name": "name", + "sortable": true, + "type": "str" + }, + { + "default": "description of field", + "description": "Describe the purpose of the output field.", + "disable_edit": false, + "display_name": "Description", + "edit_mode": "popover", + "filterable": true, + "formatter": "text", + "hidden": false, + "name": "description", + "sortable": true, + "type": "str" + }, + { + "default": "str", + "description": "Indicate the data type of the output field (e.g., str, int, float, bool, dict).", + "disable_edit": false, + "display_name": "Type", + "edit_mode": "inline", + "filterable": true, + "formatter": "text", + "hidden": false, + "name": "type", + "options": [ + "str", + "int", + "float", + "bool", + "dict" + ], + "sortable": true, + "type": "str" + }, + { + "default": false, + "description": "Set to True if this output field should be a list of the specified type.", + "disable_edit": false, + "display_name": "As List", + "edit_mode": "inline", + "filterable": true, + "formatter": "boolean", + "hidden": false, + "name": "multiple", + "sortable": true, + "type": "boolean" + } + ] + }, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "trigger_icon": "Table", + "trigger_text": "Open table", + "type": "table", + "value": [ + { + "description": "description of field", + "multiple": "False", + "name": "field", + "type": "str" + } + ] + }, + "schema_name": { + "_input_type": "MessageTextInput", + "advanced": true, + "display_name": "Schema Name", + "dynamic": false, + "info": "Provide a name for the output data schema.", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "schema_name", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "system_prompt": { + "_input_type": "MultilineInput", + "advanced": true, + "copy_field": false, + "display_name": "Format Instructions", + "dynamic": false, + "info": "The instructions to the language model for formatting the output.", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "multiline": true, + "name": "system_prompt", + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "You are an AI system designed to extract structured information from unstructured text.Given the input_text, return a JSON object with predefined keys based on the expected structure.Extract values accurately and format them according to the specified type (e.g., string, integer, float, date).If a value is missing or cannot be determined, return a default (e.g., null, 0, or 'N/A').If multiple instances of the expected structure exist within the input_text, stream each as a separate JSON object." + } + }, + "tool_mode": false + }, + "showNode": true, + "type": "StructuredOutput" + }, + "dragging": false, + "id": "StructuredOutput-38AOi", + "measured": { + "height": 348, + "width": 320 + }, + "position": { + "x": 735.3215653605321, + "y": 423.7970360460631 + }, + "selected": false, "type": "genericNode" } ], "viewport": { - "x": -67.37260947004211, - "y": 117.51074540050547, - "zoom": 0.5728040781386226 + "x": 104.19697716143673, + "y": 93.92237895963603, + "zoom": 0.5685314513072638 } }, "description": "Uncover Business Opportunities with NLP.", "endpoint_name": null, - "id": "5a023d0b-da61-4042-abb7-a16c2b88ac72", + "id": "0e2f686f-3f13-4e45-bf2e-0da08d8239cc", "is_component": false, - "last_tested_version": "1.3.2", + "last_tested_version": "1.4.3", "name": "Hybrid Search RAG", "tags": [ "openai", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json b/src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json index 940d7efda..ff874ff36 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json @@ -7,7 +7,7 @@ "data": { "sourceHandle": { "dataType": "parser", - "id": "parser-o6H8E", + "id": "parser-Z6kPy", "name": "parsed_text", "output_types": [ "Message" @@ -15,7 +15,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-WVlr5", + "id": "ChatOutput-mm3yo", "inputTypes": [ "Data", "DataFrame", @@ -24,12 +24,12 @@ "type": "str" } }, - "id": "reactflow__edge-parser-o6H8E{œdataTypeœ:œparserœ,œidœ:œparser-o6H8Eœ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-WVlr5{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-WVlr5œ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-parser-Z6kPy{œdataTypeœ:œparserœ,œidœ:œparser-Z6kPyœ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-mm3yo{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-mm3yoœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "parser-o6H8E", - "sourceHandle": "{œdataTypeœ: œparserœ, œidœ: œparser-o6H8Eœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-WVlr5", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-WVlr5œ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" + "source": "parser-Z6kPy", + "sourceHandle": "{œdataTypeœ: œparserœ, œidœ: œparser-Z6kPyœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-mm3yo", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-mm3yoœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -37,7 +37,7 @@ "data": { "sourceHandle": { "dataType": "StructuredOutput", - "id": "StructuredOutput-eoFyT", + "id": "StructuredOutput-93GZ3", "name": "structured_output", "output_types": [ "Data" @@ -45,7 +45,7 @@ }, "targetHandle": { "fieldName": "input_data", - "id": "parser-o6H8E", + "id": "parser-Z6kPy", "inputTypes": [ "DataFrame", "Data" @@ -53,40 +53,12 @@ "type": "other" } }, - "id": "reactflow__edge-StructuredOutput-eoFyT{œdataTypeœ:œStructuredOutputœ,œidœ:œStructuredOutput-eoFyTœ,œnameœ:œstructured_outputœ,œoutput_typesœ:[œDataœ]}-parser-o6H8E{œfieldNameœ:œinput_dataœ,œidœ:œparser-o6H8Eœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-StructuredOutput-93GZ3{œdataTypeœ:œStructuredOutputœ,œidœ:œStructuredOutput-93GZ3œ,œnameœ:œstructured_outputœ,œoutput_typesœ:[œDataœ]}-parser-Z6kPy{œfieldNameœ:œinput_dataœ,œidœ:œparser-Z6kPyœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", "selected": false, - "source": "StructuredOutput-eoFyT", - "sourceHandle": "{œdataTypeœ: œStructuredOutputœ, œidœ: œStructuredOutput-eoFyTœ, œnameœ: œstructured_outputœ, œoutput_typesœ: [œDataœ]}", - "target": "parser-o6H8E", - "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œparser-o6H8Eœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "LanguageModelComponent", - "id": "LanguageModelComponent-2h2qm", - "name": "model_output", - "output_types": [ - "LanguageModel" - ] - }, - "targetHandle": { - "fieldName": "llm", - "id": "StructuredOutput-eoFyT", - "inputTypes": [ - "LanguageModel" - ], - "type": "other" - } - }, - "id": "reactflow__edge-LanguageModelComponent-2h2qm{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-2h2qmœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}-StructuredOutput-eoFyT{œfieldNameœ:œllmœ,œidœ:œStructuredOutput-eoFyTœ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}", - "selected": false, - "source": "LanguageModelComponent-2h2qm", - "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-2h2qmœ, œnameœ: œmodel_outputœ, œoutput_typesœ: [œLanguageModelœ]}", - "target": "StructuredOutput-eoFyT", - "targetHandle": "{œfieldNameœ: œllmœ, œidœ: œStructuredOutput-eoFyTœ, œinputTypesœ: [œLanguageModelœ], œtypeœ: œotherœ}" + "source": "StructuredOutput-93GZ3", + "sourceHandle": "{œdataTypeœ: œStructuredOutputœ, œidœ: œStructuredOutput-93GZ3œ, œnameœ: œstructured_outputœ, œoutput_typesœ: [œDataœ]}", + "target": "parser-Z6kPy", + "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œparser-Z6kPyœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -94,7 +66,7 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-ElcZb", + "id": "Prompt-9gGBt", "name": "prompt", "output_types": [ "Message" @@ -102,47 +74,19 @@ }, "targetHandle": { "fieldName": "system_message", - "id": "LanguageModelComponent-YHUqJ", + "id": "LanguageModelComponent-1KtUQ", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-ElcZb{œdataTypeœ:œPromptœ,œidœ:œPrompt-ElcZbœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-YHUqJ{œfieldNameœ:œsystem_messageœ,œidœ:œLanguageModelComponent-YHUqJœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Prompt-9gGBt{œdataTypeœ:œPromptœ,œidœ:œPrompt-9gGBtœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-1KtUQ{œfieldNameœ:œsystem_messageœ,œidœ:œLanguageModelComponent-1KtUQœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-ElcZb", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-ElcZbœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "LanguageModelComponent-YHUqJ", - "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œLanguageModelComponent-YHUqJœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-CbbPG", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "LanguageModelComponent-YHUqJ", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-CbbPG{œdataTypeœ:œChatInputœ,œidœ:œChatInput-CbbPGœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-YHUqJ{œfieldNameœ:œinput_valueœ,œidœ:œLanguageModelComponent-YHUqJœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ChatInput-CbbPG", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-CbbPGœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "LanguageModelComponent-YHUqJ", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œLanguageModelComponent-YHUqJœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-9gGBt", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-9gGBtœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-1KtUQ", + "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œLanguageModelComponent-1KtUQœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -150,7 +94,7 @@ "data": { "sourceHandle": { "dataType": "LanguageModelComponent", - "id": "LanguageModelComponent-YHUqJ", + "id": "LanguageModelComponent-1KtUQ", "name": "text_output", "output_types": [ "Message" @@ -158,19 +102,103 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "StructuredOutput-eoFyT", + "id": "StructuredOutput-93GZ3", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-LanguageModelComponent-YHUqJ{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-YHUqJœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-StructuredOutput-eoFyT{œfieldNameœ:œinput_valueœ,œidœ:œStructuredOutput-eoFyTœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-LanguageModelComponent-1KtUQ{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-1KtUQœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-StructuredOutput-93GZ3{œfieldNameœ:œinput_valueœ,œidœ:œStructuredOutput-93GZ3œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "LanguageModelComponent-YHUqJ", - "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-YHUqJœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "StructuredOutput-eoFyT", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œStructuredOutput-eoFyTœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "LanguageModelComponent-1KtUQ", + "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-1KtUQœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "StructuredOutput-93GZ3", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œStructuredOutput-93GZ3œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-9gGBt", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "LanguageModelComponent-t4Dhl", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "xy-edge__Prompt-9gGBt{œdataTypeœ:œPromptœ,œidœ:œPrompt-9gGBtœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-t4Dhl{œfieldNameœ:œinput_valueœ,œidœ:œLanguageModelComponent-t4Dhlœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "Prompt-9gGBt", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-9gGBtœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-t4Dhl", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œLanguageModelComponent-t4Dhlœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-MmdjK", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "LanguageModelComponent-1KtUQ", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "xy-edge__ChatInput-MmdjK{œdataTypeœ:œChatInputœ,œidœ:œChatInput-MmdjKœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-1KtUQ{œfieldNameœ:œinput_valueœ,œidœ:œLanguageModelComponent-1KtUQœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "ChatInput-MmdjK", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-MmdjKœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-1KtUQ", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œLanguageModelComponent-1KtUQœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "LanguageModelComponent", + "id": "LanguageModelComponent-t4Dhl", + "name": "model_output", + "output_types": [ + "LanguageModel" + ] + }, + "targetHandle": { + "fieldName": "llm", + "id": "StructuredOutput-93GZ3", + "inputTypes": [ + "LanguageModel" + ], + "type": "other" + } + }, + "id": "xy-edge__LanguageModelComponent-t4Dhl{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-t4Dhlœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}-StructuredOutput-93GZ3{œfieldNameœ:œllmœ,œidœ:œStructuredOutput-93GZ3œ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}", + "selected": false, + "source": "LanguageModelComponent-t4Dhl", + "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-t4Dhlœ, œnameœ: œmodel_outputœ, œoutput_typesœ: [œLanguageModelœ]}", + "target": "StructuredOutput-93GZ3", + "targetHandle": "{œfieldNameœ: œllmœ, œidœ: œStructuredOutput-93GZ3œ, œinputTypesœ: [œLanguageModelœ], œtypeœ: œotherœ}" } ], "nodes": [ @@ -178,7 +206,7 @@ "data": { "description": "Get chat inputs from the Playground.", "display_name": "Chat Input", - "id": "ChatInput-CbbPG", + "id": "ChatInput-MmdjK", "node": { "base_classes": [ "Message" @@ -462,7 +490,7 @@ }, "dragging": false, "height": 234, - "id": "ChatInput-CbbPG", + "id": "ChatInput-MmdjK", "measured": { "height": 234, "width": 320 @@ -483,7 +511,7 @@ "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-WVlr5", + "id": "ChatOutput-mm3yo", "node": { "base_classes": [ "Message" @@ -766,7 +794,7 @@ }, "dragging": false, "height": 234, - "id": "ChatOutput-WVlr5", + "id": "ChatOutput-mm3yo", "measured": { "height": 234, "width": 320 @@ -785,9 +813,9 @@ }, { "data": { - "id": "note-k9mrI", + "id": "note-tC1fr", "node": { - "description": "# Image Sentiment Analysis\nWelcome to the Image Sentiment Classifier - an AI tool for quick image sentiment analysis!\n\n## Instructions\n\n1. **Prepare Your Image**\n - Image should be clear and visible\n\n2. **Upload Options**\n - Open the Playground\n - Click file attachment icon\n - Or drag and drop into playground\n\n3. **Wait for Analysis**\n - System will process the image\n - Uses zero-shot learning\n - Classification happens automatically\n\n4. **Review Results**\n - Get classification: Positive/Negative/Neutral\n - Review confidence level\n - Check reasoning if provided\n\n5. **Expected Classifications**\n - Positive: Happy scenes, smiles, celebrations\n - Negative: Sad scenes, problems, conflicts\n - Neutral: Objects, landscapes, neutral scenes\n\nRemember: The clearer the image, the more accurate the classification! 📸✨", + "description": "# Image Sentiment Analysis\nClassify images uploaded to the Playground by sentiment.\n\n## Prerequisites\n\n* [OpenAI API Key](https://platform.openai.com/)\n\n## Quickstart\n\n1. In the **Language Model** component, add your OpenAI API key.\n\n2. Open the **Playground**, and then submit an image to the chat. \n\nThe LLM analyzes the image. The sentiment is output into a structured table according to the **Structured Output** component's Output Schema, and then parsed into a message for the Playground to display.", "display_name": "", "documentation": "", "template": {} @@ -796,14 +824,14 @@ }, "dragging": false, "height": 583, - "id": "note-k9mrI", + "id": "note-tC1fr", "measured": { "height": 583, - "width": 325 + "width": 391 }, "position": { - "x": 791.7294511578832, - "y": 340.1333942936967 + "x": 636.4409835338676, + "y": 119.16831706772064 }, "positionAbsolute": { "x": 791.7294511578832, @@ -816,13 +844,13 @@ "width": 324 }, "type": "noteNode", - "width": 324 + "width": 391 }, { "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-ElcZb", + "id": "Prompt-9gGBt", "node": { "base_classes": [ "Message" @@ -929,7 +957,7 @@ }, "dragging": false, "height": 260, - "id": "Prompt-ElcZb", + "id": "Prompt-9gGBt", "measured": { "height": 260, "width": 320 @@ -948,7 +976,7 @@ }, { "data": { - "id": "StructuredOutput-eoFyT", + "id": "StructuredOutput-93GZ3", "node": { "base_classes": [ "Data" @@ -1207,21 +1235,21 @@ "type": "StructuredOutput" }, "dragging": false, - "id": "StructuredOutput-eoFyT", + "id": "StructuredOutput-93GZ3", "measured": { - "height": 349, + "height": 348, "width": 320 }, "position": { - "x": 2029.014435320394, - "y": 390.91002340476973 + "x": 2021.6355491355362, + "y": 373.20069656111025 }, "selected": false, "type": "genericNode" }, { "data": { - "id": "parser-o6H8E", + "id": "parser-Z6kPy", "node": { "base_classes": [ "Message" @@ -1350,7 +1378,7 @@ "trace_as_input": true, "trace_as_metadata": true, "type": "str", - "value": "Sentiment: {sentiment} Description: {description} " + "value": "Sentiment: {sentiment}, Description: {description}" }, "sep": { "_input_type": "MessageTextInput", @@ -1382,9 +1410,9 @@ "type": "parser" }, "dragging": false, - "id": "parser-o6H8E", + "id": "parser-Z6kPy", "measured": { - "height": 361, + "height": 360, "width": 320 }, "position": { @@ -1396,7 +1424,7 @@ }, { "data": { - "id": "LanguageModelComponent-2h2qm", + "id": "LanguageModelComponent-t4Dhl", "node": { "base_classes": [ "LanguageModel", @@ -1473,7 +1501,7 @@ "dynamic": false, "info": "Model Provider API key", "input_types": [], - "load_from_db": false, + "load_from_db": true, "name": "api_key", "password": true, "placeholder": "", @@ -1482,7 +1510,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "OPENAI_API_KEY" }, "code": { "advanced": true, @@ -1503,7 +1531,7 @@ "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\": \"Google\"}],\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", + "_input_type": "MessageTextInput", "advanced": false, "display_name": "Input", "dynamic": false, @@ -1612,9 +1640,8 @@ "value": false }, "system_message": { - "_input_type": "MultilineInput", + "_input_type": "MessageTextInput", "advanced": true, - "copy_field": false, "display_name": "System Message", "dynamic": false, "info": "A system message that helps set the behavior of the assistant", @@ -1624,7 +1651,6 @@ "list": false, "list_add_label": "Add More", "load_from_db": false, - "multiline": true, "name": "system_message", "placeholder": "", "required": false, @@ -1672,21 +1698,21 @@ "type": "LanguageModelComponent" }, "dragging": false, - "id": "LanguageModelComponent-2h2qm", + "id": "LanguageModelComponent-t4Dhl", "measured": { - "height": 451, + "height": 450, "width": 320 }, "position": { - "x": 1639.476019848849, - "y": -40.182392195326116 + "x": 1645.4600361504665, + "y": 292.02587622395924 }, "selected": false, "type": "genericNode" }, { "data": { - "id": "LanguageModelComponent-YHUqJ", + "id": "LanguageModelComponent-1KtUQ", "node": { "base_classes": [ "LanguageModel", @@ -1763,7 +1789,7 @@ "dynamic": false, "info": "Model Provider API key", "input_types": [], - "load_from_db": false, + "load_from_db": true, "name": "api_key", "password": true, "placeholder": "", @@ -1772,7 +1798,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "OPENAI_API_KEY" }, "code": { "advanced": true, @@ -1793,7 +1819,7 @@ "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\": \"Google\"}],\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", + "_input_type": "MessageTextInput", "advanced": false, "display_name": "Input", "dynamic": false, @@ -1902,9 +1928,8 @@ "value": false }, "system_message": { - "_input_type": "MultilineInput", - "advanced": false, - "copy_field": false, + "_input_type": "MessageTextInput", + "advanced": true, "display_name": "System Message", "dynamic": false, "info": "A system message that helps set the behavior of the assistant", @@ -1914,7 +1939,6 @@ "list": false, "list_add_label": "Add More", "load_from_db": false, - "multiline": true, "name": "system_message", "placeholder": "", "required": false, @@ -1957,32 +1981,33 @@ }, "tool_mode": false }, + "selected_output": "text_output", "showNode": true, "type": "LanguageModelComponent" }, "dragging": false, - "id": "LanguageModelComponent-YHUqJ", + "id": "LanguageModelComponent-1KtUQ", "measured": { - "height": 534, + "height": 450, "width": 320 }, "position": { - "x": 1659.6268676037548, - "y": 577.7964730516118 + "x": 1632.2008343481689, + "y": -201.15856374270624 }, "selected": false, "type": "genericNode" } ], "viewport": { - "x": -779.9735306873563, - "y": 114.7787669766526, - "zoom": 0.6873063891390285 + "x": -287.7429081989603, + "y": 200.72301072909082, + "zoom": 0.5605278689284416 } }, "description": "Analyzes images and categorizes them as positive, negative, or neutral using zero-shot learning.", "endpoint_name": null, - "id": "0cccdf9b-c4ae-4e14-8d19-1b1ac4dd1edf", + "id": "bf5000cf-7400-4fe1-87f8-c4ddf91fbddf", "is_component": false, "last_tested_version": "1.4.3", "name": "Image Sentiment Analysis", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json b/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json index c60372e3e..e2d985723 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json @@ -7,7 +7,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-xGZs1", + "id": "ChatInput-Vu7qu", "name": "message", "output_types": [ "Message" @@ -15,19 +15,19 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "Agent-GuZvV", + "id": "Agent-ZGDpX", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ChatInput-xGZs1{œdataTypeœ:œChatInputœ,œidœ:œChatInput-xGZs1œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-GuZvV{œfieldNameœ:œinput_valueœ,œidœ:œAgent-GuZvVœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-Vu7qu{œdataTypeœ:œChatInputœ,œidœ:œChatInput-Vu7quœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-ZGDpX{œfieldNameœ:œinput_valueœ,œidœ:œAgent-ZGDpXœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-xGZs1", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-xGZs1œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-GuZvV", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-GuZvVœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatInput-Vu7qu", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-Vu7quœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-ZGDpX", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-ZGDpXœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -35,7 +35,7 @@ "data": { "sourceHandle": { "dataType": "Agent", - "id": "Agent-GuZvV", + "id": "Agent-ZGDpX", "name": "response", "output_types": [ "Message" @@ -43,19 +43,19 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "StructuredOutput-TgwNF", + "id": "StructuredOutput-Aph6K", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Agent-GuZvV{œdataTypeœ:œAgentœ,œidœ:œAgent-GuZvVœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-StructuredOutput-TgwNF{œfieldNameœ:œinput_valueœ,œidœ:œStructuredOutput-TgwNFœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Agent-ZGDpX{œdataTypeœ:œAgentœ,œidœ:œAgent-ZGDpXœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-StructuredOutput-Aph6K{œfieldNameœ:œinput_valueœ,œidœ:œStructuredOutput-Aph6Kœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Agent-GuZvV", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-GuZvVœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "StructuredOutput-TgwNF", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œStructuredOutput-TgwNFœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Agent-ZGDpX", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-ZGDpXœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "StructuredOutput-Aph6K", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œStructuredOutput-Aph6Kœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -63,7 +63,7 @@ "data": { "sourceHandle": { "dataType": "TavilySearchComponent", - "id": "TavilySearchComponent-oQBdN", + "id": "TavilySearchComponent-Q9JKS", "name": "component_as_tool", "output_types": [ "Tool" @@ -71,19 +71,19 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-GuZvV", + "id": "Agent-ZGDpX", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "reactflow__edge-TavilySearchComponent-oQBdN{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-oQBdNœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-GuZvV{œfieldNameœ:œtoolsœ,œidœ:œAgent-GuZvVœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-TavilySearchComponent-Q9JKS{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-Q9JKSœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-ZGDpX{œfieldNameœ:œtoolsœ,œidœ:œAgent-ZGDpXœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", "selected": false, - "source": "TavilySearchComponent-oQBdN", - "sourceHandle": "{œdataTypeœ: œTavilySearchComponentœ, œidœ: œTavilySearchComponent-oQBdNœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-GuZvV", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-GuZvVœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "source": "TavilySearchComponent-Q9JKS", + "sourceHandle": "{œdataTypeœ: œTavilySearchComponentœ, œidœ: œTavilySearchComponent-Q9JKSœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-ZGDpX", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-ZGDpXœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -91,7 +91,7 @@ "data": { "sourceHandle": { "dataType": "OpenAIModel", - "id": "OpenAIModel-kaJVR", + "id": "OpenAIModel-YQpWE", "name": "model_output", "output_types": [ "LanguageModel" @@ -99,19 +99,19 @@ }, "targetHandle": { "fieldName": "llm", - "id": "StructuredOutput-TgwNF", + "id": "StructuredOutput-Aph6K", "inputTypes": [ "LanguageModel" ], "type": "other" } }, - "id": "reactflow__edge-OpenAIModel-kaJVR{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-kaJVRœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}-StructuredOutput-TgwNF{œfieldNameœ:œllmœ,œidœ:œStructuredOutput-TgwNFœ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-OpenAIModel-YQpWE{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-YQpWEœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}-StructuredOutput-Aph6K{œfieldNameœ:œllmœ,œidœ:œStructuredOutput-Aph6Kœ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}", "selected": false, - "source": "OpenAIModel-kaJVR", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-kaJVRœ, œnameœ: œmodel_outputœ, œoutput_typesœ: [œLanguageModelœ]}", - "target": "StructuredOutput-TgwNF", - "targetHandle": "{œfieldNameœ: œllmœ, œidœ: œStructuredOutput-TgwNFœ, œinputTypesœ: [œLanguageModelœ], œtypeœ: œotherœ}" + "source": "OpenAIModel-YQpWE", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-YQpWEœ, œnameœ: œmodel_outputœ, œoutput_typesœ: [œLanguageModelœ]}", + "target": "StructuredOutput-Aph6K", + "targetHandle": "{œfieldNameœ: œllmœ, œidœ: œStructuredOutput-Aph6Kœ, œinputTypesœ: [œLanguageModelœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -119,7 +119,7 @@ "data": { "sourceHandle": { "dataType": "parser", - "id": "parser-4iVNG", + "id": "parser-0YWi5", "name": "parsed_text", "output_types": [ "Message" @@ -127,7 +127,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-eTO66", + "id": "ChatOutput-CfBiH", "inputTypes": [ "Data", "DataFrame", @@ -136,19 +136,20 @@ "type": "str" } }, - "id": "reactflow__edge-parser-4iVNG{œdataTypeœ:œparserœ,œidœ:œparser-4iVNGœ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-eTO66{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-eTO66œ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-parser-0YWi5{œdataTypeœ:œparserœ,œidœ:œparser-0YWi5œ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-CfBiH{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-CfBiHœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "parser-4iVNG", - "sourceHandle": "{œdataTypeœ: œparserœ, œidœ: œparser-4iVNGœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-eTO66", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-eTO66œ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" + "source": "parser-0YWi5", + "sourceHandle": "{œdataTypeœ: œparserœ, œidœ: œparser-0YWi5œ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-CfBiH", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-CfBiHœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, + "className": "", "data": { "sourceHandle": { "dataType": "StructuredOutput", - "id": "StructuredOutput-TgwNF", + "id": "StructuredOutput-Aph6K", "name": "structured_output", "output_types": [ "Data" @@ -156,7 +157,7 @@ }, "targetHandle": { "fieldName": "input_data", - "id": "parser-4iVNG", + "id": "parser-0YWi5", "inputTypes": [ "DataFrame", "Data" @@ -164,12 +165,12 @@ "type": "other" } }, - "id": "xy-edge__StructuredOutput-TgwNF{œdataTypeœ:œStructuredOutputœ,œidœ:œStructuredOutput-TgwNFœ,œnameœ:œstructured_outputœ,œoutput_typesœ:[œDataœ]}-parser-4iVNG{œfieldNameœ:œinput_dataœ,œidœ:œparser-4iVNGœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", + "id": "xy-edge__StructuredOutput-Aph6K{œdataTypeœ:œStructuredOutputœ,œidœ:œStructuredOutput-Aph6Kœ,œnameœ:œstructured_outputœ,œoutput_typesœ:[œDataœ]}-parser-0YWi5{œfieldNameœ:œinput_dataœ,œidœ:œparser-0YWi5œ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", "selected": false, - "source": "StructuredOutput-TgwNF", - "sourceHandle": "{œdataTypeœ: œStructuredOutputœ, œidœ: œStructuredOutput-TgwNFœ, œnameœ: œstructured_outputœ, œoutput_typesœ: [œDataœ]}", - "target": "parser-4iVNG", - "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œparser-4iVNGœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" + "source": "StructuredOutput-Aph6K", + "sourceHandle": "{œdataTypeœ: œStructuredOutputœ, œidœ: œStructuredOutput-Aph6Kœ, œnameœ: œstructured_outputœ, œoutput_typesœ: [œDataœ]}", + "target": "parser-0YWi5", + "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œparser-0YWi5œ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" } ], "nodes": [ @@ -177,7 +178,7 @@ "data": { "description": "Get chat inputs from the Playground.", "display_name": "Chat Input", - "id": "ChatInput-xGZs1", + "id": "ChatInput-Vu7qu", "node": { "base_classes": [ "Message" @@ -454,7 +455,7 @@ }, "dragging": false, "height": 234, - "id": "ChatInput-xGZs1", + "id": "ChatInput-Vu7qu", "measured": { "height": 234, "width": 320 @@ -475,7 +476,7 @@ "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-eTO66", + "id": "ChatOutput-CfBiH", "node": { "base_classes": [ "Message" @@ -758,7 +759,7 @@ }, "dragging": false, "height": 234, - "id": "ChatOutput-eTO66", + "id": "ChatOutput-CfBiH", "measured": { "height": 234, "width": 320 @@ -777,7 +778,7 @@ }, { "data": { - "id": "note-tcZdh", + "id": "note-wiaOc", "node": { "description": "# Market Research\nThis flow helps you gather comprehensive information about companies for sales and business intelligence purposes.\n\n## Prerequisites\n\n- **[Tavily API Key](https://docs.tavily.com/welcome)**\n- **[OpenAI API Key](https://platform.openai.com/)**\n\n## Quickstart\n\n1. Add your **OpenAI API key** to the **OpenAI** model and **Agent** components.\n2. Add your **Tavily API key** to the **Tavily Search** component.\n3. In the **Chat Input**, enter a company name you want to research.\n4. Open the **Playground** and research the company. The **Structured Output** component transforms the raw LLM response into structured data, and the **Parser** component presents the data as text for the **Chat output** component to present.", "display_name": "", @@ -790,7 +791,7 @@ }, "dragging": false, "height": 671, - "id": "note-tcZdh", + "id": "note-wiaOc", "measured": { "height": 671, "width": 660 @@ -816,7 +817,7 @@ "data": { "description": "Transforms LLM responses into **structured data formats**. Ideal for extracting specific information or creating consistent outputs.", "display_name": "Structured Output", - "id": "StructuredOutput-TgwNF", + "id": "StructuredOutput-Aph6K", "node": { "base_classes": [ "Data", @@ -1127,7 +1128,7 @@ }, "dragging": false, "height": 541, - "id": "StructuredOutput-TgwNF", + "id": "StructuredOutput-Aph6K", "measured": { "height": 541, "width": 320 @@ -1148,7 +1149,7 @@ "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "Agent", - "id": "Agent-GuZvV", + "id": "Agent-ZGDpX", "node": { "base_classes": [ "Message" @@ -1820,7 +1821,7 @@ }, "dragging": false, "height": 650, - "id": "Agent-GuZvV", + "id": "Agent-ZGDpX", "measured": { "height": 650, "width": 320 @@ -1837,7 +1838,7 @@ "data": { "description": "**Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", "display_name": "Tavily AI Search", - "id": "TavilySearchComponent-oQBdN", + "id": "TavilySearchComponent-Q9JKS", "node": { "base_classes": [ "Data", @@ -1896,7 +1897,7 @@ "dynamic": false, "info": "Your Tavily API Key.", "input_types": [], - "load_from_db": false, + "load_from_db": true, "name": "api_key", "password": true, "placeholder": "", @@ -2218,7 +2219,7 @@ "type": "TavilySearchComponent" }, "dragging": false, - "id": "TavilySearchComponent-oQBdN", + "id": "TavilySearchComponent-Q9JKS", "measured": { "height": 316, "width": 320 @@ -2232,7 +2233,7 @@ }, { "data": { - "id": "OpenAIModel-kaJVR", + "id": "OpenAIModel-YQpWE", "node": { "base_classes": [ "LanguageModel", @@ -2609,9 +2610,9 @@ "type": "OpenAIModel" }, "dragging": false, - "id": "OpenAIModel-kaJVR", + "id": "OpenAIModel-YQpWE", "measured": { - "height": 540, + "height": 539, "width": 320 }, "position": { @@ -2623,7 +2624,7 @@ }, { "data": { - "id": "parser-4iVNG", + "id": "parser-0YWi5", "node": { "base_classes": [ "Message" @@ -2784,9 +2785,9 @@ "type": "parser" }, "dragging": false, - "id": "parser-4iVNG", + "id": "parser-0YWi5", "measured": { - "height": 361, + "height": 360, "width": 320 }, "position": { @@ -2798,14 +2799,14 @@ } ], "viewport": { - "x": -318.95425982795314, - "y": -363.533384278095, - "zoom": 0.6920146245449773 + "x": -93.26437689350178, + "y": -217.58870925998986, + "zoom": 0.5616361094335138 } }, "description": "Researches companies, extracts key business data, and presents structured information for efficient analysis. ", "endpoint_name": null, - "id": "8ce19804-52f5-4894-9354-4272aff238f7", + "id": "33ed74a4-250a-45d3-aebd-8eea096cc3c5", "is_component": false, "last_tested_version": "1.4.3", "name": "Market Research", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json b/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json index 7390ea11e..f5e61f60c 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json @@ -7,7 +7,7 @@ "data": { "sourceHandle": { "dataType": "AgentQL", - "id": "AgentQL-TCADj", + "id": "AgentQL-mAUuI", "name": "component_as_tool", "output_types": [ "Tool" @@ -15,19 +15,19 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-x50rv", + "id": "Agent-MtFB7", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "reactflow__edge-AgentQL-TCADj{œdataTypeœ:œAgentQLœ,œidœ:œAgentQL-TCADjœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-x50rv{œfieldNameœ:œtoolsœ,œidœ:œAgent-x50rvœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-AgentQL-mAUuI{œdataTypeœ:œAgentQLœ,œidœ:œAgentQL-mAUuIœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-MtFB7{œfieldNameœ:œtoolsœ,œidœ:œAgent-MtFB7œ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", "selected": false, - "source": "AgentQL-TCADj", - "sourceHandle": "{œdataTypeœ: œAgentQLœ, œidœ: œAgentQL-TCADjœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-x50rv", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-x50rvœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "source": "AgentQL-mAUuI", + "sourceHandle": "{œdataTypeœ: œAgentQLœ, œidœ: œAgentQL-mAUuIœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-MtFB7", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-MtFB7œ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -35,7 +35,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-LwqUD", + "id": "ChatInput-l2zGd", "name": "message", "output_types": [ "Message" @@ -43,19 +43,19 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "Agent-x50rv", + "id": "Agent-MtFB7", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ChatInput-LwqUD{œdataTypeœ:œChatInputœ,œidœ:œChatInput-LwqUDœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-x50rv{œfieldNameœ:œinput_valueœ,œidœ:œAgent-x50rvœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-l2zGd{œdataTypeœ:œChatInputœ,œidœ:œChatInput-l2zGdœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-MtFB7{œfieldNameœ:œinput_valueœ,œidœ:œAgent-MtFB7œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-LwqUD", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-LwqUDœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-x50rv", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-x50rvœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatInput-l2zGd", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-l2zGdœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-MtFB7", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-MtFB7œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -63,7 +63,7 @@ "data": { "sourceHandle": { "dataType": "Agent", - "id": "Agent-x50rv", + "id": "Agent-MtFB7", "name": "response", "output_types": [ "Message" @@ -71,7 +71,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-RB2DM", + "id": "ChatOutput-ZC7ao", "inputTypes": [ "Data", "DataFrame", @@ -80,12 +80,12 @@ "type": "other" } }, - "id": "reactflow__edge-Agent-x50rv{œdataTypeœ:œAgentœ,œidœ:œAgent-x50rvœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-RB2DM{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-RB2DMœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-Agent-MtFB7{œdataTypeœ:œAgentœ,œidœ:œAgent-MtFB7œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-ZC7ao{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-ZC7aoœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}", "selected": false, - "source": "Agent-x50rv", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-x50rvœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-RB2DM", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-RB2DMœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}" + "source": "Agent-MtFB7", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-MtFB7œ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-ZC7ao", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-ZC7aoœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -93,33 +93,35 @@ "data": { "sourceHandle": { "dataType": "ChatOutput", - "id": "ChatOutput-RB2DM", + "id": "ChatOutput-ZC7ao", "name": "message", "output_types": [ "Message" ] }, "targetHandle": { - "fieldName": "message", - "id": "SaveToFile-FmELb", + "fieldName": "input", + "id": "SaveToFile-PIe7f", "inputTypes": [ + "Data", + "DataFrame", "Message" ], - "type": "str" + "type": "other" } }, - "id": "reactflow__edge-ChatOutput-RB2DM{œdataTypeœ:œChatOutputœ,œidœ:œChatOutput-RB2DMœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-SaveToFile-FmELb{œfieldNameœ:œmessageœ,œidœ:œSaveToFile-FmELbœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "xy-edge__ChatOutput-ZC7ao{œdataTypeœ:œChatOutputœ,œidœ:œChatOutput-ZC7aoœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-SaveToFile-PIe7f{œfieldNameœ:œinputœ,œidœ:œSaveToFile-PIe7fœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}", "selected": false, - "source": "ChatOutput-RB2DM", - "sourceHandle": "{œdataTypeœ: œChatOutputœ, œidœ: œChatOutput-RB2DMœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "SaveToFile-FmELb", - "targetHandle": "{œfieldNameœ: œmessageœ, œidœ: œSaveToFile-FmELbœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatOutput-ZC7ao", + "sourceHandle": "{œdataTypeœ: œChatOutputœ, œidœ: œChatOutput-ZC7aoœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "SaveToFile-PIe7f", + "targetHandle": "{œfieldNameœ: œinputœ, œidœ: œSaveToFile-PIe7fœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}" } ], "nodes": [ { "data": { - "id": "note-Z1JPk", + "id": "note-QUpTh", "node": { "description": "### 💡 Add your OpenAI API key here", "display_name": "", @@ -131,7 +133,7 @@ "type": "note" }, "dragging": false, - "id": "note-Z1JPk", + "id": "note-QUpTh", "measured": { "height": 324, "width": 324 @@ -145,7 +147,7 @@ }, { "data": { - "id": "note-7vrvb", + "id": "note-e9QOB", "node": { "description": "### 💡 Add your AgentQL API key here", "display_name": "", @@ -158,7 +160,7 @@ }, "dragging": false, "height": 346, - "id": "note-7vrvb", + "id": "note-e9QOB", "measured": { "height": 346, "width": 324 @@ -174,7 +176,7 @@ "data": { "description": "Uses AgentQL API to extract structured data from a given URL.", "display_name": "AgentQL Query Data", - "id": "AgentQL-TCADj", + "id": "AgentQL-mAUuI", "node": { "base_classes": [ "Data" @@ -201,7 +203,7 @@ "frozen": false, "icon": "AgentQL", "legacy": false, - "lf_version": "1.3.2", + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "output_types": [], @@ -210,6 +212,7 @@ "allows_loop": false, "cache": true, "display_name": "Toolset", + "group_outputs": false, "hidden": null, "method": "to_toolkit", "name": "component_as_tool", @@ -407,11 +410,11 @@ "value": 900 }, "tools_metadata": { - "_input_type": "TableInput", + "_input_type": "ToolsInput", "advanced": false, - "display_name": "Edit tools", + "display_name": "Actions", "dynamic": false, - "info": "", + "info": "Modify tool names and descriptions to help agents understand when to use each tool.", "is_list": true, "list_add_label": "Add More", "name": "tools_metadata", @@ -419,94 +422,39 @@ "real_time_refresh": true, "required": false, "show": true, - "table_icon": "Hammer", - "table_options": { - "block_add": true, - "block_delete": true, - "block_edit": true, - "block_filter": true, - "block_hide": true, - "block_select": true, - "block_sort": true, - "description": "Modify tool names and descriptions to help agents understand when to use each tool.", - "field_parsers": { - "commands": "commands", - "name": [ - "snake_case", - "no_blank" - ] - }, - "hide_options": true - }, - "table_schema": { - "columns": [ - { - "default": "None", - "description": "Specify the name of the tool.", - "disable_edit": false, - "display_name": "Tool Name", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "hidden": false, - "name": "name", - "sortable": false, - "type": "str" - }, - { - "default": "None", - "description": "Describe the purpose of the tool.", - "disable_edit": false, - "display_name": "Tool Description", - "edit_mode": "popover", - "filterable": false, - "formatter": "text", - "hidden": false, - "name": "description", - "sortable": false, - "type": "str" - }, - { - "default": "None", - "description": "The default identifiers for the tools and cannot be changed.", - "disable_edit": true, - "display_name": "Tool Identifiers", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "hidden": true, - "name": "tags", - "sortable": false, - "type": "str" - }, - { - "default": true, - "description": "Indicates whether the tool is currently active. Set to True to activate this tool.", - "disable_edit": false, - "display_name": "Enable", - "edit_mode": "popover", - "filterable": true, - "formatter": "boolean", - "hidden": false, - "name": "status", - "sortable": true, - "type": "boolean" - } - ] - }, "title_case": false, "tool_mode": false, "trace_as_metadata": true, - "trigger_icon": "Hammer", - "trigger_text": "", - "type": "table", + "type": "tools", "value": [ { - "description": "build_output(api_key: Message, url: Message) - Extracts structured data from a web page using an AgentQL query or a Natural Language description.", - "name": "AgentQL-build_output", + "args": { + "prompt": { + "default": "", + "description": "A Natural Language description of the data to extract from the page. Alternative to AgentQL query.", + "title": "Prompt", + "type": "string" + }, + "query": { + "default": "", + "description": "The AgentQL query to execute. Learn more at https://docs.agentql.com/agentql-query or use a prompt.", + "title": "Query", + "type": "string" + }, + "url": { + "description": "The URL of the public web page you want to extract data from.", + "title": "Url", + "type": "string" + } + }, + "description": "AgentQL. build_output - Extracts structured data from a web page using an AgentQL query or a Natural Language description.", + "display_description": "AgentQL. build_output - Extracts structured data from a web page using an AgentQL query or a Natural Language description.", + "display_name": "build_output", + "name": "build_output", + "readonly": false, "status": true, "tags": [ - "AgentQL-build_output" + "build_output" ] } ] @@ -566,9 +514,9 @@ "type": "AgentQL" }, "dragging": false, - "id": "AgentQL-TCADj", + "id": "AgentQL-mAUuI", "measured": { - "height": 644, + "height": 316, "width": 320 }, "position": { @@ -580,7 +528,7 @@ }, { "data": { - "id": "ChatInput-LwqUD", + "id": "ChatInput-l2zGd", "node": { "base_classes": [ "Message" @@ -608,7 +556,7 @@ "icon": "MessagesSquare", "key": "ChatInput", "legacy": false, - "lf_version": "1.3.2", + "lf_version": "1.4.3", "metadata": {}, "minimized": true, "output_types": [], @@ -880,9 +828,9 @@ "type": "ChatInput" }, "dragging": false, - "id": "ChatInput-LwqUD", + "id": "ChatInput-l2zGd", "measured": { - "height": 66, + "height": 48, "width": 192 }, "position": { @@ -894,7 +842,7 @@ }, { "data": { - "id": "Agent-x50rv", + "id": "Agent-MtFB7", "node": { "base_classes": [ "Message" @@ -937,7 +885,7 @@ "frozen": false, "icon": "bot", "legacy": false, - "lf_version": "1.3.2", + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "output_types": [], @@ -1644,9 +1592,9 @@ "type": "Agent" }, "dragging": false, - "id": "Agent-x50rv", + "id": "Agent-MtFB7", "measured": { - "height": 624, + "height": 593, "width": 320 }, "position": { @@ -1658,7 +1606,7 @@ }, { "data": { - "id": "note-DqbD6", + "id": "note-lghpM", "node": { "description": "# News Aggregator\n\nThis flow extracts structured data from a URL and saves it into a JSON file.\n\n## Prerequisites\n\n* **[AgentQL API Key](https://dev.agentql.com/api-keys)**\n* **[OpenAI API Key](https://platform.openai.com/)**\n\n## Quick Start\n\n1. Add your [AgentQL API Key](https://dev.agentql.com/api-keys) to the **AgentQL** component.\n2. Add your [OpenAI API Key](https://platform.openai.com/) to the **Agent** component.\n3. Click **Playground** and enter a question.\n\nThe **Agent** component populates the **AgentQL** component's **URL** and **Query** fields, and returns a structured response to your question. Then the extracted data is saved into a JSON file `news-aggregated.json`, which can be found in your current project directory.", "display_name": "", @@ -1670,9 +1618,9 @@ "type": "note" }, "dragging": false, - "id": "note-DqbD6", + "id": "note-lghpM", "measured": { - "height": 717, + "height": 696, "width": 325 }, "position": { @@ -1684,164 +1632,7 @@ }, { "data": { - "id": "SaveToFile-FmELb", - "node": { - "base_classes": [ - "Text" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Save data to a local file in the selected format.", - "display_name": "Save to File", - "documentation": "", - "edited": false, - "field_order": [ - "input_type", - "df", - "data", - "message", - "file_format", - "file_path" - ], - "frozen": false, - "icon": "save", - "legacy": false, - "lf_version": "1.3.2", - "metadata": {}, - "minimized": false, - "output_types": [], - "outputs": [ - { - "allows_loop": false, - "cache": true, - "display_name": "File Path", - "group_outputs": false, - "method": "save_to_file", - "name": "result", - "selected": "Text", - "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": "import json\nfrom collections.abc import AsyncIterator, Iterator\nfrom pathlib import Path\n\nimport orjson\nimport pandas as pd\nfrom fastapi import UploadFile\nfrom fastapi.encoders import jsonable_encoder\n\nfrom langflow.api.v2.files import upload_user_file\nfrom langflow.custom import Component\nfrom langflow.io import DropdownInput, HandleInput, StrInput\nfrom langflow.schema import Data, DataFrame, Message\nfrom langflow.services.auth.utils import create_user_longterm_token\nfrom langflow.services.database.models.user.crud import get_user_by_id\nfrom langflow.services.deps import get_session, get_settings_service, get_storage_service\nfrom langflow.template.field.base import Output\n\n\nclass SaveToFileComponent(Component):\n display_name = \"Save File\"\n description = \"Save data to a local file in the selected format.\"\n icon = \"save\"\n name = \"SaveToFile\"\n\n # File format options for different types\n DATA_FORMAT_CHOICES = [\"csv\", \"excel\", \"json\", \"markdown\"]\n MESSAGE_FORMAT_CHOICES = [\"txt\", \"json\", \"markdown\"]\n\n inputs = [\n HandleInput(\n name=\"input\",\n display_name=\"Input\",\n info=\"The input to save.\",\n dynamic=True,\n input_types=[\"Data\", \"DataFrame\", \"Message\"],\n required=True,\n ),\n StrInput(\n name=\"file_name\",\n display_name=\"File Name\",\n info=\"Name file will be saved as (without extension).\",\n required=True,\n ),\n DropdownInput(\n name=\"file_format\",\n display_name=\"File Format\",\n options=list(dict.fromkeys(DATA_FORMAT_CHOICES + MESSAGE_FORMAT_CHOICES)),\n info=\"Select the file format to save the input. If not provided, the default format will be used.\",\n value=\"\",\n advanced=True,\n ),\n ]\n\n outputs = [Output(display_name=\"File Path\", name=\"result\", method=\"save_to_file\")]\n\n async def save_to_file(self) -> Message:\n \"\"\"Save the input to a file and upload it, returning a confirmation message.\"\"\"\n # Validate inputs\n if not self.file_name:\n msg = \"File name must be provided.\"\n raise ValueError(msg)\n if not self._get_input_type():\n msg = \"Input type is not set.\"\n raise ValueError(msg)\n\n # Validate file format based on input type\n file_format = self.file_format or self._get_default_format()\n allowed_formats = (\n self.MESSAGE_FORMAT_CHOICES if self._get_input_type() == \"Message\" else self.DATA_FORMAT_CHOICES\n )\n if file_format not in allowed_formats:\n msg = f\"Invalid file format '{file_format}' for {self._get_input_type()}. Allowed: {allowed_formats}\"\n raise ValueError(msg)\n\n # Prepare file path\n file_path = Path(self.file_name).expanduser()\n if not file_path.parent.exists():\n file_path.parent.mkdir(parents=True, exist_ok=True)\n file_path = self._adjust_file_path_with_format(file_path, file_format)\n\n # Save the input to file based on type\n if self._get_input_type() == \"DataFrame\":\n confirmation = self._save_dataframe(self.input, file_path, file_format)\n elif self._get_input_type() == \"Data\":\n confirmation = self._save_data(self.input, file_path, file_format)\n elif self._get_input_type() == \"Message\":\n confirmation = await self._save_message(self.input, file_path, file_format)\n else:\n msg = f\"Unsupported input type: {self._get_input_type()}\"\n raise ValueError(msg)\n\n # Upload the saved file\n await self._upload_file(file_path)\n\n # Return the final file path and confirmation message\n final_path = Path.cwd() / file_path if not file_path.is_absolute() else file_path\n\n return Message(text=f\"{confirmation} at {final_path}\")\n\n def _get_input_type(self) -> str:\n \"\"\"Determine the input type based on the provided input.\"\"\"\n # Use exact type checking (type() is) instead of isinstance() to avoid inheritance issues.\n # Since Message inherits from Data, isinstance(message, Data) would return True for Message objects,\n # causing Message inputs to be incorrectly identified as Data type.\n if type(self.input) is DataFrame:\n return \"DataFrame\"\n if type(self.input) is Message:\n return \"Message\"\n if type(self.input) is Data:\n return \"Data\"\n msg = f\"Unsupported input type: {type(self.input)}\"\n raise ValueError(msg)\n\n def _get_default_format(self) -> str:\n \"\"\"Return the default file format based on input type.\"\"\"\n if self._get_input_type() == \"DataFrame\":\n return \"csv\"\n if self._get_input_type() == \"Data\":\n return \"json\"\n if self._get_input_type() == \"Message\":\n return \"json\"\n return \"json\" # Fallback\n\n def _adjust_file_path_with_format(self, path: Path, fmt: str) -> Path:\n \"\"\"Adjust the file path to include the correct extension.\"\"\"\n file_extension = path.suffix.lower().lstrip(\".\")\n if fmt == \"excel\":\n return Path(f\"{path}.xlsx\").expanduser() if file_extension not in [\"xlsx\", \"xls\"] else path\n return Path(f\"{path}.{fmt}\").expanduser() if file_extension != fmt else path\n\n async def _upload_file(self, file_path: Path) -> None:\n \"\"\"Upload the saved file using the upload_user_file service.\"\"\"\n if not file_path.exists():\n msg = f\"File not found: {file_path}\"\n raise FileNotFoundError(msg)\n\n with file_path.open(\"rb\") as f:\n async for db in get_session():\n user_id, _ = await create_user_longterm_token(db)\n current_user = await get_user_by_id(db, user_id)\n\n await upload_user_file(\n file=UploadFile(filename=file_path.name, file=f, size=file_path.stat().st_size),\n session=db,\n current_user=current_user,\n storage_service=get_storage_service(),\n settings_service=get_settings_service(),\n )\n\n def _save_dataframe(self, dataframe: DataFrame, path: Path, fmt: str) -> str:\n \"\"\"Save a DataFrame to the specified file format.\"\"\"\n if fmt == \"csv\":\n dataframe.to_csv(path, index=False)\n elif fmt == \"excel\":\n dataframe.to_excel(path, index=False, engine=\"openpyxl\")\n elif fmt == \"json\":\n dataframe.to_json(path, orient=\"records\", indent=2)\n elif fmt == \"markdown\":\n path.write_text(dataframe.to_markdown(index=False), encoding=\"utf-8\")\n else:\n msg = f\"Unsupported DataFrame format: {fmt}\"\n raise ValueError(msg)\n return f\"DataFrame saved successfully as '{path}'\"\n\n def _save_data(self, data: Data, path: Path, fmt: str) -> str:\n \"\"\"Save a Data object to the specified file format.\"\"\"\n if fmt == \"csv\":\n pd.DataFrame(data.data).to_csv(path, index=False)\n elif fmt == \"excel\":\n pd.DataFrame(data.data).to_excel(path, index=False, engine=\"openpyxl\")\n elif fmt == \"json\":\n path.write_text(\n orjson.dumps(jsonable_encoder(data.data), option=orjson.OPT_INDENT_2).decode(\"utf-8\"), encoding=\"utf-8\"\n )\n elif fmt == \"markdown\":\n path.write_text(pd.DataFrame(data.data).to_markdown(index=False), encoding=\"utf-8\")\n else:\n msg = f\"Unsupported Data format: {fmt}\"\n raise ValueError(msg)\n return f\"Data saved successfully as '{path}'\"\n\n async def _save_message(self, message: Message, path: Path, fmt: str) -> str:\n \"\"\"Save a Message to the specified file format, handling async iterators.\"\"\"\n content = \"\"\n if message.text is None:\n content = \"\"\n elif isinstance(message.text, AsyncIterator):\n async for item in message.text:\n content += str(item) + \" \"\n content = content.strip()\n elif isinstance(message.text, Iterator):\n content = \" \".join(str(item) for item in message.text)\n else:\n content = str(message.text)\n\n if fmt == \"txt\":\n path.write_text(content, encoding=\"utf-8\")\n elif fmt == \"json\":\n path.write_text(json.dumps({\"message\": content}, indent=2), encoding=\"utf-8\")\n elif fmt == \"markdown\":\n path.write_text(f\"**Message:**\\n\\n{content}\", encoding=\"utf-8\")\n else:\n msg = f\"Unsupported Message format: {fmt}\"\n raise ValueError(msg)\n return f\"Message saved successfully as '{path}'\"\n" - }, - "file_format": { - "_input_type": "DropdownInput", - "advanced": true, - "combobox": false, - "dialog_inputs": {}, - "display_name": "File Format", - "dynamic": false, - "info": "Select the file format to save the input. If not provided, the default format will be used.", - "name": "file_format", - "options": [ - "csv", - "excel", - "json", - "markdown", - "txt" - ], - "options_metadata": [], - "placeholder": "", - "real_time_refresh": true, - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "json" - }, - "file_name": { - "_input_type": "StrInput", - "advanced": false, - "display_name": "File Name", - "dynamic": false, - "info": "Name file will be saved as (without extension).", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "file_name", - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "./output" - }, - "input": { - "_input_type": "HandleInput", - "advanced": false, - "combobox": false, - "dialog_inputs": {}, - "display_name": "Input", - "dynamic": false, - "info": "The input to save.", - "name": "input_type", - "options": [ - "DataFrame", - "Data", - "Message" - ], - "options_metadata": [], - "placeholder": "", - "real_time_refresh": true, - "required": true, - "show": true, - "title_case": false, - "toggle": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "str", - "value": "DataFrame" - } - }, - "tool_mode": false - }, - "showNode": true, - "type": "SaveToFile" - }, - "dragging": false, - "id": "SaveToFile-FmELb", - "measured": { - "height": 497, - "width": 320 - }, - "position": { - "x": 1792.6734722792191, - "y": 270.7843661133249 - }, - "selected": false, - "type": "genericNode" - }, - { - "data": { - "id": "ChatOutput-RB2DM", + "id": "ChatOutput-ZC7ao", "node": { "base_classes": [ "Message" @@ -1868,7 +1659,7 @@ "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.3.2", + "lf_version": "1.4.3", "metadata": {}, "minimized": true, "output_types": [], @@ -2136,9 +1927,9 @@ "type": "ChatOutput" }, "dragging": false, - "id": "ChatOutput-RB2DM", + "id": "ChatOutput-ZC7ao", "measured": { - "height": 66, + "height": 48, "width": 192 }, "position": { @@ -2147,20 +1938,169 @@ }, "selected": false, "type": "genericNode" + }, + { + "data": { + "id": "SaveToFile-PIe7f", + "node": { + "base_classes": [ + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Save data to a local file in the selected format.", + "display_name": "Save File", + "documentation": "", + "edited": false, + "field_order": [ + "input", + "file_name", + "file_format" + ], + "frozen": false, + "icon": "save", + "legacy": false, + "lf_version": "1.4.3", + "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "allows_loop": false, + "cache": true, + "display_name": "File Path", + "group_outputs": false, + "method": "save_to_file", + "name": "result", + "selected": "Text", + "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": "import json\nfrom collections.abc import AsyncIterator, Iterator\nfrom pathlib import Path\n\nimport orjson\nimport pandas as pd\nfrom fastapi import UploadFile\nfrom fastapi.encoders import jsonable_encoder\n\nfrom langflow.api.v2.files import upload_user_file\nfrom langflow.custom import Component\nfrom langflow.io import DropdownInput, HandleInput, StrInput\nfrom langflow.schema import Data, DataFrame, Message\nfrom langflow.services.auth.utils import create_user_longterm_token\nfrom langflow.services.database.models.user.crud import get_user_by_id\nfrom langflow.services.deps import get_session, get_settings_service, get_storage_service\nfrom langflow.template.field.base import Output\n\n\nclass SaveToFileComponent(Component):\n display_name = \"Save File\"\n description = \"Save data to a local file in the selected format.\"\n icon = \"save\"\n name = \"SaveToFile\"\n\n # File format options for different types\n DATA_FORMAT_CHOICES = [\"csv\", \"excel\", \"json\", \"markdown\"]\n MESSAGE_FORMAT_CHOICES = [\"txt\", \"json\", \"markdown\"]\n\n inputs = [\n HandleInput(\n name=\"input\",\n display_name=\"Input\",\n info=\"The input to save.\",\n dynamic=True,\n input_types=[\"Data\", \"DataFrame\", \"Message\"],\n required=True,\n ),\n StrInput(\n name=\"file_name\",\n display_name=\"File Name\",\n info=\"Name file will be saved as (without extension).\",\n required=True,\n ),\n DropdownInput(\n name=\"file_format\",\n display_name=\"File Format\",\n options=list(dict.fromkeys(DATA_FORMAT_CHOICES + MESSAGE_FORMAT_CHOICES)),\n info=\"Select the file format to save the input. If not provided, the default format will be used.\",\n value=\"\",\n advanced=True,\n ),\n ]\n\n outputs = [Output(display_name=\"File Path\", name=\"result\", method=\"save_to_file\")]\n\n async def save_to_file(self) -> Message:\n \"\"\"Save the input to a file and upload it, returning a confirmation message.\"\"\"\n # Validate inputs\n if not self.file_name:\n msg = \"File name must be provided.\"\n raise ValueError(msg)\n if not self._get_input_type():\n msg = \"Input type is not set.\"\n raise ValueError(msg)\n\n # Validate file format based on input type\n file_format = self.file_format or self._get_default_format()\n allowed_formats = (\n self.MESSAGE_FORMAT_CHOICES if self._get_input_type() == \"Message\" else self.DATA_FORMAT_CHOICES\n )\n if file_format not in allowed_formats:\n msg = f\"Invalid file format '{file_format}' for {self._get_input_type()}. Allowed: {allowed_formats}\"\n raise ValueError(msg)\n\n # Prepare file path\n file_path = Path(self.file_name).expanduser()\n if not file_path.parent.exists():\n file_path.parent.mkdir(parents=True, exist_ok=True)\n file_path = self._adjust_file_path_with_format(file_path, file_format)\n\n # Save the input to file based on type\n if self._get_input_type() == \"DataFrame\":\n confirmation = self._save_dataframe(self.input, file_path, file_format)\n elif self._get_input_type() == \"Data\":\n confirmation = self._save_data(self.input, file_path, file_format)\n elif self._get_input_type() == \"Message\":\n confirmation = await self._save_message(self.input, file_path, file_format)\n else:\n msg = f\"Unsupported input type: {self._get_input_type()}\"\n raise ValueError(msg)\n\n # Upload the saved file\n await self._upload_file(file_path)\n\n # Return the final file path and confirmation message\n final_path = Path.cwd() / file_path if not file_path.is_absolute() else file_path\n\n return Message(text=f\"{confirmation} at {final_path}\")\n\n def _get_input_type(self) -> str:\n \"\"\"Determine the input type based on the provided input.\"\"\"\n # Use exact type checking (type() is) instead of isinstance() to avoid inheritance issues.\n # Since Message inherits from Data, isinstance(message, Data) would return True for Message objects,\n # causing Message inputs to be incorrectly identified as Data type.\n if type(self.input) is DataFrame:\n return \"DataFrame\"\n if type(self.input) is Message:\n return \"Message\"\n if type(self.input) is Data:\n return \"Data\"\n msg = f\"Unsupported input type: {type(self.input)}\"\n raise ValueError(msg)\n\n def _get_default_format(self) -> str:\n \"\"\"Return the default file format based on input type.\"\"\"\n if self._get_input_type() == \"DataFrame\":\n return \"csv\"\n if self._get_input_type() == \"Data\":\n return \"json\"\n if self._get_input_type() == \"Message\":\n return \"json\"\n return \"json\" # Fallback\n\n def _adjust_file_path_with_format(self, path: Path, fmt: str) -> Path:\n \"\"\"Adjust the file path to include the correct extension.\"\"\"\n file_extension = path.suffix.lower().lstrip(\".\")\n if fmt == \"excel\":\n return Path(f\"{path}.xlsx\").expanduser() if file_extension not in [\"xlsx\", \"xls\"] else path\n return Path(f\"{path}.{fmt}\").expanduser() if file_extension != fmt else path\n\n async def _upload_file(self, file_path: Path) -> None:\n \"\"\"Upload the saved file using the upload_user_file service.\"\"\"\n if not file_path.exists():\n msg = f\"File not found: {file_path}\"\n raise FileNotFoundError(msg)\n\n with file_path.open(\"rb\") as f:\n async for db in get_session():\n user_id, _ = await create_user_longterm_token(db)\n current_user = await get_user_by_id(db, user_id)\n\n await upload_user_file(\n file=UploadFile(filename=file_path.name, file=f, size=file_path.stat().st_size),\n session=db,\n current_user=current_user,\n storage_service=get_storage_service(),\n settings_service=get_settings_service(),\n )\n\n def _save_dataframe(self, dataframe: DataFrame, path: Path, fmt: str) -> str:\n \"\"\"Save a DataFrame to the specified file format.\"\"\"\n if fmt == \"csv\":\n dataframe.to_csv(path, index=False)\n elif fmt == \"excel\":\n dataframe.to_excel(path, index=False, engine=\"openpyxl\")\n elif fmt == \"json\":\n dataframe.to_json(path, orient=\"records\", indent=2)\n elif fmt == \"markdown\":\n path.write_text(dataframe.to_markdown(index=False), encoding=\"utf-8\")\n else:\n msg = f\"Unsupported DataFrame format: {fmt}\"\n raise ValueError(msg)\n return f\"DataFrame saved successfully as '{path}'\"\n\n def _save_data(self, data: Data, path: Path, fmt: str) -> str:\n \"\"\"Save a Data object to the specified file format.\"\"\"\n if fmt == \"csv\":\n pd.DataFrame(data.data).to_csv(path, index=False)\n elif fmt == \"excel\":\n pd.DataFrame(data.data).to_excel(path, index=False, engine=\"openpyxl\")\n elif fmt == \"json\":\n path.write_text(\n orjson.dumps(jsonable_encoder(data.data), option=orjson.OPT_INDENT_2).decode(\"utf-8\"), encoding=\"utf-8\"\n )\n elif fmt == \"markdown\":\n path.write_text(pd.DataFrame(data.data).to_markdown(index=False), encoding=\"utf-8\")\n else:\n msg = f\"Unsupported Data format: {fmt}\"\n raise ValueError(msg)\n return f\"Data saved successfully as '{path}'\"\n\n async def _save_message(self, message: Message, path: Path, fmt: str) -> str:\n \"\"\"Save a Message to the specified file format, handling async iterators.\"\"\"\n content = \"\"\n if message.text is None:\n content = \"\"\n elif isinstance(message.text, AsyncIterator):\n async for item in message.text:\n content += str(item) + \" \"\n content = content.strip()\n elif isinstance(message.text, Iterator):\n content = \" \".join(str(item) for item in message.text)\n else:\n content = str(message.text)\n\n if fmt == \"txt\":\n path.write_text(content, encoding=\"utf-8\")\n elif fmt == \"json\":\n path.write_text(json.dumps({\"message\": content}, indent=2), encoding=\"utf-8\")\n elif fmt == \"markdown\":\n path.write_text(f\"**Message:**\\n\\n{content}\", encoding=\"utf-8\")\n else:\n msg = f\"Unsupported Message format: {fmt}\"\n raise ValueError(msg)\n return f\"Message saved successfully as '{path}'\"\n" + }, + "file_format": { + "_input_type": "DropdownInput", + "advanced": true, + "combobox": false, + "dialog_inputs": {}, + "display_name": "File Format", + "dynamic": false, + "info": "Select the file format to save the input. If not provided, the default format will be used.", + "name": "file_format", + "options": [ + "csv", + "excel", + "json", + "markdown", + "txt" + ], + "options_metadata": [], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "toggle": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "file_name": { + "_input_type": "StrInput", + "advanced": false, + "display_name": "File Name", + "dynamic": false, + "info": "Name file will be saved as (without extension).", + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "file_name", + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "news-aggregated" + }, + "input": { + "_input_type": "HandleInput", + "advanced": false, + "display_name": "Input", + "dynamic": true, + "info": "The input to save.", + "input_types": [ + "Data", + "DataFrame", + "Message" + ], + "list": false, + "list_add_label": "Add More", + "name": "input", + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "trace_as_metadata": true, + "type": "other", + "value": "" + } + }, + "tool_mode": false + }, + "showNode": true, + "type": "SaveToFile" + }, + "dragging": false, + "id": "SaveToFile-PIe7f", + "measured": { + "height": 248, + "width": 320 + }, + "position": { + "x": 1796.3663744322935, + "y": 374.05935092875194 + }, + "selected": false, + "type": "genericNode" } ], "viewport": { - "x": -215.98323049294243, - "y": 32.882716478010025, - "zoom": 0.6324556495385397 + "x": -259.1169460892288, + "y": 69.5397109756077, + "zoom": 0.787209650668357 } }, "description": "Extracts data and information from webpages.", "endpoint_name": null, - "icon": "Newspaper", - "id": "e76ee0ae-b1cd-4a89-a720-2010e5c7ab7b", + "id": "b5548b67-c370-4931-83f5-e3b934c3b116", "is_component": false, - "last_tested_version": "1.3.2", + "last_tested_version": "1.4.3", "name": "News Aggregator", "tags": [ "web-scraping", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json index 8b46a2ddf..8cc090840 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json @@ -7,7 +7,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-KgyhN", + "id": "ChatInput-BUgw3", "name": "message", "output_types": [ "Message" @@ -15,7 +15,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "Prompt-o2zd8", + "id": "Prompt-gjXon", "inputTypes": [ "Message", "Text" @@ -23,12 +23,12 @@ "type": "str" } }, - "id": "reactflow__edge-ChatInput-KgyhN{œdataTypeœ:œChatInputœ,œidœ:œChatInput-KgyhNœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-o2zd8{œfieldNameœ:œinput_valueœ,œidœ:œPrompt-o2zd8œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-BUgw3{œdataTypeœ:œChatInputœ,œidœ:œChatInput-BUgw3œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-gjXon{œfieldNameœ:œinput_valueœ,œidœ:œPrompt-gjXonœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-KgyhN", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-KgyhNœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-o2zd8", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œPrompt-o2zd8œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + "source": "ChatInput-BUgw3", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-BUgw3œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-gjXon", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œPrompt-gjXonœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -36,7 +36,7 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-I3JbF", + "id": "Prompt-pmjSJ", "name": "prompt", "output_types": [ "Message" @@ -44,19 +44,19 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "Agent-TPxdA", + "id": "Agent-Z2V8G", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-I3JbF{œdataTypeœ:œPromptœ,œidœ:œPrompt-I3JbFœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-TPxdA{œfieldNameœ:œinput_valueœ,œidœ:œAgent-TPxdAœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Prompt-pmjSJ{œdataTypeœ:œPromptœ,œidœ:œPrompt-pmjSJœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-Z2V8G{œfieldNameœ:œinput_valueœ,œidœ:œAgent-Z2V8Gœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-I3JbF", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-I3JbFœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-TPxdA", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-TPxdAœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-pmjSJ", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-pmjSJœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-Z2V8G", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-Z2V8Gœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -64,7 +64,7 @@ "data": { "sourceHandle": { "dataType": "Agent", - "id": "Agent-TPxdA", + "id": "Agent-Z2V8G", "name": "response", "output_types": [ "Message" @@ -72,7 +72,7 @@ }, "targetHandle": { "fieldName": "search_results", - "id": "Prompt-o2zd8", + "id": "Prompt-gjXon", "inputTypes": [ "Message", "Text" @@ -80,12 +80,12 @@ "type": "str" } }, - "id": "reactflow__edge-Agent-TPxdA{œdataTypeœ:œAgentœ,œidœ:œAgent-TPxdAœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-o2zd8{œfieldNameœ:œsearch_resultsœ,œidœ:œPrompt-o2zd8œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Agent-Z2V8G{œdataTypeœ:œAgentœ,œidœ:œAgent-Z2V8Gœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-gjXon{œfieldNameœ:œsearch_resultsœ,œidœ:œPrompt-gjXonœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", "selected": false, - "source": "Agent-TPxdA", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-TPxdAœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-o2zd8", - "targetHandle": "{œfieldNameœ: œsearch_resultsœ, œidœ: œPrompt-o2zd8œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + "source": "Agent-Z2V8G", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-Z2V8Gœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-gjXon", + "targetHandle": "{œfieldNameœ: œsearch_resultsœ, œidœ: œPrompt-gjXonœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -93,7 +93,7 @@ "data": { "sourceHandle": { "dataType": "TavilySearchComponent", - "id": "TavilySearchComponent-okHYL", + "id": "TavilySearchComponent-bQqQ3", "name": "component_as_tool", "output_types": [ "Tool" @@ -101,19 +101,19 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-TPxdA", + "id": "Agent-Z2V8G", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "reactflow__edge-TavilySearchComponent-okHYL{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-okHYLœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-TPxdA{œfieldNameœ:œtoolsœ,œidœ:œAgent-TPxdAœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-TavilySearchComponent-bQqQ3{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-bQqQ3œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-Z2V8G{œfieldNameœ:œtoolsœ,œidœ:œAgent-Z2V8Gœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", "selected": false, - "source": "TavilySearchComponent-okHYL", - "sourceHandle": "{œdataTypeœ: œTavilySearchComponentœ, œidœ: œTavilySearchComponent-okHYLœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-TPxdA", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-TPxdAœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "source": "TavilySearchComponent-bQqQ3", + "sourceHandle": "{œdataTypeœ: œTavilySearchComponentœ, œidœ: œTavilySearchComponent-bQqQ3œ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-Z2V8G", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-Z2V8Gœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -121,7 +121,7 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-saNk6", + "id": "Prompt-GEpb2", "name": "prompt", "output_types": [ "Message" @@ -129,19 +129,19 @@ }, "targetHandle": { "fieldName": "system_message", - "id": "OpenAIModel-sO8rf", + "id": "OpenAIModel-6XjJL", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-saNk6{œdataTypeœ:œPromptœ,œidœ:œPrompt-saNk6œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-sO8rf{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-sO8rfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Prompt-GEpb2{œdataTypeœ:œPromptœ,œidœ:œPrompt-GEpb2œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-6XjJL{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-6XjJLœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-saNk6", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-saNk6œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-sO8rf", - "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œOpenAIModel-sO8rfœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-GEpb2", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-GEpb2œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-6XjJL", + "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œOpenAIModel-6XjJLœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -149,7 +149,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-KgyhN", + "id": "ChatInput-BUgw3", "name": "message", "output_types": [ "Message" @@ -157,19 +157,19 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "OpenAIModel-sO8rf", + "id": "OpenAIModel-6XjJL", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ChatInput-KgyhN{œdataTypeœ:œChatInputœ,œidœ:œChatInput-KgyhNœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-sO8rf{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-sO8rfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-BUgw3{œdataTypeœ:œChatInputœ,œidœ:œChatInput-BUgw3œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-6XjJL{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-6XjJLœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-KgyhN", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-KgyhNœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-sO8rf", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-sO8rfœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatInput-BUgw3", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-BUgw3œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-6XjJL", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-6XjJLœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -177,7 +177,7 @@ "data": { "sourceHandle": { "dataType": "OpenAIModel", - "id": "OpenAIModel-sO8rf", + "id": "OpenAIModel-6XjJL", "name": "text_output", "output_types": [ "Message" @@ -185,7 +185,7 @@ }, "targetHandle": { "fieldName": "previous_response", - "id": "Prompt-I3JbF", + "id": "Prompt-pmjSJ", "inputTypes": [ "Message", "Text" @@ -193,12 +193,12 @@ "type": "str" } }, - "id": "reactflow__edge-OpenAIModel-sO8rf{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-sO8rfœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-I3JbF{œfieldNameœ:œprevious_responseœ,œidœ:œPrompt-I3JbFœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-OpenAIModel-6XjJL{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-6XjJLœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-pmjSJ{œfieldNameœ:œprevious_responseœ,œidœ:œPrompt-pmjSJœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", "selected": false, - "source": "OpenAIModel-sO8rf", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-sO8rfœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-I3JbF", - "targetHandle": "{œfieldNameœ: œprevious_responseœ, œidœ: œPrompt-I3JbFœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + "source": "OpenAIModel-6XjJL", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-6XjJLœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-pmjSJ", + "targetHandle": "{œfieldNameœ: œprevious_responseœ, œidœ: œPrompt-pmjSJœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -206,7 +206,7 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-o2zd8", + "id": "Prompt-gjXon", "name": "prompt", "output_types": [ "Message" @@ -214,19 +214,19 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "OpenAIModel-1pnlf", + "id": "OpenAIModel-rCRSl", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-o2zd8{œdataTypeœ:œPromptœ,œidœ:œPrompt-o2zd8œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-1pnlf{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-1pnlfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Prompt-gjXon{œdataTypeœ:œPromptœ,œidœ:œPrompt-gjXonœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-rCRSl{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-rCRSlœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-o2zd8", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-o2zd8œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-1pnlf", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-1pnlfœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-gjXon", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-gjXonœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-rCRSl", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-rCRSlœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -234,7 +234,7 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-z31Nf", + "id": "Prompt-LzmiE", "name": "prompt", "output_types": [ "Message" @@ -242,19 +242,19 @@ }, "targetHandle": { "fieldName": "system_message", - "id": "OpenAIModel-1pnlf", + "id": "OpenAIModel-rCRSl", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-z31Nf{œdataTypeœ:œPromptœ,œidœ:œPrompt-z31Nfœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-1pnlf{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-1pnlfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Prompt-LzmiE{œdataTypeœ:œPromptœ,œidœ:œPrompt-LzmiEœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-rCRSl{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-rCRSlœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-z31Nf", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-z31Nfœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-1pnlf", - "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œOpenAIModel-1pnlfœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-LzmiE", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-LzmiEœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-rCRSl", + "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œOpenAIModel-rCRSlœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -262,7 +262,7 @@ "data": { "sourceHandle": { "dataType": "OpenAIModel", - "id": "OpenAIModel-1pnlf", + "id": "OpenAIModel-rCRSl", "name": "text_output", "output_types": [ "Message" @@ -270,7 +270,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-Fg9B4", + "id": "ChatOutput-qShGq", "inputTypes": [ "Data", "DataFrame", @@ -279,12 +279,12 @@ "type": "other" } }, - "id": "reactflow__edge-OpenAIModel-1pnlf{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-1pnlfœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-Fg9B4{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-Fg9B4œ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-OpenAIModel-rCRSl{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-rCRSlœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-qShGq{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-qShGqœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}", "selected": false, - "source": "OpenAIModel-1pnlf", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-1pnlfœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-Fg9B4", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-Fg9B4œ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}" + "source": "OpenAIModel-rCRSl", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-rCRSlœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-qShGq", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-qShGqœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}" } ], "nodes": [ @@ -292,7 +292,7 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-I3JbF", + "id": "Prompt-pmjSJ", "node": { "base_classes": [ "Message" @@ -314,7 +314,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.3", "metadata": {}, "output_types": [], "outputs": [ @@ -425,7 +425,7 @@ }, "dragging": false, "height": 347, - "id": "Prompt-I3JbF", + "id": "Prompt-pmjSJ", "measured": { "height": 347, "width": 320 @@ -444,7 +444,7 @@ }, { "data": { - "id": "ChatInput-KgyhN", + "id": "ChatInput-BUgw3", "node": { "base_classes": [ "Message" @@ -472,7 +472,7 @@ "icon": "MessagesSquare", "key": "ChatInput", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.3", "metadata": {}, "output_types": [], "outputs": [ @@ -723,7 +723,7 @@ }, "dragging": false, "height": 234, - "id": "ChatInput-KgyhN", + "id": "ChatInput-BUgw3", "measured": { "height": 234, "width": 320 @@ -744,7 +744,7 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-o2zd8", + "id": "Prompt-gjXon", "node": { "base_classes": [ "Message" @@ -767,7 +767,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.3", "metadata": {}, "output_types": [], "outputs": [ @@ -901,7 +901,7 @@ }, "dragging": false, "height": 433, - "id": "Prompt-o2zd8", + "id": "Prompt-gjXon", "measured": { "height": 433, "width": 320 @@ -920,7 +920,7 @@ }, { "data": { - "id": "note-DarNU", + "id": "note-KPs4x", "node": { "description": "# Research Agent \n\nWelcome to the Research Agent! This flow helps you conduct in-depth research on various topics using AI-powered tools and analysis.\n\n## Instructions\n1. Enter Your Research Query\n - Type your research question or topic into the Chat Input node.\n - Be specific and clear about what you want to investigate.\n\n2. Generate Research Plan\n - The system will create a focused research plan based on your query.\n - This plan includes key search queries and priorities.\n\n3. Conduct Web Search\n - The Tavily AI Search tool will perform web searches using the generated queries.\n - It focuses on finding academic and reliable sources.\n\n4. Analyze and Synthesize\n - The AI agent will review the search results and create a comprehensive synthesis.\n - The report includes an executive summary, methodology, findings, and conclusions.\n\n5. Review the Output\n - Read the final report in the Chat Output node.\n - Use this information as a starting point for further research or decision-making.\n\nRemember: You can refine your initial query for more specific results! 🔍📊", "display_name": "", @@ -933,7 +933,7 @@ }, "dragging": false, "height": 694, - "id": "note-DarNU", + "id": "note-KPs4x", "measured": { "height": 694, "width": 325 @@ -959,7 +959,7 @@ "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "Agent", - "id": "Agent-TPxdA", + "id": "Agent-Z2V8G", "node": { "base_classes": [ "Message" @@ -1002,7 +1002,7 @@ "frozen": false, "icon": "bot", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.3", "metadata": {}, "output_types": [], "outputs": [ @@ -1108,7 +1108,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -1631,7 +1631,7 @@ }, "dragging": false, "height": 658, - "id": "Agent-TPxdA", + "id": "Agent-Z2V8G", "measured": { "height": 658, "width": 320 @@ -1652,7 +1652,7 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-saNk6", + "id": "Prompt-GEpb2", "node": { "base_classes": [ "Message" @@ -1672,7 +1672,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.3", "metadata": {}, "output_types": [], "outputs": [ @@ -1760,7 +1760,7 @@ }, "dragging": false, "height": 260, - "id": "Prompt-saNk6", + "id": "Prompt-GEpb2", "measured": { "height": 260, "width": 320 @@ -1781,7 +1781,7 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-z31Nf", + "id": "Prompt-LzmiE", "node": { "base_classes": [ "Message" @@ -1801,7 +1801,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.3", "metadata": {}, "output_types": [], "outputs": [ @@ -1889,7 +1889,7 @@ }, "dragging": false, "height": 260, - "id": "Prompt-z31Nf", + "id": "Prompt-LzmiE", "measured": { "height": 260, "width": 320 @@ -1908,7 +1908,7 @@ }, { "data": { - "id": "note-ZQq6I", + "id": "note-J4Hc2", "node": { "description": "# 🔑 Tavily AI Search Needs API Key\n\nYou can get 1000 searches/month free [here](https://tavily.com/) ", "display_name": "", @@ -1921,7 +1921,7 @@ }, "dragging": false, "height": 325, - "id": "note-ZQq6I", + "id": "note-J4Hc2", "measured": { "height": 325, "width": 326 @@ -1940,7 +1940,7 @@ }, { "data": { - "id": "TavilySearchComponent-okHYL", + "id": "TavilySearchComponent-bQqQ3", "node": { "base_classes": [ "Data", @@ -1966,6 +1966,7 @@ "frozen": false, "icon": "TavilyIcon", "legacy": false, + "lf_version": "1.4.3", "metadata": {}, "minimized": false, "output_types": [], @@ -1974,6 +1975,7 @@ "allows_loop": false, "cache": true, "display_name": "Toolset", + "group_outputs": false, "hidden": null, "method": "to_toolkit", "name": "component_as_tool", @@ -2005,7 +2007,7 @@ "show": true, "title_case": false, "type": "str", - "value": "TAVILY_API_KEY" + "value": "" }, "chunks_per_source": { "_input_type": "IntInput", @@ -2250,11 +2252,11 @@ "type": "str" }, "tools_metadata": { - "_input_type": "TableInput", + "_input_type": "ToolsInput", "advanced": false, - "display_name": "Edit tools", + "display_name": "Actions", "dynamic": false, - "info": "", + "info": "Modify tool names and descriptions to help agents understand when to use each tool.", "is_list": true, "list_add_label": "Add More", "name": "tools_metadata", @@ -2262,100 +2264,28 @@ "real_time_refresh": true, "required": false, "show": true, - "table_icon": "Hammer", - "table_options": { - "block_add": true, - "block_delete": true, - "block_edit": true, - "block_filter": true, - "block_hide": true, - "block_select": true, - "block_sort": true, - "description": "Modify tool names and descriptions to help agents understand when to use each tool.", - "field_parsers": { - "commands": "commands", - "name": [ - "snake_case", - "no_blank" - ] - }, - "hide_options": true - }, - "table_schema": { - "columns": [ - { - "default": "None", - "description": "Specify the name of the tool.", - "disable_edit": false, - "display_name": "Tool Name", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "hidden": false, - "name": "name", - "sortable": false, - "type": "str" - }, - { - "default": "None", - "description": "Describe the purpose of the tool.", - "disable_edit": false, - "display_name": "Tool Description", - "edit_mode": "popover", - "filterable": false, - "formatter": "text", - "hidden": false, - "name": "description", - "sortable": false, - "type": "str" - }, - { - "default": "None", - "description": "The default identifiers for the tools and cannot be changed.", - "disable_edit": true, - "display_name": "Tool Identifiers", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "hidden": true, - "name": "tags", - "sortable": false, - "type": "str" - }, - { - "default": true, - "description": "Indicates whether the tool is currently active. Set to True to activate this tool.", - "disable_edit": false, - "display_name": "Enable", - "edit_mode": "popover", - "filterable": true, - "formatter": "boolean", - "hidden": false, - "name": "status", - "sortable": true, - "type": "boolean" - } - ] - }, "title_case": false, "tool_mode": false, "trace_as_metadata": true, - "trigger_icon": "Hammer", - "trigger_text": "", - "type": "table", + "type": "tools", "value": [ { - "description": "fetch_content(api_key: Message) - **Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", - "name": "TavilySearchComponent-fetch_content", + "args": { + "query": { + "default": "", + "description": "The search query you want to execute with Tavily.", + "title": "Query", + "type": "string" + } + }, + "description": "TavilySearchComponent. fetch_content_dataframe - **Tavily Search** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", + "display_description": "TavilySearchComponent. fetch_content_dataframe - **Tavily Search** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", + "display_name": "fetch_content_dataframe", + "name": "fetch_content_dataframe", + "readonly": false, + "status": true, "tags": [ - "TavilySearchComponent-fetch_content" - ] - }, - { - "description": "fetch_content_text(api_key: Message) - **Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", - "name": "TavilySearchComponent-fetch_content_text", - "tags": [ - "TavilySearchComponent-fetch_content_text" + "fetch_content_dataframe" ] } ] @@ -2391,9 +2321,9 @@ "type": "TavilySearchComponent" }, "dragging": false, - "id": "TavilySearchComponent-okHYL", + "id": "TavilySearchComponent-bQqQ3", "measured": { - "height": 437, + "height": 316, "width": 320 }, "position": { @@ -2405,7 +2335,7 @@ }, { "data": { - "id": "OpenAIModel-sO8rf", + "id": "OpenAIModel-6XjJL", "node": { "base_classes": [ "LanguageModel", @@ -2436,6 +2366,7 @@ "icon": "OpenAI", "key": "OpenAIModel", "legacy": false, + "lf_version": "1.4.3", "metadata": { "keywords": [ "model", @@ -2495,7 +2426,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -2781,9 +2712,9 @@ "type": "OpenAIModel" }, "dragging": false, - "id": "OpenAIModel-sO8rf", + "id": "OpenAIModel-6XjJL", "measured": { - "height": 525, + "height": 539, "width": 320 }, "position": { @@ -2795,7 +2726,7 @@ }, { "data": { - "id": "OpenAIModel-1pnlf", + "id": "OpenAIModel-rCRSl", "node": { "base_classes": [ "LanguageModel", @@ -2826,6 +2757,7 @@ "icon": "OpenAI", "key": "OpenAIModel", "legacy": false, + "lf_version": "1.4.3", "metadata": { "keywords": [ "model", @@ -2885,7 +2817,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -3171,9 +3103,9 @@ "type": "OpenAIModel" }, "dragging": false, - "id": "OpenAIModel-1pnlf", + "id": "OpenAIModel-rCRSl", "measured": { - "height": 525, + "height": 539, "width": 320 }, "position": { @@ -3185,7 +3117,7 @@ }, { "data": { - "id": "ChatOutput-Fg9B4", + "id": "ChatOutput-qShGq", "node": { "base_classes": [ "Message" @@ -3214,6 +3146,7 @@ "icon": "MessagesSquare", "key": "ChatOutput", "legacy": false, + "lf_version": "1.4.3", "metadata": {}, "minimized": true, "output_types": [], @@ -3480,9 +3413,9 @@ "showNode": false, "type": "ChatOutput" }, - "id": "ChatOutput-Fg9B4", + "id": "ChatOutput-qShGq", "measured": { - "height": 66, + "height": 48, "width": 192 }, "position": { @@ -3494,16 +3427,16 @@ } ], "viewport": { - "x": -154.13080129013133, - "y": 193.27768148412844, - "zoom": 0.436204605187947 + "x": -270.56486809177886, + "y": 55.40724387742989, + "zoom": 0.4817049597080576 } }, "description": "Agent that generates focused plans, conducts web searches, and synthesizes findings into comprehensive reports.", "endpoint_name": null, - "id": "b833e38c-c394-4bde-b35c-334ce43a0476", + "id": "c42f508b-de52-4d07-b2fa-ffe15e5212a1", "is_component": false, - "last_tested_version": "1.2.0", + "last_tested_version": "1.4.3", "name": "Research Agent", "tags": [ "assistants", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json b/src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json index 7893dbecc..0ec42a571 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json @@ -7,27 +7,27 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-KlZxj", + "id": "Prompt-CMP8r", "name": "prompt", "output_types": [ "Message" ] }, "targetHandle": { - "fieldName": "system_message", - "id": "OpenAIModel-xbTZw", + "fieldName": "input_value", + "id": "LanguageModelComponent-v0n1N", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-KlZxj{œdataTypeœ:œPromptœ,œidœ:œPrompt-KlZxjœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-xbTZw{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-xbTZwœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "xy-edge__Prompt-CMP8r{œdataTypeœ:œPromptœ,œidœ:œPrompt-CMP8rœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-v0n1N{œfieldNameœ:œinput_valueœ,œidœ:œLanguageModelComponent-v0n1Nœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-KlZxj", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-KlZxjœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-xbTZw", - "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œOpenAIModel-xbTZwœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-CMP8r", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-CMP8rœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-v0n1N", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œLanguageModelComponent-v0n1Nœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -35,35 +35,35 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-KHvO6", + "id": "Prompt-PZu7g", "name": "prompt", "output_types": [ "Message" ] }, "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-xbTZw", + "fieldName": "system_message", + "id": "LanguageModelComponent-v0n1N", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-KHvO6{œdataTypeœ:œPromptœ,œidœ:œPrompt-KHvO6œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-xbTZw{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-xbTZwœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "xy-edge__Prompt-PZu7g{œdataTypeœ:œPromptœ,œidœ:œPrompt-PZu7gœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-LanguageModelComponent-v0n1N{œfieldNameœ:œsystem_messageœ,œidœ:œLanguageModelComponent-v0n1Nœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-KHvO6", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-KHvO6œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-xbTZw", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-xbTZwœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-PZu7g", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-PZu7gœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "LanguageModelComponent-v0n1N", + "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œLanguageModelComponent-v0n1Nœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, "className": "", "data": { "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-xbTZw", + "dataType": "LanguageModelComponent", + "id": "LanguageModelComponent-v0n1N", "name": "text_output", "output_types": [ "Message" @@ -71,7 +71,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-iMyF9", + "id": "ChatOutput-2rZzN", "inputTypes": [ "Data", "DataFrame", @@ -80,12 +80,12 @@ "type": "str" } }, - "id": "reactflow__edge-OpenAIModel-xbTZw{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-xbTZwœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-iMyF9{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-iMyF9œ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", + "id": "xy-edge__LanguageModelComponent-v0n1N{œdataTypeœ:œLanguageModelComponentœ,œidœ:œLanguageModelComponent-v0n1Nœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-2rZzN{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-2rZzNœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "OpenAIModel-xbTZw", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-xbTZwœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-iMyF9", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-iMyF9œ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" + "source": "LanguageModelComponent-v0n1N", + "sourceHandle": "{œdataTypeœ: œLanguageModelComponentœ, œidœ: œLanguageModelComponent-v0n1Nœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-2rZzN", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-2rZzNœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" } ], "nodes": [ @@ -93,7 +93,7 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-KHvO6", + "id": "Prompt-CMP8r", "node": { "base_classes": [ "Message" @@ -120,7 +120,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -346,7 +346,7 @@ }, "dragging": false, "height": 779, - "id": "Prompt-KHvO6", + "id": "Prompt-CMP8r", "measured": { "height": 779, "width": 320 @@ -359,15 +359,15 @@ "x": 816.9328565352126, "y": 189.70442453076902 }, - "selected": true, + "selected": false, "type": "genericNode", "width": 320 }, { "data": { - "id": "note-UCQVH", + "id": "note-PopoT", "node": { - "description": "# SEO Keyword Generator\nWelcome to the SEO Keywords Generator - an AI tool to create strategic keywords based on your product and audience profile!\n\n## Instructions\n\n1. **Fill Product Information**\n - Enter your product name and description\n - Keep it clear and specific\n - Highlight unique features and benefits\n\n2. **Define Pain Points**\n - List customer problems and challenges\n - Be specific about what frustrations they face\n - Include both practical and emotional pain points\n\n3. **Set Goals & Solutions**\n - Specify customer objectives\n - Detail how they currently solve problems\n - Outline desired outcomes\n\n4. **Target Audience Details**\n - Define demographics and characteristics\n - Include expertise level\n - Describe behavior patterns and preferences\n\n5. **Review Output**\n - Examine generated keywords\n - Check relevance and search intent\n - Use insights for SEO strategy planning\n\nRemember: The more detailed your input, the more targeted and effective your keywords will be! 🎯🔍✨", + "description": "## SEO Keyword Generator\n\nThis template creates strategic keywords based on your product and audience profile.\n\n### Prerequisites\n\n* [OpenAI API Key](https://platform.openai.com/)\n\n### Quickstart\n\n1. In the **Language Model** component, add your OpenAI API Key.\n\n2. In the **Prompt** component, complete the following fields. Optionally, just run the flow with the included example values.\n\n* Product Information\n* Pain Points\n* Goals\n* Target Audience\n* Expertise Level\n* Review Output \n\n3. Open the **Playground**, and then click **Run Flow**. The LLM generates keywords based on your inputs.", "display_name": "", "documentation": "", "template": {} @@ -375,15 +375,15 @@ "type": "note" }, "dragging": false, - "height": 607, - "id": "note-UCQVH", + "height": 716, + "id": "note-PopoT", "measured": { - "height": 607, - "width": 325 + "height": 716, + "width": 569 }, "position": { - "x": 221.74248905040588, - "y": 363.5469410934121 + "x": 147.91696397014965, + "y": 259.0768584326721 }, "positionAbsolute": { "x": 221.74248905040588, @@ -396,13 +396,13 @@ "width": 324 }, "type": "noteNode", - "width": 324 + "width": 568 }, { "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-KlZxj", + "id": "Prompt-PZu7g", "node": { "base_classes": [ "Message" @@ -422,7 +422,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -510,7 +510,7 @@ }, "dragging": false, "height": 260, - "id": "Prompt-KlZxj", + "id": "Prompt-PZu7g", "measured": { "height": 260, "width": 320 @@ -531,7 +531,7 @@ "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-iMyF9", + "id": "ChatOutput-2rZzN", "node": { "base_classes": [ "Message" @@ -557,7 +557,7 @@ "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -814,7 +814,7 @@ }, "dragging": false, "height": 234, - "id": "ChatOutput-iMyF9", + "id": "ChatOutput-2rZzN", "measured": { "height": 234, "width": 320 @@ -833,67 +833,58 @@ }, { "data": { - "id": "note-wwutt", + "id": "note-Wojgl", "node": { - "description": "## Make sure to add your OpenAI API key from [platform.openai.com](https://platform.openai.com). ", + "description": "### 💡 Add your OpenAI API key here", "display_name": "", "documentation": "", - "template": {} + "template": { + "backgroundColor": "transparent" + } }, "type": "note" }, "dragging": false, - "height": 325, - "id": "note-wwutt", + "id": "note-Wojgl", "measured": { - "height": 325, - "width": 326 + "height": 324, + "width": 324 }, "position": { - "x": 1207.1996899547116, - "y": 260.0148704431837 - }, - "positionAbsolute": { - "x": 1207.1996899547116, - "y": 260.0148704431837 + "x": 1212.6765474786587, + "y": 346.5142342999466 }, "selected": false, - "type": "noteNode", - "width": 325 + "type": "noteNode" }, { "data": { - "id": "OpenAIModel-xbTZw", + "id": "LanguageModelComponent-v0n1N", "node": { "base_classes": [ "LanguageModel", "Message" ], "beta": false, - "category": "models", "conditional_paths": [], "custom_fields": {}, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", + "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", - "max_tokens", - "model_kwargs", - "json_mode", - "model_name", - "openai_api_base", - "api_key", - "temperature", - "seed" + "temperature" ], "frozen": false, - "icon": "OpenAI", - "key": "OpenAIModel", + "icon": "brain-circuit", "legacy": false, + "lf_version": "1.4.2", "metadata": { "keywords": [ "model", @@ -935,7 +926,7 @@ } ], "pinned": false, - "score": 2.220446049250313e-16, + "priority": 0, "template": { "_type": "Component", "api_key": { @@ -943,17 +934,18 @@ "advanced": false, "display_name": "OpenAI API Key", "dynamic": false, - "info": "The OpenAI API Key to use for the OpenAI model.", + "info": "Model Provider API key", "input_types": [], - "load_from_db": true, + "load_from_db": false, "name": "api_key", "password": true, "placeholder": "", - "required": true, + "real_time_refresh": true, + "required": false, "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -971,14 +963,14 @@ "show": true, "title_case": false, "type": "code", - "value": "from typing import Any\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import (\n OPENAI_MODEL_NAMES,\n OPENAI_REASONING_MODEL_NAMES,\n)\nfrom langflow.field_typing import LanguageModel\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.inputs.inputs import BoolInput, DictInput, DropdownInput, IntInput, SecretStrInput, SliderInput, StrInput\nfrom langflow.logging import logger\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n name = \"OpenAIModel\"\n\n inputs = [\n *LCModelComponent._base_inputs,\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n range_spec=RangeSpec(min=0, max=128000),\n ),\n DictInput(\n name=\"model_kwargs\",\n display_name=\"Model Kwargs\",\n advanced=True,\n info=\"Additional keyword arguments to pass to the model.\",\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n advanced=False,\n options=OPENAI_MODEL_NAMES + OPENAI_REASONING_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[1],\n combobox=True,\n real_time_refresh=True,\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. \"\n \"Defaults to https://api.openai.com/v1. \"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n required=True,\n ),\n SliderInput(\n name=\"temperature\",\n display_name=\"Temperature\",\n value=0.1,\n range_spec=RangeSpec(min=0, max=1, step=0.01),\n show=True,\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n IntInput(\n name=\"max_retries\",\n display_name=\"Max Retries\",\n info=\"The maximum number of retries to make when generating.\",\n advanced=True,\n value=5,\n ),\n IntInput(\n name=\"timeout\",\n display_name=\"Timeout\",\n info=\"The timeout for requests to OpenAI completion API.\",\n advanced=True,\n value=700,\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n parameters = {\n \"api_key\": SecretStr(self.api_key).get_secret_value() if self.api_key else None,\n \"model_name\": self.model_name,\n \"max_tokens\": self.max_tokens or None,\n \"model_kwargs\": self.model_kwargs or {},\n \"base_url\": self.openai_api_base or \"https://api.openai.com/v1\",\n \"seed\": self.seed,\n \"max_retries\": self.max_retries,\n \"timeout\": self.timeout,\n \"temperature\": self.temperature if self.temperature is not None else 0.1,\n }\n\n logger.info(f\"Model name: {self.model_name}\")\n if self.model_name in OPENAI_REASONING_MODEL_NAMES:\n logger.info(\"Getting reasoning model parameters\")\n parameters.pop(\"temperature\")\n parameters.pop(\"seed\")\n output = ChatOpenAI(**parameters)\n if self.json_mode:\n output = output.bind(response_format={\"type\": \"json_object\"})\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"Get a message from an OpenAI exception.\n\n Args:\n e (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n try:\n from openai import BadRequestError\n except ImportError:\n return None\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\")\n if message:\n return message\n return None\n\n def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None) -> dict:\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_REASONING_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = False\n build_config[\"seed\"][\"show\"] = False\n if field_name in {\"base_url\", \"model_name\", \"api_key\"} and field_value in OPENAI_MODEL_NAMES:\n build_config[\"temperature\"][\"show\"] = True\n build_config[\"seed\"][\"show\"] = True\n return build_config\n" + "value": "from typing import Any\n\nfrom langchain_anthropic import ChatAnthropic\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nfrom langchain_openai import ChatOpenAI\n\nfrom 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\": \"Google\"}],\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", + "_input_type": "MessageTextInput", "advanced": false, "display_name": "Input", "dynamic": false, - "info": "", + "info": "The input text to send to the model", "input_types": [ "Message" ], @@ -996,92 +988,14 @@ "type": "str", "value": "" }, - "json_mode": { - "_input_type": "BoolInput", - "advanced": true, - "display_name": "JSON Mode", - "dynamic": false, - "info": "If True, it will output JSON regardless of passing a schema.", - "list": false, - "list_add_label": "Add More", - "name": "json_mode", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "bool", - "value": false - }, - "max_retries": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Retries", - "dynamic": false, - "info": "The maximum number of retries to make when generating.", - "list": false, - "list_add_label": "Add More", - "name": "max_retries", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 5 - }, - "max_tokens": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "list_add_label": "Add More", - "name": "max_tokens", - "placeholder": "", - "range_spec": { - "max": 128000, - "min": 0, - "step": 0.1, - "step_type": "float" - }, - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": "" - }, - "model_kwargs": { - "_input_type": "DictInput", - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "info": "Additional keyword arguments to pass to the model.", - "list": false, - "list_add_label": "Add More", - "name": "model_kwargs", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "type": "dict", - "value": {} - }, "model_name": { "_input_type": "DropdownInput", "advanced": false, - "combobox": true, + "combobox": false, "dialog_inputs": {}, "display_name": "Model Name", "dynamic": false, - "info": "", + "info": "Select the model to use", "name": "model_name", "options": [ "gpt-4o-mini", @@ -1093,62 +1007,61 @@ "gpt-4-turbo", "gpt-4-turbo-preview", "gpt-4", - "gpt-3.5-turbo", - "o1" + "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-4.1-mini" + "value": "gpt-4o-mini" }, - "openai_api_base": { - "_input_type": "StrInput", - "advanced": true, - "display_name": "OpenAI API Base", + "provider": { + "_input_type": "DropdownInput", + "advanced": false, + "combobox": false, + "dialog_inputs": {}, + "display_name": "Model Provider", "dynamic": false, - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.", - "list": false, - "list_add_label": "Add More", - "load_from_db": false, - "name": "openai_api_base", + "info": "Select the model provider", + "name": "provider", + "options": [ + "OpenAI", + "Anthropic", + "Google" + ], + "options_metadata": [ + { + "icon": "OpenAI" + }, + { + "icon": "Anthropic" + }, + { + "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": "" - }, - "seed": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Seed", - "dynamic": false, - "info": "The seed controls the reproducibility of the job.", - "list": false, - "list_add_label": "Add More", - "name": "seed", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 1 + "value": "OpenAI" }, "stream": { "_input_type": "BoolInput", "advanced": true, "display_name": "Stream", "dynamic": false, - "info": "Stream the response from the model. Streaming works only in Chat.", + "info": "Whether to stream the response", "list": false, "list_add_label": "Add More", "name": "stream", @@ -1162,18 +1075,17 @@ "value": false }, "system_message": { - "_input_type": "MultilineInput", - "advanced": false, + "_input_type": "MessageTextInput", + "advanced": true, "display_name": "System Message", "dynamic": false, - "info": "System message to pass to the model.", + "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, @@ -1187,10 +1099,10 @@ }, "temperature": { "_input_type": "SliderInput", - "advanced": false, + "advanced": true, "display_name": "Temperature", "dynamic": false, - "info": "", + "info": "Controls randomness in responses", "max_label": "", "max_label_icon": "", "min_label": "", @@ -1212,57 +1124,38 @@ "tool_mode": false, "type": "slider", "value": 0.1 - }, - "timeout": { - "_input_type": "IntInput", - "advanced": true, - "display_name": "Timeout", - "dynamic": false, - "info": "The timeout for requests to OpenAI completion API.", - "list": false, - "list_add_label": "Add More", - "name": "timeout", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "type": "int", - "value": 700 } }, "tool_mode": false }, "showNode": true, - "type": "OpenAIModel", - "selected_output": "text_output" + "type": "LanguageModelComponent" }, "dragging": false, - "id": "OpenAIModel-xbTZw", + "id": "LanguageModelComponent-v0n1N", "measured": { - "height": 525, + "height": 534, "width": 320 }, "position": { - "x": 1211.6745177781336, - "y": 389.1200512413449 + "x": 1211.3850919018707, + "y": 419.17658202237317 }, "selected": false, "type": "genericNode" } ], "viewport": { - "x": -111.23719516361678, - "y": -172.21601486484758, - "zoom": 0.7759242611491008 + "x": -10.563204467302512, + "y": -29.97245595813189, + "zoom": 0.681755116725734 } }, "description": "Generates targeted SEO keywords based on product information, pain points, and customer profiles for strategic marketing.", "endpoint_name": null, - "id": "0908c10f-b941-4e96-89be-1c65337bbfbd", + "id": "d4228d1f-4f1b-48d6-8ffc-430f47bfb5d4", "is_component": false, - "last_tested_version": "1.2.0", + "last_tested_version": "1.4.2", "name": "SEO Keyword Generator", "tags": [ "chatbots", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json b/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json index 3ef1055ce..01faae61f 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json @@ -1,42 +1,13 @@ { "data": { "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-GgGua", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-SplPb", - "inputTypes": [ - "Data", - "DataFrame", - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-GgGua{œdataTypeœ:œAgentœ,œidœ:œAgent-GgGuaœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-SplPb{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-SplPbœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-GgGua", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-GgGuaœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-SplPb", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-SplPbœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" - }, { "animated": false, "className": "", "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-tqP9Q", + "id": "Prompt-PX9QB", "name": "prompt", "output_types": [ "Message" @@ -44,25 +15,27 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "Agent-GgGua", + "id": "Agent-sir3U", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-tqP9Q{œdataTypeœ:œPromptœ,œidœ:œPrompt-tqP9Qœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-GgGua{œfieldNameœ:œinput_valueœ,œidœ:œAgent-GgGuaœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-tqP9Q", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-tqP9Qœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-GgGua", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-GgGuaœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "id": "reactflow__edge-Prompt-PX9QB{œdataTypeœ:œPromptœ,œidœ:œPrompt-PX9QBœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-sir3U{œfieldNameœ:œinput_valueœ,œidœ:œAgent-sir3Uœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "Prompt-PX9QB", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-PX9QBœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-sir3U", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-sir3Uœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { + "animated": false, "className": "", "data": { "sourceHandle": { "dataType": "CalculatorComponent", - "id": "CalculatorComponent-LyoFm", + "id": "CalculatorComponent-JhT2c", "name": "component_as_tool", "output_types": [ "Tool" @@ -70,18 +43,49 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-GgGua", + "id": "Agent-sir3U", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "reactflow__edge-CalculatorComponent-LyoFm{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-LyoFmœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-GgGua{œfieldNameœ:œtoolsœ,œidœ:œAgent-GgGuaœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "source": "CalculatorComponent-LyoFm", - "sourceHandle": "{œdataTypeœ: œCalculatorComponentœ, œidœ: œCalculatorComponent-LyoFmœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-GgGua", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-GgGuaœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "id": "reactflow__edge-CalculatorComponent-JhT2c{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-JhT2cœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-sir3U{œfieldNameœ:œtoolsœ,œidœ:œAgent-sir3Uœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "selected": false, + "source": "CalculatorComponent-JhT2c", + "sourceHandle": "{œdataTypeœ: œCalculatorComponentœ, œidœ: œCalculatorComponent-JhT2cœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-sir3U", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-sir3Uœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-sir3U", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-tv6P2", + "inputTypes": [ + "Data", + "DataFrame", + "Message" + ], + "type": "other" + } + }, + "id": "xy-edge__Agent-sir3U{œdataTypeœ:œAgentœ,œidœ:œAgent-sir3Uœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-tv6P2{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-tv6P2œ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}", + "selected": false, + "source": "Agent-sir3U", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-sir3Uœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-tv6P2", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-tv6P2œ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}" } ], "nodes": [ @@ -89,7 +93,7 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-tqP9Q", + "id": "Prompt-PX9QB", "node": { "base_classes": [ "Message" @@ -115,7 +119,7 @@ "frozen": false, "icon": "braces", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -318,7 +322,7 @@ }, "dragging": false, "height": 693, - "id": "Prompt-tqP9Q", + "id": "Prompt-PX9QB", "measured": { "height": 693, "width": 320 @@ -339,7 +343,7 @@ "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-SplPb", + "id": "ChatOutput-tv6P2", "node": { "base_classes": [ "Message" @@ -360,13 +364,15 @@ "data_template", "background_color", "chat_icon", - "text_color" + "text_color", + "clean_data" ], "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.2", "metadata": {}, + "minimized": true, "output_types": [], "outputs": [ { @@ -397,6 +403,7 @@ "Message" ], "list": false, + "list_add_label": "Add More", "load_from_db": false, "name": "background_color", "placeholder": "", @@ -419,6 +426,7 @@ "Message" ], "list": false, + "list_add_label": "Add More", "load_from_db": false, "name": "chat_icon", "placeholder": "", @@ -477,6 +485,7 @@ "Message" ], "list": false, + "list_add_label": "Add More", "load_from_db": false, "name": "data_template", "placeholder": "", @@ -490,7 +499,7 @@ "value": "{text}" }, "input_value": { - "_input_type": "MessageInput", + "_input_type": "HandleInput", "advanced": false, "display_name": "Inputs", "dynamic": false, @@ -501,21 +510,21 @@ "Message" ], "list": false, - "load_from_db": false, + "list_add_label": "Add More", "name": "input_value", "placeholder": "", "required": true, "show": true, "title_case": false, - "trace_as_input": true, "trace_as_metadata": true, - "type": "str", + "type": "other", "value": "" }, "sender": { "_input_type": "DropdownInput", "advanced": true, "combobox": false, + "dialog_inputs": {}, "display_name": "Sender Type", "dynamic": false, "info": "Type of sender.", @@ -524,10 +533,12 @@ "Machine", "User" ], + "options_metadata": [], "placeholder": "", "required": false, "show": true, "title_case": false, + "toggle": false, "tool_mode": false, "trace_as_metadata": true, "type": "str", @@ -543,6 +554,7 @@ "Message" ], "list": false, + "list_add_label": "Add More", "load_from_db": false, "name": "sender_name", "placeholder": "", @@ -565,6 +577,7 @@ "Message" ], "list": false, + "list_add_label": "Add More", "load_from_db": false, "name": "session_id", "placeholder": "", @@ -584,11 +597,13 @@ "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 @@ -603,6 +618,7 @@ "Message" ], "list": false, + "list_add_label": "Add More", "load_from_db": false, "name": "text_color", "placeholder": "", @@ -622,7 +638,7 @@ }, "dragging": false, "height": 234, - "id": "ChatOutput-SplPb", + "id": "ChatOutput-tv6P2", "measured": { "height": 234, "width": 320 @@ -635,13 +651,13 @@ "x": 2240.3625274769397, "y": 355.16302699218204 }, - "selected": false, + "selected": true, "type": "genericNode", "width": 320 }, { "data": { - "id": "note-VL2VP", + "id": "note-PwGXK", "node": { "description": "# SaaS Pricing Calculator\n\nWelcome to the SaaS Pricing Calculator! This flow helps you determine the optimal monthly subscription price for your software service.\n\n## Instructions\n\n1. Prepare Your Data\n - Gather information on monthly infrastructure costs\n - Calculate customer support expenses\n - Estimate continuous development costs\n - Decide on your desired profit margin\n - Determine the estimated number of subscribers\n\n2. Input Values\n - Enter the gathered data into the respective fields in the Prompt node\n - Double-check the accuracy of your inputs\n\n3. Run the Flow\n - Click the \"Run\" button to start the calculation process\n - The flow will use Chain-of-Thought prompting to guide the AI through the steps\n\n4. Review the Results\n - Examine the output in the Chat Output node\n - The result will show a breakdown of costs and the final subscription price\n\n5. Adjust and Refine\n - If needed, modify your inputs to explore different pricing scenarios\n - Re-run the flow to see how changes affect the final price\n\nRemember: Regularly update your costs and subscriber estimates to keep your pricing model accurate and competitive! 💼📊", "display_name": "", @@ -652,10 +668,10 @@ }, "dragging": false, "height": 800, - "id": "note-VL2VP", + "id": "note-PwGXK", "measured": { "height": 800, - "width": 324 + "width": 325 }, "position": { "x": 689.7659055360411, @@ -666,7 +682,7 @@ "y": 68.95847391680593 }, "resizing": false, - "selected": true, + "selected": false, "style": { "height": 800, "width": 324 @@ -678,7 +694,7 @@ "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "Agent", - "id": "Agent-GgGua", + "id": "Agent-sir3U", "node": { "base_classes": [ "Message" @@ -721,7 +737,7 @@ "frozen": false, "icon": "bot", "legacy": false, - "lf_version": "1.0.19.post2", + "lf_version": "1.4.2", "metadata": {}, "output_types": [], "outputs": [ @@ -827,7 +843,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -1350,7 +1366,7 @@ }, "dragging": false, "height": 650, - "id": "Agent-GgGua", + "id": "Agent-sir3U", "measured": { "height": 650, "width": 320 @@ -1369,7 +1385,7 @@ }, { "data": { - "id": "CalculatorComponent-LyoFm", + "id": "CalculatorComponent-JhT2c", "node": { "base_classes": [ "Data" @@ -1389,6 +1405,7 @@ "icon": "calculator", "key": "CalculatorComponent", "legacy": false, + "lf_version": "1.4.2", "metadata": {}, "minimized": false, "output_types": [], @@ -1397,11 +1414,14 @@ "allows_loop": false, "cache": true, "display_name": "Toolset", + "group_outputs": false, "hidden": null, "method": "to_toolkit", "name": "component_as_tool", + "options": null, "required_inputs": null, "selected": "Tool", + "tool_mode": true, "types": [ "Tool" ], @@ -1454,11 +1474,11 @@ "value": "" }, "tools_metadata": { - "_input_type": "TableInput", + "_input_type": "ToolsInput", "advanced": false, - "display_name": "Edit tools", + "display_name": "Actions", "dynamic": false, - "info": "", + "info": "Modify tool names and descriptions to help agents understand when to use each tool.", "is_list": true, "list_add_label": "Add More", "name": "tools_metadata", @@ -1466,74 +1486,28 @@ "real_time_refresh": true, "required": false, "show": true, - "table_icon": "Hammer", - "table_options": { - "block_add": true, - "block_delete": true, - "block_edit": true, - "block_filter": true, - "block_hide": true, - "block_select": true, - "block_sort": true, - "description": "Modify tool names and descriptions to help agents understand when to use each tool.", - "field_parsers": { - "commands": "commands", - "name": [ - "snake_case", - "no_blank" - ] - }, - "hide_options": true - }, - "table_schema": { - "columns": [ - { - "description": "Specify the name of the tool.", - "disable_edit": false, - "display_name": "Tool Name", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "name": "name", - "sortable": false, - "type": "text" - }, - { - "description": "Describe the purpose of the tool.", - "disable_edit": false, - "display_name": "Tool Description", - "edit_mode": "popover", - "filterable": false, - "formatter": "text", - "name": "description", - "sortable": false, - "type": "text" - }, - { - "description": "The default identifiers for the tools and cannot be changed.", - "disable_edit": true, - "display_name": "Tool Identifiers", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "name": "tags", - "sortable": false, - "type": "text" - } - ] - }, "title_case": false, "tool_mode": false, "trace_as_metadata": true, - "trigger_icon": "Hammer", - "trigger_text": "", - "type": "table", + "type": "tools", "value": [ { - "description": "evaluate_expression() - Perform basic arithmetic operations on a given expression.", - "name": "None-evaluate_expression", + "args": { + "expression": { + "default": "", + "description": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').", + "title": "Expression", + "type": "string" + } + }, + "description": "CalculatorComponent. evaluate_expression - Perform basic arithmetic operations on a given expression.", + "display_description": "CalculatorComponent. evaluate_expression - Perform basic arithmetic operations on a given expression.", + "display_name": "evaluate_expression", + "name": "evaluate_expression", + "readonly": false, + "status": true, "tags": [ - "None-evaluate_expression" + "evaluate_expression" ] } ] @@ -1546,9 +1520,9 @@ "type": "CalculatorComponent" }, "dragging": false, - "id": "CalculatorComponent-LyoFm", + "id": "CalculatorComponent-JhT2c", "measured": { - "height": 333, + "height": 218, "width": 320 }, "position": { @@ -1560,18 +1534,16 @@ } ], "viewport": { - "x": -419.5792282920602, - "y": 250.7080185506556, - "zoom": 0.7037132543294129 + "x": -514.4665122679305, + "y": 57.59497096606026, + "zoom": 0.5864177566573868 } }, "description": "Calculate SaaS subscription price based on costs, profit margin, and subscribers using step-by-step method and Chain-of-Thought prompting. ", "endpoint_name": null, - "gradient": "3", - "icon": "calculator", - "id": "9357f72e-2121-4541-8e7d-74b7ba2ada2b", + "id": "45470d4c-fade-4ec5-8bc1-96f14160d957", "is_component": false, - "last_tested_version": "1.1.1", + "last_tested_version": "1.4.2", "name": "SaaS Pricing", "tags": [ "agents", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json index 34b18339b..f21035332 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json @@ -7,7 +7,7 @@ "data": { "sourceHandle": { "dataType": "ApifyActors", - "id": "ApifyActors-n0Tjo", + "id": "ApifyActors-CVPGK", "name": "tool", "output_types": [ "Tool" @@ -15,19 +15,19 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-EePDq", + "id": "Agent-yJhxC", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "reactflow__edge-ApifyActors-n0Tjo{œdataTypeœ:œApifyActorsœ,œidœ:œApifyActors-n0Tjoœ,œnameœ:œtoolœ,œoutput_typesœ:[œToolœ]}-Agent-EePDq{œfieldNameœ:œtoolsœ,œidœ:œAgent-EePDqœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-ApifyActors-CVPGK{œdataTypeœ:œApifyActorsœ,œidœ:œApifyActors-CVPGKœ,œnameœ:œtoolœ,œoutput_typesœ:[œToolœ]}-Agent-yJhxC{œfieldNameœ:œtoolsœ,œidœ:œAgent-yJhxCœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", "selected": false, - "source": "ApifyActors-n0Tjo", - "sourceHandle": "{œdataTypeœ: œApifyActorsœ, œidœ: œApifyActors-n0Tjoœ, œnameœ: œtoolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-EePDq", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-EePDqœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "source": "ApifyActors-CVPGK", + "sourceHandle": "{œdataTypeœ: œApifyActorsœ, œidœ: œApifyActors-CVPGKœ, œnameœ: œtoolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-yJhxC", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-yJhxCœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -35,7 +35,7 @@ "data": { "sourceHandle": { "dataType": "ApifyActors", - "id": "ApifyActors-t44sy", + "id": "ApifyActors-tL94Y", "name": "tool", "output_types": [ "Tool" @@ -43,19 +43,19 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-EePDq", + "id": "Agent-yJhxC", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "reactflow__edge-ApifyActors-t44sy{œdataTypeœ:œApifyActorsœ,œidœ:œApifyActors-t44syœ,œnameœ:œtoolœ,œoutput_typesœ:[œToolœ]}-Agent-EePDq{œfieldNameœ:œtoolsœ,œidœ:œAgent-EePDqœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-ApifyActors-tL94Y{œdataTypeœ:œApifyActorsœ,œidœ:œApifyActors-tL94Yœ,œnameœ:œtoolœ,œoutput_typesœ:[œToolœ]}-Agent-yJhxC{œfieldNameœ:œtoolsœ,œidœ:œAgent-yJhxCœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", "selected": false, - "source": "ApifyActors-t44sy", - "sourceHandle": "{œdataTypeœ: œApifyActorsœ, œidœ: œApifyActors-t44syœ, œnameœ: œtoolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-EePDq", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-EePDqœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "source": "ApifyActors-tL94Y", + "sourceHandle": "{œdataTypeœ: œApifyActorsœ, œidœ: œApifyActors-tL94Yœ, œnameœ: œtoolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-yJhxC", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-yJhxCœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -63,7 +63,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-9joxW", + "id": "ChatInput-E01OU", "name": "message", "output_types": [ "Message" @@ -71,19 +71,19 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "Agent-EePDq", + "id": "Agent-yJhxC", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ChatInput-9joxW{œdataTypeœ:œChatInputœ,œidœ:œChatInput-9joxWœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-EePDq{œfieldNameœ:œinput_valueœ,œidœ:œAgent-EePDqœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-E01OU{œdataTypeœ:œChatInputœ,œidœ:œChatInput-E01OUœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-yJhxC{œfieldNameœ:œinput_valueœ,œidœ:œAgent-yJhxCœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-9joxW", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-9joxWœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-EePDq", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-EePDqœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatInput-E01OU", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-E01OUœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-yJhxC", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-yJhxCœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -91,7 +91,7 @@ "data": { "sourceHandle": { "dataType": "Agent", - "id": "Agent-EePDq", + "id": "Agent-yJhxC", "name": "response", "output_types": [ "Message" @@ -99,7 +99,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-dWtqL", + "id": "ChatOutput-xSo6b", "inputTypes": [ "Data", "DataFrame", @@ -108,18 +108,18 @@ "type": "other" } }, - "id": "reactflow__edge-Agent-EePDq{œdataTypeœ:œAgentœ,œidœ:œAgent-EePDqœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-dWtqL{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-dWtqLœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-Agent-yJhxC{œdataTypeœ:œAgentœ,œidœ:œAgent-yJhxCœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-xSo6b{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-xSo6bœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œotherœ}", "selected": false, - "source": "Agent-EePDq", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-EePDqœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-dWtqL", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-dWtqLœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}" + "source": "Agent-yJhxC", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-yJhxCœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-xSo6b", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-xSo6bœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œotherœ}" } ], "nodes": [ { "data": { - "id": "ApifyActors-t44sy", + "id": "ApifyActors-tL94Y", "node": { "base_classes": [ "Data", @@ -142,6 +142,7 @@ "frozen": false, "icon": "Apify", "legacy": false, + "lf_version": "1.4.2", "metadata": {}, "minimized": false, "output_types": [], @@ -154,7 +155,6 @@ "method": "run_model", "name": "output", "required_inputs": null, - "selected": "Data", "tool_mode": true, "types": [ "Data" @@ -214,7 +214,7 @@ "show": true, "title_case": false, "type": "str", - "value": "APIFY_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -308,9 +308,9 @@ "type": "ApifyActors" }, "dragging": false, - "id": "ApifyActors-t44sy", + "id": "ApifyActors-tL94Y", "measured": { - "height": 628, + "height": 526, "width": 320 }, "position": { @@ -322,7 +322,7 @@ }, { "data": { - "id": "ApifyActors-n0Tjo", + "id": "ApifyActors-CVPGK", "node": { "base_classes": [ "Data", @@ -345,6 +345,7 @@ "frozen": false, "icon": "Apify", "legacy": false, + "lf_version": "1.4.2", "metadata": {}, "minimized": false, "output_types": [], @@ -357,7 +358,6 @@ "method": "run_model", "name": "output", "required_inputs": null, - "selected": "Data", "tool_mode": true, "types": [ "Data" @@ -417,7 +417,7 @@ "show": true, "title_case": false, "type": "str", - "value": "APIFY_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -511,9 +511,9 @@ "type": "ApifyActors" }, "dragging": false, - "id": "ApifyActors-n0Tjo", + "id": "ApifyActors-CVPGK", "measured": { - "height": 628, + "height": 526, "width": 320 }, "position": { @@ -525,7 +525,7 @@ }, { "data": { - "id": "note-QhVg5", + "id": "note-hmQk5", "node": { "description": "### 💡 Add your Apify API key here ", "display_name": "", @@ -537,7 +537,7 @@ "type": "note" }, "dragging": false, - "id": "note-QhVg5", + "id": "note-hmQk5", "measured": { "height": 324, "width": 324 @@ -551,7 +551,7 @@ }, { "data": { - "id": "note-JuSWo", + "id": "note-Utxei", "node": { "description": "### 💡 Add your Apify API key here ", "display_name": "", @@ -564,7 +564,7 @@ }, "dragging": false, "height": 324, - "id": "note-JuSWo", + "id": "note-Utxei", "measured": { "height": 324, "width": 324 @@ -580,7 +580,7 @@ }, { "data": { - "id": "note-yDKv9", + "id": "note-NoZ4e", "node": { "description": "# Social Media Agent\n\nExtract data with **Apify Actors** and analyze the data with an **Agent**.\n\n## Prerequisites\n\n* An [Apify API token](https://docs.apify.com/platform/integrations/api#api-token)\n* An [OpenAI API key](https://platform.openai.com/)\n\n## Quickstart\n\n1. Enter your **Apify** API token in the **Apify Token** fields of the **Apify Actors** components. \n2. Enter your **OpenAI** API token in the **OpenAI API Key** field of the **Agent** component.\n3. Open the **Playground** and chat with the agent. For example, task it with retrieving a profile bio and the latest video by using this prompt: \n ```\n Find the TikTok profile of the company OpenAI using Google search, then show me the profile bio and their latest video.\n ```", "display_name": "", @@ -593,7 +593,7 @@ }, "dragging": false, "height": 657, - "id": "note-yDKv9", + "id": "note-NoZ4e", "measured": { "height": 657, "width": 525 @@ -609,7 +609,7 @@ }, { "data": { - "id": "ChatInput-9joxW", + "id": "ChatInput-E01OU", "node": { "base_classes": [ "Message" @@ -635,7 +635,7 @@ "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.1.5", + "lf_version": "1.4.2", "metadata": {}, "minimized": true, "output_types": [], @@ -906,9 +906,9 @@ "type": "ChatInput" }, "dragging": false, - "id": "ChatInput-9joxW", + "id": "ChatInput-E01OU", "measured": { - "height": 66, + "height": 48, "width": 192 }, "position": { @@ -920,7 +920,7 @@ }, { "data": { - "id": "ChatOutput-dWtqL", + "id": "ChatOutput-xSo6b", "node": { "base_classes": [ "Message" @@ -947,7 +947,7 @@ "frozen": false, "icon": "MessagesSquare", "legacy": false, - "lf_version": "1.1.5", + "lf_version": "1.4.2", "metadata": {}, "minimized": true, "output_types": [], @@ -1214,9 +1214,9 @@ "type": "ChatOutput" }, "dragging": false, - "id": "ChatOutput-dWtqL", + "id": "ChatOutput-xSo6b", "measured": { - "height": 66, + "height": 48, "width": 192 }, "position": { @@ -1228,7 +1228,7 @@ }, { "data": { - "id": "note-NYz05", + "id": "note-kMYOt", "node": { "description": "### 💡 Add your OpenAI API key here ", "display_name": "", @@ -1240,7 +1240,7 @@ "type": "note" }, "dragging": false, - "id": "note-NYz05", + "id": "note-kMYOt", "measured": { "height": 324, "width": 324 @@ -1254,7 +1254,7 @@ }, { "data": { - "id": "Agent-EePDq", + "id": "Agent-yJhxC", "node": { "base_classes": [ "Message" @@ -1299,6 +1299,7 @@ "icon": "bot", "key": "Agent", "legacy": false, + "lf_version": "1.4.2", "metadata": {}, "minimized": false, "output_types": [], @@ -1439,7 +1440,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -2008,9 +2009,9 @@ "type": "Agent" }, "dragging": false, - "id": "Agent-EePDq", + "id": "Agent-yJhxC", "measured": { - "height": 624, + "height": 594, "width": 320 }, "position": { @@ -2022,16 +2023,16 @@ } ], "viewport": { - "x": 280.5777285013439, - "y": 153.83586264930773, - "zoom": 0.6859951115676428 + "x": 251.14965955941773, + "y": 42.193990847111536, + "zoom": 0.5946080556136385 } }, "description": "Utilize Apify Actors as agent tools to search and analyze social media profiles.", "endpoint_name": null, - "id": "6aa57fa5-c085-4a30-8654-b56b4944679a", + "id": "08525bf9-dd32-4bbe-920c-169cffc78890", "is_component": false, - "last_tested_version": "1.2.0", + "last_tested_version": "1.4.2", "name": "Social Media Agent", "tags": [ "agent", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json index d93e804c3..a937fc328 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json @@ -7,7 +7,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-kNQkx", + "id": "ChatInput-1w4cJ", "name": "message", "output_types": [ "Message" @@ -15,7 +15,7 @@ }, "targetHandle": { "fieldName": "question", - "id": "Prompt-zHQI0", + "id": "Prompt-I9T0w", "inputTypes": [ "Message", "Text" @@ -23,12 +23,12 @@ "type": "str" } }, - "id": "reactflow__edge-ChatInput-kNQkx{œdataTypeœ:œChatInputœ,œidœ:œChatInput-kNQkxœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-zHQI0{œfieldNameœ:œquestionœ,œidœ:œPrompt-zHQI0œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-1w4cJ{œdataTypeœ:œChatInputœ,œidœ:œChatInput-1w4cJœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-I9T0w{œfieldNameœ:œquestionœ,œidœ:œPrompt-I9T0wœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-kNQkx", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-kNQkxœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-zHQI0", - "targetHandle": "{œfieldNameœ: œquestionœ, œidœ: œPrompt-zHQI0œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + "source": "ChatInput-1w4cJ", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-1w4cJœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-I9T0w", + "targetHandle": "{œfieldNameœ: œquestionœ, œidœ: œPrompt-I9T0wœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -36,7 +36,7 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-zHQI0", + "id": "Prompt-I9T0w", "name": "prompt", "output_types": [ "Message" @@ -44,19 +44,19 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "OpenAIModel-9bWp2", + "id": "OpenAIModel-GczRI", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-zHQI0{œdataTypeœ:œPromptœ,œidœ:œPrompt-zHQI0œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-9bWp2{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-9bWp2œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Prompt-I9T0w{œdataTypeœ:œPromptœ,œidœ:œPrompt-I9T0wœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-GczRI{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-GczRIœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-zHQI0", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-zHQI0œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-9bWp2", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-9bWp2œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-I9T0w", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-I9T0wœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-GczRI", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-GczRIœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -64,7 +64,7 @@ "data": { "sourceHandle": { "dataType": "OpenAIModel", - "id": "OpenAIModel-9bWp2", + "id": "OpenAIModel-GczRI", "name": "text_output", "output_types": [ "Message" @@ -72,7 +72,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-GAFHg", + "id": "ChatOutput-Dlahs", "inputTypes": [ "Data", "DataFrame", @@ -81,12 +81,12 @@ "type": "str" } }, - "id": "reactflow__edge-OpenAIModel-9bWp2{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-9bWp2œ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-GAFHg{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-GAFHgœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-OpenAIModel-GczRI{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-GczRIœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-Dlahs{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-Dlahsœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "OpenAIModel-9bWp2", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-9bWp2œ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-GAFHg", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-GAFHgœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" + "source": "OpenAIModel-GczRI", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-GczRIœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-Dlahs", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-Dlahsœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -94,7 +94,7 @@ "data": { "sourceHandle": { "dataType": "parser", - "id": "parser-Qet8H", + "id": "parser-IEn6I", "name": "parsed_text", "output_types": [ "Message" @@ -102,7 +102,7 @@ }, "targetHandle": { "fieldName": "context", - "id": "Prompt-zHQI0", + "id": "Prompt-I9T0w", "inputTypes": [ "Message", "Text" @@ -110,12 +110,12 @@ "type": "str" } }, - "id": "reactflow__edge-parser-Qet8H{œdataTypeœ:œparserœ,œidœ:œparser-Qet8Hœ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-Prompt-zHQI0{œfieldNameœ:œcontextœ,œidœ:œPrompt-zHQI0œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-parser-IEn6I{œdataTypeœ:œparserœ,œidœ:œparser-IEn6Iœ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-Prompt-I9T0w{œfieldNameœ:œcontextœ,œidœ:œPrompt-I9T0wœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", "selected": false, - "source": "parser-Qet8H", - "sourceHandle": "{œdataTypeœ: œparserœ, œidœ: œparser-Qet8Hœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-zHQI0", - "targetHandle": "{œfieldNameœ: œcontextœ, œidœ: œPrompt-zHQI0œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + "source": "parser-IEn6I", + "sourceHandle": "{œdataTypeœ: œparserœ, œidœ: œparser-IEn6Iœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-I9T0w", + "targetHandle": "{œfieldNameœ: œcontextœ, œidœ: œPrompt-I9T0wœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -123,7 +123,7 @@ "data": { "sourceHandle": { "dataType": "OpenAIEmbeddings", - "id": "OpenAIEmbeddings-D1jSt", + "id": "OpenAIEmbeddings-OlQ6R", "name": "embeddings", "output_types": [ "Embeddings" @@ -131,19 +131,19 @@ }, "targetHandle": { "fieldName": "embedding_model", - "id": "AstraDB-eQaxM", + "id": "AstraDB-8AuVs", "inputTypes": [ "Embeddings" ], "type": "other" } }, - "id": "reactflow__edge-OpenAIEmbeddings-D1jSt{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-D1jStœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}-AstraDB-eQaxM{œfieldNameœ:œembedding_modelœ,œidœ:œAstraDB-eQaxMœ,œinputTypesœ:[œEmbeddingsœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-OpenAIEmbeddings-OlQ6R{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-OlQ6Rœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}-AstraDB-8AuVs{œfieldNameœ:œembedding_modelœ,œidœ:œAstraDB-8AuVsœ,œinputTypesœ:[œEmbeddingsœ],œtypeœ:œotherœ}", "selected": false, - "source": "OpenAIEmbeddings-D1jSt", - "sourceHandle": "{œdataTypeœ: œOpenAIEmbeddingsœ, œidœ: œOpenAIEmbeddings-D1jStœ, œnameœ: œembeddingsœ, œoutput_typesœ: [œEmbeddingsœ]}", - "target": "AstraDB-eQaxM", - "targetHandle": "{œfieldNameœ: œembedding_modelœ, œidœ: œAstraDB-eQaxMœ, œinputTypesœ: [œEmbeddingsœ], œtypeœ: œotherœ}" + "source": "OpenAIEmbeddings-OlQ6R", + "sourceHandle": "{œdataTypeœ: œOpenAIEmbeddingsœ, œidœ: œOpenAIEmbeddings-OlQ6Rœ, œnameœ: œembeddingsœ, œoutput_typesœ: [œEmbeddingsœ]}", + "target": "AstraDB-8AuVs", + "targetHandle": "{œfieldNameœ: œembedding_modelœ, œidœ: œAstraDB-8AuVsœ, œinputTypesœ: [œEmbeddingsœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -151,7 +151,7 @@ "data": { "sourceHandle": { "dataType": "OpenAIEmbeddings", - "id": "OpenAIEmbeddings-4Uky4", + "id": "OpenAIEmbeddings-ulN0y", "name": "embeddings", "output_types": [ "Embeddings" @@ -159,19 +159,19 @@ }, "targetHandle": { "fieldName": "embedding_model", - "id": "AstraDB-tVkFw", + "id": "AstraDB-Wep9C", "inputTypes": [ "Embeddings" ], "type": "other" } }, - "id": "reactflow__edge-OpenAIEmbeddings-4Uky4{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-4Uky4œ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}-AstraDB-tVkFw{œfieldNameœ:œembedding_modelœ,œidœ:œAstraDB-tVkFwœ,œinputTypesœ:[œEmbeddingsœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-OpenAIEmbeddings-ulN0y{œdataTypeœ:œOpenAIEmbeddingsœ,œidœ:œOpenAIEmbeddings-ulN0yœ,œnameœ:œembeddingsœ,œoutput_typesœ:[œEmbeddingsœ]}-AstraDB-Wep9C{œfieldNameœ:œembedding_modelœ,œidœ:œAstraDB-Wep9Cœ,œinputTypesœ:[œEmbeddingsœ],œtypeœ:œotherœ}", "selected": false, - "source": "OpenAIEmbeddings-4Uky4", - "sourceHandle": "{œdataTypeœ: œOpenAIEmbeddingsœ, œidœ: œOpenAIEmbeddings-4Uky4œ, œnameœ: œembeddingsœ, œoutput_typesœ: [œEmbeddingsœ]}", - "target": "AstraDB-tVkFw", - "targetHandle": "{œfieldNameœ: œembedding_modelœ, œidœ: œAstraDB-tVkFwœ, œinputTypesœ: [œEmbeddingsœ], œtypeœ: œotherœ}" + "source": "OpenAIEmbeddings-ulN0y", + "sourceHandle": "{œdataTypeœ: œOpenAIEmbeddingsœ, œidœ: œOpenAIEmbeddings-ulN0yœ, œnameœ: œembeddingsœ, œoutput_typesœ: [œEmbeddingsœ]}", + "target": "AstraDB-Wep9C", + "targetHandle": "{œfieldNameœ: œembedding_modelœ, œidœ: œAstraDB-Wep9Cœ, œinputTypesœ: [œEmbeddingsœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -179,7 +179,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-kNQkx", + "id": "ChatInput-1w4cJ", "name": "message", "output_types": [ "Message" @@ -187,19 +187,19 @@ }, "targetHandle": { "fieldName": "search_query", - "id": "AstraDB-tVkFw", + "id": "AstraDB-Wep9C", "inputTypes": [ "Message" ], "type": "query" } }, - "id": "reactflow__edge-ChatInput-kNQkx{œdataTypeœ:œChatInputœ,œidœ:œChatInput-kNQkxœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-AstraDB-tVkFw{œfieldNameœ:œsearch_queryœ,œidœ:œAstraDB-tVkFwœ,œinputTypesœ:[œMessageœ],œtypeœ:œqueryœ}", + "id": "reactflow__edge-ChatInput-1w4cJ{œdataTypeœ:œChatInputœ,œidœ:œChatInput-1w4cJœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-AstraDB-Wep9C{œfieldNameœ:œsearch_queryœ,œidœ:œAstraDB-Wep9Cœ,œinputTypesœ:[œMessageœ],œtypeœ:œqueryœ}", "selected": false, - "source": "ChatInput-kNQkx", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-kNQkxœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "AstraDB-tVkFw", - "targetHandle": "{œfieldNameœ: œsearch_queryœ, œidœ: œAstraDB-tVkFwœ, œinputTypesœ: [œMessageœ], œtypeœ: œqueryœ}" + "source": "ChatInput-1w4cJ", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-1w4cJœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "AstraDB-Wep9C", + "targetHandle": "{œfieldNameœ: œsearch_queryœ, œidœ: œAstraDB-Wep9Cœ, œinputTypesœ: [œMessageœ], œtypeœ: œqueryœ}" }, { "animated": false, @@ -207,7 +207,7 @@ "data": { "sourceHandle": { "dataType": "AstraDB", - "id": "AstraDB-tVkFw", + "id": "AstraDB-Wep9C", "name": "dataframe", "output_types": [ "DataFrame" @@ -215,7 +215,7 @@ }, "targetHandle": { "fieldName": "input_data", - "id": "parser-Qet8H", + "id": "parser-IEn6I", "inputTypes": [ "DataFrame", "Data" @@ -223,12 +223,12 @@ "type": "other" } }, - "id": "reactflow__edge-AstraDB-tVkFw{œdataTypeœ:œAstraDBœ,œidœ:œAstraDB-tVkFwœ,œnameœ:œdataframeœ,œoutput_typesœ:[œDataFrameœ]}-parser-Qet8H{œfieldNameœ:œinput_dataœ,œidœ:œparser-Qet8Hœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-AstraDB-Wep9C{œdataTypeœ:œAstraDBœ,œidœ:œAstraDB-Wep9Cœ,œnameœ:œdataframeœ,œoutput_typesœ:[œDataFrameœ]}-parser-IEn6I{œfieldNameœ:œinput_dataœ,œidœ:œparser-IEn6Iœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", "selected": false, - "source": "AstraDB-tVkFw", - "sourceHandle": "{œdataTypeœ: œAstraDBœ, œidœ: œAstraDB-tVkFwœ, œnameœ: œdataframeœ, œoutput_typesœ: [œDataFrameœ]}", - "target": "parser-Qet8H", - "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œparser-Qet8Hœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" + "source": "AstraDB-Wep9C", + "sourceHandle": "{œdataTypeœ: œAstraDBœ, œidœ: œAstraDB-Wep9Cœ, œnameœ: œdataframeœ, œoutput_typesœ: [œDataFrameœ]}", + "target": "parser-IEn6I", + "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œparser-IEn6Iœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -236,7 +236,7 @@ "data": { "sourceHandle": { "dataType": "File", - "id": "File-kPRpn", + "id": "File-C3stS", "name": "dataframe", "output_types": [ "DataFrame" @@ -244,7 +244,7 @@ }, "targetHandle": { "fieldName": "data_inputs", - "id": "SplitText-sDxql", + "id": "SplitText-5RcUo", "inputTypes": [ "Data", "DataFrame" @@ -252,18 +252,20 @@ "type": "other" } }, - "id": "reactflow__edge-File-kPRpn{œdataTypeœ:œFileœ,œidœ:œFile-kPRpnœ,œnameœ:œdataframeœ,œoutput_typesœ:[œDataFrameœ]}-SplitText-sDxql{œfieldNameœ:œdata_inputsœ,œidœ:œSplitText-sDxqlœ,œinputTypesœ:[œDataœ,œDataFrameœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-File-C3stS{œdataTypeœ:œFileœ,œidœ:œFile-C3stSœ,œnameœ:œdataframeœ,œoutput_typesœ:[œDataFrameœ]}-SplitText-5RcUo{œfieldNameœ:œdata_inputsœ,œidœ:œSplitText-5RcUoœ,œinputTypesœ:[œDataœ,œDataFrameœ],œtypeœ:œotherœ}", "selected": false, - "source": "File-kPRpn", - "sourceHandle": "{œdataTypeœ: œFileœ, œidœ: œFile-kPRpnœ, œnameœ: œdataframeœ, œoutput_typesœ: [œDataFrameœ]}", - "target": "SplitText-sDxql", - "targetHandle": "{œfieldNameœ: œdata_inputsœ, œidœ: œSplitText-sDxqlœ, œinputTypesœ: [œDataœ, œDataFrameœ], œtypeœ: œotherœ}" + "source": "File-C3stS", + "sourceHandle": "{œdataTypeœ: œFileœ, œidœ: œFile-C3stSœ, œnameœ: œdataframeœ, œoutput_typesœ: [œDataFrameœ]}", + "target": "SplitText-5RcUo", + "targetHandle": "{œfieldNameœ: œdata_inputsœ, œidœ: œSplitText-5RcUoœ, œinputTypesœ: [œDataœ, œDataFrameœ], œtypeœ: œotherœ}" }, { + "animated": false, + "className": "", "data": { "sourceHandle": { "dataType": "SplitText", - "id": "SplitText-sDxql", + "id": "SplitText-5RcUo", "name": "dataframe", "output_types": [ "DataFrame" @@ -271,7 +273,7 @@ }, "targetHandle": { "fieldName": "ingest_data", - "id": "AstraDB-eQaxM", + "id": "AstraDB-8AuVs", "inputTypes": [ "Data", "DataFrame" @@ -279,11 +281,12 @@ "type": "other" } }, - "id": "xy-edge__SplitText-sDxql{œdataTypeœ:œSplitTextœ,œidœ:œSplitText-sDxqlœ,œnameœ:œdataframeœ,œoutput_typesœ:[œDataFrameœ]}-AstraDB-eQaxM{œfieldNameœ:œingest_dataœ,œidœ:œAstraDB-eQaxMœ,œinputTypesœ:[œDataœ,œDataFrameœ],œtypeœ:œotherœ}", - "source": "SplitText-sDxql", - "sourceHandle": "{œdataTypeœ: œSplitTextœ, œidœ: œSplitText-sDxqlœ, œnameœ: œdataframeœ, œoutput_typesœ: [œDataFrameœ]}", - "target": "AstraDB-eQaxM", - "targetHandle": "{œfieldNameœ: œingest_dataœ, œidœ: œAstraDB-eQaxMœ, œinputTypesœ: [œDataœ, œDataFrameœ], œtypeœ: œotherœ}" + "id": "reactflow__edge-SplitText-5RcUo{œdataTypeœ:œSplitTextœ,œidœ:œSplitText-5RcUoœ,œnameœ:œdataframeœ,œoutput_typesœ:[œDataFrameœ]}-AstraDB-8AuVs{œfieldNameœ:œingest_dataœ,œidœ:œAstraDB-8AuVsœ,œinputTypesœ:[œDataœ,œDataFrameœ],œtypeœ:œotherœ}", + "selected": false, + "source": "SplitText-5RcUo", + "sourceHandle": "{œdataTypeœ: œSplitTextœ, œidœ: œSplitText-5RcUoœ, œnameœ: œdataframeœ, œoutput_typesœ: [œDataFrameœ]}", + "target": "AstraDB-8AuVs", + "targetHandle": "{œfieldNameœ: œingest_dataœ, œidœ: œAstraDB-8AuVsœ, œinputTypesœ: [œDataœ, œDataFrameœ], œtypeœ: œotherœ}" } ], "nodes": [ @@ -291,7 +294,7 @@ "data": { "description": "Get chat inputs from the Playground.", "display_name": "Chat Input", - "id": "ChatInput-kNQkx", + "id": "ChatInput-1w4cJ", "node": { "base_classes": [ "Message" @@ -558,7 +561,7 @@ }, "dragging": false, "height": 234, - "id": "ChatInput-kNQkx", + "id": "ChatInput-1w4cJ", "measured": { "height": 234, "width": 320 @@ -579,7 +582,7 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-zHQI0", + "id": "Prompt-I9T0w", "node": { "base_classes": [ "Message" @@ -740,7 +743,7 @@ }, "dragging": false, "height": 433, - "id": "Prompt-zHQI0", + "id": "Prompt-I9T0w", "measured": { "height": 433, "width": 320 @@ -761,7 +764,7 @@ "data": { "description": "Split text into chunks based on specified criteria.", "display_name": "Split Text", - "id": "SplitText-sDxql", + "id": "SplitText-5RcUo", "node": { "base_classes": [ "Data" @@ -946,7 +949,7 @@ }, "dragging": false, "height": 475, - "id": "SplitText-sDxql", + "id": "SplitText-5RcUo", "measured": { "height": 475, "width": 320 @@ -965,7 +968,7 @@ }, { "data": { - "id": "note-VWeXf", + "id": "note-BG8Kh", "node": { "description": "## 🐕 2. Retriever Flow\n\nThis flow answers your questions with contextual data retrieved from your vector database.\n\nOpen the **Playground** and ask, \n\n```\nWhat is this document about?\n```\n", "display_name": "", @@ -978,7 +981,7 @@ }, "dragging": false, "height": 324, - "id": "note-VWeXf", + "id": "note-BG8Kh", "measured": { "height": 324, "width": 325 @@ -1002,7 +1005,7 @@ }, { "data": { - "id": "note-K46GL", + "id": "note-IF0Cy", "node": { "description": "## 📖 README\n\nLoad your data into a vector database with the 📚 **Load Data** flow, and then use your data as chat context with the 🐕 **Retriever** flow.\n\n**🚨 Add your OpenAI API key as a global variable to easily add it to all of the OpenAI components in this flow.** \n\n**Quick start**\n1. Run the 📚 **Load Data** flow.\n2. Run the 🐕 **Retriever** flow.\n\n**Next steps** \n\n- Experiment by changing the prompt and the loaded data to see how the bot's responses change. \n\nFor more info, see the [Langflow docs](https://docs.langflow.org/starter-projects-vector-store-rag).", "display_name": "Read Me", @@ -1015,7 +1018,7 @@ }, "dragging": false, "height": 324, - "id": "note-K46GL", + "id": "note-IF0Cy", "measured": { "height": 324, "width": 325 @@ -1041,7 +1044,7 @@ "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-GAFHg", + "id": "ChatOutput-Dlahs", "node": { "base_classes": [ "Message" @@ -1324,7 +1327,7 @@ }, "dragging": false, "height": 234, - "id": "ChatOutput-GAFHg", + "id": "ChatOutput-Dlahs", "measured": { "height": 234, "width": 320 @@ -1343,7 +1346,7 @@ }, { "data": { - "id": "OpenAIEmbeddings-4Uky4", + "id": "OpenAIEmbeddings-ulN0y", "node": { "base_classes": [ "Embeddings" @@ -1636,7 +1639,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "OPENAI_API_KEY" }, "openai_api_type": { "_input_type": "MessageTextInput", @@ -1820,7 +1823,7 @@ }, "dragging": false, "height": 320, - "id": "OpenAIEmbeddings-4Uky4", + "id": "OpenAIEmbeddings-ulN0y", "measured": { "height": 320, "width": 320 @@ -1839,7 +1842,7 @@ }, { "data": { - "id": "note-Jk7TI", + "id": "note-odwIB", "node": { "description": "## 📚 1. Load Data Flow\n\nRun this first! Load data from a local file and embed it into the vector database.\n\nSelect a Database and a Collection, or create new ones. \n\nClick ▶️ **Run component** on the **Astra DB** component to load your data.\n\n* If you're using OSS Langflow, add your Astra DB Application Token to the Astra DB component.\n\n#### Next steps:\n Experiment by changing the prompt and the contextual data to see how the retrieval flow's responses change.", "display_name": "", @@ -1852,7 +1855,7 @@ }, "dragging": false, "height": 324, - "id": "note-Jk7TI", + "id": "note-odwIB", "measured": { "height": 324, "width": 325 @@ -1876,7 +1879,7 @@ }, { "data": { - "id": "OpenAIEmbeddings-D1jSt", + "id": "OpenAIEmbeddings-OlQ6R", "node": { "base_classes": [ "Embeddings" @@ -2169,7 +2172,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "OPENAI_API_KEY" }, "openai_api_type": { "_input_type": "MessageTextInput", @@ -2353,7 +2356,7 @@ }, "dragging": false, "height": 320, - "id": "OpenAIEmbeddings-D1jSt", + "id": "OpenAIEmbeddings-OlQ6R", "measured": { "height": 320, "width": 320 @@ -2372,7 +2375,7 @@ }, { "data": { - "id": "File-kPRpn", + "id": "File-C3stS", "node": { "base_classes": [ "Data" @@ -2633,7 +2636,7 @@ }, "dragging": false, "height": 367, - "id": "File-kPRpn", + "id": "File-C3stS", "measured": { "height": 367, "width": 320 @@ -2652,7 +2655,7 @@ }, { "data": { - "id": "note-mQAwf", + "id": "note-aHmST", "node": { "description": "### 💡 Add your OpenAI API key here 👇", "display_name": "", @@ -2665,7 +2668,7 @@ }, "dragging": false, "height": 324, - "id": "note-mQAwf", + "id": "note-aHmST", "measured": { "height": 324, "width": 324 @@ -2684,7 +2687,7 @@ }, { "data": { - "id": "note-6Bw7F", + "id": "note-QvcXX", "node": { "description": "### 💡 Add your OpenAI API key here 👇", "display_name": "", @@ -2697,7 +2700,7 @@ }, "dragging": false, "height": 324, - "id": "note-6Bw7F", + "id": "note-QvcXX", "measured": { "height": 324, "width": 324 @@ -2716,7 +2719,7 @@ }, { "data": { - "id": "note-dVn2E", + "id": "note-xLYll", "node": { "description": "### 💡 Add your OpenAI API key here 👇", "display_name": "", @@ -2729,7 +2732,7 @@ }, "dragging": false, "height": 324, - "id": "note-dVn2E", + "id": "note-xLYll", "measured": { "height": 324, "width": 324 @@ -2748,7 +2751,7 @@ }, { "data": { - "id": "OpenAIModel-9bWp2", + "id": "OpenAIModel-GczRI", "node": { "base_classes": [ "LanguageModel", @@ -3124,9 +3127,9 @@ "type": "OpenAIModel" }, "dragging": false, - "id": "OpenAIModel-9bWp2", + "id": "OpenAIModel-GczRI", "measured": { - "height": 540, + "height": 539, "width": 320 }, "position": { @@ -3138,7 +3141,7 @@ }, { "data": { - "id": "parser-Qet8H", + "id": "parser-IEn6I", "node": { "base_classes": [ "Message" @@ -3300,9 +3303,9 @@ "type": "parser" }, "dragging": false, - "id": "parser-Qet8H", + "id": "parser-IEn6I", "measured": { - "height": 361, + "height": 360, "width": 320 }, "position": { @@ -3314,7 +3317,7 @@ }, { "data": { - "id": "AstraDB-tVkFw", + "id": "AstraDB-Wep9C", "node": { "base_classes": [ "Data", @@ -3443,7 +3446,7 @@ "tool_mode": false, "trace_as_metadata": true, "type": "str", - "value": "ASTRA_DB_API_ENDPOINT" + "value": "" }, "astradb_vectorstore_kwargs": { "_input_type": "NestedDictInput", @@ -3731,17 +3734,7 @@ "info": "The Database name for the Astra DB instance.", "name": "database_name", "options": [], - "options_metadata": [ - { - "api_endpoint": "https://deb10a81-3c5d-4fd3-8b1b-945915d2835b-us-east-2.apps.astra.datastax.com", - "collections": 1, - "keyspaces": [ - "default_keyspace" - ], - "org_id": "4bd8a5f9-41b3-4d8a-b039-0dd35f5eb374", - "status": null - } - ], + "options_metadata": [], "placeholder": "", "real_time_refresh": true, "refresh_button": true, @@ -4072,21 +4065,21 @@ "type": "AstraDB" }, "dragging": false, - "id": "AstraDB-tVkFw", + "id": "AstraDB-Wep9C", "measured": { - "height": 458, + "height": 501, "width": 320 }, "position": { "x": 1206.2272993725155, "y": 491.41485400844977 }, - "selected": false, + "selected": true, "type": "genericNode" }, { "data": { - "id": "AstraDB-eQaxM", + "id": "AstraDB-8AuVs", "node": { "base_classes": [ "Data", @@ -4502,17 +4495,7 @@ "info": "The Database name for the Astra DB instance.", "name": "database_name", "options": [], - "options_metadata": [ - { - "api_endpoint": "https://deb10a81-3c5d-4fd3-8b1b-945915d2835b-us-east-2.apps.astra.datastax.com", - "collections": 1, - "keyspaces": [ - "default_keyspace" - ], - "org_id": "4bd8a5f9-41b3-4d8a-b039-0dd35f5eb374", - "status": null - } - ], + "options_metadata": [], "placeholder": "", "real_time_refresh": true, "refresh_button": true, @@ -4833,7 +4816,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "ASTRA_DB_APPLICATION_TOKEN" } }, "tool_mode": false @@ -4842,9 +4825,9 @@ "type": "AstraDB" }, "dragging": false, - "id": "AstraDB-eQaxM", + "id": "AstraDB-8AuVs", "measured": { - "height": 458, + "height": 501, "width": 320 }, "position": { @@ -4856,16 +4839,16 @@ } ], "viewport": { - "x": 20.50191698112849, - "y": -144.65436276592914, - "zoom": 0.43295751491830675 + "x": -218.5246908040316, + "y": -275.7883822982229, + "zoom": 0.5382133171428375 } }, "description": "Load your data for chat context with Retrieval Augmented Generation.", "endpoint_name": null, - "id": "e120d90a-3ba4-4f53-a551-8b6d94ccb424", + "id": "20809df7-902f-4ea8-b4e5-c395b171633b", "is_component": false, - "last_tested_version": "1.4.2", + "last_tested_version": "1.4.3", "name": "Vector Store RAG", "tags": [ "openai", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json b/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json index c7bec11c1..d34f37d61 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json @@ -7,7 +7,7 @@ "data": { "sourceHandle": { "dataType": "YouTubeCommentsComponent", - "id": "YouTubeCommentsComponent-g4VZV", + "id": "YouTubeCommentsComponent-4pxuY", "name": "comments", "output_types": [ "DataFrame" @@ -15,19 +15,19 @@ }, "targetHandle": { "fieldName": "df", - "id": "BatchRunComponent-kxOUU", + "id": "BatchRunComponent-jFt7j", "inputTypes": [ "DataFrame" ], "type": "other" } }, - "id": "reactflow__edge-YouTubeCommentsComponent-g4VZV{œdataTypeœ:œYouTubeCommentsComponentœ,œidœ:œYouTubeCommentsComponent-g4VZVœ,œnameœ:œcommentsœ,œoutput_typesœ:[œDataFrameœ]}-BatchRunComponent-kxOUU{œfieldNameœ:œdfœ,œidœ:œBatchRunComponent-kxOUUœ,œinputTypesœ:[œDataFrameœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-YouTubeCommentsComponent-4pxuY{œdataTypeœ:œYouTubeCommentsComponentœ,œidœ:œYouTubeCommentsComponent-4pxuYœ,œnameœ:œcommentsœ,œoutput_typesœ:[œDataFrameœ]}-BatchRunComponent-jFt7j{œfieldNameœ:œdfœ,œidœ:œBatchRunComponent-jFt7jœ,œinputTypesœ:[œDataFrameœ],œtypeœ:œotherœ}", "selected": false, - "source": "YouTubeCommentsComponent-g4VZV", - "sourceHandle": "{œdataTypeœ: œYouTubeCommentsComponentœ, œidœ: œYouTubeCommentsComponent-g4VZVœ, œnameœ: œcommentsœ, œoutput_typesœ: [œDataFrameœ]}", - "target": "BatchRunComponent-kxOUU", - "targetHandle": "{œfieldNameœ: œdfœ, œidœ: œBatchRunComponent-kxOUUœ, œinputTypesœ: [œDataFrameœ], œtypeœ: œotherœ}" + "source": "YouTubeCommentsComponent-4pxuY", + "sourceHandle": "{œdataTypeœ: œYouTubeCommentsComponentœ, œidœ: œYouTubeCommentsComponent-4pxuYœ, œnameœ: œcommentsœ, œoutput_typesœ: [œDataFrameœ]}", + "target": "BatchRunComponent-jFt7j", + "targetHandle": "{œfieldNameœ: œdfœ, œidœ: œBatchRunComponent-jFt7jœ, œinputTypesœ: [œDataFrameœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -35,7 +35,7 @@ "data": { "sourceHandle": { "dataType": "OpenAIModel", - "id": "OpenAIModel-0iBkZ", + "id": "OpenAIModel-3klNa", "name": "model_output", "output_types": [ "LanguageModel" @@ -43,19 +43,19 @@ }, "targetHandle": { "fieldName": "model", - "id": "BatchRunComponent-kxOUU", + "id": "BatchRunComponent-jFt7j", "inputTypes": [ "LanguageModel" ], "type": "other" } }, - "id": "reactflow__edge-OpenAIModel-0iBkZ{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-0iBkZœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}-BatchRunComponent-kxOUU{œfieldNameœ:œmodelœ,œidœ:œBatchRunComponent-kxOUUœ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-OpenAIModel-3klNa{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-3klNaœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}-BatchRunComponent-jFt7j{œfieldNameœ:œmodelœ,œidœ:œBatchRunComponent-jFt7jœ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}", "selected": false, - "source": "OpenAIModel-0iBkZ", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-0iBkZœ, œnameœ: œmodel_outputœ, œoutput_typesœ: [œLanguageModelœ]}", - "target": "BatchRunComponent-kxOUU", - "targetHandle": "{œfieldNameœ: œmodelœ, œidœ: œBatchRunComponent-kxOUUœ, œinputTypesœ: [œLanguageModelœ], œtypeœ: œotherœ}" + "source": "OpenAIModel-3klNa", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-3klNaœ, œnameœ: œmodel_outputœ, œoutput_typesœ: [œLanguageModelœ]}", + "target": "BatchRunComponent-jFt7j", + "targetHandle": "{œfieldNameœ: œmodelœ, œidœ: œBatchRunComponent-jFt7jœ, œinputTypesœ: [œLanguageModelœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -63,7 +63,7 @@ "data": { "sourceHandle": { "dataType": "Prompt", - "id": "Prompt-UAMac", + "id": "Prompt-tR2a7", "name": "prompt", "output_types": [ "Message" @@ -71,19 +71,19 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "Agent-0gW4Y", + "id": "Agent-A37q9", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-Prompt-UAMac{œdataTypeœ:œPromptœ,œidœ:œPrompt-UAMacœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-0gW4Y{œfieldNameœ:œinput_valueœ,œidœ:œAgent-0gW4Yœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Prompt-tR2a7{œdataTypeœ:œPromptœ,œidœ:œPrompt-tR2a7œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-A37q9{œfieldNameœ:œinput_valueœ,œidœ:œAgent-A37q9œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Prompt-UAMac", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-UAMacœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-0gW4Y", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-0gW4Yœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "Prompt-tR2a7", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-tR2a7œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-A37q9", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-A37q9œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -91,7 +91,7 @@ "data": { "sourceHandle": { "dataType": "Agent", - "id": "Agent-0gW4Y", + "id": "Agent-A37q9", "name": "response", "output_types": [ "Message" @@ -99,7 +99,7 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "ChatOutput-9nsTW", + "id": "ChatOutput-w4PAC", "inputTypes": [ "Data", "DataFrame", @@ -108,12 +108,12 @@ "type": "str" } }, - "id": "reactflow__edge-Agent-0gW4Y{œdataTypeœ:œAgentœ,œidœ:œAgent-0gW4Yœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-9nsTW{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-9nsTWœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-Agent-A37q9{œdataTypeœ:œAgentœ,œidœ:œAgent-A37q9œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-w4PAC{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-w4PACœ,œinputTypesœ:[œDataœ,œDataFrameœ,œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Agent-0gW4Y", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-0gW4Yœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-9nsTW", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-9nsTWœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" + "source": "Agent-A37q9", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-A37q9œ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-w4PAC", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-w4PACœ, œinputTypesœ: [œDataœ, œDataFrameœ, œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -121,7 +121,7 @@ "data": { "sourceHandle": { "dataType": "YouTubeTranscripts", - "id": "YouTubeTranscripts-QMIjk", + "id": "YouTubeTranscripts-Nbrx3", "name": "component_as_tool", "output_types": [ "Tool" @@ -129,19 +129,19 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-0gW4Y", + "id": "Agent-A37q9", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "reactflow__edge-YouTubeTranscripts-QMIjk{œdataTypeœ:œYouTubeTranscriptsœ,œidœ:œYouTubeTranscripts-QMIjkœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-0gW4Y{œfieldNameœ:œtoolsœ,œidœ:œAgent-0gW4Yœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-YouTubeTranscripts-Nbrx3{œdataTypeœ:œYouTubeTranscriptsœ,œidœ:œYouTubeTranscripts-Nbrx3œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-A37q9{œfieldNameœ:œtoolsœ,œidœ:œAgent-A37q9œ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", "selected": false, - "source": "YouTubeTranscripts-QMIjk", - "sourceHandle": "{œdataTypeœ: œYouTubeTranscriptsœ, œidœ: œYouTubeTranscripts-QMIjkœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-0gW4Y", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-0gW4Yœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "source": "YouTubeTranscripts-Nbrx3", + "sourceHandle": "{œdataTypeœ: œYouTubeTranscriptsœ, œidœ: œYouTubeTranscripts-Nbrx3œ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-A37q9", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-A37q9œ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -149,7 +149,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-XErsc", + "id": "ChatInput-jHqUS", "name": "message", "output_types": [ "Message" @@ -157,19 +157,19 @@ }, "targetHandle": { "fieldName": "input_text", - "id": "ConditionalRouter-7lzPh", + "id": "ConditionalRouter-SP1WC", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ChatInput-XErsc{œdataTypeœ:œChatInputœ,œidœ:œChatInput-XErscœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-ConditionalRouter-7lzPh{œfieldNameœ:œinput_textœ,œidœ:œConditionalRouter-7lzPhœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-jHqUS{œdataTypeœ:œChatInputœ,œidœ:œChatInput-jHqUSœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-ConditionalRouter-SP1WC{œfieldNameœ:œinput_textœ,œidœ:œConditionalRouter-SP1WCœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-XErsc", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-XErscœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "ConditionalRouter-7lzPh", - "targetHandle": "{œfieldNameœ: œinput_textœ, œidœ: œConditionalRouter-7lzPhœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatInput-jHqUS", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-jHqUSœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "ConditionalRouter-SP1WC", + "targetHandle": "{œfieldNameœ: œinput_textœ, œidœ: œConditionalRouter-SP1WCœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -177,7 +177,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-XErsc", + "id": "ChatInput-jHqUS", "name": "message", "output_types": [ "Message" @@ -185,19 +185,19 @@ }, "targetHandle": { "fieldName": "message", - "id": "ConditionalRouter-7lzPh", + "id": "ConditionalRouter-SP1WC", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ChatInput-XErsc{œdataTypeœ:œChatInputœ,œidœ:œChatInput-XErscœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-ConditionalRouter-7lzPh{œfieldNameœ:œmessageœ,œidœ:œConditionalRouter-7lzPhœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-jHqUS{œdataTypeœ:œChatInputœ,œidœ:œChatInput-jHqUSœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-ConditionalRouter-SP1WC{œfieldNameœ:œmessageœ,œidœ:œConditionalRouter-SP1WCœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-XErsc", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-XErscœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "ConditionalRouter-7lzPh", - "targetHandle": "{œfieldNameœ: œmessageœ, œidœ: œConditionalRouter-7lzPhœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatInput-jHqUS", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-jHqUSœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "ConditionalRouter-SP1WC", + "targetHandle": "{œfieldNameœ: œmessageœ, œidœ: œConditionalRouter-SP1WCœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -205,7 +205,7 @@ "data": { "sourceHandle": { "dataType": "ConditionalRouter", - "id": "ConditionalRouter-7lzPh", + "id": "ConditionalRouter-SP1WC", "name": "true_result", "output_types": [ "Message" @@ -213,19 +213,19 @@ }, "targetHandle": { "fieldName": "video_url", - "id": "YouTubeCommentsComponent-g4VZV", + "id": "YouTubeCommentsComponent-4pxuY", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ConditionalRouter-7lzPh{œdataTypeœ:œConditionalRouterœ,œidœ:œConditionalRouter-7lzPhœ,œnameœ:œtrue_resultœ,œoutput_typesœ:[œMessageœ]}-YouTubeCommentsComponent-g4VZV{œfieldNameœ:œvideo_urlœ,œidœ:œYouTubeCommentsComponent-g4VZVœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ConditionalRouter-SP1WC{œdataTypeœ:œConditionalRouterœ,œidœ:œConditionalRouter-SP1WCœ,œnameœ:œtrue_resultœ,œoutput_typesœ:[œMessageœ]}-YouTubeCommentsComponent-4pxuY{œfieldNameœ:œvideo_urlœ,œidœ:œYouTubeCommentsComponent-4pxuYœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ConditionalRouter-7lzPh", - "sourceHandle": "{œdataTypeœ: œConditionalRouterœ, œidœ: œConditionalRouter-7lzPhœ, œnameœ: œtrue_resultœ, œoutput_typesœ: [œMessageœ]}", - "target": "YouTubeCommentsComponent-g4VZV", - "targetHandle": "{œfieldNameœ: œvideo_urlœ, œidœ: œYouTubeCommentsComponent-g4VZVœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ConditionalRouter-SP1WC", + "sourceHandle": "{œdataTypeœ: œConditionalRouterœ, œidœ: œConditionalRouter-SP1WCœ, œnameœ: œtrue_resultœ, œoutput_typesœ: [œMessageœ]}", + "target": "YouTubeCommentsComponent-4pxuY", + "targetHandle": "{œfieldNameœ: œvideo_urlœ, œidœ: œYouTubeCommentsComponent-4pxuYœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, @@ -233,7 +233,7 @@ "data": { "sourceHandle": { "dataType": "ConditionalRouter", - "id": "ConditionalRouter-7lzPh", + "id": "ConditionalRouter-SP1WC", "name": "true_result", "output_types": [ "Message" @@ -241,26 +241,27 @@ }, "targetHandle": { "fieldName": "url", - "id": "Prompt-UAMac", + "id": "Prompt-tR2a7", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ConditionalRouter-7lzPh{œdataTypeœ:œConditionalRouterœ,œidœ:œConditionalRouter-7lzPhœ,œnameœ:œtrue_resultœ,œoutput_typesœ:[œMessageœ]}-Prompt-UAMac{œfieldNameœ:œurlœ,œidœ:œPrompt-UAMacœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ConditionalRouter-SP1WC{œdataTypeœ:œConditionalRouterœ,œidœ:œConditionalRouter-SP1WCœ,œnameœ:œtrue_resultœ,œoutput_typesœ:[œMessageœ]}-Prompt-tR2a7{œfieldNameœ:œurlœ,œidœ:œPrompt-tR2a7œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ConditionalRouter-7lzPh", - "sourceHandle": "{œdataTypeœ: œConditionalRouterœ, œidœ: œConditionalRouter-7lzPhœ, œnameœ: œtrue_resultœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-UAMac", - "targetHandle": "{œfieldNameœ: œurlœ, œidœ: œPrompt-UAMacœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ConditionalRouter-SP1WC", + "sourceHandle": "{œdataTypeœ: œConditionalRouterœ, œidœ: œConditionalRouter-SP1WCœ, œnameœ: œtrue_resultœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-tR2a7", + "targetHandle": "{œfieldNameœ: œurlœ, œidœ: œPrompt-tR2a7œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" }, { "animated": false, + "className": "", "data": { "sourceHandle": { "dataType": "BatchRunComponent", - "id": "BatchRunComponent-kxOUU", + "id": "BatchRunComponent-jFt7j", "name": "batch_results", "output_types": [ "DataFrame" @@ -268,7 +269,7 @@ }, "targetHandle": { "fieldName": "input_data", - "id": "parser-r3iNU", + "id": "parser-LDaMh", "inputTypes": [ "DataFrame", "Data" @@ -276,19 +277,20 @@ "type": "other" } }, - "id": "xy-edge__BatchRunComponent-kxOUU{œdataTypeœ:œBatchRunComponentœ,œidœ:œBatchRunComponent-kxOUUœ,œnameœ:œbatch_resultsœ,œoutput_typesœ:[œDataFrameœ]}-parser-r3iNU{œfieldNameœ:œinput_dataœ,œidœ:œparser-r3iNUœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-BatchRunComponent-jFt7j{œdataTypeœ:œBatchRunComponentœ,œidœ:œBatchRunComponent-jFt7jœ,œnameœ:œbatch_resultsœ,œoutput_typesœ:[œDataFrameœ]}-parser-LDaMh{œfieldNameœ:œinput_dataœ,œidœ:œparser-LDaMhœ,œinputTypesœ:[œDataFrameœ,œDataœ],œtypeœ:œotherœ}", "selected": false, - "source": "BatchRunComponent-kxOUU", - "sourceHandle": "{œdataTypeœ: œBatchRunComponentœ, œidœ: œBatchRunComponent-kxOUUœ, œnameœ: œbatch_resultsœ, œoutput_typesœ: [œDataFrameœ]}", - "target": "parser-r3iNU", - "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œparser-r3iNUœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" + "source": "BatchRunComponent-jFt7j", + "sourceHandle": "{œdataTypeœ: œBatchRunComponentœ, œidœ: œBatchRunComponent-jFt7jœ, œnameœ: œbatch_resultsœ, œoutput_typesœ: [œDataFrameœ]}", + "target": "parser-LDaMh", + "targetHandle": "{œfieldNameœ: œinput_dataœ, œidœ: œparser-LDaMhœ, œinputTypesœ: [œDataFrameœ, œDataœ], œtypeœ: œotherœ}" }, { "animated": false, + "className": "", "data": { "sourceHandle": { "dataType": "parser", - "id": "parser-r3iNU", + "id": "parser-LDaMh", "name": "parsed_text", "output_types": [ "Message" @@ -296,25 +298,25 @@ }, "targetHandle": { "fieldName": "analysis", - "id": "Prompt-UAMac", + "id": "Prompt-tR2a7", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "xy-edge__parser-r3iNU{œdataTypeœ:œparserœ,œidœ:œparser-r3iNUœ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-Prompt-UAMac{œfieldNameœ:œanalysisœ,œidœ:œPrompt-UAMacœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-parser-LDaMh{œdataTypeœ:œparserœ,œidœ:œparser-LDaMhœ,œnameœ:œparsed_textœ,œoutput_typesœ:[œMessageœ]}-Prompt-tR2a7{œfieldNameœ:œanalysisœ,œidœ:œPrompt-tR2a7œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "parser-r3iNU", - "sourceHandle": "{œdataTypeœ: œparserœ, œidœ: œparser-r3iNUœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-UAMac", - "targetHandle": "{œfieldNameœ: œanalysisœ, œidœ: œPrompt-UAMacœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "parser-LDaMh", + "sourceHandle": "{œdataTypeœ: œparserœ, œidœ: œparser-LDaMhœ, œnameœ: œparsed_textœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-tR2a7", + "targetHandle": "{œfieldNameœ: œanalysisœ, œidœ: œPrompt-tR2a7œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" } ], "nodes": [ { "data": { - "id": "BatchRunComponent-kxOUU", + "id": "BatchRunComponent-jFt7j", "node": { "base_classes": [ "DataFrame" @@ -513,9 +515,9 @@ "type": "BatchRunComponent" }, "dragging": false, - "id": "BatchRunComponent-kxOUU", + "id": "BatchRunComponent-jFt7j", "measured": { - "height": 399, + "height": 391, "width": 320 }, "position": { @@ -527,7 +529,7 @@ }, { "data": { - "id": "YouTubeCommentsComponent-g4VZV", + "id": "YouTubeCommentsComponent-4pxuY", "node": { "base_classes": [ "DataFrame" @@ -583,7 +585,7 @@ "dynamic": false, "info": "Your YouTube Data API key.", "input_types": [], - "load_from_db": true, + "load_from_db": false, "name": "api_key", "password": true, "placeholder": "", @@ -591,7 +593,7 @@ "show": true, "title_case": false, "type": "str", - "value": "YOUTUBE_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -719,9 +721,9 @@ "type": "YouTubeCommentsComponent" }, "dragging": false, - "id": "YouTubeCommentsComponent-g4VZV", + "id": "YouTubeCommentsComponent-4pxuY", "measured": { - "height": 497, + "height": 467, "width": 320 }, "position": { @@ -733,7 +735,7 @@ }, { "data": { - "id": "OpenAIModel-0iBkZ", + "id": "OpenAIModel-3klNa", "node": { "base_classes": [ "LanguageModel", @@ -764,7 +766,7 @@ "icon": "OpenAI", "key": "OpenAIModel", "legacy": false, - "lf_version": "1.1.3", + "lf_version": "1.4.2", "metadata": { "keywords": [ "model", @@ -824,7 +826,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -1110,9 +1112,9 @@ "type": "OpenAIModel" }, "dragging": false, - "id": "OpenAIModel-0iBkZ", + "id": "OpenAIModel-3klNa", "measured": { - "height": 525, + "height": 540, "width": 320 }, "position": { @@ -1124,7 +1126,7 @@ }, { "data": { - "id": "Agent-0gW4Y", + "id": "Agent-A37q9", "node": { "base_classes": [ "Message" @@ -1279,7 +1281,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -1846,9 +1848,9 @@ "type": "Agent" }, "dragging": false, - "id": "Agent-0gW4Y", + "id": "Agent-A37q9", "measured": { - "height": 624, + "height": 594, "width": 320 }, "position": { @@ -1860,7 +1862,7 @@ }, { "data": { - "id": "Prompt-UAMac", + "id": "Prompt-tR2a7", "node": { "base_classes": [ "Message" @@ -2024,9 +2026,9 @@ "type": "Prompt" }, "dragging": false, - "id": "Prompt-UAMac", + "id": "Prompt-tR2a7", "measured": { - "height": 495, + "height": 449, "width": 320 }, "position": { @@ -2038,7 +2040,7 @@ }, { "data": { - "id": "ChatOutput-9nsTW", + "id": "ChatOutput-w4PAC", "node": { "base_classes": [ "Message" @@ -2337,9 +2339,9 @@ "type": "ChatOutput" }, "dragging": false, - "id": "ChatOutput-9nsTW", + "id": "ChatOutput-w4PAC", "measured": { - "height": 230, + "height": 204, "width": 320 }, "position": { @@ -2351,7 +2353,7 @@ }, { "data": { - "id": "YouTubeTranscripts-QMIjk", + "id": "YouTubeTranscripts-Nbrx3", "node": { "base_classes": [ "Data", @@ -2373,6 +2375,7 @@ "frozen": false, "icon": "YouTube", "legacy": false, + "lf_version": "1.4.2", "metadata": {}, "minimized": false, "output_types": [], @@ -2381,6 +2384,7 @@ "allows_loop": false, "cache": true, "display_name": "Toolset", + "group_outputs": false, "hidden": null, "method": "to_toolkit", "name": "component_as_tool", @@ -2434,11 +2438,11 @@ "value": "import pandas as pd\nimport youtube_transcript_api\nfrom langchain_community.document_loaders import YoutubeLoader\nfrom langchain_community.document_loaders.youtube import TranscriptFormat\n\nfrom langflow.custom.custom_component.component import Component\nfrom langflow.inputs.inputs import DropdownInput, IntInput, MultilineInput\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 YouTubeTranscriptsComponent(Component):\n \"\"\"A component that extracts spoken content from YouTube videos as transcripts.\"\"\"\n\n display_name: str = \"YouTube Transcripts\"\n description: str = \"Extracts spoken content from YouTube videos with multiple output options.\"\n icon: str = \"YouTube\"\n name = \"YouTubeTranscripts\"\n\n inputs = [\n MultilineInput(\n name=\"url\",\n display_name=\"Video URL\",\n info=\"Enter the YouTube video URL to get transcripts from.\",\n tool_mode=True,\n required=True,\n ),\n IntInput(\n name=\"chunk_size_seconds\",\n display_name=\"Chunk Size (seconds)\",\n value=60,\n info=\"The size of each transcript chunk in seconds.\",\n ),\n DropdownInput(\n name=\"translation\",\n display_name=\"Translation Language\",\n advanced=True,\n options=[\"\", \"en\", \"es\", \"fr\", \"de\", \"it\", \"pt\", \"ru\", \"ja\", \"ko\", \"hi\", \"ar\", \"id\"],\n info=\"Translate the transcripts to the specified language. Leave empty for no translation.\",\n ),\n ]\n\n outputs = [\n Output(name=\"dataframe\", display_name=\"Chunks\", method=\"get_dataframe_output\"),\n Output(name=\"message\", display_name=\"Transcript\", method=\"get_message_output\"),\n Output(name=\"data_output\", display_name=\"Transcript + Source\", method=\"get_data_output\"),\n ]\n\n def _load_transcripts(self, *, as_chunks: bool = True):\n \"\"\"Internal method to load transcripts from YouTube.\"\"\"\n loader = YoutubeLoader.from_youtube_url(\n self.url,\n transcript_format=TranscriptFormat.CHUNKS if as_chunks else TranscriptFormat.TEXT,\n chunk_size_seconds=self.chunk_size_seconds,\n translation=self.translation or None,\n )\n return loader.load()\n\n def get_dataframe_output(self) -> DataFrame:\n \"\"\"Provides transcript output as a DataFrame with timestamp and text columns.\"\"\"\n try:\n transcripts = self._load_transcripts(as_chunks=True)\n\n # Create DataFrame with timestamp and text columns\n data = []\n for doc in transcripts:\n start_seconds = int(doc.metadata[\"start_seconds\"])\n start_minutes = start_seconds // 60\n start_seconds %= 60\n timestamp = f\"{start_minutes:02d}:{start_seconds:02d}\"\n data.append({\"timestamp\": timestamp, \"text\": doc.page_content})\n\n return DataFrame(pd.DataFrame(data))\n\n except (youtube_transcript_api.TranscriptsDisabled, youtube_transcript_api.NoTranscriptFound) as exc:\n return DataFrame(pd.DataFrame({\"error\": [f\"Failed to get YouTube transcripts: {exc!s}\"]}))\n\n def get_message_output(self) -> Message:\n \"\"\"Provides transcript output as continuous text.\"\"\"\n try:\n transcripts = self._load_transcripts(as_chunks=False)\n result = transcripts[0].page_content\n return Message(text=result)\n\n except (youtube_transcript_api.TranscriptsDisabled, youtube_transcript_api.NoTranscriptFound) as exc:\n error_msg = f\"Failed to get YouTube transcripts: {exc!s}\"\n return Message(text=error_msg)\n\n def get_data_output(self) -> Data:\n \"\"\"Creates a structured data object with transcript and metadata.\n\n Returns a Data object containing transcript text, video URL, and any error\n messages that occurred during processing. The object includes:\n - 'transcript': continuous text from the entire video (concatenated if multiple parts)\n - 'video_url': the input YouTube URL\n - 'error': error message if an exception occurs\n \"\"\"\n default_data = {\"transcript\": \"\", \"video_url\": self.url, \"error\": None}\n\n try:\n transcripts = self._load_transcripts(as_chunks=False)\n if not transcripts:\n default_data[\"error\"] = \"No transcripts found.\"\n return Data(data=default_data)\n\n # Combine all transcript parts\n full_transcript = \" \".join(doc.page_content for doc in transcripts)\n return Data(data={\"transcript\": full_transcript, \"video_url\": self.url})\n\n except (\n youtube_transcript_api.TranscriptsDisabled,\n youtube_transcript_api.NoTranscriptFound,\n youtube_transcript_api.CouldNotRetrieveTranscript,\n ) as exc:\n default_data[\"error\"] = str(exc)\n return Data(data=default_data)\n" }, "tools_metadata": { - "_input_type": "TableInput", + "_input_type": "ToolsInput", "advanced": false, - "display_name": "Edit tools", + "display_name": "Actions", "dynamic": false, - "info": "", + "info": "Modify tool names and descriptions to help agents understand when to use each tool.", "is_list": true, "list_add_label": "Add More", "name": "tools_metadata", @@ -2446,107 +2450,63 @@ "real_time_refresh": true, "required": false, "show": true, - "table_icon": "Hammer", - "table_options": { - "block_add": true, - "block_delete": true, - "block_edit": true, - "block_filter": true, - "block_hide": true, - "block_select": true, - "block_sort": true, - "description": "Modify tool names and descriptions to help agents understand when to use each tool.", - "field_parsers": { - "commands": "commands", - "name": [ - "snake_case", - "no_blank" - ] - }, - "hide_options": true - }, - "table_schema": { - "columns": [ - { - "default": "None", - "description": "Specify the name of the tool.", - "disable_edit": false, - "display_name": "Tool Name", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "hidden": false, - "name": "name", - "sortable": false, - "type": "str" - }, - { - "default": "None", - "description": "Describe the purpose of the tool.", - "disable_edit": false, - "display_name": "Tool Description", - "edit_mode": "popover", - "filterable": false, - "formatter": "text", - "hidden": false, - "name": "description", - "sortable": false, - "type": "str" - }, - { - "default": "None", - "description": "The default identifiers for the tools and cannot be changed.", - "disable_edit": true, - "display_name": "Tool Identifiers", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "hidden": true, - "name": "tags", - "sortable": false, - "type": "str" - }, - { - "default": true, - "description": "Indicates whether the tool is currently active. Set to True to activate this tool.", - "disable_edit": false, - "display_name": "Enable", - "edit_mode": "popover", - "filterable": true, - "formatter": "boolean", - "hidden": false, - "name": "status", - "sortable": true, - "type": "boolean" - } - ] - }, "title_case": false, "tool_mode": false, "trace_as_metadata": true, - "trigger_icon": "Hammer", - "trigger_text": "", - "type": "table", + "type": "tools", "value": [ { - "description": "get_dataframe_output(url: Message) - Extracts spoken content from YouTube videos with multiple output options.", - "name": "YouTubeTranscripts-get_dataframe_output", + "args": { + "url": { + "description": "Enter the YouTube video URL to get transcripts from.", + "title": "Url", + "type": "string" + } + }, + "description": "YouTubeTranscripts. get_dataframe_output - Extracts spoken content from YouTube videos with multiple output options.", + "display_description": "YouTubeTranscripts. get_dataframe_output - Extracts spoken content from YouTube videos with multiple output options.", + "display_name": "get_dataframe_output", + "name": "get_dataframe_output", + "readonly": false, + "status": true, "tags": [ - "YouTubeTranscripts-get_dataframe_output" + "get_dataframe_output" ] }, { - "description": "get_message_output(url: Message) - Extracts spoken content from YouTube videos with multiple output options.", - "name": "YouTubeTranscripts-get_message_output", + "args": { + "url": { + "description": "Enter the YouTube video URL to get transcripts from.", + "title": "Url", + "type": "string" + } + }, + "description": "YouTubeTranscripts. get_message_output - Extracts spoken content from YouTube videos with multiple output options.", + "display_description": "YouTubeTranscripts. get_message_output - Extracts spoken content from YouTube videos with multiple output options.", + "display_name": "get_message_output", + "name": "get_message_output", + "readonly": false, + "status": true, "tags": [ - "YouTubeTranscripts-get_message_output" + "get_message_output" ] }, { - "description": "get_data_output(url: Message) - Extracts spoken content from YouTube videos with multiple output options.", - "name": "YouTubeTranscripts-get_data_output", + "args": { + "url": { + "description": "Enter the YouTube video URL to get transcripts from.", + "title": "Url", + "type": "string" + } + }, + "description": "YouTubeTranscripts. get_data_output - Extracts spoken content from YouTube videos with multiple output options.", + "display_description": "YouTubeTranscripts. get_data_output - Extracts spoken content from YouTube videos with multiple output options.", + "display_name": "get_data_output", + "name": "get_data_output", + "readonly": false, + "status": true, "tags": [ - "YouTubeTranscripts-get_data_output" + "get_data_output" ] } ] @@ -2617,9 +2577,9 @@ "type": "YouTubeTranscripts" }, "dragging": false, - "id": "YouTubeTranscripts-QMIjk", + "id": "YouTubeTranscripts-Nbrx3", "measured": { - "height": 417, + "height": 328, "width": 320 }, "position": { @@ -2631,7 +2591,7 @@ }, { "data": { - "id": "ChatInput-XErsc", + "id": "ChatInput-jHqUS", "node": { "base_classes": [ "Message" @@ -2659,7 +2619,7 @@ "icon": "MessagesSquare", "key": "ChatInput", "legacy": false, - "lf_version": "1.1.3", + "lf_version": "1.4.2", "metadata": {}, "minimized": true, "output_types": [], @@ -2931,9 +2891,9 @@ "type": "ChatInput" }, "dragging": false, - "id": "ChatInput-XErsc", + "id": "ChatInput-jHqUS", "measured": { - "height": 230, + "height": 204, "width": 320 }, "position": { @@ -2945,7 +2905,7 @@ }, { "data": { - "id": "note-Cc4Ez", + "id": "note-UUFzO", "node": { "description": "# Batch Run component\n\nThis component processes a DataFrame by running each row through a Language Model (LLM). Perfect for batch analysis, sentiment scoring, or content generation at scale.\n\n## How It Works\n1. Accepts a DataFrame with text data.\n2. Routes each row through your chosen LLM.\n3. Returns new DataFrame with `text_input` and `model_response`.\n\n", "display_name": "", @@ -2958,7 +2918,7 @@ }, "dragging": false, "height": 522, - "id": "note-Cc4Ez", + "id": "note-UUFzO", "measured": { "height": 522, "width": 325 @@ -2974,7 +2934,7 @@ }, { "data": { - "id": "note-fckWh", + "id": "note-sqTuK", "node": { "description": "## Set up the YouTube API\n1. Go to [Google Cloud Console](https://console.cloud.google.com).\n2. Create a new project or select existing one.\n3. Enable YouTube Data API v3:\n - Navigate to APIs & Services > Library.\n - Search \"YouTube Data API v3\".\n - Click Enable.\n4. Create credentials:\n - Go to APIs & Services > Credentials.\n - Click Create Credentials > API Key.\n5. Copy your new API key for use in the component.\n\n⚠️ Remember to:\n- Restrict the API key to YouTube Data API v3 only.\n- Set appropriate quotas and restrictions.\n", "display_name": "", @@ -2987,7 +2947,7 @@ }, "dragging": false, "height": 486, - "id": "note-fckWh", + "id": "note-sqTuK", "measured": { "height": 486, "width": 325 @@ -3003,7 +2963,7 @@ }, { "data": { - "id": "note-FZ1Fg", + "id": "note-Di19o", "node": { "description": "# 🎥 YouTube Video Analysis\nThis flow performs comprehensive analysis of YouTube videos.\n1. Extract video comments and transcripts.\n2. Run sentiment analysis on comments using LLM.\n3. Combine transcript content and comment sentiment for comprehensive video analysis.\n\n## Prerequisites\n- OpenAI API Key\n- YouTube Data API v3 key", "display_name": "", @@ -3016,7 +2976,7 @@ }, "dragging": false, "height": 454, - "id": "note-FZ1Fg", + "id": "note-Di19o", "measured": { "height": 454, "width": 433 @@ -3032,7 +2992,7 @@ }, { "data": { - "id": "ConditionalRouter-7lzPh", + "id": "ConditionalRouter-SP1WC", "node": { "base_classes": [ "Message" @@ -3278,9 +3238,9 @@ "type": "ConditionalRouter" }, "dragging": false, - "id": "ConditionalRouter-7lzPh", + "id": "ConditionalRouter-SP1WC", "measured": { - "height": 588, + "height": 429, "width": 320 }, "position": { @@ -3292,7 +3252,7 @@ }, { "data": { - "id": "parser-r3iNU", + "id": "parser-LDaMh", "node": { "base_classes": [ "Message" @@ -3453,9 +3413,9 @@ "type": "parser" }, "dragging": false, - "id": "parser-r3iNU", + "id": "parser-LDaMh", "measured": { - "height": 395, + "height": 361, "width": 320 }, "position": { @@ -3467,16 +3427,16 @@ } ], "viewport": { - "x": 69.36235934000024, - "y": -2491.3683867679606, - "zoom": 0.4827961559150896 + "x": 442.6851065891309, + "y": -1378.1987686741775, + "zoom": 0.2815925120128663 } }, "description": "The YouTube Analysis flow extracts video comments and transcripts, analyzing sentiment patterns and content themes.", "endpoint_name": null, - "id": "5865d442-4b78-49a2-b561-c29b8286a981", + "id": "828f13a1-cb75-4c8f-90e7-6e948c2fd899", "is_component": false, - "last_tested_version": "1.2.0", + "last_tested_version": "1.4.2", "name": "Youtube Analysis", "tags": [ "agents", diff --git a/src/frontend/tests/core/integrations/Financial Report Parser.spec.ts b/src/frontend/tests/core/integrations/Financial Report Parser.spec.ts index d987461da..2c30b7ebb 100644 --- a/src/frontend/tests/core/integrations/Financial Report Parser.spec.ts +++ b/src/frontend/tests/core/integrations/Financial Report Parser.spec.ts @@ -34,13 +34,6 @@ withEventDeliveryModes( await initialGPTsetup(page); - //* TODO: Remove these 3 steps once the template is updated *// - await page.getByTestId("dropdown-output-openaimodel").click(); - - await page - .getByTestId("dropdown-item-output-openaimodel-language model") - .click(); - await page.getByTestId("tab_1_stringify").click(); await page.getByTestId("playground-btn-flow-io").click();