lfx-nightly 0.1.11.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (699) hide show
  1. lfx/__init__.py +0 -0
  2. lfx/__main__.py +25 -0
  3. lfx/base/__init__.py +0 -0
  4. lfx/base/agents/__init__.py +0 -0
  5. lfx/base/agents/agent.py +268 -0
  6. lfx/base/agents/callback.py +130 -0
  7. lfx/base/agents/context.py +109 -0
  8. lfx/base/agents/crewai/__init__.py +0 -0
  9. lfx/base/agents/crewai/crew.py +231 -0
  10. lfx/base/agents/crewai/tasks.py +12 -0
  11. lfx/base/agents/default_prompts.py +23 -0
  12. lfx/base/agents/errors.py +15 -0
  13. lfx/base/agents/events.py +346 -0
  14. lfx/base/agents/utils.py +205 -0
  15. lfx/base/astra_assistants/__init__.py +0 -0
  16. lfx/base/astra_assistants/util.py +171 -0
  17. lfx/base/chains/__init__.py +0 -0
  18. lfx/base/chains/model.py +19 -0
  19. lfx/base/composio/__init__.py +0 -0
  20. lfx/base/composio/composio_base.py +1291 -0
  21. lfx/base/compressors/__init__.py +0 -0
  22. lfx/base/compressors/model.py +60 -0
  23. lfx/base/constants.py +46 -0
  24. lfx/base/curl/__init__.py +0 -0
  25. lfx/base/curl/parse.py +188 -0
  26. lfx/base/data/__init__.py +5 -0
  27. lfx/base/data/base_file.py +685 -0
  28. lfx/base/data/docling_utils.py +245 -0
  29. lfx/base/data/utils.py +198 -0
  30. lfx/base/document_transformers/__init__.py +0 -0
  31. lfx/base/document_transformers/model.py +43 -0
  32. lfx/base/embeddings/__init__.py +0 -0
  33. lfx/base/embeddings/aiml_embeddings.py +62 -0
  34. lfx/base/embeddings/model.py +26 -0
  35. lfx/base/flow_processing/__init__.py +0 -0
  36. lfx/base/flow_processing/utils.py +86 -0
  37. lfx/base/huggingface/__init__.py +0 -0
  38. lfx/base/huggingface/model_bridge.py +133 -0
  39. lfx/base/io/__init__.py +0 -0
  40. lfx/base/io/chat.py +20 -0
  41. lfx/base/io/text.py +22 -0
  42. lfx/base/langchain_utilities/__init__.py +0 -0
  43. lfx/base/langchain_utilities/model.py +35 -0
  44. lfx/base/langchain_utilities/spider_constants.py +1 -0
  45. lfx/base/langwatch/__init__.py +0 -0
  46. lfx/base/langwatch/utils.py +18 -0
  47. lfx/base/mcp/__init__.py +0 -0
  48. lfx/base/mcp/constants.py +2 -0
  49. lfx/base/mcp/util.py +1398 -0
  50. lfx/base/memory/__init__.py +0 -0
  51. lfx/base/memory/memory.py +49 -0
  52. lfx/base/memory/model.py +38 -0
  53. lfx/base/models/__init__.py +3 -0
  54. lfx/base/models/aiml_constants.py +51 -0
  55. lfx/base/models/anthropic_constants.py +47 -0
  56. lfx/base/models/aws_constants.py +151 -0
  57. lfx/base/models/chat_result.py +76 -0
  58. lfx/base/models/google_generative_ai_constants.py +70 -0
  59. lfx/base/models/groq_constants.py +134 -0
  60. lfx/base/models/model.py +375 -0
  61. lfx/base/models/model_input_constants.py +307 -0
  62. lfx/base/models/model_metadata.py +41 -0
  63. lfx/base/models/model_utils.py +8 -0
  64. lfx/base/models/novita_constants.py +35 -0
  65. lfx/base/models/ollama_constants.py +49 -0
  66. lfx/base/models/openai_constants.py +122 -0
  67. lfx/base/models/sambanova_constants.py +18 -0
  68. lfx/base/processing/__init__.py +0 -0
  69. lfx/base/prompts/__init__.py +0 -0
  70. lfx/base/prompts/api_utils.py +224 -0
  71. lfx/base/prompts/utils.py +61 -0
  72. lfx/base/textsplitters/__init__.py +0 -0
  73. lfx/base/textsplitters/model.py +28 -0
  74. lfx/base/tools/__init__.py +0 -0
  75. lfx/base/tools/base.py +26 -0
  76. lfx/base/tools/component_tool.py +325 -0
  77. lfx/base/tools/constants.py +49 -0
  78. lfx/base/tools/flow_tool.py +132 -0
  79. lfx/base/tools/run_flow.py +224 -0
  80. lfx/base/vectorstores/__init__.py +0 -0
  81. lfx/base/vectorstores/model.py +193 -0
  82. lfx/base/vectorstores/utils.py +22 -0
  83. lfx/base/vectorstores/vector_store_connection_decorator.py +52 -0
  84. lfx/cli/__init__.py +5 -0
  85. lfx/cli/commands.py +319 -0
  86. lfx/cli/common.py +650 -0
  87. lfx/cli/run.py +441 -0
  88. lfx/cli/script_loader.py +247 -0
  89. lfx/cli/serve_app.py +546 -0
  90. lfx/cli/validation.py +69 -0
  91. lfx/components/FAISS/__init__.py +34 -0
  92. lfx/components/FAISS/faiss.py +111 -0
  93. lfx/components/Notion/__init__.py +19 -0
  94. lfx/components/Notion/add_content_to_page.py +269 -0
  95. lfx/components/Notion/create_page.py +94 -0
  96. lfx/components/Notion/list_database_properties.py +68 -0
  97. lfx/components/Notion/list_pages.py +122 -0
  98. lfx/components/Notion/list_users.py +77 -0
  99. lfx/components/Notion/page_content_viewer.py +93 -0
  100. lfx/components/Notion/search.py +111 -0
  101. lfx/components/Notion/update_page_property.py +114 -0
  102. lfx/components/__init__.py +411 -0
  103. lfx/components/_importing.py +42 -0
  104. lfx/components/agentql/__init__.py +3 -0
  105. lfx/components/agentql/agentql_api.py +151 -0
  106. lfx/components/agents/__init__.py +34 -0
  107. lfx/components/agents/agent.py +558 -0
  108. lfx/components/agents/mcp_component.py +501 -0
  109. lfx/components/aiml/__init__.py +37 -0
  110. lfx/components/aiml/aiml.py +112 -0
  111. lfx/components/aiml/aiml_embeddings.py +37 -0
  112. lfx/components/amazon/__init__.py +36 -0
  113. lfx/components/amazon/amazon_bedrock_embedding.py +109 -0
  114. lfx/components/amazon/amazon_bedrock_model.py +124 -0
  115. lfx/components/amazon/s3_bucket_uploader.py +211 -0
  116. lfx/components/anthropic/__init__.py +34 -0
  117. lfx/components/anthropic/anthropic.py +187 -0
  118. lfx/components/apify/__init__.py +5 -0
  119. lfx/components/apify/apify_actor.py +325 -0
  120. lfx/components/arxiv/__init__.py +3 -0
  121. lfx/components/arxiv/arxiv.py +163 -0
  122. lfx/components/assemblyai/__init__.py +46 -0
  123. lfx/components/assemblyai/assemblyai_get_subtitles.py +83 -0
  124. lfx/components/assemblyai/assemblyai_lemur.py +183 -0
  125. lfx/components/assemblyai/assemblyai_list_transcripts.py +95 -0
  126. lfx/components/assemblyai/assemblyai_poll_transcript.py +72 -0
  127. lfx/components/assemblyai/assemblyai_start_transcript.py +188 -0
  128. lfx/components/azure/__init__.py +37 -0
  129. lfx/components/azure/azure_openai.py +95 -0
  130. lfx/components/azure/azure_openai_embeddings.py +83 -0
  131. lfx/components/baidu/__init__.py +32 -0
  132. lfx/components/baidu/baidu_qianfan_chat.py +113 -0
  133. lfx/components/bing/__init__.py +3 -0
  134. lfx/components/bing/bing_search_api.py +61 -0
  135. lfx/components/cassandra/__init__.py +40 -0
  136. lfx/components/cassandra/cassandra.py +264 -0
  137. lfx/components/cassandra/cassandra_chat.py +92 -0
  138. lfx/components/cassandra/cassandra_graph.py +238 -0
  139. lfx/components/chains/__init__.py +3 -0
  140. lfx/components/chroma/__init__.py +34 -0
  141. lfx/components/chroma/chroma.py +167 -0
  142. lfx/components/cleanlab/__init__.py +40 -0
  143. lfx/components/cleanlab/cleanlab_evaluator.py +155 -0
  144. lfx/components/cleanlab/cleanlab_rag_evaluator.py +254 -0
  145. lfx/components/cleanlab/cleanlab_remediator.py +131 -0
  146. lfx/components/clickhouse/__init__.py +34 -0
  147. lfx/components/clickhouse/clickhouse.py +135 -0
  148. lfx/components/cloudflare/__init__.py +32 -0
  149. lfx/components/cloudflare/cloudflare.py +81 -0
  150. lfx/components/cohere/__init__.py +40 -0
  151. lfx/components/cohere/cohere_embeddings.py +81 -0
  152. lfx/components/cohere/cohere_models.py +46 -0
  153. lfx/components/cohere/cohere_rerank.py +51 -0
  154. lfx/components/composio/__init__.py +74 -0
  155. lfx/components/composio/composio_api.py +268 -0
  156. lfx/components/composio/dropbox_compnent.py +11 -0
  157. lfx/components/composio/github_composio.py +11 -0
  158. lfx/components/composio/gmail_composio.py +38 -0
  159. lfx/components/composio/googlecalendar_composio.py +11 -0
  160. lfx/components/composio/googlemeet_composio.py +11 -0
  161. lfx/components/composio/googletasks_composio.py +8 -0
  162. lfx/components/composio/linear_composio.py +11 -0
  163. lfx/components/composio/outlook_composio.py +11 -0
  164. lfx/components/composio/reddit_composio.py +11 -0
  165. lfx/components/composio/slack_composio.py +582 -0
  166. lfx/components/composio/slackbot_composio.py +11 -0
  167. lfx/components/composio/supabase_composio.py +11 -0
  168. lfx/components/composio/todoist_composio.py +11 -0
  169. lfx/components/composio/youtube_composio.py +11 -0
  170. lfx/components/confluence/__init__.py +3 -0
  171. lfx/components/confluence/confluence.py +84 -0
  172. lfx/components/couchbase/__init__.py +34 -0
  173. lfx/components/couchbase/couchbase.py +102 -0
  174. lfx/components/crewai/__init__.py +49 -0
  175. lfx/components/crewai/crewai.py +107 -0
  176. lfx/components/crewai/hierarchical_crew.py +46 -0
  177. lfx/components/crewai/hierarchical_task.py +44 -0
  178. lfx/components/crewai/sequential_crew.py +52 -0
  179. lfx/components/crewai/sequential_task.py +73 -0
  180. lfx/components/crewai/sequential_task_agent.py +143 -0
  181. lfx/components/custom_component/__init__.py +34 -0
  182. lfx/components/custom_component/custom_component.py +31 -0
  183. lfx/components/data/__init__.py +64 -0
  184. lfx/components/data/api_request.py +544 -0
  185. lfx/components/data/csv_to_data.py +95 -0
  186. lfx/components/data/directory.py +113 -0
  187. lfx/components/data/file.py +577 -0
  188. lfx/components/data/json_to_data.py +98 -0
  189. lfx/components/data/news_search.py +164 -0
  190. lfx/components/data/rss.py +69 -0
  191. lfx/components/data/sql_executor.py +101 -0
  192. lfx/components/data/url.py +311 -0
  193. lfx/components/data/web_search.py +112 -0
  194. lfx/components/data/webhook.py +56 -0
  195. lfx/components/datastax/__init__.py +70 -0
  196. lfx/components/datastax/astra_assistant_manager.py +306 -0
  197. lfx/components/datastax/astra_db.py +75 -0
  198. lfx/components/datastax/astra_vectorize.py +124 -0
  199. lfx/components/datastax/astradb.py +1285 -0
  200. lfx/components/datastax/astradb_cql.py +314 -0
  201. lfx/components/datastax/astradb_graph.py +330 -0
  202. lfx/components/datastax/astradb_tool.py +414 -0
  203. lfx/components/datastax/astradb_vectorstore.py +1285 -0
  204. lfx/components/datastax/cassandra.py +92 -0
  205. lfx/components/datastax/create_assistant.py +58 -0
  206. lfx/components/datastax/create_thread.py +32 -0
  207. lfx/components/datastax/dotenv.py +35 -0
  208. lfx/components/datastax/get_assistant.py +37 -0
  209. lfx/components/datastax/getenvvar.py +30 -0
  210. lfx/components/datastax/graph_rag.py +141 -0
  211. lfx/components/datastax/hcd.py +314 -0
  212. lfx/components/datastax/list_assistants.py +25 -0
  213. lfx/components/datastax/run.py +89 -0
  214. lfx/components/deactivated/__init__.py +15 -0
  215. lfx/components/deactivated/amazon_kendra.py +66 -0
  216. lfx/components/deactivated/chat_litellm_model.py +158 -0
  217. lfx/components/deactivated/code_block_extractor.py +26 -0
  218. lfx/components/deactivated/documents_to_data.py +22 -0
  219. lfx/components/deactivated/embed.py +16 -0
  220. lfx/components/deactivated/extract_key_from_data.py +46 -0
  221. lfx/components/deactivated/json_document_builder.py +57 -0
  222. lfx/components/deactivated/list_flows.py +20 -0
  223. lfx/components/deactivated/mcp_sse.py +61 -0
  224. lfx/components/deactivated/mcp_stdio.py +62 -0
  225. lfx/components/deactivated/merge_data.py +93 -0
  226. lfx/components/deactivated/message.py +37 -0
  227. lfx/components/deactivated/metal.py +54 -0
  228. lfx/components/deactivated/multi_query.py +59 -0
  229. lfx/components/deactivated/retriever.py +43 -0
  230. lfx/components/deactivated/selective_passthrough.py +77 -0
  231. lfx/components/deactivated/should_run_next.py +40 -0
  232. lfx/components/deactivated/split_text.py +63 -0
  233. lfx/components/deactivated/store_message.py +24 -0
  234. lfx/components/deactivated/sub_flow.py +124 -0
  235. lfx/components/deactivated/vectara_self_query.py +76 -0
  236. lfx/components/deactivated/vector_store.py +24 -0
  237. lfx/components/deepseek/__init__.py +34 -0
  238. lfx/components/deepseek/deepseek.py +136 -0
  239. lfx/components/docling/__init__.py +43 -0
  240. lfx/components/docling/chunk_docling_document.py +186 -0
  241. lfx/components/docling/docling_inline.py +231 -0
  242. lfx/components/docling/docling_remote.py +193 -0
  243. lfx/components/docling/export_docling_document.py +117 -0
  244. lfx/components/documentloaders/__init__.py +3 -0
  245. lfx/components/duckduckgo/__init__.py +3 -0
  246. lfx/components/duckduckgo/duck_duck_go_search_run.py +92 -0
  247. lfx/components/elastic/__init__.py +37 -0
  248. lfx/components/elastic/elasticsearch.py +267 -0
  249. lfx/components/elastic/opensearch.py +243 -0
  250. lfx/components/embeddings/__init__.py +37 -0
  251. lfx/components/embeddings/similarity.py +76 -0
  252. lfx/components/embeddings/text_embedder.py +64 -0
  253. lfx/components/exa/__init__.py +3 -0
  254. lfx/components/exa/exa_search.py +68 -0
  255. lfx/components/firecrawl/__init__.py +43 -0
  256. lfx/components/firecrawl/firecrawl_crawl_api.py +88 -0
  257. lfx/components/firecrawl/firecrawl_extract_api.py +136 -0
  258. lfx/components/firecrawl/firecrawl_map_api.py +89 -0
  259. lfx/components/firecrawl/firecrawl_scrape_api.py +73 -0
  260. lfx/components/git/__init__.py +4 -0
  261. lfx/components/git/git.py +262 -0
  262. lfx/components/git/gitextractor.py +196 -0
  263. lfx/components/glean/__init__.py +3 -0
  264. lfx/components/glean/glean_search_api.py +173 -0
  265. lfx/components/google/__init__.py +17 -0
  266. lfx/components/google/gmail.py +192 -0
  267. lfx/components/google/google_bq_sql_executor.py +157 -0
  268. lfx/components/google/google_drive.py +92 -0
  269. lfx/components/google/google_drive_search.py +152 -0
  270. lfx/components/google/google_generative_ai.py +147 -0
  271. lfx/components/google/google_generative_ai_embeddings.py +141 -0
  272. lfx/components/google/google_oauth_token.py +89 -0
  273. lfx/components/google/google_search_api_core.py +68 -0
  274. lfx/components/google/google_serper_api_core.py +74 -0
  275. lfx/components/groq/__init__.py +34 -0
  276. lfx/components/groq/groq.py +136 -0
  277. lfx/components/helpers/__init__.py +52 -0
  278. lfx/components/helpers/calculator_core.py +89 -0
  279. lfx/components/helpers/create_list.py +40 -0
  280. lfx/components/helpers/current_date.py +42 -0
  281. lfx/components/helpers/id_generator.py +42 -0
  282. lfx/components/helpers/memory.py +251 -0
  283. lfx/components/helpers/output_parser.py +45 -0
  284. lfx/components/helpers/store_message.py +90 -0
  285. lfx/components/homeassistant/__init__.py +7 -0
  286. lfx/components/homeassistant/home_assistant_control.py +152 -0
  287. lfx/components/homeassistant/list_home_assistant_states.py +137 -0
  288. lfx/components/huggingface/__init__.py +37 -0
  289. lfx/components/huggingface/huggingface.py +197 -0
  290. lfx/components/huggingface/huggingface_inference_api.py +106 -0
  291. lfx/components/ibm/__init__.py +34 -0
  292. lfx/components/ibm/watsonx.py +203 -0
  293. lfx/components/ibm/watsonx_embeddings.py +135 -0
  294. lfx/components/icosacomputing/__init__.py +5 -0
  295. lfx/components/icosacomputing/combinatorial_reasoner.py +84 -0
  296. lfx/components/input_output/__init__.py +38 -0
  297. lfx/components/input_output/chat.py +120 -0
  298. lfx/components/input_output/chat_output.py +200 -0
  299. lfx/components/input_output/text.py +27 -0
  300. lfx/components/input_output/text_output.py +29 -0
  301. lfx/components/jigsawstack/__init__.py +23 -0
  302. lfx/components/jigsawstack/ai_scrape.py +126 -0
  303. lfx/components/jigsawstack/ai_web_search.py +136 -0
  304. lfx/components/jigsawstack/file_read.py +115 -0
  305. lfx/components/jigsawstack/file_upload.py +94 -0
  306. lfx/components/jigsawstack/image_generation.py +205 -0
  307. lfx/components/jigsawstack/nsfw.py +60 -0
  308. lfx/components/jigsawstack/object_detection.py +124 -0
  309. lfx/components/jigsawstack/sentiment.py +112 -0
  310. lfx/components/jigsawstack/text_to_sql.py +90 -0
  311. lfx/components/jigsawstack/text_translate.py +77 -0
  312. lfx/components/jigsawstack/vocr.py +107 -0
  313. lfx/components/langchain_utilities/__init__.py +109 -0
  314. lfx/components/langchain_utilities/character.py +53 -0
  315. lfx/components/langchain_utilities/conversation.py +59 -0
  316. lfx/components/langchain_utilities/csv_agent.py +107 -0
  317. lfx/components/langchain_utilities/fake_embeddings.py +26 -0
  318. lfx/components/langchain_utilities/html_link_extractor.py +35 -0
  319. lfx/components/langchain_utilities/json_agent.py +45 -0
  320. lfx/components/langchain_utilities/langchain_hub.py +126 -0
  321. lfx/components/langchain_utilities/language_recursive.py +49 -0
  322. lfx/components/langchain_utilities/language_semantic.py +138 -0
  323. lfx/components/langchain_utilities/llm_checker.py +39 -0
  324. lfx/components/langchain_utilities/llm_math.py +42 -0
  325. lfx/components/langchain_utilities/natural_language.py +61 -0
  326. lfx/components/langchain_utilities/openai_tools.py +53 -0
  327. lfx/components/langchain_utilities/openapi.py +48 -0
  328. lfx/components/langchain_utilities/recursive_character.py +60 -0
  329. lfx/components/langchain_utilities/retrieval_qa.py +83 -0
  330. lfx/components/langchain_utilities/runnable_executor.py +137 -0
  331. lfx/components/langchain_utilities/self_query.py +80 -0
  332. lfx/components/langchain_utilities/spider.py +142 -0
  333. lfx/components/langchain_utilities/sql.py +40 -0
  334. lfx/components/langchain_utilities/sql_database.py +35 -0
  335. lfx/components/langchain_utilities/sql_generator.py +78 -0
  336. lfx/components/langchain_utilities/tool_calling.py +59 -0
  337. lfx/components/langchain_utilities/vector_store_info.py +49 -0
  338. lfx/components/langchain_utilities/vector_store_router.py +33 -0
  339. lfx/components/langchain_utilities/xml_agent.py +71 -0
  340. lfx/components/langwatch/__init__.py +3 -0
  341. lfx/components/langwatch/langwatch.py +278 -0
  342. lfx/components/link_extractors/__init__.py +3 -0
  343. lfx/components/lmstudio/__init__.py +34 -0
  344. lfx/components/lmstudio/lmstudioembeddings.py +89 -0
  345. lfx/components/lmstudio/lmstudiomodel.py +129 -0
  346. lfx/components/logic/__init__.py +52 -0
  347. lfx/components/logic/conditional_router.py +171 -0
  348. lfx/components/logic/data_conditional_router.py +125 -0
  349. lfx/components/logic/flow_tool.py +110 -0
  350. lfx/components/logic/listen.py +29 -0
  351. lfx/components/logic/loop.py +125 -0
  352. lfx/components/logic/notify.py +88 -0
  353. lfx/components/logic/pass_message.py +35 -0
  354. lfx/components/logic/run_flow.py +71 -0
  355. lfx/components/logic/sub_flow.py +114 -0
  356. lfx/components/maritalk/__init__.py +32 -0
  357. lfx/components/maritalk/maritalk.py +52 -0
  358. lfx/components/mem0/__init__.py +3 -0
  359. lfx/components/mem0/mem0_chat_memory.py +136 -0
  360. lfx/components/milvus/__init__.py +34 -0
  361. lfx/components/milvus/milvus.py +115 -0
  362. lfx/components/mistral/__init__.py +37 -0
  363. lfx/components/mistral/mistral.py +114 -0
  364. lfx/components/mistral/mistral_embeddings.py +58 -0
  365. lfx/components/models/__init__.py +34 -0
  366. lfx/components/models/embedding_model.py +114 -0
  367. lfx/components/models/language_model.py +144 -0
  368. lfx/components/mongodb/__init__.py +34 -0
  369. lfx/components/mongodb/mongodb_atlas.py +213 -0
  370. lfx/components/needle/__init__.py +3 -0
  371. lfx/components/needle/needle.py +104 -0
  372. lfx/components/notdiamond/__init__.py +34 -0
  373. lfx/components/notdiamond/notdiamond.py +228 -0
  374. lfx/components/novita/__init__.py +32 -0
  375. lfx/components/novita/novita.py +130 -0
  376. lfx/components/nvidia/__init__.py +57 -0
  377. lfx/components/nvidia/nvidia.py +157 -0
  378. lfx/components/nvidia/nvidia_embedding.py +77 -0
  379. lfx/components/nvidia/nvidia_ingest.py +317 -0
  380. lfx/components/nvidia/nvidia_rerank.py +63 -0
  381. lfx/components/nvidia/system_assist.py +65 -0
  382. lfx/components/olivya/__init__.py +3 -0
  383. lfx/components/olivya/olivya.py +116 -0
  384. lfx/components/ollama/__init__.py +37 -0
  385. lfx/components/ollama/ollama.py +330 -0
  386. lfx/components/ollama/ollama_embeddings.py +106 -0
  387. lfx/components/openai/__init__.py +37 -0
  388. lfx/components/openai/openai.py +100 -0
  389. lfx/components/openai/openai_chat_model.py +176 -0
  390. lfx/components/openrouter/__init__.py +32 -0
  391. lfx/components/openrouter/openrouter.py +202 -0
  392. lfx/components/output_parsers/__init__.py +3 -0
  393. lfx/components/perplexity/__init__.py +34 -0
  394. lfx/components/perplexity/perplexity.py +75 -0
  395. lfx/components/pgvector/__init__.py +34 -0
  396. lfx/components/pgvector/pgvector.py +72 -0
  397. lfx/components/pinecone/__init__.py +34 -0
  398. lfx/components/pinecone/pinecone.py +134 -0
  399. lfx/components/processing/__init__.py +117 -0
  400. lfx/components/processing/alter_metadata.py +108 -0
  401. lfx/components/processing/batch_run.py +205 -0
  402. lfx/components/processing/combine_text.py +39 -0
  403. lfx/components/processing/converter.py +159 -0
  404. lfx/components/processing/create_data.py +110 -0
  405. lfx/components/processing/data_operations.py +438 -0
  406. lfx/components/processing/data_to_dataframe.py +70 -0
  407. lfx/components/processing/dataframe_operations.py +313 -0
  408. lfx/components/processing/extract_key.py +53 -0
  409. lfx/components/processing/filter_data.py +42 -0
  410. lfx/components/processing/filter_data_values.py +88 -0
  411. lfx/components/processing/json_cleaner.py +103 -0
  412. lfx/components/processing/lambda_filter.py +154 -0
  413. lfx/components/processing/llm_router.py +499 -0
  414. lfx/components/processing/merge_data.py +90 -0
  415. lfx/components/processing/message_to_data.py +36 -0
  416. lfx/components/processing/parse_data.py +70 -0
  417. lfx/components/processing/parse_dataframe.py +68 -0
  418. lfx/components/processing/parse_json_data.py +90 -0
  419. lfx/components/processing/parser.py +143 -0
  420. lfx/components/processing/prompt.py +67 -0
  421. lfx/components/processing/python_repl_core.py +98 -0
  422. lfx/components/processing/regex.py +82 -0
  423. lfx/components/processing/save_file.py +225 -0
  424. lfx/components/processing/select_data.py +48 -0
  425. lfx/components/processing/split_text.py +141 -0
  426. lfx/components/processing/structured_output.py +202 -0
  427. lfx/components/processing/update_data.py +160 -0
  428. lfx/components/prototypes/__init__.py +34 -0
  429. lfx/components/prototypes/python_function.py +73 -0
  430. lfx/components/qdrant/__init__.py +34 -0
  431. lfx/components/qdrant/qdrant.py +109 -0
  432. lfx/components/redis/__init__.py +37 -0
  433. lfx/components/redis/redis.py +89 -0
  434. lfx/components/redis/redis_chat.py +43 -0
  435. lfx/components/sambanova/__init__.py +32 -0
  436. lfx/components/sambanova/sambanova.py +84 -0
  437. lfx/components/scrapegraph/__init__.py +40 -0
  438. lfx/components/scrapegraph/scrapegraph_markdownify_api.py +64 -0
  439. lfx/components/scrapegraph/scrapegraph_search_api.py +64 -0
  440. lfx/components/scrapegraph/scrapegraph_smart_scraper_api.py +71 -0
  441. lfx/components/searchapi/__init__.py +34 -0
  442. lfx/components/searchapi/search.py +79 -0
  443. lfx/components/serpapi/__init__.py +3 -0
  444. lfx/components/serpapi/serp.py +115 -0
  445. lfx/components/supabase/__init__.py +34 -0
  446. lfx/components/supabase/supabase.py +76 -0
  447. lfx/components/tavily/__init__.py +4 -0
  448. lfx/components/tavily/tavily_extract.py +117 -0
  449. lfx/components/tavily/tavily_search.py +212 -0
  450. lfx/components/textsplitters/__init__.py +3 -0
  451. lfx/components/toolkits/__init__.py +3 -0
  452. lfx/components/tools/__init__.py +72 -0
  453. lfx/components/tools/calculator.py +108 -0
  454. lfx/components/tools/google_search_api.py +45 -0
  455. lfx/components/tools/google_serper_api.py +115 -0
  456. lfx/components/tools/python_code_structured_tool.py +327 -0
  457. lfx/components/tools/python_repl.py +97 -0
  458. lfx/components/tools/search_api.py +87 -0
  459. lfx/components/tools/searxng.py +145 -0
  460. lfx/components/tools/serp_api.py +119 -0
  461. lfx/components/tools/tavily_search_tool.py +344 -0
  462. lfx/components/tools/wikidata_api.py +102 -0
  463. lfx/components/tools/wikipedia_api.py +49 -0
  464. lfx/components/tools/yahoo_finance.py +129 -0
  465. lfx/components/twelvelabs/__init__.py +52 -0
  466. lfx/components/twelvelabs/convert_astra_results.py +84 -0
  467. lfx/components/twelvelabs/pegasus_index.py +311 -0
  468. lfx/components/twelvelabs/split_video.py +291 -0
  469. lfx/components/twelvelabs/text_embeddings.py +57 -0
  470. lfx/components/twelvelabs/twelvelabs_pegasus.py +408 -0
  471. lfx/components/twelvelabs/video_embeddings.py +100 -0
  472. lfx/components/twelvelabs/video_file.py +179 -0
  473. lfx/components/unstructured/__init__.py +3 -0
  474. lfx/components/unstructured/unstructured.py +121 -0
  475. lfx/components/upstash/__init__.py +34 -0
  476. lfx/components/upstash/upstash.py +124 -0
  477. lfx/components/vectara/__init__.py +37 -0
  478. lfx/components/vectara/vectara.py +97 -0
  479. lfx/components/vectara/vectara_rag.py +164 -0
  480. lfx/components/vectorstores/__init__.py +40 -0
  481. lfx/components/vectorstores/astradb.py +1285 -0
  482. lfx/components/vectorstores/astradb_graph.py +319 -0
  483. lfx/components/vectorstores/cassandra.py +264 -0
  484. lfx/components/vectorstores/cassandra_graph.py +238 -0
  485. lfx/components/vectorstores/chroma.py +167 -0
  486. lfx/components/vectorstores/clickhouse.py +135 -0
  487. lfx/components/vectorstores/couchbase.py +102 -0
  488. lfx/components/vectorstores/elasticsearch.py +267 -0
  489. lfx/components/vectorstores/faiss.py +111 -0
  490. lfx/components/vectorstores/graph_rag.py +141 -0
  491. lfx/components/vectorstores/hcd.py +314 -0
  492. lfx/components/vectorstores/local_db.py +261 -0
  493. lfx/components/vectorstores/milvus.py +115 -0
  494. lfx/components/vectorstores/mongodb_atlas.py +213 -0
  495. lfx/components/vectorstores/opensearch.py +243 -0
  496. lfx/components/vectorstores/pgvector.py +72 -0
  497. lfx/components/vectorstores/pinecone.py +134 -0
  498. lfx/components/vectorstores/qdrant.py +109 -0
  499. lfx/components/vectorstores/supabase.py +76 -0
  500. lfx/components/vectorstores/upstash.py +124 -0
  501. lfx/components/vectorstores/vectara.py +97 -0
  502. lfx/components/vectorstores/vectara_rag.py +164 -0
  503. lfx/components/vectorstores/weaviate.py +89 -0
  504. lfx/components/vertexai/__init__.py +37 -0
  505. lfx/components/vertexai/vertexai.py +71 -0
  506. lfx/components/vertexai/vertexai_embeddings.py +67 -0
  507. lfx/components/weaviate/__init__.py +34 -0
  508. lfx/components/weaviate/weaviate.py +89 -0
  509. lfx/components/wikipedia/__init__.py +4 -0
  510. lfx/components/wikipedia/wikidata.py +86 -0
  511. lfx/components/wikipedia/wikipedia.py +53 -0
  512. lfx/components/wolframalpha/__init__.py +3 -0
  513. lfx/components/wolframalpha/wolfram_alpha_api.py +54 -0
  514. lfx/components/xai/__init__.py +32 -0
  515. lfx/components/xai/xai.py +167 -0
  516. lfx/components/yahoosearch/__init__.py +3 -0
  517. lfx/components/yahoosearch/yahoo.py +137 -0
  518. lfx/components/youtube/__init__.py +52 -0
  519. lfx/components/youtube/channel.py +227 -0
  520. lfx/components/youtube/comments.py +231 -0
  521. lfx/components/youtube/playlist.py +33 -0
  522. lfx/components/youtube/search.py +120 -0
  523. lfx/components/youtube/trending.py +285 -0
  524. lfx/components/youtube/video_details.py +263 -0
  525. lfx/components/youtube/youtube_transcripts.py +118 -0
  526. lfx/components/zep/__init__.py +3 -0
  527. lfx/components/zep/zep.py +44 -0
  528. lfx/constants.py +6 -0
  529. lfx/custom/__init__.py +7 -0
  530. lfx/custom/attributes.py +86 -0
  531. lfx/custom/code_parser/__init__.py +3 -0
  532. lfx/custom/code_parser/code_parser.py +361 -0
  533. lfx/custom/custom_component/__init__.py +0 -0
  534. lfx/custom/custom_component/base_component.py +128 -0
  535. lfx/custom/custom_component/component.py +1808 -0
  536. lfx/custom/custom_component/component_with_cache.py +8 -0
  537. lfx/custom/custom_component/custom_component.py +588 -0
  538. lfx/custom/dependency_analyzer.py +165 -0
  539. lfx/custom/directory_reader/__init__.py +3 -0
  540. lfx/custom/directory_reader/directory_reader.py +359 -0
  541. lfx/custom/directory_reader/utils.py +171 -0
  542. lfx/custom/eval.py +12 -0
  543. lfx/custom/schema.py +32 -0
  544. lfx/custom/tree_visitor.py +21 -0
  545. lfx/custom/utils.py +877 -0
  546. lfx/custom/validate.py +488 -0
  547. lfx/events/__init__.py +1 -0
  548. lfx/events/event_manager.py +110 -0
  549. lfx/exceptions/__init__.py +0 -0
  550. lfx/exceptions/component.py +15 -0
  551. lfx/field_typing/__init__.py +91 -0
  552. lfx/field_typing/constants.py +215 -0
  553. lfx/field_typing/range_spec.py +35 -0
  554. lfx/graph/__init__.py +6 -0
  555. lfx/graph/edge/__init__.py +0 -0
  556. lfx/graph/edge/base.py +277 -0
  557. lfx/graph/edge/schema.py +119 -0
  558. lfx/graph/edge/utils.py +0 -0
  559. lfx/graph/graph/__init__.py +0 -0
  560. lfx/graph/graph/ascii.py +202 -0
  561. lfx/graph/graph/base.py +2238 -0
  562. lfx/graph/graph/constants.py +63 -0
  563. lfx/graph/graph/runnable_vertices_manager.py +133 -0
  564. lfx/graph/graph/schema.py +52 -0
  565. lfx/graph/graph/state_model.py +66 -0
  566. lfx/graph/graph/utils.py +1024 -0
  567. lfx/graph/schema.py +75 -0
  568. lfx/graph/state/__init__.py +0 -0
  569. lfx/graph/state/model.py +237 -0
  570. lfx/graph/utils.py +200 -0
  571. lfx/graph/vertex/__init__.py +0 -0
  572. lfx/graph/vertex/base.py +823 -0
  573. lfx/graph/vertex/constants.py +0 -0
  574. lfx/graph/vertex/exceptions.py +4 -0
  575. lfx/graph/vertex/param_handler.py +264 -0
  576. lfx/graph/vertex/schema.py +26 -0
  577. lfx/graph/vertex/utils.py +19 -0
  578. lfx/graph/vertex/vertex_types.py +489 -0
  579. lfx/helpers/__init__.py +1 -0
  580. lfx/helpers/base_model.py +71 -0
  581. lfx/helpers/custom.py +13 -0
  582. lfx/helpers/data.py +167 -0
  583. lfx/helpers/flow.py +194 -0
  584. lfx/inputs/__init__.py +68 -0
  585. lfx/inputs/constants.py +2 -0
  586. lfx/inputs/input_mixin.py +328 -0
  587. lfx/inputs/inputs.py +714 -0
  588. lfx/inputs/validators.py +19 -0
  589. lfx/interface/__init__.py +6 -0
  590. lfx/interface/components.py +489 -0
  591. lfx/interface/importing/__init__.py +5 -0
  592. lfx/interface/importing/utils.py +39 -0
  593. lfx/interface/initialize/__init__.py +3 -0
  594. lfx/interface/initialize/loading.py +224 -0
  595. lfx/interface/listing.py +26 -0
  596. lfx/interface/run.py +16 -0
  597. lfx/interface/utils.py +111 -0
  598. lfx/io/__init__.py +63 -0
  599. lfx/io/schema.py +289 -0
  600. lfx/load/__init__.py +8 -0
  601. lfx/load/load.py +256 -0
  602. lfx/load/utils.py +99 -0
  603. lfx/log/__init__.py +5 -0
  604. lfx/log/logger.py +385 -0
  605. lfx/memory/__init__.py +90 -0
  606. lfx/memory/stubs.py +283 -0
  607. lfx/processing/__init__.py +1 -0
  608. lfx/processing/process.py +238 -0
  609. lfx/processing/utils.py +25 -0
  610. lfx/py.typed +0 -0
  611. lfx/schema/__init__.py +66 -0
  612. lfx/schema/artifact.py +83 -0
  613. lfx/schema/content_block.py +62 -0
  614. lfx/schema/content_types.py +91 -0
  615. lfx/schema/data.py +308 -0
  616. lfx/schema/dataframe.py +210 -0
  617. lfx/schema/dotdict.py +74 -0
  618. lfx/schema/encoders.py +13 -0
  619. lfx/schema/graph.py +47 -0
  620. lfx/schema/image.py +131 -0
  621. lfx/schema/json_schema.py +141 -0
  622. lfx/schema/log.py +61 -0
  623. lfx/schema/message.py +473 -0
  624. lfx/schema/openai_responses_schemas.py +74 -0
  625. lfx/schema/properties.py +41 -0
  626. lfx/schema/schema.py +171 -0
  627. lfx/schema/serialize.py +13 -0
  628. lfx/schema/table.py +140 -0
  629. lfx/schema/validators.py +114 -0
  630. lfx/serialization/__init__.py +5 -0
  631. lfx/serialization/constants.py +2 -0
  632. lfx/serialization/serialization.py +314 -0
  633. lfx/services/__init__.py +23 -0
  634. lfx/services/base.py +28 -0
  635. lfx/services/cache/__init__.py +6 -0
  636. lfx/services/cache/base.py +183 -0
  637. lfx/services/cache/service.py +166 -0
  638. lfx/services/cache/utils.py +169 -0
  639. lfx/services/chat/__init__.py +1 -0
  640. lfx/services/chat/config.py +2 -0
  641. lfx/services/chat/schema.py +10 -0
  642. lfx/services/deps.py +129 -0
  643. lfx/services/factory.py +19 -0
  644. lfx/services/initialize.py +19 -0
  645. lfx/services/interfaces.py +103 -0
  646. lfx/services/manager.py +172 -0
  647. lfx/services/schema.py +20 -0
  648. lfx/services/session.py +82 -0
  649. lfx/services/settings/__init__.py +3 -0
  650. lfx/services/settings/auth.py +130 -0
  651. lfx/services/settings/base.py +539 -0
  652. lfx/services/settings/constants.py +31 -0
  653. lfx/services/settings/factory.py +23 -0
  654. lfx/services/settings/feature_flags.py +12 -0
  655. lfx/services/settings/service.py +35 -0
  656. lfx/services/settings/utils.py +40 -0
  657. lfx/services/shared_component_cache/__init__.py +1 -0
  658. lfx/services/shared_component_cache/factory.py +30 -0
  659. lfx/services/shared_component_cache/service.py +9 -0
  660. lfx/services/storage/__init__.py +5 -0
  661. lfx/services/storage/local.py +155 -0
  662. lfx/services/storage/service.py +54 -0
  663. lfx/services/tracing/__init__.py +1 -0
  664. lfx/services/tracing/service.py +21 -0
  665. lfx/settings.py +6 -0
  666. lfx/template/__init__.py +6 -0
  667. lfx/template/field/__init__.py +0 -0
  668. lfx/template/field/base.py +257 -0
  669. lfx/template/field/prompt.py +15 -0
  670. lfx/template/frontend_node/__init__.py +6 -0
  671. lfx/template/frontend_node/base.py +212 -0
  672. lfx/template/frontend_node/constants.py +65 -0
  673. lfx/template/frontend_node/custom_components.py +79 -0
  674. lfx/template/template/__init__.py +0 -0
  675. lfx/template/template/base.py +100 -0
  676. lfx/template/utils.py +217 -0
  677. lfx/type_extraction/__init__.py +19 -0
  678. lfx/type_extraction/type_extraction.py +75 -0
  679. lfx/type_extraction.py +80 -0
  680. lfx/utils/__init__.py +1 -0
  681. lfx/utils/async_helpers.py +42 -0
  682. lfx/utils/component_utils.py +154 -0
  683. lfx/utils/concurrency.py +60 -0
  684. lfx/utils/connection_string_parser.py +11 -0
  685. lfx/utils/constants.py +205 -0
  686. lfx/utils/data_structure.py +212 -0
  687. lfx/utils/exceptions.py +22 -0
  688. lfx/utils/helpers.py +28 -0
  689. lfx/utils/image.py +73 -0
  690. lfx/utils/lazy_load.py +15 -0
  691. lfx/utils/request_utils.py +18 -0
  692. lfx/utils/schemas.py +139 -0
  693. lfx/utils/util.py +481 -0
  694. lfx/utils/util_strings.py +56 -0
  695. lfx/utils/version.py +24 -0
  696. lfx_nightly-0.1.11.dev0.dist-info/METADATA +293 -0
  697. lfx_nightly-0.1.11.dev0.dist-info/RECORD +699 -0
  698. lfx_nightly-0.1.11.dev0.dist-info/WHEEL +4 -0
  699. lfx_nightly-0.1.11.dev0.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,501 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import uuid
