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,87 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
from langchain.tools import StructuredTool
|
4
|
+
from langchain_community.utilities.searchapi import SearchApiAPIWrapper
|
5
|
+
from pydantic import BaseModel, Field
|
6
|
+
|
7
|
+
from lfx.base.langchain_utilities.model import LCToolComponent
|
8
|
+
from lfx.field_typing import Tool
|
9
|
+
from lfx.inputs.inputs import DictInput, IntInput, MessageTextInput, MultilineInput, SecretStrInput
|
10
|
+
from lfx.schema.data import Data
|
11
|
+
|
12
|
+
|
13
|
+
class SearchAPIComponent(LCToolComponent):
|
14
|
+
display_name: str = "Search API [DEPRECATED]"
|
15
|
+
description: str = "Call the searchapi.io API with result limiting"
|
16
|
+
name = "SearchAPI"
|
17
|
+
documentation: str = "https://www.searchapi.io/docs/google"
|
18
|
+
icon = "SearchAPI"
|
19
|
+
legacy = True
|
20
|
+
|
21
|
+
inputs = [
|
22
|
+
MessageTextInput(name="engine", display_name="Engine", value="google"),
|
23
|
+
SecretStrInput(name="api_key", display_name="SearchAPI API Key", required=True),
|
24
|
+
MultilineInput(
|
25
|
+
name="input_value",
|
26
|
+
display_name="Input",
|
27
|
+
),
|
28
|
+
DictInput(name="search_params", display_name="Search parameters", advanced=True, is_list=True),
|
29
|
+
IntInput(name="max_results", display_name="Max Results", value=5, advanced=True),
|
30
|
+
IntInput(name="max_snippet_length", display_name="Max Snippet Length", value=100, advanced=True),
|
31
|
+
]
|
32
|
+
|
33
|
+
class SearchAPISchema(BaseModel):
|
34
|
+
query: str = Field(..., description="The search query")
|
35
|
+
params: dict[str, Any] = Field(default_factory=dict, description="Additional search parameters")
|
36
|
+
max_results: int = Field(5, description="Maximum number of results to return")
|
37
|
+
max_snippet_length: int = Field(100, description="Maximum length of each result snippet")
|
38
|
+
|
39
|
+
def _build_wrapper(self):
|
40
|
+
return SearchApiAPIWrapper(engine=self.engine, searchapi_api_key=self.api_key)
|
41
|
+
|
42
|
+
def build_tool(self) -> Tool:
|
43
|
+
wrapper = self._build_wrapper()
|
44
|
+
|
45
|
+
def search_func(
|
46
|
+
query: str, params: dict[str, Any] | None = None, max_results: int = 5, max_snippet_length: int = 100
|
47
|
+
) -> list[dict[str, Any]]:
|
48
|
+
params = params or {}
|
49
|
+
full_results = wrapper.results(query=query, **params)
|
50
|
+
organic_results = full_results.get("organic_results", [])[:max_results]
|
51
|
+
|
52
|
+
limited_results = []
|
53
|
+
for result in organic_results:
|
54
|
+
limited_result = {
|
55
|
+
"title": result.get("title", "")[:max_snippet_length],
|
56
|
+
"link": result.get("link", ""),
|
57
|
+
"snippet": result.get("snippet", "")[:max_snippet_length],
|
58
|
+
}
|
59
|
+
limited_results.append(limited_result)
|
60
|
+
|
61
|
+
return limited_results
|
62
|
+
|
63
|
+
tool = StructuredTool.from_function(
|
64
|
+
name="search_api",
|
65
|
+
description="Search for recent results using searchapi.io with result limiting",
|
66
|
+
func=search_func,
|
67
|
+
args_schema=self.SearchAPISchema,
|
68
|
+
)
|
69
|
+
|
70
|
+
self.status = f"Search API Tool created with engine: {self.engine}"
|
71
|
+
return tool
|
72
|
+
|
73
|
+
def run_model(self) -> list[Data]:
|
74
|
+
tool = self.build_tool()
|
75
|
+
results = tool.run(
|
76
|
+
{
|
77
|
+
"query": self.input_value,
|
78
|
+
"params": self.search_params or {},
|
79
|
+
"max_results": self.max_results,
|
80
|
+
"max_snippet_length": self.max_snippet_length,
|
81
|
+
}
|
82
|
+
)
|
83
|
+
|
84
|
+
data_list = [Data(data=result, text=result.get("snippet", "")) for result in results]
|
85
|
+
|
86
|
+
self.status = data_list
|
87
|
+
return data_list
|
@@ -0,0 +1,145 @@
|
|
1
|
+
import json
|
2
|
+
from collections.abc import Sequence
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
import requests
|
6
|
+
from langchain.agents import Tool
|
7
|
+
from langchain_core.tools import StructuredTool
|
8
|
+
from pydantic.v1 import Field, create_model
|
9
|
+
|
10
|
+
from lfx.base.langchain_utilities.model import LCToolComponent
|
11
|
+
from lfx.inputs.inputs import DropdownInput, IntInput, MessageTextInput, MultiselectInput
|
12
|
+
from lfx.io import Output
|
13
|
+
from lfx.log.logger import logger
|
14
|
+
from lfx.schema.dotdict import dotdict
|
15
|
+
|
16
|
+
|
17
|
+
class SearXNGToolComponent(LCToolComponent):
|
18
|
+
search_headers: dict = {}
|
19
|
+
display_name = "SearXNG Search"
|
20
|
+
description = "A component that searches for tools using SearXNG."
|
21
|
+
name = "SearXNGTool"
|
22
|
+
legacy: bool = True
|
23
|
+
|
24
|
+
inputs = [
|
25
|
+
MessageTextInput(
|
26
|
+
name="url",
|
27
|
+
display_name="URL",
|
28
|
+
value="http://localhost",
|
29
|
+
required=True,
|
30
|
+
refresh_button=True,
|
31
|
+
),
|
32
|
+
IntInput(
|
33
|
+
name="max_results",
|
34
|
+
display_name="Max Results",
|
35
|
+
value=10,
|
36
|
+
required=True,
|
37
|
+
),
|
38
|
+
MultiselectInput(
|
39
|
+
name="categories",
|
40
|
+
display_name="Categories",
|
41
|
+
options=[],
|
42
|
+
value=[],
|
43
|
+
),
|
44
|
+
DropdownInput(
|
45
|
+
name="language",
|
46
|
+
display_name="Language",
|
47
|
+
options=[],
|
48
|
+
),
|
49
|
+
]
|
50
|
+
|
51
|
+
outputs = [
|
52
|
+
Output(display_name="Tool", name="result_tool", method="build_tool"),
|
53
|
+
]
|
54
|
+
|
55
|
+
def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:
|
56
|
+
if field_name is None:
|
57
|
+
return build_config
|
58
|
+
|
59
|
+
if field_name != "url":
|
60
|
+
return build_config
|
61
|
+
|
62
|
+
try:
|
63
|
+
url = f"{field_value}/config"
|
64
|
+
|
65
|
+
response = requests.get(url=url, headers=self.search_headers.copy(), timeout=10)
|
66
|
+
data = None
|
67
|
+
if response.headers.get("Content-Encoding") == "zstd":
|
68
|
+
data = json.loads(response.content)
|
69
|
+
else:
|
70
|
+
data = response.json()
|
71
|
+
build_config["categories"]["options"] = data["categories"].copy()
|
72
|
+
for selected_category in build_config["categories"]["value"]:
|
73
|
+
if selected_category not in build_config["categories"]["options"]:
|
74
|
+
build_config["categories"]["value"].remove(selected_category)
|
75
|
+
languages = list(data["locales"])
|
76
|
+
build_config["language"]["options"] = languages.copy()
|
77
|
+
except Exception as e: # noqa: BLE001
|
78
|
+
self.status = f"Failed to extract names: {e}"
|
79
|
+
logger.debug(self.status, exc_info=True)
|
80
|
+
build_config["categories"]["options"] = ["Failed to parse", str(e)]
|
81
|
+
return build_config
|
82
|
+
|
83
|
+
def build_tool(self) -> Tool:
|
84
|
+
class SearxSearch:
|
85
|
+
_url: str = ""
|
86
|
+
_categories: list[str] = []
|
87
|
+
_language: str = ""
|
88
|
+
_headers: dict = {}
|
89
|
+
_max_results: int = 10
|
90
|
+
|
91
|
+
@staticmethod
|
92
|
+
def search(query: str, categories: Sequence[str] = ()) -> list:
|
93
|
+
if not SearxSearch._categories and not categories:
|
94
|
+
msg = "No categories provided."
|
95
|
+
raise ValueError(msg)
|
96
|
+
all_categories = SearxSearch._categories + list(set(categories) - set(SearxSearch._categories))
|
97
|
+
try:
|
98
|
+
url = f"{SearxSearch._url}/"
|
99
|
+
headers = SearxSearch._headers.copy()
|
100
|
+
response = requests.get(
|
101
|
+
url=url,
|
102
|
+
headers=headers,
|
103
|
+
params={
|
104
|
+
"q": query,
|
105
|
+
"categories": ",".join(all_categories),
|
106
|
+
"language": SearxSearch._language,
|
107
|
+
"format": "json",
|
108
|
+
},
|
109
|
+
timeout=10,
|
110
|
+
).json()
|
111
|
+
|
112
|
+
num_results = min(SearxSearch._max_results, len(response["results"]))
|
113
|
+
return [response["results"][i] for i in range(num_results)]
|
114
|
+
except Exception as e: # noqa: BLE001
|
115
|
+
logger.debug("Error running SearXNG Search", exc_info=True)
|
116
|
+
return [f"Failed to search: {e}"]
|
117
|
+
|
118
|
+
SearxSearch._url = self.url
|
119
|
+
SearxSearch._categories = self.categories.copy()
|
120
|
+
SearxSearch._language = self.language
|
121
|
+
SearxSearch._headers = self.search_headers.copy()
|
122
|
+
SearxSearch._max_results = self.max_results
|
123
|
+
|
124
|
+
globals_ = globals()
|
125
|
+
local = {}
|
126
|
+
local["SearxSearch"] = SearxSearch
|
127
|
+
globals_.update(local)
|
128
|
+
|
129
|
+
schema_fields = {
|
130
|
+
"query": (str, Field(..., description="The query to search for.")),
|
131
|
+
"categories": (
|
132
|
+
list[str],
|
133
|
+
Field(default=[], description="The categories to search in."),
|
134
|
+
),
|
135
|
+
}
|
136
|
+
|
137
|
+
searx_search_schema = create_model("SearxSearchSchema", **schema_fields)
|
138
|
+
|
139
|
+
return StructuredTool.from_function(
|
140
|
+
func=local["SearxSearch"].search,
|
141
|
+
args_schema=searx_search_schema,
|
142
|
+
name="searxng_search_tool",
|
143
|
+
description="A tool that searches for tools using SearXNG.\nThe available categories are: "
|
144
|
+
+ ", ".join(self.categories),
|
145
|
+
)
|
@@ -0,0 +1,119 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
from langchain.tools import StructuredTool
|
4
|
+
from langchain_community.utilities.serpapi import SerpAPIWrapper
|
5
|
+
from langchain_core.tools import ToolException
|
6
|
+
from pydantic import BaseModel, Field
|
7
|
+
|
8
|
+
from lfx.base.langchain_utilities.model import LCToolComponent
|
9
|
+
from lfx.field_typing import Tool
|
10
|
+
from lfx.inputs.inputs import DictInput, IntInput, MultilineInput, SecretStrInput
|
11
|
+
from lfx.log.logger import logger
|
12
|
+
from lfx.schema.data import Data
|
13
|
+
|
14
|
+
|
15
|
+
class SerpAPISchema(BaseModel):
|
16
|
+
"""Schema for SerpAPI search parameters."""
|
17
|
+
|
18
|
+
query: str = Field(..., description="The search query")
|
19
|
+
params: dict[str, Any] | None = Field(
|
20
|
+
default={
|
21
|
+
"engine": "google",
|
22
|
+
"google_domain": "google.com",
|
23
|
+
"gl": "us",
|
24
|
+
"hl": "en",
|
25
|
+
},
|
26
|
+
description="Additional search parameters",
|
27
|
+
)
|
28
|
+
max_results: int = Field(5, description="Maximum number of results to return")
|
29
|
+
max_snippet_length: int = Field(100, description="Maximum length of each result snippet")
|
30
|
+
|
31
|
+
|
32
|
+
class SerpAPIComponent(LCToolComponent):
|
33
|
+
display_name = "Serp Search API [DEPRECATED]"
|
34
|
+
description = "Call Serp Search API with result limiting"
|
35
|
+
name = "SerpAPI"
|
36
|
+
icon = "SerpSearch"
|
37
|
+
legacy = True
|
38
|
+
|
39
|
+
inputs = [
|
40
|
+
SecretStrInput(name="serpapi_api_key", display_name="SerpAPI API Key", required=True),
|
41
|
+
MultilineInput(
|
42
|
+
name="input_value",
|
43
|
+
display_name="Input",
|
44
|
+
),
|
45
|
+
DictInput(name="search_params", display_name="Parameters", advanced=True, is_list=True),
|
46
|
+
IntInput(name="max_results", display_name="Max Results", value=5, advanced=True),
|
47
|
+
IntInput(name="max_snippet_length", display_name="Max Snippet Length", value=100, advanced=True),
|
48
|
+
]
|
49
|
+
|
50
|
+
def _build_wrapper(self, params: dict[str, Any] | None = None) -> SerpAPIWrapper:
|
51
|
+
"""Build a SerpAPIWrapper with the provided parameters."""
|
52
|
+
params = params or {}
|
53
|
+
if params:
|
54
|
+
return SerpAPIWrapper(
|
55
|
+
serpapi_api_key=self.serpapi_api_key,
|
56
|
+
params=params,
|
57
|
+
)
|
58
|
+
return SerpAPIWrapper(serpapi_api_key=self.serpapi_api_key)
|
59
|
+
|
60
|
+
def build_tool(self) -> Tool:
|
61
|
+
wrapper = self._build_wrapper(self.search_params)
|
62
|
+
|
63
|
+
def search_func(
|
64
|
+
query: str, params: dict[str, Any] | None = None, max_results: int = 5, max_snippet_length: int = 100
|
65
|
+
) -> list[dict[str, Any]]:
|
66
|
+
try:
|
67
|
+
local_wrapper = wrapper
|
68
|
+
if params:
|
69
|
+
local_wrapper = self._build_wrapper(params)
|
70
|
+
|
71
|
+
full_results = local_wrapper.results(query)
|
72
|
+
organic_results = full_results.get("organic_results", [])[:max_results]
|
73
|
+
|
74
|
+
limited_results = []
|
75
|
+
for result in organic_results:
|
76
|
+
limited_result = {
|
77
|
+
"title": result.get("title", "")[:max_snippet_length],
|
78
|
+
"link": result.get("link", ""),
|
79
|
+
"snippet": result.get("snippet", "")[:max_snippet_length],
|
80
|
+
}
|
81
|
+
limited_results.append(limited_result)
|
82
|
+
|
83
|
+
except Exception as e:
|
84
|
+
error_message = f"Error in SerpAPI search: {e!s}"
|
85
|
+
logger.debug(error_message)
|
86
|
+
raise ToolException(error_message) from e
|
87
|
+
return limited_results
|
88
|
+
|
89
|
+
tool = StructuredTool.from_function(
|
90
|
+
name="serp_search_api",
|
91
|
+
description="Search for recent results using SerpAPI with result limiting",
|
92
|
+
func=search_func,
|
93
|
+
args_schema=SerpAPISchema,
|
94
|
+
)
|
95
|
+
|
96
|
+
self.status = "SerpAPI Tool created"
|
97
|
+
return tool
|
98
|
+
|
99
|
+
def run_model(self) -> list[Data]:
|
100
|
+
tool = self.build_tool()
|
101
|
+
try:
|
102
|
+
results = tool.run(
|
103
|
+
{
|
104
|
+
"query": self.input_value,
|
105
|
+
"params": self.search_params or {},
|
106
|
+
"max_results": self.max_results,
|
107
|
+
"max_snippet_length": self.max_snippet_length,
|
108
|
+
}
|
109
|
+
)
|
110
|
+
|
111
|
+
data_list = [Data(data=result, text=result.get("snippet", "")) for result in results]
|
112
|
+
|
113
|
+
except Exception as e: # noqa: BLE001
|
114
|
+
logger.debug("Error running SerpAPI", exc_info=True)
|
115
|
+
self.status = f"Error: {e}"
|
116
|
+
return [Data(data={"error": str(e)}, text=str(e))]
|
117
|
+
|
118
|
+
self.status = data_list # type: ignore[assignment]
|
119
|
+
return data_list
|
@@ -0,0 +1,344 @@
|
|
1
|
+
from enum import Enum
|
2
|
+
|
3
|
+
import httpx
|
4
|
+
from langchain.tools import StructuredTool
|
5
|
+
from langchain_core.tools import ToolException
|
6
|
+
from pydantic import BaseModel, Field
|
7
|
+
|
8
|
+
from lfx.base.langchain_utilities.model import LCToolComponent
|
9
|
+
from lfx.field_typing import Tool
|
10
|
+
from lfx.inputs.inputs import BoolInput, DropdownInput, IntInput, MessageTextInput, SecretStrInput
|
11
|
+
from lfx.log.logger import logger
|
12
|
+
from lfx.schema.data import Data
|
13
|
+
|
14
|
+
# Add at the top with other constants
|
15
|
+
MAX_CHUNKS_PER_SOURCE = 3
|
16
|
+
|
17
|
+
|
18
|
+
class TavilySearchDepth(Enum):
|
19
|
+
BASIC = "basic"
|
20
|
+
ADVANCED = "advanced"
|
21
|
+
|
22
|
+
|
23
|
+
class TavilySearchTopic(Enum):
|
24
|
+
GENERAL = "general"
|
25
|
+
NEWS = "news"
|
26
|
+
|
27
|
+
|
28
|
+
class TavilySearchTimeRange(Enum):
|
29
|
+
DAY = "day"
|
30
|
+
WEEK = "week"
|
31
|
+
MONTH = "month"
|
32
|
+
YEAR = "year"
|
33
|
+
|
34
|
+
|
35
|
+
class TavilySearchSchema(BaseModel):
|
36
|
+
query: str = Field(..., description="The search query you want to execute with Tavily.")
|
37
|
+
search_depth: TavilySearchDepth = Field(TavilySearchDepth.BASIC, description="The depth of the search.")
|
38
|
+
topic: TavilySearchTopic = Field(TavilySearchTopic.GENERAL, description="The category of the search.")
|
39
|
+
max_results: int = Field(5, description="The maximum number of search results to return.")
|
40
|
+
include_images: bool = Field(default=False, description="Include a list of query-related images in the response.")
|
41
|
+
include_answer: bool = Field(default=False, description="Include a short answer to original query.")
|
42
|
+
chunks_per_source: int = Field(
|
43
|
+
default=MAX_CHUNKS_PER_SOURCE,
|
44
|
+
description=(
|
45
|
+
"The number of content chunks to retrieve from each source (max 500 chars each). Only for advanced search."
|
46
|
+
),
|
47
|
+
ge=1,
|
48
|
+
le=MAX_CHUNKS_PER_SOURCE,
|
49
|
+
)
|
50
|
+
include_domains: list[str] = Field(
|
51
|
+
default=[],
|
52
|
+
description="A list of domains to specifically include in the search results.",
|
53
|
+
)
|
54
|
+
exclude_domains: list[str] = Field(
|
55
|
+
default=[],
|
56
|
+
description="A list of domains to specifically exclude from the search results.",
|
57
|
+
)
|
58
|
+
include_raw_content: bool = Field(
|
59
|
+
default=False,
|
60
|
+
description="Include the cleaned and parsed HTML content of each search result.",
|
61
|
+
)
|
62
|
+
days: int = Field(
|
63
|
+
default=7,
|
64
|
+
description="Number of days back from the current date to include. Only available if topic is news.",
|
65
|
+
ge=1,
|
66
|
+
)
|
67
|
+
time_range: TavilySearchTimeRange | None = Field(
|
68
|
+
default=None,
|
69
|
+
description="The time range back from the current date to filter results.",
|
70
|
+
)
|
71
|
+
|
72
|
+
|
73
|
+
class TavilySearchToolComponent(LCToolComponent):
|
74
|
+
display_name = "Tavily Search API"
|
75
|
+
description = """**Tavily Search API** is a search engine optimized for LLMs and RAG, \
|
76
|
+
aimed at efficient, quick, and persistent search results. It can be used independently or as an agent tool.
|
77
|
+
|
78
|
+
Note: Check 'Advanced' for all options.
|
79
|
+
"""
|
80
|
+
icon = "TavilyIcon"
|
81
|
+
name = "TavilyAISearch"
|
82
|
+
documentation = "https://docs.tavily.com/"
|
83
|
+
legacy = True
|
84
|
+
|
85
|
+
inputs = [
|
86
|
+
SecretStrInput(
|
87
|
+
name="api_key",
|
88
|
+
display_name="Tavily API Key",
|
89
|
+
required=True,
|
90
|
+
info="Your Tavily API Key.",
|
91
|
+
),
|
92
|
+
MessageTextInput(
|
93
|
+
name="query",
|
94
|
+
display_name="Search Query",
|
95
|
+
info="The search query you want to execute with Tavily.",
|
96
|
+
),
|
97
|
+
DropdownInput(
|
98
|
+
name="search_depth",
|
99
|
+
display_name="Search Depth",
|
100
|
+
info="The depth of the search.",
|
101
|
+
options=list(TavilySearchDepth),
|
102
|
+
value=TavilySearchDepth.ADVANCED,
|
103
|
+
advanced=True,
|
104
|
+
),
|
105
|
+
IntInput(
|
106
|
+
name="chunks_per_source",
|
107
|
+
display_name="Chunks Per Source",
|
108
|
+
info=("The number of content chunks to retrieve from each source (1-3). Only works with advanced search."),
|
109
|
+
value=MAX_CHUNKS_PER_SOURCE,
|
110
|
+
advanced=True,
|
111
|
+
),
|
112
|
+
DropdownInput(
|
113
|
+
name="topic",
|
114
|
+
display_name="Search Topic",
|
115
|
+
info="The category of the search.",
|
116
|
+
options=list(TavilySearchTopic),
|
117
|
+
value=TavilySearchTopic.GENERAL,
|
118
|
+
advanced=True,
|
119
|
+
),
|
120
|
+
IntInput(
|
121
|
+
name="days",
|
122
|
+
display_name="Days",
|
123
|
+
info="Number of days back from current date to include. Only available with news topic.",
|
124
|
+
value=7,
|
125
|
+
advanced=True,
|
126
|
+
),
|
127
|
+
IntInput(
|
128
|
+
name="max_results",
|
129
|
+
display_name="Max Results",
|
130
|
+
info="The maximum number of search results to return.",
|
131
|
+
value=5,
|
132
|
+
advanced=True,
|
133
|
+
),
|
134
|
+
BoolInput(
|
135
|
+
name="include_answer",
|
136
|
+
display_name="Include Answer",
|
137
|
+
info="Include a short answer to original query.",
|
138
|
+
value=True,
|
139
|
+
advanced=True,
|
140
|
+
),
|
141
|
+
DropdownInput(
|
142
|
+
name="time_range",
|
143
|
+
display_name="Time Range",
|
144
|
+
info="The time range back from the current date to filter results.",
|
145
|
+
options=list(TavilySearchTimeRange),
|
146
|
+
value=None,
|
147
|
+
advanced=True,
|
148
|
+
),
|
149
|
+
BoolInput(
|
150
|
+
name="include_images",
|
151
|
+
display_name="Include Images",
|
152
|
+
info="Include a list of query-related images in the response.",
|
153
|
+
value=True,
|
154
|
+
advanced=True,
|
155
|
+
),
|
156
|
+
MessageTextInput(
|
157
|
+
name="include_domains",
|
158
|
+
display_name="Include Domains",
|
159
|
+
info="Comma-separated list of domains to include in the search results.",
|
160
|
+
advanced=True,
|
161
|
+
),
|
162
|
+
MessageTextInput(
|
163
|
+
name="exclude_domains",
|
164
|
+
display_name="Exclude Domains",
|
165
|
+
info="Comma-separated list of domains to exclude from the search results.",
|
166
|
+
advanced=True,
|
167
|
+
),
|
168
|
+
BoolInput(
|
169
|
+
name="include_raw_content",
|
170
|
+
display_name="Include Raw Content",
|
171
|
+
info="Include the cleaned and parsed HTML content of each search result.",
|
172
|
+
value=False,
|
173
|
+
advanced=True,
|
174
|
+
),
|
175
|
+
]
|
176
|
+
|
177
|
+
def run_model(self) -> list[Data]:
|
178
|
+
# Convert string values to enum instances with validation
|
179
|
+
try:
|
180
|
+
search_depth_enum = (
|
181
|
+
self.search_depth
|
182
|
+
if isinstance(self.search_depth, TavilySearchDepth)
|
183
|
+
else TavilySearchDepth(str(self.search_depth).lower())
|
184
|
+
)
|
185
|
+
except ValueError as e:
|
186
|
+
error_message = f"Invalid search depth value: {e!s}"
|
187
|
+
self.status = error_message
|
188
|
+
return [Data(data={"error": error_message})]
|
189
|
+
|
190
|
+
try:
|
191
|
+
topic_enum = (
|
192
|
+
self.topic if isinstance(self.topic, TavilySearchTopic) else TavilySearchTopic(str(self.topic).lower())
|
193
|
+
)
|
194
|
+
except ValueError as e:
|
195
|
+
error_message = f"Invalid topic value: {e!s}"
|
196
|
+
self.status = error_message
|
197
|
+
return [Data(data={"error": error_message})]
|
198
|
+
|
199
|
+
try:
|
200
|
+
time_range_enum = (
|
201
|
+
self.time_range
|
202
|
+
if isinstance(self.time_range, TavilySearchTimeRange)
|
203
|
+
else TavilySearchTimeRange(str(self.time_range).lower())
|
204
|
+
if self.time_range
|
205
|
+
else None
|
206
|
+
)
|
207
|
+
except ValueError as e:
|
208
|
+
error_message = f"Invalid time range value: {e!s}"
|
209
|
+
self.status = error_message
|
210
|
+
return [Data(data={"error": error_message})]
|
211
|
+
|
212
|
+
# Initialize domain variables as None
|
213
|
+
include_domains = None
|
214
|
+
exclude_domains = None
|
215
|
+
|
216
|
+
# Only process domains if they're provided
|
217
|
+
if self.include_domains:
|
218
|
+
include_domains = [domain.strip() for domain in self.include_domains.split(",") if domain.strip()]
|
219
|
+
|
220
|
+
if self.exclude_domains:
|
221
|
+
exclude_domains = [domain.strip() for domain in self.exclude_domains.split(",") if domain.strip()]
|
222
|
+
|
223
|
+
return self._tavily_search(
|
224
|
+
self.query,
|
225
|
+
search_depth=search_depth_enum,
|
226
|
+
topic=topic_enum,
|
227
|
+
max_results=self.max_results,
|
228
|
+
include_images=self.include_images,
|
229
|
+
include_answer=self.include_answer,
|
230
|
+
chunks_per_source=self.chunks_per_source,
|
231
|
+
include_domains=include_domains,
|
232
|
+
exclude_domains=exclude_domains,
|
233
|
+
include_raw_content=self.include_raw_content,
|
234
|
+
days=self.days,
|
235
|
+
time_range=time_range_enum,
|
236
|
+
)
|
237
|
+
|
238
|
+
def build_tool(self) -> Tool:
|
239
|
+
return StructuredTool.from_function(
|
240
|
+
name="tavily_search",
|
241
|
+
description="Perform a web search using the Tavily API.",
|
242
|
+
func=self._tavily_search,
|
243
|
+
args_schema=TavilySearchSchema,
|
244
|
+
)
|
245
|
+
|
246
|
+
def _tavily_search(
|
247
|
+
self,
|
248
|
+
query: str,
|
249
|
+
*,
|
250
|
+
search_depth: TavilySearchDepth = TavilySearchDepth.BASIC,
|
251
|
+
topic: TavilySearchTopic = TavilySearchTopic.GENERAL,
|
252
|
+
max_results: int = 5,
|
253
|
+
include_images: bool = False,
|
254
|
+
include_answer: bool = False,
|
255
|
+
chunks_per_source: int = MAX_CHUNKS_PER_SOURCE,
|
256
|
+
include_domains: list[str] | None = None,
|
257
|
+
exclude_domains: list[str] | None = None,
|
258
|
+
include_raw_content: bool = False,
|
259
|
+
days: int = 7,
|
260
|
+
time_range: TavilySearchTimeRange | None = None,
|
261
|
+
) -> list[Data]:
|
262
|
+
# Validate enum values
|
263
|
+
if not isinstance(search_depth, TavilySearchDepth):
|
264
|
+
msg = f"Invalid search_depth value: {search_depth}"
|
265
|
+
raise TypeError(msg)
|
266
|
+
if not isinstance(topic, TavilySearchTopic):
|
267
|
+
msg = f"Invalid topic value: {topic}"
|
268
|
+
raise TypeError(msg)
|
269
|
+
|
270
|
+
# Validate chunks_per_source range
|
271
|
+
if not 1 <= chunks_per_source <= MAX_CHUNKS_PER_SOURCE:
|
272
|
+
msg = f"chunks_per_source must be between 1 and {MAX_CHUNKS_PER_SOURCE}, got {chunks_per_source}"
|
273
|
+
raise ValueError(msg)
|
274
|
+
|
275
|
+
# Validate days is positive
|
276
|
+
if days < 1:
|
277
|
+
msg = f"days must be greater than or equal to 1, got {days}"
|
278
|
+
raise ValueError(msg)
|
279
|
+
|
280
|
+
try:
|
281
|
+
url = "https://api.tavily.com/search"
|
282
|
+
headers = {
|
283
|
+
"content-type": "application/json",
|
284
|
+
"accept": "application/json",
|
285
|
+
}
|
286
|
+
payload = {
|
287
|
+
"api_key": self.api_key,
|
288
|
+
"query": query,
|
289
|
+
"search_depth": search_depth.value,
|
290
|
+
"topic": topic.value,
|
291
|
+
"max_results": max_results,
|
292
|
+
"include_images": include_images,
|
293
|
+
"include_answer": include_answer,
|
294
|
+
"chunks_per_source": chunks_per_source if search_depth == TavilySearchDepth.ADVANCED else None,
|
295
|
+
"include_domains": include_domains if include_domains else None,
|
296
|
+
"exclude_domains": exclude_domains if exclude_domains else None,
|
297
|
+
"include_raw_content": include_raw_content,
|
298
|
+
"days": days if topic == TavilySearchTopic.NEWS else None,
|
299
|
+
"time_range": time_range.value if time_range else None,
|
300
|
+
}
|
301
|
+
|
302
|
+
with httpx.Client(timeout=90.0) as client:
|
303
|
+
response = client.post(url, json=payload, headers=headers)
|
304
|
+
|
305
|
+
response.raise_for_status()
|
306
|
+
search_results = response.json()
|
307
|
+
|
308
|
+
data_results = [
|
309
|
+
Data(
|
310
|
+
data={
|
311
|
+
"title": result.get("title"),
|
312
|
+
"url": result.get("url"),
|
313
|
+
"content": result.get("content"),
|
314
|
+
"score": result.get("score"),
|
315
|
+
"raw_content": result.get("raw_content") if include_raw_content else None,
|
316
|
+
}
|
317
|
+
)
|
318
|
+
for result in search_results.get("results", [])
|
319
|
+
]
|
320
|
+
|
321
|
+
if include_answer and search_results.get("answer"):
|
322
|
+
data_results.insert(0, Data(data={"answer": search_results["answer"]}))
|
323
|
+
|
324
|
+
if include_images and search_results.get("images"):
|
325
|
+
data_results.append(Data(data={"images": search_results["images"]}))
|
326
|
+
|
327
|
+
self.status = data_results # type: ignore[assignment]
|
328
|
+
|
329
|
+
except httpx.TimeoutException as e:
|
330
|
+
error_message = "Request timed out (90s). Please try again or adjust parameters."
|
331
|
+
logger.error(f"Timeout error: {e}")
|
332
|
+
self.status = error_message
|
333
|
+
raise ToolException(error_message) from e
|
334
|
+
except httpx.HTTPStatusError as e:
|
335
|
+
error_message = f"HTTP error: {e.response.status_code} - {e.response.text}"
|
336
|
+
logger.debug(error_message)
|
337
|
+
self.status = error_message
|
338
|
+
raise ToolException(error_message) from e
|
339
|
+
except Exception as e:
|
340
|
+
error_message = f"Unexpected error: {e}"
|
341
|
+
logger.debug("Error running Tavily Search", exc_info=True)
|
342
|
+
self.status = error_message
|
343
|
+
raise ToolException(error_message) from e
|
344
|
+
return data_results
|