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
lfx/inputs/validators.py
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
from typing import Annotated
|
2
|
+
|
3
|
+
from pydantic import PlainValidator
|
4
|
+
|
5
|
+
|
6
|
+
def validate_boolean(value: bool) -> bool: # noqa: FBT001
|
7
|
+
valid_trues = ["True", "true", "1", "yes"]
|
8
|
+
valid_falses = ["False", "false", "0", "no"]
|
9
|
+
if value in valid_trues:
|
10
|
+
return True
|
11
|
+
if value in valid_falses:
|
12
|
+
return False
|
13
|
+
if isinstance(value, bool):
|
14
|
+
return value
|
15
|
+
msg = "Value must be a boolean"
|
16
|
+
raise ValueError(msg)
|
17
|
+
|
18
|
+
|
19
|
+
CoalesceBool = Annotated[bool, PlainValidator(validate_boolean)]
|
@@ -0,0 +1,489 @@
|
|
1
|
+
import asyncio
|
2
|
+
import importlib
|
3
|
+
import json
|
4
|
+
import pkgutil
|
5
|
+
from pathlib import Path
|
6
|
+
from typing import TYPE_CHECKING, Any, Optional
|
7
|
+
|
8
|
+
from lfx.constants import BASE_COMPONENTS_PATH
|
9
|
+
from lfx.custom.utils import abuild_custom_components, create_component_template
|
10
|
+
from lfx.log.logger import logger
|
11
|
+
|
12
|
+
if TYPE_CHECKING:
|
13
|
+
from lfx.services.settings.service import SettingsService
|
14
|
+
|
15
|
+
MIN_MODULE_PARTS = 2
|
16
|
+
EXPECTED_RESULT_LENGTH = 2 # Expected length of the tuple returned by _process_single_module
|
17
|
+
|
18
|
+
|
19
|
+
# Create a class to manage component cache instead of using globals
|
20
|
+
class ComponentCache:
|
21
|
+
def __init__(self):
|
22
|
+
"""Initializes the component cache.
|
23
|
+
|
24
|
+
Creates empty storage for all component types and tracking of fully loaded components.
|
25
|
+
"""
|
26
|
+
self.all_types_dict: dict[str, Any] | None = None
|
27
|
+
self.fully_loaded_components: dict[str, bool] = {}
|
28
|
+
|
29
|
+
|
30
|
+
# Singleton instance
|
31
|
+
component_cache = ComponentCache()
|
32
|
+
|
33
|
+
|
34
|
+
async def import_langflow_components():
|
35
|
+
"""Asynchronously discovers and loads all built-in Langflow components with module-level parallelization.
|
36
|
+
|
37
|
+
Scans the `lfx.components` package and its submodules in parallel, instantiates classes that are subclasses
|
38
|
+
of `Component` or `CustomComponent`, and generates their templates. Components are grouped by their
|
39
|
+
top-level subpackage name.
|
40
|
+
|
41
|
+
Returns:
|
42
|
+
A dictionary with a "components" key mapping top-level package names to their component templates.
|
43
|
+
"""
|
44
|
+
modules_dict = {}
|
45
|
+
try:
|
46
|
+
import lfx.components as components_pkg
|
47
|
+
except ImportError as e:
|
48
|
+
await logger.aerror(f"Failed to import langflow.components package: {e}", exc_info=True)
|
49
|
+
return {"components": modules_dict}
|
50
|
+
|
51
|
+
# Collect all module names to process
|
52
|
+
module_names = []
|
53
|
+
for _, modname, _ in pkgutil.walk_packages(components_pkg.__path__, prefix=components_pkg.__name__ + "."):
|
54
|
+
# Skip if the module is in the deactivated folder
|
55
|
+
if "deactivated" not in modname:
|
56
|
+
module_names.append(modname)
|
57
|
+
|
58
|
+
if not module_names:
|
59
|
+
return {"components": modules_dict}
|
60
|
+
|
61
|
+
# Create tasks for parallel module processing
|
62
|
+
tasks = [asyncio.to_thread(_process_single_module, modname) for modname in module_names]
|
63
|
+
|
64
|
+
# Wait for all modules to be processed
|
65
|
+
try:
|
66
|
+
module_results = await asyncio.gather(*tasks, return_exceptions=True)
|
67
|
+
except Exception as e: # noqa: BLE001
|
68
|
+
await logger.aerror(f"Error during parallel module processing: {e}", exc_info=True)
|
69
|
+
return {"components": modules_dict}
|
70
|
+
|
71
|
+
# Merge results from all modules
|
72
|
+
for result in module_results:
|
73
|
+
if isinstance(result, Exception):
|
74
|
+
await logger.awarning(f"Module processing failed: {result}")
|
75
|
+
continue
|
76
|
+
|
77
|
+
if result and isinstance(result, tuple) and len(result) == EXPECTED_RESULT_LENGTH:
|
78
|
+
top_level, components = result
|
79
|
+
if top_level and components:
|
80
|
+
if top_level not in modules_dict:
|
81
|
+
modules_dict[top_level] = {}
|
82
|
+
modules_dict[top_level].update(components)
|
83
|
+
|
84
|
+
return {"components": modules_dict}
|
85
|
+
|
86
|
+
|
87
|
+
def _process_single_module(modname: str) -> tuple[str, dict] | None:
|
88
|
+
"""Process a single module and return its components.
|
89
|
+
|
90
|
+
Args:
|
91
|
+
modname: The full module name to process
|
92
|
+
|
93
|
+
Returns:
|
94
|
+
A tuple of (top_level_package, components_dict) or None if processing failed
|
95
|
+
"""
|
96
|
+
try:
|
97
|
+
module = importlib.import_module(modname)
|
98
|
+
except (ImportError, AttributeError) as e:
|
99
|
+
logger.error(f"Error importing module {modname}: {e}", exc_info=True)
|
100
|
+
return None
|
101
|
+
# Extract the top-level subpackage name after "langflow.components."
|
102
|
+
# e.g., "langflow.components.Notion.add_content_to_page" -> "Notion"
|
103
|
+
mod_parts = modname.split(".")
|
104
|
+
if len(mod_parts) <= MIN_MODULE_PARTS:
|
105
|
+
return None
|
106
|
+
|
107
|
+
top_level = mod_parts[2]
|
108
|
+
module_components = {}
|
109
|
+
|
110
|
+
# Bind frequently used functions for small speed gain
|
111
|
+
_getattr = getattr
|
112
|
+
|
113
|
+
# Fast path: only check class objects defined in this module
|
114
|
+
failed_count = []
|
115
|
+
for name, obj in vars(module).items():
|
116
|
+
if not isinstance(obj, type):
|
117
|
+
continue
|
118
|
+
|
119
|
+
# Only consider classes defined in this module
|
120
|
+
if obj.__module__ != modname:
|
121
|
+
continue
|
122
|
+
|
123
|
+
# Check for required attributes
|
124
|
+
if not (
|
125
|
+
_getattr(obj, "code_class_base_inheritance", None) is not None
|
126
|
+
or _getattr(obj, "_code_class_base_inheritance", None) is not None
|
127
|
+
):
|
128
|
+
continue
|
129
|
+
|
130
|
+
try:
|
131
|
+
comp_instance = obj()
|
132
|
+
# modname is the full module name without the name of the obj
|
133
|
+
full_module_name = f"{modname}.{name}"
|
134
|
+
comp_template, _ = create_component_template(
|
135
|
+
component_extractor=comp_instance, module_name=full_module_name
|
136
|
+
)
|
137
|
+
component_name = obj.name if hasattr(obj, "name") and obj.name else name
|
138
|
+
module_components[component_name] = comp_template
|
139
|
+
except Exception as e: # noqa: BLE001
|
140
|
+
failed_count.append(f"{name}: {e}")
|
141
|
+
continue
|
142
|
+
|
143
|
+
if failed_count:
|
144
|
+
logger.warning(
|
145
|
+
f"Skipped {len(failed_count)} component class{'es' if len(failed_count) != 1 else ''} "
|
146
|
+
f"in module '{modname}' due to instantiation failure: {', '.join(failed_count)}"
|
147
|
+
)
|
148
|
+
logger.debug(f"Processed module {modname}")
|
149
|
+
return (top_level, module_components)
|
150
|
+
|
151
|
+
|
152
|
+
async def _determine_loading_strategy(settings_service: "SettingsService") -> dict:
|
153
|
+
"""Determines and executes the appropriate component loading strategy.
|
154
|
+
|
155
|
+
Args:
|
156
|
+
settings_service: Service containing loading configuration
|
157
|
+
|
158
|
+
Returns:
|
159
|
+
Dictionary containing loaded component types and templates
|
160
|
+
"""
|
161
|
+
component_cache.all_types_dict = {}
|
162
|
+
if settings_service.settings.lazy_load_components:
|
163
|
+
# Partial loading mode - just load component metadata
|
164
|
+
await logger.adebug("Using partial component loading")
|
165
|
+
component_cache.all_types_dict = await aget_component_metadata(settings_service.settings.components_path)
|
166
|
+
elif settings_service.settings.components_path:
|
167
|
+
# Traditional full loading - filter out base components path to only load custom components
|
168
|
+
custom_paths = [p for p in settings_service.settings.components_path if p != BASE_COMPONENTS_PATH]
|
169
|
+
if custom_paths:
|
170
|
+
component_cache.all_types_dict = await aget_all_types_dict(custom_paths)
|
171
|
+
|
172
|
+
# Log custom component loading stats
|
173
|
+
components_dict = component_cache.all_types_dict or {}
|
174
|
+
component_count = sum(len(comps) for comps in components_dict.get("components", {}).values())
|
175
|
+
if component_count > 0 and settings_service.settings.components_path:
|
176
|
+
await logger.adebug(
|
177
|
+
f"Built {component_count} custom components from {settings_service.settings.components_path}"
|
178
|
+
)
|
179
|
+
|
180
|
+
return component_cache.all_types_dict
|
181
|
+
|
182
|
+
|
183
|
+
async def get_and_cache_all_types_dict(
|
184
|
+
settings_service: "SettingsService",
|
185
|
+
):
|
186
|
+
"""Retrieves and caches the complete dictionary of component types and templates.
|
187
|
+
|
188
|
+
Supports both full and partial (lazy) loading. If the cache is empty, loads built-in Langflow
|
189
|
+
components and either fully loads all components or loads only their metadata, depending on the
|
190
|
+
lazy loading setting. Merges built-in and custom components into the cache and returns the
|
191
|
+
resulting dictionary.
|
192
|
+
"""
|
193
|
+
if component_cache.all_types_dict is None:
|
194
|
+
await logger.adebug("Building components cache")
|
195
|
+
|
196
|
+
langflow_components = await import_langflow_components()
|
197
|
+
custom_components_dict = await _determine_loading_strategy(settings_service)
|
198
|
+
|
199
|
+
# merge the dicts
|
200
|
+
component_cache.all_types_dict = {
|
201
|
+
**langflow_components["components"],
|
202
|
+
**custom_components_dict,
|
203
|
+
}
|
204
|
+
component_count = sum(len(comps) for comps in component_cache.all_types_dict.values())
|
205
|
+
await logger.adebug(f"Loaded {component_count} components")
|
206
|
+
return component_cache.all_types_dict
|
207
|
+
|
208
|
+
|
209
|
+
async def aget_all_types_dict(components_paths: list[str]):
|
210
|
+
"""Get all types dictionary with full component loading."""
|
211
|
+
return await abuild_custom_components(components_paths=components_paths)
|
212
|
+
|
213
|
+
|
214
|
+
async def aget_component_metadata(components_paths: list[str]):
|
215
|
+
"""Asynchronously retrieves minimal metadata for all components in the specified paths.
|
216
|
+
|
217
|
+
Builds a dictionary containing basic information (such as display name, type, and description) for
|
218
|
+
each discovered component, without loading their full templates. Each component entry is marked as
|
219
|
+
`lazy_loaded` to indicate that only metadata has been loaded.
|
220
|
+
|
221
|
+
Args:
|
222
|
+
components_paths: List of filesystem paths to search for component types and names.
|
223
|
+
|
224
|
+
Returns:
|
225
|
+
A dictionary with component types as keys and their corresponding component metadata as values.
|
226
|
+
"""
|
227
|
+
# This builds a skeleton of the all_types_dict with just basic component info
|
228
|
+
|
229
|
+
components_dict: dict = {"components": {}}
|
230
|
+
|
231
|
+
if not components_paths:
|
232
|
+
return components_dict
|
233
|
+
|
234
|
+
# Get all component types
|
235
|
+
component_types = await discover_component_types(components_paths)
|
236
|
+
await logger.adebug(f"Discovered {len(component_types)} component types: {', '.join(component_types)}")
|
237
|
+
|
238
|
+
# For each component type directory
|
239
|
+
for component_type in component_types:
|
240
|
+
components_dict["components"][component_type] = {}
|
241
|
+
|
242
|
+
# Get list of components in this type
|
243
|
+
component_names = await discover_component_names(component_type, components_paths)
|
244
|
+
await logger.adebug(f"Found {len(component_names)} components for type {component_type}")
|
245
|
+
|
246
|
+
# Create stub entries with just basic metadata
|
247
|
+
for name in component_names:
|
248
|
+
# Get minimal metadata for component
|
249
|
+
metadata = await get_component_minimal_metadata(component_type, name, components_paths)
|
250
|
+
|
251
|
+
if metadata:
|
252
|
+
components_dict["components"][component_type][name] = metadata
|
253
|
+
# Mark as needing full loading
|
254
|
+
components_dict["components"][component_type][name]["lazy_loaded"] = True
|
255
|
+
|
256
|
+
return components_dict
|
257
|
+
|
258
|
+
|
259
|
+
async def discover_component_types(components_paths: list[str]) -> list[str]:
|
260
|
+
"""Discover available component types by scanning directories."""
|
261
|
+
component_types: set[str] = set()
|
262
|
+
|
263
|
+
for path in components_paths:
|
264
|
+
path_obj = Path(path)
|
265
|
+
if not path_obj.exists():
|
266
|
+
continue
|
267
|
+
|
268
|
+
for item in path_obj.iterdir():
|
269
|
+
# Only include directories that don't start with _ or .
|
270
|
+
if item.is_dir() and not item.name.startswith(("_", ".")):
|
271
|
+
component_types.add(item.name)
|
272
|
+
|
273
|
+
# Add known types that might not be in directories
|
274
|
+
standard_types = {
|
275
|
+
"agents",
|
276
|
+
"chains",
|
277
|
+
"embeddings",
|
278
|
+
"llms",
|
279
|
+
"memories",
|
280
|
+
"prompts",
|
281
|
+
"tools",
|
282
|
+
"retrievers",
|
283
|
+
"textsplitters",
|
284
|
+
"toolkits",
|
285
|
+
"utilities",
|
286
|
+
"vectorstores",
|
287
|
+
"custom_components",
|
288
|
+
"documentloaders",
|
289
|
+
"outputparsers",
|
290
|
+
"wrappers",
|
291
|
+
}
|
292
|
+
|
293
|
+
component_types.update(standard_types)
|
294
|
+
|
295
|
+
return sorted(component_types)
|
296
|
+
|
297
|
+
|
298
|
+
async def discover_component_names(component_type: str, components_paths: list[str]) -> list[str]:
|
299
|
+
"""Discover component names for a specific type by scanning directories."""
|
300
|
+
component_names: set[str] = set()
|
301
|
+
|
302
|
+
for path in components_paths:
|
303
|
+
type_dir = Path(path) / component_type
|
304
|
+
|
305
|
+
if type_dir.exists():
|
306
|
+
for filename in type_dir.iterdir():
|
307
|
+
# Get Python files that don't start with __
|
308
|
+
if filename.name.endswith(".py") and not filename.name.startswith("__"):
|
309
|
+
component_name = filename.name[:-3] # Remove .py extension
|
310
|
+
component_names.add(component_name)
|
311
|
+
|
312
|
+
return sorted(component_names)
|
313
|
+
|
314
|
+
|
315
|
+
async def get_component_minimal_metadata(component_type: str, component_name: str, components_paths: list[str]):
|
316
|
+
"""Extract minimal metadata for a component without loading its full implementation."""
|
317
|
+
# Create a more complete metadata structure that the UI needs
|
318
|
+
metadata = {
|
319
|
+
"display_name": component_name.replace("_", " ").title(),
|
320
|
+
"name": component_name,
|
321
|
+
"type": component_type,
|
322
|
+
"description": f"A {component_type} component (not fully loaded)",
|
323
|
+
"template": {
|
324
|
+
"_type": component_type,
|
325
|
+
"inputs": {},
|
326
|
+
"outputs": {},
|
327
|
+
"output_types": [],
|
328
|
+
"documentation": f"A {component_type} component",
|
329
|
+
"display_name": component_name.replace("_", " ").title(),
|
330
|
+
"base_classes": [component_type],
|
331
|
+
},
|
332
|
+
}
|
333
|
+
|
334
|
+
# Try to find the file to verify it exists
|
335
|
+
component_path = None
|
336
|
+
for path in components_paths:
|
337
|
+
candidate_path = Path(path) / component_type / f"{component_name}.py"
|
338
|
+
if candidate_path.exists():
|
339
|
+
component_path = candidate_path
|
340
|
+
break
|
341
|
+
|
342
|
+
if not component_path:
|
343
|
+
return None
|
344
|
+
|
345
|
+
return metadata
|
346
|
+
|
347
|
+
|
348
|
+
async def ensure_component_loaded(component_type: str, component_name: str, settings_service: "SettingsService"):
|
349
|
+
"""Ensure a component is fully loaded if it was only partially loaded."""
|
350
|
+
# If already fully loaded, return immediately
|
351
|
+
component_key = f"{component_type}:{component_name}"
|
352
|
+
if component_key in component_cache.fully_loaded_components:
|
353
|
+
return
|
354
|
+
|
355
|
+
# If we don't have a cache or the component doesn't exist in the cache, nothing to do
|
356
|
+
if (
|
357
|
+
not component_cache.all_types_dict
|
358
|
+
or "components" not in component_cache.all_types_dict
|
359
|
+
or component_type not in component_cache.all_types_dict["components"]
|
360
|
+
or component_name not in component_cache.all_types_dict["components"][component_type]
|
361
|
+
):
|
362
|
+
return
|
363
|
+
|
364
|
+
# Check if component is marked for lazy loading
|
365
|
+
if component_cache.all_types_dict["components"][component_type][component_name].get("lazy_loaded", False):
|
366
|
+
await logger.adebug(f"Fully loading component {component_type}:{component_name}")
|
367
|
+
|
368
|
+
# Load just this specific component
|
369
|
+
full_component = await load_single_component(
|
370
|
+
component_type, component_name, settings_service.settings.components_path
|
371
|
+
)
|
372
|
+
|
373
|
+
if full_component:
|
374
|
+
# Replace the stub with the fully loaded component
|
375
|
+
component_cache.all_types_dict["components"][component_type][component_name] = full_component
|
376
|
+
# Remove lazy_loaded flag if it exists
|
377
|
+
if "lazy_loaded" in component_cache.all_types_dict["components"][component_type][component_name]:
|
378
|
+
del component_cache.all_types_dict["components"][component_type][component_name]["lazy_loaded"]
|
379
|
+
|
380
|
+
# Mark as fully loaded
|
381
|
+
component_cache.fully_loaded_components[component_key] = True
|
382
|
+
await logger.adebug(f"Component {component_type}:{component_name} fully loaded")
|
383
|
+
else:
|
384
|
+
await logger.awarning(f"Failed to fully load component {component_type}:{component_name}")
|
385
|
+
|
386
|
+
|
387
|
+
async def load_single_component(component_type: str, component_name: str, components_paths: list[str]):
|
388
|
+
"""Load a single component fully."""
|
389
|
+
from lfx.custom.utils import get_single_component_dict
|
390
|
+
|
391
|
+
try:
|
392
|
+
# Delegate to a more specific function that knows how to load
|
393
|
+
# a single component of a specific type
|
394
|
+
return await get_single_component_dict(component_type, component_name, components_paths)
|
395
|
+
except (ImportError, ModuleNotFoundError) as e:
|
396
|
+
# Handle issues with importing the component or its dependencies
|
397
|
+
await logger.aerror(f"Import error loading component {component_type}:{component_name}: {e!s}")
|
398
|
+
return None
|
399
|
+
except (AttributeError, TypeError) as e:
|
400
|
+
# Handle issues with component structure or type errors
|
401
|
+
await logger.aerror(f"Component structure error for {component_type}:{component_name}: {e!s}")
|
402
|
+
return None
|
403
|
+
except FileNotFoundError as e:
|
404
|
+
# Handle missing files
|
405
|
+
await logger.aerror(f"File not found for component {component_type}:{component_name}: {e!s}")
|
406
|
+
return None
|
407
|
+
except ValueError as e:
|
408
|
+
# Handle invalid values or configurations
|
409
|
+
await logger.aerror(f"Invalid configuration for component {component_type}:{component_name}: {e!s}")
|
410
|
+
return None
|
411
|
+
except (KeyError, IndexError) as e:
|
412
|
+
# Handle data structure access errors
|
413
|
+
await logger.aerror(f"Data structure error for component {component_type}:{component_name}: {e!s}")
|
414
|
+
return None
|
415
|
+
except RuntimeError as e:
|
416
|
+
# Handle runtime errors
|
417
|
+
await logger.aerror(f"Runtime error loading component {component_type}:{component_name}: {e!s}")
|
418
|
+
await logger.adebug("Full traceback for runtime error", exc_info=True)
|
419
|
+
return None
|
420
|
+
except OSError as e:
|
421
|
+
# Handle OS-related errors (file system, permissions, etc.)
|
422
|
+
await logger.aerror(f"OS error loading component {component_type}:{component_name}: {e!s}")
|
423
|
+
return None
|
424
|
+
|
425
|
+
|
426
|
+
# Also add a utility function to load specific component types
|
427
|
+
async def get_type_dict(component_type: str, settings_service: Optional["SettingsService"] = None):
|
428
|
+
"""Get a specific component type dictionary, loading if needed."""
|
429
|
+
if settings_service is None:
|
430
|
+
# Import here to avoid circular imports
|
431
|
+
from langflow.services.deps import get_settings_service
|
432
|
+
|
433
|
+
settings_service = get_settings_service()
|
434
|
+
|
435
|
+
# Make sure all_types_dict is loaded (at least partially)
|
436
|
+
if component_cache.all_types_dict is None:
|
437
|
+
await get_and_cache_all_types_dict(settings_service)
|
438
|
+
|
439
|
+
# Check if component type exists in the cache
|
440
|
+
if (
|
441
|
+
component_cache.all_types_dict
|
442
|
+
and "components" in component_cache.all_types_dict
|
443
|
+
and component_type in component_cache.all_types_dict["components"]
|
444
|
+
):
|
445
|
+
# If in lazy mode, ensure all components of this type are fully loaded
|
446
|
+
if settings_service.settings.lazy_load_components:
|
447
|
+
for component_name in list(component_cache.all_types_dict["components"][component_type].keys()):
|
448
|
+
await ensure_component_loaded(component_type, component_name, settings_service)
|
449
|
+
|
450
|
+
return component_cache.all_types_dict["components"][component_type]
|
451
|
+
|
452
|
+
return {}
|
453
|
+
|
454
|
+
|
455
|
+
# TypeError: unhashable type: 'list'
|
456
|
+
def key_func(*args, **kwargs):
|
457
|
+
# components_paths is a list of paths
|
458
|
+
return json.dumps(args) + json.dumps(kwargs)
|
459
|
+
|
460
|
+
|
461
|
+
async def aget_all_components(components_paths, *, as_dict=False):
|
462
|
+
"""Get all components names combining native and custom components."""
|
463
|
+
all_types_dict = await aget_all_types_dict(components_paths)
|
464
|
+
components = {} if as_dict else []
|
465
|
+
for category in all_types_dict.values():
|
466
|
+
for component in category.values():
|
467
|
+
component["name"] = component["display_name"]
|
468
|
+
if as_dict:
|
469
|
+
components[component["name"]] = component
|
470
|
+
else:
|
471
|
+
components.append(component)
|
472
|
+
return components
|
473
|
+
|
474
|
+
|
475
|
+
def get_all_components(components_paths, *, as_dict=False):
|
476
|
+
"""Get all components names combining native and custom components."""
|
477
|
+
# Import here to avoid circular imports
|
478
|
+
from lfx.custom.utils import build_custom_components
|
479
|
+
|
480
|
+
all_types_dict = build_custom_components(components_paths=components_paths)
|
481
|
+
components = [] if not as_dict else {}
|
482
|
+
for category in all_types_dict.values():
|
483
|
+
for component in category.values():
|
484
|
+
component["name"] = component["display_name"]
|
485
|
+
if as_dict:
|
486
|
+
components[component["name"]] = component
|
487
|
+
else:
|
488
|
+
components.append(component)
|
489
|
+
return components
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# This module is used to import any langchain class by name.
|
2
|
+
|
3
|
+
import importlib
|
4
|
+
from typing import Any
|
5
|
+
|
6
|
+
|
7
|
+
def import_module(module_path: str) -> Any:
|
8
|
+
"""Import module from module path."""
|
9
|
+
if "from" not in module_path:
|
10
|
+
# Import the module using the module path
|
11
|
+
import warnings
|
12
|
+
|
13
|
+
with warnings.catch_warnings():
|
14
|
+
warnings.filterwarnings(
|
15
|
+
"ignore", message="Support for class-based `config` is deprecated", category=DeprecationWarning
|
16
|
+
)
|
17
|
+
warnings.filterwarnings("ignore", message="Valid config keys have changed in V2", category=UserWarning)
|
18
|
+
return importlib.import_module(module_path)
|
19
|
+
# Split the module path into its components
|
20
|
+
_, module_path, _, object_name = module_path.split()
|
21
|
+
|
22
|
+
# Import the module using the module path
|
23
|
+
import warnings
|
24
|
+
|
25
|
+
with warnings.catch_warnings():
|
26
|
+
warnings.filterwarnings(
|
27
|
+
"ignore", message="Support for class-based `config` is deprecated", category=DeprecationWarning
|
28
|
+
)
|
29
|
+
warnings.filterwarnings("ignore", message="Valid config keys have changed in V2", category=UserWarning)
|
30
|
+
module = importlib.import_module(module_path)
|
31
|
+
|
32
|
+
return getattr(module, object_name)
|
33
|
+
|
34
|
+
|
35
|
+
def import_class(class_path: str) -> Any:
|
36
|
+
"""Import class from class path."""
|
37
|
+
module_path, class_name = class_path.rsplit(".", 1)
|
38
|
+
module = import_module(module_path)
|
39
|
+
return getattr(module, class_name)
|