5
+ from typing import Any
6
+
7
+ from langchain_core.tools import StructuredTool # noqa: TC002
8
+
9
+ from lfx.base.agents.utils import maybe_unflatten_dict, safe_cache_get, safe_cache_set
10
+ from lfx.base.mcp.util import MCPSseClient, MCPStdioClient, create_input_schema_from_json_schema, update_tools
11
+ from lfx.custom.custom_component.component_with_cache import ComponentWithCache
12
+ from lfx.inputs.inputs import InputTypes # noqa: TC001
13
+ from lfx.io import DropdownInput, McpInput, MessageTextInput, Output
14
+ from lfx.io.schema import flatten_schema, schema_to_langflow_inputs
15
+ from lfx.log.logger import logger
16
+ from lfx.schema.dataframe import DataFrame
17
+ from lfx.schema.message import Message
18
+ from lfx.services.deps import get_settings_service, get_storage_service, session_scope
19
+
20
+
21
+ class MCPToolsComponent(ComponentWithCache):
22
+ schema_inputs: list = []
23
+ tools: list[StructuredTool] = []
24
+ _not_load_actions: bool = False
25
+ _tool_cache: dict = {}
26
+ _last_selected_server: str | None = None # Cache for the last selected server
27
+
28
+ def __init__(self, **data) -> None:
29
+ super().__init__(**data)
30
+ # Initialize cache keys to avoid CacheMiss when accessing them
31
+ self._ensure_cache_structure()
32
+
33
+ # Initialize clients with access to the component cache
34
+ self.stdio_client: MCPStdioClient = MCPStdioClient(component_cache=self._shared_component_cache)
35
+ self.sse_client: MCPSseClient = MCPSseClient(component_cache=self._shared_component_cache)
36
+
37
+ def _ensure_cache_structure(self):
38
+ """Ensure the cache has the required structure."""
39
+ # Check if servers key exists and is not CacheMiss
40
+ servers_value = safe_cache_get(self._shared_component_cache, "servers")
41
+ if servers_value is None:
42
+ safe_cache_set(self._shared_component_cache, "servers", {})
43
+
44
+ # Check if last_selected_server key exists and is not CacheMiss
45
+ last_server_value = safe_cache_get(self._shared_component_cache, "last_selected_server")
46
+ if last_server_value is None:
47
+ safe_cache_set(self._shared_component_cache, "last_selected_server", "")
48
+
49
+ default_keys: list[str] = [
50
+ "code",
51
+ "_type",
52
+ "tool_mode",
53
+ "tool_placeholder",
54
+ "mcp_server",
55
+ "tool",
56
+ ]
57
+
58
+ display_name = "MCP Tools"
59
+ description = "Connect to an MCP server to use its tools."
60
+ documentation: str = "https://docs.langflow.org/mcp-client"
61
+ icon = "Mcp"
62
+ name = "MCPTools"
63
+
64
+ inputs = [
65
+ McpInput(
66
+ name="mcp_server",
67
+ display_name="MCP Server",
68
+ info="Select the MCP Server that will be used by this component",
69
+ real_time_refresh=True,
70
+ ),
71
+ DropdownInput(
72
+ name="tool",
73
+ display_name="Tool",
74
+ options=[],
75
+ value="",
76
+ info="Select the tool to execute",
77
+ show=False,
78
+ required=True,
79
+ real_time_refresh=True,
80
+ ),
81
+ MessageTextInput(
82
+ name="tool_placeholder",
83
+ display_name="Tool Placeholder",
84
+ info="Placeholder for the tool",
85
+ value="",
86
+ show=False,
87
+ tool_mode=False,
88
+ ),
89
+ ]
90
+
91
+ outputs = [
92
+ Output(display_name="Response", name="response", method="build_output"),
93
+ ]
94
+
95
+ async def _validate_schema_inputs(self, tool_obj) -> list[InputTypes]:
96
+ """Validate and process schema inputs for a tool."""
97
+ try:
98
+ if not tool_obj or not hasattr(tool_obj, "args_schema"):
99
+ msg = "Invalid tool object or missing input schema"
100
+ raise ValueError(msg)
101
+
102
+ flat_schema = flatten_schema(tool_obj.args_schema.schema())
103
+ input_schema = create_input_schema_from_json_schema(flat_schema)
104
+ if not input_schema:
105
+ msg = f"Empty input schema for tool '{tool_obj.name}'"
106
+ raise ValueError(msg)
107
+
108
+ schema_inputs = schema_to_langflow_inputs(input_schema)
109
+ if not schema_inputs:
110
+ msg = f"No input parameters defined for tool '{tool_obj.name}'"
111
+ await logger.awarning(msg)
112
+ return []
113
+
114
+ except Exception as e:
115
+ msg = f"Error validating schema inputs: {e!s}"
116
+ await logger.aexception(msg)
117
+ raise ValueError(msg) from e
118
+ else:
119
+ return schema_inputs
120
+
121
+ async def update_tool_list(self, mcp_server_value=None):
122
+ # Accepts mcp_server_value as dict {name, config} or uses self.mcp_server
123
+ mcp_server = mcp_server_value if mcp_server_value is not None else getattr(self, "mcp_server", None)
124
+ server_name = None
125
+ server_config_from_value = None
126
+ if isinstance(mcp_server, dict):
127
+ server_name = mcp_server.get("name")
128
+ server_config_from_value = mcp_server.get("config")
129
+ else:
130
+ server_name = mcp_server
131
+ if not server_name:
132
+ self.tools = []
133
+ return [], {"name": server_name, "config": server_config_from_value}
134
+
135
+ # Use shared cache if available
136
+ servers_cache = safe_cache_get(self._shared_component_cache, "servers", {})
137
+ cached = servers_cache.get(server_name) if isinstance(servers_cache, dict) else None
138
+
139
+ if cached is not None:
140
+ self.tools = cached["tools"]
141
+ self.tool_names = cached["tool_names"]
142
+ self._tool_cache = cached["tool_cache"]
143
+ server_config_from_value = cached["config"]
144
+ return self.tools, {"name": server_name, "config": server_config_from_value}
145
+
146
+ try:
147
+ try:
148
+ from langflow.api.v2.mcp import get_server
149
+ from langflow.services.database.models.user.crud import get_user_by_id
150
+ except ImportError as e:
151
+ msg = (
152
+ "Langflow MCP server functionality is not available. "
153
+ "This feature requires the full Langflow installation."
154
+ )
155
+ raise ImportError(msg) from e
156
+ async with session_scope() as db:
157
+ if not self.user_id:
158
+ msg = "User ID is required for fetching MCP tools."
159
+ raise ValueError(msg)
160
+ current_user = await get_user_by_id(db, self.user_id)
161
+
162
+ # Try to get server config from DB/API
163
+ server_config = await get_server(
164
+ server_name,
165
+ current_user,
166
+ db,
167
+ storage_service=get_storage_service(),
168
+ settings_service=get_settings_service(),
169
+ )
170
+
171
+ # If get_server returns empty but we have a config, use it
172
+ if not server_config and server_config_from_value:
173
+ server_config = server_config_from_value
174
+
175
+ if not server_config:
176
+ self.tools = []
177
+ return [], {"name": server_name, "config": server_config}
178
+
179
+ _, tool_list, tool_cache = await update_tools(
180
+ server_name=server_name,
181
+ server_config=server_config,
182
+ mcp_stdio_client=self.stdio_client,
183
+ mcp_sse_client=self.sse_client,
184
+ )
185
+
186
+ self.tool_names = [tool.name for tool in tool_list if hasattr(tool, "name")]
187
+ self._tool_cache = tool_cache
188
+ self.tools = tool_list
189
+ # Cache the result using shared cache
190
+ cache_data = {
191
+ "tools": tool_list,
192
+ "tool_names": self.tool_names,
193
+ "tool_cache": tool_cache,
194
+ "config": server_config,
195
+ }
196
+
197
+ # Safely update the servers cache
198
+ current_servers_cache = safe_cache_get(self._shared_component_cache, "servers", {})
199
+ if isinstance(current_servers_cache, dict):
200
+ current_servers_cache[server_name] = cache_data
201
+ safe_cache_set(self._shared_component_cache, "servers", current_servers_cache)
202
+
203
+ except (TimeoutError, asyncio.TimeoutError) as e:
204
+ msg = f"Timeout updating tool list: {e!s}"
205
+ await logger.aexception(msg)
206
+ raise TimeoutError(msg) from e
207
+ except Exception as e:
208
+ msg = f"Error updating tool list: {e!s}"
209
+ await logger.aexception(msg)
210
+ raise ValueError(msg) from e
211
+ else:
212
+ return tool_list, {"name": server_name, "config": server_config}
213
+
214
+ async def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None) -> dict:
215
+ """Toggle the visibility of connection-specific fields based on the selected mode."""
216
+ try:
217
+ if field_name == "tool":
218
+ try:
219
+ if len(self.tools) == 0:
220
+ try:
221
+ self.tools, build_config["mcp_server"]["value"] = await self.update_tool_list()
222
+ build_config["tool"]["options"] = [tool.name for tool in self.tools]
223
+ build_config["tool"]["placeholder"] = "Select a tool"
224
+ except (TimeoutError, asyncio.TimeoutError) as e:
225
+ msg = f"Timeout updating tool list: {e!s}"
226
+ await logger.aexception(msg)
227
+ if not build_config["tools_metadata"]["show"]:
228
+ build_config["tool"]["show"] = True
229
+ build_config["tool"]["options"] = []
230
+ build_config["tool"]["value"] = ""
231
+ build_config["tool"]["placeholder"] = "Timeout on MCP server"
232
+ else:
233
+ build_config["tool"]["show"] = False
234
+ except ValueError:
235
+ if not build_config["tools_metadata"]["show"]:
236
+ build_config["tool"]["show"] = True
237
+ build_config["tool"]["options"] = []
238
+ build_config["tool"]["value"] = ""
239
+ build_config["tool"]["placeholder"] = "Error on MCP Server"
240
+ else:
241
+ build_config["tool"]["show"] = False
242
+
243
+ if field_value == "":
244
+ return build_config
245
+ tool_obj = None
246
+ for tool in self.tools:
247
+ if tool.name == field_value:
248
+ tool_obj = tool
249
+ break
250
+ if tool_obj is None:
251
+ msg = f"Tool {field_value} not found in available tools: {self.tools}"
252
+ await logger.awarning(msg)
253
+ return build_config
254
+ await self._update_tool_config(build_config, field_value)
255
+ except Exception as e:
256
+ build_config["tool"]["options"] = []
257
+ msg = f"Failed to update tools: {e!s}"
258
+ raise ValueError(msg) from e
259
+ else:
260
+ return build_config
261
+ elif field_name == "mcp_server":
262
+ if not field_value:
263
+ build_config["tool"]["show"] = False
264
+ build_config["tool"]["options"] = []
265
+ build_config["tool"]["value"] = ""
266
+ build_config["tool"]["placeholder"] = ""
267
+ build_config["tool_placeholder"]["tool_mode"] = False
268
+ self.remove_non_default_keys(build_config)
269
+ return build_config
270
+
271
+ build_config["tool_placeholder"]["tool_mode"] = True
272
+
273
+ current_server_name = field_value.get("name") if isinstance(field_value, dict) else field_value
274
+ _last_selected_server = safe_cache_get(self._shared_component_cache, "last_selected_server", "")
275
+
276
+ # To avoid unnecessary updates, only proceed if the server has actually changed
277
+ if (_last_selected_server in (current_server_name, "")) and build_config["tool"]["show"]:
278
+ return build_config
279
+
280
+ # Determine if "Tool Mode" is active by checking if the tool dropdown is hidden.
281
+ is_in_tool_mode = build_config["tools_metadata"]["show"]
282
+ safe_cache_set(self._shared_component_cache, "last_selected_server", current_server_name)
283
+
284
+ # Check if tools are already cached for this server before clearing
285
+ cached_tools = None
286
+ if current_server_name:
287
+ servers_cache = safe_cache_get(self._shared_component_cache, "servers", {})
288
+ if isinstance(servers_cache, dict):
289
+ cached = servers_cache.get(current_server_name)
290
+ if cached is not None:
291
+ cached_tools = cached["tools"]
292
+ self.tools = cached_tools
293
+ self.tool_names = cached["tool_names"]
294
+ self._tool_cache = cached["tool_cache"]
295
+
296
+ # Only clear tools if we don't have cached tools for the current server
297
+ if not cached_tools:
298
+ self.tools = [] # Clear previous tools only if no cache
299
+
300
+ self.remove_non_default_keys(build_config) # Clear previous tool inputs
301
+
302
+ # Only show the tool dropdown if not in tool_mode
303
+ if not is_in_tool_mode:
304
+ build_config["tool"]["show"] = True
305
+ if cached_tools:
306
+ # Use cached tools to populate options immediately
307
+ build_config["tool"]["options"] = [tool.name for tool in cached_tools]
308
+ build_config["tool"]["placeholder"] = "Select a tool"
309
+ else:
310
+ # Show loading state only when we need to fetch tools
311
+ build_config["tool"]["placeholder"] = "Loading tools..."
312
+ build_config["tool"]["options"] = []
313
+ build_config["tool"]["value"] = uuid.uuid4()
314
+ else:
315
+ # Keep the tool dropdown hidden if in tool_mode
316
+ self._not_load_actions = True
317
+ build_config["tool"]["show"] = False
318
+
319
+ elif field_name == "tool_mode":
320
+ build_config["tool"]["placeholder"] = ""
321
+ build_config["tool"]["show"] = not bool(field_value) and bool(build_config["mcp_server"])
322
+ self.remove_non_default_keys(build_config)
323
+ self.tool = build_config["tool"]["value"]
324
+ if field_value:
325
+ self._not_load_actions = True
326
+ else:
327
+ build_config["tool"]["value"] = uuid.uuid4()
328
+ build_config["tool"]["options"] = []
329
+ build_config["tool"]["show"] = True
330
+ build_config["tool"]["placeholder"] = "Loading tools..."
331
+ elif field_name == "tools_metadata":
332
+ self._not_load_actions = False
333
+
334
+ except Exception as e:
335
+ msg = f"Error in update_build_config: {e!s}"
336
+ await logger.aexception(msg)
337
+ raise ValueError(msg) from e
338
+ else:
339
+ return build_config
340
+
341
+ def get_inputs_for_all_tools(self, tools: list) -> dict:
342
+ """Get input schemas for all tools."""
343
+ inputs = {}
344
+ for tool in tools:
345
+ if not tool or not hasattr(tool, "name"):
346
+ continue
347
+ try:
348
+ flat_schema = flatten_schema(tool.args_schema.schema())
349
+ input_schema = create_input_schema_from_json_schema(flat_schema)
350
+ langflow_inputs = schema_to_langflow_inputs(input_schema)
351
+ inputs[tool.name] = langflow_inputs
352
+ except (AttributeError, ValueError, TypeError, KeyError) as e:
353
+ msg = f"Error getting inputs for tool {getattr(tool, 'name', 'unknown')}: {e!s}"
354
+ logger.exception(msg)
355
+ continue
356
+ return inputs
357
+
358
+ def remove_input_schema_from_build_config(
359
+ self, build_config: dict, tool_name: str, input_schema: dict[list[InputTypes], Any]
360
+ ):
361
+ """Remove the input schema for the tool from the build config."""
362
+ # Keep only schemas that don't belong to the current tool
363
+ input_schema = {k: v for k, v in input_schema.items() if k != tool_name}
364
+ # Remove all inputs from other tools
365
+ for value in input_schema.values():
366
+ for _input in value:
367
+ if _input.name in build_config:
368
+ build_config.pop(_input.name)
369
+
370
+ def remove_non_default_keys(self, build_config: dict) -> None:
371
+ """Remove non-default keys from the build config."""
372
+ for key in list(build_config.keys()):
373
+ if key not in self.default_keys:
374
+ build_config.pop(key)
375
+
376
+ async def _update_tool_config(self, build_config: dict, tool_name: str) -> None:
377
+ """Update tool configuration with proper error handling."""
378
+ if not self.tools:
379
+ self.tools, build_config["mcp_server"]["value"] = await self.update_tool_list()
380
+
381
+ if not tool_name:
382
+ return
383
+
384
+ tool_obj = next((tool for tool in self.tools if tool.name == tool_name), None)
385
+ if not tool_obj:
386
+ msg = f"Tool {tool_name} not found in available tools: {self.tools}"
387
+ self.remove_non_default_keys(build_config)
388
+ build_config["tool"]["value"] = ""
389
+ await logger.awarning(msg)
390
+ return
391
+
392
+ try:
393
+ # Store current values before removing inputs
394
+ current_values = {}
395
+ for key, value in build_config.items():
396
+ if key not in self.default_keys and isinstance(value, dict) and "value" in value:
397
+ current_values[key] = value["value"]
398
+
399
+ # Get all tool inputs and remove old ones
400
+ input_schema_for_all_tools = self.get_inputs_for_all_tools(self.tools)
401
+ self.remove_input_schema_from_build_config(build_config, tool_name, input_schema_for_all_tools)
402
+
403
+ # Get and validate new inputs
404
+ self.schema_inputs = await self._validate_schema_inputs(tool_obj)
405
+ if not self.schema_inputs:
406
+ msg = f"No input parameters to configure for tool '{tool_name}'"
407
+ await logger.ainfo(msg)
408
+ return
409
+
410
+ # Add new inputs to build config
411
+ for schema_input in self.schema_inputs:
412
+ if not schema_input or not hasattr(schema_input, "name"):
413
+ msg = "Invalid schema input detected, skipping"
414
+ await logger.awarning(msg)
415
+ continue
416
+
417
+ try:
418
+ name = schema_input.name
419
+ input_dict = schema_input.to_dict()
420
+ input_dict.setdefault("value", None)
421
+ input_dict.setdefault("required", True)
422
+
423
+ build_config[name] = input_dict
424
+
425
+ # Preserve existing value if the parameter name exists in current_values
426
+ if name in current_values:
427
+ build_config[name]["value"] = current_values[name]
428
+
429
+ except (AttributeError, KeyError, TypeError) as e:
430
+ msg = f"Error processing schema input {schema_input}: {e!s}"
431
+ await logger.aexception(msg)
432
+ continue
433
+ except ValueError as e:
434
+ msg = f"Schema validation error for tool {tool_name}: {e!s}"
435
+ await logger.aexception(msg)
436
+ self.schema_inputs = []
437
+ return
438
+ except (AttributeError, KeyError, TypeError) as e:
439
+ msg = f"Error updating tool config: {e!s}"
440
+ await logger.aexception(msg)
441
+ raise ValueError(msg) from e
442
+
443
+ async def build_output(self) -> DataFrame:
444
+ """Build output with improved error handling and validation."""
445
+ try:
446
+ self.tools, _ = await self.update_tool_list()
447
+ if self.tool != "":
448
+ # Set session context for persistent MCP sessions using Langflow session ID
449
+ session_context = self._get_session_context()
450
+ if session_context:
451
+ self.stdio_client.set_session_context(session_context)
452
+ self.sse_client.set_session_context(session_context)
453
+
454
+ exec_tool = self._tool_cache[self.tool]
455
+ tool_args = self.get_inputs_for_all_tools(self.tools)[self.tool]
456
+ kwargs = {}
457
+ for arg in tool_args:
458
+ value = getattr(self, arg.name, None)
459
+ if value is not None:
460
+ if isinstance(value, Message):
461
+ kwargs[arg.name] = value.text
462
+ else:
463
+ kwargs[arg.name] = value
464
+
465
+ unflattened_kwargs = maybe_unflatten_dict(kwargs)
466
+
467
+ output = await exec_tool.coroutine(**unflattened_kwargs)
468
+
469
+ tool_content = []
470
+ for item in output.content:
471
+ item_dict = item.model_dump()
472
+ tool_content.append(item_dict)
473
+ return DataFrame(data=tool_content)
474
+ return DataFrame(data=[{"error": "You must select a tool"}])
475
+ except Exception as e:
476
+ msg = f"Error in build_output: {e!s}"
477
+ await logger.aexception(msg)
478
+ raise ValueError(msg) from e
479
+
480
+ def _get_session_context(self) -> str | None:
481
+ """Get the Langflow session ID for MCP session caching."""
482
+ # Try to get session ID from the component's execution context
483
+ if hasattr(self, "graph") and hasattr(self.graph, "session_id"):
484
+ session_id = self.graph.session_id
485
+ # Include server name to ensure different servers get different sessions
486
+ server_name = ""
487
+ mcp_server = getattr(self, "mcp_server", None)
488
+ if isinstance(mcp_server, dict):
489
+ server_name = mcp_server.get("name", "")
490
+ elif mcp_server:
491
+ server_name = str(mcp_server)
492
+ return f"{session_id}_{server_name}" if session_id else None
493
+ return None
494
+
495
+ async def _get_tools(self):
496
+ """Get cached tools or update if necessary."""
497
+ mcp_server = getattr(self, "mcp_server", None)
498
+ if not self._not_load_actions:
499
+ tools, _ = await self.update_tool_list(mcp_server)
500
+ return tools
501
+ return []
@@ -0,0 +1,37 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from lfx.components._importing import import_mod
6
+
7
+ if TYPE_CHECKING:
8
+ from lfx.components.aiml.aiml import AIMLModelComponent
9
+ from lfx.components.aiml.aiml_embeddings import AIMLEmbeddingsComponent
10
+
11
+ _dynamic_imports = {
12
+ "AIMLModelComponent": "aiml",
13
+ "AIMLEmbeddingsComponent": "aiml_embeddings",
14
+ }
15
+
16
+ __all__ = [
17
+ "AIMLEmbeddingsComponent",
18
+ "AIMLModelComponent",
19
+ ]
20
+
21
+
22
+ def __getattr__(attr_name: str) -> Any:
23
+ """Lazily import aiml components on attribute access."""
24
+ if attr_name not in _dynamic_imports:
25
+ msg = f"module '{__name__}' has no attribute '{attr_name}'"
26
+ raise AttributeError(msg)
27
+ try:
28
+ result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
29
+ except (ModuleNotFoundError, ImportError, AttributeError) as e:
30
+ msg = f"Could not import '{attr_name}' from '{__name__}': {e}"
31
+ raise AttributeError(msg) from e
32
+ globals()[attr_name] = result
33
+ return result
34
+
35
+
36
+ def __dir__() -> list[str]:
37
+ return list(__all__)
@@ -0,0 +1,112 @@
1
+ from langchain_openai import ChatOpenAI
2
+ from pydantic.v1 import SecretStr
3
+ from typing_extensions import override
4
+
5
+ from lfx.base.models.aiml_constants import AimlModels
6
+ from lfx.base.models.model import LCModelComponent
7
+ from lfx.field_typing import LanguageModel
8
+ from lfx.field_typing.range_spec import RangeSpec
9
+ from lfx.inputs.inputs import (
10
+ DictInput,
11
+ DropdownInput,
12
+ IntInput,
13
+ SecretStrInput,
14
+ SliderInput,
15
+ StrInput,
16
+ )
17
+
18
+
19
+ class AIMLModelComponent(LCModelComponent):
20
+ display_name = "AI/ML API"
21
+ description = "Generates text using AI/ML API LLMs."
22
+ icon = "AIML"
23
+ name = "AIMLModel"
24
+ documentation = "https://docs.aimlapi.com/api-reference"
25
+
26
+ inputs = [
27
+ *LCModelComponent.get_base_inputs(),
28
+ IntInput(
29
+ name="max_tokens",
30
+ display_name="Max Tokens",
31
+ advanced=True,
32
+ info="The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
33
+ range_spec=RangeSpec(min=0, max=128000),
34
+ ),
35
+ DictInput(name="model_kwargs", display_name="Model Kwargs", advanced=True),
36
+ DropdownInput(
37
+ name="model_name",
38
+ display_name="Model Name",
39
+ advanced=False,
40
+ options=[],
41
+ refresh_button=True,
42
+ ),
43
+ StrInput(
44
+ name="aiml_api_base",
45
+ display_name="AI/ML API Base",
46
+ advanced=True,
47
+ info="The base URL of the API. Defaults to https://api.aimlapi.com . "
48
+ "You can change this to use other APIs like JinaChat, LocalAI and Prem.",
49
+ ),
50
+ SecretStrInput(
51
+ name="api_key",
52
+ display_name="AI/ML API Key",
53
+ info="The AI/ML API Key to use for the OpenAI model.",
54
+ advanced=False,
55
+ value="AIML_API_KEY",
56
+ required=True,
57
+ ),
58
+ SliderInput(
59
+ name="temperature", display_name="Temperature", value=0.1, range_spec=RangeSpec(min=0, max=2, step=0.01)
60
+ ),
61
+ ]
62
+
63
+ @override
64
+ def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None):
65
+ if field_name in {"api_key", "aiml_api_base", "model_name"}:
66
+ aiml = AimlModels()
67
+ aiml.get_aiml_models()
68
+ build_config["model_name"]["options"] = aiml.chat_models
69
+ return build_config
70
+
71
+ def build_model(self) -> LanguageModel: # type: ignore[type-var]
72
+ aiml_api_key = self.api_key
73
+ temperature = self.temperature
74
+ model_name: str = self.model_name
75
+ max_tokens = self.max_tokens
76
+ model_kwargs = self.model_kwargs or {}
77
+ aiml_api_base = self.aiml_api_base or "https://api.aimlapi.com/v2"
78
+
79
+ openai_api_key = aiml_api_key.get_secret_value() if isinstance(aiml_api_key, SecretStr) else aiml_api_key
80
+
81
+ # TODO: Once OpenAI fixes their o1 models, this part will need to be removed
82
+ # to work correctly with o1 temperature settings.
83
+ if "o1" in model_name:
84
+ temperature = 1
85
+
86
+ return ChatOpenAI(
87
+ model=model_name,
88
+ temperature=temperature,
89
+ api_key=openai_api_key,
90
+ base_url=aiml_api_base,
91
+ max_tokens=max_tokens or None,
92
+ **model_kwargs,
93
+ )
94
+
95
+ def _get_exception_message(self, e: Exception):
96
+ """Get a message from an OpenAI exception.
97
+
98
+ Args:
99
+ e (Exception): The exception to get the message from.
100
+
101
+ Returns:
102
+ str: The message from the exception.
103
+ """
104
+ try:
105
+ from openai.error import BadRequestError
106
+ except ImportError:
107
+ return None
108
+ if isinstance(e, BadRequestError):
109
+ message = e.json_body.get("error", {}).get("message", "")
110
+ if message:
111
+ return message
112
+ return None
@@ -0,0 +1,37 @@
1
+ from lfx.base.embeddings.aiml_embeddings import AIMLEmbeddingsImpl
2
+ from lfx.base.embeddings.model import LCEmbeddingsModel
3
+ from lfx.field_typing import Embeddings
4
+ from lfx.inputs.inputs import DropdownInput
5
+ from lfx.io import SecretStrInput
6
+
7
+
8
+ class AIMLEmbeddingsComponent(LCEmbeddingsModel):
9
+ display_name = "AI/ML API Embeddings"
10
+ description = "Generate embeddings using the AI/ML API."
11
+ icon = "AIML"
12
+ name = "AIMLEmbeddings"
13
+
14
+ inputs = [
15
+ DropdownInput(
16
+ name="model_name",
17
+ display_name="Model Name",
18
+ options=[
19
+ "text-embedding-3-small",
20
+ "text-embedding-3-large",
21
+ "text-embedding-ada-002",
22
+ ],
23
+ required=True,
24
+ ),
25
+ SecretStrInput(
26
+ name="aiml_api_key",
27
+ display_name="AI/ML API Key",
28
+ value="AIML_API_KEY",
29
+ required=True,
30
+ ),
31
+ ]
32
+
33
+ def build_embeddings(self) -> Embeddings:
34
+ return AIMLEmbeddingsImpl(
35
+ api_key=self.aiml_api_key,
36
+ model=self.model_name,
37
+ )