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,357 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from lfx.custom import Component
|
|
4
|
+
from lfx.io import (
|
|
5
|
+
BoolInput,
|
|
6
|
+
FloatInput,
|
|
7
|
+
HandleInput,
|
|
8
|
+
IntInput,
|
|
9
|
+
MultilineInput,
|
|
10
|
+
Output,
|
|
11
|
+
StrInput,
|
|
12
|
+
TableInput,
|
|
13
|
+
)
|
|
14
|
+
from lfx.schema.data import Data
|
|
15
|
+
from lfx.schema.message import Message
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class DynamicCreateDataComponent(Component):
|
|
19
|
+
display_name: str = "Dynamic Create Data"
|
|
20
|
+
description: str = "Dynamically create a Data with a specified number of fields."
|
|
21
|
+
name: str = "DynamicCreateData"
|
|
22
|
+
MAX_FIELDS = 15 # Define a constant for maximum number of fields
|
|
23
|
+
icon = "ListFilter"
|
|
24
|
+
|
|
25
|
+
def __init__(self, **kwargs):
|
|
26
|
+
super().__init__(**kwargs)
|
|
27
|
+
|
|
28
|
+
inputs = [
|
|
29
|
+
TableInput(
|
|
30
|
+
name="form_fields",
|
|
31
|
+
display_name="Input Configuration",
|
|
32
|
+
info=(
|
|
33
|
+
"Define the dynamic form fields. Each row creates a new input field "
|
|
34
|
+
"that can connect to other components."
|
|
35
|
+
),
|
|
36
|
+
table_schema=[
|
|
37
|
+
{
|
|
38
|
+
"name": "field_name",
|
|
39
|
+
"display_name": "Field Name",
|
|
40
|
+
"type": "str",
|
|
41
|
+
"description": "Name for the field (used as both internal name and display label)",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "field_type",
|
|
45
|
+
"display_name": "Field Type",
|
|
46
|
+
"type": "str",
|
|
47
|
+
"description": "Type of input field to create",
|
|
48
|
+
"options": ["Text", "Data", "Number", "Handle", "Boolean"],
|
|
49
|
+
"value": "Text",
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
value=[],
|
|
53
|
+
real_time_refresh=True,
|
|
54
|
+
),
|
|
55
|
+
BoolInput(
|
|
56
|
+
name="include_metadata",
|
|
57
|
+
display_name="Include Metadata",
|
|
58
|
+
info="Include form configuration metadata in the output.",
|
|
59
|
+
value=False,
|
|
60
|
+
advanced=True,
|
|
61
|
+
),
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
outputs = [
|
|
65
|
+
Output(display_name="Data", name="form_data", method="process_form"),
|
|
66
|
+
Output(display_name="Message", name="message", method="get_message"),
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None) -> dict:
|
|
70
|
+
"""Update build configuration to add dynamic inputs that can connect to other components."""
|
|
71
|
+
if field_name == "form_fields":
|
|
72
|
+
# Clear existing dynamic inputs from build config
|
|
73
|
+
keys_to_remove = [key for key in build_config if key.startswith("dynamic_")]
|
|
74
|
+
for key in keys_to_remove:
|
|
75
|
+
del build_config[key]
|
|
76
|
+
|
|
77
|
+
# Add dynamic inputs based on table configuration
|
|
78
|
+
# Safety check to ensure field_value is not None and is iterable
|
|
79
|
+
if field_value is None:
|
|
80
|
+
field_value = []
|
|
81
|
+
|
|
82
|
+
for i, field_config in enumerate(field_value):
|
|
83
|
+
# Safety check to ensure field_config is not None
|
|
84
|
+
if field_config is None:
|
|
85
|
+
continue
|
|
86
|
+
|
|
87
|
+
field_name = field_config.get("field_name", f"field_{i}")
|
|
88
|
+
display_name = field_name # Use field_name as display_name
|
|
89
|
+
field_type_option = field_config.get("field_type", "Text")
|
|
90
|
+
default_value = "" # All fields have empty default value
|
|
91
|
+
required = False # All fields are optional by default
|
|
92
|
+
help_text = "" # All fields have empty help text
|
|
93
|
+
|
|
94
|
+
# Map field type options to actual field types and input types
|
|
95
|
+
field_type_mapping = {
|
|
96
|
+
"Text": {"field_type": "multiline", "input_types": ["Text", "Message"]},
|
|
97
|
+
"Data": {"field_type": "data", "input_types": ["Data"]},
|
|
98
|
+
"Number": {"field_type": "number", "input_types": ["Text", "Message"]},
|
|
99
|
+
"Handle": {"field_type": "handle", "input_types": ["Text", "Data", "Message"]},
|
|
100
|
+
"Boolean": {"field_type": "boolean", "input_types": None},
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
field_config_mapped = field_type_mapping.get(
|
|
104
|
+
field_type_option, {"field_type": "text", "input_types": []}
|
|
105
|
+
)
|
|
106
|
+
if not isinstance(field_config_mapped, dict):
|
|
107
|
+
field_config_mapped = {"field_type": "text", "input_types": []}
|
|
108
|
+
field_type = field_config_mapped["field_type"]
|
|
109
|
+
input_types_list = field_config_mapped["input_types"]
|
|
110
|
+
|
|
111
|
+
# Create the appropriate input type based on field_type
|
|
112
|
+
dynamic_input_name = f"dynamic_{field_name}"
|
|
113
|
+
|
|
114
|
+
if field_type == "text":
|
|
115
|
+
if input_types_list:
|
|
116
|
+
build_config[dynamic_input_name] = StrInput(
|
|
117
|
+
name=dynamic_input_name,
|
|
118
|
+
display_name=display_name,
|
|
119
|
+
info=f"{help_text} (Can connect to: {', '.join(input_types_list)})",
|
|
120
|
+
value=default_value,
|
|
121
|
+
required=required,
|
|
122
|
+
input_types=input_types_list,
|
|
123
|
+
)
|
|
124
|
+
else:
|
|
125
|
+
build_config[dynamic_input_name] = StrInput(
|
|
126
|
+
name=dynamic_input_name,
|
|
127
|
+
display_name=display_name,
|
|
128
|
+
info=help_text,
|
|
129
|
+
value=default_value,
|
|
130
|
+
required=required,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
elif field_type == "multiline":
|
|
134
|
+
if input_types_list:
|
|
135
|
+
build_config[dynamic_input_name] = MultilineInput(
|
|
136
|
+
name=dynamic_input_name,
|
|
137
|
+
display_name=display_name,
|
|
138
|
+
info=f"{help_text} (Can connect to: {', '.join(input_types_list)})",
|
|
139
|
+
value=default_value,
|
|
140
|
+
required=required,
|
|
141
|
+
input_types=input_types_list,
|
|
142
|
+
)
|
|
143
|
+
else:
|
|
144
|
+
build_config[dynamic_input_name] = MultilineInput(
|
|
145
|
+
name=dynamic_input_name,
|
|
146
|
+
display_name=display_name,
|
|
147
|
+
info=help_text,
|
|
148
|
+
value=default_value,
|
|
149
|
+
required=required,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
elif field_type == "number":
|
|
153
|
+
try:
|
|
154
|
+
default_int = int(default_value) if default_value else 0
|
|
155
|
+
except ValueError:
|
|
156
|
+
default_int = 0
|
|
157
|
+
|
|
158
|
+
if input_types_list:
|
|
159
|
+
build_config[dynamic_input_name] = IntInput(
|
|
160
|
+
name=dynamic_input_name,
|
|
161
|
+
display_name=display_name,
|
|
162
|
+
info=f"{help_text} (Can connect to: {', '.join(input_types_list)})",
|
|
163
|
+
value=default_int,
|
|
164
|
+
required=required,
|
|
165
|
+
input_types=input_types_list,
|
|
166
|
+
)
|
|
167
|
+
else:
|
|
168
|
+
build_config[dynamic_input_name] = IntInput(
|
|
169
|
+
name=dynamic_input_name,
|
|
170
|
+
display_name=display_name,
|
|
171
|
+
info=help_text,
|
|
172
|
+
value=default_int,
|
|
173
|
+
required=required,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
elif field_type == "float":
|
|
177
|
+
try:
|
|
178
|
+
default_float = float(default_value) if default_value else 0.0
|
|
179
|
+
except ValueError:
|
|
180
|
+
default_float = 0.0
|
|
181
|
+
|
|
182
|
+
if input_types_list:
|
|
183
|
+
build_config[dynamic_input_name] = FloatInput(
|
|
184
|
+
name=dynamic_input_name,
|
|
185
|
+
display_name=display_name,
|
|
186
|
+
info=f"{help_text} (Can connect to: {', '.join(input_types_list)})",
|
|
187
|
+
value=default_float,
|
|
188
|
+
required=required,
|
|
189
|
+
input_types=input_types_list,
|
|
190
|
+
)
|
|
191
|
+
else:
|
|
192
|
+
build_config[dynamic_input_name] = FloatInput(
|
|
193
|
+
name=dynamic_input_name,
|
|
194
|
+
display_name=display_name,
|
|
195
|
+
info=help_text,
|
|
196
|
+
value=default_float,
|
|
197
|
+
required=required,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
elif field_type == "boolean":
|
|
201
|
+
default_bool = default_value.lower() in ["true", "1", "yes"] if default_value else False
|
|
202
|
+
|
|
203
|
+
# Boolean fields don't use input_types parameter to avoid errors
|
|
204
|
+
build_config[dynamic_input_name] = BoolInput(
|
|
205
|
+
name=dynamic_input_name,
|
|
206
|
+
display_name=display_name,
|
|
207
|
+
info=help_text,
|
|
208
|
+
value=default_bool,
|
|
209
|
+
input_types=[],
|
|
210
|
+
required=required,
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
elif field_type == "handle":
|
|
214
|
+
# HandleInput for generic data connections
|
|
215
|
+
build_config[dynamic_input_name] = HandleInput(
|
|
216
|
+
name=dynamic_input_name,
|
|
217
|
+
display_name=display_name,
|
|
218
|
+
info=f"{help_text} (Accepts: {', '.join(input_types_list) if input_types_list else 'Any'})",
|
|
219
|
+
input_types=input_types_list if input_types_list else ["Data", "Text", "Message"],
|
|
220
|
+
required=required,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
elif field_type == "data":
|
|
224
|
+
# Specialized for Data type connections
|
|
225
|
+
build_config[dynamic_input_name] = HandleInput(
|
|
226
|
+
name=dynamic_input_name,
|
|
227
|
+
display_name=display_name,
|
|
228
|
+
info=f"{help_text} (Data input)",
|
|
229
|
+
input_types=input_types_list if input_types_list else ["Data"],
|
|
230
|
+
required=required,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
else:
|
|
234
|
+
# Default to text input for unknown types
|
|
235
|
+
build_config[dynamic_input_name] = StrInput(
|
|
236
|
+
name=dynamic_input_name,
|
|
237
|
+
display_name=display_name,
|
|
238
|
+
info=f"{help_text} (Unknown type '{field_type}', defaulting to text)",
|
|
239
|
+
value=default_value,
|
|
240
|
+
required=required,
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
return build_config
|
|
244
|
+
|
|
245
|
+
def get_dynamic_values(self) -> dict[str, Any]:
|
|
246
|
+
"""Extract simple values from all dynamic inputs, handling both manual and connected inputs."""
|
|
247
|
+
dynamic_values = {}
|
|
248
|
+
connection_info = {}
|
|
249
|
+
form_fields = getattr(self, "form_fields", [])
|
|
250
|
+
|
|
251
|
+
for field_config in form_fields:
|
|
252
|
+
# Safety check to ensure field_config is not None
|
|
253
|
+
if field_config is None:
|
|
254
|
+
continue
|
|
255
|
+
|
|
256
|
+
field_name = field_config.get("field_name", "")
|
|
257
|
+
if field_name:
|
|
258
|
+
dynamic_input_name = f"dynamic_{field_name}"
|
|
259
|
+
value = getattr(self, dynamic_input_name, None)
|
|
260
|
+
|
|
261
|
+
# Extract simple values from connections or manual input
|
|
262
|
+
if value is not None:
|
|
263
|
+
try:
|
|
264
|
+
extracted_value = self._extract_simple_value(value)
|
|
265
|
+
dynamic_values[field_name] = extracted_value
|
|
266
|
+
|
|
267
|
+
# Determine connection type for status
|
|
268
|
+
if hasattr(value, "text") and hasattr(value, "timestamp"):
|
|
269
|
+
connection_info[field_name] = "Connected (Message)"
|
|
270
|
+
elif hasattr(value, "data"):
|
|
271
|
+
connection_info[field_name] = "Connected (Data)"
|
|
272
|
+
elif isinstance(value, (str, int, float, bool, list, dict)):
|
|
273
|
+
connection_info[field_name] = "Manual input"
|
|
274
|
+
else:
|
|
275
|
+
connection_info[field_name] = "Connected (Object)"
|
|
276
|
+
|
|
277
|
+
except (AttributeError, TypeError, ValueError):
|
|
278
|
+
# Fallback to string representation if all else fails
|
|
279
|
+
dynamic_values[field_name] = str(value)
|
|
280
|
+
connection_info[field_name] = "Error"
|
|
281
|
+
else:
|
|
282
|
+
# Use empty default value if nothing connected
|
|
283
|
+
dynamic_values[field_name] = ""
|
|
284
|
+
connection_info[field_name] = "Empty default"
|
|
285
|
+
|
|
286
|
+
# Store connection info for status output
|
|
287
|
+
self._connection_info = connection_info
|
|
288
|
+
return dynamic_values
|
|
289
|
+
|
|
290
|
+
def _extract_simple_value(self, value: Any) -> Any:
|
|
291
|
+
"""Extract the simplest, most useful value from any input type."""
|
|
292
|
+
# Handle None
|
|
293
|
+
if value is None:
|
|
294
|
+
return None
|
|
295
|
+
|
|
296
|
+
# Handle simple types directly
|
|
297
|
+
if isinstance(value, (str, int, float, bool)):
|
|
298
|
+
return value
|
|
299
|
+
|
|
300
|
+
# Handle lists and tuples - keep simple
|
|
301
|
+
if isinstance(value, (list, tuple)):
|
|
302
|
+
return [self._extract_simple_value(item) for item in value]
|
|
303
|
+
|
|
304
|
+
# Handle dictionaries - keep simple
|
|
305
|
+
if isinstance(value, dict):
|
|
306
|
+
return {str(k): self._extract_simple_value(v) for k, v in value.items()}
|
|
307
|
+
|
|
308
|
+
# Handle Message objects - extract only the text
|
|
309
|
+
if hasattr(value, "text"):
|
|
310
|
+
return str(value.text) if value.text is not None else ""
|
|
311
|
+
|
|
312
|
+
# Handle Data objects - extract the data content
|
|
313
|
+
if hasattr(value, "data") and value.data is not None:
|
|
314
|
+
return self._extract_simple_value(value.data)
|
|
315
|
+
|
|
316
|
+
# For any other object, convert to string
|
|
317
|
+
return str(value)
|
|
318
|
+
|
|
319
|
+
def process_form(self) -> Data:
|
|
320
|
+
"""Process all dynamic form inputs and return clean data with just field values."""
|
|
321
|
+
# Get all dynamic values (just the key:value pairs)
|
|
322
|
+
dynamic_values = self.get_dynamic_values()
|
|
323
|
+
|
|
324
|
+
# Update status with connection info
|
|
325
|
+
connected_fields = len([v for v in getattr(self, "_connection_info", {}).values() if "Connected" in v])
|
|
326
|
+
total_fields = len(dynamic_values)
|
|
327
|
+
|
|
328
|
+
self.status = f"Form processed successfully. {connected_fields}/{total_fields} fields connected to components."
|
|
329
|
+
|
|
330
|
+
# Return clean Data object with just the field values
|
|
331
|
+
return Data(data=dynamic_values)
|
|
332
|
+
|
|
333
|
+
def get_message(self) -> Message:
|
|
334
|
+
"""Return form data as a formatted text message."""
|
|
335
|
+
# Get all dynamic values
|
|
336
|
+
dynamic_values = self.get_dynamic_values()
|
|
337
|
+
|
|
338
|
+
if not dynamic_values:
|
|
339
|
+
return Message(text="No form data available")
|
|
340
|
+
|
|
341
|
+
# Format as text message
|
|
342
|
+
message_lines = ["📋 Form Data:"]
|
|
343
|
+
message_lines.append("=" * 40)
|
|
344
|
+
|
|
345
|
+
for field_name, value in dynamic_values.items():
|
|
346
|
+
# Use field_name as display_name
|
|
347
|
+
display_name = field_name
|
|
348
|
+
|
|
349
|
+
message_lines.append(f"• {display_name}: {value}")
|
|
350
|
+
|
|
351
|
+
message_lines.append("=" * 40)
|
|
352
|
+
message_lines.append(f"Total fields: {len(dynamic_values)}")
|
|
353
|
+
|
|
354
|
+
message_text = "\n".join(message_lines)
|
|
355
|
+
self.status = f"Message formatted with {len(dynamic_values)} fields"
|
|
356
|
+
|
|
357
|
+
return Message(text=message_text)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from lfx.custom.custom_component.component import Component
|
|
2
|
+
from lfx.io import DataInput, Output, StrInput
|
|
3
|
+
from lfx.schema.data import Data
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ExtractDataKeyComponent(Component):
|
|
7
|
+
display_name = "Extract Key"
|
|
8
|
+
description = (
|
|
9
|
+
"Extract a specific key from a Data object or a list of "
|
|
10
|
+
"Data objects and return the extracted value(s) as Data object(s)."
|
|
11
|
+
)
|
|
12
|
+
icon = "key"
|
|
13
|
+
name = "ExtractaKey"
|
|
14
|
+
legacy = True
|
|
15
|
+
replacement = ["processing.DataOperations"]
|
|
16
|
+
|
|
17
|
+
inputs = [
|
|
18
|
+
DataInput(
|
|
19
|
+
name="data_input",
|
|
20
|
+
display_name="Data Input",
|
|
21
|
+
info="The Data object or list of Data objects to extract the key from.",
|
|
22
|
+
),
|
|
23
|
+
StrInput(
|
|
24
|
+
name="key",
|
|
25
|
+
display_name="Key to Extract",
|
|
26
|
+
info="The key in the Data object(s) to extract.",
|
|
27
|
+
),
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
outputs = [
|
|
31
|
+
Output(display_name="Extracted Data", name="extracted_data", method="extract_key"),
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
def extract_key(self) -> Data | list[Data]:
|
|
35
|
+
key = self.key
|
|
36
|
+
|
|
37
|
+
if isinstance(self.data_input, list):
|
|
38
|
+
result = []
|
|
39
|
+
for item in self.data_input:
|
|
40
|
+
if isinstance(item, Data) and key in item.data:
|
|
41
|
+
extracted_value = item.data[key]
|
|
42
|
+
result.append(Data(data={key: extracted_value}))
|
|
43
|
+
self.status = result
|
|
44
|
+
return result
|
|
45
|
+
if isinstance(self.data_input, Data):
|
|
46
|
+
if key in self.data_input.data:
|
|
47
|
+
extracted_value = self.data_input.data[key]
|
|
48
|
+
result = Data(data={key: extracted_value})
|
|
49
|
+
self.status = result
|
|
50
|
+
return result
|
|
51
|
+
self.status = f"Key '{key}' not found in Data object."
|
|
52
|
+
return Data(data={"error": f"Key '{key}' not found in Data object."})
|
|
53
|
+
self.status = "Invalid input. Expected Data object or list of Data objects."
|
|
54
|
+
return Data(data={"error": "Invalid input. Expected Data object or list of Data objects."})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from lfx.custom.custom_component.component import Component
|
|
2
|
+
from lfx.io import DataInput, MessageTextInput, Output
|
|
3
|
+
from lfx.schema.data import Data
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FilterDataComponent(Component):
|
|
7
|
+
display_name = "Filter Data"
|
|
8
|
+
description = "Filters a Data object based on a list of keys."
|
|
9
|
+
icon = "filter"
|
|
10
|
+
beta = True
|
|
11
|
+
name = "FilterData"
|
|
12
|
+
legacy = True
|
|
13
|
+
replacement = ["processing.DataOperations"]
|
|
14
|
+
|
|
15
|
+
inputs = [
|
|
16
|
+
DataInput(
|
|
17
|
+
name="data",
|
|
18
|
+
display_name="Data",
|
|
19
|
+
info="Data object to filter.",
|
|
20
|
+
),
|
|
21
|
+
MessageTextInput(
|
|
22
|
+
name="filter_criteria",
|
|
23
|
+
display_name="Filter Criteria",
|
|
24
|
+
info="List of keys to filter by.",
|
|
25
|
+
is_list=True,
|
|
26
|
+
),
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
outputs = [
|
|
30
|
+
Output(display_name="Filtered Data", name="filtered_data", method="filter_data"),
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
def filter_data(self) -> Data:
|
|
34
|
+
filter_criteria: list[str] = self.filter_criteria
|
|
35
|
+
data = self.data.data if isinstance(self.data, Data) else {}
|
|
36
|
+
|
|
37
|
+
# Filter the data
|
|
38
|
+
filtered = {key: value for key, value in data.items() if key in filter_criteria}
|
|
39
|
+
|
|
40
|
+
# Create a new Data object with the filtered data
|
|
41
|
+
filtered_data = Data(data=filtered)
|
|
42
|
+
self.status = filtered_data
|
|
43
|
+
return filtered_data
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from lfx.custom.custom_component.component import Component
|
|
4
|
+
from lfx.io import DataInput, DropdownInput, MessageTextInput, Output
|
|
5
|
+
from lfx.schema.data import Data
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DataFilterComponent(Component):
|
|
9
|
+
display_name = "Filter Values"
|
|
10
|
+
description = (
|
|
11
|
+
"Filter a list of data items based on a specified key, filter value,"
|
|
12
|
+
" and comparison operator. Check advanced options to select match comparision."
|
|
13
|
+
)
|
|
14
|
+
icon = "filter"
|
|
15
|
+
beta = True
|
|
16
|
+
name = "FilterDataValues"
|
|
17
|
+
legacy = True
|
|
18
|
+
replacement = ["processing.DataOperations"]
|
|
19
|
+
|
|
20
|
+
inputs = [
|
|
21
|
+
DataInput(name="input_data", display_name="Input Data", info="The list of data items to filter.", is_list=True),
|
|
22
|
+
MessageTextInput(
|
|
23
|
+
name="filter_key",
|
|
24
|
+
display_name="Filter Key",
|
|
25
|
+
info="The key to filter on (e.g., 'route').",
|
|
26
|
+
value="route",
|
|
27
|
+
input_types=["Data"],
|
|
28
|
+
),
|
|
29
|
+
MessageTextInput(
|
|
30
|
+
name="filter_value",
|
|
31
|
+
display_name="Filter Value",
|
|
32
|
+
info="The value to filter by (e.g., 'CMIP').",
|
|
33
|
+
value="CMIP",
|
|
34
|
+
input_types=["Data"],
|
|
35
|
+
),
|
|
36
|
+
DropdownInput(
|
|
37
|
+
name="operator",
|
|
38
|
+
display_name="Comparison Operator",
|
|
39
|
+
options=["equals", "not equals", "contains", "starts with", "ends with"],
|
|
40
|
+
info="The operator to apply for comparing the values.",
|
|
41
|
+
value="equals",
|
|
42
|
+
advanced=True,
|
|
43
|
+
),
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
outputs = [
|
|
47
|
+
Output(display_name="Filtered Data", name="filtered_data", method="filter_data"),
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
def compare_values(self, item_value: Any, filter_value: str, operator: str) -> bool:
|
|
51
|
+
if operator == "equals":
|
|
52
|
+
return str(item_value) == filter_value
|
|
53
|
+
if operator == "not equals":
|
|
54
|
+
return str(item_value) != filter_value
|
|
55
|
+
if operator == "contains":
|
|
56
|
+
return filter_value in str(item_value)
|
|
57
|
+
if operator == "starts with":
|
|
58
|
+
return str(item_value).startswith(filter_value)
|
|
59
|
+
if operator == "ends with":
|
|
60
|
+
return str(item_value).endswith(filter_value)
|
|
61
|
+
return False
|
|
62
|
+
|
|
63
|
+
def filter_data(self) -> list[Data]:
|
|
64
|
+
# Extract inputs
|
|
65
|
+
input_data: list[Data] = self.input_data
|
|
66
|
+
filter_key: str = self.filter_key.text
|
|
67
|
+
filter_value: str = self.filter_value.text
|
|
68
|
+
operator: str = self.operator
|
|
69
|
+
|
|
70
|
+
# Validate inputs
|
|
71
|
+
if not input_data:
|
|
72
|
+
self.status = "Input data is empty."
|
|
73
|
+
return []
|
|
74
|
+
|
|
75
|
+
if not filter_key or not filter_value:
|
|
76
|
+
self.status = "Filter key or value is missing."
|
|
77
|
+
return input_data
|
|
78
|
+
|
|
79
|
+
# Filter the data
|
|
80
|
+
filtered_data = []
|
|
81
|
+
for item in input_data:
|
|
82
|
+
if isinstance(item.data, dict) and filter_key in item.data:
|
|
83
|
+
if self.compare_values(item.data[filter_key], filter_value, operator):
|
|
84
|
+
filtered_data.append(item)
|
|
85
|
+
else:
|
|
86
|
+
self.status = f"Warning: Some items don't have the key '{filter_key}' or are not dictionaries."
|
|
87
|
+
|
|
88
|
+
self.status = filtered_data
|
|
89
|
+
return filtered_data
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import unicodedata
|
|
3
|
+
|
|
4
|
+
from lfx.custom.custom_component.component import Component
|
|
5
|
+
from lfx.inputs.inputs import BoolInput, MessageTextInput
|
|
6
|
+
from lfx.schema.message import Message
|
|
7
|
+
from lfx.template.field.base import Output
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class JSONCleaner(Component):
|
|
11
|
+
icon = "braces"
|
|
12
|
+
display_name = "JSON Cleaner"
|
|
13
|
+
description = (
|
|
14
|
+
"Cleans the messy and sometimes incorrect JSON strings produced by LLMs "
|
|
15
|
+
"so that they are fully compliant with the JSON spec."
|
|
16
|
+
)
|
|
17
|
+
legacy = True
|
|
18
|
+
replacement = ["processing.ParserComponent"]
|
|
19
|
+
inputs = [
|
|
20
|
+
MessageTextInput(
|
|
21
|
+
name="json_str", display_name="JSON String", info="The JSON string to be cleaned.", required=True
|
|
22
|
+
),
|
|
23
|
+
BoolInput(
|
|
24
|
+
name="remove_control_chars",
|
|
25
|
+
display_name="Remove Control Characters",
|
|
26
|
+
info="Remove control characters from the JSON string.",
|
|
27
|
+
required=False,
|
|
28
|
+
),
|
|
29
|
+
BoolInput(
|
|
30
|
+
name="normalize_unicode",
|
|
31
|
+
display_name="Normalize Unicode",
|
|
32
|
+
info="Normalize Unicode characters in the JSON string.",
|
|
33
|
+
required=False,
|
|
34
|
+
),
|
|
35
|
+
BoolInput(
|
|
36
|
+
name="validate_json",
|
|
37
|
+
display_name="Validate JSON",
|
|
38
|
+
info="Validate the JSON string to ensure it is well-formed.",
|
|
39
|
+
required=False,
|
|
40
|
+
),
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
outputs = [
|
|
44
|
+
Output(display_name="Cleaned JSON String", name="output", method="clean_json"),
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
def clean_json(self) -> Message:
|
|
48
|
+
try:
|
|
49
|
+
from json_repair import repair_json
|
|
50
|
+
except ImportError as e:
|
|
51
|
+
msg = "Could not import the json_repair package. Please install it with `pip install json_repair`."
|
|
52
|
+
raise ImportError(msg) from e
|
|
53
|
+
|
|
54
|
+
"""Clean the input JSON string based on provided options and return the cleaned JSON string."""
|
|
55
|
+
json_str = self.json_str
|
|
56
|
+
remove_control_chars = self.remove_control_chars
|
|
57
|
+
normalize_unicode = self.normalize_unicode
|
|
58
|
+
validate_json = self.validate_json
|
|
59
|
+
|
|
60
|
+
start = json_str.find("{")
|
|
61
|
+
end = json_str.rfind("}")
|
|
62
|
+
if start == -1 or end == -1:
|
|
63
|
+
msg = "Invalid JSON string: Missing '{' or '}'"
|
|
64
|
+
raise ValueError(msg)
|
|
65
|
+
try:
|
|
66
|
+
json_str = json_str[start : end + 1]
|
|
67
|
+
|
|
68
|
+
if remove_control_chars:
|
|
69
|
+
json_str = self._remove_control_characters(json_str)
|
|
70
|
+
if normalize_unicode:
|
|
71
|
+
json_str = self._normalize_unicode(json_str)
|
|
72
|
+
if validate_json:
|
|
73
|
+
json_str = self._validate_json(json_str)
|
|
74
|
+
|
|
75
|
+
cleaned_json_str = repair_json(json_str)
|
|
76
|
+
result = str(cleaned_json_str)
|
|
77
|
+
|
|
78
|
+
self.status = result
|
|
79
|
+
return Message(text=result)
|
|
80
|
+
except Exception as e:
|
|
81
|
+
msg = f"Error cleaning JSON string: {e}"
|
|
82
|
+
raise ValueError(msg) from e
|
|
83
|
+
|
|
84
|
+
def _remove_control_characters(self, s: str) -> str:
|
|
85
|
+
"""Remove control characters from the string."""
|
|
86
|
+
return s.translate(self.translation_table)
|
|
87
|
+
|
|
88
|
+
def _normalize_unicode(self, s: str) -> str:
|
|
89
|
+
"""Normalize Unicode characters in the string."""
|
|
90
|
+
return unicodedata.normalize("NFC", s)
|
|
91
|
+
|
|
92
|
+
def _validate_json(self, s: str) -> str:
|
|
93
|
+
"""Validate the JSON string."""
|
|
94
|
+
try:
|
|
95
|
+
json.loads(s)
|
|
96
|
+
except json.JSONDecodeError as e:
|
|
97
|
+
msg = f"Invalid JSON string: {e}"
|
|
98
|
+
raise ValueError(msg) from e
|
|
99
|
+
return s
|
|
100
|
+
|
|
101
|
+
def __init__(self, *args, **kwargs):
|
|
102
|
+
# Create a translation table that maps control characters to None
|
|
103
|
+
super().__init__(*args, **kwargs)
|
|
104
|
+
self.translation_table = str.maketrans("", "", "".join(chr(i) for i in range(32)) + chr(127))
|