lfx-nightly 0.1.11.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lfx/__init__.py +0 -0
- lfx/__main__.py +25 -0
- lfx/base/__init__.py +0 -0
- lfx/base/agents/__init__.py +0 -0
- lfx/base/agents/agent.py +268 -0
- lfx/base/agents/callback.py +130 -0
- lfx/base/agents/context.py +109 -0
- lfx/base/agents/crewai/__init__.py +0 -0
- lfx/base/agents/crewai/crew.py +231 -0
- lfx/base/agents/crewai/tasks.py +12 -0
- lfx/base/agents/default_prompts.py +23 -0
- lfx/base/agents/errors.py +15 -0
- lfx/base/agents/events.py +346 -0
- lfx/base/agents/utils.py +205 -0
- lfx/base/astra_assistants/__init__.py +0 -0
- lfx/base/astra_assistants/util.py +171 -0
- lfx/base/chains/__init__.py +0 -0
- lfx/base/chains/model.py +19 -0
- lfx/base/composio/__init__.py +0 -0
- lfx/base/composio/composio_base.py +1291 -0
- lfx/base/compressors/__init__.py +0 -0
- lfx/base/compressors/model.py +60 -0
- lfx/base/constants.py +46 -0
- lfx/base/curl/__init__.py +0 -0
- lfx/base/curl/parse.py +188 -0
- lfx/base/data/__init__.py +5 -0
- lfx/base/data/base_file.py +685 -0
- lfx/base/data/docling_utils.py +245 -0
- lfx/base/data/utils.py +198 -0
- lfx/base/document_transformers/__init__.py +0 -0
- lfx/base/document_transformers/model.py +43 -0
- lfx/base/embeddings/__init__.py +0 -0
- lfx/base/embeddings/aiml_embeddings.py +62 -0
- lfx/base/embeddings/model.py +26 -0
- lfx/base/flow_processing/__init__.py +0 -0
- lfx/base/flow_processing/utils.py +86 -0
- lfx/base/huggingface/__init__.py +0 -0
- lfx/base/huggingface/model_bridge.py +133 -0
- lfx/base/io/__init__.py +0 -0
- lfx/base/io/chat.py +20 -0
- lfx/base/io/text.py +22 -0
- lfx/base/langchain_utilities/__init__.py +0 -0
- lfx/base/langchain_utilities/model.py +35 -0
- lfx/base/langchain_utilities/spider_constants.py +1 -0
- lfx/base/langwatch/__init__.py +0 -0
- lfx/base/langwatch/utils.py +18 -0
- lfx/base/mcp/__init__.py +0 -0
- lfx/base/mcp/constants.py +2 -0
- lfx/base/mcp/util.py +1398 -0
- lfx/base/memory/__init__.py +0 -0
- lfx/base/memory/memory.py +49 -0
- lfx/base/memory/model.py +38 -0
- lfx/base/models/__init__.py +3 -0
- lfx/base/models/aiml_constants.py +51 -0
- lfx/base/models/anthropic_constants.py +47 -0
- lfx/base/models/aws_constants.py +151 -0
- lfx/base/models/chat_result.py +76 -0
- lfx/base/models/google_generative_ai_constants.py +70 -0
- lfx/base/models/groq_constants.py +134 -0
- lfx/base/models/model.py +375 -0
- lfx/base/models/model_input_constants.py +307 -0
- lfx/base/models/model_metadata.py +41 -0
- lfx/base/models/model_utils.py +8 -0
- lfx/base/models/novita_constants.py +35 -0
- lfx/base/models/ollama_constants.py +49 -0
- lfx/base/models/openai_constants.py +122 -0
- lfx/base/models/sambanova_constants.py +18 -0
- lfx/base/processing/__init__.py +0 -0
- lfx/base/prompts/__init__.py +0 -0
- lfx/base/prompts/api_utils.py +224 -0
- lfx/base/prompts/utils.py +61 -0
- lfx/base/textsplitters/__init__.py +0 -0
- lfx/base/textsplitters/model.py +28 -0
- lfx/base/tools/__init__.py +0 -0
- lfx/base/tools/base.py +26 -0
- lfx/base/tools/component_tool.py +325 -0
- lfx/base/tools/constants.py +49 -0
- lfx/base/tools/flow_tool.py +132 -0
- lfx/base/tools/run_flow.py +224 -0
- lfx/base/vectorstores/__init__.py +0 -0
- lfx/base/vectorstores/model.py +193 -0
- lfx/base/vectorstores/utils.py +22 -0
- lfx/base/vectorstores/vector_store_connection_decorator.py +52 -0
- lfx/cli/__init__.py +5 -0
- lfx/cli/commands.py +319 -0
- lfx/cli/common.py +650 -0
- lfx/cli/run.py +441 -0
- lfx/cli/script_loader.py +247 -0
- lfx/cli/serve_app.py +546 -0
- lfx/cli/validation.py +69 -0
- lfx/components/FAISS/__init__.py +34 -0
- lfx/components/FAISS/faiss.py +111 -0
- lfx/components/Notion/__init__.py +19 -0
- lfx/components/Notion/add_content_to_page.py +269 -0
- lfx/components/Notion/create_page.py +94 -0
- lfx/components/Notion/list_database_properties.py +68 -0
- lfx/components/Notion/list_pages.py +122 -0
- lfx/components/Notion/list_users.py +77 -0
- lfx/components/Notion/page_content_viewer.py +93 -0
- lfx/components/Notion/search.py +111 -0
- lfx/components/Notion/update_page_property.py +114 -0
- lfx/components/__init__.py +411 -0
- lfx/components/_importing.py +42 -0
- lfx/components/agentql/__init__.py +3 -0
- lfx/components/agentql/agentql_api.py +151 -0
- lfx/components/agents/__init__.py +34 -0
- lfx/components/agents/agent.py +558 -0
- lfx/components/agents/mcp_component.py +501 -0
- lfx/components/aiml/__init__.py +37 -0
- lfx/components/aiml/aiml.py +112 -0
- lfx/components/aiml/aiml_embeddings.py +37 -0
- lfx/components/amazon/__init__.py +36 -0
- lfx/components/amazon/amazon_bedrock_embedding.py +109 -0
- lfx/components/amazon/amazon_bedrock_model.py +124 -0
- lfx/components/amazon/s3_bucket_uploader.py +211 -0
- lfx/components/anthropic/__init__.py +34 -0
- lfx/components/anthropic/anthropic.py +187 -0
- lfx/components/apify/__init__.py +5 -0
- lfx/components/apify/apify_actor.py +325 -0
- lfx/components/arxiv/__init__.py +3 -0
- lfx/components/arxiv/arxiv.py +163 -0
- lfx/components/assemblyai/__init__.py +46 -0
- lfx/components/assemblyai/assemblyai_get_subtitles.py +83 -0
- lfx/components/assemblyai/assemblyai_lemur.py +183 -0
- lfx/components/assemblyai/assemblyai_list_transcripts.py +95 -0
- lfx/components/assemblyai/assemblyai_poll_transcript.py +72 -0
- lfx/components/assemblyai/assemblyai_start_transcript.py +188 -0
- lfx/components/azure/__init__.py +37 -0
- lfx/components/azure/azure_openai.py +95 -0
- lfx/components/azure/azure_openai_embeddings.py +83 -0
- lfx/components/baidu/__init__.py +32 -0
- lfx/components/baidu/baidu_qianfan_chat.py +113 -0
- lfx/components/bing/__init__.py +3 -0
- lfx/components/bing/bing_search_api.py +61 -0
- lfx/components/cassandra/__init__.py +40 -0
- lfx/components/cassandra/cassandra.py +264 -0
- lfx/components/cassandra/cassandra_chat.py +92 -0
- lfx/components/cassandra/cassandra_graph.py +238 -0
- lfx/components/chains/__init__.py +3 -0
- lfx/components/chroma/__init__.py +34 -0
- lfx/components/chroma/chroma.py +167 -0
- lfx/components/cleanlab/__init__.py +40 -0
- lfx/components/cleanlab/cleanlab_evaluator.py +155 -0
- lfx/components/cleanlab/cleanlab_rag_evaluator.py +254 -0
- lfx/components/cleanlab/cleanlab_remediator.py +131 -0
- lfx/components/clickhouse/__init__.py +34 -0
- lfx/components/clickhouse/clickhouse.py +135 -0
- lfx/components/cloudflare/__init__.py +32 -0
- lfx/components/cloudflare/cloudflare.py +81 -0
- lfx/components/cohere/__init__.py +40 -0
- lfx/components/cohere/cohere_embeddings.py +81 -0
- lfx/components/cohere/cohere_models.py +46 -0
- lfx/components/cohere/cohere_rerank.py +51 -0
- lfx/components/composio/__init__.py +74 -0
- lfx/components/composio/composio_api.py +268 -0
- lfx/components/composio/dropbox_compnent.py +11 -0
- lfx/components/composio/github_composio.py +11 -0
- lfx/components/composio/gmail_composio.py +38 -0
- lfx/components/composio/googlecalendar_composio.py +11 -0
- lfx/components/composio/googlemeet_composio.py +11 -0
- lfx/components/composio/googletasks_composio.py +8 -0
- lfx/components/composio/linear_composio.py +11 -0
- lfx/components/composio/outlook_composio.py +11 -0
- lfx/components/composio/reddit_composio.py +11 -0
- lfx/components/composio/slack_composio.py +582 -0
- lfx/components/composio/slackbot_composio.py +11 -0
- lfx/components/composio/supabase_composio.py +11 -0
- lfx/components/composio/todoist_composio.py +11 -0
- lfx/components/composio/youtube_composio.py +11 -0
- lfx/components/confluence/__init__.py +3 -0
- lfx/components/confluence/confluence.py +84 -0
- lfx/components/couchbase/__init__.py +34 -0
- lfx/components/couchbase/couchbase.py +102 -0
- lfx/components/crewai/__init__.py +49 -0
- lfx/components/crewai/crewai.py +107 -0
- lfx/components/crewai/hierarchical_crew.py +46 -0
- lfx/components/crewai/hierarchical_task.py +44 -0
- lfx/components/crewai/sequential_crew.py +52 -0
- lfx/components/crewai/sequential_task.py +73 -0
- lfx/components/crewai/sequential_task_agent.py +143 -0
- lfx/components/custom_component/__init__.py +34 -0
- lfx/components/custom_component/custom_component.py +31 -0
- lfx/components/data/__init__.py +64 -0
- lfx/components/data/api_request.py +544 -0
- lfx/components/data/csv_to_data.py +95 -0
- lfx/components/data/directory.py +113 -0
- lfx/components/data/file.py +577 -0
- lfx/components/data/json_to_data.py +98 -0
- lfx/components/data/news_search.py +164 -0
- lfx/components/data/rss.py +69 -0
- lfx/components/data/sql_executor.py +101 -0
- lfx/components/data/url.py +311 -0
- lfx/components/data/web_search.py +112 -0
- lfx/components/data/webhook.py +56 -0
- lfx/components/datastax/__init__.py +70 -0
- lfx/components/datastax/astra_assistant_manager.py +306 -0
- lfx/components/datastax/astra_db.py +75 -0
- lfx/components/datastax/astra_vectorize.py +124 -0
- lfx/components/datastax/astradb.py +1285 -0
- lfx/components/datastax/astradb_cql.py +314 -0
- lfx/components/datastax/astradb_graph.py +330 -0
- lfx/components/datastax/astradb_tool.py +414 -0
- lfx/components/datastax/astradb_vectorstore.py +1285 -0
- lfx/components/datastax/cassandra.py +92 -0
- lfx/components/datastax/create_assistant.py +58 -0
- lfx/components/datastax/create_thread.py +32 -0
- lfx/components/datastax/dotenv.py +35 -0
- lfx/components/datastax/get_assistant.py +37 -0
- lfx/components/datastax/getenvvar.py +30 -0
- lfx/components/datastax/graph_rag.py +141 -0
- lfx/components/datastax/hcd.py +314 -0
- lfx/components/datastax/list_assistants.py +25 -0
- lfx/components/datastax/run.py +89 -0
- lfx/components/deactivated/__init__.py +15 -0
- lfx/components/deactivated/amazon_kendra.py +66 -0
- lfx/components/deactivated/chat_litellm_model.py +158 -0
- lfx/components/deactivated/code_block_extractor.py +26 -0
- lfx/components/deactivated/documents_to_data.py +22 -0
- lfx/components/deactivated/embed.py +16 -0
- lfx/components/deactivated/extract_key_from_data.py +46 -0
- lfx/components/deactivated/json_document_builder.py +57 -0
- lfx/components/deactivated/list_flows.py +20 -0
- lfx/components/deactivated/mcp_sse.py +61 -0
- lfx/components/deactivated/mcp_stdio.py +62 -0
- lfx/components/deactivated/merge_data.py +93 -0
- lfx/components/deactivated/message.py +37 -0
- lfx/components/deactivated/metal.py +54 -0
- lfx/components/deactivated/multi_query.py +59 -0
- lfx/components/deactivated/retriever.py +43 -0
- lfx/components/deactivated/selective_passthrough.py +77 -0
- lfx/components/deactivated/should_run_next.py +40 -0
- lfx/components/deactivated/split_text.py +63 -0
- lfx/components/deactivated/store_message.py +24 -0
- lfx/components/deactivated/sub_flow.py +124 -0
- lfx/components/deactivated/vectara_self_query.py +76 -0
- lfx/components/deactivated/vector_store.py +24 -0
- lfx/components/deepseek/__init__.py +34 -0
- lfx/components/deepseek/deepseek.py +136 -0
- lfx/components/docling/__init__.py +43 -0
- lfx/components/docling/chunk_docling_document.py +186 -0
- lfx/components/docling/docling_inline.py +231 -0
- lfx/components/docling/docling_remote.py +193 -0
- lfx/components/docling/export_docling_document.py +117 -0
- lfx/components/documentloaders/__init__.py +3 -0
- lfx/components/duckduckgo/__init__.py +3 -0
- lfx/components/duckduckgo/duck_duck_go_search_run.py +92 -0
- lfx/components/elastic/__init__.py +37 -0
- lfx/components/elastic/elasticsearch.py +267 -0
- lfx/components/elastic/opensearch.py +243 -0
- lfx/components/embeddings/__init__.py +37 -0
- lfx/components/embeddings/similarity.py +76 -0
- lfx/components/embeddings/text_embedder.py +64 -0
- lfx/components/exa/__init__.py +3 -0
- lfx/components/exa/exa_search.py +68 -0
- lfx/components/firecrawl/__init__.py +43 -0
- lfx/components/firecrawl/firecrawl_crawl_api.py +88 -0
- lfx/components/firecrawl/firecrawl_extract_api.py +136 -0
- lfx/components/firecrawl/firecrawl_map_api.py +89 -0
- lfx/components/firecrawl/firecrawl_scrape_api.py +73 -0
- lfx/components/git/__init__.py +4 -0
- lfx/components/git/git.py +262 -0
- lfx/components/git/gitextractor.py +196 -0
- lfx/components/glean/__init__.py +3 -0
- lfx/components/glean/glean_search_api.py +173 -0
- lfx/components/google/__init__.py +17 -0
- lfx/components/google/gmail.py +192 -0
- lfx/components/google/google_bq_sql_executor.py +157 -0
- lfx/components/google/google_drive.py +92 -0
- lfx/components/google/google_drive_search.py +152 -0
- lfx/components/google/google_generative_ai.py +147 -0
- lfx/components/google/google_generative_ai_embeddings.py +141 -0
- lfx/components/google/google_oauth_token.py +89 -0
- lfx/components/google/google_search_api_core.py +68 -0
- lfx/components/google/google_serper_api_core.py +74 -0
- lfx/components/groq/__init__.py +34 -0
- lfx/components/groq/groq.py +136 -0
- lfx/components/helpers/__init__.py +52 -0
- lfx/components/helpers/calculator_core.py +89 -0
- lfx/components/helpers/create_list.py +40 -0
- lfx/components/helpers/current_date.py +42 -0
- lfx/components/helpers/id_generator.py +42 -0
- lfx/components/helpers/memory.py +251 -0
- lfx/components/helpers/output_parser.py +45 -0
- lfx/components/helpers/store_message.py +90 -0
- lfx/components/homeassistant/__init__.py +7 -0
- lfx/components/homeassistant/home_assistant_control.py +152 -0
- lfx/components/homeassistant/list_home_assistant_states.py +137 -0
- lfx/components/huggingface/__init__.py +37 -0
- lfx/components/huggingface/huggingface.py +197 -0
- lfx/components/huggingface/huggingface_inference_api.py +106 -0
- lfx/components/ibm/__init__.py +34 -0
- lfx/components/ibm/watsonx.py +203 -0
- lfx/components/ibm/watsonx_embeddings.py +135 -0
- lfx/components/icosacomputing/__init__.py +5 -0
- lfx/components/icosacomputing/combinatorial_reasoner.py +84 -0
- lfx/components/input_output/__init__.py +38 -0
- lfx/components/input_output/chat.py +120 -0
- lfx/components/input_output/chat_output.py +200 -0
- lfx/components/input_output/text.py +27 -0
- lfx/components/input_output/text_output.py +29 -0
- lfx/components/jigsawstack/__init__.py +23 -0
- lfx/components/jigsawstack/ai_scrape.py +126 -0
- lfx/components/jigsawstack/ai_web_search.py +136 -0
- lfx/components/jigsawstack/file_read.py +115 -0
- lfx/components/jigsawstack/file_upload.py +94 -0
- lfx/components/jigsawstack/image_generation.py +205 -0
- lfx/components/jigsawstack/nsfw.py +60 -0
- lfx/components/jigsawstack/object_detection.py +124 -0
- lfx/components/jigsawstack/sentiment.py +112 -0
- lfx/components/jigsawstack/text_to_sql.py +90 -0
- lfx/components/jigsawstack/text_translate.py +77 -0
- lfx/components/jigsawstack/vocr.py +107 -0
- lfx/components/langchain_utilities/__init__.py +109 -0
- lfx/components/langchain_utilities/character.py +53 -0
- lfx/components/langchain_utilities/conversation.py +59 -0
- lfx/components/langchain_utilities/csv_agent.py +107 -0
- lfx/components/langchain_utilities/fake_embeddings.py +26 -0
- lfx/components/langchain_utilities/html_link_extractor.py +35 -0
- lfx/components/langchain_utilities/json_agent.py +45 -0
- lfx/components/langchain_utilities/langchain_hub.py +126 -0
- lfx/components/langchain_utilities/language_recursive.py +49 -0
- lfx/components/langchain_utilities/language_semantic.py +138 -0
- lfx/components/langchain_utilities/llm_checker.py +39 -0
- lfx/components/langchain_utilities/llm_math.py +42 -0
- lfx/components/langchain_utilities/natural_language.py +61 -0
- lfx/components/langchain_utilities/openai_tools.py +53 -0
- lfx/components/langchain_utilities/openapi.py +48 -0
- lfx/components/langchain_utilities/recursive_character.py +60 -0
- lfx/components/langchain_utilities/retrieval_qa.py +83 -0
- lfx/components/langchain_utilities/runnable_executor.py +137 -0
- lfx/components/langchain_utilities/self_query.py +80 -0
- lfx/components/langchain_utilities/spider.py +142 -0
- lfx/components/langchain_utilities/sql.py +40 -0
- lfx/components/langchain_utilities/sql_database.py +35 -0
- lfx/components/langchain_utilities/sql_generator.py +78 -0
- lfx/components/langchain_utilities/tool_calling.py +59 -0
- lfx/components/langchain_utilities/vector_store_info.py +49 -0
- lfx/components/langchain_utilities/vector_store_router.py +33 -0
- lfx/components/langchain_utilities/xml_agent.py +71 -0
- lfx/components/langwatch/__init__.py +3 -0
- lfx/components/langwatch/langwatch.py +278 -0
- lfx/components/link_extractors/__init__.py +3 -0
- lfx/components/lmstudio/__init__.py +34 -0
- lfx/components/lmstudio/lmstudioembeddings.py +89 -0
- lfx/components/lmstudio/lmstudiomodel.py +129 -0
- lfx/components/logic/__init__.py +52 -0
- lfx/components/logic/conditional_router.py +171 -0
- lfx/components/logic/data_conditional_router.py +125 -0
- lfx/components/logic/flow_tool.py +110 -0
- lfx/components/logic/listen.py +29 -0
- lfx/components/logic/loop.py +125 -0
- lfx/components/logic/notify.py +88 -0
- lfx/components/logic/pass_message.py +35 -0
- lfx/components/logic/run_flow.py +71 -0
- lfx/components/logic/sub_flow.py +114 -0
- lfx/components/maritalk/__init__.py +32 -0
- lfx/components/maritalk/maritalk.py +52 -0
- lfx/components/mem0/__init__.py +3 -0
- lfx/components/mem0/mem0_chat_memory.py +136 -0
- lfx/components/milvus/__init__.py +34 -0
- lfx/components/milvus/milvus.py +115 -0
- lfx/components/mistral/__init__.py +37 -0
- lfx/components/mistral/mistral.py +114 -0
- lfx/components/mistral/mistral_embeddings.py +58 -0
- lfx/components/models/__init__.py +34 -0
- lfx/components/models/embedding_model.py +114 -0
- lfx/components/models/language_model.py +144 -0
- lfx/components/mongodb/__init__.py +34 -0
- lfx/components/mongodb/mongodb_atlas.py +213 -0
- lfx/components/needle/__init__.py +3 -0
- lfx/components/needle/needle.py +104 -0
- lfx/components/notdiamond/__init__.py +34 -0
- lfx/components/notdiamond/notdiamond.py +228 -0
- lfx/components/novita/__init__.py +32 -0
- lfx/components/novita/novita.py +130 -0
- lfx/components/nvidia/__init__.py +57 -0
- lfx/components/nvidia/nvidia.py +157 -0
- lfx/components/nvidia/nvidia_embedding.py +77 -0
- lfx/components/nvidia/nvidia_ingest.py +317 -0
- lfx/components/nvidia/nvidia_rerank.py +63 -0
- lfx/components/nvidia/system_assist.py +65 -0
- lfx/components/olivya/__init__.py +3 -0
- lfx/components/olivya/olivya.py +116 -0
- lfx/components/ollama/__init__.py +37 -0
- lfx/components/ollama/ollama.py +330 -0
- lfx/components/ollama/ollama_embeddings.py +106 -0
- lfx/components/openai/__init__.py +37 -0
- lfx/components/openai/openai.py +100 -0
- lfx/components/openai/openai_chat_model.py +176 -0
- lfx/components/openrouter/__init__.py +32 -0
- lfx/components/openrouter/openrouter.py +202 -0
- lfx/components/output_parsers/__init__.py +3 -0
- lfx/components/perplexity/__init__.py +34 -0
- lfx/components/perplexity/perplexity.py +75 -0
- lfx/components/pgvector/__init__.py +34 -0
- lfx/components/pgvector/pgvector.py +72 -0
- lfx/components/pinecone/__init__.py +34 -0
- lfx/components/pinecone/pinecone.py +134 -0
- lfx/components/processing/__init__.py +117 -0
- lfx/components/processing/alter_metadata.py +108 -0
- lfx/components/processing/batch_run.py +205 -0
- lfx/components/processing/combine_text.py +39 -0
- lfx/components/processing/converter.py +159 -0
- lfx/components/processing/create_data.py +110 -0
- lfx/components/processing/data_operations.py +438 -0
- lfx/components/processing/data_to_dataframe.py +70 -0
- lfx/components/processing/dataframe_operations.py +313 -0
- lfx/components/processing/extract_key.py +53 -0
- lfx/components/processing/filter_data.py +42 -0
- lfx/components/processing/filter_data_values.py +88 -0
- lfx/components/processing/json_cleaner.py +103 -0
- lfx/components/processing/lambda_filter.py +154 -0
- lfx/components/processing/llm_router.py +499 -0
- lfx/components/processing/merge_data.py +90 -0
- lfx/components/processing/message_to_data.py +36 -0
- lfx/components/processing/parse_data.py +70 -0
- lfx/components/processing/parse_dataframe.py +68 -0
- lfx/components/processing/parse_json_data.py +90 -0
- lfx/components/processing/parser.py +143 -0
- lfx/components/processing/prompt.py +67 -0
- lfx/components/processing/python_repl_core.py +98 -0
- lfx/components/processing/regex.py +82 -0
- lfx/components/processing/save_file.py +225 -0
- lfx/components/processing/select_data.py +48 -0
- lfx/components/processing/split_text.py +141 -0
- lfx/components/processing/structured_output.py +202 -0
- lfx/components/processing/update_data.py +160 -0
- lfx/components/prototypes/__init__.py +34 -0
- lfx/components/prototypes/python_function.py +73 -0
- lfx/components/qdrant/__init__.py +34 -0
- lfx/components/qdrant/qdrant.py +109 -0
- lfx/components/redis/__init__.py +37 -0
- lfx/components/redis/redis.py +89 -0
- lfx/components/redis/redis_chat.py +43 -0
- lfx/components/sambanova/__init__.py +32 -0
- lfx/components/sambanova/sambanova.py +84 -0
- lfx/components/scrapegraph/__init__.py +40 -0
- lfx/components/scrapegraph/scrapegraph_markdownify_api.py +64 -0
- lfx/components/scrapegraph/scrapegraph_search_api.py +64 -0
- lfx/components/scrapegraph/scrapegraph_smart_scraper_api.py +71 -0
- lfx/components/searchapi/__init__.py +34 -0
- lfx/components/searchapi/search.py +79 -0
- lfx/components/serpapi/__init__.py +3 -0
- lfx/components/serpapi/serp.py +115 -0
- lfx/components/supabase/__init__.py +34 -0
- lfx/components/supabase/supabase.py +76 -0
- lfx/components/tavily/__init__.py +4 -0
- lfx/components/tavily/tavily_extract.py +117 -0
- lfx/components/tavily/tavily_search.py +212 -0
- lfx/components/textsplitters/__init__.py +3 -0
- lfx/components/toolkits/__init__.py +3 -0
- lfx/components/tools/__init__.py +72 -0
- lfx/components/tools/calculator.py +108 -0
- lfx/components/tools/google_search_api.py +45 -0
- lfx/components/tools/google_serper_api.py +115 -0
- lfx/components/tools/python_code_structured_tool.py +327 -0
- lfx/components/tools/python_repl.py +97 -0
- lfx/components/tools/search_api.py +87 -0
- lfx/components/tools/searxng.py +145 -0
- lfx/components/tools/serp_api.py +119 -0
- lfx/components/tools/tavily_search_tool.py +344 -0
- lfx/components/tools/wikidata_api.py +102 -0
- lfx/components/tools/wikipedia_api.py +49 -0
- lfx/components/tools/yahoo_finance.py +129 -0
- lfx/components/twelvelabs/__init__.py +52 -0
- lfx/components/twelvelabs/convert_astra_results.py +84 -0
- lfx/components/twelvelabs/pegasus_index.py +311 -0
- lfx/components/twelvelabs/split_video.py +291 -0
- lfx/components/twelvelabs/text_embeddings.py +57 -0
- lfx/components/twelvelabs/twelvelabs_pegasus.py +408 -0
- lfx/components/twelvelabs/video_embeddings.py +100 -0
- lfx/components/twelvelabs/video_file.py +179 -0
- lfx/components/unstructured/__init__.py +3 -0
- lfx/components/unstructured/unstructured.py +121 -0
- lfx/components/upstash/__init__.py +34 -0
- lfx/components/upstash/upstash.py +124 -0
- lfx/components/vectara/__init__.py +37 -0
- lfx/components/vectara/vectara.py +97 -0
- lfx/components/vectara/vectara_rag.py +164 -0
- lfx/components/vectorstores/__init__.py +40 -0
- lfx/components/vectorstores/astradb.py +1285 -0
- lfx/components/vectorstores/astradb_graph.py +319 -0
- lfx/components/vectorstores/cassandra.py +264 -0
- lfx/components/vectorstores/cassandra_graph.py +238 -0
- lfx/components/vectorstores/chroma.py +167 -0
- lfx/components/vectorstores/clickhouse.py +135 -0
- lfx/components/vectorstores/couchbase.py +102 -0
- lfx/components/vectorstores/elasticsearch.py +267 -0
- lfx/components/vectorstores/faiss.py +111 -0
- lfx/components/vectorstores/graph_rag.py +141 -0
- lfx/components/vectorstores/hcd.py +314 -0
- lfx/components/vectorstores/local_db.py +261 -0
- lfx/components/vectorstores/milvus.py +115 -0
- lfx/components/vectorstores/mongodb_atlas.py +213 -0
- lfx/components/vectorstores/opensearch.py +243 -0
- lfx/components/vectorstores/pgvector.py +72 -0
- lfx/components/vectorstores/pinecone.py +134 -0
- lfx/components/vectorstores/qdrant.py +109 -0
- lfx/components/vectorstores/supabase.py +76 -0
- lfx/components/vectorstores/upstash.py +124 -0
- lfx/components/vectorstores/vectara.py +97 -0
- lfx/components/vectorstores/vectara_rag.py +164 -0
- lfx/components/vectorstores/weaviate.py +89 -0
- lfx/components/vertexai/__init__.py +37 -0
- lfx/components/vertexai/vertexai.py +71 -0
- lfx/components/vertexai/vertexai_embeddings.py +67 -0
- lfx/components/weaviate/__init__.py +34 -0
- lfx/components/weaviate/weaviate.py +89 -0
- lfx/components/wikipedia/__init__.py +4 -0
- lfx/components/wikipedia/wikidata.py +86 -0
- lfx/components/wikipedia/wikipedia.py +53 -0
- lfx/components/wolframalpha/__init__.py +3 -0
- lfx/components/wolframalpha/wolfram_alpha_api.py +54 -0
- lfx/components/xai/__init__.py +32 -0
- lfx/components/xai/xai.py +167 -0
- lfx/components/yahoosearch/__init__.py +3 -0
- lfx/components/yahoosearch/yahoo.py +137 -0
- lfx/components/youtube/__init__.py +52 -0
- lfx/components/youtube/channel.py +227 -0
- lfx/components/youtube/comments.py +231 -0
- lfx/components/youtube/playlist.py +33 -0
- lfx/components/youtube/search.py +120 -0
- lfx/components/youtube/trending.py +285 -0
- lfx/components/youtube/video_details.py +263 -0
- lfx/components/youtube/youtube_transcripts.py +118 -0
- lfx/components/zep/__init__.py +3 -0
- lfx/components/zep/zep.py +44 -0
- lfx/constants.py +6 -0
- lfx/custom/__init__.py +7 -0
- lfx/custom/attributes.py +86 -0
- lfx/custom/code_parser/__init__.py +3 -0
- lfx/custom/code_parser/code_parser.py +361 -0
- lfx/custom/custom_component/__init__.py +0 -0
- lfx/custom/custom_component/base_component.py +128 -0
- lfx/custom/custom_component/component.py +1808 -0
- lfx/custom/custom_component/component_with_cache.py +8 -0
- lfx/custom/custom_component/custom_component.py +588 -0
- lfx/custom/dependency_analyzer.py +165 -0
- lfx/custom/directory_reader/__init__.py +3 -0
- lfx/custom/directory_reader/directory_reader.py +359 -0
- lfx/custom/directory_reader/utils.py +171 -0
- lfx/custom/eval.py +12 -0
- lfx/custom/schema.py +32 -0
- lfx/custom/tree_visitor.py +21 -0
- lfx/custom/utils.py +877 -0
- lfx/custom/validate.py +488 -0
- lfx/events/__init__.py +1 -0
- lfx/events/event_manager.py +110 -0
- lfx/exceptions/__init__.py +0 -0
- lfx/exceptions/component.py +15 -0
- lfx/field_typing/__init__.py +91 -0
- lfx/field_typing/constants.py +215 -0
- lfx/field_typing/range_spec.py +35 -0
- lfx/graph/__init__.py +6 -0
- lfx/graph/edge/__init__.py +0 -0
- lfx/graph/edge/base.py +277 -0
- lfx/graph/edge/schema.py +119 -0
- lfx/graph/edge/utils.py +0 -0
- lfx/graph/graph/__init__.py +0 -0
- lfx/graph/graph/ascii.py +202 -0
- lfx/graph/graph/base.py +2238 -0
- lfx/graph/graph/constants.py +63 -0
- lfx/graph/graph/runnable_vertices_manager.py +133 -0
- lfx/graph/graph/schema.py +52 -0
- lfx/graph/graph/state_model.py +66 -0
- lfx/graph/graph/utils.py +1024 -0
- lfx/graph/schema.py +75 -0
- lfx/graph/state/__init__.py +0 -0
- lfx/graph/state/model.py +237 -0
- lfx/graph/utils.py +200 -0
- lfx/graph/vertex/__init__.py +0 -0
- lfx/graph/vertex/base.py +823 -0
- lfx/graph/vertex/constants.py +0 -0
- lfx/graph/vertex/exceptions.py +4 -0
- lfx/graph/vertex/param_handler.py +264 -0
- lfx/graph/vertex/schema.py +26 -0
- lfx/graph/vertex/utils.py +19 -0
- lfx/graph/vertex/vertex_types.py +489 -0
- lfx/helpers/__init__.py +1 -0
- lfx/helpers/base_model.py +71 -0
- lfx/helpers/custom.py +13 -0
- lfx/helpers/data.py +167 -0
- lfx/helpers/flow.py +194 -0
- lfx/inputs/__init__.py +68 -0
- lfx/inputs/constants.py +2 -0
- lfx/inputs/input_mixin.py +328 -0
- lfx/inputs/inputs.py +714 -0
- lfx/inputs/validators.py +19 -0
- lfx/interface/__init__.py +6 -0
- lfx/interface/components.py +489 -0
- lfx/interface/importing/__init__.py +5 -0
- lfx/interface/importing/utils.py +39 -0
- lfx/interface/initialize/__init__.py +3 -0
- lfx/interface/initialize/loading.py +224 -0
- lfx/interface/listing.py +26 -0
- lfx/interface/run.py +16 -0
- lfx/interface/utils.py +111 -0
- lfx/io/__init__.py +63 -0
- lfx/io/schema.py +289 -0
- lfx/load/__init__.py +8 -0
- lfx/load/load.py +256 -0
- lfx/load/utils.py +99 -0
- lfx/log/__init__.py +5 -0
- lfx/log/logger.py +385 -0
- lfx/memory/__init__.py +90 -0
- lfx/memory/stubs.py +283 -0
- lfx/processing/__init__.py +1 -0
- lfx/processing/process.py +238 -0
- lfx/processing/utils.py +25 -0
- lfx/py.typed +0 -0
- lfx/schema/__init__.py +66 -0
- lfx/schema/artifact.py +83 -0
- lfx/schema/content_block.py +62 -0
- lfx/schema/content_types.py +91 -0
- lfx/schema/data.py +308 -0
- lfx/schema/dataframe.py +210 -0
- lfx/schema/dotdict.py +74 -0
- lfx/schema/encoders.py +13 -0
- lfx/schema/graph.py +47 -0
- lfx/schema/image.py +131 -0
- lfx/schema/json_schema.py +141 -0
- lfx/schema/log.py +61 -0
- lfx/schema/message.py +473 -0
- lfx/schema/openai_responses_schemas.py +74 -0
- lfx/schema/properties.py +41 -0
- lfx/schema/schema.py +171 -0
- lfx/schema/serialize.py +13 -0
- lfx/schema/table.py +140 -0
- lfx/schema/validators.py +114 -0
- lfx/serialization/__init__.py +5 -0
- lfx/serialization/constants.py +2 -0
- lfx/serialization/serialization.py +314 -0
- lfx/services/__init__.py +23 -0
- lfx/services/base.py +28 -0
- lfx/services/cache/__init__.py +6 -0
- lfx/services/cache/base.py +183 -0
- lfx/services/cache/service.py +166 -0
- lfx/services/cache/utils.py +169 -0
- lfx/services/chat/__init__.py +1 -0
- lfx/services/chat/config.py +2 -0
- lfx/services/chat/schema.py +10 -0
- lfx/services/deps.py +129 -0
- lfx/services/factory.py +19 -0
- lfx/services/initialize.py +19 -0
- lfx/services/interfaces.py +103 -0
- lfx/services/manager.py +172 -0
- lfx/services/schema.py +20 -0
- lfx/services/session.py +82 -0
- lfx/services/settings/__init__.py +3 -0
- lfx/services/settings/auth.py +130 -0
- lfx/services/settings/base.py +539 -0
- lfx/services/settings/constants.py +31 -0
- lfx/services/settings/factory.py +23 -0
- lfx/services/settings/feature_flags.py +12 -0
- lfx/services/settings/service.py +35 -0
- lfx/services/settings/utils.py +40 -0
- lfx/services/shared_component_cache/__init__.py +1 -0
- lfx/services/shared_component_cache/factory.py +30 -0
- lfx/services/shared_component_cache/service.py +9 -0
- lfx/services/storage/__init__.py +5 -0
- lfx/services/storage/local.py +155 -0
- lfx/services/storage/service.py +54 -0
- lfx/services/tracing/__init__.py +1 -0
- lfx/services/tracing/service.py +21 -0
- lfx/settings.py +6 -0
- lfx/template/__init__.py +6 -0
- lfx/template/field/__init__.py +0 -0
- lfx/template/field/base.py +257 -0
- lfx/template/field/prompt.py +15 -0
- lfx/template/frontend_node/__init__.py +6 -0
- lfx/template/frontend_node/base.py +212 -0
- lfx/template/frontend_node/constants.py +65 -0
- lfx/template/frontend_node/custom_components.py +79 -0
- lfx/template/template/__init__.py +0 -0
- lfx/template/template/base.py +100 -0
- lfx/template/utils.py +217 -0
- lfx/type_extraction/__init__.py +19 -0
- lfx/type_extraction/type_extraction.py +75 -0
- lfx/type_extraction.py +80 -0
- lfx/utils/__init__.py +1 -0
- lfx/utils/async_helpers.py +42 -0
- lfx/utils/component_utils.py +154 -0
- lfx/utils/concurrency.py +60 -0
- lfx/utils/connection_string_parser.py +11 -0
- lfx/utils/constants.py +205 -0
- lfx/utils/data_structure.py +212 -0
- lfx/utils/exceptions.py +22 -0
- lfx/utils/helpers.py +28 -0
- lfx/utils/image.py +73 -0
- lfx/utils/lazy_load.py +15 -0
- lfx/utils/request_utils.py +18 -0
- lfx/utils/schemas.py +139 -0
- lfx/utils/util.py +481 -0
- lfx/utils/util_strings.py +56 -0
- lfx/utils/version.py +24 -0
- lfx_nightly-0.1.11.dev0.dist-info/METADATA +293 -0
- lfx_nightly-0.1.11.dev0.dist-info/RECORD +699 -0
- lfx_nightly-0.1.11.dev0.dist-info/WHEEL +4 -0
- lfx_nightly-0.1.11.dev0.dist-info/entry_points.txt +2 -0
lfx/schema/message.py
ADDED
@@ -0,0 +1,473 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import asyncio
|
4
|
+
import json
|
5
|
+
import re
|
6
|
+
import traceback
|
7
|
+
from collections.abc import AsyncIterator, Iterator
|
8
|
+
from datetime import datetime, timezone
|
9
|
+
from typing import TYPE_CHECKING, Annotated, Any, Literal
|
10
|
+
from uuid import UUID
|
11
|
+
|
12
|
+
from fastapi.encoders import jsonable_encoder
|
13
|
+
from langchain_core.load import load
|
14
|
+
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, SystemMessage
|
15
|
+
from langchain_core.prompts.chat import BaseChatPromptTemplate, ChatPromptTemplate
|
16
|
+
from langchain_core.prompts.prompt import PromptTemplate
|
17
|
+
from pydantic import BaseModel, ConfigDict, Field, ValidationError, field_serializer, field_validator
|
18
|
+
|
19
|
+
from lfx.base.prompts.utils import dict_values_to_string
|
20
|
+
from lfx.log.logger import logger
|
21
|
+
from lfx.schema.content_block import ContentBlock
|
22
|
+
from lfx.schema.content_types import ErrorContent
|
23
|
+
from lfx.schema.data import Data
|
24
|
+
from lfx.schema.image import Image, get_file_paths, is_image_file
|
25
|
+
from lfx.schema.properties import Properties, Source
|
26
|
+
from lfx.schema.validators import timestamp_to_str, timestamp_to_str_validator
|
27
|
+
from lfx.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_NAME_AI, MESSAGE_SENDER_NAME_USER, MESSAGE_SENDER_USER
|
28
|
+
from lfx.utils.image import create_image_content_dict
|
29
|
+
|
30
|
+
if TYPE_CHECKING:
|
31
|
+
from lfx.schema.dataframe import DataFrame
|
32
|
+
|
33
|
+
|
34
|
+
class Message(Data):
|
35
|
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
36
|
+
# Helper class to deal with image data
|
37
|
+
text_key: str = "text"
|
38
|
+
text: str | AsyncIterator | Iterator | None = Field(default="")
|
39
|
+
sender: str | None = None
|
40
|
+
sender_name: str | None = None
|
41
|
+
files: list[str | Image] | None = Field(default=[])
|
42
|
+
session_id: str | UUID | None = Field(default="")
|
43
|
+
timestamp: Annotated[str, timestamp_to_str_validator] = Field(
|
44
|
+
default_factory=lambda: datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S %Z")
|
45
|
+
)
|
46
|
+
flow_id: str | UUID | None = None
|
47
|
+
error: bool = Field(default=False)
|
48
|
+
edit: bool = Field(default=False)
|
49
|
+
|
50
|
+
properties: Properties = Field(default_factory=Properties)
|
51
|
+
category: Literal["message", "error", "warning", "info"] | None = "message"
|
52
|
+
content_blocks: list[ContentBlock] = Field(default_factory=list)
|
53
|
+
duration: int | None = None
|
54
|
+
|
55
|
+
@field_validator("flow_id", mode="before")
|
56
|
+
@classmethod
|
57
|
+
def validate_flow_id(cls, value):
|
58
|
+
if isinstance(value, UUID):
|
59
|
+
value = str(value)
|
60
|
+
return value
|
61
|
+
|
62
|
+
@field_validator("content_blocks", mode="before")
|
63
|
+
@classmethod
|
64
|
+
def validate_content_blocks(cls, value):
|
65
|
+
# value may start with [ or not
|
66
|
+
if isinstance(value, list):
|
67
|
+
return [
|
68
|
+
ContentBlock.model_validate_json(v) if isinstance(v, str) else ContentBlock.model_validate(v)
|
69
|
+
for v in value
|
70
|
+
]
|
71
|
+
if isinstance(value, str):
|
72
|
+
value = json.loads(value) if value.startswith("[") else [ContentBlock.model_validate_json(value)]
|
73
|
+
return value
|
74
|
+
|
75
|
+
@field_validator("properties", mode="before")
|
76
|
+
@classmethod
|
77
|
+
def validate_properties(cls, value):
|
78
|
+
if isinstance(value, str):
|
79
|
+
value = Properties.model_validate_json(value)
|
80
|
+
elif isinstance(value, dict):
|
81
|
+
value = Properties.model_validate(value)
|
82
|
+
return value
|
83
|
+
|
84
|
+
@field_serializer("flow_id")
|
85
|
+
def serialize_flow_id(self, value):
|
86
|
+
if isinstance(value, UUID):
|
87
|
+
return str(value)
|
88
|
+
return value
|
89
|
+
|
90
|
+
@field_serializer("timestamp")
|
91
|
+
def serialize_timestamp(self, value):
|
92
|
+
try:
|
93
|
+
# Try parsing with timezone
|
94
|
+
return datetime.strptime(value.strip(), "%Y-%m-%d %H:%M:%S %Z").replace(tzinfo=timezone.utc)
|
95
|
+
except ValueError:
|
96
|
+
# Try parsing without timezone
|
97
|
+
return datetime.strptime(value.strip(), "%Y-%m-%d %H:%M:%S").replace(tzinfo=timezone.utc)
|
98
|
+
|
99
|
+
@field_validator("files", mode="before")
|
100
|
+
@classmethod
|
101
|
+
def validate_files(cls, value):
|
102
|
+
if not value:
|
103
|
+
value = []
|
104
|
+
elif not isinstance(value, list):
|
105
|
+
value = [value]
|
106
|
+
return value
|
107
|
+
|
108
|
+
def model_post_init(self, /, _context: Any) -> None:
|
109
|
+
new_files: list[Any] = []
|
110
|
+
for file in self.files or []:
|
111
|
+
if is_image_file(file):
|
112
|
+
new_files.append(Image(path=file))
|
113
|
+
else:
|
114
|
+
new_files.append(file)
|
115
|
+
self.files = new_files
|
116
|
+
if "timestamp" not in self.data:
|
117
|
+
self.data["timestamp"] = self.timestamp
|
118
|
+
|
119
|
+
def set_flow_id(self, flow_id: str) -> None:
|
120
|
+
self.flow_id = flow_id
|
121
|
+
|
122
|
+
def to_lc_message(
|
123
|
+
self,
|
124
|
+
) -> BaseMessage:
|
125
|
+
"""Converts the Data to a BaseMessage.
|
126
|
+
|
127
|
+
Returns:
|
128
|
+
BaseMessage: The converted BaseMessage.
|
129
|
+
"""
|
130
|
+
# The idea of this function is to be a helper to convert a Data to a BaseMessage
|
131
|
+
# It will use the "sender" key to determine if the message is Human or AI
|
132
|
+
# If the key is not present, it will default to AI
|
133
|
+
# But first we check if all required keys are present in the data dictionary
|
134
|
+
# they are: "text", "sender"
|
135
|
+
if self.text is None or not self.sender:
|
136
|
+
logger.warning("Missing required keys ('text', 'sender') in Message, defaulting to HumanMessage.")
|
137
|
+
text = "" if not isinstance(self.text, str) else self.text
|
138
|
+
|
139
|
+
if self.sender == MESSAGE_SENDER_USER or not self.sender:
|
140
|
+
if self.files:
|
141
|
+
contents = [{"type": "text", "text": text}]
|
142
|
+
contents.extend(self.get_file_content_dicts())
|
143
|
+
human_message = HumanMessage(content=contents)
|
144
|
+
else:
|
145
|
+
human_message = HumanMessage(content=text)
|
146
|
+
return human_message
|
147
|
+
|
148
|
+
return AIMessage(content=text)
|
149
|
+
|
150
|
+
@classmethod
|
151
|
+
def from_lc_message(cls, lc_message: BaseMessage) -> Message:
|
152
|
+
if lc_message.type == "human":
|
153
|
+
sender = MESSAGE_SENDER_USER
|
154
|
+
sender_name = MESSAGE_SENDER_NAME_USER
|
155
|
+
elif lc_message.type == "ai":
|
156
|
+
sender = MESSAGE_SENDER_AI
|
157
|
+
sender_name = MESSAGE_SENDER_NAME_AI
|
158
|
+
elif lc_message.type == "system":
|
159
|
+
sender = "System"
|
160
|
+
sender_name = "System"
|
161
|
+
else:
|
162
|
+
sender = lc_message.type
|
163
|
+
sender_name = lc_message.type
|
164
|
+
|
165
|
+
return cls(text=lc_message.content, sender=sender, sender_name=sender_name)
|
166
|
+
|
167
|
+
@classmethod
|
168
|
+
def from_data(cls, data: Data) -> Message:
|
169
|
+
"""Converts Data to a Message.
|
170
|
+
|
171
|
+
Args:
|
172
|
+
data: The Data to convert.
|
173
|
+
|
174
|
+
Returns:
|
175
|
+
The converted Message.
|
176
|
+
"""
|
177
|
+
return cls(
|
178
|
+
text=data.text,
|
179
|
+
sender=data.sender,
|
180
|
+
sender_name=data.sender_name,
|
181
|
+
files=data.files,
|
182
|
+
session_id=data.session_id,
|
183
|
+
timestamp=data.timestamp,
|
184
|
+
flow_id=data.flow_id,
|
185
|
+
error=data.error,
|
186
|
+
edit=data.edit,
|
187
|
+
)
|
188
|
+
|
189
|
+
@field_serializer("text", mode="plain")
|
190
|
+
def serialize_text(self, value):
|
191
|
+
if isinstance(value, AsyncIterator | Iterator):
|
192
|
+
return ""
|
193
|
+
return value
|
194
|
+
|
195
|
+
# Keep this async method for backwards compatibility
|
196
|
+
def get_file_content_dicts(self):
|
197
|
+
content_dicts = []
|
198
|
+
files = get_file_paths(self.files)
|
199
|
+
|
200
|
+
for file in files:
|
201
|
+
if isinstance(file, Image):
|
202
|
+
content_dicts.append(file.to_content_dict())
|
203
|
+
else:
|
204
|
+
content_dicts.append(create_image_content_dict(file))
|
205
|
+
return content_dicts
|
206
|
+
|
207
|
+
def load_lc_prompt(self):
|
208
|
+
if "prompt" not in self:
|
209
|
+
msg = "Prompt is required."
|
210
|
+
raise ValueError(msg)
|
211
|
+
# self.prompt was passed through jsonable_encoder
|
212
|
+
# so inner messages are not BaseMessage
|
213
|
+
# we need to convert them to BaseMessage
|
214
|
+
messages = []
|
215
|
+
for message in self.prompt.get("kwargs", {}).get("messages", []):
|
216
|
+
match message:
|
217
|
+
case HumanMessage():
|
218
|
+
messages.append(message)
|
219
|
+
case _ if message.get("type") == "human":
|
220
|
+
messages.append(HumanMessage(content=message.get("content")))
|
221
|
+
case _ if message.get("type") == "system":
|
222
|
+
messages.append(SystemMessage(content=message.get("content")))
|
223
|
+
case _ if message.get("type") == "ai":
|
224
|
+
messages.append(AIMessage(content=message.get("content")))
|
225
|
+
|
226
|
+
self.prompt["kwargs"]["messages"] = messages
|
227
|
+
return load(self.prompt)
|
228
|
+
|
229
|
+
@classmethod
|
230
|
+
def from_lc_prompt(
|
231
|
+
cls,
|
232
|
+
prompt: BaseChatPromptTemplate,
|
233
|
+
):
|
234
|
+
prompt_json = prompt.to_json()
|
235
|
+
return cls(prompt=prompt_json)
|
236
|
+
|
237
|
+
def format_text(self):
|
238
|
+
prompt_template = PromptTemplate.from_template(self.template)
|
239
|
+
variables_with_str_values = dict_values_to_string(self.variables)
|
240
|
+
formatted_prompt = prompt_template.format(**variables_with_str_values)
|
241
|
+
self.text = formatted_prompt
|
242
|
+
return formatted_prompt
|
243
|
+
|
244
|
+
@classmethod
|
245
|
+
async def from_template_and_variables(cls, template: str, **variables):
|
246
|
+
# This method has to be async for backwards compatibility with versions
|
247
|
+
# >1.0.15, <1.1
|
248
|
+
return cls.from_template(template, **variables)
|
249
|
+
|
250
|
+
# Define a sync version for backwards compatibility with versions >1.0.15, <1.1
|
251
|
+
@classmethod
|
252
|
+
def from_template(cls, template: str, **variables):
|
253
|
+
instance = cls(template=template, variables=variables)
|
254
|
+
text = instance.format_text()
|
255
|
+
message = HumanMessage(content=text)
|
256
|
+
contents = []
|
257
|
+
for value in variables.values():
|
258
|
+
if isinstance(value, cls) and value.files:
|
259
|
+
content_dicts = value.get_file_content_dicts()
|
260
|
+
contents.extend(content_dicts)
|
261
|
+
if contents:
|
262
|
+
message = HumanMessage(content=[{"type": "text", "text": text}, *contents])
|
263
|
+
|
264
|
+
prompt_template = ChatPromptTemplate.from_messages([message])
|
265
|
+
|
266
|
+
instance.prompt = jsonable_encoder(prompt_template.to_json())
|
267
|
+
instance.messages = instance.prompt.get("kwargs", {}).get("messages", [])
|
268
|
+
return instance
|
269
|
+
|
270
|
+
@classmethod
|
271
|
+
async def create(cls, **kwargs):
|
272
|
+
"""If files are present, create the message in a separate thread as is_image_file is blocking."""
|
273
|
+
if "files" in kwargs:
|
274
|
+
return await asyncio.to_thread(cls, **kwargs)
|
275
|
+
return cls(**kwargs)
|
276
|
+
|
277
|
+
def to_data(self) -> Data:
|
278
|
+
return Data(data=self.data)
|
279
|
+
|
280
|
+
def to_dataframe(self) -> DataFrame:
|
281
|
+
from lfx.schema.dataframe import DataFrame # Local import to avoid circular import
|
282
|
+
|
283
|
+
return DataFrame(data=[self])
|
284
|
+
|
285
|
+
|
286
|
+
class DefaultModel(BaseModel):
|
287
|
+
model_config = ConfigDict(
|
288
|
+
from_attributes=True,
|
289
|
+
populate_by_name=True,
|
290
|
+
json_encoders={
|
291
|
+
datetime: lambda v: v.isoformat(),
|
292
|
+
UUID: lambda v: str(v),
|
293
|
+
},
|
294
|
+
)
|
295
|
+
|
296
|
+
def json(self, **kwargs):
|
297
|
+
# Usa a função de serialização personalizada
|
298
|
+
return super().model_dump_json(**kwargs, encoder=self.custom_encoder)
|
299
|
+
|
300
|
+
@staticmethod
|
301
|
+
def custom_encoder(obj):
|
302
|
+
if isinstance(obj, datetime):
|
303
|
+
return obj.isoformat()
|
304
|
+
msg = f"Object of type {obj.__class__.__name__} is not JSON serializable"
|
305
|
+
raise TypeError(msg)
|
306
|
+
|
307
|
+
|
308
|
+
class MessageResponse(DefaultModel):
|
309
|
+
id: str | UUID | None = Field(default=None)
|
310
|
+
flow_id: UUID | None = Field(default=None)
|
311
|
+
timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
312
|
+
sender: str
|
313
|
+
sender_name: str
|
314
|
+
session_id: str
|
315
|
+
text: str
|
316
|
+
files: list[str] = []
|
317
|
+
edit: bool
|
318
|
+
duration: float | None = None
|
319
|
+
|
320
|
+
properties: Properties | None = None
|
321
|
+
category: str | None = None
|
322
|
+
content_blocks: list[ContentBlock] | None = None
|
323
|
+
|
324
|
+
@field_validator("content_blocks", mode="before")
|
325
|
+
@classmethod
|
326
|
+
def validate_content_blocks(cls, v):
|
327
|
+
if isinstance(v, str):
|
328
|
+
v = json.loads(v)
|
329
|
+
if isinstance(v, list):
|
330
|
+
return [cls.validate_content_blocks(block) for block in v]
|
331
|
+
if isinstance(v, dict):
|
332
|
+
return ContentBlock.model_validate(v)
|
333
|
+
return v
|
334
|
+
|
335
|
+
@field_validator("properties", mode="before")
|
336
|
+
@classmethod
|
337
|
+
def validate_properties(cls, v):
|
338
|
+
if isinstance(v, str):
|
339
|
+
v = json.loads(v)
|
340
|
+
return v
|
341
|
+
|
342
|
+
@field_validator("files", mode="before")
|
343
|
+
@classmethod
|
344
|
+
def validate_files(cls, v):
|
345
|
+
if isinstance(v, str):
|
346
|
+
v = json.loads(v)
|
347
|
+
return v
|
348
|
+
|
349
|
+
@field_serializer("timestamp")
|
350
|
+
@classmethod
|
351
|
+
def serialize_timestamp(cls, v):
|
352
|
+
return timestamp_to_str(v)
|
353
|
+
|
354
|
+
@field_serializer("files")
|
355
|
+
@classmethod
|
356
|
+
def serialize_files(cls, v):
|
357
|
+
if isinstance(v, list):
|
358
|
+
return json.dumps(v)
|
359
|
+
return v
|
360
|
+
|
361
|
+
@classmethod
|
362
|
+
def from_message(cls, message: Message, flow_id: str | None = None):
|
363
|
+
# first check if the record has all the required fields
|
364
|
+
if message.text is None or not message.sender or not message.sender_name:
|
365
|
+
msg = "The message does not have the required fields (text, sender, sender_name)."
|
366
|
+
raise ValueError(msg)
|
367
|
+
return cls(
|
368
|
+
sender=message.sender,
|
369
|
+
sender_name=message.sender_name,
|
370
|
+
text=message.text,
|
371
|
+
session_id=message.session_id,
|
372
|
+
files=message.files or [],
|
373
|
+
timestamp=message.timestamp,
|
374
|
+
flow_id=flow_id,
|
375
|
+
)
|
376
|
+
|
377
|
+
|
378
|
+
class ErrorMessage(Message):
|
379
|
+
"""A message class specifically for error messages with predefined error-specific attributes."""
|
380
|
+
|
381
|
+
@staticmethod
|
382
|
+
def _format_markdown_reason(exception: BaseException) -> str:
|
383
|
+
"""Format the error reason with markdown formatting."""
|
384
|
+
reason = f"**{exception.__class__.__name__}**\n"
|
385
|
+
if hasattr(exception, "body") and isinstance(exception.body, dict) and "message" in exception.body:
|
386
|
+
reason += f" - **{exception.body.get('message')}**\n"
|
387
|
+
elif hasattr(exception, "code"):
|
388
|
+
reason += f" - **Code: {exception.code}**\n"
|
389
|
+
elif hasattr(exception, "args") and exception.args:
|
390
|
+
reason += f" - **Details: {exception.args[0]}**\n"
|
391
|
+
elif isinstance(exception, ValidationError):
|
392
|
+
reason += f" - **Details:**\n\n```python\n{exception!s}\n```\n"
|
393
|
+
else:
|
394
|
+
reason += " - **An unknown error occurred.**\n"
|
395
|
+
return reason
|
396
|
+
|
397
|
+
@staticmethod
|
398
|
+
def _format_plain_reason(exception: BaseException) -> str:
|
399
|
+
"""Format the error reason without markdown."""
|
400
|
+
if hasattr(exception, "body") and isinstance(exception.body, dict) and "message" in exception.body:
|
401
|
+
reason = f"{exception.body.get('message')}\n"
|
402
|
+
elif hasattr(exception, "_message"):
|
403
|
+
reason = f"{exception._message()}\n" if callable(exception._message) else f"{exception._message}\n" # noqa: SLF001
|
404
|
+
elif hasattr(exception, "code"):
|
405
|
+
reason = f"Code: {exception.code}\n"
|
406
|
+
elif hasattr(exception, "args") and exception.args:
|
407
|
+
reason = f"{exception.args[0]}\n"
|
408
|
+
elif isinstance(exception, ValidationError):
|
409
|
+
reason = f"{exception!s}\n"
|
410
|
+
elif hasattr(exception, "detail"):
|
411
|
+
reason = f"{exception.detail}\n"
|
412
|
+
elif hasattr(exception, "message"):
|
413
|
+
reason = f"{exception.message}\n"
|
414
|
+
else:
|
415
|
+
reason = "An unknown error occurred.\n"
|
416
|
+
return reason
|
417
|
+
|
418
|
+
def __init__(
|
419
|
+
self,
|
420
|
+
exception: BaseException,
|
421
|
+
session_id: str | None = None,
|
422
|
+
source: Source | None = None,
|
423
|
+
trace_name: str | None = None,
|
424
|
+
flow_id: UUID | str | None = None,
|
425
|
+
) -> None:
|
426
|
+
# This is done to avoid circular imports
|
427
|
+
if exception.__class__.__name__ == "ExceptionWithMessageError" and exception.__cause__ is not None:
|
428
|
+
exception = exception.__cause__
|
429
|
+
|
430
|
+
plain_reason = self._format_plain_reason(exception)
|
431
|
+
markdown_reason = self._format_markdown_reason(exception)
|
432
|
+
# Get the sender ID
|
433
|
+
if trace_name:
|
434
|
+
match = re.search(r"\((.*?)\)", trace_name)
|
435
|
+
if match:
|
436
|
+
match.group(1)
|
437
|
+
|
438
|
+
super().__init__(
|
439
|
+
session_id=session_id,
|
440
|
+
sender=source.display_name if source else None,
|
441
|
+
sender_name=source.display_name if source else None,
|
442
|
+
text=plain_reason,
|
443
|
+
properties=Properties(
|
444
|
+
text_color="red",
|
445
|
+
background_color="red",
|
446
|
+
edited=False,
|
447
|
+
source=source,
|
448
|
+
icon="error",
|
449
|
+
allow_markdown=False,
|
450
|
+
targets=[],
|
451
|
+
),
|
452
|
+
category="error",
|
453
|
+
error=True,
|
454
|
+
content_blocks=[
|
455
|
+
ContentBlock(
|
456
|
+
title="Error",
|
457
|
+
contents=[
|
458
|
+
ErrorContent(
|
459
|
+
type="error",
|
460
|
+
component=source.display_name if source else None,
|
461
|
+
field=str(exception.field) if hasattr(exception, "field") else None,
|
462
|
+
reason=markdown_reason,
|
463
|
+
solution=str(exception.solution) if hasattr(exception, "solution") else None,
|
464
|
+
traceback=traceback.format_exc(),
|
465
|
+
)
|
466
|
+
],
|
467
|
+
)
|
468
|
+
],
|
469
|
+
flow_id=flow_id,
|
470
|
+
)
|
471
|
+
|
472
|
+
|
473
|
+
__all__ = ["ContentBlock", "DefaultModel", "ErrorMessage", "Message", "MessageResponse"]
|
@@ -0,0 +1,74 @@
|
|
1
|
+
from typing import Any, Literal
|
2
|
+
|
3
|
+
from pydantic import BaseModel, Field
|
4
|
+
|
5
|
+
|
6
|
+
class OpenAIResponsesRequest(BaseModel):
|
7
|
+
"""OpenAI-compatible responses request with flow_id as model parameter."""
|
8
|
+
|
9
|
+
model: str = Field(..., description="The flow ID to execute (used instead of OpenAI model)")
|
10
|
+
input: str = Field(..., description="The input text to process")
|
11
|
+
stream: bool = Field(default=False, description="Whether to stream the response")
|
12
|
+
background: bool = Field(default=False, description="Whether to process in background")
|
13
|
+
tools: list[Any] | None = Field(default=None, description="Tools are not supported yet")
|
14
|
+
previous_response_id: str | None = Field(
|
15
|
+
default=None, description="ID of previous response to continue conversation"
|
16
|
+
)
|
17
|
+
include: list[str] | None = Field(
|
18
|
+
default=None, description="Additional response data to include, e.g., ['tool_call.results']"
|
19
|
+
)
|
20
|
+
|
21
|
+
|
22
|
+
class OpenAIResponsesResponse(BaseModel):
|
23
|
+
"""OpenAI-compatible responses response."""
|
24
|
+
|
25
|
+
id: str
|
26
|
+
object: Literal["response"] = "response"
|
27
|
+
created_at: int
|
28
|
+
status: Literal["completed", "in_progress", "failed"] = "completed"
|
29
|
+
error: dict | None = None
|
30
|
+
incomplete_details: dict | None = None
|
31
|
+
instructions: str | None = None
|
32
|
+
max_output_tokens: int | None = None
|
33
|
+
model: str
|
34
|
+
output: list[dict]
|
35
|
+
parallel_tool_calls: bool = True
|
36
|
+
previous_response_id: str | None = None
|
37
|
+
reasoning: dict = Field(default_factory=lambda: {"effort": None, "summary": None})
|
38
|
+
store: bool = True
|
39
|
+
temperature: float = 1.0
|
40
|
+
text: dict = Field(default_factory=lambda: {"format": {"type": "text"}})
|
41
|
+
tool_choice: str = "auto"
|
42
|
+
tools: list[dict] = Field(default_factory=list)
|
43
|
+
top_p: float = 1.0
|
44
|
+
truncation: str = "disabled"
|
45
|
+
usage: dict | None = None
|
46
|
+
user: str | None = None
|
47
|
+
metadata: dict = Field(default_factory=dict)
|
48
|
+
|
49
|
+
|
50
|
+
class OpenAIResponsesStreamChunk(BaseModel):
|
51
|
+
"""OpenAI-compatible responses stream chunk."""
|
52
|
+
|
53
|
+
id: str
|
54
|
+
object: Literal["response.chunk"] = "response.chunk"
|
55
|
+
created: int
|
56
|
+
model: str
|
57
|
+
delta: dict
|
58
|
+
status: Literal["completed", "in_progress", "failed"] | None = None
|
59
|
+
|
60
|
+
|
61
|
+
class OpenAIErrorResponse(BaseModel):
|
62
|
+
error: dict = Field(..., description="Error details")
|
63
|
+
|
64
|
+
|
65
|
+
def create_openai_error(message: str, type_: str = "invalid_request_error", code: str | None = None) -> dict:
|
66
|
+
"""Create an OpenAI-compatible error response."""
|
67
|
+
error_data = {
|
68
|
+
"message": message,
|
69
|
+
"type": type_,
|
70
|
+
}
|
71
|
+
if code:
|
72
|
+
error_data["code"] = code
|
73
|
+
|
74
|
+
return {"error": error_data}
|
lfx/schema/properties.py
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
"""Properties and Source schema classes copied from langflow for lfx package."""
|
2
|
+
|
3
|
+
from typing import Literal
|
4
|
+
|
5
|
+
from pydantic import BaseModel, Field, field_serializer, field_validator
|
6
|
+
|
7
|
+
|
8
|
+
class Source(BaseModel):
|
9
|
+
id: str | None = Field(default=None, description="The id of the source component.")
|
10
|
+
display_name: str | None = Field(default=None, description="The display name of the source component.")
|
11
|
+
source: str | None = Field(
|
12
|
+
default=None,
|
13
|
+
description="The source of the message. Normally used to display the model name (e.g. 'gpt-4o')",
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
class Properties(BaseModel):
|
18
|
+
text_color: str | None = None
|
19
|
+
background_color: str | None = None
|
20
|
+
edited: bool = False
|
21
|
+
source: Source = Field(default_factory=Source)
|
22
|
+
icon: str | None = None
|
23
|
+
allow_markdown: bool = False
|
24
|
+
positive_feedback: bool | None = None
|
25
|
+
state: Literal["partial", "complete"] = "complete"
|
26
|
+
targets: list = []
|
27
|
+
|
28
|
+
@field_validator("source", mode="before")
|
29
|
+
@classmethod
|
30
|
+
def validate_source(cls, v):
|
31
|
+
if isinstance(v, str):
|
32
|
+
return Source(id=v, display_name=v, source=v)
|
33
|
+
if v is None:
|
34
|
+
return Source()
|
35
|
+
return v
|
36
|
+
|
37
|
+
@field_serializer("source")
|
38
|
+
def serialize_source(self, value):
|
39
|
+
if isinstance(value, Source):
|
40
|
+
return value.model_dump()
|
41
|
+
return value
|