lfx-nightly 0.1.11.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lfx/__init__.py +0 -0
- lfx/__main__.py +25 -0
- lfx/base/__init__.py +0 -0
- lfx/base/agents/__init__.py +0 -0
- lfx/base/agents/agent.py +268 -0
- lfx/base/agents/callback.py +130 -0
- lfx/base/agents/context.py +109 -0
- lfx/base/agents/crewai/__init__.py +0 -0
- lfx/base/agents/crewai/crew.py +231 -0
- lfx/base/agents/crewai/tasks.py +12 -0
- lfx/base/agents/default_prompts.py +23 -0
- lfx/base/agents/errors.py +15 -0
- lfx/base/agents/events.py +346 -0
- lfx/base/agents/utils.py +205 -0
- lfx/base/astra_assistants/__init__.py +0 -0
- lfx/base/astra_assistants/util.py +171 -0
- lfx/base/chains/__init__.py +0 -0
- lfx/base/chains/model.py +19 -0
- lfx/base/composio/__init__.py +0 -0
- lfx/base/composio/composio_base.py +1291 -0
- lfx/base/compressors/__init__.py +0 -0
- lfx/base/compressors/model.py +60 -0
- lfx/base/constants.py +46 -0
- lfx/base/curl/__init__.py +0 -0
- lfx/base/curl/parse.py +188 -0
- lfx/base/data/__init__.py +5 -0
- lfx/base/data/base_file.py +685 -0
- lfx/base/data/docling_utils.py +245 -0
- lfx/base/data/utils.py +198 -0
- lfx/base/document_transformers/__init__.py +0 -0
- lfx/base/document_transformers/model.py +43 -0
- lfx/base/embeddings/__init__.py +0 -0
- lfx/base/embeddings/aiml_embeddings.py +62 -0
- lfx/base/embeddings/model.py +26 -0
- lfx/base/flow_processing/__init__.py +0 -0
- lfx/base/flow_processing/utils.py +86 -0
- lfx/base/huggingface/__init__.py +0 -0
- lfx/base/huggingface/model_bridge.py +133 -0
- lfx/base/io/__init__.py +0 -0
- lfx/base/io/chat.py +20 -0
- lfx/base/io/text.py +22 -0
- lfx/base/langchain_utilities/__init__.py +0 -0
- lfx/base/langchain_utilities/model.py +35 -0
- lfx/base/langchain_utilities/spider_constants.py +1 -0
- lfx/base/langwatch/__init__.py +0 -0
- lfx/base/langwatch/utils.py +18 -0
- lfx/base/mcp/__init__.py +0 -0
- lfx/base/mcp/constants.py +2 -0
- lfx/base/mcp/util.py +1398 -0
- lfx/base/memory/__init__.py +0 -0
- lfx/base/memory/memory.py +49 -0
- lfx/base/memory/model.py +38 -0
- lfx/base/models/__init__.py +3 -0
- lfx/base/models/aiml_constants.py +51 -0
- lfx/base/models/anthropic_constants.py +47 -0
- lfx/base/models/aws_constants.py +151 -0
- lfx/base/models/chat_result.py +76 -0
- lfx/base/models/google_generative_ai_constants.py +70 -0
- lfx/base/models/groq_constants.py +134 -0
- lfx/base/models/model.py +375 -0
- lfx/base/models/model_input_constants.py +307 -0
- lfx/base/models/model_metadata.py +41 -0
- lfx/base/models/model_utils.py +8 -0
- lfx/base/models/novita_constants.py +35 -0
- lfx/base/models/ollama_constants.py +49 -0
- lfx/base/models/openai_constants.py +122 -0
- lfx/base/models/sambanova_constants.py +18 -0
- lfx/base/processing/__init__.py +0 -0
- lfx/base/prompts/__init__.py +0 -0
- lfx/base/prompts/api_utils.py +224 -0
- lfx/base/prompts/utils.py +61 -0
- lfx/base/textsplitters/__init__.py +0 -0
- lfx/base/textsplitters/model.py +28 -0
- lfx/base/tools/__init__.py +0 -0
- lfx/base/tools/base.py +26 -0
- lfx/base/tools/component_tool.py +325 -0
- lfx/base/tools/constants.py +49 -0
- lfx/base/tools/flow_tool.py +132 -0
- lfx/base/tools/run_flow.py +224 -0
- lfx/base/vectorstores/__init__.py +0 -0
- lfx/base/vectorstores/model.py +193 -0
- lfx/base/vectorstores/utils.py +22 -0
- lfx/base/vectorstores/vector_store_connection_decorator.py +52 -0
- lfx/cli/__init__.py +5 -0
- lfx/cli/commands.py +319 -0
- lfx/cli/common.py +650 -0
- lfx/cli/run.py +441 -0
- lfx/cli/script_loader.py +247 -0
- lfx/cli/serve_app.py +546 -0
- lfx/cli/validation.py +69 -0
- lfx/components/FAISS/__init__.py +34 -0
- lfx/components/FAISS/faiss.py +111 -0
- lfx/components/Notion/__init__.py +19 -0
- lfx/components/Notion/add_content_to_page.py +269 -0
- lfx/components/Notion/create_page.py +94 -0
- lfx/components/Notion/list_database_properties.py +68 -0
- lfx/components/Notion/list_pages.py +122 -0
- lfx/components/Notion/list_users.py +77 -0
- lfx/components/Notion/page_content_viewer.py +93 -0
- lfx/components/Notion/search.py +111 -0
- lfx/components/Notion/update_page_property.py +114 -0
- lfx/components/__init__.py +411 -0
- lfx/components/_importing.py +42 -0
- lfx/components/agentql/__init__.py +3 -0
- lfx/components/agentql/agentql_api.py +151 -0
- lfx/components/agents/__init__.py +34 -0
- lfx/components/agents/agent.py +558 -0
- lfx/components/agents/mcp_component.py +501 -0
- lfx/components/aiml/__init__.py +37 -0
- lfx/components/aiml/aiml.py +112 -0
- lfx/components/aiml/aiml_embeddings.py +37 -0
- lfx/components/amazon/__init__.py +36 -0
- lfx/components/amazon/amazon_bedrock_embedding.py +109 -0
- lfx/components/amazon/amazon_bedrock_model.py +124 -0
- lfx/components/amazon/s3_bucket_uploader.py +211 -0
- lfx/components/anthropic/__init__.py +34 -0
- lfx/components/anthropic/anthropic.py +187 -0
- lfx/components/apify/__init__.py +5 -0
- lfx/components/apify/apify_actor.py +325 -0
- lfx/components/arxiv/__init__.py +3 -0
- lfx/components/arxiv/arxiv.py +163 -0
- lfx/components/assemblyai/__init__.py +46 -0
- lfx/components/assemblyai/assemblyai_get_subtitles.py +83 -0
- lfx/components/assemblyai/assemblyai_lemur.py +183 -0
- lfx/components/assemblyai/assemblyai_list_transcripts.py +95 -0
- lfx/components/assemblyai/assemblyai_poll_transcript.py +72 -0
- lfx/components/assemblyai/assemblyai_start_transcript.py +188 -0
- lfx/components/azure/__init__.py +37 -0
- lfx/components/azure/azure_openai.py +95 -0
- lfx/components/azure/azure_openai_embeddings.py +83 -0
- lfx/components/baidu/__init__.py +32 -0
- lfx/components/baidu/baidu_qianfan_chat.py +113 -0
- lfx/components/bing/__init__.py +3 -0
- lfx/components/bing/bing_search_api.py +61 -0
- lfx/components/cassandra/__init__.py +40 -0
- lfx/components/cassandra/cassandra.py +264 -0
- lfx/components/cassandra/cassandra_chat.py +92 -0
- lfx/components/cassandra/cassandra_graph.py +238 -0
- lfx/components/chains/__init__.py +3 -0
- lfx/components/chroma/__init__.py +34 -0
- lfx/components/chroma/chroma.py +167 -0
- lfx/components/cleanlab/__init__.py +40 -0
- lfx/components/cleanlab/cleanlab_evaluator.py +155 -0
- lfx/components/cleanlab/cleanlab_rag_evaluator.py +254 -0
- lfx/components/cleanlab/cleanlab_remediator.py +131 -0
- lfx/components/clickhouse/__init__.py +34 -0
- lfx/components/clickhouse/clickhouse.py +135 -0
- lfx/components/cloudflare/__init__.py +32 -0
- lfx/components/cloudflare/cloudflare.py +81 -0
- lfx/components/cohere/__init__.py +40 -0
- lfx/components/cohere/cohere_embeddings.py +81 -0
- lfx/components/cohere/cohere_models.py +46 -0
- lfx/components/cohere/cohere_rerank.py +51 -0
- lfx/components/composio/__init__.py +74 -0
- lfx/components/composio/composio_api.py +268 -0
- lfx/components/composio/dropbox_compnent.py +11 -0
- lfx/components/composio/github_composio.py +11 -0
- lfx/components/composio/gmail_composio.py +38 -0
- lfx/components/composio/googlecalendar_composio.py +11 -0
- lfx/components/composio/googlemeet_composio.py +11 -0
- lfx/components/composio/googletasks_composio.py +8 -0
- lfx/components/composio/linear_composio.py +11 -0
- lfx/components/composio/outlook_composio.py +11 -0
- lfx/components/composio/reddit_composio.py +11 -0
- lfx/components/composio/slack_composio.py +582 -0
- lfx/components/composio/slackbot_composio.py +11 -0
- lfx/components/composio/supabase_composio.py +11 -0
- lfx/components/composio/todoist_composio.py +11 -0
- lfx/components/composio/youtube_composio.py +11 -0
- lfx/components/confluence/__init__.py +3 -0
- lfx/components/confluence/confluence.py +84 -0
- lfx/components/couchbase/__init__.py +34 -0
- lfx/components/couchbase/couchbase.py +102 -0
- lfx/components/crewai/__init__.py +49 -0
- lfx/components/crewai/crewai.py +107 -0
- lfx/components/crewai/hierarchical_crew.py +46 -0
- lfx/components/crewai/hierarchical_task.py +44 -0
- lfx/components/crewai/sequential_crew.py +52 -0
- lfx/components/crewai/sequential_task.py +73 -0
- lfx/components/crewai/sequential_task_agent.py +143 -0
- lfx/components/custom_component/__init__.py +34 -0
- lfx/components/custom_component/custom_component.py +31 -0
- lfx/components/data/__init__.py +64 -0
- lfx/components/data/api_request.py +544 -0
- lfx/components/data/csv_to_data.py +95 -0
- lfx/components/data/directory.py +113 -0
- lfx/components/data/file.py +577 -0
- lfx/components/data/json_to_data.py +98 -0
- lfx/components/data/news_search.py +164 -0
- lfx/components/data/rss.py +69 -0
- lfx/components/data/sql_executor.py +101 -0
- lfx/components/data/url.py +311 -0
- lfx/components/data/web_search.py +112 -0
- lfx/components/data/webhook.py +56 -0
- lfx/components/datastax/__init__.py +70 -0
- lfx/components/datastax/astra_assistant_manager.py +306 -0
- lfx/components/datastax/astra_db.py +75 -0
- lfx/components/datastax/astra_vectorize.py +124 -0
- lfx/components/datastax/astradb.py +1285 -0
- lfx/components/datastax/astradb_cql.py +314 -0
- lfx/components/datastax/astradb_graph.py +330 -0
- lfx/components/datastax/astradb_tool.py +414 -0
- lfx/components/datastax/astradb_vectorstore.py +1285 -0
- lfx/components/datastax/cassandra.py +92 -0
- lfx/components/datastax/create_assistant.py +58 -0
- lfx/components/datastax/create_thread.py +32 -0
- lfx/components/datastax/dotenv.py +35 -0
- lfx/components/datastax/get_assistant.py +37 -0
- lfx/components/datastax/getenvvar.py +30 -0
- lfx/components/datastax/graph_rag.py +141 -0
- lfx/components/datastax/hcd.py +314 -0
- lfx/components/datastax/list_assistants.py +25 -0
- lfx/components/datastax/run.py +89 -0
- lfx/components/deactivated/__init__.py +15 -0
- lfx/components/deactivated/amazon_kendra.py +66 -0
- lfx/components/deactivated/chat_litellm_model.py +158 -0
- lfx/components/deactivated/code_block_extractor.py +26 -0
- lfx/components/deactivated/documents_to_data.py +22 -0
- lfx/components/deactivated/embed.py +16 -0
- lfx/components/deactivated/extract_key_from_data.py +46 -0
- lfx/components/deactivated/json_document_builder.py +57 -0
- lfx/components/deactivated/list_flows.py +20 -0
- lfx/components/deactivated/mcp_sse.py +61 -0
- lfx/components/deactivated/mcp_stdio.py +62 -0
- lfx/components/deactivated/merge_data.py +93 -0
- lfx/components/deactivated/message.py +37 -0
- lfx/components/deactivated/metal.py +54 -0
- lfx/components/deactivated/multi_query.py +59 -0
- lfx/components/deactivated/retriever.py +43 -0
- lfx/components/deactivated/selective_passthrough.py +77 -0
- lfx/components/deactivated/should_run_next.py +40 -0
- lfx/components/deactivated/split_text.py +63 -0
- lfx/components/deactivated/store_message.py +24 -0
- lfx/components/deactivated/sub_flow.py +124 -0
- lfx/components/deactivated/vectara_self_query.py +76 -0
- lfx/components/deactivated/vector_store.py +24 -0
- lfx/components/deepseek/__init__.py +34 -0
- lfx/components/deepseek/deepseek.py +136 -0
- lfx/components/docling/__init__.py +43 -0
- lfx/components/docling/chunk_docling_document.py +186 -0
- lfx/components/docling/docling_inline.py +231 -0
- lfx/components/docling/docling_remote.py +193 -0
- lfx/components/docling/export_docling_document.py +117 -0
- lfx/components/documentloaders/__init__.py +3 -0
- lfx/components/duckduckgo/__init__.py +3 -0
- lfx/components/duckduckgo/duck_duck_go_search_run.py +92 -0
- lfx/components/elastic/__init__.py +37 -0
- lfx/components/elastic/elasticsearch.py +267 -0
- lfx/components/elastic/opensearch.py +243 -0
- lfx/components/embeddings/__init__.py +37 -0
- lfx/components/embeddings/similarity.py +76 -0
- lfx/components/embeddings/text_embedder.py +64 -0
- lfx/components/exa/__init__.py +3 -0
- lfx/components/exa/exa_search.py +68 -0
- lfx/components/firecrawl/__init__.py +43 -0
- lfx/components/firecrawl/firecrawl_crawl_api.py +88 -0
- lfx/components/firecrawl/firecrawl_extract_api.py +136 -0
- lfx/components/firecrawl/firecrawl_map_api.py +89 -0
- lfx/components/firecrawl/firecrawl_scrape_api.py +73 -0
- lfx/components/git/__init__.py +4 -0
- lfx/components/git/git.py +262 -0
- lfx/components/git/gitextractor.py +196 -0
- lfx/components/glean/__init__.py +3 -0
- lfx/components/glean/glean_search_api.py +173 -0
- lfx/components/google/__init__.py +17 -0
- lfx/components/google/gmail.py +192 -0
- lfx/components/google/google_bq_sql_executor.py +157 -0
- lfx/components/google/google_drive.py +92 -0
- lfx/components/google/google_drive_search.py +152 -0
- lfx/components/google/google_generative_ai.py +147 -0
- lfx/components/google/google_generative_ai_embeddings.py +141 -0
- lfx/components/google/google_oauth_token.py +89 -0
- lfx/components/google/google_search_api_core.py +68 -0
- lfx/components/google/google_serper_api_core.py +74 -0
- lfx/components/groq/__init__.py +34 -0
- lfx/components/groq/groq.py +136 -0
- lfx/components/helpers/__init__.py +52 -0
- lfx/components/helpers/calculator_core.py +89 -0
- lfx/components/helpers/create_list.py +40 -0
- lfx/components/helpers/current_date.py +42 -0
- lfx/components/helpers/id_generator.py +42 -0
- lfx/components/helpers/memory.py +251 -0
- lfx/components/helpers/output_parser.py +45 -0
- lfx/components/helpers/store_message.py +90 -0
- lfx/components/homeassistant/__init__.py +7 -0
- lfx/components/homeassistant/home_assistant_control.py +152 -0
- lfx/components/homeassistant/list_home_assistant_states.py +137 -0
- lfx/components/huggingface/__init__.py +37 -0
- lfx/components/huggingface/huggingface.py +197 -0
- lfx/components/huggingface/huggingface_inference_api.py +106 -0
- lfx/components/ibm/__init__.py +34 -0
- lfx/components/ibm/watsonx.py +203 -0
- lfx/components/ibm/watsonx_embeddings.py +135 -0
- lfx/components/icosacomputing/__init__.py +5 -0
- lfx/components/icosacomputing/combinatorial_reasoner.py +84 -0
- lfx/components/input_output/__init__.py +38 -0
- lfx/components/input_output/chat.py +120 -0
- lfx/components/input_output/chat_output.py +200 -0
- lfx/components/input_output/text.py +27 -0
- lfx/components/input_output/text_output.py +29 -0
- lfx/components/jigsawstack/__init__.py +23 -0
- lfx/components/jigsawstack/ai_scrape.py +126 -0
- lfx/components/jigsawstack/ai_web_search.py +136 -0
- lfx/components/jigsawstack/file_read.py +115 -0
- lfx/components/jigsawstack/file_upload.py +94 -0
- lfx/components/jigsawstack/image_generation.py +205 -0
- lfx/components/jigsawstack/nsfw.py +60 -0
- lfx/components/jigsawstack/object_detection.py +124 -0
- lfx/components/jigsawstack/sentiment.py +112 -0
- lfx/components/jigsawstack/text_to_sql.py +90 -0
- lfx/components/jigsawstack/text_translate.py +77 -0
- lfx/components/jigsawstack/vocr.py +107 -0
- lfx/components/langchain_utilities/__init__.py +109 -0
- lfx/components/langchain_utilities/character.py +53 -0
- lfx/components/langchain_utilities/conversation.py +59 -0
- lfx/components/langchain_utilities/csv_agent.py +107 -0
- lfx/components/langchain_utilities/fake_embeddings.py +26 -0
- lfx/components/langchain_utilities/html_link_extractor.py +35 -0
- lfx/components/langchain_utilities/json_agent.py +45 -0
- lfx/components/langchain_utilities/langchain_hub.py +126 -0
- lfx/components/langchain_utilities/language_recursive.py +49 -0
- lfx/components/langchain_utilities/language_semantic.py +138 -0
- lfx/components/langchain_utilities/llm_checker.py +39 -0
- lfx/components/langchain_utilities/llm_math.py +42 -0
- lfx/components/langchain_utilities/natural_language.py +61 -0
- lfx/components/langchain_utilities/openai_tools.py +53 -0
- lfx/components/langchain_utilities/openapi.py +48 -0
- lfx/components/langchain_utilities/recursive_character.py +60 -0
- lfx/components/langchain_utilities/retrieval_qa.py +83 -0
- lfx/components/langchain_utilities/runnable_executor.py +137 -0
- lfx/components/langchain_utilities/self_query.py +80 -0
- lfx/components/langchain_utilities/spider.py +142 -0
- lfx/components/langchain_utilities/sql.py +40 -0
- lfx/components/langchain_utilities/sql_database.py +35 -0
- lfx/components/langchain_utilities/sql_generator.py +78 -0
- lfx/components/langchain_utilities/tool_calling.py +59 -0
- lfx/components/langchain_utilities/vector_store_info.py +49 -0
- lfx/components/langchain_utilities/vector_store_router.py +33 -0
- lfx/components/langchain_utilities/xml_agent.py +71 -0
- lfx/components/langwatch/__init__.py +3 -0
- lfx/components/langwatch/langwatch.py +278 -0
- lfx/components/link_extractors/__init__.py +3 -0
- lfx/components/lmstudio/__init__.py +34 -0
- lfx/components/lmstudio/lmstudioembeddings.py +89 -0
- lfx/components/lmstudio/lmstudiomodel.py +129 -0
- lfx/components/logic/__init__.py +52 -0
- lfx/components/logic/conditional_router.py +171 -0
- lfx/components/logic/data_conditional_router.py +125 -0
- lfx/components/logic/flow_tool.py +110 -0
- lfx/components/logic/listen.py +29 -0
- lfx/components/logic/loop.py +125 -0
- lfx/components/logic/notify.py +88 -0
- lfx/components/logic/pass_message.py +35 -0
- lfx/components/logic/run_flow.py +71 -0
- lfx/components/logic/sub_flow.py +114 -0
- lfx/components/maritalk/__init__.py +32 -0
- lfx/components/maritalk/maritalk.py +52 -0
- lfx/components/mem0/__init__.py +3 -0
- lfx/components/mem0/mem0_chat_memory.py +136 -0
- lfx/components/milvus/__init__.py +34 -0
- lfx/components/milvus/milvus.py +115 -0
- lfx/components/mistral/__init__.py +37 -0
- lfx/components/mistral/mistral.py +114 -0
- lfx/components/mistral/mistral_embeddings.py +58 -0
- lfx/components/models/__init__.py +34 -0
- lfx/components/models/embedding_model.py +114 -0
- lfx/components/models/language_model.py +144 -0
- lfx/components/mongodb/__init__.py +34 -0
- lfx/components/mongodb/mongodb_atlas.py +213 -0
- lfx/components/needle/__init__.py +3 -0
- lfx/components/needle/needle.py +104 -0
- lfx/components/notdiamond/__init__.py +34 -0
- lfx/components/notdiamond/notdiamond.py +228 -0
- lfx/components/novita/__init__.py +32 -0
- lfx/components/novita/novita.py +130 -0
- lfx/components/nvidia/__init__.py +57 -0
- lfx/components/nvidia/nvidia.py +157 -0
- lfx/components/nvidia/nvidia_embedding.py +77 -0
- lfx/components/nvidia/nvidia_ingest.py +317 -0
- lfx/components/nvidia/nvidia_rerank.py +63 -0
- lfx/components/nvidia/system_assist.py +65 -0
- lfx/components/olivya/__init__.py +3 -0
- lfx/components/olivya/olivya.py +116 -0
- lfx/components/ollama/__init__.py +37 -0
- lfx/components/ollama/ollama.py +330 -0
- lfx/components/ollama/ollama_embeddings.py +106 -0
- lfx/components/openai/__init__.py +37 -0
- lfx/components/openai/openai.py +100 -0
- lfx/components/openai/openai_chat_model.py +176 -0
- lfx/components/openrouter/__init__.py +32 -0
- lfx/components/openrouter/openrouter.py +202 -0
- lfx/components/output_parsers/__init__.py +3 -0
- lfx/components/perplexity/__init__.py +34 -0
- lfx/components/perplexity/perplexity.py +75 -0
- lfx/components/pgvector/__init__.py +34 -0
- lfx/components/pgvector/pgvector.py +72 -0
- lfx/components/pinecone/__init__.py +34 -0
- lfx/components/pinecone/pinecone.py +134 -0
- lfx/components/processing/__init__.py +117 -0
- lfx/components/processing/alter_metadata.py +108 -0
- lfx/components/processing/batch_run.py +205 -0
- lfx/components/processing/combine_text.py +39 -0
- lfx/components/processing/converter.py +159 -0
- lfx/components/processing/create_data.py +110 -0
- lfx/components/processing/data_operations.py +438 -0
- lfx/components/processing/data_to_dataframe.py +70 -0
- lfx/components/processing/dataframe_operations.py +313 -0
- lfx/components/processing/extract_key.py +53 -0
- lfx/components/processing/filter_data.py +42 -0
- lfx/components/processing/filter_data_values.py +88 -0
- lfx/components/processing/json_cleaner.py +103 -0
- lfx/components/processing/lambda_filter.py +154 -0
- lfx/components/processing/llm_router.py +499 -0
- lfx/components/processing/merge_data.py +90 -0
- lfx/components/processing/message_to_data.py +36 -0
- lfx/components/processing/parse_data.py +70 -0
- lfx/components/processing/parse_dataframe.py +68 -0
- lfx/components/processing/parse_json_data.py +90 -0
- lfx/components/processing/parser.py +143 -0
- lfx/components/processing/prompt.py +67 -0
- lfx/components/processing/python_repl_core.py +98 -0
- lfx/components/processing/regex.py +82 -0
- lfx/components/processing/save_file.py +225 -0
- lfx/components/processing/select_data.py +48 -0
- lfx/components/processing/split_text.py +141 -0
- lfx/components/processing/structured_output.py +202 -0
- lfx/components/processing/update_data.py +160 -0
- lfx/components/prototypes/__init__.py +34 -0
- lfx/components/prototypes/python_function.py +73 -0
- lfx/components/qdrant/__init__.py +34 -0
- lfx/components/qdrant/qdrant.py +109 -0
- lfx/components/redis/__init__.py +37 -0
- lfx/components/redis/redis.py +89 -0
- lfx/components/redis/redis_chat.py +43 -0
- lfx/components/sambanova/__init__.py +32 -0
- lfx/components/sambanova/sambanova.py +84 -0
- lfx/components/scrapegraph/__init__.py +40 -0
- lfx/components/scrapegraph/scrapegraph_markdownify_api.py +64 -0
- lfx/components/scrapegraph/scrapegraph_search_api.py +64 -0
- lfx/components/scrapegraph/scrapegraph_smart_scraper_api.py +71 -0
- lfx/components/searchapi/__init__.py +34 -0
- lfx/components/searchapi/search.py +79 -0
- lfx/components/serpapi/__init__.py +3 -0
- lfx/components/serpapi/serp.py +115 -0
- lfx/components/supabase/__init__.py +34 -0
- lfx/components/supabase/supabase.py +76 -0
- lfx/components/tavily/__init__.py +4 -0
- lfx/components/tavily/tavily_extract.py +117 -0
- lfx/components/tavily/tavily_search.py +212 -0
- lfx/components/textsplitters/__init__.py +3 -0
- lfx/components/toolkits/__init__.py +3 -0
- lfx/components/tools/__init__.py +72 -0
- lfx/components/tools/calculator.py +108 -0
- lfx/components/tools/google_search_api.py +45 -0
- lfx/components/tools/google_serper_api.py +115 -0
- lfx/components/tools/python_code_structured_tool.py +327 -0
- lfx/components/tools/python_repl.py +97 -0
- lfx/components/tools/search_api.py +87 -0
- lfx/components/tools/searxng.py +145 -0
- lfx/components/tools/serp_api.py +119 -0
- lfx/components/tools/tavily_search_tool.py +344 -0
- lfx/components/tools/wikidata_api.py +102 -0
- lfx/components/tools/wikipedia_api.py +49 -0
- lfx/components/tools/yahoo_finance.py +129 -0
- lfx/components/twelvelabs/__init__.py +52 -0
- lfx/components/twelvelabs/convert_astra_results.py +84 -0
- lfx/components/twelvelabs/pegasus_index.py +311 -0
- lfx/components/twelvelabs/split_video.py +291 -0
- lfx/components/twelvelabs/text_embeddings.py +57 -0
- lfx/components/twelvelabs/twelvelabs_pegasus.py +408 -0
- lfx/components/twelvelabs/video_embeddings.py +100 -0
- lfx/components/twelvelabs/video_file.py +179 -0
- lfx/components/unstructured/__init__.py +3 -0
- lfx/components/unstructured/unstructured.py +121 -0
- lfx/components/upstash/__init__.py +34 -0
- lfx/components/upstash/upstash.py +124 -0
- lfx/components/vectara/__init__.py +37 -0
- lfx/components/vectara/vectara.py +97 -0
- lfx/components/vectara/vectara_rag.py +164 -0
- lfx/components/vectorstores/__init__.py +40 -0
- lfx/components/vectorstores/astradb.py +1285 -0
- lfx/components/vectorstores/astradb_graph.py +319 -0
- lfx/components/vectorstores/cassandra.py +264 -0
- lfx/components/vectorstores/cassandra_graph.py +238 -0
- lfx/components/vectorstores/chroma.py +167 -0
- lfx/components/vectorstores/clickhouse.py +135 -0
- lfx/components/vectorstores/couchbase.py +102 -0
- lfx/components/vectorstores/elasticsearch.py +267 -0
- lfx/components/vectorstores/faiss.py +111 -0
- lfx/components/vectorstores/graph_rag.py +141 -0
- lfx/components/vectorstores/hcd.py +314 -0
- lfx/components/vectorstores/local_db.py +261 -0
- lfx/components/vectorstores/milvus.py +115 -0
- lfx/components/vectorstores/mongodb_atlas.py +213 -0
- lfx/components/vectorstores/opensearch.py +243 -0
- lfx/components/vectorstores/pgvector.py +72 -0
- lfx/components/vectorstores/pinecone.py +134 -0
- lfx/components/vectorstores/qdrant.py +109 -0
- lfx/components/vectorstores/supabase.py +76 -0
- lfx/components/vectorstores/upstash.py +124 -0
- lfx/components/vectorstores/vectara.py +97 -0
- lfx/components/vectorstores/vectara_rag.py +164 -0
- lfx/components/vectorstores/weaviate.py +89 -0
- lfx/components/vertexai/__init__.py +37 -0
- lfx/components/vertexai/vertexai.py +71 -0
- lfx/components/vertexai/vertexai_embeddings.py +67 -0
- lfx/components/weaviate/__init__.py +34 -0
- lfx/components/weaviate/weaviate.py +89 -0
- lfx/components/wikipedia/__init__.py +4 -0
- lfx/components/wikipedia/wikidata.py +86 -0
- lfx/components/wikipedia/wikipedia.py +53 -0
- lfx/components/wolframalpha/__init__.py +3 -0
- lfx/components/wolframalpha/wolfram_alpha_api.py +54 -0
- lfx/components/xai/__init__.py +32 -0
- lfx/components/xai/xai.py +167 -0
- lfx/components/yahoosearch/__init__.py +3 -0
- lfx/components/yahoosearch/yahoo.py +137 -0
- lfx/components/youtube/__init__.py +52 -0
- lfx/components/youtube/channel.py +227 -0
- lfx/components/youtube/comments.py +231 -0
- lfx/components/youtube/playlist.py +33 -0
- lfx/components/youtube/search.py +120 -0
- lfx/components/youtube/trending.py +285 -0
- lfx/components/youtube/video_details.py +263 -0
- lfx/components/youtube/youtube_transcripts.py +118 -0
- lfx/components/zep/__init__.py +3 -0
- lfx/components/zep/zep.py +44 -0
- lfx/constants.py +6 -0
- lfx/custom/__init__.py +7 -0
- lfx/custom/attributes.py +86 -0
- lfx/custom/code_parser/__init__.py +3 -0
- lfx/custom/code_parser/code_parser.py +361 -0
- lfx/custom/custom_component/__init__.py +0 -0
- lfx/custom/custom_component/base_component.py +128 -0
- lfx/custom/custom_component/component.py +1808 -0
- lfx/custom/custom_component/component_with_cache.py +8 -0
- lfx/custom/custom_component/custom_component.py +588 -0
- lfx/custom/dependency_analyzer.py +165 -0
- lfx/custom/directory_reader/__init__.py +3 -0
- lfx/custom/directory_reader/directory_reader.py +359 -0
- lfx/custom/directory_reader/utils.py +171 -0
- lfx/custom/eval.py +12 -0
- lfx/custom/schema.py +32 -0
- lfx/custom/tree_visitor.py +21 -0
- lfx/custom/utils.py +877 -0
- lfx/custom/validate.py +488 -0
- lfx/events/__init__.py +1 -0
- lfx/events/event_manager.py +110 -0
- lfx/exceptions/__init__.py +0 -0
- lfx/exceptions/component.py +15 -0
- lfx/field_typing/__init__.py +91 -0
- lfx/field_typing/constants.py +215 -0
- lfx/field_typing/range_spec.py +35 -0
- lfx/graph/__init__.py +6 -0
- lfx/graph/edge/__init__.py +0 -0
- lfx/graph/edge/base.py +277 -0
- lfx/graph/edge/schema.py +119 -0
- lfx/graph/edge/utils.py +0 -0
- lfx/graph/graph/__init__.py +0 -0
- lfx/graph/graph/ascii.py +202 -0
- lfx/graph/graph/base.py +2238 -0
- lfx/graph/graph/constants.py +63 -0
- lfx/graph/graph/runnable_vertices_manager.py +133 -0
- lfx/graph/graph/schema.py +52 -0
- lfx/graph/graph/state_model.py +66 -0
- lfx/graph/graph/utils.py +1024 -0
- lfx/graph/schema.py +75 -0
- lfx/graph/state/__init__.py +0 -0
- lfx/graph/state/model.py +237 -0
- lfx/graph/utils.py +200 -0
- lfx/graph/vertex/__init__.py +0 -0
- lfx/graph/vertex/base.py +823 -0
- lfx/graph/vertex/constants.py +0 -0
- lfx/graph/vertex/exceptions.py +4 -0
- lfx/graph/vertex/param_handler.py +264 -0
- lfx/graph/vertex/schema.py +26 -0
- lfx/graph/vertex/utils.py +19 -0
- lfx/graph/vertex/vertex_types.py +489 -0
- lfx/helpers/__init__.py +1 -0
- lfx/helpers/base_model.py +71 -0
- lfx/helpers/custom.py +13 -0
- lfx/helpers/data.py +167 -0
- lfx/helpers/flow.py +194 -0
- lfx/inputs/__init__.py +68 -0
- lfx/inputs/constants.py +2 -0
- lfx/inputs/input_mixin.py +328 -0
- lfx/inputs/inputs.py +714 -0
- lfx/inputs/validators.py +19 -0
- lfx/interface/__init__.py +6 -0
- lfx/interface/components.py +489 -0
- lfx/interface/importing/__init__.py +5 -0
- lfx/interface/importing/utils.py +39 -0
- lfx/interface/initialize/__init__.py +3 -0
- lfx/interface/initialize/loading.py +224 -0
- lfx/interface/listing.py +26 -0
- lfx/interface/run.py +16 -0
- lfx/interface/utils.py +111 -0
- lfx/io/__init__.py +63 -0
- lfx/io/schema.py +289 -0
- lfx/load/__init__.py +8 -0
- lfx/load/load.py +256 -0
- lfx/load/utils.py +99 -0
- lfx/log/__init__.py +5 -0
- lfx/log/logger.py +385 -0
- lfx/memory/__init__.py +90 -0
- lfx/memory/stubs.py +283 -0
- lfx/processing/__init__.py +1 -0
- lfx/processing/process.py +238 -0
- lfx/processing/utils.py +25 -0
- lfx/py.typed +0 -0
- lfx/schema/__init__.py +66 -0
- lfx/schema/artifact.py +83 -0
- lfx/schema/content_block.py +62 -0
- lfx/schema/content_types.py +91 -0
- lfx/schema/data.py +308 -0
- lfx/schema/dataframe.py +210 -0
- lfx/schema/dotdict.py +74 -0
- lfx/schema/encoders.py +13 -0
- lfx/schema/graph.py +47 -0
- lfx/schema/image.py +131 -0
- lfx/schema/json_schema.py +141 -0
- lfx/schema/log.py +61 -0
- lfx/schema/message.py +473 -0
- lfx/schema/openai_responses_schemas.py +74 -0
- lfx/schema/properties.py +41 -0
- lfx/schema/schema.py +171 -0
- lfx/schema/serialize.py +13 -0
- lfx/schema/table.py +140 -0
- lfx/schema/validators.py +114 -0
- lfx/serialization/__init__.py +5 -0
- lfx/serialization/constants.py +2 -0
- lfx/serialization/serialization.py +314 -0
- lfx/services/__init__.py +23 -0
- lfx/services/base.py +28 -0
- lfx/services/cache/__init__.py +6 -0
- lfx/services/cache/base.py +183 -0
- lfx/services/cache/service.py +166 -0
- lfx/services/cache/utils.py +169 -0
- lfx/services/chat/__init__.py +1 -0
- lfx/services/chat/config.py +2 -0
- lfx/services/chat/schema.py +10 -0
- lfx/services/deps.py +129 -0
- lfx/services/factory.py +19 -0
- lfx/services/initialize.py +19 -0
- lfx/services/interfaces.py +103 -0
- lfx/services/manager.py +172 -0
- lfx/services/schema.py +20 -0
- lfx/services/session.py +82 -0
- lfx/services/settings/__init__.py +3 -0
- lfx/services/settings/auth.py +130 -0
- lfx/services/settings/base.py +539 -0
- lfx/services/settings/constants.py +31 -0
- lfx/services/settings/factory.py +23 -0
- lfx/services/settings/feature_flags.py +12 -0
- lfx/services/settings/service.py +35 -0
- lfx/services/settings/utils.py +40 -0
- lfx/services/shared_component_cache/__init__.py +1 -0
- lfx/services/shared_component_cache/factory.py +30 -0
- lfx/services/shared_component_cache/service.py +9 -0
- lfx/services/storage/__init__.py +5 -0
- lfx/services/storage/local.py +155 -0
- lfx/services/storage/service.py +54 -0
- lfx/services/tracing/__init__.py +1 -0
- lfx/services/tracing/service.py +21 -0
- lfx/settings.py +6 -0
- lfx/template/__init__.py +6 -0
- lfx/template/field/__init__.py +0 -0
- lfx/template/field/base.py +257 -0
- lfx/template/field/prompt.py +15 -0
- lfx/template/frontend_node/__init__.py +6 -0
- lfx/template/frontend_node/base.py +212 -0
- lfx/template/frontend_node/constants.py +65 -0
- lfx/template/frontend_node/custom_components.py +79 -0
- lfx/template/template/__init__.py +0 -0
- lfx/template/template/base.py +100 -0
- lfx/template/utils.py +217 -0
- lfx/type_extraction/__init__.py +19 -0
- lfx/type_extraction/type_extraction.py +75 -0
- lfx/type_extraction.py +80 -0
- lfx/utils/__init__.py +1 -0
- lfx/utils/async_helpers.py +42 -0
- lfx/utils/component_utils.py +154 -0
- lfx/utils/concurrency.py +60 -0
- lfx/utils/connection_string_parser.py +11 -0
- lfx/utils/constants.py +205 -0
- lfx/utils/data_structure.py +212 -0
- lfx/utils/exceptions.py +22 -0
- lfx/utils/helpers.py +28 -0
- lfx/utils/image.py +73 -0
- lfx/utils/lazy_load.py +15 -0
- lfx/utils/request_utils.py +18 -0
- lfx/utils/schemas.py +139 -0
- lfx/utils/util.py +481 -0
- lfx/utils/util_strings.py +56 -0
- lfx/utils/version.py +24 -0
- lfx_nightly-0.1.11.dev0.dist-info/METADATA +293 -0
- lfx_nightly-0.1.11.dev0.dist-info/RECORD +699 -0
- lfx_nightly-0.1.11.dev0.dist-info/WHEEL +4 -0
- lfx_nightly-0.1.11.dev0.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,251 @@
|
|
1
|
+
from typing import Any, cast
|
2
|
+
|
3
|
+
from lfx.custom.custom_component.component import Component
|
4
|
+
from lfx.helpers.data import data_to_text
|
5
|
+
from lfx.inputs.inputs import DropdownInput, HandleInput, IntInput, MessageTextInput, MultilineInput, TabInput
|
6
|
+
from lfx.memory import aget_messages, astore_message
|
7
|
+
from lfx.schema.data import Data
|
8
|
+
from lfx.schema.dataframe import DataFrame
|
9
|
+
from lfx.schema.dotdict import dotdict
|
10
|
+
from lfx.schema.message import Message
|
11
|
+
from lfx.template.field.base import Output
|
12
|
+
from lfx.utils.component_utils import set_current_fields, set_field_display
|
13
|
+
from lfx.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_NAME_AI, MESSAGE_SENDER_USER
|
14
|
+
|
15
|
+
|
16
|
+
class MemoryComponent(Component):
|
17
|
+
display_name = "Message History"
|
18
|
+
description = "Stores or retrieves stored chat messages from Langflow tables or an external memory."
|
19
|
+
documentation: str = "https://docs.langflow.org/components-helpers#message-history"
|
20
|
+
icon = "message-square-more"
|
21
|
+
name = "Memory"
|
22
|
+
default_keys = ["mode", "memory"]
|
23
|
+
mode_config = {
|
24
|
+
"Store": ["message", "memory", "sender", "sender_name", "session_id"],
|
25
|
+
"Retrieve": ["n_messages", "order", "template", "memory"],
|
26
|
+
}
|
27
|
+
|
28
|
+
inputs = [
|
29
|
+
TabInput(
|
30
|
+
name="mode",
|
31
|
+
display_name="Mode",
|
32
|
+
options=["Retrieve", "Store"],
|
33
|
+
value="Retrieve",
|
34
|
+
info="Operation mode: Store messages or Retrieve messages.",
|
35
|
+
real_time_refresh=True,
|
36
|
+
),
|
37
|
+
MessageTextInput(
|
38
|
+
name="message",
|
39
|
+
display_name="Message",
|
40
|
+
info="The chat message to be stored.",
|
41
|
+
tool_mode=True,
|
42
|
+
dynamic=True,
|
43
|
+
show=False,
|
44
|
+
),
|
45
|
+
HandleInput(
|
46
|
+
name="memory",
|
47
|
+
display_name="External Memory",
|
48
|
+
input_types=["Memory"],
|
49
|
+
info="Retrieve messages from an external memory. If empty, it will use the Langflow tables.",
|
50
|
+
advanced=True,
|
51
|
+
),
|
52
|
+
DropdownInput(
|
53
|
+
name="sender_type",
|
54
|
+
display_name="Sender Type",
|
55
|
+
options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER, "Machine and User"],
|
56
|
+
value="Machine and User",
|
57
|
+
info="Filter by sender type.",
|
58
|
+
advanced=True,
|
59
|
+
),
|
60
|
+
MessageTextInput(
|
61
|
+
name="sender",
|
62
|
+
display_name="Sender",
|
63
|
+
info="The sender of the message. Might be Machine or User. "
|
64
|
+
"If empty, the current sender parameter will be used.",
|
65
|
+
advanced=True,
|
66
|
+
),
|
67
|
+
MessageTextInput(
|
68
|
+
name="sender_name",
|
69
|
+
display_name="Sender Name",
|
70
|
+
info="Filter by sender name.",
|
71
|
+
advanced=True,
|
72
|
+
show=False,
|
73
|
+
),
|
74
|
+
IntInput(
|
75
|
+
name="n_messages",
|
76
|
+
display_name="Number of Messages",
|
77
|
+
value=100,
|
78
|
+
info="Number of messages to retrieve.",
|
79
|
+
advanced=True,
|
80
|
+
show=True,
|
81
|
+
),
|
82
|
+
MessageTextInput(
|
83
|
+
name="session_id",
|
84
|
+
display_name="Session ID",
|
85
|
+
info="The session ID of the chat. If empty, the current session ID parameter will be used.",
|
86
|
+
value="",
|
87
|
+
advanced=True,
|
88
|
+
),
|
89
|
+
DropdownInput(
|
90
|
+
name="order",
|
91
|
+
display_name="Order",
|
92
|
+
options=["Ascending", "Descending"],
|
93
|
+
value="Ascending",
|
94
|
+
info="Order of the messages.",
|
95
|
+
advanced=True,
|
96
|
+
tool_mode=True,
|
97
|
+
required=True,
|
98
|
+
),
|
99
|
+
MultilineInput(
|
100
|
+
name="template",
|
101
|
+
display_name="Template",
|
102
|
+
info="The template to use for formatting the data. "
|
103
|
+
"It can contain the keys {text}, {sender} or any other key in the message data.",
|
104
|
+
value="{sender_name}: {text}",
|
105
|
+
advanced=True,
|
106
|
+
show=False,
|
107
|
+
),
|
108
|
+
]
|
109
|
+
|
110
|
+
outputs = [
|
111
|
+
Output(display_name="Message", name="messages_text", method="retrieve_messages_as_text", dynamic=True),
|
112
|
+
Output(display_name="Dataframe", name="dataframe", method="retrieve_messages_dataframe", dynamic=True),
|
113
|
+
]
|
114
|
+
|
115
|
+
def update_outputs(self, frontend_node: dict, field_name: str, field_value: Any) -> dict:
|
116
|
+
"""Dynamically show only the relevant output based on the selected output type."""
|
117
|
+
if field_name == "mode":
|
118
|
+
# Start with empty outputs
|
119
|
+
frontend_node["outputs"] = []
|
120
|
+
if field_value == "Store":
|
121
|
+
frontend_node["outputs"] = [
|
122
|
+
Output(
|
123
|
+
display_name="Stored Messages",
|
124
|
+
name="stored_messages",
|
125
|
+
method="store_message",
|
126
|
+
hidden=True,
|
127
|
+
dynamic=True,
|
128
|
+
)
|
129
|
+
]
|
130
|
+
if field_value == "Retrieve":
|
131
|
+
frontend_node["outputs"] = [
|
132
|
+
Output(
|
133
|
+
display_name="Messages", name="messages_text", method="retrieve_messages_as_text", dynamic=True
|
134
|
+
),
|
135
|
+
Output(
|
136
|
+
display_name="Dataframe", name="dataframe", method="retrieve_messages_dataframe", dynamic=True
|
137
|
+
),
|
138
|
+
]
|
139
|
+
return frontend_node
|
140
|
+
|
141
|
+
async def store_message(self) -> Message:
|
142
|
+
message = Message(text=self.message) if isinstance(self.message, str) else self.message
|
143
|
+
|
144
|
+
message.session_id = self.session_id or message.session_id
|
145
|
+
message.sender = self.sender or message.sender or MESSAGE_SENDER_AI
|
146
|
+
message.sender_name = self.sender_name or message.sender_name or MESSAGE_SENDER_NAME_AI
|
147
|
+
|
148
|
+
stored_messages: list[Message] = []
|
149
|
+
|
150
|
+
if self.memory:
|
151
|
+
self.memory.session_id = message.session_id
|
152
|
+
lc_message = message.to_lc_message()
|
153
|
+
await self.memory.aadd_messages([lc_message])
|
154
|
+
|
155
|
+
stored_messages = await self.memory.aget_messages() or []
|
156
|
+
|
157
|
+
stored_messages = [Message.from_lc_message(m) for m in stored_messages] if stored_messages else []
|
158
|
+
|
159
|
+
if message.sender:
|
160
|
+
stored_messages = [m for m in stored_messages if m.sender == message.sender]
|
161
|
+
else:
|
162
|
+
await astore_message(message, flow_id=self.graph.flow_id)
|
163
|
+
stored_messages = (
|
164
|
+
await aget_messages(
|
165
|
+
session_id=message.session_id, sender_name=message.sender_name, sender=message.sender
|
166
|
+
)
|
167
|
+
or []
|
168
|
+
)
|
169
|
+
|
170
|
+
if not stored_messages:
|
171
|
+
msg = "No messages were stored. Please ensure that the session ID and sender are properly set."
|
172
|
+
raise ValueError(msg)
|
173
|
+
|
174
|
+
stored_message = stored_messages[0]
|
175
|
+
self.status = stored_message
|
176
|
+
return stored_message
|
177
|
+
|
178
|
+
async def retrieve_messages(self) -> Data:
|
179
|
+
sender_type = self.sender_type
|
180
|
+
sender_name = self.sender_name
|
181
|
+
session_id = self.session_id
|
182
|
+
n_messages = self.n_messages
|
183
|
+
order = "DESC" if self.order == "Descending" else "ASC"
|
184
|
+
|
185
|
+
if sender_type == "Machine and User":
|
186
|
+
sender_type = None
|
187
|
+
|
188
|
+
if self.memory and not hasattr(self.memory, "aget_messages"):
|
189
|
+
memory_name = type(self.memory).__name__
|
190
|
+
err_msg = f"External Memory object ({memory_name}) must have 'aget_messages' method."
|
191
|
+
raise AttributeError(err_msg)
|
192
|
+
# Check if n_messages is None or 0
|
193
|
+
if n_messages == 0:
|
194
|
+
stored = []
|
195
|
+
elif self.memory:
|
196
|
+
# override session_id
|
197
|
+
self.memory.session_id = session_id
|
198
|
+
|
199
|
+
stored = await self.memory.aget_messages()
|
200
|
+
# langchain memories are supposed to return messages in ascending order
|
201
|
+
|
202
|
+
if order == "DESC":
|
203
|
+
stored = stored[::-1]
|
204
|
+
if n_messages:
|
205
|
+
stored = stored[-n_messages:] if order == "ASC" else stored[:n_messages]
|
206
|
+
stored = [Message.from_lc_message(m) for m in stored]
|
207
|
+
if sender_type:
|
208
|
+
expected_type = MESSAGE_SENDER_AI if sender_type == MESSAGE_SENDER_AI else MESSAGE_SENDER_USER
|
209
|
+
stored = [m for m in stored if m.type == expected_type]
|
210
|
+
else:
|
211
|
+
# For internal memory, we always fetch the last N messages by ordering by DESC
|
212
|
+
stored = await aget_messages(
|
213
|
+
sender=sender_type,
|
214
|
+
sender_name=sender_name,
|
215
|
+
session_id=session_id,
|
216
|
+
limit=10000,
|
217
|
+
order=order,
|
218
|
+
)
|
219
|
+
if n_messages:
|
220
|
+
stored = stored[-n_messages:] if order == "ASC" else stored[:n_messages]
|
221
|
+
|
222
|
+
# self.status = stored
|
223
|
+
return cast("Data", stored)
|
224
|
+
|
225
|
+
async def retrieve_messages_as_text(self) -> Message:
|
226
|
+
stored_text = data_to_text(self.template, await self.retrieve_messages())
|
227
|
+
# self.status = stored_text
|
228
|
+
return Message(text=stored_text)
|
229
|
+
|
230
|
+
async def retrieve_messages_dataframe(self) -> DataFrame:
|
231
|
+
"""Convert the retrieved messages into a DataFrame.
|
232
|
+
|
233
|
+
Returns:
|
234
|
+
DataFrame: A DataFrame containing the message data.
|
235
|
+
"""
|
236
|
+
messages = await self.retrieve_messages()
|
237
|
+
return DataFrame(messages)
|
238
|
+
|
239
|
+
def update_build_config(
|
240
|
+
self,
|
241
|
+
build_config: dotdict,
|
242
|
+
field_value: Any, # noqa: ARG002
|
243
|
+
field_name: str | None = None, # noqa: ARG002
|
244
|
+
) -> dotdict:
|
245
|
+
return set_current_fields(
|
246
|
+
build_config=build_config,
|
247
|
+
action_fields=self.mode_config,
|
248
|
+
selected_action=build_config["mode"]["value"],
|
249
|
+
default_fields=self.default_keys,
|
250
|
+
func=set_field_display,
|
251
|
+
)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from langchain_core.output_parsers import CommaSeparatedListOutputParser
|
2
|
+
|
3
|
+
from lfx.custom.custom_component.component import Component
|
4
|
+
from lfx.field_typing.constants import OutputParser
|
5
|
+
from lfx.io import DropdownInput, Output
|
6
|
+
from lfx.schema.message import Message
|
7
|
+
|
8
|
+
|
9
|
+
class OutputParserComponent(Component):
|
10
|
+
display_name = "Output Parser"
|
11
|
+
description = "Transforms the output of an LLM into a specified format."
|
12
|
+
icon = "type"
|
13
|
+
name = "OutputParser"
|
14
|
+
legacy = True
|
15
|
+
|
16
|
+
inputs = [
|
17
|
+
DropdownInput(
|
18
|
+
name="parser_type",
|
19
|
+
display_name="Parser",
|
20
|
+
options=["CSV"],
|
21
|
+
value="CSV",
|
22
|
+
),
|
23
|
+
]
|
24
|
+
|
25
|
+
outputs = [
|
26
|
+
Output(
|
27
|
+
display_name="Format Instructions",
|
28
|
+
name="format_instructions",
|
29
|
+
info="Pass to a prompt template to include formatting instructions for LLM responses.",
|
30
|
+
method="format_instructions",
|
31
|
+
),
|
32
|
+
Output(display_name="Output Parser", name="output_parser", method="build_parser"),
|
33
|
+
]
|
34
|
+
|
35
|
+
def build_parser(self) -> OutputParser:
|
36
|
+
if self.parser_type == "CSV":
|
37
|
+
return CommaSeparatedListOutputParser()
|
38
|
+
msg = "Unsupported or missing parser"
|
39
|
+
raise ValueError(msg)
|
40
|
+
|
41
|
+
def format_instructions(self) -> Message:
|
42
|
+
if self.parser_type == "CSV":
|
43
|
+
return Message(text=CommaSeparatedListOutputParser().get_format_instructions())
|
44
|
+
msg = "Unsupported or missing parser"
|
45
|
+
raise ValueError(msg)
|
@@ -0,0 +1,90 @@
|
|
1
|
+
from lfx.custom.custom_component.component import Component
|
2
|
+
from lfx.inputs.inputs import (
|
3
|
+
HandleInput,
|
4
|
+
MessageTextInput,
|
5
|
+
)
|
6
|
+
from lfx.memory import aget_messages, astore_message
|
7
|
+
from lfx.schema.message import Message
|
8
|
+
from lfx.template.field.base import Output
|
9
|
+
from lfx.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_NAME_AI
|
10
|
+
|
11
|
+
|
12
|
+
class MessageStoreComponent(Component):
|
13
|
+
display_name = "Message Store"
|
14
|
+
description = "Stores a chat message or text into Langflow tables or an external memory."
|
15
|
+
icon = "message-square-text"
|
16
|
+
name = "StoreMessage"
|
17
|
+
legacy = True
|
18
|
+
|
19
|
+
inputs = [
|
20
|
+
MessageTextInput(
|
21
|
+
name="message", display_name="Message", info="The chat message to be stored.", required=True, tool_mode=True
|
22
|
+
),
|
23
|
+
HandleInput(
|
24
|
+
name="memory",
|
25
|
+
display_name="External Memory",
|
26
|
+
input_types=["Memory"],
|
27
|
+
info="The external memory to store the message. If empty, it will use the Langflow tables.",
|
28
|
+
),
|
29
|
+
MessageTextInput(
|
30
|
+
name="sender",
|
31
|
+
display_name="Sender",
|
32
|
+
info="The sender of the message. Might be Machine or User. "
|
33
|
+
"If empty, the current sender parameter will be used.",
|
34
|
+
advanced=True,
|
35
|
+
),
|
36
|
+
MessageTextInput(
|
37
|
+
name="sender_name",
|
38
|
+
display_name="Sender Name",
|
39
|
+
info="The name of the sender. Might be AI or User. If empty, the current sender parameter will be used.",
|
40
|
+
advanced=True,
|
41
|
+
),
|
42
|
+
MessageTextInput(
|
43
|
+
name="session_id",
|
44
|
+
display_name="Session ID",
|
45
|
+
info="The session ID of the chat. If empty, the current session ID parameter will be used.",
|
46
|
+
value="",
|
47
|
+
advanced=True,
|
48
|
+
),
|
49
|
+
]
|
50
|
+
|
51
|
+
outputs = [
|
52
|
+
Output(display_name="Stored Messages", name="stored_messages", method="store_message", hidden=True),
|
53
|
+
]
|
54
|
+
|
55
|
+
async def store_message(self) -> Message:
|
56
|
+
message = Message(text=self.message) if isinstance(self.message, str) else self.message
|
57
|
+
|
58
|
+
message.session_id = self.session_id or message.session_id
|
59
|
+
message.sender = self.sender or message.sender or MESSAGE_SENDER_AI
|
60
|
+
message.sender_name = self.sender_name or message.sender_name or MESSAGE_SENDER_NAME_AI
|
61
|
+
|
62
|
+
stored_messages: list[Message] = []
|
63
|
+
|
64
|
+
if self.memory:
|
65
|
+
self.memory.session_id = message.session_id
|
66
|
+
lc_message = message.to_lc_message()
|
67
|
+
await self.memory.aadd_messages([lc_message])
|
68
|
+
|
69
|
+
stored_messages = await self.memory.aget_messages() or []
|
70
|
+
|
71
|
+
stored_messages = [Message.from_lc_message(m) for m in stored_messages] if stored_messages else []
|
72
|
+
|
73
|
+
if message.sender:
|
74
|
+
stored_messages = [m for m in stored_messages if m.sender == message.sender]
|
75
|
+
else:
|
76
|
+
await astore_message(message, flow_id=self.graph.flow_id)
|
77
|
+
stored_messages = (
|
78
|
+
await aget_messages(
|
79
|
+
session_id=message.session_id, sender_name=message.sender_name, sender=message.sender
|
80
|
+
)
|
81
|
+
or []
|
82
|
+
)
|
83
|
+
|
84
|
+
if not stored_messages:
|
85
|
+
msg = "No messages were stored. Please ensure that the session ID and sender are properly set."
|
86
|
+
raise ValueError(msg)
|
87
|
+
|
88
|
+
stored_message = stored_messages[0]
|
89
|
+
self.status = stored_message
|
90
|
+
return stored_message
|
@@ -0,0 +1,152 @@
|
|
1
|
+
import json
|
2
|
+
from typing import Any
|
3
|
+
|
4
|
+
import requests
|
5
|
+
from langchain.tools import StructuredTool
|
6
|
+
from pydantic import BaseModel, Field
|
7
|
+
|
8
|
+
from lfx.base.langchain_utilities.model import LCToolComponent
|
9
|
+
from lfx.field_typing import Tool
|
10
|
+
from lfx.inputs.inputs import SecretStrInput, StrInput
|
11
|
+
from lfx.schema.data import Data
|
12
|
+
|
13
|
+
|
14
|
+
class HomeAssistantControl(LCToolComponent):
|
15
|
+
"""This tool is used to control Home Assistant devices.
|
16
|
+
|
17
|
+
A very simple tool to control Home Assistant devices.
|
18
|
+
- The agent only needs to provide action (turn_on, turn_off, toggle) + entity_id (e.g., switch.xxx, light.xxx).
|
19
|
+
- The domain (e.g., 'switch', 'light') is automatically extracted from entity_id.
|
20
|
+
"""
|
21
|
+
|
22
|
+
display_name: str = "Home Assistant Control"
|
23
|
+
description: str = (
|
24
|
+
"A very simple tool to control Home Assistant devices. "
|
25
|
+
"Only action (turn_on, turn_off, toggle) and entity_id need to be provided."
|
26
|
+
)
|
27
|
+
documentation: str = "https://developers.home-assistant.io/docs/api/rest/"
|
28
|
+
icon: str = "HomeAssistant"
|
29
|
+
|
30
|
+
# --- Input fields for LangFlow UI (token, URL) ---
|
31
|
+
inputs = [
|
32
|
+
SecretStrInput(
|
33
|
+
name="ha_token",
|
34
|
+
display_name="Home Assistant Token",
|
35
|
+
info="Home Assistant Long-Lived Access Token",
|
36
|
+
required=True,
|
37
|
+
),
|
38
|
+
StrInput(
|
39
|
+
name="base_url",
|
40
|
+
display_name="Home Assistant URL",
|
41
|
+
info="e.g., http://192.168.0.10:8123",
|
42
|
+
required=True,
|
43
|
+
),
|
44
|
+
StrInput(
|
45
|
+
name="default_action",
|
46
|
+
display_name="Default Action (Optional)",
|
47
|
+
info="One of turn_on, turn_off, toggle",
|
48
|
+
required=False,
|
49
|
+
),
|
50
|
+
StrInput(
|
51
|
+
name="default_entity_id",
|
52
|
+
display_name="Default Entity ID (Optional)",
|
53
|
+
info="Default entity ID to control (e.g., switch.unknown_switch_3)",
|
54
|
+
required=False,
|
55
|
+
),
|
56
|
+
]
|
57
|
+
|
58
|
+
# --- Parameters exposed to the agent (Pydantic schema) ---
|
59
|
+
class ToolSchema(BaseModel):
|
60
|
+
"""Parameters to be passed by the agent: action, entity_id only."""
|
61
|
+
|
62
|
+
action: str = Field(..., description="Home Assistant service name. (One of turn_on, turn_off, toggle)")
|
63
|
+
entity_id: str = Field(
|
64
|
+
...,
|
65
|
+
description="Entity ID to control (e.g., switch.xxx, light.xxx, cover.xxx, etc.)."
|
66
|
+
"Do not infer; use the list_homeassistant_states tool to retrieve it.",
|
67
|
+
)
|
68
|
+
|
69
|
+
def run_model(self) -> Data:
|
70
|
+
"""Used when the 'Run' button is clicked in LangFlow.
|
71
|
+
|
72
|
+
- Uses default_action and default_entity_id entered in the UI.
|
73
|
+
"""
|
74
|
+
action = self.default_action or "turn_off"
|
75
|
+
entity_id = self.default_entity_id or "switch.unknown_switch_3"
|
76
|
+
|
77
|
+
result = self._control_device(
|
78
|
+
ha_token=self.ha_token,
|
79
|
+
base_url=self.base_url,
|
80
|
+
action=action,
|
81
|
+
entity_id=entity_id,
|
82
|
+
)
|
83
|
+
return self._make_data_response(result)
|
84
|
+
|
85
|
+
def build_tool(self) -> Tool:
|
86
|
+
"""Returns a tool to be used by the agent (LLM).
|
87
|
+
|
88
|
+
- The agent can only pass action and entity_id as arguments.
|
89
|
+
"""
|
90
|
+
return StructuredTool.from_function(
|
91
|
+
name="home_assistant_control",
|
92
|
+
description=(
|
93
|
+
"A tool to control Home Assistant devices easily. "
|
94
|
+
"Parameters: action ('turn_on'/'turn_off'/'toggle'), entity_id ('switch.xxx', etc.)."
|
95
|
+
"Entity ID must be obtained using the list_homeassistant_states tool and not guessed."
|
96
|
+
),
|
97
|
+
func=self._control_device_for_tool, # Wrapper function below
|
98
|
+
args_schema=self.ToolSchema,
|
99
|
+
)
|
100
|
+
|
101
|
+
def _control_device_for_tool(self, action: str, entity_id: str) -> dict[str, Any] | str:
|
102
|
+
"""Function called by the agent.
|
103
|
+
|
104
|
+
-> Internally calls _control_device.
|
105
|
+
"""
|
106
|
+
return self._control_device(
|
107
|
+
ha_token=self.ha_token,
|
108
|
+
base_url=self.base_url,
|
109
|
+
action=action,
|
110
|
+
entity_id=entity_id,
|
111
|
+
)
|
112
|
+
|
113
|
+
def _control_device(
|
114
|
+
self,
|
115
|
+
ha_token: str,
|
116
|
+
base_url: str,
|
117
|
+
action: str,
|
118
|
+
entity_id: str,
|
119
|
+
) -> dict[str, Any] | str:
|
120
|
+
"""Actual logic to call the Home Assistant service.
|
121
|
+
|
122
|
+
The domain is extracted from the beginning of the entity_id.
|
123
|
+
Example: entity_id="switch.unknown_switch_3" -> domain="switch".
|
124
|
+
"""
|
125
|
+
try:
|
126
|
+
domain = entity_id.split(".")[0] # switch, light, cover, etc.
|
127
|
+
url = f"{base_url}/api/services/{domain}/{action}"
|
128
|
+
|
129
|
+
headers = {
|
130
|
+
"Authorization": f"Bearer {ha_token}",
|
131
|
+
"Content-Type": "application/json",
|
132
|
+
}
|
133
|
+
payload = {"entity_id": entity_id}
|
134
|
+
|
135
|
+
response = requests.post(url, headers=headers, json=payload, timeout=10)
|
136
|
+
response.raise_for_status()
|
137
|
+
|
138
|
+
return response.json() # HA response JSON on success
|
139
|
+
except requests.exceptions.RequestException as e:
|
140
|
+
return f"Error: Failed to call service. {e}"
|
141
|
+
except Exception as e: # noqa: BLE001
|
142
|
+
return f"An unexpected error occurred: {e}"
|
143
|
+
|
144
|
+
def _make_data_response(self, result: dict[str, Any] | str) -> Data:
|
145
|
+
"""Returns a response in the LangFlow Data format."""
|
146
|
+
if isinstance(result, str):
|
147
|
+
# Handle error messages
|
148
|
+
return Data(text=result)
|
149
|
+
|
150
|
+
# Convert dict to JSON string
|
151
|
+
formatted_json = json.dumps(result, indent=2, ensure_ascii=False)
|
152
|
+
return Data(data=result, text=formatted_json)
|
@@ -0,0 +1,137 @@
|
|
1
|
+
import json
|
2
|
+
from typing import Any
|
3
|
+
|
4
|
+
import requests
|
5
|
+
from langchain.tools import StructuredTool
|
6
|
+
from pydantic import BaseModel, Field
|
7
|
+
|
8
|
+
from lfx.base.langchain_utilities.model import LCToolComponent
|
9
|
+
from lfx.field_typing import Tool
|
10
|
+
from lfx.inputs.inputs import SecretStrInput, StrInput
|
11
|
+
from lfx.schema.data import Data
|
12
|
+
|
13
|
+
|
14
|
+
class ListHomeAssistantStates(LCToolComponent):
|
15
|
+
display_name: str = "List Home Assistant States"
|
16
|
+
description: str = (
|
17
|
+
"Retrieve states from Home Assistant. "
|
18
|
+
"The agent only needs to specify 'filter_domain' (optional). "
|
19
|
+
"Token and base_url are not exposed to the agent."
|
20
|
+
)
|
21
|
+
documentation: str = "https://developers.home-assistant.io/docs/api/rest/"
|
22
|
+
icon = "HomeAssistant"
|
23
|
+
|
24
|
+
# 1) Define fields to be received in LangFlow UI
|
25
|
+
inputs = [
|
26
|
+
SecretStrInput(
|
27
|
+
name="ha_token",
|
28
|
+
display_name="Home Assistant Token",
|
29
|
+
info="Home Assistant Long-Lived Access Token",
|
30
|
+
required=True,
|
31
|
+
),
|
32
|
+
StrInput(
|
33
|
+
name="base_url",
|
34
|
+
display_name="Home Assistant URL",
|
35
|
+
info="e.g., http://192.168.0.10:8123",
|
36
|
+
required=True,
|
37
|
+
),
|
38
|
+
StrInput(
|
39
|
+
name="filter_domain",
|
40
|
+
display_name="Default Filter Domain (Optional)",
|
41
|
+
info="light, switch, sensor, etc. (Leave empty to fetch all)",
|
42
|
+
required=False,
|
43
|
+
),
|
44
|
+
]
|
45
|
+
|
46
|
+
# 2) Pydantic schema containing only parameters exposed to the agent
|
47
|
+
class ToolSchema(BaseModel):
|
48
|
+
"""Parameters to be passed by the agent: filter_domain only."""
|
49
|
+
|
50
|
+
filter_domain: str = Field("", description="Filter domain (e.g., 'light'). If empty, returns all.")
|
51
|
+
|
52
|
+
def run_model(self) -> Data:
|
53
|
+
"""Execute the LangFlow component.
|
54
|
+
|
55
|
+
Uses self.ha_token, self.base_url, self.filter_domain as entered in the UI.
|
56
|
+
Triggered when 'Run' is clicked directly without an agent.
|
57
|
+
"""
|
58
|
+
filter_domain = self.filter_domain or "" # Use "" for fetching all states
|
59
|
+
result = self._list_states(
|
60
|
+
ha_token=self.ha_token,
|
61
|
+
base_url=self.base_url,
|
62
|
+
filter_domain=filter_domain,
|
63
|
+
)
|
64
|
+
return self._make_data_response(result)
|
65
|
+
|
66
|
+
def build_tool(self) -> Tool:
|
67
|
+
"""Build a tool object to be used by the agent.
|
68
|
+
|
69
|
+
The agent can only pass 'filter_domain' as a parameter.
|
70
|
+
'ha_token' and 'base_url' are not exposed (stored as self attributes).
|
71
|
+
"""
|
72
|
+
return StructuredTool.from_function(
|
73
|
+
name="list_homeassistant_states",
|
74
|
+
description=(
|
75
|
+
"Retrieve states from Home Assistant. "
|
76
|
+
"You can provide filter_domain='light', 'switch', etc. to narrow results."
|
77
|
+
),
|
78
|
+
func=self._list_states_for_tool, # Wrapper function below
|
79
|
+
args_schema=self.ToolSchema, # Requires only filter_domain
|
80
|
+
)
|
81
|
+
|
82
|
+
def _list_states_for_tool(self, filter_domain: str = "") -> list[Any] | str:
|
83
|
+
"""Execute the tool when called by the agent.
|
84
|
+
|
85
|
+
'ha_token' and 'base_url' are stored in self (not exposed).
|
86
|
+
"""
|
87
|
+
return self._list_states(
|
88
|
+
ha_token=self.ha_token,
|
89
|
+
base_url=self.base_url,
|
90
|
+
filter_domain=filter_domain,
|
91
|
+
)
|
92
|
+
|
93
|
+
def _list_states(
|
94
|
+
self,
|
95
|
+
ha_token: str,
|
96
|
+
base_url: str,
|
97
|
+
filter_domain: str = "",
|
98
|
+
) -> list[Any] | str:
|
99
|
+
"""Call the Home Assistant /api/states endpoint."""
|
100
|
+
try:
|
101
|
+
headers = {
|
102
|
+
"Authorization": f"Bearer {ha_token}",
|
103
|
+
"Content-Type": "application/json",
|
104
|
+
}
|
105
|
+
url = f"{base_url}/api/states"
|
106
|
+
response = requests.get(url, headers=headers, timeout=10)
|
107
|
+
response.raise_for_status()
|
108
|
+
|
109
|
+
all_states = response.json()
|
110
|
+
if filter_domain:
|
111
|
+
return [st for st in all_states if st.get("entity_id", "").startswith(f"{filter_domain}.")]
|
112
|
+
|
113
|
+
except requests.exceptions.RequestException as e:
|
114
|
+
return f"Error: Failed to fetch states. {e}"
|
115
|
+
except (ValueError, TypeError) as e:
|
116
|
+
return f"Error processing response: {e}"
|
117
|
+
return all_states
|
118
|
+
|
119
|
+
def _make_data_response(self, result: list[Any] | str | dict) -> Data:
|
120
|
+
"""Format the response into a Data object."""
|
121
|
+
try:
|
122
|
+
if isinstance(result, list):
|
123
|
+
# Wrap list data into a dictionary and convert to text
|
124
|
+
wrapped_result = {"result": result}
|
125
|
+
return Data(data=wrapped_result, text=json.dumps(wrapped_result, indent=2, ensure_ascii=False))
|
126
|
+
if isinstance(result, dict):
|
127
|
+
# Return dictionary as-is
|
128
|
+
return Data(data=result, text=json.dumps(result, indent=2, ensure_ascii=False))
|
129
|
+
if isinstance(result, str):
|
130
|
+
# Return error messages or strings
|
131
|
+
return Data(data={}, text=result)
|
132
|
+
|
133
|
+
# Handle unexpected data types
|
134
|
+
return Data(data={}, text="Error: Unexpected response format.")
|
135
|
+
except (TypeError, ValueError) as e:
|
136
|
+
# Handle specific exceptions during formatting
|
137
|
+
return Data(data={}, text=f"Error: Failed to process response. Details: {e!s}")
|