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,325 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import asyncio
|
4
|
+
import re
|
5
|
+
from typing import TYPE_CHECKING, Literal
|
6
|
+
|
7
|
+
import pandas as pd
|
8
|
+
from langchain_core.tools import BaseTool, ToolException
|
9
|
+
from langchain_core.tools.structured import StructuredTool
|
10
|
+
|
11
|
+
from lfx.base.tools.constants import TOOL_OUTPUT_NAME
|
12
|
+
from lfx.schema.data import Data
|
13
|
+
from lfx.schema.message import Message
|
14
|
+
from lfx.serialization.serialization import serialize
|
15
|
+
|
16
|
+
if TYPE_CHECKING:
|
17
|
+
from collections.abc import Callable
|
18
|
+
|
19
|
+
from langchain_core.callbacks import Callbacks
|
20
|
+
|
21
|
+
from lfx.custom.custom_component.component import Component
|
22
|
+
from lfx.events.event_manager import EventManager
|
23
|
+
from lfx.inputs.inputs import InputTypes
|
24
|
+
from lfx.io import Output
|
25
|
+
from lfx.schema.content_block import ContentBlock
|
26
|
+
from lfx.schema.dotdict import dotdict
|
27
|
+
|
28
|
+
TOOL_TYPES_SET = {"Tool", "BaseTool", "StructuredTool"}
|
29
|
+
|
30
|
+
|
31
|
+
def _get_input_type(input_: InputTypes):
|
32
|
+
if input_.input_types:
|
33
|
+
if len(input_.input_types) == 1:
|
34
|
+
return input_.input_types[0]
|
35
|
+
return " | ".join(input_.input_types)
|
36
|
+
return input_.field_type
|
37
|
+
|
38
|
+
|
39
|
+
def build_description(component: Component) -> str:
|
40
|
+
return component.description or ""
|
41
|
+
|
42
|
+
|
43
|
+
async def send_message_noop(
|
44
|
+
message: Message,
|
45
|
+
text: str | None = None, # noqa: ARG001
|
46
|
+
background_color: str | None = None, # noqa: ARG001
|
47
|
+
text_color: str | None = None, # noqa: ARG001
|
48
|
+
icon: str | None = None, # noqa: ARG001
|
49
|
+
content_blocks: list[ContentBlock] | None = None, # noqa: ARG001
|
50
|
+
format_type: Literal["default", "error", "warning", "info"] = "default", # noqa: ARG001
|
51
|
+
id_: str | None = None, # noqa: ARG001
|
52
|
+
*,
|
53
|
+
allow_markdown: bool = True, # noqa: ARG001
|
54
|
+
) -> Message:
|
55
|
+
"""No-op implementation of send_message."""
|
56
|
+
return message
|
57
|
+
|
58
|
+
|
59
|
+
def patch_components_send_message(component: Component):
|
60
|
+
old_send_message = component.send_message
|
61
|
+
component.send_message = send_message_noop # type: ignore[method-assign, assignment]
|
62
|
+
return old_send_message
|
63
|
+
|
64
|
+
|
65
|
+
def _patch_send_message_decorator(component, func):
|
66
|
+
"""Decorator to patch the send_message method of a component.
|
67
|
+
|
68
|
+
This is useful when we want to use a component as a tool, but we don't want to
|
69
|
+
send any messages to the UI. With this only the Component calling the tool
|
70
|
+
will send messages to the UI.
|
71
|
+
"""
|
72
|
+
|
73
|
+
async def async_wrapper(*args, **kwargs):
|
74
|
+
original_send_message = component.send_message
|
75
|
+
component.send_message = send_message_noop
|
76
|
+
try:
|
77
|
+
return await func(*args, **kwargs)
|
78
|
+
finally:
|
79
|
+
component.send_message = original_send_message
|
80
|
+
|
81
|
+
def sync_wrapper(*args, **kwargs):
|
82
|
+
original_send_message = component.send_message
|
83
|
+
component.send_message = send_message_noop
|
84
|
+
try:
|
85
|
+
return func(*args, **kwargs)
|
86
|
+
finally:
|
87
|
+
component.send_message = original_send_message
|
88
|
+
|
89
|
+
return async_wrapper if asyncio.iscoroutinefunction(func) else sync_wrapper
|
90
|
+
|
91
|
+
|
92
|
+
def _build_output_function(component: Component, output_method: Callable, event_manager: EventManager | None = None):
|
93
|
+
def output_function(*args, **kwargs):
|
94
|
+
try:
|
95
|
+
if event_manager:
|
96
|
+
event_manager.on_build_start(data={"id": component.get_id()})
|
97
|
+
component.set(*args, **kwargs)
|
98
|
+
result = output_method()
|
99
|
+
if event_manager:
|
100
|
+
event_manager.on_build_end(data={"id": component.get_id()})
|
101
|
+
except Exception as e:
|
102
|
+
raise ToolException(e) from e
|
103
|
+
|
104
|
+
if isinstance(result, Message):
|
105
|
+
return result.get_text()
|
106
|
+
if isinstance(result, Data):
|
107
|
+
return result.data
|
108
|
+
# removing the model_dump() call here because it is not serializable
|
109
|
+
return serialize(result)
|
110
|
+
|
111
|
+
return _patch_send_message_decorator(component, output_function)
|
112
|
+
|
113
|
+
|
114
|
+
def _build_output_async_function(
|
115
|
+
component: Component, output_method: Callable, event_manager: EventManager | None = None
|
116
|
+
):
|
117
|
+
async def output_function(*args, **kwargs):
|
118
|
+
try:
|
119
|
+
if event_manager:
|
120
|
+
await asyncio.to_thread(event_manager.on_build_start, data={"id": component.get_id()})
|
121
|
+
component.set(*args, **kwargs)
|
122
|
+
result = await output_method()
|
123
|
+
if event_manager:
|
124
|
+
await asyncio.to_thread(event_manager.on_build_end, data={"id": component.get_id()})
|
125
|
+
except Exception as e:
|
126
|
+
raise ToolException(e) from e
|
127
|
+
if isinstance(result, Message):
|
128
|
+
return result.get_text()
|
129
|
+
if isinstance(result, Data):
|
130
|
+
return result.data
|
131
|
+
# removing the model_dump() call here because it is not serializable
|
132
|
+
return serialize(result)
|
133
|
+
|
134
|
+
return _patch_send_message_decorator(component, output_function)
|
135
|
+
|
136
|
+
|
137
|
+
def _format_tool_name(name: str):
|
138
|
+
# format to '^[a-zA-Z0-9_-]+$'."
|
139
|
+
# to do that we must remove all non-alphanumeric characters
|
140
|
+
|
141
|
+
return re.sub(r"[^a-zA-Z0-9_-]", "-", name)
|
142
|
+
|
143
|
+
|
144
|
+
def _add_commands_to_tool_description(tool_description: str, commands: str):
|
145
|
+
return f"very_time you see one of those commands {commands} run the tool. tool description is {tool_description}"
|
146
|
+
|
147
|
+
|
148
|
+
class ComponentToolkit:
|
149
|
+
def __init__(self, component: Component, metadata: pd.DataFrame | None = None):
|
150
|
+
self.component = component
|
151
|
+
self.metadata = metadata
|
152
|
+
|
153
|
+
def _should_skip_output(self, output: Output) -> bool:
|
154
|
+
"""Determines if an output should be skipped when creating tools.
|
155
|
+
|
156
|
+
Args:
|
157
|
+
output (Output): The output to check.
|
158
|
+
|
159
|
+
Returns:
|
160
|
+
bool: True if the output should be skipped, False otherwise.
|
161
|
+
|
162
|
+
The output will be skipped if:
|
163
|
+
- tool_mode is False (output is not meant to be used as a tool)
|
164
|
+
- output name matches TOOL_OUTPUT_NAME
|
165
|
+
- output types contain any of the tool types in TOOL_TYPES_SET
|
166
|
+
"""
|
167
|
+
return not output.tool_mode or (
|
168
|
+
output.name == TOOL_OUTPUT_NAME or any(tool_type in output.types for tool_type in TOOL_TYPES_SET)
|
169
|
+
)
|
170
|
+
|
171
|
+
def get_tools(
|
172
|
+
self,
|
173
|
+
tool_name: str | None = None,
|
174
|
+
tool_description: str | None = None,
|
175
|
+
callbacks: Callbacks | None = None,
|
176
|
+
flow_mode_inputs: list[dotdict] | None = None,
|
177
|
+
) -> list[BaseTool]:
|
178
|
+
from lfx.io.schema import create_input_schema, create_input_schema_from_dict
|
179
|
+
|
180
|
+
tools = []
|
181
|
+
for output in self.component.outputs:
|
182
|
+
if self._should_skip_output(output):
|
183
|
+
continue
|
184
|
+
|
185
|
+
if not output.method:
|
186
|
+
msg = f"Output {output.name} does not have a method defined"
|
187
|
+
raise ValueError(msg)
|
188
|
+
|
189
|
+
output_method: Callable = getattr(self.component, output.method)
|
190
|
+
args_schema = None
|
191
|
+
tool_mode_inputs = [_input for _input in self.component.inputs if getattr(_input, "tool_mode", False)]
|
192
|
+
if flow_mode_inputs:
|
193
|
+
args_schema = create_input_schema_from_dict(
|
194
|
+
inputs=flow_mode_inputs,
|
195
|
+
param_key="flow_tweak_data",
|
196
|
+
)
|
197
|
+
elif tool_mode_inputs:
|
198
|
+
args_schema = create_input_schema(tool_mode_inputs)
|
199
|
+
elif output.required_inputs:
|
200
|
+
inputs = [
|
201
|
+
self.component.get_underscore_inputs()[input_name]
|
202
|
+
for input_name in output.required_inputs
|
203
|
+
if getattr(self.component, input_name) is None
|
204
|
+
]
|
205
|
+
# If any of the required inputs are not in tool mode, this means
|
206
|
+
# that when the tool is called it will raise an error.
|
207
|
+
# so we should raise an error here.
|
208
|
+
# TODO: This logic might need to be improved, example if the required is an api key.
|
209
|
+
if not all(getattr(_input, "tool_mode", False) for _input in inputs):
|
210
|
+
non_tool_mode_inputs = [
|
211
|
+
input_.name
|
212
|
+
for input_ in inputs
|
213
|
+
if not getattr(input_, "tool_mode", False) and input_.name is not None
|
214
|
+
]
|
215
|
+
non_tool_mode_inputs_str = ", ".join(non_tool_mode_inputs)
|
216
|
+
msg = (
|
217
|
+
f"Output '{output.name}' requires inputs that are not in tool mode. "
|
218
|
+
f"The following inputs are not in tool mode: {non_tool_mode_inputs_str}. "
|
219
|
+
"Please ensure all required inputs are set to tool mode."
|
220
|
+
)
|
221
|
+
raise ValueError(msg)
|
222
|
+
args_schema = create_input_schema(inputs)
|
223
|
+
|
224
|
+
else:
|
225
|
+
args_schema = create_input_schema(self.component.inputs)
|
226
|
+
|
227
|
+
name = f"{output.method}".strip(".")
|
228
|
+
formatted_name = _format_tool_name(name)
|
229
|
+
event_manager = self.component.get_event_manager()
|
230
|
+
if asyncio.iscoroutinefunction(output_method):
|
231
|
+
tools.append(
|
232
|
+
StructuredTool(
|
233
|
+
name=formatted_name,
|
234
|
+
description=build_description(self.component),
|
235
|
+
coroutine=_build_output_async_function(self.component, output_method, event_manager),
|
236
|
+
args_schema=args_schema,
|
237
|
+
handle_tool_error=True,
|
238
|
+
callbacks=callbacks,
|
239
|
+
tags=[formatted_name],
|
240
|
+
metadata={
|
241
|
+
"display_name": formatted_name,
|
242
|
+
"display_description": build_description(self.component),
|
243
|
+
},
|
244
|
+
)
|
245
|
+
)
|
246
|
+
else:
|
247
|
+
tools.append(
|
248
|
+
StructuredTool(
|
249
|
+
name=formatted_name,
|
250
|
+
description=build_description(self.component),
|
251
|
+
func=_build_output_function(self.component, output_method, event_manager),
|
252
|
+
args_schema=args_schema,
|
253
|
+
handle_tool_error=True,
|
254
|
+
callbacks=callbacks,
|
255
|
+
tags=[formatted_name],
|
256
|
+
metadata={
|
257
|
+
"display_name": formatted_name,
|
258
|
+
"display_description": build_description(self.component),
|
259
|
+
},
|
260
|
+
)
|
261
|
+
)
|
262
|
+
if len(tools) == 1 and (tool_name or tool_description):
|
263
|
+
tool = tools[0]
|
264
|
+
tool.name = _format_tool_name(str(tool_name)) or tool.name
|
265
|
+
tool.description = tool_description or tool.description
|
266
|
+
tool.tags = [tool.name]
|
267
|
+
elif flow_mode_inputs and (tool_name or tool_description):
|
268
|
+
for tool in tools:
|
269
|
+
tool.name = _format_tool_name(str(tool_name) + "_" + str(tool.name)) or tool.name
|
270
|
+
tool.description = (
|
271
|
+
str(tool_description) + " Output details: " + str(tool.description)
|
272
|
+
) or tool.description
|
273
|
+
tool.tags = [tool.name]
|
274
|
+
elif tool_name or tool_description:
|
275
|
+
msg = (
|
276
|
+
"When passing a tool name or description, there must be only one tool, "
|
277
|
+
f"but {len(tools)} tools were found."
|
278
|
+
)
|
279
|
+
raise ValueError(msg)
|
280
|
+
return tools
|
281
|
+
|
282
|
+
def get_tools_metadata_dictionary(self) -> dict:
|
283
|
+
if isinstance(self.metadata, pd.DataFrame):
|
284
|
+
try:
|
285
|
+
return {
|
286
|
+
record["tags"][0]: record
|
287
|
+
for record in self.metadata.to_dict(orient="records")
|
288
|
+
if record.get("tags")
|
289
|
+
}
|
290
|
+
except (KeyError, IndexError) as e:
|
291
|
+
msg = "Error processing metadata records: " + str(e)
|
292
|
+
raise ValueError(msg) from e
|
293
|
+
return {}
|
294
|
+
|
295
|
+
def update_tools_metadata(
|
296
|
+
self,
|
297
|
+
tools: list[BaseTool | StructuredTool],
|
298
|
+
) -> list[BaseTool]:
|
299
|
+
# update the tool_name and description according to the name and secriotion mentioned in the list
|
300
|
+
if isinstance(self.metadata, pd.DataFrame):
|
301
|
+
metadata_dict = self.get_tools_metadata_dictionary()
|
302
|
+
filtered_tools = []
|
303
|
+
for tool in tools:
|
304
|
+
if isinstance(tool, StructuredTool | BaseTool) and tool.tags:
|
305
|
+
try:
|
306
|
+
tag = tool.tags[0]
|
307
|
+
except IndexError:
|
308
|
+
msg = "Tool tags cannot be empty."
|
309
|
+
raise ValueError(msg) from None
|
310
|
+
if tag in metadata_dict:
|
311
|
+
tool_metadata = metadata_dict[tag]
|
312
|
+
# Only include tools with status=True
|
313
|
+
if tool_metadata.get("status", True):
|
314
|
+
tool.name = tool_metadata.get("name", tool.name)
|
315
|
+
tool.description = tool_metadata.get("description", tool.description)
|
316
|
+
if tool_metadata.get("commands"):
|
317
|
+
tool.description = _add_commands_to_tool_description(
|
318
|
+
tool.description, tool_metadata.get("commands")
|
319
|
+
)
|
320
|
+
filtered_tools.append(tool)
|
321
|
+
else:
|
322
|
+
msg = f"Expected a StructuredTool or BaseTool, got {type(tool)}"
|
323
|
+
raise TypeError(msg)
|
324
|
+
return filtered_tools
|
325
|
+
return tools
|
@@ -0,0 +1,49 @@
|
|
1
|
+
from lfx.schema.table import EditMode
|
2
|
+
|
3
|
+
TOOL_OUTPUT_NAME = "component_as_tool"
|
4
|
+
TOOL_OUTPUT_DISPLAY_NAME = "Toolset"
|
5
|
+
TOOLS_METADATA_INPUT_NAME = "tools_metadata"
|
6
|
+
TOOL_TABLE_SCHEMA = [
|
7
|
+
{
|
8
|
+
"name": "name",
|
9
|
+
"display_name": "Tool Name",
|
10
|
+
"type": "str",
|
11
|
+
"description": "Specify the name of the tool.",
|
12
|
+
"sortable": False,
|
13
|
+
"filterable": False,
|
14
|
+
"edit_mode": EditMode.INLINE,
|
15
|
+
"hidden": False,
|
16
|
+
},
|
17
|
+
{
|
18
|
+
"name": "description",
|
19
|
+
"display_name": "Tool Description",
|
20
|
+
"type": "str",
|
21
|
+
"description": "Describe the purpose of the tool.",
|
22
|
+
"sortable": False,
|
23
|
+
"filterable": False,
|
24
|
+
"edit_mode": EditMode.POPOVER,
|
25
|
+
"hidden": False,
|
26
|
+
},
|
27
|
+
{
|
28
|
+
"name": "tags",
|
29
|
+
"display_name": "Tool Identifiers",
|
30
|
+
"type": "str",
|
31
|
+
"description": ("The default identifiers for the tools and cannot be changed."),
|
32
|
+
"disable_edit": True,
|
33
|
+
"sortable": False,
|
34
|
+
"filterable": False,
|
35
|
+
"edit_mode": EditMode.INLINE,
|
36
|
+
"hidden": True,
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"name": "status",
|
40
|
+
"display_name": "Enable",
|
41
|
+
"type": "boolean",
|
42
|
+
"description": "Indicates whether the tool is currently active. Set to True to activate this tool.",
|
43
|
+
"default": True,
|
44
|
+
},
|
45
|
+
]
|
46
|
+
|
47
|
+
TOOLS_METADATA_INFO = "Modify tool names and descriptions to help agents understand when to use each tool."
|
48
|
+
|
49
|
+
TOOL_UPDATE_CONSTANTS = ["tool_mode", "tool_actions", TOOLS_METADATA_INPUT_NAME, "flow_name_selected"]
|
@@ -0,0 +1,132 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Any
|
4
|
+
|
5
|
+
from langchain_core.tools import BaseTool, ToolException
|
6
|
+
from typing_extensions import override
|
7
|
+
|
8
|
+
from lfx.base.flow_processing.utils import build_data_from_result_data, format_flow_output_data
|
9
|
+
from lfx.helpers.flow import build_schema_from_inputs, get_arg_names, get_flow_inputs, run_flow
|
10
|
+
from lfx.log.logger import logger
|
11
|
+
from lfx.utils.async_helpers import run_until_complete
|
12
|
+
|
13
|
+
if TYPE_CHECKING:
|
14
|
+
from langchain_core.runnables import RunnableConfig
|
15
|
+
from pydantic.v1 import BaseModel
|
16
|
+
|
17
|
+
from lfx.graph.graph.base import Graph
|
18
|
+
from lfx.graph.vertex.base import Vertex
|
19
|
+
|
20
|
+
|
21
|
+
class FlowTool(BaseTool):
|
22
|
+
name: str
|
23
|
+
description: str
|
24
|
+
graph: Graph | None = None
|
25
|
+
flow_id: str | None = None
|
26
|
+
user_id: str | None = None
|
27
|
+
session_id: str | None = None
|
28
|
+
inputs: list[Vertex] = []
|
29
|
+
get_final_results_only: bool = True
|
30
|
+
|
31
|
+
@property
|
32
|
+
def args(self) -> dict:
|
33
|
+
schema = self.get_input_schema()
|
34
|
+
return schema.schema()["properties"]
|
35
|
+
|
36
|
+
@override
|
37
|
+
def get_input_schema( # type: ignore[misc]
|
38
|
+
self, config: RunnableConfig | None = None
|
39
|
+
) -> type[BaseModel]:
|
40
|
+
"""The tool's input schema."""
|
41
|
+
if self.args_schema is not None:
|
42
|
+
return self.args_schema
|
43
|
+
if self.graph is not None:
|
44
|
+
return build_schema_from_inputs(self.name, get_flow_inputs(self.graph))
|
45
|
+
msg = "No input schema available."
|
46
|
+
raise ToolException(msg)
|
47
|
+
|
48
|
+
def _run(
|
49
|
+
self,
|
50
|
+
*args: Any,
|
51
|
+
**kwargs: Any,
|
52
|
+
) -> str:
|
53
|
+
"""Use the tool."""
|
54
|
+
args_names = get_arg_names(self.inputs)
|
55
|
+
if len(args_names) == len(args):
|
56
|
+
kwargs = {arg["arg_name"]: arg_value for arg, arg_value in zip(args_names, args, strict=True)}
|
57
|
+
elif len(args_names) != len(args) and len(args) != 0:
|
58
|
+
msg = "Number of arguments does not match the number of inputs. Pass keyword arguments instead."
|
59
|
+
raise ToolException(msg)
|
60
|
+
tweaks = {arg["component_name"]: kwargs[arg["arg_name"]] for arg in args_names}
|
61
|
+
|
62
|
+
run_outputs = run_until_complete(
|
63
|
+
run_flow(
|
64
|
+
graph=self.graph,
|
65
|
+
tweaks={key: {"input_value": value} for key, value in tweaks.items()},
|
66
|
+
flow_id=self.flow_id,
|
67
|
+
user_id=self.user_id,
|
68
|
+
session_id=self.session_id,
|
69
|
+
)
|
70
|
+
)
|
71
|
+
if not run_outputs:
|
72
|
+
return "No output"
|
73
|
+
run_output = run_outputs[0]
|
74
|
+
|
75
|
+
data = []
|
76
|
+
if run_output is not None:
|
77
|
+
for output in run_output.outputs:
|
78
|
+
if output:
|
79
|
+
data.extend(build_data_from_result_data(output))
|
80
|
+
return format_flow_output_data(data)
|
81
|
+
|
82
|
+
def validate_inputs(self, args_names: list[dict[str, str]], args: Any, kwargs: Any):
|
83
|
+
"""Validate the inputs."""
|
84
|
+
if len(args) > 0 and len(args) != len(args_names):
|
85
|
+
msg = "Number of positional arguments does not match the number of inputs. Pass keyword arguments instead."
|
86
|
+
raise ToolException(msg)
|
87
|
+
|
88
|
+
if len(args) == len(args_names):
|
89
|
+
kwargs = {arg_name["arg_name"]: arg_value for arg_name, arg_value in zip(args_names, args, strict=True)}
|
90
|
+
|
91
|
+
missing_args = [arg["arg_name"] for arg in args_names if arg["arg_name"] not in kwargs]
|
92
|
+
if missing_args:
|
93
|
+
msg = f"Missing required arguments: {', '.join(missing_args)}"
|
94
|
+
raise ToolException(msg)
|
95
|
+
|
96
|
+
return kwargs
|
97
|
+
|
98
|
+
def build_tweaks_dict(self, args, kwargs):
|
99
|
+
args_names = get_arg_names(self.inputs)
|
100
|
+
kwargs = self.validate_inputs(args_names=args_names, args=args, kwargs=kwargs)
|
101
|
+
return {arg["component_name"]: kwargs[arg["arg_name"]] for arg in args_names}
|
102
|
+
|
103
|
+
async def _arun(
|
104
|
+
self,
|
105
|
+
*args: Any,
|
106
|
+
**kwargs: Any,
|
107
|
+
) -> str:
|
108
|
+
"""Use the tool asynchronously."""
|
109
|
+
tweaks = self.build_tweaks_dict(args, kwargs)
|
110
|
+
try:
|
111
|
+
run_id = self.graph.run_id if hasattr(self, "graph") and self.graph else None
|
112
|
+
except Exception: # noqa: BLE001
|
113
|
+
logger.warning("Failed to set run_id", exc_info=True)
|
114
|
+
run_id = None
|
115
|
+
run_outputs = await run_flow(
|
116
|
+
tweaks={key: {"input_value": value} for key, value in tweaks.items()},
|
117
|
+
flow_id=self.flow_id,
|
118
|
+
user_id=self.user_id,
|
119
|
+
run_id=run_id,
|
120
|
+
session_id=self.session_id,
|
121
|
+
graph=self.graph,
|
122
|
+
)
|
123
|
+
if not run_outputs:
|
124
|
+
return "No output"
|
125
|
+
run_output = run_outputs[0]
|
126
|
+
|
127
|
+
data = []
|
128
|
+
if run_output is not None:
|
129
|
+
for output in run_output.outputs:
|
130
|
+
if output:
|
131
|
+
data.extend(build_data_from_result_data(output))
|
132
|
+
return format_flow_output_data(data)
|