lfx-nightly 0.1.11.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lfx/__init__.py +0 -0
- lfx/__main__.py +25 -0
- lfx/base/__init__.py +0 -0
- lfx/base/agents/__init__.py +0 -0
- lfx/base/agents/agent.py +268 -0
- lfx/base/agents/callback.py +130 -0
- lfx/base/agents/context.py +109 -0
- lfx/base/agents/crewai/__init__.py +0 -0
- lfx/base/agents/crewai/crew.py +231 -0
- lfx/base/agents/crewai/tasks.py +12 -0
- lfx/base/agents/default_prompts.py +23 -0
- lfx/base/agents/errors.py +15 -0
- lfx/base/agents/events.py +346 -0
- lfx/base/agents/utils.py +205 -0
- lfx/base/astra_assistants/__init__.py +0 -0
- lfx/base/astra_assistants/util.py +171 -0
- lfx/base/chains/__init__.py +0 -0
- lfx/base/chains/model.py +19 -0
- lfx/base/composio/__init__.py +0 -0
- lfx/base/composio/composio_base.py +1291 -0
- lfx/base/compressors/__init__.py +0 -0
- lfx/base/compressors/model.py +60 -0
- lfx/base/constants.py +46 -0
- lfx/base/curl/__init__.py +0 -0
- lfx/base/curl/parse.py +188 -0
- lfx/base/data/__init__.py +5 -0
- lfx/base/data/base_file.py +685 -0
- lfx/base/data/docling_utils.py +245 -0
- lfx/base/data/utils.py +198 -0
- lfx/base/document_transformers/__init__.py +0 -0
- lfx/base/document_transformers/model.py +43 -0
- lfx/base/embeddings/__init__.py +0 -0
- lfx/base/embeddings/aiml_embeddings.py +62 -0
- lfx/base/embeddings/model.py +26 -0
- lfx/base/flow_processing/__init__.py +0 -0
- lfx/base/flow_processing/utils.py +86 -0
- lfx/base/huggingface/__init__.py +0 -0
- lfx/base/huggingface/model_bridge.py +133 -0
- lfx/base/io/__init__.py +0 -0
- lfx/base/io/chat.py +20 -0
- lfx/base/io/text.py +22 -0
- lfx/base/langchain_utilities/__init__.py +0 -0
- lfx/base/langchain_utilities/model.py +35 -0
- lfx/base/langchain_utilities/spider_constants.py +1 -0
- lfx/base/langwatch/__init__.py +0 -0
- lfx/base/langwatch/utils.py +18 -0
- lfx/base/mcp/__init__.py +0 -0
- lfx/base/mcp/constants.py +2 -0
- lfx/base/mcp/util.py +1398 -0
- lfx/base/memory/__init__.py +0 -0
- lfx/base/memory/memory.py +49 -0
- lfx/base/memory/model.py +38 -0
- lfx/base/models/__init__.py +3 -0
- lfx/base/models/aiml_constants.py +51 -0
- lfx/base/models/anthropic_constants.py +47 -0
- lfx/base/models/aws_constants.py +151 -0
- lfx/base/models/chat_result.py +76 -0
- lfx/base/models/google_generative_ai_constants.py +70 -0
- lfx/base/models/groq_constants.py +134 -0
- lfx/base/models/model.py +375 -0
- lfx/base/models/model_input_constants.py +307 -0
- lfx/base/models/model_metadata.py +41 -0
- lfx/base/models/model_utils.py +8 -0
- lfx/base/models/novita_constants.py +35 -0
- lfx/base/models/ollama_constants.py +49 -0
- lfx/base/models/openai_constants.py +122 -0
- lfx/base/models/sambanova_constants.py +18 -0
- lfx/base/processing/__init__.py +0 -0
- lfx/base/prompts/__init__.py +0 -0
- lfx/base/prompts/api_utils.py +224 -0
- lfx/base/prompts/utils.py +61 -0
- lfx/base/textsplitters/__init__.py +0 -0
- lfx/base/textsplitters/model.py +28 -0
- lfx/base/tools/__init__.py +0 -0
- lfx/base/tools/base.py +26 -0
- lfx/base/tools/component_tool.py +325 -0
- lfx/base/tools/constants.py +49 -0
- lfx/base/tools/flow_tool.py +132 -0
- lfx/base/tools/run_flow.py +224 -0
- lfx/base/vectorstores/__init__.py +0 -0
- lfx/base/vectorstores/model.py +193 -0
- lfx/base/vectorstores/utils.py +22 -0
- lfx/base/vectorstores/vector_store_connection_decorator.py +52 -0
- lfx/cli/__init__.py +5 -0
- lfx/cli/commands.py +319 -0
- lfx/cli/common.py +650 -0
- lfx/cli/run.py +441 -0
- lfx/cli/script_loader.py +247 -0
- lfx/cli/serve_app.py +546 -0
- lfx/cli/validation.py +69 -0
- lfx/components/FAISS/__init__.py +34 -0
- lfx/components/FAISS/faiss.py +111 -0
- lfx/components/Notion/__init__.py +19 -0
- lfx/components/Notion/add_content_to_page.py +269 -0
- lfx/components/Notion/create_page.py +94 -0
- lfx/components/Notion/list_database_properties.py +68 -0
- lfx/components/Notion/list_pages.py +122 -0
- lfx/components/Notion/list_users.py +77 -0
- lfx/components/Notion/page_content_viewer.py +93 -0
- lfx/components/Notion/search.py +111 -0
- lfx/components/Notion/update_page_property.py +114 -0
- lfx/components/__init__.py +411 -0
- lfx/components/_importing.py +42 -0
- lfx/components/agentql/__init__.py +3 -0
- lfx/components/agentql/agentql_api.py +151 -0
- lfx/components/agents/__init__.py +34 -0
- lfx/components/agents/agent.py +558 -0
- lfx/components/agents/mcp_component.py +501 -0
- lfx/components/aiml/__init__.py +37 -0
- lfx/components/aiml/aiml.py +112 -0
- lfx/components/aiml/aiml_embeddings.py +37 -0
- lfx/components/amazon/__init__.py +36 -0
- lfx/components/amazon/amazon_bedrock_embedding.py +109 -0
- lfx/components/amazon/amazon_bedrock_model.py +124 -0
- lfx/components/amazon/s3_bucket_uploader.py +211 -0
- lfx/components/anthropic/__init__.py +34 -0
- lfx/components/anthropic/anthropic.py +187 -0
- lfx/components/apify/__init__.py +5 -0
- lfx/components/apify/apify_actor.py +325 -0
- lfx/components/arxiv/__init__.py +3 -0
- lfx/components/arxiv/arxiv.py +163 -0
- lfx/components/assemblyai/__init__.py +46 -0
- lfx/components/assemblyai/assemblyai_get_subtitles.py +83 -0
- lfx/components/assemblyai/assemblyai_lemur.py +183 -0
- lfx/components/assemblyai/assemblyai_list_transcripts.py +95 -0
- lfx/components/assemblyai/assemblyai_poll_transcript.py +72 -0
- lfx/components/assemblyai/assemblyai_start_transcript.py +188 -0
- lfx/components/azure/__init__.py +37 -0
- lfx/components/azure/azure_openai.py +95 -0
- lfx/components/azure/azure_openai_embeddings.py +83 -0
- lfx/components/baidu/__init__.py +32 -0
- lfx/components/baidu/baidu_qianfan_chat.py +113 -0
- lfx/components/bing/__init__.py +3 -0
- lfx/components/bing/bing_search_api.py +61 -0
- lfx/components/cassandra/__init__.py +40 -0
- lfx/components/cassandra/cassandra.py +264 -0
- lfx/components/cassandra/cassandra_chat.py +92 -0
- lfx/components/cassandra/cassandra_graph.py +238 -0
- lfx/components/chains/__init__.py +3 -0
- lfx/components/chroma/__init__.py +34 -0
- lfx/components/chroma/chroma.py +167 -0
- lfx/components/cleanlab/__init__.py +40 -0
- lfx/components/cleanlab/cleanlab_evaluator.py +155 -0
- lfx/components/cleanlab/cleanlab_rag_evaluator.py +254 -0
- lfx/components/cleanlab/cleanlab_remediator.py +131 -0
- lfx/components/clickhouse/__init__.py +34 -0
- lfx/components/clickhouse/clickhouse.py +135 -0
- lfx/components/cloudflare/__init__.py +32 -0
- lfx/components/cloudflare/cloudflare.py +81 -0
- lfx/components/cohere/__init__.py +40 -0
- lfx/components/cohere/cohere_embeddings.py +81 -0
- lfx/components/cohere/cohere_models.py +46 -0
- lfx/components/cohere/cohere_rerank.py +51 -0
- lfx/components/composio/__init__.py +74 -0
- lfx/components/composio/composio_api.py +268 -0
- lfx/components/composio/dropbox_compnent.py +11 -0
- lfx/components/composio/github_composio.py +11 -0
- lfx/components/composio/gmail_composio.py +38 -0
- lfx/components/composio/googlecalendar_composio.py +11 -0
- lfx/components/composio/googlemeet_composio.py +11 -0
- lfx/components/composio/googletasks_composio.py +8 -0
- lfx/components/composio/linear_composio.py +11 -0
- lfx/components/composio/outlook_composio.py +11 -0
- lfx/components/composio/reddit_composio.py +11 -0
- lfx/components/composio/slack_composio.py +582 -0
- lfx/components/composio/slackbot_composio.py +11 -0
- lfx/components/composio/supabase_composio.py +11 -0
- lfx/components/composio/todoist_composio.py +11 -0
- lfx/components/composio/youtube_composio.py +11 -0
- lfx/components/confluence/__init__.py +3 -0
- lfx/components/confluence/confluence.py +84 -0
- lfx/components/couchbase/__init__.py +34 -0
- lfx/components/couchbase/couchbase.py +102 -0
- lfx/components/crewai/__init__.py +49 -0
- lfx/components/crewai/crewai.py +107 -0
- lfx/components/crewai/hierarchical_crew.py +46 -0
- lfx/components/crewai/hierarchical_task.py +44 -0
- lfx/components/crewai/sequential_crew.py +52 -0
- lfx/components/crewai/sequential_task.py +73 -0
- lfx/components/crewai/sequential_task_agent.py +143 -0
- lfx/components/custom_component/__init__.py +34 -0
- lfx/components/custom_component/custom_component.py +31 -0
- lfx/components/data/__init__.py +64 -0
- lfx/components/data/api_request.py +544 -0
- lfx/components/data/csv_to_data.py +95 -0
- lfx/components/data/directory.py +113 -0
- lfx/components/data/file.py +577 -0
- lfx/components/data/json_to_data.py +98 -0
- lfx/components/data/news_search.py +164 -0
- lfx/components/data/rss.py +69 -0
- lfx/components/data/sql_executor.py +101 -0
- lfx/components/data/url.py +311 -0
- lfx/components/data/web_search.py +112 -0
- lfx/components/data/webhook.py +56 -0
- lfx/components/datastax/__init__.py +70 -0
- lfx/components/datastax/astra_assistant_manager.py +306 -0
- lfx/components/datastax/astra_db.py +75 -0
- lfx/components/datastax/astra_vectorize.py +124 -0
- lfx/components/datastax/astradb.py +1285 -0
- lfx/components/datastax/astradb_cql.py +314 -0
- lfx/components/datastax/astradb_graph.py +330 -0
- lfx/components/datastax/astradb_tool.py +414 -0
- lfx/components/datastax/astradb_vectorstore.py +1285 -0
- lfx/components/datastax/cassandra.py +92 -0
- lfx/components/datastax/create_assistant.py +58 -0
- lfx/components/datastax/create_thread.py +32 -0
- lfx/components/datastax/dotenv.py +35 -0
- lfx/components/datastax/get_assistant.py +37 -0
- lfx/components/datastax/getenvvar.py +30 -0
- lfx/components/datastax/graph_rag.py +141 -0
- lfx/components/datastax/hcd.py +314 -0
- lfx/components/datastax/list_assistants.py +25 -0
- lfx/components/datastax/run.py +89 -0
- lfx/components/deactivated/__init__.py +15 -0
- lfx/components/deactivated/amazon_kendra.py +66 -0
- lfx/components/deactivated/chat_litellm_model.py +158 -0
- lfx/components/deactivated/code_block_extractor.py +26 -0
- lfx/components/deactivated/documents_to_data.py +22 -0
- lfx/components/deactivated/embed.py +16 -0
- lfx/components/deactivated/extract_key_from_data.py +46 -0
- lfx/components/deactivated/json_document_builder.py +57 -0
- lfx/components/deactivated/list_flows.py +20 -0
- lfx/components/deactivated/mcp_sse.py +61 -0
- lfx/components/deactivated/mcp_stdio.py +62 -0
- lfx/components/deactivated/merge_data.py +93 -0
- lfx/components/deactivated/message.py +37 -0
- lfx/components/deactivated/metal.py +54 -0
- lfx/components/deactivated/multi_query.py +59 -0
- lfx/components/deactivated/retriever.py +43 -0
- lfx/components/deactivated/selective_passthrough.py +77 -0
- lfx/components/deactivated/should_run_next.py +40 -0
- lfx/components/deactivated/split_text.py +63 -0
- lfx/components/deactivated/store_message.py +24 -0
- lfx/components/deactivated/sub_flow.py +124 -0
- lfx/components/deactivated/vectara_self_query.py +76 -0
- lfx/components/deactivated/vector_store.py +24 -0
- lfx/components/deepseek/__init__.py +34 -0
- lfx/components/deepseek/deepseek.py +136 -0
- lfx/components/docling/__init__.py +43 -0
- lfx/components/docling/chunk_docling_document.py +186 -0
- lfx/components/docling/docling_inline.py +231 -0
- lfx/components/docling/docling_remote.py +193 -0
- lfx/components/docling/export_docling_document.py +117 -0
- lfx/components/documentloaders/__init__.py +3 -0
- lfx/components/duckduckgo/__init__.py +3 -0
- lfx/components/duckduckgo/duck_duck_go_search_run.py +92 -0
- lfx/components/elastic/__init__.py +37 -0
- lfx/components/elastic/elasticsearch.py +267 -0
- lfx/components/elastic/opensearch.py +243 -0
- lfx/components/embeddings/__init__.py +37 -0
- lfx/components/embeddings/similarity.py +76 -0
- lfx/components/embeddings/text_embedder.py +64 -0
- lfx/components/exa/__init__.py +3 -0
- lfx/components/exa/exa_search.py +68 -0
- lfx/components/firecrawl/__init__.py +43 -0
- lfx/components/firecrawl/firecrawl_crawl_api.py +88 -0
- lfx/components/firecrawl/firecrawl_extract_api.py +136 -0
- lfx/components/firecrawl/firecrawl_map_api.py +89 -0
- lfx/components/firecrawl/firecrawl_scrape_api.py +73 -0
- lfx/components/git/__init__.py +4 -0
- lfx/components/git/git.py +262 -0
- lfx/components/git/gitextractor.py +196 -0
- lfx/components/glean/__init__.py +3 -0
- lfx/components/glean/glean_search_api.py +173 -0
- lfx/components/google/__init__.py +17 -0
- lfx/components/google/gmail.py +192 -0
- lfx/components/google/google_bq_sql_executor.py +157 -0
- lfx/components/google/google_drive.py +92 -0
- lfx/components/google/google_drive_search.py +152 -0
- lfx/components/google/google_generative_ai.py +147 -0
- lfx/components/google/google_generative_ai_embeddings.py +141 -0
- lfx/components/google/google_oauth_token.py +89 -0
- lfx/components/google/google_search_api_core.py +68 -0
- lfx/components/google/google_serper_api_core.py +74 -0
- lfx/components/groq/__init__.py +34 -0
- lfx/components/groq/groq.py +136 -0
- lfx/components/helpers/__init__.py +52 -0
- lfx/components/helpers/calculator_core.py +89 -0
- lfx/components/helpers/create_list.py +40 -0
- lfx/components/helpers/current_date.py +42 -0
- lfx/components/helpers/id_generator.py +42 -0
- lfx/components/helpers/memory.py +251 -0
- lfx/components/helpers/output_parser.py +45 -0
- lfx/components/helpers/store_message.py +90 -0
- lfx/components/homeassistant/__init__.py +7 -0
- lfx/components/homeassistant/home_assistant_control.py +152 -0
- lfx/components/homeassistant/list_home_assistant_states.py +137 -0
- lfx/components/huggingface/__init__.py +37 -0
- lfx/components/huggingface/huggingface.py +197 -0
- lfx/components/huggingface/huggingface_inference_api.py +106 -0
- lfx/components/ibm/__init__.py +34 -0
- lfx/components/ibm/watsonx.py +203 -0
- lfx/components/ibm/watsonx_embeddings.py +135 -0
- lfx/components/icosacomputing/__init__.py +5 -0
- lfx/components/icosacomputing/combinatorial_reasoner.py +84 -0
- lfx/components/input_output/__init__.py +38 -0
- lfx/components/input_output/chat.py +120 -0
- lfx/components/input_output/chat_output.py +200 -0
- lfx/components/input_output/text.py +27 -0
- lfx/components/input_output/text_output.py +29 -0
- lfx/components/jigsawstack/__init__.py +23 -0
- lfx/components/jigsawstack/ai_scrape.py +126 -0
- lfx/components/jigsawstack/ai_web_search.py +136 -0
- lfx/components/jigsawstack/file_read.py +115 -0
- lfx/components/jigsawstack/file_upload.py +94 -0
- lfx/components/jigsawstack/image_generation.py +205 -0
- lfx/components/jigsawstack/nsfw.py +60 -0
- lfx/components/jigsawstack/object_detection.py +124 -0
- lfx/components/jigsawstack/sentiment.py +112 -0
- lfx/components/jigsawstack/text_to_sql.py +90 -0
- lfx/components/jigsawstack/text_translate.py +77 -0
- lfx/components/jigsawstack/vocr.py +107 -0
- lfx/components/langchain_utilities/__init__.py +109 -0
- lfx/components/langchain_utilities/character.py +53 -0
- lfx/components/langchain_utilities/conversation.py +59 -0
- lfx/components/langchain_utilities/csv_agent.py +107 -0
- lfx/components/langchain_utilities/fake_embeddings.py +26 -0
- lfx/components/langchain_utilities/html_link_extractor.py +35 -0
- lfx/components/langchain_utilities/json_agent.py +45 -0
- lfx/components/langchain_utilities/langchain_hub.py +126 -0
- lfx/components/langchain_utilities/language_recursive.py +49 -0
- lfx/components/langchain_utilities/language_semantic.py +138 -0
- lfx/components/langchain_utilities/llm_checker.py +39 -0
- lfx/components/langchain_utilities/llm_math.py +42 -0
- lfx/components/langchain_utilities/natural_language.py +61 -0
- lfx/components/langchain_utilities/openai_tools.py +53 -0
- lfx/components/langchain_utilities/openapi.py +48 -0
- lfx/components/langchain_utilities/recursive_character.py +60 -0
- lfx/components/langchain_utilities/retrieval_qa.py +83 -0
- lfx/components/langchain_utilities/runnable_executor.py +137 -0
- lfx/components/langchain_utilities/self_query.py +80 -0
- lfx/components/langchain_utilities/spider.py +142 -0
- lfx/components/langchain_utilities/sql.py +40 -0
- lfx/components/langchain_utilities/sql_database.py +35 -0
- lfx/components/langchain_utilities/sql_generator.py +78 -0
- lfx/components/langchain_utilities/tool_calling.py +59 -0
- lfx/components/langchain_utilities/vector_store_info.py +49 -0
- lfx/components/langchain_utilities/vector_store_router.py +33 -0
- lfx/components/langchain_utilities/xml_agent.py +71 -0
- lfx/components/langwatch/__init__.py +3 -0
- lfx/components/langwatch/langwatch.py +278 -0
- lfx/components/link_extractors/__init__.py +3 -0
- lfx/components/lmstudio/__init__.py +34 -0
- lfx/components/lmstudio/lmstudioembeddings.py +89 -0
- lfx/components/lmstudio/lmstudiomodel.py +129 -0
- lfx/components/logic/__init__.py +52 -0
- lfx/components/logic/conditional_router.py +171 -0
- lfx/components/logic/data_conditional_router.py +125 -0
- lfx/components/logic/flow_tool.py +110 -0
- lfx/components/logic/listen.py +29 -0
- lfx/components/logic/loop.py +125 -0
- lfx/components/logic/notify.py +88 -0
- lfx/components/logic/pass_message.py +35 -0
- lfx/components/logic/run_flow.py +71 -0
- lfx/components/logic/sub_flow.py +114 -0
- lfx/components/maritalk/__init__.py +32 -0
- lfx/components/maritalk/maritalk.py +52 -0
- lfx/components/mem0/__init__.py +3 -0
- lfx/components/mem0/mem0_chat_memory.py +136 -0
- lfx/components/milvus/__init__.py +34 -0
- lfx/components/milvus/milvus.py +115 -0
- lfx/components/mistral/__init__.py +37 -0
- lfx/components/mistral/mistral.py +114 -0
- lfx/components/mistral/mistral_embeddings.py +58 -0
- lfx/components/models/__init__.py +34 -0
- lfx/components/models/embedding_model.py +114 -0
- lfx/components/models/language_model.py +144 -0
- lfx/components/mongodb/__init__.py +34 -0
- lfx/components/mongodb/mongodb_atlas.py +213 -0
- lfx/components/needle/__init__.py +3 -0
- lfx/components/needle/needle.py +104 -0
- lfx/components/notdiamond/__init__.py +34 -0
- lfx/components/notdiamond/notdiamond.py +228 -0
- lfx/components/novita/__init__.py +32 -0
- lfx/components/novita/novita.py +130 -0
- lfx/components/nvidia/__init__.py +57 -0
- lfx/components/nvidia/nvidia.py +157 -0
- lfx/components/nvidia/nvidia_embedding.py +77 -0
- lfx/components/nvidia/nvidia_ingest.py +317 -0
- lfx/components/nvidia/nvidia_rerank.py +63 -0
- lfx/components/nvidia/system_assist.py +65 -0
- lfx/components/olivya/__init__.py +3 -0
- lfx/components/olivya/olivya.py +116 -0
- lfx/components/ollama/__init__.py +37 -0
- lfx/components/ollama/ollama.py +330 -0
- lfx/components/ollama/ollama_embeddings.py +106 -0
- lfx/components/openai/__init__.py +37 -0
- lfx/components/openai/openai.py +100 -0
- lfx/components/openai/openai_chat_model.py +176 -0
- lfx/components/openrouter/__init__.py +32 -0
- lfx/components/openrouter/openrouter.py +202 -0
- lfx/components/output_parsers/__init__.py +3 -0
- lfx/components/perplexity/__init__.py +34 -0
- lfx/components/perplexity/perplexity.py +75 -0
- lfx/components/pgvector/__init__.py +34 -0
- lfx/components/pgvector/pgvector.py +72 -0
- lfx/components/pinecone/__init__.py +34 -0
- lfx/components/pinecone/pinecone.py +134 -0
- lfx/components/processing/__init__.py +117 -0
- lfx/components/processing/alter_metadata.py +108 -0
- lfx/components/processing/batch_run.py +205 -0
- lfx/components/processing/combine_text.py +39 -0
- lfx/components/processing/converter.py +159 -0
- lfx/components/processing/create_data.py +110 -0
- lfx/components/processing/data_operations.py +438 -0
- lfx/components/processing/data_to_dataframe.py +70 -0
- lfx/components/processing/dataframe_operations.py +313 -0
- lfx/components/processing/extract_key.py +53 -0
- lfx/components/processing/filter_data.py +42 -0
- lfx/components/processing/filter_data_values.py +88 -0
- lfx/components/processing/json_cleaner.py +103 -0
- lfx/components/processing/lambda_filter.py +154 -0
- lfx/components/processing/llm_router.py +499 -0
- lfx/components/processing/merge_data.py +90 -0
- lfx/components/processing/message_to_data.py +36 -0
- lfx/components/processing/parse_data.py +70 -0
- lfx/components/processing/parse_dataframe.py +68 -0
- lfx/components/processing/parse_json_data.py +90 -0
- lfx/components/processing/parser.py +143 -0
- lfx/components/processing/prompt.py +67 -0
- lfx/components/processing/python_repl_core.py +98 -0
- lfx/components/processing/regex.py +82 -0
- lfx/components/processing/save_file.py +225 -0
- lfx/components/processing/select_data.py +48 -0
- lfx/components/processing/split_text.py +141 -0
- lfx/components/processing/structured_output.py +202 -0
- lfx/components/processing/update_data.py +160 -0
- lfx/components/prototypes/__init__.py +34 -0
- lfx/components/prototypes/python_function.py +73 -0
- lfx/components/qdrant/__init__.py +34 -0
- lfx/components/qdrant/qdrant.py +109 -0
- lfx/components/redis/__init__.py +37 -0
- lfx/components/redis/redis.py +89 -0
- lfx/components/redis/redis_chat.py +43 -0
- lfx/components/sambanova/__init__.py +32 -0
- lfx/components/sambanova/sambanova.py +84 -0
- lfx/components/scrapegraph/__init__.py +40 -0
- lfx/components/scrapegraph/scrapegraph_markdownify_api.py +64 -0
- lfx/components/scrapegraph/scrapegraph_search_api.py +64 -0
- lfx/components/scrapegraph/scrapegraph_smart_scraper_api.py +71 -0
- lfx/components/searchapi/__init__.py +34 -0
- lfx/components/searchapi/search.py +79 -0
- lfx/components/serpapi/__init__.py +3 -0
- lfx/components/serpapi/serp.py +115 -0
- lfx/components/supabase/__init__.py +34 -0
- lfx/components/supabase/supabase.py +76 -0
- lfx/components/tavily/__init__.py +4 -0
- lfx/components/tavily/tavily_extract.py +117 -0
- lfx/components/tavily/tavily_search.py +212 -0
- lfx/components/textsplitters/__init__.py +3 -0
- lfx/components/toolkits/__init__.py +3 -0
- lfx/components/tools/__init__.py +72 -0
- lfx/components/tools/calculator.py +108 -0
- lfx/components/tools/google_search_api.py +45 -0
- lfx/components/tools/google_serper_api.py +115 -0
- lfx/components/tools/python_code_structured_tool.py +327 -0
- lfx/components/tools/python_repl.py +97 -0
- lfx/components/tools/search_api.py +87 -0
- lfx/components/tools/searxng.py +145 -0
- lfx/components/tools/serp_api.py +119 -0
- lfx/components/tools/tavily_search_tool.py +344 -0
- lfx/components/tools/wikidata_api.py +102 -0
- lfx/components/tools/wikipedia_api.py +49 -0
- lfx/components/tools/yahoo_finance.py +129 -0
- lfx/components/twelvelabs/__init__.py +52 -0
- lfx/components/twelvelabs/convert_astra_results.py +84 -0
- lfx/components/twelvelabs/pegasus_index.py +311 -0
- lfx/components/twelvelabs/split_video.py +291 -0
- lfx/components/twelvelabs/text_embeddings.py +57 -0
- lfx/components/twelvelabs/twelvelabs_pegasus.py +408 -0
- lfx/components/twelvelabs/video_embeddings.py +100 -0
- lfx/components/twelvelabs/video_file.py +179 -0
- lfx/components/unstructured/__init__.py +3 -0
- lfx/components/unstructured/unstructured.py +121 -0
- lfx/components/upstash/__init__.py +34 -0
- lfx/components/upstash/upstash.py +124 -0
- lfx/components/vectara/__init__.py +37 -0
- lfx/components/vectara/vectara.py +97 -0
- lfx/components/vectara/vectara_rag.py +164 -0
- lfx/components/vectorstores/__init__.py +40 -0
- lfx/components/vectorstores/astradb.py +1285 -0
- lfx/components/vectorstores/astradb_graph.py +319 -0
- lfx/components/vectorstores/cassandra.py +264 -0
- lfx/components/vectorstores/cassandra_graph.py +238 -0
- lfx/components/vectorstores/chroma.py +167 -0
- lfx/components/vectorstores/clickhouse.py +135 -0
- lfx/components/vectorstores/couchbase.py +102 -0
- lfx/components/vectorstores/elasticsearch.py +267 -0
- lfx/components/vectorstores/faiss.py +111 -0
- lfx/components/vectorstores/graph_rag.py +141 -0
- lfx/components/vectorstores/hcd.py +314 -0
- lfx/components/vectorstores/local_db.py +261 -0
- lfx/components/vectorstores/milvus.py +115 -0
- lfx/components/vectorstores/mongodb_atlas.py +213 -0
- lfx/components/vectorstores/opensearch.py +243 -0
- lfx/components/vectorstores/pgvector.py +72 -0
- lfx/components/vectorstores/pinecone.py +134 -0
- lfx/components/vectorstores/qdrant.py +109 -0
- lfx/components/vectorstores/supabase.py +76 -0
- lfx/components/vectorstores/upstash.py +124 -0
- lfx/components/vectorstores/vectara.py +97 -0
- lfx/components/vectorstores/vectara_rag.py +164 -0
- lfx/components/vectorstores/weaviate.py +89 -0
- lfx/components/vertexai/__init__.py +37 -0
- lfx/components/vertexai/vertexai.py +71 -0
- lfx/components/vertexai/vertexai_embeddings.py +67 -0
- lfx/components/weaviate/__init__.py +34 -0
- lfx/components/weaviate/weaviate.py +89 -0
- lfx/components/wikipedia/__init__.py +4 -0
- lfx/components/wikipedia/wikidata.py +86 -0
- lfx/components/wikipedia/wikipedia.py +53 -0
- lfx/components/wolframalpha/__init__.py +3 -0
- lfx/components/wolframalpha/wolfram_alpha_api.py +54 -0
- lfx/components/xai/__init__.py +32 -0
- lfx/components/xai/xai.py +167 -0
- lfx/components/yahoosearch/__init__.py +3 -0
- lfx/components/yahoosearch/yahoo.py +137 -0
- lfx/components/youtube/__init__.py +52 -0
- lfx/components/youtube/channel.py +227 -0
- lfx/components/youtube/comments.py +231 -0
- lfx/components/youtube/playlist.py +33 -0
- lfx/components/youtube/search.py +120 -0
- lfx/components/youtube/trending.py +285 -0
- lfx/components/youtube/video_details.py +263 -0
- lfx/components/youtube/youtube_transcripts.py +118 -0
- lfx/components/zep/__init__.py +3 -0
- lfx/components/zep/zep.py +44 -0
- lfx/constants.py +6 -0
- lfx/custom/__init__.py +7 -0
- lfx/custom/attributes.py +86 -0
- lfx/custom/code_parser/__init__.py +3 -0
- lfx/custom/code_parser/code_parser.py +361 -0
- lfx/custom/custom_component/__init__.py +0 -0
- lfx/custom/custom_component/base_component.py +128 -0
- lfx/custom/custom_component/component.py +1808 -0
- lfx/custom/custom_component/component_with_cache.py +8 -0
- lfx/custom/custom_component/custom_component.py +588 -0
- lfx/custom/dependency_analyzer.py +165 -0
- lfx/custom/directory_reader/__init__.py +3 -0
- lfx/custom/directory_reader/directory_reader.py +359 -0
- lfx/custom/directory_reader/utils.py +171 -0
- lfx/custom/eval.py +12 -0
- lfx/custom/schema.py +32 -0
- lfx/custom/tree_visitor.py +21 -0
- lfx/custom/utils.py +877 -0
- lfx/custom/validate.py +488 -0
- lfx/events/__init__.py +1 -0
- lfx/events/event_manager.py +110 -0
- lfx/exceptions/__init__.py +0 -0
- lfx/exceptions/component.py +15 -0
- lfx/field_typing/__init__.py +91 -0
- lfx/field_typing/constants.py +215 -0
- lfx/field_typing/range_spec.py +35 -0
- lfx/graph/__init__.py +6 -0
- lfx/graph/edge/__init__.py +0 -0
- lfx/graph/edge/base.py +277 -0
- lfx/graph/edge/schema.py +119 -0
- lfx/graph/edge/utils.py +0 -0
- lfx/graph/graph/__init__.py +0 -0
- lfx/graph/graph/ascii.py +202 -0
- lfx/graph/graph/base.py +2238 -0
- lfx/graph/graph/constants.py +63 -0
- lfx/graph/graph/runnable_vertices_manager.py +133 -0
- lfx/graph/graph/schema.py +52 -0
- lfx/graph/graph/state_model.py +66 -0
- lfx/graph/graph/utils.py +1024 -0
- lfx/graph/schema.py +75 -0
- lfx/graph/state/__init__.py +0 -0
- lfx/graph/state/model.py +237 -0
- lfx/graph/utils.py +200 -0
- lfx/graph/vertex/__init__.py +0 -0
- lfx/graph/vertex/base.py +823 -0
- lfx/graph/vertex/constants.py +0 -0
- lfx/graph/vertex/exceptions.py +4 -0
- lfx/graph/vertex/param_handler.py +264 -0
- lfx/graph/vertex/schema.py +26 -0
- lfx/graph/vertex/utils.py +19 -0
- lfx/graph/vertex/vertex_types.py +489 -0
- lfx/helpers/__init__.py +1 -0
- lfx/helpers/base_model.py +71 -0
- lfx/helpers/custom.py +13 -0
- lfx/helpers/data.py +167 -0
- lfx/helpers/flow.py +194 -0
- lfx/inputs/__init__.py +68 -0
- lfx/inputs/constants.py +2 -0
- lfx/inputs/input_mixin.py +328 -0
- lfx/inputs/inputs.py +714 -0
- lfx/inputs/validators.py +19 -0
- lfx/interface/__init__.py +6 -0
- lfx/interface/components.py +489 -0
- lfx/interface/importing/__init__.py +5 -0
- lfx/interface/importing/utils.py +39 -0
- lfx/interface/initialize/__init__.py +3 -0
- lfx/interface/initialize/loading.py +224 -0
- lfx/interface/listing.py +26 -0
- lfx/interface/run.py +16 -0
- lfx/interface/utils.py +111 -0
- lfx/io/__init__.py +63 -0
- lfx/io/schema.py +289 -0
- lfx/load/__init__.py +8 -0
- lfx/load/load.py +256 -0
- lfx/load/utils.py +99 -0
- lfx/log/__init__.py +5 -0
- lfx/log/logger.py +385 -0
- lfx/memory/__init__.py +90 -0
- lfx/memory/stubs.py +283 -0
- lfx/processing/__init__.py +1 -0
- lfx/processing/process.py +238 -0
- lfx/processing/utils.py +25 -0
- lfx/py.typed +0 -0
- lfx/schema/__init__.py +66 -0
- lfx/schema/artifact.py +83 -0
- lfx/schema/content_block.py +62 -0
- lfx/schema/content_types.py +91 -0
- lfx/schema/data.py +308 -0
- lfx/schema/dataframe.py +210 -0
- lfx/schema/dotdict.py +74 -0
- lfx/schema/encoders.py +13 -0
- lfx/schema/graph.py +47 -0
- lfx/schema/image.py +131 -0
- lfx/schema/json_schema.py +141 -0
- lfx/schema/log.py +61 -0
- lfx/schema/message.py +473 -0
- lfx/schema/openai_responses_schemas.py +74 -0
- lfx/schema/properties.py +41 -0
- lfx/schema/schema.py +171 -0
- lfx/schema/serialize.py +13 -0
- lfx/schema/table.py +140 -0
- lfx/schema/validators.py +114 -0
- lfx/serialization/__init__.py +5 -0
- lfx/serialization/constants.py +2 -0
- lfx/serialization/serialization.py +314 -0
- lfx/services/__init__.py +23 -0
- lfx/services/base.py +28 -0
- lfx/services/cache/__init__.py +6 -0
- lfx/services/cache/base.py +183 -0
- lfx/services/cache/service.py +166 -0
- lfx/services/cache/utils.py +169 -0
- lfx/services/chat/__init__.py +1 -0
- lfx/services/chat/config.py +2 -0
- lfx/services/chat/schema.py +10 -0
- lfx/services/deps.py +129 -0
- lfx/services/factory.py +19 -0
- lfx/services/initialize.py +19 -0
- lfx/services/interfaces.py +103 -0
- lfx/services/manager.py +172 -0
- lfx/services/schema.py +20 -0
- lfx/services/session.py +82 -0
- lfx/services/settings/__init__.py +3 -0
- lfx/services/settings/auth.py +130 -0
- lfx/services/settings/base.py +539 -0
- lfx/services/settings/constants.py +31 -0
- lfx/services/settings/factory.py +23 -0
- lfx/services/settings/feature_flags.py +12 -0
- lfx/services/settings/service.py +35 -0
- lfx/services/settings/utils.py +40 -0
- lfx/services/shared_component_cache/__init__.py +1 -0
- lfx/services/shared_component_cache/factory.py +30 -0
- lfx/services/shared_component_cache/service.py +9 -0
- lfx/services/storage/__init__.py +5 -0
- lfx/services/storage/local.py +155 -0
- lfx/services/storage/service.py +54 -0
- lfx/services/tracing/__init__.py +1 -0
- lfx/services/tracing/service.py +21 -0
- lfx/settings.py +6 -0
- lfx/template/__init__.py +6 -0
- lfx/template/field/__init__.py +0 -0
- lfx/template/field/base.py +257 -0
- lfx/template/field/prompt.py +15 -0
- lfx/template/frontend_node/__init__.py +6 -0
- lfx/template/frontend_node/base.py +212 -0
- lfx/template/frontend_node/constants.py +65 -0
- lfx/template/frontend_node/custom_components.py +79 -0
- lfx/template/template/__init__.py +0 -0
- lfx/template/template/base.py +100 -0
- lfx/template/utils.py +217 -0
- lfx/type_extraction/__init__.py +19 -0
- lfx/type_extraction/type_extraction.py +75 -0
- lfx/type_extraction.py +80 -0
- lfx/utils/__init__.py +1 -0
- lfx/utils/async_helpers.py +42 -0
- lfx/utils/component_utils.py +154 -0
- lfx/utils/concurrency.py +60 -0
- lfx/utils/connection_string_parser.py +11 -0
- lfx/utils/constants.py +205 -0
- lfx/utils/data_structure.py +212 -0
- lfx/utils/exceptions.py +22 -0
- lfx/utils/helpers.py +28 -0
- lfx/utils/image.py +73 -0
- lfx/utils/lazy_load.py +15 -0
- lfx/utils/request_utils.py +18 -0
- lfx/utils/schemas.py +139 -0
- lfx/utils/util.py +481 -0
- lfx/utils/util_strings.py +56 -0
- lfx/utils/version.py +24 -0
- lfx_nightly-0.1.11.dev0.dist-info/METADATA +293 -0
- lfx_nightly-0.1.11.dev0.dist-info/RECORD +699 -0
- lfx_nightly-0.1.11.dev0.dist-info/WHEEL +4 -0
- lfx_nightly-0.1.11.dev0.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,212 @@
|
|
1
|
+
import json
|
2
|
+
from collections import Counter
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
from lfx.schema.data import Data
|
6
|
+
|
7
|
+
|
8
|
+
def infer_list_type(items: list, max_samples: int = 5) -> str:
|
9
|
+
"""Infer the type of a list by sampling its items.
|
10
|
+
|
11
|
+
Handles mixed types and provides more detailed type information.
|
12
|
+
"""
|
13
|
+
if not items:
|
14
|
+
return "list(unknown)"
|
15
|
+
|
16
|
+
# Sample items (use all if less than max_samples)
|
17
|
+
samples = items[:max_samples]
|
18
|
+
types = [get_type_str(item) for item in samples]
|
19
|
+
|
20
|
+
# Count type occurrences
|
21
|
+
type_counter = Counter(types)
|
22
|
+
|
23
|
+
if len(type_counter) == 1:
|
24
|
+
# Single type
|
25
|
+
return f"list({types[0]})"
|
26
|
+
# Mixed types - show all found types
|
27
|
+
type_str = "|".join(sorted(type_counter.keys()))
|
28
|
+
return f"list({type_str})"
|
29
|
+
|
30
|
+
|
31
|
+
def get_type_str(value: Any) -> str:
|
32
|
+
"""Get a detailed string representation of the type of a value.
|
33
|
+
|
34
|
+
Handles special cases and provides more specific type information.
|
35
|
+
"""
|
36
|
+
if value is None:
|
37
|
+
return "null"
|
38
|
+
if isinstance(value, bool):
|
39
|
+
return "bool"
|
40
|
+
if isinstance(value, int):
|
41
|
+
return "int"
|
42
|
+
if isinstance(value, float):
|
43
|
+
return "float"
|
44
|
+
if isinstance(value, str):
|
45
|
+
# Check if string is actually a date/datetime
|
46
|
+
if any(date_pattern in value.lower() for date_pattern in ["date", "time", "yyyy", "mm/dd", "dd/mm", "yyyy-mm"]):
|
47
|
+
return "str(possible_date)"
|
48
|
+
# Check if it's a JSON string
|
49
|
+
try:
|
50
|
+
json.loads(value)
|
51
|
+
return "str(json)"
|
52
|
+
except (json.JSONDecodeError, TypeError):
|
53
|
+
pass
|
54
|
+
else:
|
55
|
+
return "str"
|
56
|
+
if isinstance(value, list | tuple | set):
|
57
|
+
return infer_list_type(list(value))
|
58
|
+
if isinstance(value, dict):
|
59
|
+
return "dict"
|
60
|
+
# Handle custom objects
|
61
|
+
return type(value).__name__
|
62
|
+
|
63
|
+
|
64
|
+
def analyze_value(
|
65
|
+
value: Any,
|
66
|
+
max_depth: int = 10,
|
67
|
+
current_depth: int = 0,
|
68
|
+
path: str = "",
|
69
|
+
*,
|
70
|
+
size_hints: bool = True,
|
71
|
+
include_samples: bool = True,
|
72
|
+
) -> str | dict:
|
73
|
+
"""Analyze a value and return its structure with additional metadata.
|
74
|
+
|
75
|
+
Args:
|
76
|
+
value: The value to analyze
|
77
|
+
max_depth: Maximum recursion depth
|
78
|
+
current_depth: Current recursion depth
|
79
|
+
path: Current path in the structure
|
80
|
+
size_hints: Whether to include size information for collections
|
81
|
+
include_samples: Whether to include sample structure for lists
|
82
|
+
"""
|
83
|
+
if current_depth >= max_depth:
|
84
|
+
return f"max_depth_reached(depth={max_depth})"
|
85
|
+
|
86
|
+
try:
|
87
|
+
if isinstance(value, list | tuple | set):
|
88
|
+
length = len(value)
|
89
|
+
if length == 0:
|
90
|
+
return "list(unknown)"
|
91
|
+
|
92
|
+
type_info = infer_list_type(list(value))
|
93
|
+
size_info = f"[size={length}]" if size_hints else ""
|
94
|
+
|
95
|
+
# For lists of complex objects, include a sample of the structure
|
96
|
+
if (
|
97
|
+
include_samples
|
98
|
+
and length > 0
|
99
|
+
and isinstance(value, list | tuple)
|
100
|
+
and isinstance(value[0], dict | list)
|
101
|
+
and current_depth < max_depth - 1
|
102
|
+
):
|
103
|
+
sample = analyze_value(
|
104
|
+
value[0],
|
105
|
+
max_depth,
|
106
|
+
current_depth + 1,
|
107
|
+
f"{path}[0]",
|
108
|
+
size_hints=size_hints,
|
109
|
+
include_samples=include_samples,
|
110
|
+
)
|
111
|
+
return f"{type_info}{size_info}, sample: {json.dumps(sample)}"
|
112
|
+
|
113
|
+
return f"{type_info}{size_info}"
|
114
|
+
|
115
|
+
if isinstance(value, dict):
|
116
|
+
result = {}
|
117
|
+
for k, v in value.items():
|
118
|
+
new_path = f"{path}.{k}" if path else k
|
119
|
+
try:
|
120
|
+
result[k] = analyze_value(
|
121
|
+
v,
|
122
|
+
max_depth,
|
123
|
+
current_depth + 1,
|
124
|
+
new_path,
|
125
|
+
size_hints=size_hints,
|
126
|
+
include_samples=include_samples,
|
127
|
+
)
|
128
|
+
except Exception as e: # noqa: BLE001
|
129
|
+
result[k] = f"error({e!s})"
|
130
|
+
return result
|
131
|
+
|
132
|
+
return get_type_str(value)
|
133
|
+
|
134
|
+
except Exception as e: # noqa: BLE001
|
135
|
+
return f"error({e!s})"
|
136
|
+
|
137
|
+
|
138
|
+
def get_data_structure(
|
139
|
+
data_obj: Data | dict,
|
140
|
+
max_depth: int = 10,
|
141
|
+
max_sample_size: int = 3,
|
142
|
+
*,
|
143
|
+
size_hints: bool = True,
|
144
|
+
include_sample_values: bool = False,
|
145
|
+
include_sample_structure: bool = True,
|
146
|
+
) -> dict:
|
147
|
+
"""Convert a Data object or dictionary into a detailed schema representation.
|
148
|
+
|
149
|
+
Args:
|
150
|
+
data_obj: The Data object or dictionary to analyze
|
151
|
+
max_depth: Maximum depth for nested structures
|
152
|
+
size_hints: Include size information for collections
|
153
|
+
include_sample_values: Whether to include sample values in the output
|
154
|
+
include_sample_structure: Whether to include sample structure for lists
|
155
|
+
max_sample_size: Maximum number of sample values to include
|
156
|
+
|
157
|
+
Returns:
|
158
|
+
dict: A dictionary containing:
|
159
|
+
- structure: The structure of the data
|
160
|
+
- samples: (optional) Sample values from the data
|
161
|
+
|
162
|
+
Example:
|
163
|
+
>>> data = {
|
164
|
+
... "name": "John",
|
165
|
+
... "scores": [1, 2, 3, 4, 5],
|
166
|
+
... "details": {
|
167
|
+
... "age": 30,
|
168
|
+
... "cities": ["NY", "LA", "SF", "CHI"],
|
169
|
+
... "metadata": {
|
170
|
+
... "created": "2023-01-01",
|
171
|
+
... "tags": ["user", "admin", 123]
|
172
|
+
... }
|
173
|
+
... }
|
174
|
+
... }
|
175
|
+
>>> result = get_data_structure(data)
|
176
|
+
{
|
177
|
+
"structure": {
|
178
|
+
"name": "str",
|
179
|
+
"scores": "list(int)[size=5]",
|
180
|
+
"details": {
|
181
|
+
"age": "int",
|
182
|
+
"cities": "list(str)[size=4]",
|
183
|
+
"metadata": {
|
184
|
+
"created": "str(possible_date)",
|
185
|
+
"tags": "list(str|int)[size=3]"
|
186
|
+
}
|
187
|
+
}
|
188
|
+
}
|
189
|
+
}
|
190
|
+
"""
|
191
|
+
# Handle both Data objects and dictionaries
|
192
|
+
data = data_obj.data if isinstance(data_obj, Data) else data_obj
|
193
|
+
|
194
|
+
result = {
|
195
|
+
"structure": analyze_value(
|
196
|
+
data, max_depth=max_depth, size_hints=size_hints, include_samples=include_sample_structure
|
197
|
+
)
|
198
|
+
}
|
199
|
+
|
200
|
+
if include_sample_values:
|
201
|
+
result["samples"] = get_sample_values(data, max_items=max_sample_size)
|
202
|
+
|
203
|
+
return result
|
204
|
+
|
205
|
+
|
206
|
+
def get_sample_values(data: Any, max_items: int = 3) -> Any:
|
207
|
+
"""Get sample values from a data structure, handling nested structures."""
|
208
|
+
if isinstance(data, list | tuple | set):
|
209
|
+
return [get_sample_values(item) for item in list(data)[:max_items]]
|
210
|
+
if isinstance(data, dict):
|
211
|
+
return {k: get_sample_values(v, max_items) for k, v in data.items()}
|
212
|
+
return data
|
lfx/utils/exceptions.py
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
def format_syntax_error_message(exc: SyntaxError) -> str:
|
2
|
+
"""Format a SyntaxError message for returning to the frontend."""
|
3
|
+
if exc.text is None:
|
4
|
+
return f"Syntax error in code. Error on line {exc.lineno}"
|
5
|
+
return f"Syntax error in code. Error on line {exc.lineno}: {exc.text.strip()}"
|
6
|
+
|
7
|
+
|
8
|
+
def get_causing_exception(exc: BaseException) -> BaseException:
|
9
|
+
"""Get the causing exception from an exception."""
|
10
|
+
if hasattr(exc, "__cause__") and exc.__cause__:
|
11
|
+
return get_causing_exception(exc.__cause__)
|
12
|
+
return exc
|
13
|
+
|
14
|
+
|
15
|
+
def format_exception_message(exc: Exception) -> str:
|
16
|
+
"""Format an exception message for returning to the frontend."""
|
17
|
+
# We need to check if the __cause__ is a SyntaxError
|
18
|
+
# If it is, we need to return the message of the SyntaxError
|
19
|
+
causing_exception = get_causing_exception(exc)
|
20
|
+
if isinstance(causing_exception, SyntaxError):
|
21
|
+
return format_syntax_error_message(causing_exception)
|
22
|
+
return str(exc)
|
lfx/utils/helpers.py
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
"""Helper utility functions for lfx package."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
import mimetypes
|
6
|
+
from typing import TYPE_CHECKING
|
7
|
+
|
8
|
+
if TYPE_CHECKING:
|
9
|
+
from pathlib import Path
|
10
|
+
|
11
|
+
|
12
|
+
def get_mime_type(file_path: str | Path) -> str:
|
13
|
+
"""Get the MIME type of a file based on its extension.
|
14
|
+
|
15
|
+
Args:
|
16
|
+
file_path: Path to the file
|
17
|
+
|
18
|
+
Returns:
|
19
|
+
MIME type string (e.g., 'image/jpeg', 'image/png')
|
20
|
+
|
21
|
+
Raises:
|
22
|
+
ValueError: If MIME type cannot be determined
|
23
|
+
"""
|
24
|
+
mime_type, _ = mimetypes.guess_type(str(file_path))
|
25
|
+
if mime_type is None:
|
26
|
+
msg = f"Could not determine MIME type for: {file_path}"
|
27
|
+
raise ValueError(msg)
|
28
|
+
return mime_type
|
lfx/utils/image.py
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
"""Image utility functions for lfx package."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
import base64
|
6
|
+
from functools import lru_cache
|
7
|
+
from pathlib import Path
|
8
|
+
|
9
|
+
from lfx.utils.helpers import get_mime_type
|
10
|
+
|
11
|
+
|
12
|
+
def convert_image_to_base64(image_path: str | Path) -> str:
|
13
|
+
"""Convert an image file to a base64 encoded string.
|
14
|
+
|
15
|
+
Args:
|
16
|
+
image_path: Path to the image file
|
17
|
+
|
18
|
+
Returns:
|
19
|
+
Base64 encoded string of the image
|
20
|
+
|
21
|
+
Raises:
|
22
|
+
FileNotFoundError: If the image file doesn't exist
|
23
|
+
"""
|
24
|
+
image_path = Path(image_path)
|
25
|
+
if not image_path.exists():
|
26
|
+
msg = f"Image file not found: {image_path}"
|
27
|
+
raise FileNotFoundError(msg)
|
28
|
+
|
29
|
+
with image_path.open("rb") as image_file:
|
30
|
+
return base64.b64encode(image_file.read()).decode("utf-8")
|
31
|
+
|
32
|
+
|
33
|
+
def create_data_url(image_path: str | Path, mime_type: str | None = None) -> str:
|
34
|
+
"""Create a data URL from an image file.
|
35
|
+
|
36
|
+
Args:
|
37
|
+
image_path: Path to the image file
|
38
|
+
mime_type: MIME type of the image. If None, will be auto-detected
|
39
|
+
|
40
|
+
Returns:
|
41
|
+
Data URL string in format: data:mime/type;base64,{base64_data}
|
42
|
+
|
43
|
+
Raises:
|
44
|
+
FileNotFoundError: If the image file doesn't exist
|
45
|
+
"""
|
46
|
+
image_path = Path(image_path)
|
47
|
+
if not image_path.exists():
|
48
|
+
msg = f"Image file not found: {image_path}"
|
49
|
+
raise FileNotFoundError(msg)
|
50
|
+
|
51
|
+
if mime_type is None:
|
52
|
+
mime_type = get_mime_type(image_path)
|
53
|
+
|
54
|
+
base64_data = convert_image_to_base64(image_path)
|
55
|
+
return f"data:{mime_type};base64,{base64_data}"
|
56
|
+
|
57
|
+
|
58
|
+
@lru_cache(maxsize=50)
|
59
|
+
def create_image_content_dict(image_path: str | Path, mime_type: str | None = None) -> dict:
|
60
|
+
"""Create a content dictionary for multimodal inputs from an image file.
|
61
|
+
|
62
|
+
Args:
|
63
|
+
image_path: Path to the image file
|
64
|
+
mime_type: MIME type of the image. If None, will be auto-detected
|
65
|
+
|
66
|
+
Returns:
|
67
|
+
Content dictionary with type, source_type, and url fields
|
68
|
+
|
69
|
+
Raises:
|
70
|
+
FileNotFoundError: If the image file doesn't exist
|
71
|
+
"""
|
72
|
+
data_url = create_data_url(image_path, mime_type)
|
73
|
+
return {"type": "image", "source_type": "url", "url": data_url}
|
lfx/utils/lazy_load.py
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
class LazyLoadDictBase:
|
2
|
+
def __init__(self) -> None:
|
3
|
+
self._all_types_dict = None
|
4
|
+
|
5
|
+
@property
|
6
|
+
def all_types_dict(self):
|
7
|
+
if self._all_types_dict is None:
|
8
|
+
self._all_types_dict = self._build_dict()
|
9
|
+
return self._all_types_dict
|
10
|
+
|
11
|
+
def _build_dict(self):
|
12
|
+
raise NotImplementedError
|
13
|
+
|
14
|
+
def get_type_dict(self):
|
15
|
+
raise NotImplementedError
|
@@ -0,0 +1,18 @@
|
|
1
|
+
from lfx.services.deps import get_settings_service
|
2
|
+
|
3
|
+
DEFAULT_USER_AGENT = "Langflow"
|
4
|
+
|
5
|
+
|
6
|
+
def get_user_agent():
|
7
|
+
"""Get user agent with fallback."""
|
8
|
+
try:
|
9
|
+
settings_service = get_settings_service()
|
10
|
+
if (
|
11
|
+
settings_service
|
12
|
+
and hasattr(settings_service, "settings")
|
13
|
+
and hasattr(settings_service.settings, "user_agent")
|
14
|
+
):
|
15
|
+
return settings_service.settings.user_agent
|
16
|
+
except (AttributeError, TypeError):
|
17
|
+
pass
|
18
|
+
return DEFAULT_USER_AGENT
|
lfx/utils/schemas.py
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
import enum
|
2
|
+
|
3
|
+
from langchain_core.messages import BaseMessage
|
4
|
+
from pydantic import BaseModel, field_validator, model_validator
|
5
|
+
from typing_extensions import TypedDict
|
6
|
+
|
7
|
+
from .constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_NAME_AI
|
8
|
+
|
9
|
+
# File types moved from lfx.base.data.utils
|
10
|
+
TEXT_FILE_TYPES = [
|
11
|
+
"txt",
|
12
|
+
"md",
|
13
|
+
"mdx",
|
14
|
+
"csv",
|
15
|
+
"json",
|
16
|
+
"yaml",
|
17
|
+
"yml",
|
18
|
+
"xml",
|
19
|
+
"html",
|
20
|
+
"htm",
|
21
|
+
"pdf",
|
22
|
+
"docx",
|
23
|
+
"py",
|
24
|
+
"sh",
|
25
|
+
"sql",
|
26
|
+
"js",
|
27
|
+
"ts",
|
28
|
+
"tsx",
|
29
|
+
]
|
30
|
+
IMG_FILE_TYPES = ["jpg", "jpeg", "png", "bmp", "image"]
|
31
|
+
|
32
|
+
|
33
|
+
class File(TypedDict):
|
34
|
+
"""File schema."""
|
35
|
+
|
36
|
+
path: str
|
37
|
+
name: str
|
38
|
+
type: str
|
39
|
+
|
40
|
+
|
41
|
+
class ChatOutputResponse(BaseModel):
|
42
|
+
"""Chat output response schema."""
|
43
|
+
|
44
|
+
message: str | list[str | dict]
|
45
|
+
sender: str | None = MESSAGE_SENDER_AI
|
46
|
+
sender_name: str | None = MESSAGE_SENDER_NAME_AI
|
47
|
+
session_id: str | None = None
|
48
|
+
stream_url: str | None = None
|
49
|
+
component_id: str | None = None
|
50
|
+
files: list[File] = []
|
51
|
+
type: str
|
52
|
+
|
53
|
+
@field_validator("files", mode="before")
|
54
|
+
@classmethod
|
55
|
+
def validate_files(cls, files):
|
56
|
+
"""Validate files."""
|
57
|
+
if not files:
|
58
|
+
return files
|
59
|
+
|
60
|
+
for file in files:
|
61
|
+
if not isinstance(file, dict):
|
62
|
+
msg = "Files must be a list of dictionaries."
|
63
|
+
raise ValueError(msg) # noqa: TRY004
|
64
|
+
|
65
|
+
if not all(key in file for key in ["path", "name", "type"]):
|
66
|
+
# If any of the keys are missing, we should extract the
|
67
|
+
# values from the file path
|
68
|
+
path = file.get("path")
|
69
|
+
if not path:
|
70
|
+
msg = "File path is required."
|
71
|
+
raise ValueError(msg)
|
72
|
+
|
73
|
+
name = file.get("name")
|
74
|
+
if not name:
|
75
|
+
name = path.split("/")[-1]
|
76
|
+
file["name"] = name
|
77
|
+
type_ = file.get("type")
|
78
|
+
if not type_:
|
79
|
+
# get the file type from the path
|
80
|
+
extension = path.split(".")[-1]
|
81
|
+
file_types = set(TEXT_FILE_TYPES + IMG_FILE_TYPES)
|
82
|
+
if extension and extension in file_types:
|
83
|
+
type_ = extension
|
84
|
+
else:
|
85
|
+
for file_type in file_types:
|
86
|
+
if file_type in path:
|
87
|
+
type_ = file_type
|
88
|
+
break
|
89
|
+
if not type_:
|
90
|
+
msg = "File type is required."
|
91
|
+
raise ValueError(msg)
|
92
|
+
file["type"] = type_
|
93
|
+
|
94
|
+
return files
|
95
|
+
|
96
|
+
@classmethod
|
97
|
+
def from_message(
|
98
|
+
cls,
|
99
|
+
message: BaseMessage,
|
100
|
+
sender: str | None = MESSAGE_SENDER_AI,
|
101
|
+
sender_name: str | None = MESSAGE_SENDER_NAME_AI,
|
102
|
+
):
|
103
|
+
"""Build chat output response from message."""
|
104
|
+
content = message.content
|
105
|
+
return cls(message=content, sender=sender, sender_name=sender_name)
|
106
|
+
|
107
|
+
@model_validator(mode="after")
|
108
|
+
def validate_message(self):
|
109
|
+
"""Validate message."""
|
110
|
+
# The idea here is ensure the \n in message
|
111
|
+
# is compliant with markdown if sender is machine
|
112
|
+
# so, for example:
|
113
|
+
# \n\n -> \n\n
|
114
|
+
# \n -> \n\n
|
115
|
+
|
116
|
+
if self.sender != MESSAGE_SENDER_AI:
|
117
|
+
return self
|
118
|
+
|
119
|
+
# We need to make sure we don't duplicate \n
|
120
|
+
# in the message
|
121
|
+
message = self.message.replace("\n\n", "\n")
|
122
|
+
self.message = message.replace("\n", "\n\n")
|
123
|
+
return self
|
124
|
+
|
125
|
+
|
126
|
+
class DataOutputResponse(BaseModel):
|
127
|
+
"""Data output response schema."""
|
128
|
+
|
129
|
+
data: list[dict | None]
|
130
|
+
|
131
|
+
|
132
|
+
class ContainsEnumMeta(enum.EnumMeta):
|
133
|
+
def __contains__(cls, item) -> bool:
|
134
|
+
try:
|
135
|
+
cls(item)
|
136
|
+
except ValueError:
|
137
|
+
return False
|
138
|
+
else:
|
139
|
+
return True
|