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,157 @@
|
|
1
|
+
import json
|
2
|
+
import re
|
3
|
+
from pathlib import Path
|
4
|
+
|
5
|
+
from google.auth.exceptions import RefreshError
|
6
|
+
from google.cloud import bigquery
|
7
|
+
from google.oauth2.service_account import Credentials
|
8
|
+
|
9
|
+
from lfx.custom import Component
|
10
|
+
from lfx.io import BoolInput, FileInput, MessageTextInput, Output
|
11
|
+
from lfx.schema.dataframe import DataFrame
|
12
|
+
|
13
|
+
|
14
|
+
class BigQueryExecutorComponent(Component):
|
15
|
+
display_name = "BigQuery"
|
16
|
+
description = "Execute SQL queries on Google BigQuery."
|
17
|
+
name = "BigQueryExecutor"
|
18
|
+
icon = "Google"
|
19
|
+
beta: bool = True
|
20
|
+
|
21
|
+
inputs = [
|
22
|
+
FileInput(
|
23
|
+
name="service_account_json_file",
|
24
|
+
display_name="Upload Service Account JSON",
|
25
|
+
info="Upload the JSON file containing Google Cloud service account credentials.",
|
26
|
+
file_types=["json"],
|
27
|
+
required=True,
|
28
|
+
),
|
29
|
+
MessageTextInput(
|
30
|
+
name="query",
|
31
|
+
display_name="SQL Query",
|
32
|
+
info="The SQL query to execute on BigQuery.",
|
33
|
+
required=True,
|
34
|
+
tool_mode=True,
|
35
|
+
),
|
36
|
+
BoolInput(
|
37
|
+
name="clean_query",
|
38
|
+
display_name="Clean Query",
|
39
|
+
info="When enabled, this will automatically clean up your SQL query.",
|
40
|
+
value=False,
|
41
|
+
advanced=True,
|
42
|
+
),
|
43
|
+
]
|
44
|
+
|
45
|
+
outputs = [
|
46
|
+
Output(display_name="Query Results", name="query_results", method="execute_sql"),
|
47
|
+
]
|
48
|
+
|
49
|
+
def _clean_sql_query(self, query: str) -> str:
|
50
|
+
"""Clean SQL query by removing surrounding quotes and whitespace.
|
51
|
+
|
52
|
+
Also extracts SQL statements from text that might contain other content.
|
53
|
+
|
54
|
+
Args:
|
55
|
+
query: The SQL query to clean
|
56
|
+
|
57
|
+
Returns:
|
58
|
+
The cleaned SQL query
|
59
|
+
"""
|
60
|
+
# First, try to extract SQL from code blocks
|
61
|
+
sql_pattern = r"```(?:sql)?\s*([\s\S]*?)\s*```"
|
62
|
+
sql_matches = re.findall(sql_pattern, query, re.IGNORECASE)
|
63
|
+
|
64
|
+
if sql_matches:
|
65
|
+
# If we found SQL in code blocks, use the first match
|
66
|
+
query = sql_matches[0]
|
67
|
+
else:
|
68
|
+
# If no code block, try to find SQL statements
|
69
|
+
# Look for common SQL keywords at the start of lines
|
70
|
+
sql_keywords = r"(?i)(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|WITH|MERGE)"
|
71
|
+
lines = query.split("\n")
|
72
|
+
sql_lines = []
|
73
|
+
in_sql = False
|
74
|
+
|
75
|
+
for _line in lines:
|
76
|
+
line = _line.strip()
|
77
|
+
if re.match(sql_keywords, line):
|
78
|
+
in_sql = True
|
79
|
+
if in_sql:
|
80
|
+
sql_lines.append(line)
|
81
|
+
if line.endswith(";"):
|
82
|
+
in_sql = False
|
83
|
+
|
84
|
+
if sql_lines:
|
85
|
+
query = "\n".join(sql_lines)
|
86
|
+
|
87
|
+
# Remove any backticks that might be at the start or end
|
88
|
+
query = query.strip("`")
|
89
|
+
|
90
|
+
# Then remove surrounding quotes (single or double) if they exist
|
91
|
+
query = query.strip()
|
92
|
+
if (query.startswith('"') and query.endswith('"')) or (query.startswith("'") and query.endswith("'")):
|
93
|
+
query = query[1:-1]
|
94
|
+
|
95
|
+
# Finally, clean up any remaining whitespace and ensure no backticks remain
|
96
|
+
query = query.strip()
|
97
|
+
# Remove any remaining backticks, but preserve them if they're part of a table/column name
|
98
|
+
# This regex will remove backticks that are not part of a valid identifier
|
99
|
+
return re.sub(r"`(?![a-zA-Z0-9_])|(?<![a-zA-Z0-9_])`", "", query)
|
100
|
+
|
101
|
+
def execute_sql(self) -> DataFrame:
|
102
|
+
try:
|
103
|
+
# First try to read the file
|
104
|
+
try:
|
105
|
+
service_account_path = Path(self.service_account_json_file)
|
106
|
+
with service_account_path.open() as f:
|
107
|
+
credentials_json = json.load(f)
|
108
|
+
project_id = credentials_json.get("project_id")
|
109
|
+
if not project_id:
|
110
|
+
msg = "No project_id found in service account credentials file."
|
111
|
+
raise ValueError(msg)
|
112
|
+
except FileNotFoundError as e:
|
113
|
+
msg = f"Service account file not found: {e}"
|
114
|
+
raise ValueError(msg) from e
|
115
|
+
except json.JSONDecodeError as e:
|
116
|
+
msg = "Invalid JSON string for service account credentials"
|
117
|
+
raise ValueError(msg) from e
|
118
|
+
|
119
|
+
# Then try to load credentials
|
120
|
+
try:
|
121
|
+
credentials = Credentials.from_service_account_file(self.service_account_json_file)
|
122
|
+
except Exception as e:
|
123
|
+
msg = f"Error loading service account credentials: {e}"
|
124
|
+
raise ValueError(msg) from e
|
125
|
+
|
126
|
+
except ValueError:
|
127
|
+
raise
|
128
|
+
except Exception as e:
|
129
|
+
msg = f"Error executing BigQuery SQL query: {e}"
|
130
|
+
raise ValueError(msg) from e
|
131
|
+
|
132
|
+
try:
|
133
|
+
client = bigquery.Client(credentials=credentials, project=project_id)
|
134
|
+
|
135
|
+
# Check for empty or whitespace-only query before cleaning
|
136
|
+
if not str(self.query).strip():
|
137
|
+
msg = "No valid SQL query found in input text."
|
138
|
+
raise ValueError(msg)
|
139
|
+
|
140
|
+
# Always clean the query if it contains code block markers, quotes, or if clean_query is enabled
|
141
|
+
if "```" in str(self.query) or '"' in str(self.query) or "'" in str(self.query) or self.clean_query:
|
142
|
+
sql_query = self._clean_sql_query(str(self.query))
|
143
|
+
else:
|
144
|
+
sql_query = str(self.query).strip() # At minimum, strip whitespace
|
145
|
+
|
146
|
+
query_job = client.query(sql_query)
|
147
|
+
results = query_job.result()
|
148
|
+
output_dict = [dict(row) for row in results]
|
149
|
+
|
150
|
+
except RefreshError as e:
|
151
|
+
msg = "Authentication error: Unable to refresh authentication token. Please try to reauthenticate."
|
152
|
+
raise ValueError(msg) from e
|
153
|
+
except Exception as e:
|
154
|
+
msg = f"Error executing BigQuery SQL query: {e}"
|
155
|
+
raise ValueError(msg) from e
|
156
|
+
|
157
|
+
return DataFrame(output_dict)
|
@@ -0,0 +1,92 @@
|
|
1
|
+
import json
|
2
|
+
from json.decoder import JSONDecodeError
|
3
|
+
|
4
|
+
from google.auth.exceptions import RefreshError
|
5
|
+
from google.oauth2.credentials import Credentials
|
6
|
+
from langchain_google_community import GoogleDriveLoader
|
7
|
+
|
8
|
+
from lfx.custom.custom_component.component import Component
|
9
|
+
from lfx.helpers.data import docs_to_data
|
10
|
+
from lfx.inputs.inputs import MessageTextInput
|
11
|
+
from lfx.io import SecretStrInput
|
12
|
+
from lfx.schema.data import Data
|
13
|
+
from lfx.template.field.base import Output
|
14
|
+
|
15
|
+
|
16
|
+
class GoogleDriveComponent(Component):
|
17
|
+
display_name = "Google Drive Loader"
|
18
|
+
description = "Loads documents from Google Drive using provided credentials."
|
19
|
+
icon = "Google"
|
20
|
+
legacy: bool = True
|
21
|
+
|
22
|
+
inputs = [
|
23
|
+
SecretStrInput(
|
24
|
+
name="json_string",
|
25
|
+
display_name="JSON String of the Service Account Token",
|
26
|
+
info="JSON string containing OAuth 2.0 access token information for service account access",
|
27
|
+
required=True,
|
28
|
+
),
|
29
|
+
MessageTextInput(
|
30
|
+
name="document_id", display_name="Document ID", info="Single Google Drive document ID", required=True
|
31
|
+
),
|
32
|
+
]
|
33
|
+
|
34
|
+
outputs = [
|
35
|
+
Output(display_name="Loaded Documents", name="docs", method="load_documents"),
|
36
|
+
]
|
37
|
+
|
38
|
+
def load_documents(self) -> Data:
|
39
|
+
class CustomGoogleDriveLoader(GoogleDriveLoader):
|
40
|
+
creds: Credentials | None = None
|
41
|
+
"""Credentials object to be passed directly."""
|
42
|
+
|
43
|
+
def _load_credentials(self):
|
44
|
+
"""Load credentials from the provided creds attribute or fallback to the original method."""
|
45
|
+
if self.creds:
|
46
|
+
return self.creds
|
47
|
+
msg = "No credentials provided."
|
48
|
+
raise ValueError(msg)
|
49
|
+
|
50
|
+
class Config:
|
51
|
+
arbitrary_types_allowed = True
|
52
|
+
|
53
|
+
json_string = self.json_string
|
54
|
+
|
55
|
+
document_ids = [self.document_id]
|
56
|
+
if len(document_ids) != 1:
|
57
|
+
msg = "Expected a single document ID"
|
58
|
+
raise ValueError(msg)
|
59
|
+
|
60
|
+
# TODO: Add validation to check if the document ID is valid
|
61
|
+
|
62
|
+
# Load the token information from the JSON string
|
63
|
+
try:
|
64
|
+
token_info = json.loads(json_string)
|
65
|
+
except JSONDecodeError as e:
|
66
|
+
msg = "Invalid JSON string"
|
67
|
+
raise ValueError(msg) from e
|
68
|
+
|
69
|
+
# Initialize the custom loader with the provided credentials and document IDs
|
70
|
+
loader = CustomGoogleDriveLoader(
|
71
|
+
creds=Credentials.from_authorized_user_info(token_info), document_ids=document_ids
|
72
|
+
)
|
73
|
+
|
74
|
+
# Load the documents
|
75
|
+
try:
|
76
|
+
docs = loader.load()
|
77
|
+
# catch google.auth.exceptions.RefreshError
|
78
|
+
except RefreshError as e:
|
79
|
+
msg = "Authentication error: Unable to refresh authentication token. Please try to reauthenticate."
|
80
|
+
raise ValueError(msg) from e
|
81
|
+
except Exception as e:
|
82
|
+
msg = f"Error loading documents: {e}"
|
83
|
+
raise ValueError(msg) from e
|
84
|
+
|
85
|
+
if len(docs) != 1:
|
86
|
+
msg = "Expected a single document to be loaded."
|
87
|
+
raise ValueError(msg)
|
88
|
+
|
89
|
+
data = docs_to_data(docs)
|
90
|
+
# Return the loaded documents
|
91
|
+
self.status = data
|
92
|
+
return Data(data={"text": data})
|
@@ -0,0 +1,152 @@
|
|
1
|
+
import json
|
2
|
+
|
3
|
+
from google.oauth2.credentials import Credentials
|
4
|
+
from googleapiclient.discovery import build
|
5
|
+
|
6
|
+
from lfx.custom.custom_component.component import Component
|
7
|
+
from lfx.inputs.inputs import DropdownInput, MessageTextInput
|
8
|
+
from lfx.io import SecretStrInput
|
9
|
+
from lfx.schema.data import Data
|
10
|
+
from lfx.template.field.base import Output
|
11
|
+
|
12
|
+
|
13
|
+
class GoogleDriveSearchComponent(Component):
|
14
|
+
display_name = "Google Drive Search"
|
15
|
+
description = "Searches Google Drive files using provided credentials and query parameters."
|
16
|
+
icon = "Google"
|
17
|
+
legacy: bool = True
|
18
|
+
|
19
|
+
inputs = [
|
20
|
+
SecretStrInput(
|
21
|
+
name="token_string",
|
22
|
+
display_name="Token String",
|
23
|
+
info="JSON string containing OAuth 2.0 access token information for service account access",
|
24
|
+
required=True,
|
25
|
+
),
|
26
|
+
DropdownInput(
|
27
|
+
name="query_item",
|
28
|
+
display_name="Query Item",
|
29
|
+
options=[
|
30
|
+
"name",
|
31
|
+
"fullText",
|
32
|
+
"mimeType",
|
33
|
+
"modifiedTime",
|
34
|
+
"viewedByMeTime",
|
35
|
+
"trashed",
|
36
|
+
"starred",
|
37
|
+
"parents",
|
38
|
+
"owners",
|
39
|
+
"writers",
|
40
|
+
"readers",
|
41
|
+
"sharedWithMe",
|
42
|
+
"createdTime",
|
43
|
+
"properties",
|
44
|
+
"appProperties",
|
45
|
+
"visibility",
|
46
|
+
"shortcutDetails.targetId",
|
47
|
+
],
|
48
|
+
info="The field to query.",
|
49
|
+
required=True,
|
50
|
+
),
|
51
|
+
DropdownInput(
|
52
|
+
name="valid_operator",
|
53
|
+
display_name="Valid Operator",
|
54
|
+
options=["contains", "=", "!=", "<=", "<", ">", ">=", "in", "has"],
|
55
|
+
info="Operator to use in the query.",
|
56
|
+
required=True,
|
57
|
+
),
|
58
|
+
MessageTextInput(
|
59
|
+
name="search_term",
|
60
|
+
display_name="Search Term",
|
61
|
+
info="The value to search for in the specified query item.",
|
62
|
+
required=True,
|
63
|
+
),
|
64
|
+
MessageTextInput(
|
65
|
+
name="query_string",
|
66
|
+
display_name="Query String",
|
67
|
+
info="The query string used for searching. You can edit this manually.",
|
68
|
+
value="", # This will be updated with the generated query string
|
69
|
+
),
|
70
|
+
]
|
71
|
+
|
72
|
+
outputs = [
|
73
|
+
Output(display_name="Document URLs", name="doc_urls", method="search_doc_urls"),
|
74
|
+
Output(display_name="Document IDs", name="doc_ids", method="search_doc_ids"),
|
75
|
+
Output(display_name="Document Titles", name="doc_titles", method="search_doc_titles"),
|
76
|
+
Output(display_name="Data", name="Data", method="search_data"),
|
77
|
+
]
|
78
|
+
|
79
|
+
def generate_query_string(self) -> str:
|
80
|
+
query_item = self.query_item
|
81
|
+
valid_operator = self.valid_operator
|
82
|
+
search_term = self.search_term
|
83
|
+
|
84
|
+
# Construct the query string
|
85
|
+
query = f"{query_item} {valid_operator} '{search_term}'"
|
86
|
+
|
87
|
+
# Update the editable query string input with the generated query
|
88
|
+
self.query_string = query
|
89
|
+
|
90
|
+
return query
|
91
|
+
|
92
|
+
def on_inputs_changed(self) -> None:
|
93
|
+
# Automatically regenerate the query string when inputs change
|
94
|
+
self.generate_query_string()
|
95
|
+
|
96
|
+
def generate_file_url(self, file_id: str, mime_type: str) -> str:
|
97
|
+
"""Generates the appropriate Google Drive URL for a file based on its MIME type."""
|
98
|
+
return {
|
99
|
+
"application/vnd.google-apps.document": f"https://docs.google.com/document/d/{file_id}/edit",
|
100
|
+
"application/vnd.google-apps.spreadsheet": f"https://docs.google.com/spreadsheets/d/{file_id}/edit",
|
101
|
+
"application/vnd.google-apps.presentation": f"https://docs.google.com/presentation/d/{file_id}/edit",
|
102
|
+
"application/vnd.google-apps.drawing": f"https://docs.google.com/drawings/d/{file_id}/edit",
|
103
|
+
"application/pdf": f"https://drive.google.com/file/d/{file_id}/view?usp=drivesdk",
|
104
|
+
}.get(mime_type, f"https://drive.google.com/file/d/{file_id}/view?usp=drivesdk")
|
105
|
+
|
106
|
+
def search_files(self) -> dict:
|
107
|
+
# Load the token information from the JSON string
|
108
|
+
token_info = json.loads(self.token_string)
|
109
|
+
creds = Credentials.from_authorized_user_info(token_info)
|
110
|
+
|
111
|
+
# Use the query string from the input (which might have been edited by the user)
|
112
|
+
query = self.query_string or self.generate_query_string()
|
113
|
+
|
114
|
+
# Initialize the Google Drive API service
|
115
|
+
service = build("drive", "v3", credentials=creds)
|
116
|
+
|
117
|
+
# Perform the search
|
118
|
+
results = service.files().list(q=query, pageSize=5, fields="nextPageToken, files(id, name, mimeType)").execute()
|
119
|
+
items = results.get("files", [])
|
120
|
+
|
121
|
+
doc_urls = []
|
122
|
+
doc_ids = []
|
123
|
+
doc_titles_urls = []
|
124
|
+
doc_titles = []
|
125
|
+
|
126
|
+
if items:
|
127
|
+
for item in items:
|
128
|
+
# Directly use the file ID, title, and MIME type to generate the URL
|
129
|
+
file_id = item["id"]
|
130
|
+
file_title = item["name"]
|
131
|
+
mime_type = item["mimeType"]
|
132
|
+
file_url = self.generate_file_url(file_id, mime_type)
|
133
|
+
|
134
|
+
# Store the URL, ID, and title+URL in their respective lists
|
135
|
+
doc_urls.append(file_url)
|
136
|
+
doc_ids.append(file_id)
|
137
|
+
doc_titles.append(file_title)
|
138
|
+
doc_titles_urls.append({"title": file_title, "url": file_url})
|
139
|
+
|
140
|
+
return {"doc_urls": doc_urls, "doc_ids": doc_ids, "doc_titles_urls": doc_titles_urls, "doc_titles": doc_titles}
|
141
|
+
|
142
|
+
def search_doc_ids(self) -> list[str]:
|
143
|
+
return self.search_files()["doc_ids"]
|
144
|
+
|
145
|
+
def search_doc_urls(self) -> list[str]:
|
146
|
+
return self.search_files()["doc_urls"]
|
147
|
+
|
148
|
+
def search_doc_titles(self) -> list[str]:
|
149
|
+
return self.search_files()["doc_titles"]
|
150
|
+
|
151
|
+
def search_data(self) -> Data:
|
152
|
+
return Data(data={"text": self.search_files()["doc_titles_urls"]})
|
@@ -0,0 +1,147 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
import requests
|
4
|
+
from pydantic.v1 import SecretStr
|
5
|
+
|
6
|
+
from lfx.base.models.google_generative_ai_constants import GOOGLE_GENERATIVE_AI_MODELS
|
7
|
+
from lfx.base.models.model import LCModelComponent
|
8
|
+
from lfx.field_typing import LanguageModel
|
9
|
+
from lfx.field_typing.range_spec import RangeSpec
|
10
|
+
from lfx.inputs.inputs import BoolInput, DropdownInput, FloatInput, IntInput, SecretStrInput, SliderInput
|
11
|
+
from lfx.log.logger import logger
|
12
|
+
from lfx.schema.dotdict import dotdict
|
13
|
+
|
14
|
+
|
15
|
+
class GoogleGenerativeAIComponent(LCModelComponent):
|
16
|
+
display_name = "Google Generative AI"
|
17
|
+
description = "Generate text using Google Generative AI."
|
18
|
+
icon = "GoogleGenerativeAI"
|
19
|
+
name = "GoogleGenerativeAIModel"
|
20
|
+
|
21
|
+
inputs = [
|
22
|
+
*LCModelComponent.get_base_inputs(),
|
23
|
+
IntInput(
|
24
|
+
name="max_output_tokens", display_name="Max Output Tokens", info="The maximum number of tokens to generate."
|
25
|
+
),
|
26
|
+
DropdownInput(
|
27
|
+
name="model_name",
|
28
|
+
display_name="Model",
|
29
|
+
info="The name of the model to use.",
|
30
|
+
options=GOOGLE_GENERATIVE_AI_MODELS,
|
31
|
+
value="gemini-1.5-pro",
|
32
|
+
refresh_button=True,
|
33
|
+
combobox=True,
|
34
|
+
),
|
35
|
+
SecretStrInput(
|
36
|
+
name="api_key",
|
37
|
+
display_name="Google API Key",
|
38
|
+
info="The Google API Key to use for the Google Generative AI.",
|
39
|
+
required=True,
|
40
|
+
real_time_refresh=True,
|
41
|
+
),
|
42
|
+
FloatInput(
|
43
|
+
name="top_p",
|
44
|
+
display_name="Top P",
|
45
|
+
info="The maximum cumulative probability of tokens to consider when sampling.",
|
46
|
+
advanced=True,
|
47
|
+
),
|
48
|
+
SliderInput(
|
49
|
+
name="temperature",
|
50
|
+
display_name="Temperature",
|
51
|
+
value=0.1,
|
52
|
+
range_spec=RangeSpec(min=0, max=1, step=0.01),
|
53
|
+
info="Controls randomness. Lower values are more deterministic, higher values are more creative.",
|
54
|
+
),
|
55
|
+
IntInput(
|
56
|
+
name="n",
|
57
|
+
display_name="N",
|
58
|
+
info="Number of chat completions to generate for each prompt. "
|
59
|
+
"Note that the API may not return the full n completions if duplicates are generated.",
|
60
|
+
advanced=True,
|
61
|
+
),
|
62
|
+
IntInput(
|
63
|
+
name="top_k",
|
64
|
+
display_name="Top K",
|
65
|
+
info="Decode using top-k sampling: consider the set of top_k most probable tokens. Must be positive.",
|
66
|
+
advanced=True,
|
67
|
+
),
|
68
|
+
BoolInput(
|
69
|
+
name="tool_model_enabled",
|
70
|
+
display_name="Tool Model Enabled",
|
71
|
+
info="Whether to use the tool model.",
|
72
|
+
value=False,
|
73
|
+
),
|
74
|
+
]
|
75
|
+
|
76
|
+
def build_model(self) -> LanguageModel: # type: ignore[type-var]
|
77
|
+
try:
|
78
|
+
from langchain_google_genai import ChatGoogleGenerativeAI
|
79
|
+
except ImportError as e:
|
80
|
+
msg = "The 'langchain_google_genai' package is required to use the Google Generative AI model."
|
81
|
+
raise ImportError(msg) from e
|
82
|
+
|
83
|
+
google_api_key = self.api_key
|
84
|
+
model = self.model_name
|
85
|
+
max_output_tokens = self.max_output_tokens
|
86
|
+
temperature = self.temperature
|
87
|
+
top_k = self.top_k
|
88
|
+
top_p = self.top_p
|
89
|
+
n = self.n
|
90
|
+
|
91
|
+
return ChatGoogleGenerativeAI(
|
92
|
+
model=model,
|
93
|
+
max_output_tokens=max_output_tokens or None,
|
94
|
+
temperature=temperature,
|
95
|
+
top_k=top_k or None,
|
96
|
+
top_p=top_p or None,
|
97
|
+
n=n or 1,
|
98
|
+
google_api_key=SecretStr(google_api_key).get_secret_value(),
|
99
|
+
)
|
100
|
+
|
101
|
+
def get_models(self, *, tool_model_enabled: bool | None = None) -> list[str]:
|
102
|
+
try:
|
103
|
+
import google.generativeai as genai
|
104
|
+
|
105
|
+
genai.configure(api_key=self.api_key)
|
106
|
+
model_ids = [
|
107
|
+
model.name.replace("models/", "")
|
108
|
+
for model in genai.list_models()
|
109
|
+
if "generateContent" in model.supported_generation_methods
|
110
|
+
]
|
111
|
+
model_ids.sort(reverse=True)
|
112
|
+
except (ImportError, ValueError) as e:
|
113
|
+
logger.exception(f"Error getting model names: {e}")
|
114
|
+
model_ids = GOOGLE_GENERATIVE_AI_MODELS
|
115
|
+
if tool_model_enabled:
|
116
|
+
try:
|
117
|
+
from langchain_google_genai.chat_models import ChatGoogleGenerativeAI
|
118
|
+
except ImportError as e:
|
119
|
+
msg = "langchain_google_genai is not installed."
|
120
|
+
raise ImportError(msg) from e
|
121
|
+
for model in model_ids:
|
122
|
+
model_with_tool = ChatGoogleGenerativeAI(
|
123
|
+
model=self.model_name,
|
124
|
+
google_api_key=self.api_key,
|
125
|
+
)
|
126
|
+
if not self.supports_tool_calling(model_with_tool):
|
127
|
+
model_ids.remove(model)
|
128
|
+
return model_ids
|
129
|
+
|
130
|
+
def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None):
|
131
|
+
if field_name in {"base_url", "model_name", "tool_model_enabled", "api_key"} and field_value:
|
132
|
+
try:
|
133
|
+
if len(self.api_key) == 0:
|
134
|
+
ids = GOOGLE_GENERATIVE_AI_MODELS
|
135
|
+
else:
|
136
|
+
try:
|
137
|
+
ids = self.get_models(tool_model_enabled=self.tool_model_enabled)
|
138
|
+
except (ImportError, ValueError, requests.exceptions.RequestException) as e:
|
139
|
+
logger.exception(f"Error getting model names: {e}")
|
140
|
+
ids = GOOGLE_GENERATIVE_AI_MODELS
|
141
|
+
build_config.setdefault("model_name", {})
|
142
|
+
build_config["model_name"]["options"] = ids
|
143
|
+
build_config["model_name"].setdefault("value", ids[0])
|
144
|
+
except Exception as e:
|
145
|
+
msg = f"Error getting model names: {e}"
|
146
|
+
raise ValueError(msg) from e
|
147
|
+
return build_config
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# from lfx.field_typing import Data
|
2
|
+
|
3
|
+
# TODO: remove ignore once the google package is published with types
|
4
|
+
from google.ai.generativelanguage_v1beta.types import BatchEmbedContentsRequest
|
5
|
+
from langchain_core.embeddings import Embeddings
|
6
|
+
from langchain_google_genai import GoogleGenerativeAIEmbeddings
|
7
|
+
from langchain_google_genai._common import GoogleGenerativeAIError
|
8
|
+
|
9
|
+
from lfx.custom.custom_component.component import Component
|
10
|
+
from lfx.io import MessageTextInput, Output, SecretStrInput
|
11
|
+
|
12
|
+
MIN_DIMENSION_ERROR = "Output dimensionality must be at least 1"
|
13
|
+
MAX_DIMENSION_ERROR = (
|
14
|
+
"Output dimensionality cannot exceed 768. Google's embedding models only support dimensions up to 768."
|
15
|
+
)
|
16
|
+
MAX_DIMENSION = 768
|
17
|
+
MIN_DIMENSION = 1
|
18
|
+
|
19
|
+
|
20
|
+
class GoogleGenerativeAIEmbeddingsComponent(Component):
|
21
|
+
display_name = "Google Generative AI Embeddings"
|
22
|
+
description = (
|
23
|
+
"Connect to Google's generative AI embeddings service using the GoogleGenerativeAIEmbeddings class, "
|
24
|
+
"found in the langchain-google-genai package."
|
25
|
+
)
|
26
|
+
documentation: str = "https://python.langchain.com/v0.2/docs/integrations/text_embedding/google_generative_ai/"
|
27
|
+
icon = "GoogleGenerativeAI"
|
28
|
+
name = "Google Generative AI Embeddings"
|
29
|
+
|
30
|
+
inputs = [
|
31
|
+
SecretStrInput(name="api_key", display_name="API Key", required=True),
|
32
|
+
MessageTextInput(name="model_name", display_name="Model Name", value="models/text-embedding-004"),
|
33
|
+
]
|
34
|
+
|
35
|
+
outputs = [
|
36
|
+
Output(display_name="Embeddings", name="embeddings", method="build_embeddings"),
|
37
|
+
]
|
38
|
+
|
39
|
+
def build_embeddings(self) -> Embeddings:
|
40
|
+
if not self.api_key:
|
41
|
+
msg = "API Key is required"
|
42
|
+
raise ValueError(msg)
|
43
|
+
|
44
|
+
class HotaGoogleGenerativeAIEmbeddings(GoogleGenerativeAIEmbeddings):
|
45
|
+
def __init__(self, *args, **kwargs) -> None:
|
46
|
+
super(GoogleGenerativeAIEmbeddings, self).__init__(*args, **kwargs)
|
47
|
+
|
48
|
+
def embed_documents(
|
49
|
+
self,
|
50
|
+
texts: list[str],
|
51
|
+
*,
|
52
|
+
batch_size: int = 100,
|
53
|
+
task_type: str | None = None,
|
54
|
+
titles: list[str] | None = None,
|
55
|
+
output_dimensionality: int | None = 768,
|
56
|
+
) -> list[list[float]]:
|
57
|
+
"""Embed a list of strings.
|
58
|
+
|
59
|
+
Google Generative AI currently sets a max batch size of 100 strings.
|
60
|
+
|
61
|
+
Args:
|
62
|
+
texts: List[str] The list of strings to embed.
|
63
|
+
batch_size: [int] The batch size of embeddings to send to the model
|
64
|
+
task_type: task_type (https://ai.google.dev/api/rest/v1/TaskType)
|
65
|
+
titles: An optional list of titles for texts provided.
|
66
|
+
Only applicable when TaskType is RETRIEVAL_DOCUMENT.
|
67
|
+
output_dimensionality: Optional reduced dimension for the output embedding.
|
68
|
+
https://ai.google.dev/api/rest/v1/models/batchEmbedContents#EmbedContentRequest
|
69
|
+
Returns:
|
70
|
+
List of embeddings, one for each text.
|
71
|
+
"""
|
72
|
+
if output_dimensionality is not None and output_dimensionality < MIN_DIMENSION:
|
73
|
+
raise ValueError(MIN_DIMENSION_ERROR)
|
74
|
+
if output_dimensionality is not None and output_dimensionality > MAX_DIMENSION:
|
75
|
+
error_msg = MAX_DIMENSION_ERROR.format(output_dimensionality)
|
76
|
+
raise ValueError(error_msg)
|
77
|
+
|
78
|
+
embeddings: list[list[float]] = []
|
79
|
+
batch_start_index = 0
|
80
|
+
for batch in GoogleGenerativeAIEmbeddings._prepare_batches(texts, batch_size):
|
81
|
+
if titles:
|
82
|
+
titles_batch = titles[batch_start_index : batch_start_index + len(batch)]
|
83
|
+
batch_start_index += len(batch)
|
84
|
+
else:
|
85
|
+
titles_batch = [None] * len(batch) # type: ignore[list-item]
|
86
|
+
|
87
|
+
requests = [
|
88
|
+
self._prepare_request(
|
89
|
+
text=text,
|
90
|
+
task_type=task_type,
|
91
|
+
title=title,
|
92
|
+
output_dimensionality=output_dimensionality,
|
93
|
+
)
|
94
|
+
for text, title in zip(batch, titles_batch, strict=True)
|
95
|
+
]
|
96
|
+
|
97
|
+
try:
|
98
|
+
result = self.client.batch_embed_contents(
|
99
|
+
BatchEmbedContentsRequest(requests=requests, model=self.model)
|
100
|
+
)
|
101
|
+
except Exception as e:
|
102
|
+
msg = f"Error embedding content: {e}"
|
103
|
+
raise GoogleGenerativeAIError(msg) from e
|
104
|
+
embeddings.extend([list(e.values) for e in result.embeddings])
|
105
|
+
return embeddings
|
106
|
+
|
107
|
+
def embed_query(
|
108
|
+
self,
|
109
|
+
text: str,
|
110
|
+
task_type: str | None = None,
|
111
|
+
title: str | None = None,
|
112
|
+
output_dimensionality: int | None = 768,
|
113
|
+
) -> list[float]:
|
114
|
+
"""Embed a text.
|
115
|
+
|
116
|
+
Args:
|
117
|
+
text: The text to embed.
|
118
|
+
task_type: task_type (https://ai.google.dev/api/rest/v1/TaskType)
|
119
|
+
title: An optional title for the text.
|
120
|
+
Only applicable when TaskType is RETRIEVAL_DOCUMENT.
|
121
|
+
output_dimensionality: Optional reduced dimension for the output embedding.
|
122
|
+
https://ai.google.dev/api/rest/v1/models/batchEmbedContents#EmbedContentRequest
|
123
|
+
|
124
|
+
Returns:
|
125
|
+
Embedding for the text.
|
126
|
+
"""
|
127
|
+
if output_dimensionality is not None and output_dimensionality < MIN_DIMENSION:
|
128
|
+
raise ValueError(MIN_DIMENSION_ERROR)
|
129
|
+
if output_dimensionality is not None and output_dimensionality > MAX_DIMENSION:
|
130
|
+
error_msg = MAX_DIMENSION_ERROR.format(output_dimensionality)
|
131
|
+
raise ValueError(error_msg)
|
132
|
+
|
133
|
+
task_type = task_type or "RETRIEVAL_QUERY"
|
134
|
+
return self.embed_documents(
|
135
|
+
[text],
|
136
|
+
task_type=task_type,
|
137
|
+
titles=[title] if title else None,
|
138
|
+
output_dimensionality=output_dimensionality,
|
139
|
+
)[0]
|
140
|
+
|
141
|
+
return HotaGoogleGenerativeAIEmbeddings(model=self.model_name, google_api_key=self.api_key)
|