lfx-nightly 0.2.0.dev25__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.
Potentially problematic release.
This version of lfx-nightly might be problematic. Click here for more details.
- lfx/__init__.py +0 -0
- lfx/__main__.py +25 -0
- lfx/_assets/component_index.json +1 -0
- lfx/base/__init__.py +0 -0
- lfx/base/agents/__init__.py +0 -0
- lfx/base/agents/agent.py +375 -0
- lfx/base/agents/altk_base_agent.py +380 -0
- lfx/base/agents/altk_tool_wrappers.py +565 -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 +430 -0
- lfx/base/agents/utils.py +237 -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 +2584 -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 +810 -0
- lfx/base/data/docling_utils.py +338 -0
- lfx/base/data/storage_utils.py +192 -0
- lfx/base/data/utils.py +362 -0
- lfx/base/datastax/__init__.py +5 -0
- lfx/base/datastax/astradb_base.py +896 -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/embeddings_class.py +113 -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 +21 -0
- lfx/base/io/text.py +22 -0
- lfx/base/knowledge_bases/__init__.py +3 -0
- lfx/base/knowledge_bases/knowledge_base_utils.py +137 -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 +1659 -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 +51 -0
- lfx/base/models/aws_constants.py +151 -0
- lfx/base/models/chat_result.py +76 -0
- lfx/base/models/cometapi_constants.py +54 -0
- lfx/base/models/google_generative_ai_constants.py +70 -0
- lfx/base/models/google_generative_ai_model.py +38 -0
- lfx/base/models/groq_constants.py +150 -0
- lfx/base/models/groq_model_discovery.py +265 -0
- lfx/base/models/model.py +375 -0
- lfx/base/models/model_input_constants.py +378 -0
- lfx/base/models/model_metadata.py +41 -0
- lfx/base/models/model_utils.py +108 -0
- lfx/base/models/novita_constants.py +35 -0
- lfx/base/models/ollama_constants.py +52 -0
- lfx/base/models/openai_constants.py +129 -0
- lfx/base/models/sambanova_constants.py +18 -0
- lfx/base/models/watsonx_constants.py +36 -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 +698 -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 +327 -0
- lfx/cli/common.py +650 -0
- lfx/cli/run.py +506 -0
- lfx/cli/script_loader.py +289 -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 +428 -0
- lfx/components/_importing.py +42 -0
- lfx/components/agentql/__init__.py +3 -0
- lfx/components/agentql/agentql_api.py +151 -0
- lfx/components/aiml/__init__.py +37 -0
- lfx/components/aiml/aiml.py +115 -0
- lfx/components/aiml/aiml_embeddings.py +37 -0
- lfx/components/altk/__init__.py +34 -0
- lfx/components/altk/altk_agent.py +193 -0
- lfx/components/amazon/__init__.py +36 -0
- lfx/components/amazon/amazon_bedrock_converse.py +195 -0
- lfx/components/amazon/amazon_bedrock_embedding.py +109 -0
- lfx/components/amazon/amazon_bedrock_model.py +130 -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 +169 -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 +169 -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/cometapi/__init__.py +32 -0
- lfx/components/cometapi/cometapi.py +166 -0
- lfx/components/composio/__init__.py +222 -0
- lfx/components/composio/agentql_composio.py +11 -0
- lfx/components/composio/agiled_composio.py +11 -0
- lfx/components/composio/airtable_composio.py +11 -0
- lfx/components/composio/apollo_composio.py +11 -0
- lfx/components/composio/asana_composio.py +11 -0
- lfx/components/composio/attio_composio.py +11 -0
- lfx/components/composio/bitbucket_composio.py +11 -0
- lfx/components/composio/bolna_composio.py +11 -0
- lfx/components/composio/brightdata_composio.py +11 -0
- lfx/components/composio/calendly_composio.py +11 -0
- lfx/components/composio/canva_composio.py +11 -0
- lfx/components/composio/canvas_composio.py +11 -0
- lfx/components/composio/coda_composio.py +11 -0
- lfx/components/composio/composio_api.py +278 -0
- lfx/components/composio/contentful_composio.py +11 -0
- lfx/components/composio/digicert_composio.py +11 -0
- lfx/components/composio/discord_composio.py +11 -0
- lfx/components/composio/dropbox_compnent.py +11 -0
- lfx/components/composio/elevenlabs_composio.py +11 -0
- lfx/components/composio/exa_composio.py +11 -0
- lfx/components/composio/figma_composio.py +11 -0
- lfx/components/composio/finage_composio.py +11 -0
- lfx/components/composio/firecrawl_composio.py +11 -0
- lfx/components/composio/fireflies_composio.py +11 -0
- lfx/components/composio/fixer_composio.py +11 -0
- lfx/components/composio/flexisign_composio.py +11 -0
- lfx/components/composio/freshdesk_composio.py +11 -0
- lfx/components/composio/github_composio.py +11 -0
- lfx/components/composio/gmail_composio.py +38 -0
- lfx/components/composio/googlebigquery_composio.py +11 -0
- lfx/components/composio/googlecalendar_composio.py +11 -0
- lfx/components/composio/googleclassroom_composio.py +11 -0
- lfx/components/composio/googledocs_composio.py +11 -0
- lfx/components/composio/googlemeet_composio.py +11 -0
- lfx/components/composio/googlesheets_composio.py +11 -0
- lfx/components/composio/googletasks_composio.py +8 -0
- lfx/components/composio/heygen_composio.py +11 -0
- lfx/components/composio/instagram_composio.py +11 -0
- lfx/components/composio/jira_composio.py +11 -0
- lfx/components/composio/jotform_composio.py +11 -0
- lfx/components/composio/klaviyo_composio.py +11 -0
- lfx/components/composio/linear_composio.py +11 -0
- lfx/components/composio/listennotes_composio.py +11 -0
- lfx/components/composio/mem0_composio.py +11 -0
- lfx/components/composio/miro_composio.py +11 -0
- lfx/components/composio/missive_composio.py +11 -0
- lfx/components/composio/notion_composio.py +11 -0
- lfx/components/composio/onedrive_composio.py +11 -0
- lfx/components/composio/outlook_composio.py +11 -0
- lfx/components/composio/pandadoc_composio.py +11 -0
- lfx/components/composio/peopledatalabs_composio.py +11 -0
- lfx/components/composio/perplexityai_composio.py +11 -0
- lfx/components/composio/reddit_composio.py +11 -0
- lfx/components/composio/serpapi_composio.py +11 -0
- lfx/components/composio/slack_composio.py +11 -0
- lfx/components/composio/slackbot_composio.py +11 -0
- lfx/components/composio/snowflake_composio.py +11 -0
- lfx/components/composio/supabase_composio.py +11 -0
- lfx/components/composio/tavily_composio.py +11 -0
- lfx/components/composio/timelinesai_composio.py +11 -0
- lfx/components/composio/todoist_composio.py +11 -0
- lfx/components/composio/wrike_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 +108 -0
- lfx/components/crewai/hierarchical_crew.py +47 -0
- lfx/components/crewai/hierarchical_task.py +45 -0
- lfx/components/crewai/sequential_crew.py +53 -0
- lfx/components/crewai/sequential_task.py +74 -0
- lfx/components/crewai/sequential_task_agent.py +144 -0
- lfx/components/cuga/__init__.py +34 -0
- lfx/components/cuga/cuga_agent.py +730 -0
- lfx/components/custom_component/__init__.py +34 -0
- lfx/components/custom_component/custom_component.py +31 -0
- lfx/components/data/__init__.py +114 -0
- lfx/components/data_source/__init__.py +58 -0
- lfx/components/data_source/api_request.py +577 -0
- lfx/components/data_source/csv_to_data.py +101 -0
- lfx/components/data_source/json_to_data.py +106 -0
- lfx/components/data_source/mock_data.py +398 -0
- lfx/components/data_source/news_search.py +166 -0
- lfx/components/data_source/rss.py +71 -0
- lfx/components/data_source/sql_executor.py +101 -0
- lfx/components/data_source/url.py +311 -0
- lfx/components/data_source/web_search.py +326 -0
- lfx/components/datastax/__init__.py +76 -0
- lfx/components/datastax/astradb_assistant_manager.py +307 -0
- lfx/components/datastax/astradb_chatmemory.py +40 -0
- lfx/components/datastax/astradb_cql.py +288 -0
- lfx/components/datastax/astradb_graph.py +217 -0
- lfx/components/datastax/astradb_tool.py +378 -0
- lfx/components/datastax/astradb_vectorize.py +122 -0
- lfx/components/datastax/astradb_vectorstore.py +449 -0
- lfx/components/datastax/create_assistant.py +59 -0
- lfx/components/datastax/create_thread.py +33 -0
- lfx/components/datastax/dotenv.py +36 -0
- lfx/components/datastax/get_assistant.py +38 -0
- lfx/components/datastax/getenvvar.py +31 -0
- lfx/components/datastax/graph_rag.py +141 -0
- lfx/components/datastax/hcd.py +315 -0
- lfx/components/datastax/list_assistants.py +26 -0
- lfx/components/datastax/run.py +90 -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 +238 -0
- lfx/components/docling/docling_remote.py +195 -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 +789 -0
- lfx/components/elastic/opensearch_multimodal.py +1575 -0
- lfx/components/embeddings/__init__.py +37 -0
- lfx/components/embeddings/similarity.py +77 -0
- lfx/components/embeddings/text_embedder.py +65 -0
- lfx/components/exa/__init__.py +3 -0
- lfx/components/exa/exa_search.py +68 -0
- lfx/components/files_and_knowledge/__init__.py +47 -0
- lfx/components/files_and_knowledge/directory.py +113 -0
- lfx/components/files_and_knowledge/file.py +841 -0
- lfx/components/files_and_knowledge/ingestion.py +694 -0
- lfx/components/files_and_knowledge/retrieval.py +264 -0
- lfx/components/files_and_knowledge/save_file.py +746 -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/flow_controls/__init__.py +58 -0
- lfx/components/flow_controls/conditional_router.py +208 -0
- lfx/components/flow_controls/data_conditional_router.py +126 -0
- lfx/components/flow_controls/flow_tool.py +111 -0
- lfx/components/flow_controls/listen.py +29 -0
- lfx/components/flow_controls/loop.py +163 -0
- lfx/components/flow_controls/notify.py +88 -0
- lfx/components/flow_controls/pass_message.py +36 -0
- lfx/components/flow_controls/run_flow.py +108 -0
- lfx/components/flow_controls/sub_flow.py +115 -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 +193 -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 +144 -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 +143 -0
- lfx/components/helpers/__init__.py +154 -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 +199 -0
- lfx/components/huggingface/huggingface_inference_api.py +106 -0
- lfx/components/ibm/__init__.py +34 -0
- lfx/components/ibm/watsonx.py +207 -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 +40 -0
- lfx/components/input_output/chat.py +109 -0
- lfx/components/input_output/chat_output.py +184 -0
- lfx/components/input_output/text.py +27 -0
- lfx/components/input_output/text_output.py +29 -0
- lfx/components/input_output/webhook.py +56 -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/knowledge_bases/__init__.py +89 -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 +175 -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 +100 -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/llm_operations/__init__.py +46 -0
- lfx/components/llm_operations/batch_run.py +205 -0
- lfx/components/llm_operations/lambda_filter.py +218 -0
- lfx/components/llm_operations/llm_conditional_router.py +421 -0
- lfx/components/llm_operations/llm_selector.py +499 -0
- lfx/components/llm_operations/structured_output.py +244 -0
- lfx/components/lmstudio/__init__.py +34 -0
- lfx/components/lmstudio/lmstudioembeddings.py +89 -0
- lfx/components/lmstudio/lmstudiomodel.py +133 -0
- lfx/components/logic/__init__.py +181 -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 +147 -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 +89 -0
- lfx/components/models_and_agents/__init__.py +49 -0
- lfx/components/models_and_agents/agent.py +644 -0
- lfx/components/models_and_agents/embedding_model.py +423 -0
- lfx/components/models_and_agents/language_model.py +398 -0
- lfx/components/models_and_agents/mcp_component.py +594 -0
- lfx/components/models_and_agents/memory.py +268 -0
- lfx/components/models_and_agents/prompt.py +67 -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 +151 -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 +548 -0
- lfx/components/ollama/ollama_embeddings.py +103 -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 +104 -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 +72 -0
- lfx/components/processing/alter_metadata.py +109 -0
- lfx/components/processing/combine_text.py +40 -0
- lfx/components/processing/converter.py +248 -0
- lfx/components/processing/create_data.py +111 -0
- lfx/components/processing/create_list.py +40 -0
- lfx/components/processing/data_operations.py +528 -0
- lfx/components/processing/data_to_dataframe.py +71 -0
- lfx/components/processing/dataframe_operations.py +313 -0
- lfx/components/processing/dataframe_to_toolset.py +259 -0
- lfx/components/processing/dynamic_create_data.py +357 -0
- lfx/components/processing/extract_key.py +54 -0
- lfx/components/processing/filter_data.py +43 -0
- lfx/components/processing/filter_data_values.py +89 -0
- lfx/components/processing/json_cleaner.py +104 -0
- lfx/components/processing/merge_data.py +91 -0
- lfx/components/processing/message_to_data.py +37 -0
- lfx/components/processing/output_parser.py +46 -0
- lfx/components/processing/parse_data.py +71 -0
- lfx/components/processing/parse_dataframe.py +69 -0
- lfx/components/processing/parse_json_data.py +91 -0
- lfx/components/processing/parser.py +148 -0
- lfx/components/processing/regex.py +83 -0
- lfx/components/processing/select_data.py +49 -0
- lfx/components/processing/split_text.py +141 -0
- lfx/components/processing/store_message.py +91 -0
- lfx/components/processing/update_data.py +161 -0
- lfx/components/prototypes/__init__.py +35 -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 +66 -0
- lfx/components/tools/calculator.py +109 -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 +328 -0
- lfx/components/tools/python_repl.py +98 -0
- lfx/components/tools/search_api.py +88 -0
- lfx/components/tools/searxng.py +145 -0
- lfx/components/tools/serp_api.py +120 -0
- lfx/components/tools/tavily_search_tool.py +345 -0
- lfx/components/tools/wikidata_api.py +103 -0
- lfx/components/tools/wikipedia_api.py +50 -0
- lfx/components/tools/yahoo_finance.py +130 -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 +301 -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 +191 -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/utilities/__init__.py +43 -0
- lfx/components/utilities/calculator_core.py +89 -0
- lfx/components/utilities/current_date.py +42 -0
- lfx/components/utilities/id_generator.py +42 -0
- lfx/components/utilities/python_repl_core.py +98 -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 +34 -0
- lfx/components/vectorstores/local_db.py +270 -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/vlmrun/__init__.py +34 -0
- lfx/components/vlmrun/vlmrun_transcription.py +224 -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 +206 -0
- lfx/components/zep/__init__.py +3 -0
- lfx/components/zep/zep.py +45 -0
- lfx/constants.py +6 -0
- lfx/custom/__init__.py +7 -0
- lfx/custom/attributes.py +87 -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 +1890 -0
- lfx/custom/custom_component/component_with_cache.py +8 -0
- lfx/custom/custom_component/custom_component.py +650 -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 +523 -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 +216 -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 +300 -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 +2298 -0
- lfx/graph/graph/constants.py +63 -0
- lfx/graph/graph/runnable_vertices_manager.py +133 -0
- lfx/graph/graph/schema.py +53 -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 +250 -0
- lfx/graph/utils.py +206 -0
- lfx/graph/vertex/__init__.py +0 -0
- lfx/graph/vertex/base.py +826 -0
- lfx/graph/vertex/constants.py +0 -0
- lfx/graph/vertex/exceptions.py +4 -0
- lfx/graph/vertex/param_handler.py +316 -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 +141 -0
- lfx/helpers/base_model.py +71 -0
- lfx/helpers/custom.py +13 -0
- lfx/helpers/data.py +167 -0
- lfx/helpers/flow.py +308 -0
- lfx/inputs/__init__.py +68 -0
- lfx/inputs/constants.py +2 -0
- lfx/inputs/input_mixin.py +352 -0
- lfx/inputs/inputs.py +718 -0
- lfx/inputs/validators.py +19 -0
- lfx/interface/__init__.py +6 -0
- lfx/interface/components.py +897 -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 +317 -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 +295 -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 +411 -0
- lfx/logging/__init__.py +11 -0
- lfx/logging/logger.py +24 -0
- lfx/memory/__init__.py +70 -0
- lfx/memory/stubs.py +302 -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/cross_module.py +80 -0
- lfx/schema/data.py +309 -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 +184 -0
- lfx/schema/json_schema.py +186 -0
- lfx/schema/log.py +62 -0
- lfx/schema/message.py +493 -0
- lfx/schema/openai_responses_schemas.py +74 -0
- lfx/schema/properties.py +41 -0
- lfx/schema/schema.py +180 -0
- lfx/schema/serialize.py +13 -0
- lfx/schema/table.py +142 -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 +26 -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/database/__init__.py +5 -0
- lfx/services/database/service.py +25 -0
- lfx/services/deps.py +194 -0
- lfx/services/factory.py +19 -0
- lfx/services/initialize.py +19 -0
- lfx/services/interfaces.py +103 -0
- lfx/services/manager.py +185 -0
- lfx/services/mcp_composer/__init__.py +6 -0
- lfx/services/mcp_composer/factory.py +16 -0
- lfx/services/mcp_composer/service.py +1441 -0
- lfx/services/schema.py +21 -0
- lfx/services/session.py +87 -0
- lfx/services/settings/__init__.py +3 -0
- lfx/services/settings/auth.py +133 -0
- lfx/services/settings/base.py +668 -0
- lfx/services/settings/constants.py +43 -0
- lfx/services/settings/factory.py +23 -0
- lfx/services/settings/feature_flags.py +11 -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 +185 -0
- lfx/services/storage/service.py +177 -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 +260 -0
- lfx/template/field/prompt.py +15 -0
- lfx/template/frontend_node/__init__.py +6 -0
- lfx/template/frontend_node/base.py +214 -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 +233 -0
- lfx/utils/data_structure.py +212 -0
- lfx/utils/exceptions.py +22 -0
- lfx/utils/helpers.py +34 -0
- lfx/utils/image.py +79 -0
- lfx/utils/langflow_utils.py +52 -0
- lfx/utils/lazy_load.py +15 -0
- lfx/utils/request_utils.py +18 -0
- lfx/utils/schemas.py +139 -0
- lfx/utils/ssrf_protection.py +384 -0
- lfx/utils/util.py +626 -0
- lfx/utils/util_strings.py +56 -0
- lfx/utils/validate_cloud.py +26 -0
- lfx/utils/version.py +24 -0
- lfx_nightly-0.2.0.dev25.dist-info/METADATA +312 -0
- lfx_nightly-0.2.0.dev25.dist-info/RECORD +769 -0
- lfx_nightly-0.2.0.dev25.dist-info/WHEEL +4 -0
- lfx_nightly-0.2.0.dev25.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from pydantic.v1 import SecretStr
|
|
3
|
+
from typing_extensions import override
|
|
4
|
+
|
|
5
|
+
from lfx.base.models.model import LCModelComponent
|
|
6
|
+
from lfx.field_typing import LanguageModel
|
|
7
|
+
from lfx.field_typing.range_spec import RangeSpec
|
|
8
|
+
from lfx.inputs.inputs import BoolInput, DictInput, DropdownInput, IntInput, SecretStrInput, SliderInput, StrInput
|
|
9
|
+
|
|
10
|
+
DEEPSEEK_MODELS = ["deepseek-chat"]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DeepSeekModelComponent(LCModelComponent):
|
|
14
|
+
display_name = "DeepSeek"
|
|
15
|
+
description = "Generate text using DeepSeek LLMs."
|
|
16
|
+
icon = "DeepSeek"
|
|
17
|
+
|
|
18
|
+
inputs = [
|
|
19
|
+
*LCModelComponent.get_base_inputs(),
|
|
20
|
+
IntInput(
|
|
21
|
+
name="max_tokens",
|
|
22
|
+
display_name="Max Tokens",
|
|
23
|
+
advanced=True,
|
|
24
|
+
info="Maximum number of tokens to generate. Set to 0 for unlimited.",
|
|
25
|
+
range_spec=RangeSpec(min=0, max=128000),
|
|
26
|
+
),
|
|
27
|
+
DictInput(
|
|
28
|
+
name="model_kwargs",
|
|
29
|
+
display_name="Model Kwargs",
|
|
30
|
+
advanced=True,
|
|
31
|
+
info="Additional keyword arguments to pass to the model.",
|
|
32
|
+
),
|
|
33
|
+
BoolInput(
|
|
34
|
+
name="json_mode",
|
|
35
|
+
display_name="JSON Mode",
|
|
36
|
+
advanced=True,
|
|
37
|
+
info="If True, it will output JSON regardless of passing a schema.",
|
|
38
|
+
),
|
|
39
|
+
DropdownInput(
|
|
40
|
+
name="model_name",
|
|
41
|
+
display_name="Model Name",
|
|
42
|
+
info="DeepSeek model to use",
|
|
43
|
+
options=DEEPSEEK_MODELS,
|
|
44
|
+
value="deepseek-chat",
|
|
45
|
+
refresh_button=True,
|
|
46
|
+
),
|
|
47
|
+
StrInput(
|
|
48
|
+
name="api_base",
|
|
49
|
+
display_name="DeepSeek API Base",
|
|
50
|
+
advanced=True,
|
|
51
|
+
info="Base URL for API requests. Defaults to https://api.deepseek.com",
|
|
52
|
+
value="https://api.deepseek.com",
|
|
53
|
+
),
|
|
54
|
+
SecretStrInput(
|
|
55
|
+
name="api_key",
|
|
56
|
+
display_name="DeepSeek API Key",
|
|
57
|
+
info="The DeepSeek API Key",
|
|
58
|
+
advanced=False,
|
|
59
|
+
required=True,
|
|
60
|
+
),
|
|
61
|
+
SliderInput(
|
|
62
|
+
name="temperature",
|
|
63
|
+
display_name="Temperature",
|
|
64
|
+
info="Controls randomness in responses",
|
|
65
|
+
value=1.0,
|
|
66
|
+
range_spec=RangeSpec(min=0, max=2, step=0.01),
|
|
67
|
+
advanced=True,
|
|
68
|
+
),
|
|
69
|
+
IntInput(
|
|
70
|
+
name="seed",
|
|
71
|
+
display_name="Seed",
|
|
72
|
+
info="The seed controls the reproducibility of the job.",
|
|
73
|
+
advanced=True,
|
|
74
|
+
value=1,
|
|
75
|
+
),
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
def get_models(self) -> list[str]:
|
|
79
|
+
if not self.api_key:
|
|
80
|
+
return DEEPSEEK_MODELS
|
|
81
|
+
|
|
82
|
+
url = f"{self.api_base}/models"
|
|
83
|
+
headers = {"Authorization": f"Bearer {self.api_key}", "Accept": "application/json"}
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
response = requests.get(url, headers=headers, timeout=10)
|
|
87
|
+
response.raise_for_status()
|
|
88
|
+
model_list = response.json()
|
|
89
|
+
return [model["id"] for model in model_list.get("data", [])]
|
|
90
|
+
except requests.RequestException as e:
|
|
91
|
+
self.status = f"Error fetching models: {e}"
|
|
92
|
+
return DEEPSEEK_MODELS
|
|
93
|
+
|
|
94
|
+
@override
|
|
95
|
+
def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None):
|
|
96
|
+
if field_name in {"api_key", "api_base", "model_name"}:
|
|
97
|
+
models = self.get_models()
|
|
98
|
+
build_config["model_name"]["options"] = models
|
|
99
|
+
return build_config
|
|
100
|
+
|
|
101
|
+
def build_model(self) -> LanguageModel:
|
|
102
|
+
try:
|
|
103
|
+
from langchain_openai import ChatOpenAI
|
|
104
|
+
except ImportError as e:
|
|
105
|
+
msg = "langchain-openai not installed. Please install with `pip install langchain-openai`"
|
|
106
|
+
raise ImportError(msg) from e
|
|
107
|
+
|
|
108
|
+
api_key = SecretStr(self.api_key).get_secret_value() if self.api_key else None
|
|
109
|
+
output = ChatOpenAI(
|
|
110
|
+
model=self.model_name,
|
|
111
|
+
temperature=self.temperature if self.temperature is not None else 0.1,
|
|
112
|
+
max_tokens=self.max_tokens or None,
|
|
113
|
+
model_kwargs=self.model_kwargs or {},
|
|
114
|
+
base_url=self.api_base,
|
|
115
|
+
api_key=api_key,
|
|
116
|
+
streaming=self.stream if hasattr(self, "stream") else False,
|
|
117
|
+
seed=self.seed,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if self.json_mode:
|
|
121
|
+
output = output.bind(response_format={"type": "json_object"})
|
|
122
|
+
|
|
123
|
+
return output
|
|
124
|
+
|
|
125
|
+
def _get_exception_message(self, e: Exception):
|
|
126
|
+
"""Get message from DeepSeek API exception."""
|
|
127
|
+
try:
|
|
128
|
+
from openai import BadRequestError
|
|
129
|
+
|
|
130
|
+
if isinstance(e, BadRequestError):
|
|
131
|
+
message = e.body.get("message")
|
|
132
|
+
if message:
|
|
133
|
+
return message
|
|
134
|
+
except ImportError:
|
|
135
|
+
pass
|
|
136
|
+
return None
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from lfx.components._importing import import_mod
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from .chunk_docling_document import ChunkDoclingDocumentComponent
|
|
9
|
+
from .docling_inline import DoclingInlineComponent
|
|
10
|
+
from .docling_remote import DoclingRemoteComponent
|
|
11
|
+
from .export_docling_document import ExportDoclingDocumentComponent
|
|
12
|
+
|
|
13
|
+
_dynamic_imports = {
|
|
14
|
+
"ChunkDoclingDocumentComponent": "chunk_docling_document",
|
|
15
|
+
"DoclingInlineComponent": "docling_inline",
|
|
16
|
+
"DoclingRemoteComponent": "docling_remote",
|
|
17
|
+
"ExportDoclingDocumentComponent": "export_docling_document",
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"ChunkDoclingDocumentComponent",
|
|
22
|
+
"DoclingInlineComponent",
|
|
23
|
+
"DoclingRemoteComponent",
|
|
24
|
+
"ExportDoclingDocumentComponent",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def __getattr__(attr_name: str) -> Any:
|
|
29
|
+
"""Lazily import docling components on attribute access."""
|
|
30
|
+
if attr_name not in _dynamic_imports:
|
|
31
|
+
msg = f"module '{__name__}' has no attribute '{attr_name}'"
|
|
32
|
+
raise AttributeError(msg)
|
|
33
|
+
try:
|
|
34
|
+
result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
|
|
35
|
+
except (ModuleNotFoundError, ImportError, AttributeError) as e:
|
|
36
|
+
msg = f"Could not import '{attr_name}' from '{__name__}': {e}"
|
|
37
|
+
raise AttributeError(msg) from e
|
|
38
|
+
globals()[attr_name] = result
|
|
39
|
+
return result
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def __dir__() -> list[str]:
|
|
43
|
+
return list(__all__)
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
import tiktoken
|
|
4
|
+
from docling_core.transforms.chunker import BaseChunker, DocMeta
|
|
5
|
+
from docling_core.transforms.chunker.hierarchical_chunker import HierarchicalChunker
|
|
6
|
+
|
|
7
|
+
from lfx.base.data.docling_utils import extract_docling_documents
|
|
8
|
+
from lfx.custom import Component
|
|
9
|
+
from lfx.io import DropdownInput, HandleInput, IntInput, MessageTextInput, Output, StrInput
|
|
10
|
+
from lfx.schema import Data, DataFrame
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ChunkDoclingDocumentComponent(Component):
|
|
14
|
+
display_name: str = "Chunk DoclingDocument"
|
|
15
|
+
description: str = "Use the DocumentDocument chunkers to split the document into chunks."
|
|
16
|
+
documentation = "https://docling-project.github.io/docling/concepts/chunking/"
|
|
17
|
+
icon = "Docling"
|
|
18
|
+
name = "ChunkDoclingDocument"
|
|
19
|
+
|
|
20
|
+
inputs = [
|
|
21
|
+
HandleInput(
|
|
22
|
+
name="data_inputs",
|
|
23
|
+
display_name="Data or DataFrame",
|
|
24
|
+
info="The data with documents to split in chunks.",
|
|
25
|
+
input_types=["Data", "DataFrame"],
|
|
26
|
+
required=True,
|
|
27
|
+
),
|
|
28
|
+
DropdownInput(
|
|
29
|
+
name="chunker",
|
|
30
|
+
display_name="Chunker",
|
|
31
|
+
options=["HybridChunker", "HierarchicalChunker"],
|
|
32
|
+
info=("Which chunker to use."),
|
|
33
|
+
value="HybridChunker",
|
|
34
|
+
real_time_refresh=True,
|
|
35
|
+
),
|
|
36
|
+
DropdownInput(
|
|
37
|
+
name="provider",
|
|
38
|
+
display_name="Provider",
|
|
39
|
+
options=["Hugging Face", "OpenAI"],
|
|
40
|
+
info=("Which tokenizer provider."),
|
|
41
|
+
value="Hugging Face",
|
|
42
|
+
show=True,
|
|
43
|
+
real_time_refresh=True,
|
|
44
|
+
advanced=True,
|
|
45
|
+
dynamic=True,
|
|
46
|
+
),
|
|
47
|
+
StrInput(
|
|
48
|
+
name="hf_model_name",
|
|
49
|
+
display_name="HF model name",
|
|
50
|
+
info=(
|
|
51
|
+
"Model name of the tokenizer to use with the HybridChunker when Hugging Face is chosen as a tokenizer."
|
|
52
|
+
),
|
|
53
|
+
value="sentence-transformers/all-MiniLM-L6-v2",
|
|
54
|
+
show=True,
|
|
55
|
+
advanced=True,
|
|
56
|
+
dynamic=True,
|
|
57
|
+
),
|
|
58
|
+
StrInput(
|
|
59
|
+
name="openai_model_name",
|
|
60
|
+
display_name="OpenAI model name",
|
|
61
|
+
info=("Model name of the tokenizer to use with the HybridChunker when OpenAI is chosen as a tokenizer."),
|
|
62
|
+
value="gpt-4o",
|
|
63
|
+
show=False,
|
|
64
|
+
advanced=True,
|
|
65
|
+
dynamic=True,
|
|
66
|
+
),
|
|
67
|
+
IntInput(
|
|
68
|
+
name="max_tokens",
|
|
69
|
+
display_name="Maximum tokens",
|
|
70
|
+
info=("Maximum number of tokens for the HybridChunker."),
|
|
71
|
+
show=True,
|
|
72
|
+
required=False,
|
|
73
|
+
advanced=True,
|
|
74
|
+
dynamic=True,
|
|
75
|
+
),
|
|
76
|
+
MessageTextInput(
|
|
77
|
+
name="doc_key",
|
|
78
|
+
display_name="Doc Key",
|
|
79
|
+
info="The key to use for the DoclingDocument column.",
|
|
80
|
+
value="doc",
|
|
81
|
+
advanced=True,
|
|
82
|
+
),
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
outputs = [
|
|
86
|
+
Output(display_name="DataFrame", name="dataframe", method="chunk_documents"),
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None) -> dict:
|
|
90
|
+
if field_name == "chunker":
|
|
91
|
+
provider_type = build_config["provider"]["value"]
|
|
92
|
+
is_hf = provider_type == "Hugging Face"
|
|
93
|
+
is_openai = provider_type == "OpenAI"
|
|
94
|
+
if field_value == "HybridChunker":
|
|
95
|
+
build_config["provider"]["show"] = True
|
|
96
|
+
build_config["hf_model_name"]["show"] = is_hf
|
|
97
|
+
build_config["openai_model_name"]["show"] = is_openai
|
|
98
|
+
build_config["max_tokens"]["show"] = True
|
|
99
|
+
else:
|
|
100
|
+
build_config["provider"]["show"] = False
|
|
101
|
+
build_config["hf_model_name"]["show"] = False
|
|
102
|
+
build_config["openai_model_name"]["show"] = False
|
|
103
|
+
build_config["max_tokens"]["show"] = False
|
|
104
|
+
elif field_name == "provider" and build_config["chunker"]["value"] == "HybridChunker":
|
|
105
|
+
if field_value == "Hugging Face":
|
|
106
|
+
build_config["hf_model_name"]["show"] = True
|
|
107
|
+
build_config["openai_model_name"]["show"] = False
|
|
108
|
+
elif field_value == "OpenAI":
|
|
109
|
+
build_config["hf_model_name"]["show"] = False
|
|
110
|
+
build_config["openai_model_name"]["show"] = True
|
|
111
|
+
|
|
112
|
+
return build_config
|
|
113
|
+
|
|
114
|
+
def _docs_to_data(self, docs) -> list[Data]:
|
|
115
|
+
return [Data(text=doc.page_content, data=doc.metadata) for doc in docs]
|
|
116
|
+
|
|
117
|
+
def chunk_documents(self) -> DataFrame:
|
|
118
|
+
documents = extract_docling_documents(self.data_inputs, self.doc_key)
|
|
119
|
+
|
|
120
|
+
chunker: BaseChunker
|
|
121
|
+
if self.chunker == "HybridChunker":
|
|
122
|
+
try:
|
|
123
|
+
from docling_core.transforms.chunker.hybrid_chunker import HybridChunker
|
|
124
|
+
except ImportError as e:
|
|
125
|
+
msg = (
|
|
126
|
+
"HybridChunker is not installed. Please install it with `uv pip install docling-core[chunking] "
|
|
127
|
+
"or `uv pip install transformers`"
|
|
128
|
+
)
|
|
129
|
+
raise ImportError(msg) from e
|
|
130
|
+
max_tokens: int | None = self.max_tokens if self.max_tokens else None
|
|
131
|
+
if self.provider == "Hugging Face":
|
|
132
|
+
try:
|
|
133
|
+
from docling_core.transforms.chunker.tokenizer.huggingface import HuggingFaceTokenizer
|
|
134
|
+
except ImportError as e:
|
|
135
|
+
msg = (
|
|
136
|
+
"HuggingFaceTokenizer is not installed."
|
|
137
|
+
" Please install it with `uv pip install docling-core[chunking]`"
|
|
138
|
+
)
|
|
139
|
+
raise ImportError(msg) from e
|
|
140
|
+
tokenizer = HuggingFaceTokenizer.from_pretrained(
|
|
141
|
+
model_name=self.hf_model_name,
|
|
142
|
+
max_tokens=max_tokens,
|
|
143
|
+
)
|
|
144
|
+
elif self.provider == "OpenAI":
|
|
145
|
+
try:
|
|
146
|
+
from docling_core.transforms.chunker.tokenizer.openai import OpenAITokenizer
|
|
147
|
+
except ImportError as e:
|
|
148
|
+
msg = (
|
|
149
|
+
"OpenAITokenizer is not installed."
|
|
150
|
+
" Please install it with `uv pip install docling-core[chunking]`"
|
|
151
|
+
" or `uv pip install transformers`"
|
|
152
|
+
)
|
|
153
|
+
raise ImportError(msg) from e
|
|
154
|
+
if max_tokens is None:
|
|
155
|
+
max_tokens = 128 * 1024 # context window length required for OpenAI tokenizers
|
|
156
|
+
tokenizer = OpenAITokenizer(
|
|
157
|
+
tokenizer=tiktoken.encoding_for_model(self.openai_model_name), max_tokens=max_tokens
|
|
158
|
+
)
|
|
159
|
+
chunker = HybridChunker(
|
|
160
|
+
tokenizer=tokenizer,
|
|
161
|
+
)
|
|
162
|
+
elif self.chunker == "HierarchicalChunker":
|
|
163
|
+
chunker = HierarchicalChunker()
|
|
164
|
+
|
|
165
|
+
results: list[Data] = []
|
|
166
|
+
try:
|
|
167
|
+
for doc in documents:
|
|
168
|
+
for chunk in chunker.chunk(dl_doc=doc):
|
|
169
|
+
enriched_text = chunker.contextualize(chunk=chunk)
|
|
170
|
+
meta = DocMeta.model_validate(chunk.meta)
|
|
171
|
+
|
|
172
|
+
results.append(
|
|
173
|
+
Data(
|
|
174
|
+
data={
|
|
175
|
+
"text": enriched_text,
|
|
176
|
+
"document_id": f"{doc.origin.binary_hash}",
|
|
177
|
+
"doc_items": json.dumps([item.self_ref for item in meta.doc_items]),
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
except Exception as e:
|
|
183
|
+
msg = f"Error splitting text: {e}"
|
|
184
|
+
raise TypeError(msg) from e
|
|
185
|
+
|
|
186
|
+
return DataFrame(results)
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from multiprocessing import Queue, get_context
|
|
3
|
+
from queue import Empty
|
|
4
|
+
|
|
5
|
+
from lfx.base.data import BaseFileComponent
|
|
6
|
+
from lfx.base.data.docling_utils import _serialize_pydantic_model, docling_worker
|
|
7
|
+
from lfx.inputs import BoolInput, DropdownInput, HandleInput, StrInput
|
|
8
|
+
from lfx.schema import Data
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DoclingInlineComponent(BaseFileComponent):
|
|
12
|
+
display_name = "Docling"
|
|
13
|
+
description = "Uses Docling to process input documents running the Docling models locally."
|
|
14
|
+
documentation = "https://docling-project.github.io/docling/"
|
|
15
|
+
trace_type = "tool"
|
|
16
|
+
icon = "Docling"
|
|
17
|
+
name = "DoclingInline"
|
|
18
|
+
|
|
19
|
+
# https://docling-project.github.io/docling/usage/supported_formats/
|
|
20
|
+
VALID_EXTENSIONS = [
|
|
21
|
+
"adoc",
|
|
22
|
+
"asciidoc",
|
|
23
|
+
"asc",
|
|
24
|
+
"bmp",
|
|
25
|
+
"csv",
|
|
26
|
+
"dotx",
|
|
27
|
+
"dotm",
|
|
28
|
+
"docm",
|
|
29
|
+
"docx",
|
|
30
|
+
"htm",
|
|
31
|
+
"html",
|
|
32
|
+
"jpeg",
|
|
33
|
+
"json",
|
|
34
|
+
"md",
|
|
35
|
+
"pdf",
|
|
36
|
+
"png",
|
|
37
|
+
"potx",
|
|
38
|
+
"ppsx",
|
|
39
|
+
"pptm",
|
|
40
|
+
"potm",
|
|
41
|
+
"ppsm",
|
|
42
|
+
"pptx",
|
|
43
|
+
"tiff",
|
|
44
|
+
"txt",
|
|
45
|
+
"xls",
|
|
46
|
+
"xlsx",
|
|
47
|
+
"xhtml",
|
|
48
|
+
"xml",
|
|
49
|
+
"webp",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
inputs = [
|
|
53
|
+
*BaseFileComponent.get_base_inputs(),
|
|
54
|
+
DropdownInput(
|
|
55
|
+
name="pipeline",
|
|
56
|
+
display_name="Pipeline",
|
|
57
|
+
info="Docling pipeline to use",
|
|
58
|
+
options=["standard", "vlm"],
|
|
59
|
+
value="standard",
|
|
60
|
+
),
|
|
61
|
+
DropdownInput(
|
|
62
|
+
name="ocr_engine",
|
|
63
|
+
display_name="OCR Engine",
|
|
64
|
+
info="OCR engine to use. None will disable OCR.",
|
|
65
|
+
options=["None", "easyocr", "tesserocr", "rapidocr", "ocrmac"],
|
|
66
|
+
value="None",
|
|
67
|
+
),
|
|
68
|
+
BoolInput(
|
|
69
|
+
name="do_picture_classification",
|
|
70
|
+
display_name="Picture classification",
|
|
71
|
+
info="If enabled, the Docling pipeline will classify the pictures type.",
|
|
72
|
+
value=False,
|
|
73
|
+
),
|
|
74
|
+
HandleInput(
|
|
75
|
+
name="pic_desc_llm",
|
|
76
|
+
display_name="Picture description LLM",
|
|
77
|
+
info="If connected, the model to use for running the picture description task.",
|
|
78
|
+
input_types=["LanguageModel"],
|
|
79
|
+
required=False,
|
|
80
|
+
),
|
|
81
|
+
StrInput(
|
|
82
|
+
name="pic_desc_prompt",
|
|
83
|
+
display_name="Picture description prompt",
|
|
84
|
+
value="Describe the image in three sentences. Be concise and accurate.",
|
|
85
|
+
info="The user prompt to use when invoking the model.",
|
|
86
|
+
advanced=True,
|
|
87
|
+
),
|
|
88
|
+
# TODO: expose more Docling options
|
|
89
|
+
]
|
|
90
|
+
|
|
91
|
+
outputs = [
|
|
92
|
+
*BaseFileComponent.get_base_outputs(),
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
def _wait_for_result_with_process_monitoring(self, queue: Queue, proc, timeout: int = 300):
|
|
96
|
+
"""Wait for result from queue while monitoring process health.
|
|
97
|
+
|
|
98
|
+
Handles cases where process crashes without sending result.
|
|
99
|
+
"""
|
|
100
|
+
start_time = time.time()
|
|
101
|
+
|
|
102
|
+
while time.time() - start_time < timeout:
|
|
103
|
+
# Check if process is still alive
|
|
104
|
+
if not proc.is_alive():
|
|
105
|
+
# Process died, try to get any result it might have sent
|
|
106
|
+
try:
|
|
107
|
+
result = queue.get_nowait()
|
|
108
|
+
except Empty:
|
|
109
|
+
# Process died without sending result
|
|
110
|
+
msg = f"Worker process crashed unexpectedly without producing result. Exit code: {proc.exitcode}"
|
|
111
|
+
raise RuntimeError(msg) from None
|
|
112
|
+
else:
|
|
113
|
+
self.log("Process completed and result retrieved")
|
|
114
|
+
return result
|
|
115
|
+
|
|
116
|
+
# Poll the queue instead of blocking
|
|
117
|
+
try:
|
|
118
|
+
result = queue.get(timeout=1)
|
|
119
|
+
except Empty:
|
|
120
|
+
# No result yet, continue monitoring
|
|
121
|
+
continue
|
|
122
|
+
else:
|
|
123
|
+
self.log("Result received from worker process")
|
|
124
|
+
return result
|
|
125
|
+
|
|
126
|
+
# Overall timeout reached
|
|
127
|
+
msg = f"Process timed out after {timeout} seconds"
|
|
128
|
+
raise TimeoutError(msg)
|
|
129
|
+
|
|
130
|
+
def _terminate_process_gracefully(self, proc, timeout_terminate: int = 10, timeout_kill: int = 5):
|
|
131
|
+
"""Terminate process gracefully with escalating signals.
|
|
132
|
+
|
|
133
|
+
First tries SIGTERM, then SIGKILL if needed.
|
|
134
|
+
"""
|
|
135
|
+
if not proc.is_alive():
|
|
136
|
+
return
|
|
137
|
+
|
|
138
|
+
self.log("Attempting graceful process termination with SIGTERM")
|
|
139
|
+
proc.terminate() # Send SIGTERM
|
|
140
|
+
proc.join(timeout=timeout_terminate)
|
|
141
|
+
|
|
142
|
+
if proc.is_alive():
|
|
143
|
+
self.log("Process didn't respond to SIGTERM, using SIGKILL")
|
|
144
|
+
proc.kill() # Send SIGKILL
|
|
145
|
+
proc.join(timeout=timeout_kill)
|
|
146
|
+
|
|
147
|
+
if proc.is_alive():
|
|
148
|
+
self.log("Warning: Process still alive after SIGKILL")
|
|
149
|
+
|
|
150
|
+
def process_files(self, file_list: list[BaseFileComponent.BaseFile]) -> list[BaseFileComponent.BaseFile]:
|
|
151
|
+
try:
|
|
152
|
+
from docling.document_converter import DocumentConverter # noqa: F401
|
|
153
|
+
except ImportError as e:
|
|
154
|
+
msg = (
|
|
155
|
+
"Docling is an optional dependency. Install with `uv pip install 'langflow[docling]'` or refer to the "
|
|
156
|
+
"documentation on how to install optional dependencies."
|
|
157
|
+
)
|
|
158
|
+
raise ImportError(msg) from e
|
|
159
|
+
|
|
160
|
+
file_paths = [file.path for file in file_list if file.path]
|
|
161
|
+
|
|
162
|
+
if not file_paths:
|
|
163
|
+
self.log("No files to process.")
|
|
164
|
+
return file_list
|
|
165
|
+
|
|
166
|
+
pic_desc_config: dict | None = None
|
|
167
|
+
if self.pic_desc_llm is not None:
|
|
168
|
+
pic_desc_config = _serialize_pydantic_model(self.pic_desc_llm)
|
|
169
|
+
|
|
170
|
+
ctx = get_context("spawn")
|
|
171
|
+
queue: Queue = ctx.Queue()
|
|
172
|
+
proc = ctx.Process(
|
|
173
|
+
target=docling_worker,
|
|
174
|
+
kwargs={
|
|
175
|
+
"file_paths": file_paths,
|
|
176
|
+
"queue": queue,
|
|
177
|
+
"pipeline": self.pipeline,
|
|
178
|
+
"ocr_engine": self.ocr_engine,
|
|
179
|
+
"do_picture_classification": self.do_picture_classification,
|
|
180
|
+
"pic_desc_config": pic_desc_config,
|
|
181
|
+
"pic_desc_prompt": self.pic_desc_prompt,
|
|
182
|
+
},
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
result = None
|
|
186
|
+
proc.start()
|
|
187
|
+
|
|
188
|
+
try:
|
|
189
|
+
result = self._wait_for_result_with_process_monitoring(queue, proc, timeout=300)
|
|
190
|
+
except KeyboardInterrupt:
|
|
191
|
+
self.log("Docling process cancelled by user")
|
|
192
|
+
result = []
|
|
193
|
+
except Exception as e:
|
|
194
|
+
self.log(f"Error during processing: {e}")
|
|
195
|
+
raise
|
|
196
|
+
finally:
|
|
197
|
+
# Improved cleanup with graceful termination
|
|
198
|
+
try:
|
|
199
|
+
self._terminate_process_gracefully(proc)
|
|
200
|
+
finally:
|
|
201
|
+
# Always close and cleanup queue resources
|
|
202
|
+
try:
|
|
203
|
+
queue.close()
|
|
204
|
+
queue.join_thread()
|
|
205
|
+
except Exception as e: # noqa: BLE001
|
|
206
|
+
# Ignore cleanup errors, but log them
|
|
207
|
+
self.log(f"Warning: Error during queue cleanup - {e}")
|
|
208
|
+
|
|
209
|
+
# Enhanced error checking with dependency-specific handling
|
|
210
|
+
if isinstance(result, dict) and "error" in result:
|
|
211
|
+
error_msg = result["error"]
|
|
212
|
+
|
|
213
|
+
# Handle dependency errors specifically
|
|
214
|
+
if result.get("error_type") == "dependency_error":
|
|
215
|
+
dependency_name = result.get("dependency_name", "Unknown dependency")
|
|
216
|
+
install_command = result.get("install_command", "Please check documentation")
|
|
217
|
+
|
|
218
|
+
# Create a user-friendly error message
|
|
219
|
+
user_message = (
|
|
220
|
+
f"Missing OCR dependency: {dependency_name}. "
|
|
221
|
+
f"{install_command} "
|
|
222
|
+
f"Alternatively, you can set OCR Engine to 'None' to disable OCR processing."
|
|
223
|
+
)
|
|
224
|
+
raise ImportError(user_message)
|
|
225
|
+
|
|
226
|
+
# Handle other specific errors
|
|
227
|
+
if error_msg.startswith("Docling is not installed"):
|
|
228
|
+
raise ImportError(error_msg)
|
|
229
|
+
|
|
230
|
+
# Handle graceful shutdown
|
|
231
|
+
if "Worker interrupted by SIGINT" in error_msg or "shutdown" in result:
|
|
232
|
+
self.log("Docling process cancelled by user")
|
|
233
|
+
result = []
|
|
234
|
+
else:
|
|
235
|
+
raise RuntimeError(error_msg)
|
|
236
|
+
|
|
237
|
+
processed_data = [Data(data={"doc": r["document"], "file_path": r["file_path"]}) if r else None for r in result]
|
|
238
|
+
return self.rollup_data(file_list, processed_data)
|