Spaces:
Running
Running
agent-flow
/
src
/backend
/base
/langflow
/initial_setup
/starter_projects
/Custom Component Maker.json
{ | |
"data": { | |
"edges": [ | |
{ | |
"animated": false, | |
"className": "", | |
"data": { | |
"sourceHandle": { | |
"dataType": "Memory", | |
"id": "Memory-QarNf", | |
"name": "messages_text", | |
"output_types": [ | |
"Message" | |
] | |
}, | |
"targetHandle": { | |
"fieldName": "CHAT_HISTORY", | |
"id": "Prompt-VXWKj", | |
"inputTypes": [ | |
"Message", | |
"Text" | |
], | |
"type": "str" | |
} | |
}, | |
"id": "reactflow__edge-Memory-QarNf{œdataTypeœ:œMemoryœ,œidœ:œMemory-QarNfœ,œnameœ:œmessages_textœ,œoutput_typesœ:[œMessageœ]}-Prompt-VXWKj{œfieldNameœ:œCHAT_HISTORYœ,œidœ:œPrompt-VXWKjœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", | |
"selected": false, | |
"source": "Memory-QarNf", | |
"sourceHandle": "{œdataTypeœ: œMemoryœ, œidœ: œMemory-QarNfœ, œnameœ: œmessages_textœ, œoutput_typesœ: [œMessageœ]}", | |
"target": "Prompt-VXWKj", | |
"targetHandle": "{œfieldNameœ: œCHAT_HISTORYœ, œidœ: œPrompt-VXWKjœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" | |
}, | |
{ | |
"animated": false, | |
"className": "", | |
"data": { | |
"sourceHandle": { | |
"dataType": "ChatInput", | |
"id": "ChatInput-j1FgM", | |
"name": "message", | |
"output_types": [ | |
"Message" | |
] | |
}, | |
"targetHandle": { | |
"fieldName": "USER_INPUT", | |
"id": "Prompt-VXWKj", | |
"inputTypes": [ | |
"Message", | |
"Text" | |
], | |
"type": "str" | |
} | |
}, | |
"id": "reactflow__edge-ChatInput-j1FgM{œdataTypeœ:œChatInputœ,œidœ:œChatInput-j1FgMœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-VXWKj{œfieldNameœ:œUSER_INPUTœ,œidœ:œPrompt-VXWKjœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", | |
"selected": false, | |
"source": "ChatInput-j1FgM", | |
"sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-j1FgMœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", | |
"target": "Prompt-VXWKj", | |
"targetHandle": "{œfieldNameœ: œUSER_INPUTœ, œidœ: œPrompt-VXWKjœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" | |
}, | |
{ | |
"animated": false, | |
"className": "", | |
"data": { | |
"sourceHandle": { | |
"dataType": "Prompt", | |
"id": "Prompt-VXWKj", | |
"name": "prompt", | |
"output_types": [ | |
"Message" | |
] | |
}, | |
"targetHandle": { | |
"fieldName": "input_value", | |
"id": "AnthropicModel-39lt2", | |
"inputTypes": [ | |
"Message" | |
], | |
"type": "str" | |
} | |
}, | |
"id": "reactflow__edge-Prompt-VXWKj{œdataTypeœ:œPromptœ,œidœ:œPrompt-VXWKjœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-AnthropicModel-39lt2{œfieldNameœ:œinput_valueœ,œidœ:œAnthropicModel-39lt2œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", | |
"source": "Prompt-VXWKj", | |
"sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-VXWKjœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", | |
"target": "AnthropicModel-39lt2", | |
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAnthropicModel-39lt2œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" | |
}, | |
{ | |
"animated": false, | |
"className": "", | |
"data": { | |
"sourceHandle": { | |
"dataType": "AnthropicModel", | |
"id": "AnthropicModel-39lt2", | |
"name": "text_output", | |
"output_types": [ | |
"Message" | |
] | |
}, | |
"targetHandle": { | |
"fieldName": "input_value", | |
"id": "ChatOutput-ZCLW2", | |
"inputTypes": [ | |
"Message" | |
], | |
"type": "str" | |
} | |
}, | |
"id": "reactflow__edge-AnthropicModel-39lt2{œdataTypeœ:œAnthropicModelœ,œidœ:œAnthropicModel-39lt2œ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-ZCLW2{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-ZCLW2œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", | |
"source": "AnthropicModel-39lt2", | |
"sourceHandle": "{œdataTypeœ: œAnthropicModelœ, œidœ: œAnthropicModel-39lt2œ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", | |
"target": "ChatOutput-ZCLW2", | |
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-ZCLW2œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" | |
}, | |
{ | |
"animated": false, | |
"className": "", | |
"data": { | |
"sourceHandle": { | |
"dataType": "URL", | |
"id": "URL-ynvHI", | |
"name": "text", | |
"output_types": [ | |
"Message" | |
] | |
}, | |
"targetHandle": { | |
"fieldName": "EXAMPLE_COMPONENTS", | |
"id": "Prompt-VXWKj", | |
"inputTypes": [ | |
"Message", | |
"Text" | |
], | |
"type": "str" | |
} | |
}, | |
"id": "reactflow__edge-URL-ynvHI{œdataTypeœ:œURLœ,œidœ:œURL-ynvHIœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-VXWKj{œfieldNameœ:œEXAMPLE_COMPONENTSœ,œidœ:œPrompt-VXWKjœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", | |
"source": "URL-ynvHI", | |
"sourceHandle": "{œdataTypeœ: œURLœ, œidœ: œURL-ynvHIœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", | |
"target": "Prompt-VXWKj", | |
"targetHandle": "{œfieldNameœ: œEXAMPLE_COMPONENTSœ, œidœ: œPrompt-VXWKjœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" | |
}, | |
{ | |
"animated": false, | |
"className": "", | |
"data": { | |
"sourceHandle": { | |
"dataType": "URL", | |
"id": "URL-j0mBc", | |
"name": "text", | |
"output_types": [ | |
"Message" | |
] | |
}, | |
"targetHandle": { | |
"fieldName": "BASE_COMPONENT_CODE", | |
"id": "Prompt-VXWKj", | |
"inputTypes": [ | |
"Message", | |
"Text" | |
], | |
"type": "str" | |
} | |
}, | |
"id": "reactflow__edge-URL-j0mBc{œdataTypeœ:œURLœ,œidœ:œURL-j0mBcœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-VXWKj{œfieldNameœ:œBASE_COMPONENT_CODEœ,œidœ:œPrompt-VXWKjœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", | |
"source": "URL-j0mBc", | |
"sourceHandle": "{œdataTypeœ: œURLœ, œidœ: œURL-j0mBcœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", | |
"target": "Prompt-VXWKj", | |
"targetHandle": "{œfieldNameœ: œBASE_COMPONENT_CODEœ, œidœ: œPrompt-VXWKjœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" | |
}, | |
{ | |
"animated": false, | |
"className": "", | |
"data": { | |
"sourceHandle": { | |
"dataType": "URL", | |
"id": "URL-xqtKG", | |
"name": "text", | |
"output_types": [ | |
"Message" | |
] | |
}, | |
"targetHandle": { | |
"fieldName": "CUSTOM_COMPONENT_CODE", | |
"id": "Prompt-VXWKj", | |
"inputTypes": [ | |
"Message", | |
"Text" | |
], | |
"type": "str" | |
} | |
}, | |
"id": "reactflow__edge-URL-xqtKG{œdataTypeœ:œURLœ,œidœ:œURL-xqtKGœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-VXWKj{œfieldNameœ:œCUSTOM_COMPONENT_CODEœ,œidœ:œPrompt-VXWKjœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", | |
"source": "URL-xqtKG", | |
"sourceHandle": "{œdataTypeœ: œURLœ, œidœ: œURL-xqtKGœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", | |
"target": "Prompt-VXWKj", | |
"targetHandle": "{œfieldNameœ: œCUSTOM_COMPONENT_CODEœ, œidœ: œPrompt-VXWKjœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" | |
} | |
], | |
"nodes": [ | |
{ | |
"data": { | |
"description": "Get chat inputs from the Playground.", | |
"display_name": "Chat Input", | |
"id": "ChatInput-j1FgM", | |
"node": { | |
"base_classes": [ | |
"Message" | |
], | |
"beta": false, | |
"conditional_paths": [], | |
"custom_fields": {}, | |
"description": "Get chat inputs from the Playground.", | |
"display_name": "Chat Input", | |
"documentation": "", | |
"edited": false, | |
"field_order": [ | |
"input_value", | |
"should_store_message", | |
"sender", | |
"sender_name", | |
"session_id", | |
"files", | |
"background_color", | |
"chat_icon", | |
"text_color" | |
], | |
"frozen": false, | |
"icon": "MessagesSquare", | |
"legacy": false, | |
"lf_version": "1.0.19.post2", | |
"metadata": {}, | |
"output_types": [], | |
"outputs": [ | |
{ | |
"cache": true, | |
"display_name": "Message", | |
"method": "message_response", | |
"name": "message", | |
"selected": "Message", | |
"types": [ | |
"Message" | |
], | |
"value": "__UNDEFINED__" | |
} | |
], | |
"pinned": false, | |
"template": { | |
"_type": "Component", | |
"background_color": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Background Color", | |
"dynamic": false, | |
"info": "The background color of the icon.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "background_color", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
}, | |
"chat_icon": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Icon", | |
"dynamic": false, | |
"info": "The icon of the message.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "chat_icon", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
}, | |
"code": { | |
"advanced": true, | |
"dynamic": true, | |
"fileTypes": [], | |
"file_path": "", | |
"info": "", | |
"list": false, | |
"load_from_db": false, | |
"multiline": true, | |
"name": "code", | |
"password": false, | |
"placeholder": "", | |
"required": true, | |
"show": true, | |
"title_case": false, | |
"type": "code", | |
"value": "from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.schema.message import Message\nfrom langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_NAME_USER, MESSAGE_SENDER_USER\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\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\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 ),\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=\"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={\"background_color\": background_color, \"text_color\": text_color, \"icon\": icon},\n )\n if self.session_id and isinstance(message, Message) and self.should_store_message:\n stored_message = await self.send_message(\n message,\n )\n self.message.value = stored_message\n message = stored_message\n\n self.status = message\n return message\n" | |
}, | |
"files": { | |
"_input_type": "FileInput", | |
"advanced": true, | |
"display_name": "Files", | |
"dynamic": false, | |
"fileTypes": [ | |
"txt", | |
"md", | |
"mdx", | |
"csv", | |
"json", | |
"yaml", | |
"yml", | |
"xml", | |
"html", | |
"htm", | |
"pdf", | |
"docx", | |
"py", | |
"sh", | |
"sql", | |
"js", | |
"ts", | |
"tsx", | |
"jpg", | |
"jpeg", | |
"png", | |
"bmp", | |
"image" | |
], | |
"file_path": "", | |
"info": "Files to be sent with the message.", | |
"list": true, | |
"name": "files", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_metadata": true, | |
"type": "file", | |
"value": "" | |
}, | |
"input_value": { | |
"_input_type": "MultilineInput", | |
"advanced": false, | |
"display_name": "Text", | |
"dynamic": false, | |
"info": "Message to be passed as input.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"multiline": true, | |
"name": "input_value", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "Failed to get YouTube transcripts: 1 validation error for Data\ndata\n Input should be a valid dictionary [type=dict_type, input_value=Document(metadata={'sourc...adding the API key and\"), input_type=Document]\n For further information visit https://errors.pydantic.dev/2.9/v/dict_type\n\n\nAlso, adapt the \"text\" bc it returns this \"Document(metadata={'source': 'UkV79sJAvz8'}, page_content=\"assembly AI is one of the leaders in transcription services so you can convert speech into text and they have many different products available on their platform and we can use assembly within langlow and the way we can get started is to First make an account with assembly Ai and once you get started you will be provided with an API key this is something we're going to need in langlow now back in link flow there are a few different components available and in this example we are using the start transcript component within this component we can provide a file and what I did is I uploaded a 1-hour talk by Andre karpati and this is intro to the large language models and this is an MP3 file so after adding the API key and then the audio file we can select a model that we want to use for the transcription there are two different options available here best and Nano now after you select the model you can either have the language detection on or leave defaults so I left everything in default and then I started the task and once we run the flow we get a transcript ID and attaching this component with the assembly AI pole transcript component we can now get the results and if we were to look at the results available able from this component there are quite a lot of fields that we can see as a result of this component and some of the most important ones you can see is the text from the transcript as you can see it's quite a large file and all of that was converted from speech to text easily by assembly AI it just took a few seconds and then we can see Word level timestamps if needed as what was spoken at what time the starting and end time for that and also the confidence if there are multiple speakers then it also identifies the speakers for us and then we can also see the utterances at different times so there's also word there's a full text and there's some additional information available here now we can use this data for many different things one is we can parse the transcript so we can just look at the full transcript that was available from this video or in this case this MP3 file and then we can also run to get subtitles and this could be used for any Services where we want to add subtitles in different formats so there is the SRT and the VT format available and the way this looks so I ran it for SRT We have basically the time stamps as well as the sentences those were converted from those time stamps and we can see that it goes on for the full length of the audio file and then if needed we can also convert that to vtt last thing is that if you have credits available in your assembly AI account you can also perform a summary of the audio or you could perhaps do some additional task so for example in our case we could say that create a summary of the transcript we could also say that create a blog post from the transcript or perhaps an essay from the transcript so we can get creative with the available information since the transcript of the file is now available and we can utilize that text for many different purposes the flow and the components should be available in the store be sure to add your API key in all of these components wherever it says to add the API key if not it might throw some errors and there are also some additional components available you can check those out based on your use cases as well give it a try and let us know if you found it helpful\")\" \n\nwe only want the page_content " | |
}, | |
"sender": { | |
"_input_type": "DropdownInput", | |
"advanced": true, | |
"combobox": false, | |
"display_name": "Sender Type", | |
"dynamic": false, | |
"info": "Type of sender.", | |
"name": "sender", | |
"options": [ | |
"Machine", | |
"User" | |
], | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "User" | |
}, | |
"sender_name": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Sender Name", | |
"dynamic": false, | |
"info": "Name of the sender.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "sender_name", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "User" | |
}, | |
"session_id": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Session ID", | |
"dynamic": false, | |
"info": "The session ID of the chat. If empty, the current session ID parameter will be used.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "session_id", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
}, | |
"should_store_message": { | |
"_input_type": "BoolInput", | |
"advanced": true, | |
"display_name": "Store Messages", | |
"dynamic": false, | |
"info": "Store the message in the history.", | |
"list": false, | |
"name": "should_store_message", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_metadata": true, | |
"type": "bool", | |
"value": true | |
}, | |
"text_color": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Text Color", | |
"dynamic": false, | |
"info": "The text color of the name", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "text_color", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
} | |
}, | |
"tool_mode": false | |
}, | |
"type": "ChatInput" | |
}, | |
"dragging": false, | |
"height": 231, | |
"id": "ChatInput-j1FgM", | |
"position": { | |
"x": 1436.7228707197569, | |
"y": 1045.2749109595 | |
}, | |
"positionAbsolute": { | |
"x": 1436.7228707197569, | |
"y": 1045.2749109595 | |
}, | |
"selected": false, | |
"type": "genericNode", | |
"width": 320 | |
}, | |
{ | |
"data": { | |
"description": "Retrieves stored chat messages from Langflow tables or an external memory.", | |
"display_name": "Chat Memory", | |
"id": "Memory-QarNf", | |
"node": { | |
"base_classes": [ | |
"Data", | |
"Message" | |
], | |
"beta": false, | |
"conditional_paths": [], | |
"custom_fields": {}, | |
"description": "Retrieves stored chat messages from Langflow tables or an external memory.", | |
"display_name": "Chat Memory", | |
"documentation": "", | |
"edited": false, | |
"field_order": [ | |
"memory", | |
"sender", | |
"sender_name", | |
"n_messages", | |
"session_id", | |
"order", | |
"template" | |
], | |
"frozen": false, | |
"icon": "message-square-more", | |
"legacy": false, | |
"lf_version": "1.0.19.post2", | |
"metadata": {}, | |
"output_types": [], | |
"outputs": [ | |
{ | |
"cache": true, | |
"display_name": "Data", | |
"method": "retrieve_messages", | |
"name": "messages", | |
"selected": "Data", | |
"types": [ | |
"Data" | |
], | |
"value": "__UNDEFINED__" | |
}, | |
{ | |
"cache": true, | |
"display_name": "Text", | |
"method": "retrieve_messages_as_text", | |
"name": "messages_text", | |
"selected": "Message", | |
"types": [ | |
"Message" | |
], | |
"value": "__UNDEFINED__" | |
} | |
], | |
"pinned": false, | |
"template": { | |
"_type": "Component", | |
"code": { | |
"advanced": true, | |
"dynamic": true, | |
"fileTypes": [], | |
"file_path": "", | |
"info": "", | |
"list": false, | |
"load_from_db": false, | |
"multiline": true, | |
"name": "code", | |
"password": false, | |
"placeholder": "", | |
"required": true, | |
"show": true, | |
"title_case": false, | |
"type": "code", | |
"value": "from langchain.memory import ConversationBufferMemory\n\nfrom langflow.custom import Component\nfrom langflow.field_typing import BaseChatMemory\nfrom langflow.helpers.data import data_to_text\nfrom langflow.inputs import HandleInput\nfrom langflow.io import DropdownInput, IntInput, MessageTextInput, MultilineInput, Output\nfrom langflow.memory import LCBuiltinChatMemory, aget_messages\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\nfrom langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER\n\n\nclass MemoryComponent(Component):\n display_name = \"Message History\"\n description = \"Retrieves stored chat messages from Langflow tables or an external memory.\"\n icon = \"message-square-more\"\n name = \"Memory\"\n\n inputs = [\n HandleInput(\n name=\"memory\",\n display_name=\"External Memory\",\n input_types=[\"BaseChatMessageHistory\"],\n info=\"Retrieve messages from an external memory. If empty, it will use the Langflow tables.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER, \"Machine and User\"],\n value=\"Machine and User\",\n info=\"Filter by sender type.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Filter by sender name.\",\n advanced=True,\n ),\n IntInput(\n name=\"n_messages\",\n display_name=\"Number of Messages\",\n value=100,\n info=\"Number of messages to retrieve.\",\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 DropdownInput(\n name=\"order\",\n display_name=\"Order\",\n options=[\"Ascending\", \"Descending\"],\n value=\"Ascending\",\n info=\"Order of the messages.\",\n advanced=True,\n tool_mode=True,\n ),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. \"\n \"It can contain the keys {text}, {sender} or any other key in the message data.\",\n value=\"{sender_name}: {text}\",\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"messages\", method=\"retrieve_messages\"),\n Output(display_name=\"Text\", name=\"messages_text\", method=\"retrieve_messages_as_text\"),\n ]\n\n async def retrieve_messages(self) -> Data:\n sender = self.sender\n sender_name = self.sender_name\n session_id = self.session_id\n n_messages = self.n_messages\n order = \"DESC\" if self.order == \"Descending\" else \"ASC\"\n\n if sender == \"Machine and User\":\n sender = None\n\n if self.memory:\n # override session_id\n self.memory.session_id = session_id\n\n stored = await self.memory.aget_messages()\n # langchain memories are supposed to return messages in ascending order\n if order == \"DESC\":\n stored = stored[::-1]\n if n_messages:\n stored = stored[:n_messages]\n stored = [Message.from_lc_message(m) for m in stored]\n if sender:\n expected_type = MESSAGE_SENDER_AI if sender == MESSAGE_SENDER_AI else MESSAGE_SENDER_USER\n stored = [m for m in stored if m.type == expected_type]\n else:\n stored = await aget_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n self.status = stored\n return stored\n\n async def retrieve_messages_as_text(self) -> Message:\n stored_text = data_to_text(self.template, await self.retrieve_messages())\n self.status = stored_text\n return Message(text=stored_text)\n\n def build_lc_memory(self) -> BaseChatMemory:\n chat_memory = self.memory or LCBuiltinChatMemory(flow_id=self.flow_id, session_id=self.session_id)\n return ConversationBufferMemory(chat_memory=chat_memory)\n" | |
}, | |
"memory": { | |
"_input_type": "HandleInput", | |
"advanced": false, | |
"display_name": "External Memory", | |
"dynamic": false, | |
"info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", | |
"input_types": [ | |
"BaseChatMessageHistory" | |
], | |
"list": false, | |
"name": "memory", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_metadata": true, | |
"type": "other", | |
"value": "" | |
}, | |
"n_messages": { | |
"_input_type": "IntInput", | |
"advanced": true, | |
"display_name": "Number of Messages", | |
"dynamic": false, | |
"info": "Number of messages to retrieve.", | |
"list": false, | |
"name": "n_messages", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_metadata": true, | |
"type": "int", | |
"value": 100 | |
}, | |
"order": { | |
"_input_type": "DropdownInput", | |
"advanced": true, | |
"combobox": false, | |
"display_name": "Order", | |
"dynamic": false, | |
"info": "Order of the messages.", | |
"name": "order", | |
"options": [ | |
"Ascending", | |
"Descending" | |
], | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "Ascending" | |
}, | |
"sender": { | |
"_input_type": "DropdownInput", | |
"advanced": true, | |
"combobox": false, | |
"display_name": "Sender Type", | |
"dynamic": false, | |
"info": "Filter by sender type.", | |
"name": "sender", | |
"options": [ | |
"Machine", | |
"User", | |
"Machine and User" | |
], | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "Machine and User" | |
}, | |
"sender_name": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Sender Name", | |
"dynamic": false, | |
"info": "Filter by sender name.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"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": "" | |
}, | |
"session_id": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Session ID", | |
"dynamic": false, | |
"info": "The session ID of the chat. If empty, the current session ID parameter will be used.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "session_id", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
}, | |
"template": { | |
"_input_type": "MultilineInput", | |
"advanced": true, | |
"display_name": "Template", | |
"dynamic": false, | |
"info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"multiline": true, | |
"name": "template", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "{sender_name}: {text}" | |
} | |
}, | |
"tool_mode": false | |
}, | |
"type": "Memory" | |
}, | |
"dragging": false, | |
"height": 262, | |
"id": "Memory-QarNf", | |
"position": { | |
"x": 1830.6888981898887, | |
"y": 946.1205963195098 | |
}, | |
"positionAbsolute": { | |
"x": 1830.6888981898887, | |
"y": 946.1205963195098 | |
}, | |
"selected": false, | |
"type": "genericNode", | |
"width": 320 | |
}, | |
{ | |
"data": { | |
"description": "Create a prompt template with dynamic variables.", | |
"display_name": "Prompt", | |
"id": "Prompt-VXWKj", | |
"node": { | |
"base_classes": [ | |
"Message" | |
], | |
"beta": false, | |
"conditional_paths": [], | |
"custom_fields": { | |
"template": [ | |
"BASE_COMPONENT_CODE", | |
"CUSTOM_COMPONENT_CODE", | |
"EXAMPLE_COMPONENTS", | |
"CHAT_HISTORY", | |
"USER_INPUT" | |
] | |
}, | |
"description": "Create a prompt template with dynamic variables.", | |
"display_name": "Prompt", | |
"documentation": "", | |
"edited": false, | |
"field_order": [ | |
"template" | |
], | |
"frozen": false, | |
"icon": "prompts", | |
"legacy": false, | |
"lf_version": "1.0.19.post2", | |
"metadata": {}, | |
"output_types": [], | |
"outputs": [ | |
{ | |
"cache": true, | |
"display_name": "Prompt Message", | |
"method": "build_prompt", | |
"name": "prompt", | |
"selected": "Message", | |
"types": [ | |
"Message" | |
], | |
"value": "__UNDEFINED__" | |
} | |
], | |
"pinned": false, | |
"template": { | |
"BASE_COMPONENT_CODE": { | |
"advanced": false, | |
"display_name": "BASE_COMPONENT_CODE", | |
"dynamic": false, | |
"field_type": "str", | |
"fileTypes": [], | |
"file_path": "", | |
"info": "", | |
"input_types": [ | |
"Message", | |
"Text" | |
], | |
"list": false, | |
"load_from_db": false, | |
"multiline": true, | |
"name": "BASE_COMPONENT_CODE", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"type": "str", | |
"value": "" | |
}, | |
"CHAT_HISTORY": { | |
"advanced": false, | |
"display_name": "CHAT_HISTORY", | |
"dynamic": false, | |
"field_type": "str", | |
"fileTypes": [], | |
"file_path": "", | |
"info": "", | |
"input_types": [ | |
"Message", | |
"Text" | |
], | |
"list": false, | |
"load_from_db": false, | |
"multiline": true, | |
"name": "CHAT_HISTORY", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"type": "str", | |
"value": "" | |
}, | |
"CUSTOM_COMPONENT_CODE": { | |
"advanced": false, | |
"display_name": "CUSTOM_COMPONENT_CODE", | |
"dynamic": false, | |
"field_type": "str", | |
"fileTypes": [], | |
"file_path": "", | |
"info": "", | |
"input_types": [ | |
"Message", | |
"Text" | |
], | |
"list": false, | |
"load_from_db": false, | |
"multiline": true, | |
"name": "CUSTOM_COMPONENT_CODE", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"type": "str", | |
"value": "" | |
}, | |
"EXAMPLE_COMPONENTS": { | |
"advanced": false, | |
"display_name": "EXAMPLE_COMPONENTS", | |
"dynamic": false, | |
"field_type": "str", | |
"fileTypes": [], | |
"file_path": "", | |
"info": "", | |
"input_types": [ | |
"Message", | |
"Text" | |
], | |
"list": false, | |
"load_from_db": false, | |
"multiline": true, | |
"name": "EXAMPLE_COMPONENTS", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"type": "str", | |
"value": "" | |
}, | |
"USER_INPUT": { | |
"advanced": false, | |
"display_name": "USER_INPUT", | |
"dynamic": false, | |
"field_type": "str", | |
"fileTypes": [], | |
"file_path": "", | |
"info": "", | |
"input_types": [ | |
"Message", | |
"Text" | |
], | |
"list": false, | |
"load_from_db": false, | |
"multiline": true, | |
"name": "USER_INPUT", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"type": "str", | |
"value": "" | |
}, | |
"_type": "Component", | |
"code": { | |
"advanced": true, | |
"dynamic": true, | |
"fileTypes": [], | |
"file_path": "", | |
"info": "", | |
"list": false, | |
"load_from_db": false, | |
"multiline": true, | |
"name": "code", | |
"password": false, | |
"placeholder": "", | |
"required": true, | |
"show": true, | |
"title_case": false, | |
"type": "code", | |
"value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.inputs.inputs import DefaultPromptField\nfrom langflow.io import MessageTextInput, Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n name = \"Prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n MessageTextInput(\n name=\"tool_placeholder\",\n display_name=\"Tool Placeholder\",\n tool_mode=True,\n advanced=True,\n info=\"A placeholder input for tool mode.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(self) -> Message:\n prompt = Message.from_template(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def _update_template(self, frontend_node: dict):\n prompt_template = frontend_node[\"template\"][\"template\"][\"value\"]\n custom_fields = frontend_node[\"custom_fields\"]\n frontend_node_template = frontend_node[\"template\"]\n _ = process_prompt_template(\n template=prompt_template,\n name=\"template\",\n custom_fields=custom_fields,\n frontend_node_template=frontend_node_template,\n )\n return frontend_node\n\n def post_code_processing(self, new_frontend_node: dict, current_frontend_node: dict):\n \"\"\"This function is called after the code validation is done.\"\"\"\n frontend_node = super().post_code_processing(new_frontend_node, current_frontend_node)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n # Kept it duplicated for backwards compatibility\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_frontend_node\n # and update the frontend_node with those values\n update_template_values(new_template=frontend_node, previous_template=current_frontend_node[\"template\"])\n return frontend_node\n\n def _get_fallback_input(self, **kwargs):\n return DefaultPromptField(**kwargs)\n" | |
}, | |
"template": { | |
"_input_type": "PromptInput", | |
"advanced": false, | |
"display_name": "Template", | |
"dynamic": false, | |
"info": "", | |
"list": false, | |
"load_from_db": false, | |
"name": "template", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"type": "prompt", | |
"value": "<Instructions>\nYou are an AI assistant specialized in creating Langflow components based on user requirements. Your task is to generate the code for a custom Langflow component according to the user's specifications.\n\nFirst, review the following code snippets for reference:\n\n<base_component>\n{BASE_COMPONENT_CODE}\n</base_component>\n\n<custom_component>\n{CUSTOM_COMPONENT_CODE}\n</custom_component>\n\n<example_components>\n{EXAMPLE_COMPONENTS}\n</example_components>\n\nNow, follow these steps to create a custom Langflow component:\n\n1. Analyze the user's input to determine the requirements for the component.\n2. Use an <inner_monologue> section to plan out the component structure and features based on the user's requirements.\n3. Generate the code for the custom component, using the provided code snippets as reference and inspiration.\n4. Provide a brief explanation of the component's functionality and how to use it.\n\nHere's the chat history and user input:\n\n<ChatHistory>\n{CHAT_HISTORY}\n</ChatHistory>\n\n<UserInput>\n{USER_INPUT}\n</UserInput>\n\nBased on the user's input, create a custom Langflow component that meets their requirements. Your response should include:\n\n1. <inner_monologue>\n Use this section to analyze the user's requirements and plan the component structure.\n</inner_monologue>\n\n2. <component_code>\n Generate the complete code for the custom Langflow component here.\n</component_code>\n\n3. <explanation>\n Provide a brief explanation of the component's functionality and how to use it.\n</explanation>\n\nRemember to:\n- Use the provided code snippets as a reference, but create a unique component tailored to the user's needs.\n- Include all necessary imports and class definitions.\n- Implement the required inputs, outputs, and any additional features specified by the user.\n- Use clear and descriptive variable names and comments to enhance code readability.\n- Ensure that the component follows Langflow best practices and conventions.\n\nIf the user's input is unclear or lacks specific details, make reasonable assumptions based on the context and explain these assumptions in your response.\n\n</Instructions>" | |
}, | |
"tool_placeholder": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Tool Placeholder", | |
"dynamic": false, | |
"info": "A placeholder input for tool mode.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "tool_placeholder", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": true, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
} | |
}, | |
"tool_mode": false | |
}, | |
"type": "Prompt" | |
}, | |
"dragging": false, | |
"height": 685, | |
"id": "Prompt-VXWKj", | |
"position": { | |
"x": 2219.5265974825707, | |
"y": 521.6320563271215 | |
}, | |
"positionAbsolute": { | |
"x": 2219.5265974825707, | |
"y": 521.6320563271215 | |
}, | |
"selected": false, | |
"type": "genericNode", | |
"width": 320 | |
}, | |
{ | |
"data": { | |
"description": "Display a chat message in the Playground.", | |
"display_name": "Chat Output", | |
"id": "ChatOutput-ZCLW2", | |
"node": { | |
"base_classes": [ | |
"Message" | |
], | |
"beta": false, | |
"conditional_paths": [], | |
"custom_fields": {}, | |
"description": "Display a chat message in the Playground.", | |
"display_name": "Chat Output", | |
"documentation": "", | |
"edited": false, | |
"field_order": [ | |
"input_value", | |
"should_store_message", | |
"sender", | |
"sender_name", | |
"session_id", | |
"data_template", | |
"background_color", | |
"chat_icon", | |
"text_color" | |
], | |
"frozen": false, | |
"icon": "MessagesSquare", | |
"legacy": false, | |
"metadata": {}, | |
"output_types": [], | |
"outputs": [ | |
{ | |
"cache": true, | |
"display_name": "Message", | |
"method": "message_response", | |
"name": "message", | |
"selected": "Message", | |
"types": [ | |
"Message" | |
], | |
"value": "__UNDEFINED__" | |
} | |
], | |
"pinned": false, | |
"template": { | |
"_type": "Component", | |
"background_color": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Background Color", | |
"dynamic": false, | |
"info": "The background color of the icon.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "background_color", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
}, | |
"chat_icon": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Icon", | |
"dynamic": false, | |
"info": "The icon of the message.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "chat_icon", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
}, | |
"code": { | |
"advanced": true, | |
"dynamic": true, | |
"fileTypes": [], | |
"file_path": "", | |
"info": "", | |
"list": false, | |
"load_from_db": false, | |
"multiline": true, | |
"name": "code", | |
"password": false, | |
"placeholder": "", | |
"required": true, | |
"show": true, | |
"title_case": false, | |
"type": "code", | |
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput\nfrom langflow.io import DropdownInput, MessageInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\nfrom langflow.schema.properties import Source\nfrom langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_NAME_AI, MESSAGE_SENDER_USER\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"MessagesSquare\"\n name = \"ChatOutput\"\n\n inputs = [\n MessageInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n BoolInput(\n name=\"should_store_message\",\n display_name=\"Store Messages\",\n info=\"Store the message in the history.\",\n value=True,\n advanced=True,\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER],\n value=MESSAGE_SENDER_AI,\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=MESSAGE_SENDER_NAME_AI,\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"The session ID of the chat. If empty, the current session ID parameter will be used.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n MessageTextInput(\n name=\"background_color\",\n display_name=\"Background Color\",\n info=\"The background color of the icon.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"chat_icon\",\n display_name=\"Icon\",\n info=\"The icon of the message.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"text_color\",\n display_name=\"Text Color\",\n info=\"The text color of the name\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(\n display_name=\"Message\",\n name=\"message\",\n method=\"message_response\",\n ),\n ]\n\n def _build_source(self, id_: str | None, display_name: str | None, source: str | None) -> Source:\n source_dict = {}\n if id_:\n source_dict[\"id\"] = id_\n if display_name:\n source_dict[\"display_name\"] = display_name\n if source:\n source_dict[\"source\"] = source\n return Source(**source_dict)\n\n async def message_response(self) -> Message:\n source, icon, display_name, source_id = self.get_properties_from_source_component()\n background_color = self.background_color\n text_color = self.text_color\n if self.chat_icon:\n icon = self.chat_icon\n message = self.input_value if isinstance(self.input_value, Message) else Message(text=self.input_value)\n message.sender = self.sender\n message.sender_name = self.sender_name\n message.session_id = self.session_id\n message.flow_id = self.graph.flow_id if hasattr(self, \"graph\") else None\n message.properties.source = self._build_source(source_id, display_name, source)\n message.properties.icon = icon\n message.properties.background_color = background_color\n message.properties.text_color = text_color\n 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" | |
}, | |
"data_template": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Data Template", | |
"dynamic": false, | |
"info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "data_template", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "{text}" | |
}, | |
"input_value": { | |
"_input_type": "MessageInput", | |
"advanced": false, | |
"display_name": "Text", | |
"dynamic": false, | |
"info": "Message to be passed as output.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "input_value", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
}, | |
"sender": { | |
"_input_type": "DropdownInput", | |
"advanced": true, | |
"combobox": false, | |
"display_name": "Sender Type", | |
"dynamic": false, | |
"info": "Type of sender.", | |
"name": "sender", | |
"options": [ | |
"Machine", | |
"User" | |
], | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "Machine" | |
}, | |
"sender_name": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Sender Name", | |
"dynamic": false, | |
"info": "Name of the sender.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "sender_name", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "AI" | |
}, | |
"session_id": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Session ID", | |
"dynamic": false, | |
"info": "The session ID of the chat. If empty, the current session ID parameter will be used.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "session_id", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
}, | |
"should_store_message": { | |
"_input_type": "BoolInput", | |
"advanced": true, | |
"display_name": "Store Messages", | |
"dynamic": false, | |
"info": "Store the message in the history.", | |
"list": false, | |
"name": "should_store_message", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_metadata": true, | |
"type": "bool", | |
"value": true | |
}, | |
"text_color": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Text Color", | |
"dynamic": false, | |
"info": "The text color of the name", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "text_color", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
} | |
}, | |
"tool_mode": false | |
}, | |
"type": "ChatOutput" | |
}, | |
"dragging": false, | |
"height": 232, | |
"id": "ChatOutput-ZCLW2", | |
"position": { | |
"x": 2947.267779013826, | |
"y": 891.8123698756774 | |
}, | |
"positionAbsolute": { | |
"x": 2947.267779013826, | |
"y": 891.8123698756774 | |
}, | |
"selected": false, | |
"type": "genericNode", | |
"width": 320 | |
}, | |
{ | |
"data": { | |
"id": "note-lkK06", | |
"node": { | |
"description": "# Fetch Components code \n\nUsing the URL component we are extracting from Github, the code from a few classes to provide as example to the LLM. \n\nThis ensures we are always up to date with recent information from the codebase.", | |
"display_name": "", | |
"documentation": "", | |
"template": {} | |
}, | |
"type": "note" | |
}, | |
"dragging": false, | |
"height": 324, | |
"id": "note-lkK06", | |
"position": { | |
"x": 1430.2014058924922, | |
"y": -19.30392196909918 | |
}, | |
"positionAbsolute": { | |
"x": 1430.2014058924922, | |
"y": -19.30392196909918 | |
}, | |
"selected": false, | |
"type": "noteNode", | |
"width": 324 | |
}, | |
{ | |
"data": { | |
"id": "note-1foCQ", | |
"node": { | |
"description": "# 🛠️ Custom Component Generator 🚀\n\nHi! I'm here to help you create custom components for Langflow. Think of me as your technical partner who can help turn your ideas into working components! \n\n## 🎯 How to Work With Me\n\n### 1. 💭 Tell Me What You Want to Build\nSimply describe what you want your component to do in plain English. For example:\n- \"I need a component that sends Slack messages\"\n- \"I want to create a tool that can process CSV files\"\n- \"I need something that can translate text\"\n\n### 2. 📚 Share Any Relevant Information\nIf you're working with a specific:\n- 🔑 API or service (just share the documentation link or main endpoints)\n- 📄 File format\n- 🔄 Data structure\n- 🔧 Existing component you want to modify\n\n### 3. 🎨 Let Me Help Design It\nI'll help by:\n- 📊 Breaking down complex requirements into manageable pieces\n- 💡 Suggesting the best way to structure inputs and outputs\n- ⚙️ Creating the component code\n- 📝 Explaining how to use it\n\n### 4. 🔄 Iterative Refinement\nWe can then:\n- ✅ Test and refine the component\n- ⭐ Add features\n- 🔧 Modify behavior\n- 🛡️ Improve error handling\n- 📖 Add documentation\n\n## 🚀 What I Can Help With\n\nI can help create components that:\n- 📊 Process different file types (CSV, JSON, Excel, etc.)\n- 🔌 Integrate with external APIs\n- 🔄 Transform data\n- 🔀 Route messages\n- 🌐 Handle web requests\n- 🎯 Parse structured data\n- ✨ And much more!\n\n## 💡 Tips for Best Results\n\n1. **Be Specific** 🎯: The more details you provide about what you want to accomplish, the better I can help.\n\n2. **Share Examples** 📋: If you have example data or specific use cases, share them.\n\n3. **Ask Questions** ❓: Don't hesitate to ask for clarification or modifications.\n\nJust start by telling me what kind of component you'd like to create, and I'll guide you through the process! \n\nReady to build something awesome? 🚀 Let's get started!", | |
"display_name": "", | |
"documentation": "", | |
"template": {} | |
}, | |
"type": "note" | |
}, | |
"dragging": false, | |
"height": 573, | |
"id": "note-1foCQ", | |
"position": { | |
"x": 807.6293964045135, | |
"y": 605.6504562080672 | |
}, | |
"positionAbsolute": { | |
"x": 807.6293964045135, | |
"y": 605.6504562080672 | |
}, | |
"resizing": false, | |
"selected": false, | |
"style": { | |
"height": 573, | |
"width": 564 | |
}, | |
"type": "noteNode", | |
"width": 564 | |
}, | |
{ | |
"data": { | |
"id": "AnthropicModel-39lt2", | |
"node": { | |
"base_classes": [ | |
"LanguageModel", | |
"Message" | |
], | |
"beta": false, | |
"conditional_paths": [], | |
"custom_fields": {}, | |
"description": "Generate text using Anthropic Chat&Completion LLMs with prefill support.", | |
"display_name": "Anthropic", | |
"documentation": "", | |
"edited": false, | |
"field_order": [ | |
"input_value", | |
"system_message", | |
"stream", | |
"max_tokens", | |
"model", | |
"anthropic_api_key", | |
"temperature", | |
"anthropic_api_url", | |
"prefill", | |
"output_parser" | |
], | |
"frozen": false, | |
"icon": "Anthropic", | |
"legacy": false, | |
"lf_version": "1.0.19.post2", | |
"metadata": {}, | |
"output_types": [], | |
"outputs": [ | |
{ | |
"cache": true, | |
"display_name": "Text", | |
"method": "text_response", | |
"name": "text_output", | |
"required_inputs": [], | |
"selected": "Message", | |
"types": [ | |
"Message" | |
], | |
"value": "__UNDEFINED__" | |
}, | |
{ | |
"cache": true, | |
"display_name": "Language Model", | |
"method": "build_model", | |
"name": "model_output", | |
"required_inputs": [], | |
"selected": "LanguageModel", | |
"types": [ | |
"LanguageModel" | |
], | |
"value": "__UNDEFINED__" | |
} | |
], | |
"pinned": false, | |
"template": { | |
"_type": "Component", | |
"anthropic_api_key": { | |
"_input_type": "SecretStrInput", | |
"advanced": false, | |
"display_name": "Anthropic API Key", | |
"dynamic": false, | |
"info": "Your Anthropic API key.", | |
"input_types": [ | |
"Message" | |
], | |
"load_from_db": false, | |
"name": "anthropic_api_key", | |
"password": true, | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"type": "str", | |
"value": "" | |
}, | |
"anthropic_api_url": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Anthropic API URL", | |
"dynamic": false, | |
"info": "Endpoint of the Anthropic API. Defaults to 'https://api.anthropic.com' if not specified.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "anthropic_api_url", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
}, | |
"code": { | |
"advanced": true, | |
"dynamic": true, | |
"fileTypes": [], | |
"file_path": "", | |
"info": "", | |
"list": false, | |
"load_from_db": false, | |
"multiline": true, | |
"name": "code", | |
"password": false, | |
"placeholder": "", | |
"required": true, | |
"show": true, | |
"title_case": false, | |
"type": "code", | |
"value": "from pydantic.v1 import SecretStr\n\nfrom langflow.base.models.anthropic_constants import ANTHROPIC_MODELS\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.field_typing import LanguageModel\nfrom langflow.inputs.inputs import HandleInput\nfrom langflow.io import DropdownInput, FloatInput, IntInput, MessageTextInput, SecretStrInput\n\n\nclass AnthropicModelComponent(LCModelComponent):\n display_name = \"Anthropic\"\n description = \"Generate text using Anthropic Chat&Completion LLMs with prefill support.\"\n icon = \"Anthropic\"\n name = \"AnthropicModel\"\n\n inputs = [\n *LCModelComponent._base_inputs,\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n value=4096,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DropdownInput(\n name=\"model\",\n display_name=\"Model Name\",\n options=ANTHROPIC_MODELS,\n info=\"https://python.langchain.com/docs/integrations/chat/anthropic\",\n value=\"claude-3-5-sonnet-latest\",\n ),\n SecretStrInput(name=\"anthropic_api_key\", display_name=\"Anthropic API Key\", info=\"Your Anthropic API key.\"),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n MessageTextInput(\n name=\"anthropic_api_url\",\n display_name=\"Anthropic API URL\",\n advanced=True,\n info=\"Endpoint of the Anthropic API. Defaults to 'https://api.anthropic.com' if not specified.\",\n ),\n MessageTextInput(\n name=\"prefill\", display_name=\"Prefill\", info=\"Prefill text to guide the model's response.\", advanced=True\n ),\n HandleInput(\n name=\"output_parser\",\n display_name=\"Output Parser\",\n info=\"The parser to use to parse the output of the model\",\n advanced=True,\n input_types=[\"OutputParser\"],\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n try:\n from langchain_anthropic.chat_models import ChatAnthropic\n except ImportError as e:\n msg = \"langchain_anthropic is not installed. Please install it with `pip install langchain_anthropic`.\"\n raise ImportError(msg) from e\n model = self.model\n anthropic_api_key = self.anthropic_api_key\n max_tokens = self.max_tokens\n temperature = self.temperature\n anthropic_api_url = self.anthropic_api_url or \"https://api.anthropic.com\"\n\n try:\n output = ChatAnthropic(\n model=model,\n anthropic_api_key=(SecretStr(anthropic_api_key).get_secret_value() if anthropic_api_key else None),\n max_tokens_to_sample=max_tokens,\n temperature=temperature,\n anthropic_api_url=anthropic_api_url,\n streaming=self.stream,\n )\n except Exception as e:\n msg = \"Could not connect to Anthropic API.\"\n raise ValueError(msg) from e\n\n return output\n\n def _get_exception_message(self, exception: Exception) -> str | None:\n \"\"\"Get a message from an Anthropic exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n try:\n from anthropic import BadRequestError\n except ImportError:\n return None\n if isinstance(exception, BadRequestError):\n message = exception.body.get(\"error\", {}).get(\"message\")\n if message:\n return message\n return None\n" | |
}, | |
"input_value": { | |
"_input_type": "MessageInput", | |
"advanced": false, | |
"display_name": "Input", | |
"dynamic": false, | |
"info": "", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "input_value", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
}, | |
"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, | |
"name": "max_tokens", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_metadata": true, | |
"type": "int", | |
"value": 4096 | |
}, | |
"model": { | |
"_input_type": "DropdownInput", | |
"advanced": false, | |
"combobox": false, | |
"display_name": "Model Name", | |
"dynamic": false, | |
"info": "https://python.langchain.com/docs/integrations/chat/anthropic", | |
"name": "model", | |
"options": [ | |
"claude-3-5-sonnet-latest", | |
"claude-3-5-haiku-latest", | |
"claude-3-opus-latest", | |
"claude-3-5-sonnet-20240620", | |
"claude-3-5-sonnet-20241022", | |
"claude-3-5-haiku-20241022", | |
"claude-3-sonnet-20240229", | |
"claude-3-haiku-20240307" | |
], | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "claude-3-5-sonnet-20240620" | |
}, | |
"output_parser": { | |
"_input_type": "HandleInput", | |
"advanced": true, | |
"display_name": "Output Parser", | |
"dynamic": false, | |
"info": "The parser to use to parse the output of the model", | |
"input_types": [ | |
"OutputParser" | |
], | |
"list": false, | |
"name": "output_parser", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_metadata": true, | |
"type": "other", | |
"value": "" | |
}, | |
"prefill": { | |
"_input_type": "MessageTextInput", | |
"advanced": true, | |
"display_name": "Prefill", | |
"dynamic": false, | |
"info": "Prefill text to guide the model's response.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "prefill", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
}, | |
"stream": { | |
"_input_type": "BoolInput", | |
"advanced": false, | |
"display_name": "Stream", | |
"dynamic": false, | |
"info": "Stream the response from the model. Streaming works only in Chat.", | |
"list": false, | |
"name": "stream", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_metadata": true, | |
"type": "bool", | |
"value": false | |
}, | |
"system_message": { | |
"_input_type": "MessageTextInput", | |
"advanced": false, | |
"display_name": "System Message", | |
"dynamic": false, | |
"info": "System message to pass to the model.", | |
"input_types": [ | |
"Message" | |
], | |
"list": false, | |
"load_from_db": false, | |
"name": "system_message", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "" | |
}, | |
"temperature": { | |
"_input_type": "FloatInput", | |
"advanced": false, | |
"display_name": "Temperature", | |
"dynamic": false, | |
"info": "", | |
"list": false, | |
"name": "temperature", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"trace_as_metadata": true, | |
"type": "float", | |
"value": 0.1 | |
} | |
} | |
}, | |
"type": "AnthropicModel" | |
}, | |
"dragging": false, | |
"height": 687, | |
"id": "AnthropicModel-39lt2", | |
"position": { | |
"x": 2587.564685535714, | |
"y": 646.2448246136587 | |
}, | |
"positionAbsolute": { | |
"x": 2587.564685535714, | |
"y": 646.2448246136587 | |
}, | |
"selected": false, | |
"type": "genericNode", | |
"width": 320 | |
}, | |
{ | |
"data": { | |
"id": "URL-j0mBc", | |
"node": { | |
"base_classes": [ | |
"Data", | |
"Message" | |
], | |
"beta": false, | |
"conditional_paths": [], | |
"custom_fields": {}, | |
"description": "Fetch content from one or more URLs.", | |
"display_name": "URL", | |
"documentation": "", | |
"edited": false, | |
"field_order": [ | |
"urls", | |
"format" | |
], | |
"frozen": false, | |
"icon": "layout-template", | |
"legacy": false, | |
"lf_version": "1.0.19.post2", | |
"metadata": {}, | |
"output_types": [], | |
"outputs": [ | |
{ | |
"cache": true, | |
"display_name": "Data", | |
"method": "fetch_content", | |
"name": "data", | |
"selected": "Data", | |
"types": [ | |
"Data" | |
], | |
"value": "__UNDEFINED__" | |
}, | |
{ | |
"cache": true, | |
"display_name": "Text", | |
"method": "fetch_content_text", | |
"name": "text", | |
"selected": "Message", | |
"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 re\n\nfrom langchain_community.document_loaders import AsyncHtmlLoader, WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n name = \"URL\"\n\n inputs = [\n MessageTextInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, by clicking the '+' button.\",\n is_list=True,\n tool_mode=True,\n ),\n DropdownInput(\n name=\"format\",\n display_name=\"Output Format\",\n info=\"Output Format. Use 'Text' to extract the text from the HTML or 'Raw HTML' for the raw HTML content.\",\n options=[\"Text\", \"Raw HTML\"],\n value=\"Text\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n Output(display_name=\"Text\", name=\"text\", method=\"fetch_content_text\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(https?:\\/\\/)?\" # optional protocol\n r\"(www\\.)?\" # optional www\n r\"([a-zA-Z0-9.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,})?\" # top-level domain\n r\"(:\\d+)?\" # optional port\n r\"(\\/[^\\s]*)?$\", # optional path\n re.IGNORECASE,\n )\n\n if not url_regex.match(string):\n msg = f\"Invalid URL: {string}\"\n raise ValueError(msg)\n\n return string\n\n def fetch_content(self) -> list[Data]:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n if self.format == \"Raw HTML\":\n loader = AsyncHtmlLoader(web_path=urls, encoding=\"utf-8\")\n else:\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(text=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n\n def fetch_content_text(self) -> Message:\n data = self.fetch_content()\n\n result_string = data_to_text(\"{text}\", data)\n self.status = result_string\n return Message(text=result_string)\n" | |
}, | |
"format": { | |
"_input_type": "DropdownInput", | |
"advanced": false, | |
"combobox": false, | |
"display_name": "Output Format", | |
"dynamic": false, | |
"info": "Output Format. Use 'Text' to extract the text from the HTML or 'Raw HTML' for the raw HTML content.", | |
"name": "format", | |
"options": [ | |
"Text", | |
"Raw HTML" | |
], | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "Text" | |
}, | |
"urls": { | |
"_input_type": "MessageTextInput", | |
"advanced": false, | |
"display_name": "URLs", | |
"dynamic": false, | |
"info": "Enter one or more URLs, by clicking the '+' button.", | |
"input_types": [ | |
"Message" | |
], | |
"list": true, | |
"load_from_db": false, | |
"name": "urls", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": true, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": [ | |
"https://raw.githubusercontent.com/langflow-ai/langflow/refs/heads/main/src/backend/base/langflow/custom/custom_component/component.py" | |
] | |
} | |
}, | |
"tool_mode": false | |
}, | |
"type": "URL" | |
}, | |
"dragging": false, | |
"height": 365, | |
"id": "URL-j0mBc", | |
"position": { | |
"x": 1436.3617127766433, | |
"y": 264.218898085405 | |
}, | |
"positionAbsolute": { | |
"x": 1436.3617127766433, | |
"y": 264.218898085405 | |
}, | |
"selected": false, | |
"type": "genericNode", | |
"width": 320 | |
}, | |
{ | |
"data": { | |
"id": "URL-ynvHI", | |
"node": { | |
"base_classes": [ | |
"Data", | |
"Message" | |
], | |
"beta": false, | |
"conditional_paths": [], | |
"custom_fields": {}, | |
"description": "Fetch content from one or more URLs.", | |
"display_name": "URL", | |
"documentation": "", | |
"edited": false, | |
"field_order": [ | |
"urls", | |
"format" | |
], | |
"frozen": false, | |
"icon": "layout-template", | |
"legacy": false, | |
"lf_version": "1.0.19.post2", | |
"metadata": {}, | |
"output_types": [], | |
"outputs": [ | |
{ | |
"cache": true, | |
"display_name": "Data", | |
"method": "fetch_content", | |
"name": "data", | |
"selected": "Data", | |
"types": [ | |
"Data" | |
], | |
"value": "__UNDEFINED__" | |
}, | |
{ | |
"cache": true, | |
"display_name": "Text", | |
"method": "fetch_content_text", | |
"name": "text", | |
"selected": "Message", | |
"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 re\n\nfrom langchain_community.document_loaders import AsyncHtmlLoader, WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n name = \"URL\"\n\n inputs = [\n MessageTextInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, by clicking the '+' button.\",\n is_list=True,\n tool_mode=True,\n ),\n DropdownInput(\n name=\"format\",\n display_name=\"Output Format\",\n info=\"Output Format. Use 'Text' to extract the text from the HTML or 'Raw HTML' for the raw HTML content.\",\n options=[\"Text\", \"Raw HTML\"],\n value=\"Text\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n Output(display_name=\"Text\", name=\"text\", method=\"fetch_content_text\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(https?:\\/\\/)?\" # optional protocol\n r\"(www\\.)?\" # optional www\n r\"([a-zA-Z0-9.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,})?\" # top-level domain\n r\"(:\\d+)?\" # optional port\n r\"(\\/[^\\s]*)?$\", # optional path\n re.IGNORECASE,\n )\n\n if not url_regex.match(string):\n msg = f\"Invalid URL: {string}\"\n raise ValueError(msg)\n\n return string\n\n def fetch_content(self) -> list[Data]:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n if self.format == \"Raw HTML\":\n loader = AsyncHtmlLoader(web_path=urls, encoding=\"utf-8\")\n else:\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(text=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n\n def fetch_content_text(self) -> Message:\n data = self.fetch_content()\n\n result_string = data_to_text(\"{text}\", data)\n self.status = result_string\n return Message(text=result_string)\n" | |
}, | |
"format": { | |
"_input_type": "DropdownInput", | |
"advanced": false, | |
"combobox": false, | |
"display_name": "Output Format", | |
"dynamic": false, | |
"info": "Output Format. Use 'Text' to extract the text from the HTML or 'Raw HTML' for the raw HTML content.", | |
"name": "format", | |
"options": [ | |
"Text", | |
"Raw HTML" | |
], | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "Text" | |
}, | |
"urls": { | |
"_input_type": "MessageTextInput", | |
"advanced": false, | |
"display_name": "URLs", | |
"dynamic": false, | |
"info": "Enter one or more URLs, by clicking the '+' button.", | |
"input_types": [ | |
"Message" | |
], | |
"list": true, | |
"load_from_db": false, | |
"name": "urls", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": true, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": [ | |
"https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/components/agents/agent.py", | |
"https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/components/helpers/structured_output.py", | |
"https://raw.githubusercontent.com/langflow-ai/langflow/refs/heads/main/src/backend/base/langflow/components/tools/calculator.py", | |
"https://raw.githubusercontent.com/langflow-ai/langflow/refs/heads/main/src/backend/base/langflow/components/tools/tavily_search.py", | |
"https://raw.githubusercontent.com/langflow-ai/langflow/refs/heads/main/src/backend/base/langflow/components/models/ollama.py", | |
"https://raw.githubusercontent.com/langflow-ai/langflow/refs/heads/main/src/backend/base/langflow/components/logic/conditional_router.py", | |
"https://raw.githubusercontent.com/langflow-ai/langflow/refs/heads/main/src/backend/base/langflow/components/data/file.py" | |
] | |
} | |
}, | |
"tool_mode": false | |
}, | |
"type": "URL" | |
}, | |
"dragging": false, | |
"height": 661, | |
"id": "URL-ynvHI", | |
"position": { | |
"x": 1831.5895760156684, | |
"y": 245.62940316018893 | |
}, | |
"positionAbsolute": { | |
"x": 1831.5895760156684, | |
"y": 245.62940316018893 | |
}, | |
"selected": false, | |
"type": "genericNode", | |
"width": 320 | |
}, | |
{ | |
"data": { | |
"id": "URL-xqtKG", | |
"node": { | |
"base_classes": [ | |
"Data", | |
"Message" | |
], | |
"beta": false, | |
"conditional_paths": [], | |
"custom_fields": {}, | |
"description": "Fetch content from one or more URLs.", | |
"display_name": "URL", | |
"documentation": "", | |
"edited": false, | |
"field_order": [ | |
"urls", | |
"format" | |
], | |
"frozen": false, | |
"icon": "layout-template", | |
"legacy": false, | |
"lf_version": "1.0.19.post2", | |
"metadata": {}, | |
"output_types": [], | |
"outputs": [ | |
{ | |
"cache": true, | |
"display_name": "Data", | |
"method": "fetch_content", | |
"name": "data", | |
"selected": "Data", | |
"types": [ | |
"Data" | |
], | |
"value": "__UNDEFINED__" | |
}, | |
{ | |
"cache": true, | |
"display_name": "Text", | |
"method": "fetch_content_text", | |
"name": "text", | |
"selected": "Message", | |
"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 re\n\nfrom langchain_community.document_loaders import AsyncHtmlLoader, WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n name = \"URL\"\n\n inputs = [\n MessageTextInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, by clicking the '+' button.\",\n is_list=True,\n tool_mode=True,\n ),\n DropdownInput(\n name=\"format\",\n display_name=\"Output Format\",\n info=\"Output Format. Use 'Text' to extract the text from the HTML or 'Raw HTML' for the raw HTML content.\",\n options=[\"Text\", \"Raw HTML\"],\n value=\"Text\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n Output(display_name=\"Text\", name=\"text\", method=\"fetch_content_text\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(https?:\\/\\/)?\" # optional protocol\n r\"(www\\.)?\" # optional www\n r\"([a-zA-Z0-9.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,})?\" # top-level domain\n r\"(:\\d+)?\" # optional port\n r\"(\\/[^\\s]*)?$\", # optional path\n re.IGNORECASE,\n )\n\n if not url_regex.match(string):\n msg = f\"Invalid URL: {string}\"\n raise ValueError(msg)\n\n return string\n\n def fetch_content(self) -> list[Data]:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n if self.format == \"Raw HTML\":\n loader = AsyncHtmlLoader(web_path=urls, encoding=\"utf-8\")\n else:\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(text=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n\n def fetch_content_text(self) -> Message:\n data = self.fetch_content()\n\n result_string = data_to_text(\"{text}\", data)\n self.status = result_string\n return Message(text=result_string)\n" | |
}, | |
"format": { | |
"_input_type": "DropdownInput", | |
"advanced": false, | |
"combobox": false, | |
"display_name": "Output Format", | |
"dynamic": false, | |
"info": "Output Format. Use 'Text' to extract the text from the HTML or 'Raw HTML' for the raw HTML content.", | |
"name": "format", | |
"options": [ | |
"Text", | |
"Raw HTML" | |
], | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": false, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": "Text" | |
}, | |
"urls": { | |
"_input_type": "MessageTextInput", | |
"advanced": false, | |
"display_name": "URLs", | |
"dynamic": false, | |
"info": "Enter one or more URLs, by clicking the '+' button.", | |
"input_types": [ | |
"Message" | |
], | |
"list": true, | |
"load_from_db": false, | |
"name": "urls", | |
"placeholder": "", | |
"required": false, | |
"show": true, | |
"title_case": false, | |
"tool_mode": true, | |
"trace_as_input": true, | |
"trace_as_metadata": true, | |
"type": "str", | |
"value": [ | |
"https://raw.githubusercontent.com/langflow-ai/langflow/refs/heads/main/src/backend/base/langflow/components/custom_component/custom_component.py" | |
] | |
} | |
}, | |
"tool_mode": false | |
}, | |
"type": "URL" | |
}, | |
"dragging": false, | |
"height": 365, | |
"id": "URL-xqtKG", | |
"position": { | |
"x": 1436.982480021523, | |
"y": 651.1409296825055 | |
}, | |
"positionAbsolute": { | |
"x": 1436.982480021523, | |
"y": 651.1409296825055 | |
}, | |
"selected": false, | |
"type": "genericNode", | |
"width": 320 | |
} | |
], | |
"viewport": { | |
"x": -1123.4732050518141, | |
"y": -154.4525805182622, | |
"zoom": 0.8590630148881792 | |
} | |
}, | |
"description": "starterProjects.customComponent.description", | |
"endpoint_name": null, | |
"gradient": "1", | |
"icon": "SquareCode", | |
"id": "5155918c-68b1-4013-8d7b-61f31ffa931c", | |
"is_component": false, | |
"last_tested_version": "1.1.0", | |
"name": "starterProjects.customComponent.name", | |
"tags": [ | |
"coding", | |
"web-scraping" | |
] | |
} |