lfx-nightly 0.2.0.dev25__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.
Potentially problematic release.
This version of lfx-nightly might be problematic. Click here for more details.
- lfx/__init__.py +0 -0
- lfx/__main__.py +25 -0
- lfx/_assets/component_index.json +1 -0
- lfx/base/__init__.py +0 -0
- lfx/base/agents/__init__.py +0 -0
- lfx/base/agents/agent.py +375 -0
- lfx/base/agents/altk_base_agent.py +380 -0
- lfx/base/agents/altk_tool_wrappers.py +565 -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 +430 -0
- lfx/base/agents/utils.py +237 -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 +2584 -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 +810 -0
- lfx/base/data/docling_utils.py +338 -0
- lfx/base/data/storage_utils.py +192 -0
- lfx/base/data/utils.py +362 -0
- lfx/base/datastax/__init__.py +5 -0
- lfx/base/datastax/astradb_base.py +896 -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/embeddings_class.py +113 -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 +21 -0
- lfx/base/io/text.py +22 -0
- lfx/base/knowledge_bases/__init__.py +3 -0
- lfx/base/knowledge_bases/knowledge_base_utils.py +137 -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 +1659 -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 +51 -0
- lfx/base/models/aws_constants.py +151 -0
- lfx/base/models/chat_result.py +76 -0
- lfx/base/models/cometapi_constants.py +54 -0
- lfx/base/models/google_generative_ai_constants.py +70 -0
- lfx/base/models/google_generative_ai_model.py +38 -0
- lfx/base/models/groq_constants.py +150 -0
- lfx/base/models/groq_model_discovery.py +265 -0
- lfx/base/models/model.py +375 -0
- lfx/base/models/model_input_constants.py +378 -0
- lfx/base/models/model_metadata.py +41 -0
- lfx/base/models/model_utils.py +108 -0
- lfx/base/models/novita_constants.py +35 -0
- lfx/base/models/ollama_constants.py +52 -0
- lfx/base/models/openai_constants.py +129 -0
- lfx/base/models/sambanova_constants.py +18 -0
- lfx/base/models/watsonx_constants.py +36 -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 +698 -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 +327 -0
- lfx/cli/common.py +650 -0
- lfx/cli/run.py +506 -0
- lfx/cli/script_loader.py +289 -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 +428 -0
- lfx/components/_importing.py +42 -0
- lfx/components/agentql/__init__.py +3 -0
- lfx/components/agentql/agentql_api.py +151 -0
- lfx/components/aiml/__init__.py +37 -0
- lfx/components/aiml/aiml.py +115 -0
- lfx/components/aiml/aiml_embeddings.py +37 -0
- lfx/components/altk/__init__.py +34 -0
- lfx/components/altk/altk_agent.py +193 -0
- lfx/components/amazon/__init__.py +36 -0
- lfx/components/amazon/amazon_bedrock_converse.py +195 -0
- lfx/components/amazon/amazon_bedrock_embedding.py +109 -0
- lfx/components/amazon/amazon_bedrock_model.py +130 -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 +169 -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 +169 -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/cometapi/__init__.py +32 -0
- lfx/components/cometapi/cometapi.py +166 -0
- lfx/components/composio/__init__.py +222 -0
- lfx/components/composio/agentql_composio.py +11 -0
- lfx/components/composio/agiled_composio.py +11 -0
- lfx/components/composio/airtable_composio.py +11 -0
- lfx/components/composio/apollo_composio.py +11 -0
- lfx/components/composio/asana_composio.py +11 -0
- lfx/components/composio/attio_composio.py +11 -0
- lfx/components/composio/bitbucket_composio.py +11 -0
- lfx/components/composio/bolna_composio.py +11 -0
- lfx/components/composio/brightdata_composio.py +11 -0
- lfx/components/composio/calendly_composio.py +11 -0
- lfx/components/composio/canva_composio.py +11 -0
- lfx/components/composio/canvas_composio.py +11 -0
- lfx/components/composio/coda_composio.py +11 -0
- lfx/components/composio/composio_api.py +278 -0
- lfx/components/composio/contentful_composio.py +11 -0
- lfx/components/composio/digicert_composio.py +11 -0
- lfx/components/composio/discord_composio.py +11 -0
- lfx/components/composio/dropbox_compnent.py +11 -0
- lfx/components/composio/elevenlabs_composio.py +11 -0
- lfx/components/composio/exa_composio.py +11 -0
- lfx/components/composio/figma_composio.py +11 -0
- lfx/components/composio/finage_composio.py +11 -0
- lfx/components/composio/firecrawl_composio.py +11 -0
- lfx/components/composio/fireflies_composio.py +11 -0
- lfx/components/composio/fixer_composio.py +11 -0
- lfx/components/composio/flexisign_composio.py +11 -0
- lfx/components/composio/freshdesk_composio.py +11 -0
- lfx/components/composio/github_composio.py +11 -0
- lfx/components/composio/gmail_composio.py +38 -0
- lfx/components/composio/googlebigquery_composio.py +11 -0
- lfx/components/composio/googlecalendar_composio.py +11 -0
- lfx/components/composio/googleclassroom_composio.py +11 -0
- lfx/components/composio/googledocs_composio.py +11 -0
- lfx/components/composio/googlemeet_composio.py +11 -0
- lfx/components/composio/googlesheets_composio.py +11 -0
- lfx/components/composio/googletasks_composio.py +8 -0
- lfx/components/composio/heygen_composio.py +11 -0
- lfx/components/composio/instagram_composio.py +11 -0
- lfx/components/composio/jira_composio.py +11 -0
- lfx/components/composio/jotform_composio.py +11 -0
- lfx/components/composio/klaviyo_composio.py +11 -0
- lfx/components/composio/linear_composio.py +11 -0
- lfx/components/composio/listennotes_composio.py +11 -0
- lfx/components/composio/mem0_composio.py +11 -0
- lfx/components/composio/miro_composio.py +11 -0
- lfx/components/composio/missive_composio.py +11 -0
- lfx/components/composio/notion_composio.py +11 -0
- lfx/components/composio/onedrive_composio.py +11 -0
- lfx/components/composio/outlook_composio.py +11 -0
- lfx/components/composio/pandadoc_composio.py +11 -0
- lfx/components/composio/peopledatalabs_composio.py +11 -0
- lfx/components/composio/perplexityai_composio.py +11 -0
- lfx/components/composio/reddit_composio.py +11 -0
- lfx/components/composio/serpapi_composio.py +11 -0
- lfx/components/composio/slack_composio.py +11 -0
- lfx/components/composio/slackbot_composio.py +11 -0
- lfx/components/composio/snowflake_composio.py +11 -0
- lfx/components/composio/supabase_composio.py +11 -0
- lfx/components/composio/tavily_composio.py +11 -0
- lfx/components/composio/timelinesai_composio.py +11 -0
- lfx/components/composio/todoist_composio.py +11 -0
- lfx/components/composio/wrike_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 +108 -0
- lfx/components/crewai/hierarchical_crew.py +47 -0
- lfx/components/crewai/hierarchical_task.py +45 -0
- lfx/components/crewai/sequential_crew.py +53 -0
- lfx/components/crewai/sequential_task.py +74 -0
- lfx/components/crewai/sequential_task_agent.py +144 -0
- lfx/components/cuga/__init__.py +34 -0
- lfx/components/cuga/cuga_agent.py +730 -0
- lfx/components/custom_component/__init__.py +34 -0
- lfx/components/custom_component/custom_component.py +31 -0
- lfx/components/data/__init__.py +114 -0
- lfx/components/data_source/__init__.py +58 -0
- lfx/components/data_source/api_request.py +577 -0
- lfx/components/data_source/csv_to_data.py +101 -0
- lfx/components/data_source/json_to_data.py +106 -0
- lfx/components/data_source/mock_data.py +398 -0
- lfx/components/data_source/news_search.py +166 -0
- lfx/components/data_source/rss.py +71 -0
- lfx/components/data_source/sql_executor.py +101 -0
- lfx/components/data_source/url.py +311 -0
- lfx/components/data_source/web_search.py +326 -0
- lfx/components/datastax/__init__.py +76 -0
- lfx/components/datastax/astradb_assistant_manager.py +307 -0
- lfx/components/datastax/astradb_chatmemory.py +40 -0
- lfx/components/datastax/astradb_cql.py +288 -0
- lfx/components/datastax/astradb_graph.py +217 -0
- lfx/components/datastax/astradb_tool.py +378 -0
- lfx/components/datastax/astradb_vectorize.py +122 -0
- lfx/components/datastax/astradb_vectorstore.py +449 -0
- lfx/components/datastax/create_assistant.py +59 -0
- lfx/components/datastax/create_thread.py +33 -0
- lfx/components/datastax/dotenv.py +36 -0
- lfx/components/datastax/get_assistant.py +38 -0
- lfx/components/datastax/getenvvar.py +31 -0
- lfx/components/datastax/graph_rag.py +141 -0
- lfx/components/datastax/hcd.py +315 -0
- lfx/components/datastax/list_assistants.py +26 -0
- lfx/components/datastax/run.py +90 -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 +238 -0
- lfx/components/docling/docling_remote.py +195 -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 +789 -0
- lfx/components/elastic/opensearch_multimodal.py +1575 -0
- lfx/components/embeddings/__init__.py +37 -0
- lfx/components/embeddings/similarity.py +77 -0
- lfx/components/embeddings/text_embedder.py +65 -0
- lfx/components/exa/__init__.py +3 -0
- lfx/components/exa/exa_search.py +68 -0
- lfx/components/files_and_knowledge/__init__.py +47 -0
- lfx/components/files_and_knowledge/directory.py +113 -0
- lfx/components/files_and_knowledge/file.py +841 -0
- lfx/components/files_and_knowledge/ingestion.py +694 -0
- lfx/components/files_and_knowledge/retrieval.py +264 -0
- lfx/components/files_and_knowledge/save_file.py +746 -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/flow_controls/__init__.py +58 -0
- lfx/components/flow_controls/conditional_router.py +208 -0
- lfx/components/flow_controls/data_conditional_router.py +126 -0
- lfx/components/flow_controls/flow_tool.py +111 -0
- lfx/components/flow_controls/listen.py +29 -0
- lfx/components/flow_controls/loop.py +163 -0
- lfx/components/flow_controls/notify.py +88 -0
- lfx/components/flow_controls/pass_message.py +36 -0
- lfx/components/flow_controls/run_flow.py +108 -0
- lfx/components/flow_controls/sub_flow.py +115 -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 +193 -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 +144 -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 +143 -0
- lfx/components/helpers/__init__.py +154 -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 +199 -0
- lfx/components/huggingface/huggingface_inference_api.py +106 -0
- lfx/components/ibm/__init__.py +34 -0
- lfx/components/ibm/watsonx.py +207 -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 +40 -0
- lfx/components/input_output/chat.py +109 -0
- lfx/components/input_output/chat_output.py +184 -0
- lfx/components/input_output/text.py +27 -0
- lfx/components/input_output/text_output.py +29 -0
- lfx/components/input_output/webhook.py +56 -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/knowledge_bases/__init__.py +89 -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 +175 -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 +100 -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/llm_operations/__init__.py +46 -0
- lfx/components/llm_operations/batch_run.py +205 -0
- lfx/components/llm_operations/lambda_filter.py +218 -0
- lfx/components/llm_operations/llm_conditional_router.py +421 -0
- lfx/components/llm_operations/llm_selector.py +499 -0
- lfx/components/llm_operations/structured_output.py +244 -0
- lfx/components/lmstudio/__init__.py +34 -0
- lfx/components/lmstudio/lmstudioembeddings.py +89 -0
- lfx/components/lmstudio/lmstudiomodel.py +133 -0
- lfx/components/logic/__init__.py +181 -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 +147 -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 +89 -0
- lfx/components/models_and_agents/__init__.py +49 -0
- lfx/components/models_and_agents/agent.py +644 -0
- lfx/components/models_and_agents/embedding_model.py +423 -0
- lfx/components/models_and_agents/language_model.py +398 -0
- lfx/components/models_and_agents/mcp_component.py +594 -0
- lfx/components/models_and_agents/memory.py +268 -0
- lfx/components/models_and_agents/prompt.py +67 -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 +151 -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 +548 -0
- lfx/components/ollama/ollama_embeddings.py +103 -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 +104 -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 +72 -0
- lfx/components/processing/alter_metadata.py +109 -0
- lfx/components/processing/combine_text.py +40 -0
- lfx/components/processing/converter.py +248 -0
- lfx/components/processing/create_data.py +111 -0
- lfx/components/processing/create_list.py +40 -0
- lfx/components/processing/data_operations.py +528 -0
- lfx/components/processing/data_to_dataframe.py +71 -0
- lfx/components/processing/dataframe_operations.py +313 -0
- lfx/components/processing/dataframe_to_toolset.py +259 -0
- lfx/components/processing/dynamic_create_data.py +357 -0
- lfx/components/processing/extract_key.py +54 -0
- lfx/components/processing/filter_data.py +43 -0
- lfx/components/processing/filter_data_values.py +89 -0
- lfx/components/processing/json_cleaner.py +104 -0
- lfx/components/processing/merge_data.py +91 -0
- lfx/components/processing/message_to_data.py +37 -0
- lfx/components/processing/output_parser.py +46 -0
- lfx/components/processing/parse_data.py +71 -0
- lfx/components/processing/parse_dataframe.py +69 -0
- lfx/components/processing/parse_json_data.py +91 -0
- lfx/components/processing/parser.py +148 -0
- lfx/components/processing/regex.py +83 -0
- lfx/components/processing/select_data.py +49 -0
- lfx/components/processing/split_text.py +141 -0
- lfx/components/processing/store_message.py +91 -0
- lfx/components/processing/update_data.py +161 -0
- lfx/components/prototypes/__init__.py +35 -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 +66 -0
- lfx/components/tools/calculator.py +109 -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 +328 -0
- lfx/components/tools/python_repl.py +98 -0
- lfx/components/tools/search_api.py +88 -0
- lfx/components/tools/searxng.py +145 -0
- lfx/components/tools/serp_api.py +120 -0
- lfx/components/tools/tavily_search_tool.py +345 -0
- lfx/components/tools/wikidata_api.py +103 -0
- lfx/components/tools/wikipedia_api.py +50 -0
- lfx/components/tools/yahoo_finance.py +130 -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 +301 -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 +191 -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/utilities/__init__.py +43 -0
- lfx/components/utilities/calculator_core.py +89 -0
- lfx/components/utilities/current_date.py +42 -0
- lfx/components/utilities/id_generator.py +42 -0
- lfx/components/utilities/python_repl_core.py +98 -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 +34 -0
- lfx/components/vectorstores/local_db.py +270 -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/vlmrun/__init__.py +34 -0
- lfx/components/vlmrun/vlmrun_transcription.py +224 -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 +206 -0
- lfx/components/zep/__init__.py +3 -0
- lfx/components/zep/zep.py +45 -0
- lfx/constants.py +6 -0
- lfx/custom/__init__.py +7 -0
- lfx/custom/attributes.py +87 -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 +1890 -0
- lfx/custom/custom_component/component_with_cache.py +8 -0
- lfx/custom/custom_component/custom_component.py +650 -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 +523 -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 +216 -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 +300 -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 +2298 -0
- lfx/graph/graph/constants.py +63 -0
- lfx/graph/graph/runnable_vertices_manager.py +133 -0
- lfx/graph/graph/schema.py +53 -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 +250 -0
- lfx/graph/utils.py +206 -0
- lfx/graph/vertex/__init__.py +0 -0
- lfx/graph/vertex/base.py +826 -0
- lfx/graph/vertex/constants.py +0 -0
- lfx/graph/vertex/exceptions.py +4 -0
- lfx/graph/vertex/param_handler.py +316 -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 +141 -0
- lfx/helpers/base_model.py +71 -0
- lfx/helpers/custom.py +13 -0
- lfx/helpers/data.py +167 -0
- lfx/helpers/flow.py +308 -0
- lfx/inputs/__init__.py +68 -0
- lfx/inputs/constants.py +2 -0
- lfx/inputs/input_mixin.py +352 -0
- lfx/inputs/inputs.py +718 -0
- lfx/inputs/validators.py +19 -0
- lfx/interface/__init__.py +6 -0
- lfx/interface/components.py +897 -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 +317 -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 +295 -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 +411 -0
- lfx/logging/__init__.py +11 -0
- lfx/logging/logger.py +24 -0
- lfx/memory/__init__.py +70 -0
- lfx/memory/stubs.py +302 -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/cross_module.py +80 -0
- lfx/schema/data.py +309 -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 +184 -0
- lfx/schema/json_schema.py +186 -0
- lfx/schema/log.py +62 -0
- lfx/schema/message.py +493 -0
- lfx/schema/openai_responses_schemas.py +74 -0
- lfx/schema/properties.py +41 -0
- lfx/schema/schema.py +180 -0
- lfx/schema/serialize.py +13 -0
- lfx/schema/table.py +142 -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 +26 -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/database/__init__.py +5 -0
- lfx/services/database/service.py +25 -0
- lfx/services/deps.py +194 -0
- lfx/services/factory.py +19 -0
- lfx/services/initialize.py +19 -0
- lfx/services/interfaces.py +103 -0
- lfx/services/manager.py +185 -0
- lfx/services/mcp_composer/__init__.py +6 -0
- lfx/services/mcp_composer/factory.py +16 -0
- lfx/services/mcp_composer/service.py +1441 -0
- lfx/services/schema.py +21 -0
- lfx/services/session.py +87 -0
- lfx/services/settings/__init__.py +3 -0
- lfx/services/settings/auth.py +133 -0
- lfx/services/settings/base.py +668 -0
- lfx/services/settings/constants.py +43 -0
- lfx/services/settings/factory.py +23 -0
- lfx/services/settings/feature_flags.py +11 -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 +185 -0
- lfx/services/storage/service.py +177 -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 +260 -0
- lfx/template/field/prompt.py +15 -0
- lfx/template/frontend_node/__init__.py +6 -0
- lfx/template/frontend_node/base.py +214 -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 +233 -0
- lfx/utils/data_structure.py +212 -0
- lfx/utils/exceptions.py +22 -0
- lfx/utils/helpers.py +34 -0
- lfx/utils/image.py +79 -0
- lfx/utils/langflow_utils.py +52 -0
- lfx/utils/lazy_load.py +15 -0
- lfx/utils/request_utils.py +18 -0
- lfx/utils/schemas.py +139 -0
- lfx/utils/ssrf_protection.py +384 -0
- lfx/utils/util.py +626 -0
- lfx/utils/util_strings.py +56 -0
- lfx/utils/validate_cloud.py +26 -0
- lfx/utils/version.py +24 -0
- lfx_nightly-0.2.0.dev25.dist-info/METADATA +312 -0
- lfx_nightly-0.2.0.dev25.dist-info/RECORD +769 -0
- lfx_nightly-0.2.0.dev25.dist-info/WHEEL +4 -0
- lfx_nightly-0.2.0.dev25.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from lfx.custom.custom_component.component import Component
|
|
2
|
+
from lfx.io import DataInput, Output
|
|
3
|
+
from lfx.schema.data import Data
|
|
4
|
+
from lfx.schema.dataframe import DataFrame
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class DataToDataFrameComponent(Component):
|
|
8
|
+
display_name = "Data → DataFrame"
|
|
9
|
+
description = (
|
|
10
|
+
"Converts one or multiple Data objects into a DataFrame. "
|
|
11
|
+
"Each Data object corresponds to one row. Fields from `.data` become columns, "
|
|
12
|
+
"and the `.text` (if present) is placed in a 'text' column."
|
|
13
|
+
)
|
|
14
|
+
icon = "table"
|
|
15
|
+
name = "DataToDataFrame"
|
|
16
|
+
legacy = True
|
|
17
|
+
replacement = ["processing.DataOperations", "processing.TypeConverterComponent"]
|
|
18
|
+
|
|
19
|
+
inputs = [
|
|
20
|
+
DataInput(
|
|
21
|
+
name="data_list",
|
|
22
|
+
display_name="Data or Data List",
|
|
23
|
+
info="One or multiple Data objects to transform into a DataFrame.",
|
|
24
|
+
is_list=True,
|
|
25
|
+
),
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
outputs = [
|
|
29
|
+
Output(
|
|
30
|
+
display_name="DataFrame",
|
|
31
|
+
name="dataframe",
|
|
32
|
+
method="build_dataframe",
|
|
33
|
+
info="A DataFrame built from each Data object's fields plus a 'text' column.",
|
|
34
|
+
),
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
def build_dataframe(self) -> DataFrame:
|
|
38
|
+
"""Builds a DataFrame from Data objects by combining their fields.
|
|
39
|
+
|
|
40
|
+
For each Data object:
|
|
41
|
+
- Merge item.data (dictionary) as columns
|
|
42
|
+
- If item.text is present, add 'text' column
|
|
43
|
+
|
|
44
|
+
Returns a DataFrame with one row per Data object.
|
|
45
|
+
"""
|
|
46
|
+
data_input = self.data_list
|
|
47
|
+
|
|
48
|
+
# If user passed a single Data, it might come in as a single object rather than a list
|
|
49
|
+
if not isinstance(data_input, list):
|
|
50
|
+
data_input = [data_input]
|
|
51
|
+
|
|
52
|
+
rows = []
|
|
53
|
+
for item in data_input:
|
|
54
|
+
if not isinstance(item, Data):
|
|
55
|
+
msg = f"Expected Data objects, got {type(item)} instead."
|
|
56
|
+
raise TypeError(msg)
|
|
57
|
+
|
|
58
|
+
# Start with a copy of item.data or an empty dict
|
|
59
|
+
row_dict = dict(item.data) if item.data else {}
|
|
60
|
+
|
|
61
|
+
# If the Data object has text, store it under 'text' col
|
|
62
|
+
text_val = item.get_text()
|
|
63
|
+
if text_val:
|
|
64
|
+
row_dict["text"] = text_val
|
|
65
|
+
|
|
66
|
+
rows.append(row_dict)
|
|
67
|
+
|
|
68
|
+
# Build a DataFrame from these row dictionaries
|
|
69
|
+
df_result = DataFrame(rows)
|
|
70
|
+
self.status = df_result # store in self.status for logs
|
|
71
|
+
return df_result
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
|
|
3
|
+
from lfx.custom.custom_component.component import Component
|
|
4
|
+
from lfx.inputs import SortableListInput
|
|
5
|
+
from lfx.io import BoolInput, DataFrameInput, DropdownInput, IntInput, MessageTextInput, Output, StrInput
|
|
6
|
+
from lfx.log.logger import logger
|
|
7
|
+
from lfx.schema.dataframe import DataFrame
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class DataFrameOperationsComponent(Component):
|
|
11
|
+
display_name = "DataFrame Operations"
|
|
12
|
+
description = "Perform various operations on a DataFrame."
|
|
13
|
+
documentation: str = "https://docs.langflow.org/dataframe-operations"
|
|
14
|
+
icon = "table"
|
|
15
|
+
name = "DataFrameOperations"
|
|
16
|
+
|
|
17
|
+
OPERATION_CHOICES = [
|
|
18
|
+
"Add Column",
|
|
19
|
+
"Drop Column",
|
|
20
|
+
"Filter",
|
|
21
|
+
"Head",
|
|
22
|
+
"Rename Column",
|
|
23
|
+
"Replace Value",
|
|
24
|
+
"Select Columns",
|
|
25
|
+
"Sort",
|
|
26
|
+
"Tail",
|
|
27
|
+
"Drop Duplicates",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
inputs = [
|
|
31
|
+
DataFrameInput(
|
|
32
|
+
name="df",
|
|
33
|
+
display_name="DataFrame",
|
|
34
|
+
info="The input DataFrame to operate on.",
|
|
35
|
+
required=True,
|
|
36
|
+
),
|
|
37
|
+
SortableListInput(
|
|
38
|
+
name="operation",
|
|
39
|
+
display_name="Operation",
|
|
40
|
+
placeholder="Select Operation",
|
|
41
|
+
info="Select the DataFrame operation to perform.",
|
|
42
|
+
options=[
|
|
43
|
+
{"name": "Add Column", "icon": "plus"},
|
|
44
|
+
{"name": "Drop Column", "icon": "minus"},
|
|
45
|
+
{"name": "Filter", "icon": "filter"},
|
|
46
|
+
{"name": "Head", "icon": "arrow-up"},
|
|
47
|
+
{"name": "Rename Column", "icon": "pencil"},
|
|
48
|
+
{"name": "Replace Value", "icon": "replace"},
|
|
49
|
+
{"name": "Select Columns", "icon": "columns"},
|
|
50
|
+
{"name": "Sort", "icon": "arrow-up-down"},
|
|
51
|
+
{"name": "Tail", "icon": "arrow-down"},
|
|
52
|
+
{"name": "Drop Duplicates", "icon": "copy-x"},
|
|
53
|
+
],
|
|
54
|
+
real_time_refresh=True,
|
|
55
|
+
limit=1,
|
|
56
|
+
),
|
|
57
|
+
StrInput(
|
|
58
|
+
name="column_name",
|
|
59
|
+
display_name="Column Name",
|
|
60
|
+
info="The column name to use for the operation.",
|
|
61
|
+
dynamic=True,
|
|
62
|
+
show=False,
|
|
63
|
+
),
|
|
64
|
+
MessageTextInput(
|
|
65
|
+
name="filter_value",
|
|
66
|
+
display_name="Filter Value",
|
|
67
|
+
info="The value to filter rows by.",
|
|
68
|
+
dynamic=True,
|
|
69
|
+
show=False,
|
|
70
|
+
),
|
|
71
|
+
DropdownInput(
|
|
72
|
+
name="filter_operator",
|
|
73
|
+
display_name="Filter Operator",
|
|
74
|
+
options=[
|
|
75
|
+
"equals",
|
|
76
|
+
"not equals",
|
|
77
|
+
"contains",
|
|
78
|
+
"not contains",
|
|
79
|
+
"starts with",
|
|
80
|
+
"ends with",
|
|
81
|
+
"greater than",
|
|
82
|
+
"less than",
|
|
83
|
+
],
|
|
84
|
+
value="equals",
|
|
85
|
+
info="The operator to apply for filtering rows.",
|
|
86
|
+
advanced=False,
|
|
87
|
+
dynamic=True,
|
|
88
|
+
show=False,
|
|
89
|
+
),
|
|
90
|
+
BoolInput(
|
|
91
|
+
name="ascending",
|
|
92
|
+
display_name="Sort Ascending",
|
|
93
|
+
info="Whether to sort in ascending order.",
|
|
94
|
+
dynamic=True,
|
|
95
|
+
show=False,
|
|
96
|
+
value=True,
|
|
97
|
+
),
|
|
98
|
+
StrInput(
|
|
99
|
+
name="new_column_name",
|
|
100
|
+
display_name="New Column Name",
|
|
101
|
+
info="The new column name when renaming or adding a column.",
|
|
102
|
+
dynamic=True,
|
|
103
|
+
show=False,
|
|
104
|
+
),
|
|
105
|
+
MessageTextInput(
|
|
106
|
+
name="new_column_value",
|
|
107
|
+
display_name="New Column Value",
|
|
108
|
+
info="The value to populate the new column with.",
|
|
109
|
+
dynamic=True,
|
|
110
|
+
show=False,
|
|
111
|
+
),
|
|
112
|
+
StrInput(
|
|
113
|
+
name="columns_to_select",
|
|
114
|
+
display_name="Columns to Select",
|
|
115
|
+
dynamic=True,
|
|
116
|
+
is_list=True,
|
|
117
|
+
show=False,
|
|
118
|
+
),
|
|
119
|
+
IntInput(
|
|
120
|
+
name="num_rows",
|
|
121
|
+
display_name="Number of Rows",
|
|
122
|
+
info="Number of rows to return (for head/tail).",
|
|
123
|
+
dynamic=True,
|
|
124
|
+
show=False,
|
|
125
|
+
value=5,
|
|
126
|
+
),
|
|
127
|
+
MessageTextInput(
|
|
128
|
+
name="replace_value",
|
|
129
|
+
display_name="Value to Replace",
|
|
130
|
+
info="The value to replace in the column.",
|
|
131
|
+
dynamic=True,
|
|
132
|
+
show=False,
|
|
133
|
+
),
|
|
134
|
+
MessageTextInput(
|
|
135
|
+
name="replacement_value",
|
|
136
|
+
display_name="Replacement Value",
|
|
137
|
+
info="The value to replace with.",
|
|
138
|
+
dynamic=True,
|
|
139
|
+
show=False,
|
|
140
|
+
),
|
|
141
|
+
]
|
|
142
|
+
|
|
143
|
+
outputs = [
|
|
144
|
+
Output(
|
|
145
|
+
display_name="DataFrame",
|
|
146
|
+
name="output",
|
|
147
|
+
method="perform_operation",
|
|
148
|
+
info="The resulting DataFrame after the operation.",
|
|
149
|
+
)
|
|
150
|
+
]
|
|
151
|
+
|
|
152
|
+
def update_build_config(self, build_config, field_value, field_name=None):
|
|
153
|
+
dynamic_fields = [
|
|
154
|
+
"column_name",
|
|
155
|
+
"filter_value",
|
|
156
|
+
"filter_operator",
|
|
157
|
+
"ascending",
|
|
158
|
+
"new_column_name",
|
|
159
|
+
"new_column_value",
|
|
160
|
+
"columns_to_select",
|
|
161
|
+
"num_rows",
|
|
162
|
+
"replace_value",
|
|
163
|
+
"replacement_value",
|
|
164
|
+
]
|
|
165
|
+
for field in dynamic_fields:
|
|
166
|
+
build_config[field]["show"] = False
|
|
167
|
+
|
|
168
|
+
if field_name == "operation":
|
|
169
|
+
# Handle SortableListInput format
|
|
170
|
+
if isinstance(field_value, list):
|
|
171
|
+
operation_name = field_value[0].get("name", "") if field_value else ""
|
|
172
|
+
else:
|
|
173
|
+
operation_name = field_value or ""
|
|
174
|
+
|
|
175
|
+
# If no operation selected, all dynamic fields stay hidden (already set to False above)
|
|
176
|
+
if not operation_name:
|
|
177
|
+
return build_config
|
|
178
|
+
|
|
179
|
+
if operation_name == "Filter":
|
|
180
|
+
build_config["column_name"]["show"] = True
|
|
181
|
+
build_config["filter_value"]["show"] = True
|
|
182
|
+
build_config["filter_operator"]["show"] = True
|
|
183
|
+
elif operation_name == "Sort":
|
|
184
|
+
build_config["column_name"]["show"] = True
|
|
185
|
+
build_config["ascending"]["show"] = True
|
|
186
|
+
elif operation_name == "Drop Column":
|
|
187
|
+
build_config["column_name"]["show"] = True
|
|
188
|
+
elif operation_name == "Rename Column":
|
|
189
|
+
build_config["column_name"]["show"] = True
|
|
190
|
+
build_config["new_column_name"]["show"] = True
|
|
191
|
+
elif operation_name == "Add Column":
|
|
192
|
+
build_config["new_column_name"]["show"] = True
|
|
193
|
+
build_config["new_column_value"]["show"] = True
|
|
194
|
+
elif operation_name == "Select Columns":
|
|
195
|
+
build_config["columns_to_select"]["show"] = True
|
|
196
|
+
elif operation_name in {"Head", "Tail"}:
|
|
197
|
+
build_config["num_rows"]["show"] = True
|
|
198
|
+
elif operation_name == "Replace Value":
|
|
199
|
+
build_config["column_name"]["show"] = True
|
|
200
|
+
build_config["replace_value"]["show"] = True
|
|
201
|
+
build_config["replacement_value"]["show"] = True
|
|
202
|
+
elif operation_name == "Drop Duplicates":
|
|
203
|
+
build_config["column_name"]["show"] = True
|
|
204
|
+
|
|
205
|
+
return build_config
|
|
206
|
+
|
|
207
|
+
def perform_operation(self) -> DataFrame:
|
|
208
|
+
df_copy = self.df.copy()
|
|
209
|
+
|
|
210
|
+
# Handle SortableListInput format for operation
|
|
211
|
+
operation_input = getattr(self, "operation", [])
|
|
212
|
+
if isinstance(operation_input, list) and len(operation_input) > 0:
|
|
213
|
+
op = operation_input[0].get("name", "")
|
|
214
|
+
else:
|
|
215
|
+
op = ""
|
|
216
|
+
|
|
217
|
+
# If no operation selected, return original DataFrame
|
|
218
|
+
if not op:
|
|
219
|
+
return df_copy
|
|
220
|
+
|
|
221
|
+
if op == "Filter":
|
|
222
|
+
return self.filter_rows_by_value(df_copy)
|
|
223
|
+
if op == "Sort":
|
|
224
|
+
return self.sort_by_column(df_copy)
|
|
225
|
+
if op == "Drop Column":
|
|
226
|
+
return self.drop_column(df_copy)
|
|
227
|
+
if op == "Rename Column":
|
|
228
|
+
return self.rename_column(df_copy)
|
|
229
|
+
if op == "Add Column":
|
|
230
|
+
return self.add_column(df_copy)
|
|
231
|
+
if op == "Select Columns":
|
|
232
|
+
return self.select_columns(df_copy)
|
|
233
|
+
if op == "Head":
|
|
234
|
+
return self.head(df_copy)
|
|
235
|
+
if op == "Tail":
|
|
236
|
+
return self.tail(df_copy)
|
|
237
|
+
if op == "Replace Value":
|
|
238
|
+
return self.replace_values(df_copy)
|
|
239
|
+
if op == "Drop Duplicates":
|
|
240
|
+
return self.drop_duplicates(df_copy)
|
|
241
|
+
msg = f"Unsupported operation: {op}"
|
|
242
|
+
logger.error(msg)
|
|
243
|
+
raise ValueError(msg)
|
|
244
|
+
|
|
245
|
+
def filter_rows_by_value(self, df: DataFrame) -> DataFrame:
|
|
246
|
+
column = df[self.column_name]
|
|
247
|
+
filter_value = self.filter_value
|
|
248
|
+
|
|
249
|
+
# Handle regular DropdownInput format (just a string value)
|
|
250
|
+
operator = getattr(self, "filter_operator", "equals") # Default to equals for backward compatibility
|
|
251
|
+
|
|
252
|
+
if operator == "equals":
|
|
253
|
+
mask = column == filter_value
|
|
254
|
+
elif operator == "not equals":
|
|
255
|
+
mask = column != filter_value
|
|
256
|
+
elif operator == "contains":
|
|
257
|
+
mask = column.astype(str).str.contains(str(filter_value), na=False)
|
|
258
|
+
elif operator == "not contains":
|
|
259
|
+
mask = ~column.astype(str).str.contains(str(filter_value), na=False)
|
|
260
|
+
elif operator == "starts with":
|
|
261
|
+
mask = column.astype(str).str.startswith(str(filter_value), na=False)
|
|
262
|
+
elif operator == "ends with":
|
|
263
|
+
mask = column.astype(str).str.endswith(str(filter_value), na=False)
|
|
264
|
+
elif operator == "greater than":
|
|
265
|
+
try:
|
|
266
|
+
# Try to convert filter_value to numeric for comparison
|
|
267
|
+
numeric_value = pd.to_numeric(filter_value)
|
|
268
|
+
mask = column > numeric_value
|
|
269
|
+
except (ValueError, TypeError):
|
|
270
|
+
# If conversion fails, compare as strings
|
|
271
|
+
mask = column.astype(str) > str(filter_value)
|
|
272
|
+
elif operator == "less than":
|
|
273
|
+
try:
|
|
274
|
+
# Try to convert filter_value to numeric for comparison
|
|
275
|
+
numeric_value = pd.to_numeric(filter_value)
|
|
276
|
+
mask = column < numeric_value
|
|
277
|
+
except (ValueError, TypeError):
|
|
278
|
+
# If conversion fails, compare as strings
|
|
279
|
+
mask = column.astype(str) < str(filter_value)
|
|
280
|
+
else:
|
|
281
|
+
mask = column == filter_value # Fallback to equals
|
|
282
|
+
|
|
283
|
+
return DataFrame(df[mask])
|
|
284
|
+
|
|
285
|
+
def sort_by_column(self, df: DataFrame) -> DataFrame:
|
|
286
|
+
return DataFrame(df.sort_values(by=self.column_name, ascending=self.ascending))
|
|
287
|
+
|
|
288
|
+
def drop_column(self, df: DataFrame) -> DataFrame:
|
|
289
|
+
return DataFrame(df.drop(columns=[self.column_name]))
|
|
290
|
+
|
|
291
|
+
def rename_column(self, df: DataFrame) -> DataFrame:
|
|
292
|
+
return DataFrame(df.rename(columns={self.column_name: self.new_column_name}))
|
|
293
|
+
|
|
294
|
+
def add_column(self, df: DataFrame) -> DataFrame:
|
|
295
|
+
df[self.new_column_name] = [self.new_column_value] * len(df)
|
|
296
|
+
return DataFrame(df)
|
|
297
|
+
|
|
298
|
+
def select_columns(self, df: DataFrame) -> DataFrame:
|
|
299
|
+
columns = [col.strip() for col in self.columns_to_select]
|
|
300
|
+
return DataFrame(df[columns])
|
|
301
|
+
|
|
302
|
+
def head(self, df: DataFrame) -> DataFrame:
|
|
303
|
+
return DataFrame(df.head(self.num_rows))
|
|
304
|
+
|
|
305
|
+
def tail(self, df: DataFrame) -> DataFrame:
|
|
306
|
+
return DataFrame(df.tail(self.num_rows))
|
|
307
|
+
|
|
308
|
+
def replace_values(self, df: DataFrame) -> DataFrame:
|
|
309
|
+
df[self.column_name] = df[self.column_name].replace(self.replace_value, self.replacement_value)
|
|
310
|
+
return DataFrame(df)
|
|
311
|
+
|
|
312
|
+
def drop_duplicates(self, df: DataFrame) -> DataFrame:
|
|
313
|
+
return DataFrame(df.drop_duplicates(subset=self.column_name))
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"""DataFrame to Toolset Component.
|
|
2
|
+
|
|
3
|
+
This component converts each row of a DataFrame into a callable tool/action within a toolset.
|
|
4
|
+
Each row becomes a tool where the action name comes from one column and the content/response
|
|
5
|
+
comes from another column.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import re
|
|
11
|
+
from typing import TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
from langchain.tools import StructuredTool
|
|
14
|
+
from pydantic import BaseModel, create_model
|
|
15
|
+
|
|
16
|
+
from lfx.base.langchain_utilities.model import LCToolComponent
|
|
17
|
+
from lfx.field_typing.constants import Tool
|
|
18
|
+
from lfx.io import HandleInput, Output, StrInput
|
|
19
|
+
from lfx.schema.data import Data
|
|
20
|
+
from lfx.schema.dataframe import DataFrame
|
|
21
|
+
from lfx.schema.message import Message
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from lfx.field_typing.constants import Tool
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class DataFrameToToolsetComponent(LCToolComponent):
|
|
28
|
+
"""Component that converts DataFrame rows into a toolset with multiple callable actions."""
|
|
29
|
+
|
|
30
|
+
display_name = "DataFrame to Toolset"
|
|
31
|
+
description = "Convert each row of a DataFrame into a callable tool/action in a toolset."
|
|
32
|
+
icon = "wrench"
|
|
33
|
+
name = "DataFrameToToolset"
|
|
34
|
+
|
|
35
|
+
inputs = [
|
|
36
|
+
HandleInput(
|
|
37
|
+
name="dataframe",
|
|
38
|
+
display_name="DataFrame",
|
|
39
|
+
input_types=["DataFrame"],
|
|
40
|
+
info="DataFrame where each row will become a tool/action",
|
|
41
|
+
required=True,
|
|
42
|
+
),
|
|
43
|
+
StrInput(
|
|
44
|
+
name="tool_name_column",
|
|
45
|
+
display_name="Tool Name Column",
|
|
46
|
+
info="Column with tool names",
|
|
47
|
+
required=True,
|
|
48
|
+
),
|
|
49
|
+
StrInput(
|
|
50
|
+
name="tool_output_column",
|
|
51
|
+
display_name="Tool Output Column",
|
|
52
|
+
info="Column with tool outputs/responses",
|
|
53
|
+
required=True,
|
|
54
|
+
),
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
outputs = [
|
|
58
|
+
Output(display_name="Tools", name="tools", method="build_tools"),
|
|
59
|
+
Output(display_name="Message", name="message", method="get_message"),
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
def __init__(self, **kwargs):
|
|
63
|
+
super().__init__(**kwargs)
|
|
64
|
+
self._tools_cache: list[Tool] = []
|
|
65
|
+
self._action_data: dict[str, dict[str, str]] = {}
|
|
66
|
+
|
|
67
|
+
def _sanitize_tool_name(self, name: str) -> str:
|
|
68
|
+
"""Sanitize tool name to match required format '^[a-zA-Z0-9_-]+$'."""
|
|
69
|
+
# Replace any non-alphanumeric characters (except _ and -) with underscores
|
|
70
|
+
sanitized = re.sub(r"[^a-zA-Z0-9_-]", "_", str(name))
|
|
71
|
+
# Ensure it starts with a letter or underscore
|
|
72
|
+
if sanitized and not sanitized[0].isalpha() and sanitized[0] != "_":
|
|
73
|
+
sanitized = f"tool_{sanitized}"
|
|
74
|
+
return sanitized or "unnamed_tool"
|
|
75
|
+
|
|
76
|
+
def _prepare_action_data(self) -> None:
|
|
77
|
+
"""Prepare action data from DataFrame."""
|
|
78
|
+
# Check if dataframe exists and is valid
|
|
79
|
+
if not hasattr(self, "dataframe") or self.dataframe is None:
|
|
80
|
+
self._action_data = {}
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
if not isinstance(self.dataframe, DataFrame):
|
|
84
|
+
self._action_data = {}
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
if not hasattr(self.dataframe, "columns"):
|
|
88
|
+
self._action_data = {}
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
# Check if column names are provided
|
|
92
|
+
if not self.tool_name_column or not self.tool_output_column:
|
|
93
|
+
self._action_data = {}
|
|
94
|
+
return
|
|
95
|
+
|
|
96
|
+
if self.tool_name_column not in self.dataframe.columns:
|
|
97
|
+
msg = (
|
|
98
|
+
f"Tool name column '{self.tool_name_column}' not found in DataFrame columns: "
|
|
99
|
+
f"{list(self.dataframe.columns)}"
|
|
100
|
+
)
|
|
101
|
+
raise ValueError(msg)
|
|
102
|
+
|
|
103
|
+
if self.tool_output_column not in self.dataframe.columns:
|
|
104
|
+
msg = (
|
|
105
|
+
f"Tool output column '{self.tool_output_column}' not found in DataFrame columns: "
|
|
106
|
+
f"{list(self.dataframe.columns)}"
|
|
107
|
+
)
|
|
108
|
+
raise ValueError(msg)
|
|
109
|
+
|
|
110
|
+
# Clear previous data
|
|
111
|
+
self._action_data = {}
|
|
112
|
+
|
|
113
|
+
# Process each row to create action mappings
|
|
114
|
+
for _, row in self.dataframe.iterrows():
|
|
115
|
+
action_name = str(row[self.tool_name_column]).strip()
|
|
116
|
+
content = str(row[self.tool_output_column]).strip()
|
|
117
|
+
|
|
118
|
+
if action_name and content:
|
|
119
|
+
sanitized_name = self._sanitize_tool_name(action_name)
|
|
120
|
+
self._action_data[sanitized_name] = {
|
|
121
|
+
"original_name": action_name,
|
|
122
|
+
"content": content,
|
|
123
|
+
"sanitized_name": sanitized_name,
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
def _create_action_function(self, action_name: str, content: str):
|
|
127
|
+
"""Create a function for a specific action that returns the content."""
|
|
128
|
+
|
|
129
|
+
def action_function(**kwargs) -> str:
|
|
130
|
+
# You could extend this to use kwargs to modify the content
|
|
131
|
+
# For now, just return the stored content
|
|
132
|
+
self.log(kwargs) # TODO: Coming soon: implement arguments to modify content
|
|
133
|
+
return content
|
|
134
|
+
|
|
135
|
+
action_function.__name__ = f"execute_{action_name}"
|
|
136
|
+
action_function.__doc__ = f"Execute {action_name} action and return the associated content."
|
|
137
|
+
return action_function
|
|
138
|
+
|
|
139
|
+
def build_tools(self) -> list[Tool]:
|
|
140
|
+
"""Build the toolset from DataFrame data."""
|
|
141
|
+
# Handle case where inputs are not ready
|
|
142
|
+
if not hasattr(self, "dataframe") or self.dataframe is None:
|
|
143
|
+
return []
|
|
144
|
+
|
|
145
|
+
self._prepare_action_data()
|
|
146
|
+
|
|
147
|
+
if not self._action_data:
|
|
148
|
+
return []
|
|
149
|
+
|
|
150
|
+
tools_description_preview_length = 100
|
|
151
|
+
tools_description_content_length = 200
|
|
152
|
+
|
|
153
|
+
tools = []
|
|
154
|
+
|
|
155
|
+
for sanitized_name, action_info in self._action_data.items():
|
|
156
|
+
original_name = action_info["original_name"]
|
|
157
|
+
content = action_info["content"]
|
|
158
|
+
|
|
159
|
+
# Create a simple schema for this tool (no parameters needed)
|
|
160
|
+
# But we could extend this to accept parameters if needed
|
|
161
|
+
tool_schema = create_model(
|
|
162
|
+
f"{sanitized_name}Schema",
|
|
163
|
+
__base__=BaseModel,
|
|
164
|
+
# Add parameters here if you want the tools to accept inputs
|
|
165
|
+
# For now, keeping it simple with no parameters
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
# Create the tool function
|
|
169
|
+
tool_function = self._create_action_function(sanitized_name, content)
|
|
170
|
+
|
|
171
|
+
# Create the StructuredTool
|
|
172
|
+
tool = StructuredTool(
|
|
173
|
+
name=sanitized_name,
|
|
174
|
+
description=(
|
|
175
|
+
f"Execute {original_name} action. Returns: "
|
|
176
|
+
f"{content[:tools_description_preview_length]}"
|
|
177
|
+
f"{'...' if len(content) > tools_description_preview_length else ''}"
|
|
178
|
+
),
|
|
179
|
+
func=tool_function,
|
|
180
|
+
args_schema=tool_schema,
|
|
181
|
+
handle_tool_error=True,
|
|
182
|
+
tags=[sanitized_name],
|
|
183
|
+
metadata={
|
|
184
|
+
"display_name": original_name,
|
|
185
|
+
"display_description": f"Action: {original_name}",
|
|
186
|
+
"original_name": original_name,
|
|
187
|
+
"content_preview": content[:tools_description_content_length],
|
|
188
|
+
},
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
tools.append(tool)
|
|
192
|
+
|
|
193
|
+
self._tools_cache = tools
|
|
194
|
+
return tools
|
|
195
|
+
|
|
196
|
+
def build_tool(self) -> Tool:
|
|
197
|
+
"""Build a single tool (for compatibility with LCToolComponent)."""
|
|
198
|
+
tools = self.build_tools()
|
|
199
|
+
if not tools:
|
|
200
|
+
# Return a placeholder tool when no data is available
|
|
201
|
+
def placeholder_function(**kwargs) -> str:
|
|
202
|
+
self.log(kwargs) # TODO: Coming soon: implement arguments to modify content
|
|
203
|
+
return "No tools available. Please connect a DataFrame with appropriate columns."
|
|
204
|
+
|
|
205
|
+
return StructuredTool(
|
|
206
|
+
name="placeholder_tool",
|
|
207
|
+
description="Placeholder tool - waiting for DataFrame input",
|
|
208
|
+
func=placeholder_function,
|
|
209
|
+
args_schema=create_model("PlaceholderSchema", __base__=BaseModel),
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
# Return the first tool, or create a composite tool
|
|
213
|
+
return tools[0]
|
|
214
|
+
|
|
215
|
+
def get_message(self) -> Message:
|
|
216
|
+
"""Get a message describing the created toolset."""
|
|
217
|
+
# Handle case where inputs are not ready
|
|
218
|
+
if not hasattr(self, "dataframe") or self.dataframe is None:
|
|
219
|
+
return Message(text="Waiting for DataFrame input...")
|
|
220
|
+
|
|
221
|
+
self._prepare_action_data()
|
|
222
|
+
|
|
223
|
+
if not self._action_data:
|
|
224
|
+
return Message(text="No tools were created. Please check your DataFrame and column selections.")
|
|
225
|
+
|
|
226
|
+
tool_count = len(self._action_data)
|
|
227
|
+
tool_names = [info["original_name"] for info in self._action_data.values()]
|
|
228
|
+
|
|
229
|
+
message_text = f"Created toolset with {tool_count} tools:\n"
|
|
230
|
+
for i, name in enumerate(tool_names, 1):
|
|
231
|
+
message_text += f"{i}. {name}\n"
|
|
232
|
+
|
|
233
|
+
return Message(text=message_text)
|
|
234
|
+
|
|
235
|
+
def run_model(self) -> list[Data]:
|
|
236
|
+
"""Run the model and return tool information as Data objects."""
|
|
237
|
+
# Handle case where inputs are not ready
|
|
238
|
+
if not hasattr(self, "dataframe") or self.dataframe is None:
|
|
239
|
+
return [Data(data={"status": "Waiting for DataFrame input"})]
|
|
240
|
+
|
|
241
|
+
tools = self.build_tools()
|
|
242
|
+
|
|
243
|
+
if not tools:
|
|
244
|
+
return [Data(data={"status": "No tools created. Check DataFrame and column selections."})]
|
|
245
|
+
|
|
246
|
+
results = []
|
|
247
|
+
for tool in tools:
|
|
248
|
+
tool_data = {
|
|
249
|
+
"tool_name": tool.name,
|
|
250
|
+
"display_name": tool.metadata.get("display_name", tool.name)
|
|
251
|
+
if hasattr(tool, "metadata")
|
|
252
|
+
else tool.name,
|
|
253
|
+
"description": tool.description,
|
|
254
|
+
"original_name": tool.metadata.get("original_name", "") if hasattr(tool, "metadata") else "",
|
|
255
|
+
"content_preview": tool.metadata.get("content_preview", "") if hasattr(tool, "metadata") else "",
|
|
256
|
+
}
|
|
257
|
+
results.append(Data(data=tool_data))
|
|
258
|
+
|
|
259
|
+
return results
|