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,278 @@
|
|
1
|
+
import json
|
2
|
+
import os
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
import httpx
|
6
|
+
|
7
|
+
from lfx.base.langwatch.utils import get_cached_evaluators
|
8
|
+
from lfx.custom.custom_component.component import Component
|
9
|
+
from lfx.inputs.inputs import MultilineInput
|
10
|
+
from lfx.io import (
|
11
|
+
BoolInput,
|
12
|
+
DropdownInput,
|
13
|
+
FloatInput,
|
14
|
+
IntInput,
|
15
|
+
MessageTextInput,
|
16
|
+
NestedDictInput,
|
17
|
+
Output,
|
18
|
+
SecretStrInput,
|
19
|
+
)
|
20
|
+
from lfx.log.logger import logger
|
21
|
+
from lfx.schema.data import Data
|
22
|
+
from lfx.schema.dotdict import dotdict
|
23
|
+
|
24
|
+
|
25
|
+
class LangWatchComponent(Component):
|
26
|
+
display_name: str = "LangWatch Evaluator"
|
27
|
+
description: str = "Evaluates various aspects of language models using LangWatch's evaluation endpoints."
|
28
|
+
documentation: str = "https://docs.langwatch.ai/langevals/documentation/introduction"
|
29
|
+
icon: str = "Langwatch"
|
30
|
+
name: str = "LangWatchEvaluator"
|
31
|
+
|
32
|
+
inputs = [
|
33
|
+
DropdownInput(
|
34
|
+
name="evaluator_name",
|
35
|
+
display_name="Evaluator Name",
|
36
|
+
options=[],
|
37
|
+
required=True,
|
38
|
+
info="Select an evaluator.",
|
39
|
+
refresh_button=True,
|
40
|
+
real_time_refresh=True,
|
41
|
+
),
|
42
|
+
SecretStrInput(
|
43
|
+
name="api_key",
|
44
|
+
display_name="API Key",
|
45
|
+
required=True,
|
46
|
+
info="Enter your LangWatch API key.",
|
47
|
+
),
|
48
|
+
MessageTextInput(
|
49
|
+
name="input",
|
50
|
+
display_name="Input",
|
51
|
+
required=False,
|
52
|
+
info="The input text for evaluation.",
|
53
|
+
),
|
54
|
+
MessageTextInput(
|
55
|
+
name="output",
|
56
|
+
display_name="Output",
|
57
|
+
required=False,
|
58
|
+
info="The output text for evaluation.",
|
59
|
+
),
|
60
|
+
MessageTextInput(
|
61
|
+
name="expected_output",
|
62
|
+
display_name="Expected Output",
|
63
|
+
required=False,
|
64
|
+
info="The expected output for evaluation.",
|
65
|
+
),
|
66
|
+
MessageTextInput(
|
67
|
+
name="contexts",
|
68
|
+
display_name="Contexts",
|
69
|
+
required=False,
|
70
|
+
info="The contexts for evaluation (comma-separated).",
|
71
|
+
),
|
72
|
+
IntInput(
|
73
|
+
name="timeout",
|
74
|
+
display_name="Timeout",
|
75
|
+
info="The maximum time (in seconds) allowed for the server to respond before timing out.",
|
76
|
+
value=30,
|
77
|
+
advanced=True,
|
78
|
+
),
|
79
|
+
]
|
80
|
+
|
81
|
+
outputs = [
|
82
|
+
Output(name="evaluation_result", display_name="Evaluation Result", method="evaluate"),
|
83
|
+
]
|
84
|
+
|
85
|
+
def set_evaluators(self, endpoint: str):
|
86
|
+
url = f"{endpoint}/api/evaluations/list"
|
87
|
+
self.evaluators = get_cached_evaluators(url)
|
88
|
+
if not self.evaluators or len(self.evaluators) == 0:
|
89
|
+
self.status = f"No evaluators found from {endpoint}"
|
90
|
+
msg = f"No evaluators found from {endpoint}"
|
91
|
+
raise ValueError(msg)
|
92
|
+
|
93
|
+
def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:
|
94
|
+
try:
|
95
|
+
logger.info(f"Updating build config. Field name: {field_name}, Field value: {field_value}")
|
96
|
+
|
97
|
+
if field_name is None or field_name == "evaluator_name":
|
98
|
+
self.evaluators = self.get_evaluators(os.getenv("LANGWATCH_ENDPOINT", "https://app.langwatch.ai"))
|
99
|
+
build_config["evaluator_name"]["options"] = list(self.evaluators.keys())
|
100
|
+
|
101
|
+
# Set a default evaluator if none is selected
|
102
|
+
if not getattr(self, "current_evaluator", None) and self.evaluators:
|
103
|
+
self.current_evaluator = next(iter(self.evaluators))
|
104
|
+
build_config["evaluator_name"]["value"] = self.current_evaluator
|
105
|
+
|
106
|
+
# Define default keys that should always be present
|
107
|
+
default_keys = ["code", "_type", "evaluator_name", "api_key", "input", "output", "timeout"]
|
108
|
+
|
109
|
+
if field_value and field_value in self.evaluators and self.current_evaluator != field_value:
|
110
|
+
self.current_evaluator = field_value
|
111
|
+
evaluator = self.evaluators[field_value]
|
112
|
+
|
113
|
+
# Clear previous dynamic inputs
|
114
|
+
keys_to_remove = [key for key in build_config if key not in default_keys]
|
115
|
+
for key in keys_to_remove:
|
116
|
+
del build_config[key]
|
117
|
+
|
118
|
+
# Clear component's dynamic attributes
|
119
|
+
for attr in list(self.__dict__.keys()):
|
120
|
+
if attr not in default_keys and attr not in {
|
121
|
+
"evaluators",
|
122
|
+
"dynamic_inputs",
|
123
|
+
"_code",
|
124
|
+
"current_evaluator",
|
125
|
+
}:
|
126
|
+
delattr(self, attr)
|
127
|
+
|
128
|
+
# Add new dynamic inputs
|
129
|
+
self.dynamic_inputs = self.get_dynamic_inputs(evaluator)
|
130
|
+
for name, input_config in self.dynamic_inputs.items():
|
131
|
+
build_config[name] = input_config.to_dict()
|
132
|
+
|
133
|
+
# Update required fields
|
134
|
+
required_fields = {"api_key", "evaluator_name"}.union(evaluator.get("requiredFields", []))
|
135
|
+
for key in build_config:
|
136
|
+
if isinstance(build_config[key], dict):
|
137
|
+
build_config[key]["required"] = key in required_fields
|
138
|
+
|
139
|
+
# Validate presence of default keys
|
140
|
+
missing_keys = [key for key in default_keys if key not in build_config]
|
141
|
+
if missing_keys:
|
142
|
+
logger.warning(f"Missing required keys in build_config: {missing_keys}")
|
143
|
+
# Add missing keys with default values
|
144
|
+
for key in missing_keys:
|
145
|
+
build_config[key] = {"value": None, "type": "str"}
|
146
|
+
|
147
|
+
# Ensure the current_evaluator is always set in the build_config
|
148
|
+
build_config["evaluator_name"]["value"] = self.current_evaluator
|
149
|
+
|
150
|
+
logger.info(f"Current evaluator set to: {self.current_evaluator}")
|
151
|
+
|
152
|
+
except (KeyError, AttributeError, ValueError) as e:
|
153
|
+
self.status = f"Error updating component: {e!s}"
|
154
|
+
return build_config
|
155
|
+
|
156
|
+
def get_dynamic_inputs(self, evaluator: dict[str, Any]):
|
157
|
+
try:
|
158
|
+
dynamic_inputs = {}
|
159
|
+
|
160
|
+
input_fields = [
|
161
|
+
field
|
162
|
+
for field in evaluator.get("requiredFields", []) + evaluator.get("optionalFields", [])
|
163
|
+
if field not in {"input", "output"}
|
164
|
+
]
|
165
|
+
|
166
|
+
for field in input_fields:
|
167
|
+
input_params = {
|
168
|
+
"name": field,
|
169
|
+
"display_name": field.replace("_", " ").title(),
|
170
|
+
"required": field in evaluator.get("requiredFields", []),
|
171
|
+
}
|
172
|
+
if field == "contexts":
|
173
|
+
dynamic_inputs[field] = MultilineInput(**input_params, multiline=True)
|
174
|
+
else:
|
175
|
+
dynamic_inputs[field] = MessageTextInput(**input_params)
|
176
|
+
|
177
|
+
settings = evaluator.get("settings", {})
|
178
|
+
for setting_name, setting_config in settings.items():
|
179
|
+
schema = evaluator.get("settings_json_schema", {}).get("properties", {}).get(setting_name, {})
|
180
|
+
|
181
|
+
input_params = {
|
182
|
+
"name": setting_name,
|
183
|
+
"display_name": setting_name.replace("_", " ").title(),
|
184
|
+
"info": setting_config.get("description", ""),
|
185
|
+
"required": False,
|
186
|
+
}
|
187
|
+
|
188
|
+
if schema.get("type") == "object":
|
189
|
+
input_type = NestedDictInput
|
190
|
+
input_params["value"] = schema.get("default", setting_config.get("default", {}))
|
191
|
+
elif schema.get("type") == "boolean":
|
192
|
+
input_type = BoolInput
|
193
|
+
input_params["value"] = schema.get("default", setting_config.get("default", False))
|
194
|
+
elif schema.get("type") == "number":
|
195
|
+
is_float = isinstance(schema.get("default", setting_config.get("default")), float)
|
196
|
+
input_type = FloatInput if is_float else IntInput
|
197
|
+
input_params["value"] = schema.get("default", setting_config.get("default", 0))
|
198
|
+
elif "enum" in schema:
|
199
|
+
input_type = DropdownInput
|
200
|
+
input_params["options"] = schema["enum"]
|
201
|
+
input_params["value"] = schema.get("default", setting_config.get("default"))
|
202
|
+
else:
|
203
|
+
input_type = MessageTextInput
|
204
|
+
default_value = schema.get("default", setting_config.get("default"))
|
205
|
+
input_params["value"] = str(default_value) if default_value is not None else ""
|
206
|
+
|
207
|
+
dynamic_inputs[setting_name] = input_type(**input_params)
|
208
|
+
|
209
|
+
except (KeyError, AttributeError, ValueError, TypeError) as e:
|
210
|
+
self.status = f"Error creating dynamic inputs: {e!s}"
|
211
|
+
return {}
|
212
|
+
return dynamic_inputs
|
213
|
+
|
214
|
+
async def evaluate(self) -> Data:
|
215
|
+
if not self.api_key:
|
216
|
+
return Data(data={"error": "API key is required"})
|
217
|
+
|
218
|
+
self.set_evaluators(os.getenv("LANGWATCH_ENDPOINT", "https://app.langwatch.ai"))
|
219
|
+
self.dynamic_inputs = {}
|
220
|
+
if getattr(self, "current_evaluator", None) is None and self.evaluators:
|
221
|
+
self.current_evaluator = next(iter(self.evaluators))
|
222
|
+
|
223
|
+
# Prioritize evaluator_name if it exists
|
224
|
+
evaluator_name = getattr(self, "evaluator_name", None) or self.current_evaluator
|
225
|
+
|
226
|
+
if not evaluator_name:
|
227
|
+
if self.evaluators:
|
228
|
+
evaluator_name = next(iter(self.evaluators))
|
229
|
+
await logger.ainfo(f"No evaluator was selected. Using default: {evaluator_name}")
|
230
|
+
else:
|
231
|
+
return Data(
|
232
|
+
data={"error": "No evaluator selected and no evaluators available. Please choose an evaluator."}
|
233
|
+
)
|
234
|
+
|
235
|
+
try:
|
236
|
+
evaluator = self.evaluators.get(evaluator_name)
|
237
|
+
if not evaluator:
|
238
|
+
return Data(data={"error": f"Selected evaluator '{evaluator_name}' not found."})
|
239
|
+
|
240
|
+
await logger.ainfo(f"Evaluating with evaluator: {evaluator_name}")
|
241
|
+
|
242
|
+
endpoint = f"/api/evaluations/{evaluator_name}/evaluate"
|
243
|
+
url = f"{os.getenv('LANGWATCH_ENDPOINT', 'https://app.langwatch.ai')}{endpoint}"
|
244
|
+
|
245
|
+
headers = {"Content-Type": "application/json", "X-Auth-Token": self.api_key}
|
246
|
+
|
247
|
+
payload = {
|
248
|
+
"data": {
|
249
|
+
"input": self.input,
|
250
|
+
"output": self.output,
|
251
|
+
"expected_output": self.expected_output,
|
252
|
+
"contexts": self.contexts.split(",") if self.contexts else [],
|
253
|
+
},
|
254
|
+
"settings": {},
|
255
|
+
}
|
256
|
+
|
257
|
+
if self._tracing_service:
|
258
|
+
tracer = self._tracing_service.get_tracer("langwatch")
|
259
|
+
if tracer is not None and hasattr(tracer, "trace_id"):
|
260
|
+
payload["settings"]["trace_id"] = str(tracer.trace_id)
|
261
|
+
|
262
|
+
for setting_name in self.dynamic_inputs:
|
263
|
+
payload["settings"][setting_name] = getattr(self, setting_name, None)
|
264
|
+
|
265
|
+
async with httpx.AsyncClient(timeout=self.timeout) as client:
|
266
|
+
response = await client.post(url, json=payload, headers=headers)
|
267
|
+
|
268
|
+
response.raise_for_status()
|
269
|
+
result = response.json()
|
270
|
+
|
271
|
+
formatted_result = json.dumps(result, indent=2)
|
272
|
+
self.status = f"Evaluation completed successfully. Result:\n{formatted_result}"
|
273
|
+
return Data(data=result)
|
274
|
+
|
275
|
+
except (httpx.RequestError, KeyError, AttributeError, ValueError) as e:
|
276
|
+
error_message = f"Evaluation error: {e!s}"
|
277
|
+
self.status = error_message
|
278
|
+
return Data(data={"error": error_message})
|
@@ -0,0 +1,34 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Any
|
4
|
+
|
5
|
+
from lfx.components._importing import import_mod
|
6
|
+
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from lfx.components.lmstudio.lmstudioembeddings import LMStudioEmbeddingsComponent
|
9
|
+
from lfx.components.lmstudio.lmstudiomodel import LMStudioModelComponent
|
10
|
+
|
11
|
+
_dynamic_imports = {
|
12
|
+
"LMStudioEmbeddingsComponent": "lmstudioembeddings",
|
13
|
+
"LMStudioModelComponent": "lmstudiomodel",
|
14
|
+
}
|
15
|
+
|
16
|
+
__all__ = ["LMStudioEmbeddingsComponent", "LMStudioModelComponent"]
|
17
|
+
|
18
|
+
|
19
|
+
def __getattr__(attr_name: str) -> Any:
|
20
|
+
"""Lazily import lmstudio components on attribute access."""
|
21
|
+
if attr_name not in _dynamic_imports:
|
22
|
+
msg = f"module '{__name__}' has no attribute '{attr_name}'"
|
23
|
+
raise AttributeError(msg)
|
24
|
+
try:
|
25
|
+
result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
|
26
|
+
except (ModuleNotFoundError, ImportError, AttributeError) as e:
|
27
|
+
msg = f"Could not import '{attr_name}' from '{__name__}': {e}"
|
28
|
+
raise AttributeError(msg) from e
|
29
|
+
globals()[attr_name] = result
|
30
|
+
return result
|
31
|
+
|
32
|
+
|
33
|
+
def __dir__() -> list[str]:
|
34
|
+
return list(__all__)
|
@@ -0,0 +1,89 @@
|
|
1
|
+
from typing import Any
|
2
|
+
from urllib.parse import urljoin
|
3
|
+
|
4
|
+
import httpx
|
5
|
+
|
6
|
+
from lfx.base.embeddings.model import LCEmbeddingsModel
|
7
|
+
from lfx.field_typing import Embeddings
|
8
|
+
from lfx.inputs.inputs import DropdownInput, SecretStrInput
|
9
|
+
from lfx.io import FloatInput, MessageTextInput
|
10
|
+
|
11
|
+
|
12
|
+
class LMStudioEmbeddingsComponent(LCEmbeddingsModel):
|
13
|
+
display_name: str = "LM Studio Embeddings"
|
14
|
+
description: str = "Generate embeddings using LM Studio."
|
15
|
+
icon = "LMStudio"
|
16
|
+
|
17
|
+
async def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None): # noqa: ARG002
|
18
|
+
if field_name == "model":
|
19
|
+
base_url_dict = build_config.get("base_url", {})
|
20
|
+
base_url_load_from_db = base_url_dict.get("load_from_db", False)
|
21
|
+
base_url_value = base_url_dict.get("value")
|
22
|
+
if base_url_load_from_db:
|
23
|
+
base_url_value = await self.get_variables(base_url_value, field_name)
|
24
|
+
elif not base_url_value:
|
25
|
+
base_url_value = "http://localhost:1234/v1"
|
26
|
+
build_config["model"]["options"] = await self.get_model(base_url_value)
|
27
|
+
|
28
|
+
return build_config
|
29
|
+
|
30
|
+
@staticmethod
|
31
|
+
async def get_model(base_url_value: str) -> list[str]:
|
32
|
+
try:
|
33
|
+
url = urljoin(base_url_value, "/v1/models")
|
34
|
+
async with httpx.AsyncClient() as client:
|
35
|
+
response = await client.get(url)
|
36
|
+
response.raise_for_status()
|
37
|
+
data = response.json()
|
38
|
+
|
39
|
+
return [model["id"] for model in data.get("data", [])]
|
40
|
+
except Exception as e:
|
41
|
+
msg = "Could not retrieve models. Please, make sure the LM Studio server is running."
|
42
|
+
raise ValueError(msg) from e
|
43
|
+
|
44
|
+
inputs = [
|
45
|
+
DropdownInput(
|
46
|
+
name="model",
|
47
|
+
display_name="Model",
|
48
|
+
advanced=False,
|
49
|
+
refresh_button=True,
|
50
|
+
required=True,
|
51
|
+
),
|
52
|
+
MessageTextInput(
|
53
|
+
name="base_url",
|
54
|
+
display_name="LM Studio Base URL",
|
55
|
+
refresh_button=True,
|
56
|
+
value="http://localhost:1234/v1",
|
57
|
+
required=True,
|
58
|
+
),
|
59
|
+
SecretStrInput(
|
60
|
+
name="api_key",
|
61
|
+
display_name="LM Studio API Key",
|
62
|
+
advanced=True,
|
63
|
+
value="LMSTUDIO_API_KEY",
|
64
|
+
),
|
65
|
+
FloatInput(
|
66
|
+
name="temperature",
|
67
|
+
display_name="Model Temperature",
|
68
|
+
value=0.1,
|
69
|
+
advanced=True,
|
70
|
+
),
|
71
|
+
]
|
72
|
+
|
73
|
+
def build_embeddings(self) -> Embeddings:
|
74
|
+
try:
|
75
|
+
from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings
|
76
|
+
except ImportError as e:
|
77
|
+
msg = "Please install langchain-nvidia-ai-endpoints to use LM Studio Embeddings."
|
78
|
+
raise ImportError(msg) from e
|
79
|
+
try:
|
80
|
+
output = NVIDIAEmbeddings(
|
81
|
+
model=self.model,
|
82
|
+
base_url=self.base_url,
|
83
|
+
temperature=self.temperature,
|
84
|
+
nvidia_api_key=self.api_key,
|
85
|
+
)
|
86
|
+
except Exception as e:
|
87
|
+
msg = f"Could not connect to LM Studio API. Error: {e}"
|
88
|
+
raise ValueError(msg) from e
|
89
|
+
return output
|
@@ -0,0 +1,129 @@
|
|
1
|
+
from typing import Any
|
2
|
+
from urllib.parse import urljoin
|
3
|
+
|
4
|
+
import httpx
|
5
|
+
from langchain_openai import ChatOpenAI
|
6
|
+
from typing_extensions import override
|
7
|
+
|
8
|
+
from lfx.base.models.model import LCModelComponent
|
9
|
+
from lfx.field_typing import LanguageModel
|
10
|
+
from lfx.field_typing.range_spec import RangeSpec
|
11
|
+
from lfx.inputs.inputs import DictInput, DropdownInput, FloatInput, IntInput, SecretStrInput, StrInput
|
12
|
+
|
13
|
+
|
14
|
+
class LMStudioModelComponent(LCModelComponent):
|
15
|
+
display_name = "LM Studio"
|
16
|
+
description = "Generate text using LM Studio Local LLMs."
|
17
|
+
icon = "LMStudio"
|
18
|
+
name = "LMStudioModel"
|
19
|
+
|
20
|
+
@override
|
21
|
+
async def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None):
|
22
|
+
if field_name == "model_name":
|
23
|
+
base_url_dict = build_config.get("base_url", {})
|
24
|
+
base_url_load_from_db = base_url_dict.get("load_from_db", False)
|
25
|
+
base_url_value = base_url_dict.get("value")
|
26
|
+
if base_url_load_from_db:
|
27
|
+
base_url_value = await self.get_variables(base_url_value, field_name)
|
28
|
+
elif not base_url_value:
|
29
|
+
base_url_value = "http://localhost:1234/v1"
|
30
|
+
build_config["model_name"]["options"] = await self.get_model(base_url_value)
|
31
|
+
|
32
|
+
return build_config
|
33
|
+
|
34
|
+
@staticmethod
|
35
|
+
async def get_model(base_url_value: str) -> list[str]:
|
36
|
+
try:
|
37
|
+
url = urljoin(base_url_value, "/v1/models")
|
38
|
+
async with httpx.AsyncClient() as client:
|
39
|
+
response = await client.get(url)
|
40
|
+
response.raise_for_status()
|
41
|
+
data = response.json()
|
42
|
+
|
43
|
+
return [model["id"] for model in data.get("data", [])]
|
44
|
+
except Exception as e:
|
45
|
+
msg = "Could not retrieve models. Please, make sure the LM Studio server is running."
|
46
|
+
raise ValueError(msg) from e
|
47
|
+
|
48
|
+
inputs = [
|
49
|
+
*LCModelComponent.get_base_inputs(),
|
50
|
+
IntInput(
|
51
|
+
name="max_tokens",
|
52
|
+
display_name="Max Tokens",
|
53
|
+
advanced=True,
|
54
|
+
info="The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
|
55
|
+
range_spec=RangeSpec(min=0, max=128000),
|
56
|
+
),
|
57
|
+
DictInput(name="model_kwargs", display_name="Model Kwargs", advanced=True),
|
58
|
+
DropdownInput(
|
59
|
+
name="model_name",
|
60
|
+
display_name="Model Name",
|
61
|
+
advanced=False,
|
62
|
+
refresh_button=True,
|
63
|
+
),
|
64
|
+
StrInput(
|
65
|
+
name="base_url",
|
66
|
+
display_name="Base URL",
|
67
|
+
advanced=False,
|
68
|
+
info="Endpoint of the LM Studio API. Defaults to 'http://localhost:1234/v1' if not specified.",
|
69
|
+
value="http://localhost:1234/v1",
|
70
|
+
),
|
71
|
+
SecretStrInput(
|
72
|
+
name="api_key",
|
73
|
+
display_name="LM Studio API Key",
|
74
|
+
info="The LM Studio API Key to use for LM Studio.",
|
75
|
+
advanced=True,
|
76
|
+
value="LMSTUDIO_API_KEY",
|
77
|
+
),
|
78
|
+
FloatInput(
|
79
|
+
name="temperature",
|
80
|
+
display_name="Temperature",
|
81
|
+
value=0.1,
|
82
|
+
advanced=True,
|
83
|
+
),
|
84
|
+
IntInput(
|
85
|
+
name="seed",
|
86
|
+
display_name="Seed",
|
87
|
+
info="The seed controls the reproducibility of the job.",
|
88
|
+
advanced=True,
|
89
|
+
value=1,
|
90
|
+
),
|
91
|
+
]
|
92
|
+
|
93
|
+
def build_model(self) -> LanguageModel: # type: ignore[type-var]
|
94
|
+
lmstudio_api_key = self.api_key
|
95
|
+
temperature = self.temperature
|
96
|
+
model_name: str = self.model_name
|
97
|
+
max_tokens = self.max_tokens
|
98
|
+
model_kwargs = self.model_kwargs or {}
|
99
|
+
base_url = self.base_url or "http://localhost:1234/v1"
|
100
|
+
seed = self.seed
|
101
|
+
|
102
|
+
return ChatOpenAI(
|
103
|
+
max_tokens=max_tokens or None,
|
104
|
+
model_kwargs=model_kwargs,
|
105
|
+
model=model_name,
|
106
|
+
base_url=base_url,
|
107
|
+
api_key=lmstudio_api_key,
|
108
|
+
temperature=temperature if temperature is not None else 0.1,
|
109
|
+
seed=seed,
|
110
|
+
)
|
111
|
+
|
112
|
+
def _get_exception_message(self, e: Exception):
|
113
|
+
"""Get a message from an LM Studio exception.
|
114
|
+
|
115
|
+
Args:
|
116
|
+
e (Exception): The exception to get the message from.
|
117
|
+
|
118
|
+
Returns:
|
119
|
+
str: The message from the exception.
|
120
|
+
"""
|
121
|
+
try:
|
122
|
+
from openai import BadRequestError
|
123
|
+
except ImportError:
|
124
|
+
return None
|
125
|
+
if isinstance(e, BadRequestError):
|
126
|
+
message = e.body.get("message")
|
127
|
+
if message:
|
128
|
+
return message
|
129
|
+
return None
|
@@ -0,0 +1,52 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING, Any
|
4
|
+
|
5
|
+
from lfx.components._importing import import_mod
|
6
|
+
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from lfx.components.logic.conditional_router import ConditionalRouterComponent
|
9
|
+
from lfx.components.logic.data_conditional_router import DataConditionalRouterComponent
|
10
|
+
from lfx.components.logic.flow_tool import FlowToolComponent
|
11
|
+
from lfx.components.logic.loop import LoopComponent
|
12
|
+
from lfx.components.logic.pass_message import PassMessageComponent
|
13
|
+
from lfx.components.logic.run_flow import RunFlowComponent
|
14
|
+
from lfx.components.logic.sub_flow import SubFlowComponent
|
15
|
+
|
16
|
+
_dynamic_imports = {
|
17
|
+
"ConditionalRouterComponent": "conditional_router",
|
18
|
+
"DataConditionalRouterComponent": "data_conditional_router",
|
19
|
+
"FlowToolComponent": "flow_tool",
|
20
|
+
"LoopComponent": "loop",
|
21
|
+
"PassMessageComponent": "pass_message",
|
22
|
+
"RunFlowComponent": "run_flow",
|
23
|
+
"SubFlowComponent": "sub_flow",
|
24
|
+
}
|
25
|
+
|
26
|
+
__all__ = [
|
27
|
+
"ConditionalRouterComponent",
|
28
|
+
"DataConditionalRouterComponent",
|
29
|
+
"FlowToolComponent",
|
30
|
+
"LoopComponent",
|
31
|
+
"PassMessageComponent",
|
32
|
+
"RunFlowComponent",
|
33
|
+
"SubFlowComponent",
|
34
|
+
]
|
35
|
+
|
36
|
+
|
37
|
+
def __getattr__(attr_name: str) -> Any:
|
38
|
+
"""Lazily import logic components on attribute access."""
|
39
|
+
if attr_name not in _dynamic_imports:
|
40
|
+
msg = f"module '{__name__}' has no attribute '{attr_name}'"
|
41
|
+
raise AttributeError(msg)
|
42
|
+
try:
|
43
|
+
result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
|
44
|
+
except (ModuleNotFoundError, ImportError, AttributeError) as e:
|
45
|
+
msg = f"Could not import '{attr_name}' from '{__name__}': {e}"
|
46
|
+
raise AttributeError(msg) from e
|
47
|
+
globals()[attr_name] = result
|
48
|
+
return result
|
49
|
+
|
50
|
+
|
51
|
+
def __dir__() -> list[str]:
|
52
|
+
return list(__all__)
|