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.

Files changed (769) hide show
  1. lfx/__init__.py +0 -0
  2. lfx/__main__.py +25 -0
  3. lfx/_assets/component_index.json +1 -0
  4. lfx/base/__init__.py +0 -0
  5. lfx/base/agents/__init__.py +0 -0
  6. lfx/base/agents/agent.py +375 -0
  7. lfx/base/agents/altk_base_agent.py +380 -0
  8. lfx/base/agents/altk_tool_wrappers.py +565 -0
  9. lfx/base/agents/callback.py +130 -0
  10. lfx/base/agents/context.py +109 -0
  11. lfx/base/agents/crewai/__init__.py +0 -0
  12. lfx/base/agents/crewai/crew.py +231 -0
  13. lfx/base/agents/crewai/tasks.py +12 -0
  14. lfx/base/agents/default_prompts.py +23 -0
  15. lfx/base/agents/errors.py +15 -0
  16. lfx/base/agents/events.py +430 -0
  17. lfx/base/agents/utils.py +237 -0
  18. lfx/base/astra_assistants/__init__.py +0 -0
  19. lfx/base/astra_assistants/util.py +171 -0
  20. lfx/base/chains/__init__.py +0 -0
  21. lfx/base/chains/model.py +19 -0
  22. lfx/base/composio/__init__.py +0 -0
  23. lfx/base/composio/composio_base.py +2584 -0
  24. lfx/base/compressors/__init__.py +0 -0
  25. lfx/base/compressors/model.py +60 -0
  26. lfx/base/constants.py +46 -0
  27. lfx/base/curl/__init__.py +0 -0
  28. lfx/base/curl/parse.py +188 -0
  29. lfx/base/data/__init__.py +5 -0
  30. lfx/base/data/base_file.py +810 -0
  31. lfx/base/data/docling_utils.py +338 -0
  32. lfx/base/data/storage_utils.py +192 -0
  33. lfx/base/data/utils.py +362 -0
  34. lfx/base/datastax/__init__.py +5 -0
  35. lfx/base/datastax/astradb_base.py +896 -0
  36. lfx/base/document_transformers/__init__.py +0 -0
  37. lfx/base/document_transformers/model.py +43 -0
  38. lfx/base/embeddings/__init__.py +0 -0
  39. lfx/base/embeddings/aiml_embeddings.py +62 -0
  40. lfx/base/embeddings/embeddings_class.py +113 -0
  41. lfx/base/embeddings/model.py +26 -0
  42. lfx/base/flow_processing/__init__.py +0 -0
  43. lfx/base/flow_processing/utils.py +86 -0
  44. lfx/base/huggingface/__init__.py +0 -0
  45. lfx/base/huggingface/model_bridge.py +133 -0
  46. lfx/base/io/__init__.py +0 -0
  47. lfx/base/io/chat.py +21 -0
  48. lfx/base/io/text.py +22 -0
  49. lfx/base/knowledge_bases/__init__.py +3 -0
  50. lfx/base/knowledge_bases/knowledge_base_utils.py +137 -0
  51. lfx/base/langchain_utilities/__init__.py +0 -0
  52. lfx/base/langchain_utilities/model.py +35 -0
  53. lfx/base/langchain_utilities/spider_constants.py +1 -0
  54. lfx/base/langwatch/__init__.py +0 -0
  55. lfx/base/langwatch/utils.py +18 -0
  56. lfx/base/mcp/__init__.py +0 -0
  57. lfx/base/mcp/constants.py +2 -0
  58. lfx/base/mcp/util.py +1659 -0
  59. lfx/base/memory/__init__.py +0 -0
  60. lfx/base/memory/memory.py +49 -0
  61. lfx/base/memory/model.py +38 -0
  62. lfx/base/models/__init__.py +3 -0
  63. lfx/base/models/aiml_constants.py +51 -0
  64. lfx/base/models/anthropic_constants.py +51 -0
  65. lfx/base/models/aws_constants.py +151 -0
  66. lfx/base/models/chat_result.py +76 -0
  67. lfx/base/models/cometapi_constants.py +54 -0
  68. lfx/base/models/google_generative_ai_constants.py +70 -0
  69. lfx/base/models/google_generative_ai_model.py +38 -0
  70. lfx/base/models/groq_constants.py +150 -0
  71. lfx/base/models/groq_model_discovery.py +265 -0
  72. lfx/base/models/model.py +375 -0
  73. lfx/base/models/model_input_constants.py +378 -0
  74. lfx/base/models/model_metadata.py +41 -0
  75. lfx/base/models/model_utils.py +108 -0
  76. lfx/base/models/novita_constants.py +35 -0
  77. lfx/base/models/ollama_constants.py +52 -0
  78. lfx/base/models/openai_constants.py +129 -0
  79. lfx/base/models/sambanova_constants.py +18 -0
  80. lfx/base/models/watsonx_constants.py +36 -0
  81. lfx/base/processing/__init__.py +0 -0
  82. lfx/base/prompts/__init__.py +0 -0
  83. lfx/base/prompts/api_utils.py +224 -0
  84. lfx/base/prompts/utils.py +61 -0
  85. lfx/base/textsplitters/__init__.py +0 -0
  86. lfx/base/textsplitters/model.py +28 -0
  87. lfx/base/tools/__init__.py +0 -0
  88. lfx/base/tools/base.py +26 -0
  89. lfx/base/tools/component_tool.py +325 -0
  90. lfx/base/tools/constants.py +49 -0
  91. lfx/base/tools/flow_tool.py +132 -0
  92. lfx/base/tools/run_flow.py +698 -0
  93. lfx/base/vectorstores/__init__.py +0 -0
  94. lfx/base/vectorstores/model.py +193 -0
  95. lfx/base/vectorstores/utils.py +22 -0
  96. lfx/base/vectorstores/vector_store_connection_decorator.py +52 -0
  97. lfx/cli/__init__.py +5 -0
  98. lfx/cli/commands.py +327 -0
  99. lfx/cli/common.py +650 -0
  100. lfx/cli/run.py +506 -0
  101. lfx/cli/script_loader.py +289 -0
  102. lfx/cli/serve_app.py +546 -0
  103. lfx/cli/validation.py +69 -0
  104. lfx/components/FAISS/__init__.py +34 -0
  105. lfx/components/FAISS/faiss.py +111 -0
  106. lfx/components/Notion/__init__.py +19 -0
  107. lfx/components/Notion/add_content_to_page.py +269 -0
  108. lfx/components/Notion/create_page.py +94 -0
  109. lfx/components/Notion/list_database_properties.py +68 -0
  110. lfx/components/Notion/list_pages.py +122 -0
  111. lfx/components/Notion/list_users.py +77 -0
  112. lfx/components/Notion/page_content_viewer.py +93 -0
  113. lfx/components/Notion/search.py +111 -0
  114. lfx/components/Notion/update_page_property.py +114 -0
  115. lfx/components/__init__.py +428 -0
  116. lfx/components/_importing.py +42 -0
  117. lfx/components/agentql/__init__.py +3 -0
  118. lfx/components/agentql/agentql_api.py +151 -0
  119. lfx/components/aiml/__init__.py +37 -0
  120. lfx/components/aiml/aiml.py +115 -0
  121. lfx/components/aiml/aiml_embeddings.py +37 -0
  122. lfx/components/altk/__init__.py +34 -0
  123. lfx/components/altk/altk_agent.py +193 -0
  124. lfx/components/amazon/__init__.py +36 -0
  125. lfx/components/amazon/amazon_bedrock_converse.py +195 -0
  126. lfx/components/amazon/amazon_bedrock_embedding.py +109 -0
  127. lfx/components/amazon/amazon_bedrock_model.py +130 -0
  128. lfx/components/amazon/s3_bucket_uploader.py +211 -0
  129. lfx/components/anthropic/__init__.py +34 -0
  130. lfx/components/anthropic/anthropic.py +187 -0
  131. lfx/components/apify/__init__.py +5 -0
  132. lfx/components/apify/apify_actor.py +325 -0
  133. lfx/components/arxiv/__init__.py +3 -0
  134. lfx/components/arxiv/arxiv.py +169 -0
  135. lfx/components/assemblyai/__init__.py +46 -0
  136. lfx/components/assemblyai/assemblyai_get_subtitles.py +83 -0
  137. lfx/components/assemblyai/assemblyai_lemur.py +183 -0
  138. lfx/components/assemblyai/assemblyai_list_transcripts.py +95 -0
  139. lfx/components/assemblyai/assemblyai_poll_transcript.py +72 -0
  140. lfx/components/assemblyai/assemblyai_start_transcript.py +188 -0
  141. lfx/components/azure/__init__.py +37 -0
  142. lfx/components/azure/azure_openai.py +95 -0
  143. lfx/components/azure/azure_openai_embeddings.py +83 -0
  144. lfx/components/baidu/__init__.py +32 -0
  145. lfx/components/baidu/baidu_qianfan_chat.py +113 -0
  146. lfx/components/bing/__init__.py +3 -0
  147. lfx/components/bing/bing_search_api.py +61 -0
  148. lfx/components/cassandra/__init__.py +40 -0
  149. lfx/components/cassandra/cassandra.py +264 -0
  150. lfx/components/cassandra/cassandra_chat.py +92 -0
  151. lfx/components/cassandra/cassandra_graph.py +238 -0
  152. lfx/components/chains/__init__.py +3 -0
  153. lfx/components/chroma/__init__.py +34 -0
  154. lfx/components/chroma/chroma.py +169 -0
  155. lfx/components/cleanlab/__init__.py +40 -0
  156. lfx/components/cleanlab/cleanlab_evaluator.py +155 -0
  157. lfx/components/cleanlab/cleanlab_rag_evaluator.py +254 -0
  158. lfx/components/cleanlab/cleanlab_remediator.py +131 -0
  159. lfx/components/clickhouse/__init__.py +34 -0
  160. lfx/components/clickhouse/clickhouse.py +135 -0
  161. lfx/components/cloudflare/__init__.py +32 -0
  162. lfx/components/cloudflare/cloudflare.py +81 -0
  163. lfx/components/cohere/__init__.py +40 -0
  164. lfx/components/cohere/cohere_embeddings.py +81 -0
  165. lfx/components/cohere/cohere_models.py +46 -0
  166. lfx/components/cohere/cohere_rerank.py +51 -0
  167. lfx/components/cometapi/__init__.py +32 -0
  168. lfx/components/cometapi/cometapi.py +166 -0
  169. lfx/components/composio/__init__.py +222 -0
  170. lfx/components/composio/agentql_composio.py +11 -0
  171. lfx/components/composio/agiled_composio.py +11 -0
  172. lfx/components/composio/airtable_composio.py +11 -0
  173. lfx/components/composio/apollo_composio.py +11 -0
  174. lfx/components/composio/asana_composio.py +11 -0
  175. lfx/components/composio/attio_composio.py +11 -0
  176. lfx/components/composio/bitbucket_composio.py +11 -0
  177. lfx/components/composio/bolna_composio.py +11 -0
  178. lfx/components/composio/brightdata_composio.py +11 -0
  179. lfx/components/composio/calendly_composio.py +11 -0
  180. lfx/components/composio/canva_composio.py +11 -0
  181. lfx/components/composio/canvas_composio.py +11 -0
  182. lfx/components/composio/coda_composio.py +11 -0
  183. lfx/components/composio/composio_api.py +278 -0
  184. lfx/components/composio/contentful_composio.py +11 -0
  185. lfx/components/composio/digicert_composio.py +11 -0
  186. lfx/components/composio/discord_composio.py +11 -0
  187. lfx/components/composio/dropbox_compnent.py +11 -0
  188. lfx/components/composio/elevenlabs_composio.py +11 -0
  189. lfx/components/composio/exa_composio.py +11 -0
  190. lfx/components/composio/figma_composio.py +11 -0
  191. lfx/components/composio/finage_composio.py +11 -0
  192. lfx/components/composio/firecrawl_composio.py +11 -0
  193. lfx/components/composio/fireflies_composio.py +11 -0
  194. lfx/components/composio/fixer_composio.py +11 -0
  195. lfx/components/composio/flexisign_composio.py +11 -0
  196. lfx/components/composio/freshdesk_composio.py +11 -0
  197. lfx/components/composio/github_composio.py +11 -0
  198. lfx/components/composio/gmail_composio.py +38 -0
  199. lfx/components/composio/googlebigquery_composio.py +11 -0
  200. lfx/components/composio/googlecalendar_composio.py +11 -0
  201. lfx/components/composio/googleclassroom_composio.py +11 -0
  202. lfx/components/composio/googledocs_composio.py +11 -0
  203. lfx/components/composio/googlemeet_composio.py +11 -0
  204. lfx/components/composio/googlesheets_composio.py +11 -0
  205. lfx/components/composio/googletasks_composio.py +8 -0
  206. lfx/components/composio/heygen_composio.py +11 -0
  207. lfx/components/composio/instagram_composio.py +11 -0
  208. lfx/components/composio/jira_composio.py +11 -0
  209. lfx/components/composio/jotform_composio.py +11 -0
  210. lfx/components/composio/klaviyo_composio.py +11 -0
  211. lfx/components/composio/linear_composio.py +11 -0
  212. lfx/components/composio/listennotes_composio.py +11 -0
  213. lfx/components/composio/mem0_composio.py +11 -0
  214. lfx/components/composio/miro_composio.py +11 -0
  215. lfx/components/composio/missive_composio.py +11 -0
  216. lfx/components/composio/notion_composio.py +11 -0
  217. lfx/components/composio/onedrive_composio.py +11 -0
  218. lfx/components/composio/outlook_composio.py +11 -0
  219. lfx/components/composio/pandadoc_composio.py +11 -0
  220. lfx/components/composio/peopledatalabs_composio.py +11 -0
  221. lfx/components/composio/perplexityai_composio.py +11 -0
  222. lfx/components/composio/reddit_composio.py +11 -0
  223. lfx/components/composio/serpapi_composio.py +11 -0
  224. lfx/components/composio/slack_composio.py +11 -0
  225. lfx/components/composio/slackbot_composio.py +11 -0
  226. lfx/components/composio/snowflake_composio.py +11 -0
  227. lfx/components/composio/supabase_composio.py +11 -0
  228. lfx/components/composio/tavily_composio.py +11 -0
  229. lfx/components/composio/timelinesai_composio.py +11 -0
  230. lfx/components/composio/todoist_composio.py +11 -0
  231. lfx/components/composio/wrike_composio.py +11 -0
  232. lfx/components/composio/youtube_composio.py +11 -0
  233. lfx/components/confluence/__init__.py +3 -0
  234. lfx/components/confluence/confluence.py +84 -0
  235. lfx/components/couchbase/__init__.py +34 -0
  236. lfx/components/couchbase/couchbase.py +102 -0
  237. lfx/components/crewai/__init__.py +49 -0
  238. lfx/components/crewai/crewai.py +108 -0
  239. lfx/components/crewai/hierarchical_crew.py +47 -0
  240. lfx/components/crewai/hierarchical_task.py +45 -0
  241. lfx/components/crewai/sequential_crew.py +53 -0
  242. lfx/components/crewai/sequential_task.py +74 -0
  243. lfx/components/crewai/sequential_task_agent.py +144 -0
  244. lfx/components/cuga/__init__.py +34 -0
  245. lfx/components/cuga/cuga_agent.py +730 -0
  246. lfx/components/custom_component/__init__.py +34 -0
  247. lfx/components/custom_component/custom_component.py +31 -0
  248. lfx/components/data/__init__.py +114 -0
  249. lfx/components/data_source/__init__.py +58 -0
  250. lfx/components/data_source/api_request.py +577 -0
  251. lfx/components/data_source/csv_to_data.py +101 -0
  252. lfx/components/data_source/json_to_data.py +106 -0
  253. lfx/components/data_source/mock_data.py +398 -0
  254. lfx/components/data_source/news_search.py +166 -0
  255. lfx/components/data_source/rss.py +71 -0
  256. lfx/components/data_source/sql_executor.py +101 -0
  257. lfx/components/data_source/url.py +311 -0
  258. lfx/components/data_source/web_search.py +326 -0
  259. lfx/components/datastax/__init__.py +76 -0
  260. lfx/components/datastax/astradb_assistant_manager.py +307 -0
  261. lfx/components/datastax/astradb_chatmemory.py +40 -0
  262. lfx/components/datastax/astradb_cql.py +288 -0
  263. lfx/components/datastax/astradb_graph.py +217 -0
  264. lfx/components/datastax/astradb_tool.py +378 -0
  265. lfx/components/datastax/astradb_vectorize.py +122 -0
  266. lfx/components/datastax/astradb_vectorstore.py +449 -0
  267. lfx/components/datastax/create_assistant.py +59 -0
  268. lfx/components/datastax/create_thread.py +33 -0
  269. lfx/components/datastax/dotenv.py +36 -0
  270. lfx/components/datastax/get_assistant.py +38 -0
  271. lfx/components/datastax/getenvvar.py +31 -0
  272. lfx/components/datastax/graph_rag.py +141 -0
  273. lfx/components/datastax/hcd.py +315 -0
  274. lfx/components/datastax/list_assistants.py +26 -0
  275. lfx/components/datastax/run.py +90 -0
  276. lfx/components/deactivated/__init__.py +15 -0
  277. lfx/components/deactivated/amazon_kendra.py +66 -0
  278. lfx/components/deactivated/chat_litellm_model.py +158 -0
  279. lfx/components/deactivated/code_block_extractor.py +26 -0
  280. lfx/components/deactivated/documents_to_data.py +22 -0
  281. lfx/components/deactivated/embed.py +16 -0
  282. lfx/components/deactivated/extract_key_from_data.py +46 -0
  283. lfx/components/deactivated/json_document_builder.py +57 -0
  284. lfx/components/deactivated/list_flows.py +20 -0
  285. lfx/components/deactivated/mcp_sse.py +61 -0
  286. lfx/components/deactivated/mcp_stdio.py +62 -0
  287. lfx/components/deactivated/merge_data.py +93 -0
  288. lfx/components/deactivated/message.py +37 -0
  289. lfx/components/deactivated/metal.py +54 -0
  290. lfx/components/deactivated/multi_query.py +59 -0
  291. lfx/components/deactivated/retriever.py +43 -0
  292. lfx/components/deactivated/selective_passthrough.py +77 -0
  293. lfx/components/deactivated/should_run_next.py +40 -0
  294. lfx/components/deactivated/split_text.py +63 -0
  295. lfx/components/deactivated/store_message.py +24 -0
  296. lfx/components/deactivated/sub_flow.py +124 -0
  297. lfx/components/deactivated/vectara_self_query.py +76 -0
  298. lfx/components/deactivated/vector_store.py +24 -0
  299. lfx/components/deepseek/__init__.py +34 -0
  300. lfx/components/deepseek/deepseek.py +136 -0
  301. lfx/components/docling/__init__.py +43 -0
  302. lfx/components/docling/chunk_docling_document.py +186 -0
  303. lfx/components/docling/docling_inline.py +238 -0
  304. lfx/components/docling/docling_remote.py +195 -0
  305. lfx/components/docling/export_docling_document.py +117 -0
  306. lfx/components/documentloaders/__init__.py +3 -0
  307. lfx/components/duckduckgo/__init__.py +3 -0
  308. lfx/components/duckduckgo/duck_duck_go_search_run.py +92 -0
  309. lfx/components/elastic/__init__.py +37 -0
  310. lfx/components/elastic/elasticsearch.py +267 -0
  311. lfx/components/elastic/opensearch.py +789 -0
  312. lfx/components/elastic/opensearch_multimodal.py +1575 -0
  313. lfx/components/embeddings/__init__.py +37 -0
  314. lfx/components/embeddings/similarity.py +77 -0
  315. lfx/components/embeddings/text_embedder.py +65 -0
  316. lfx/components/exa/__init__.py +3 -0
  317. lfx/components/exa/exa_search.py +68 -0
  318. lfx/components/files_and_knowledge/__init__.py +47 -0
  319. lfx/components/files_and_knowledge/directory.py +113 -0
  320. lfx/components/files_and_knowledge/file.py +841 -0
  321. lfx/components/files_and_knowledge/ingestion.py +694 -0
  322. lfx/components/files_and_knowledge/retrieval.py +264 -0
  323. lfx/components/files_and_knowledge/save_file.py +746 -0
  324. lfx/components/firecrawl/__init__.py +43 -0
  325. lfx/components/firecrawl/firecrawl_crawl_api.py +88 -0
  326. lfx/components/firecrawl/firecrawl_extract_api.py +136 -0
  327. lfx/components/firecrawl/firecrawl_map_api.py +89 -0
  328. lfx/components/firecrawl/firecrawl_scrape_api.py +73 -0
  329. lfx/components/flow_controls/__init__.py +58 -0
  330. lfx/components/flow_controls/conditional_router.py +208 -0
  331. lfx/components/flow_controls/data_conditional_router.py +126 -0
  332. lfx/components/flow_controls/flow_tool.py +111 -0
  333. lfx/components/flow_controls/listen.py +29 -0
  334. lfx/components/flow_controls/loop.py +163 -0
  335. lfx/components/flow_controls/notify.py +88 -0
  336. lfx/components/flow_controls/pass_message.py +36 -0
  337. lfx/components/flow_controls/run_flow.py +108 -0
  338. lfx/components/flow_controls/sub_flow.py +115 -0
  339. lfx/components/git/__init__.py +4 -0
  340. lfx/components/git/git.py +262 -0
  341. lfx/components/git/gitextractor.py +196 -0
  342. lfx/components/glean/__init__.py +3 -0
  343. lfx/components/glean/glean_search_api.py +173 -0
  344. lfx/components/google/__init__.py +17 -0
  345. lfx/components/google/gmail.py +193 -0
  346. lfx/components/google/google_bq_sql_executor.py +157 -0
  347. lfx/components/google/google_drive.py +92 -0
  348. lfx/components/google/google_drive_search.py +152 -0
  349. lfx/components/google/google_generative_ai.py +144 -0
  350. lfx/components/google/google_generative_ai_embeddings.py +141 -0
  351. lfx/components/google/google_oauth_token.py +89 -0
  352. lfx/components/google/google_search_api_core.py +68 -0
  353. lfx/components/google/google_serper_api_core.py +74 -0
  354. lfx/components/groq/__init__.py +34 -0
  355. lfx/components/groq/groq.py +143 -0
  356. lfx/components/helpers/__init__.py +154 -0
  357. lfx/components/homeassistant/__init__.py +7 -0
  358. lfx/components/homeassistant/home_assistant_control.py +152 -0
  359. lfx/components/homeassistant/list_home_assistant_states.py +137 -0
  360. lfx/components/huggingface/__init__.py +37 -0
  361. lfx/components/huggingface/huggingface.py +199 -0
  362. lfx/components/huggingface/huggingface_inference_api.py +106 -0
  363. lfx/components/ibm/__init__.py +34 -0
  364. lfx/components/ibm/watsonx.py +207 -0
  365. lfx/components/ibm/watsonx_embeddings.py +135 -0
  366. lfx/components/icosacomputing/__init__.py +5 -0
  367. lfx/components/icosacomputing/combinatorial_reasoner.py +84 -0
  368. lfx/components/input_output/__init__.py +40 -0
  369. lfx/components/input_output/chat.py +109 -0
  370. lfx/components/input_output/chat_output.py +184 -0
  371. lfx/components/input_output/text.py +27 -0
  372. lfx/components/input_output/text_output.py +29 -0
  373. lfx/components/input_output/webhook.py +56 -0
  374. lfx/components/jigsawstack/__init__.py +23 -0
  375. lfx/components/jigsawstack/ai_scrape.py +126 -0
  376. lfx/components/jigsawstack/ai_web_search.py +136 -0
  377. lfx/components/jigsawstack/file_read.py +115 -0
  378. lfx/components/jigsawstack/file_upload.py +94 -0
  379. lfx/components/jigsawstack/image_generation.py +205 -0
  380. lfx/components/jigsawstack/nsfw.py +60 -0
  381. lfx/components/jigsawstack/object_detection.py +124 -0
  382. lfx/components/jigsawstack/sentiment.py +112 -0
  383. lfx/components/jigsawstack/text_to_sql.py +90 -0
  384. lfx/components/jigsawstack/text_translate.py +77 -0
  385. lfx/components/jigsawstack/vocr.py +107 -0
  386. lfx/components/knowledge_bases/__init__.py +89 -0
  387. lfx/components/langchain_utilities/__init__.py +109 -0
  388. lfx/components/langchain_utilities/character.py +53 -0
  389. lfx/components/langchain_utilities/conversation.py +59 -0
  390. lfx/components/langchain_utilities/csv_agent.py +175 -0
  391. lfx/components/langchain_utilities/fake_embeddings.py +26 -0
  392. lfx/components/langchain_utilities/html_link_extractor.py +35 -0
  393. lfx/components/langchain_utilities/json_agent.py +100 -0
  394. lfx/components/langchain_utilities/langchain_hub.py +126 -0
  395. lfx/components/langchain_utilities/language_recursive.py +49 -0
  396. lfx/components/langchain_utilities/language_semantic.py +138 -0
  397. lfx/components/langchain_utilities/llm_checker.py +39 -0
  398. lfx/components/langchain_utilities/llm_math.py +42 -0
  399. lfx/components/langchain_utilities/natural_language.py +61 -0
  400. lfx/components/langchain_utilities/openai_tools.py +53 -0
  401. lfx/components/langchain_utilities/openapi.py +48 -0
  402. lfx/components/langchain_utilities/recursive_character.py +60 -0
  403. lfx/components/langchain_utilities/retrieval_qa.py +83 -0
  404. lfx/components/langchain_utilities/runnable_executor.py +137 -0
  405. lfx/components/langchain_utilities/self_query.py +80 -0
  406. lfx/components/langchain_utilities/spider.py +142 -0
  407. lfx/components/langchain_utilities/sql.py +40 -0
  408. lfx/components/langchain_utilities/sql_database.py +35 -0
  409. lfx/components/langchain_utilities/sql_generator.py +78 -0
  410. lfx/components/langchain_utilities/tool_calling.py +59 -0
  411. lfx/components/langchain_utilities/vector_store_info.py +49 -0
  412. lfx/components/langchain_utilities/vector_store_router.py +33 -0
  413. lfx/components/langchain_utilities/xml_agent.py +71 -0
  414. lfx/components/langwatch/__init__.py +3 -0
  415. lfx/components/langwatch/langwatch.py +278 -0
  416. lfx/components/link_extractors/__init__.py +3 -0
  417. lfx/components/llm_operations/__init__.py +46 -0
  418. lfx/components/llm_operations/batch_run.py +205 -0
  419. lfx/components/llm_operations/lambda_filter.py +218 -0
  420. lfx/components/llm_operations/llm_conditional_router.py +421 -0
  421. lfx/components/llm_operations/llm_selector.py +499 -0
  422. lfx/components/llm_operations/structured_output.py +244 -0
  423. lfx/components/lmstudio/__init__.py +34 -0
  424. lfx/components/lmstudio/lmstudioembeddings.py +89 -0
  425. lfx/components/lmstudio/lmstudiomodel.py +133 -0
  426. lfx/components/logic/__init__.py +181 -0
  427. lfx/components/maritalk/__init__.py +32 -0
  428. lfx/components/maritalk/maritalk.py +52 -0
  429. lfx/components/mem0/__init__.py +3 -0
  430. lfx/components/mem0/mem0_chat_memory.py +147 -0
  431. lfx/components/milvus/__init__.py +34 -0
  432. lfx/components/milvus/milvus.py +115 -0
  433. lfx/components/mistral/__init__.py +37 -0
  434. lfx/components/mistral/mistral.py +114 -0
  435. lfx/components/mistral/mistral_embeddings.py +58 -0
  436. lfx/components/models/__init__.py +89 -0
  437. lfx/components/models_and_agents/__init__.py +49 -0
  438. lfx/components/models_and_agents/agent.py +644 -0
  439. lfx/components/models_and_agents/embedding_model.py +423 -0
  440. lfx/components/models_and_agents/language_model.py +398 -0
  441. lfx/components/models_and_agents/mcp_component.py +594 -0
  442. lfx/components/models_and_agents/memory.py +268 -0
  443. lfx/components/models_and_agents/prompt.py +67 -0
  444. lfx/components/mongodb/__init__.py +34 -0
  445. lfx/components/mongodb/mongodb_atlas.py +213 -0
  446. lfx/components/needle/__init__.py +3 -0
  447. lfx/components/needle/needle.py +104 -0
  448. lfx/components/notdiamond/__init__.py +34 -0
  449. lfx/components/notdiamond/notdiamond.py +228 -0
  450. lfx/components/novita/__init__.py +32 -0
  451. lfx/components/novita/novita.py +130 -0
  452. lfx/components/nvidia/__init__.py +57 -0
  453. lfx/components/nvidia/nvidia.py +151 -0
  454. lfx/components/nvidia/nvidia_embedding.py +77 -0
  455. lfx/components/nvidia/nvidia_ingest.py +317 -0
  456. lfx/components/nvidia/nvidia_rerank.py +63 -0
  457. lfx/components/nvidia/system_assist.py +65 -0
  458. lfx/components/olivya/__init__.py +3 -0
  459. lfx/components/olivya/olivya.py +116 -0
  460. lfx/components/ollama/__init__.py +37 -0
  461. lfx/components/ollama/ollama.py +548 -0
  462. lfx/components/ollama/ollama_embeddings.py +103 -0
  463. lfx/components/openai/__init__.py +37 -0
  464. lfx/components/openai/openai.py +100 -0
  465. lfx/components/openai/openai_chat_model.py +176 -0
  466. lfx/components/openrouter/__init__.py +32 -0
  467. lfx/components/openrouter/openrouter.py +104 -0
  468. lfx/components/output_parsers/__init__.py +3 -0
  469. lfx/components/perplexity/__init__.py +34 -0
  470. lfx/components/perplexity/perplexity.py +75 -0
  471. lfx/components/pgvector/__init__.py +34 -0
  472. lfx/components/pgvector/pgvector.py +72 -0
  473. lfx/components/pinecone/__init__.py +34 -0
  474. lfx/components/pinecone/pinecone.py +134 -0
  475. lfx/components/processing/__init__.py +72 -0
  476. lfx/components/processing/alter_metadata.py +109 -0
  477. lfx/components/processing/combine_text.py +40 -0
  478. lfx/components/processing/converter.py +248 -0
  479. lfx/components/processing/create_data.py +111 -0
  480. lfx/components/processing/create_list.py +40 -0
  481. lfx/components/processing/data_operations.py +528 -0
  482. lfx/components/processing/data_to_dataframe.py +71 -0
  483. lfx/components/processing/dataframe_operations.py +313 -0
  484. lfx/components/processing/dataframe_to_toolset.py +259 -0
  485. lfx/components/processing/dynamic_create_data.py +357 -0
  486. lfx/components/processing/extract_key.py +54 -0
  487. lfx/components/processing/filter_data.py +43 -0
  488. lfx/components/processing/filter_data_values.py +89 -0
  489. lfx/components/processing/json_cleaner.py +104 -0
  490. lfx/components/processing/merge_data.py +91 -0
  491. lfx/components/processing/message_to_data.py +37 -0
  492. lfx/components/processing/output_parser.py +46 -0
  493. lfx/components/processing/parse_data.py +71 -0
  494. lfx/components/processing/parse_dataframe.py +69 -0
  495. lfx/components/processing/parse_json_data.py +91 -0
  496. lfx/components/processing/parser.py +148 -0
  497. lfx/components/processing/regex.py +83 -0
  498. lfx/components/processing/select_data.py +49 -0
  499. lfx/components/processing/split_text.py +141 -0
  500. lfx/components/processing/store_message.py +91 -0
  501. lfx/components/processing/update_data.py +161 -0
  502. lfx/components/prototypes/__init__.py +35 -0
  503. lfx/components/prototypes/python_function.py +73 -0
  504. lfx/components/qdrant/__init__.py +34 -0
  505. lfx/components/qdrant/qdrant.py +109 -0
  506. lfx/components/redis/__init__.py +37 -0
  507. lfx/components/redis/redis.py +89 -0
  508. lfx/components/redis/redis_chat.py +43 -0
  509. lfx/components/sambanova/__init__.py +32 -0
  510. lfx/components/sambanova/sambanova.py +84 -0
  511. lfx/components/scrapegraph/__init__.py +40 -0
  512. lfx/components/scrapegraph/scrapegraph_markdownify_api.py +64 -0
  513. lfx/components/scrapegraph/scrapegraph_search_api.py +64 -0
  514. lfx/components/scrapegraph/scrapegraph_smart_scraper_api.py +71 -0
  515. lfx/components/searchapi/__init__.py +34 -0
  516. lfx/components/searchapi/search.py +79 -0
  517. lfx/components/serpapi/__init__.py +3 -0
  518. lfx/components/serpapi/serp.py +115 -0
  519. lfx/components/supabase/__init__.py +34 -0
  520. lfx/components/supabase/supabase.py +76 -0
  521. lfx/components/tavily/__init__.py +4 -0
  522. lfx/components/tavily/tavily_extract.py +117 -0
  523. lfx/components/tavily/tavily_search.py +212 -0
  524. lfx/components/textsplitters/__init__.py +3 -0
  525. lfx/components/toolkits/__init__.py +3 -0
  526. lfx/components/tools/__init__.py +66 -0
  527. lfx/components/tools/calculator.py +109 -0
  528. lfx/components/tools/google_search_api.py +45 -0
  529. lfx/components/tools/google_serper_api.py +115 -0
  530. lfx/components/tools/python_code_structured_tool.py +328 -0
  531. lfx/components/tools/python_repl.py +98 -0
  532. lfx/components/tools/search_api.py +88 -0
  533. lfx/components/tools/searxng.py +145 -0
  534. lfx/components/tools/serp_api.py +120 -0
  535. lfx/components/tools/tavily_search_tool.py +345 -0
  536. lfx/components/tools/wikidata_api.py +103 -0
  537. lfx/components/tools/wikipedia_api.py +50 -0
  538. lfx/components/tools/yahoo_finance.py +130 -0
  539. lfx/components/twelvelabs/__init__.py +52 -0
  540. lfx/components/twelvelabs/convert_astra_results.py +84 -0
  541. lfx/components/twelvelabs/pegasus_index.py +311 -0
  542. lfx/components/twelvelabs/split_video.py +301 -0
  543. lfx/components/twelvelabs/text_embeddings.py +57 -0
  544. lfx/components/twelvelabs/twelvelabs_pegasus.py +408 -0
  545. lfx/components/twelvelabs/video_embeddings.py +100 -0
  546. lfx/components/twelvelabs/video_file.py +191 -0
  547. lfx/components/unstructured/__init__.py +3 -0
  548. lfx/components/unstructured/unstructured.py +121 -0
  549. lfx/components/upstash/__init__.py +34 -0
  550. lfx/components/upstash/upstash.py +124 -0
  551. lfx/components/utilities/__init__.py +43 -0
  552. lfx/components/utilities/calculator_core.py +89 -0
  553. lfx/components/utilities/current_date.py +42 -0
  554. lfx/components/utilities/id_generator.py +42 -0
  555. lfx/components/utilities/python_repl_core.py +98 -0
  556. lfx/components/vectara/__init__.py +37 -0
  557. lfx/components/vectara/vectara.py +97 -0
  558. lfx/components/vectara/vectara_rag.py +164 -0
  559. lfx/components/vectorstores/__init__.py +34 -0
  560. lfx/components/vectorstores/local_db.py +270 -0
  561. lfx/components/vertexai/__init__.py +37 -0
  562. lfx/components/vertexai/vertexai.py +71 -0
  563. lfx/components/vertexai/vertexai_embeddings.py +67 -0
  564. lfx/components/vlmrun/__init__.py +34 -0
  565. lfx/components/vlmrun/vlmrun_transcription.py +224 -0
  566. lfx/components/weaviate/__init__.py +34 -0
  567. lfx/components/weaviate/weaviate.py +89 -0
  568. lfx/components/wikipedia/__init__.py +4 -0
  569. lfx/components/wikipedia/wikidata.py +86 -0
  570. lfx/components/wikipedia/wikipedia.py +53 -0
  571. lfx/components/wolframalpha/__init__.py +3 -0
  572. lfx/components/wolframalpha/wolfram_alpha_api.py +54 -0
  573. lfx/components/xai/__init__.py +32 -0
  574. lfx/components/xai/xai.py +167 -0
  575. lfx/components/yahoosearch/__init__.py +3 -0
  576. lfx/components/yahoosearch/yahoo.py +137 -0
  577. lfx/components/youtube/__init__.py +52 -0
  578. lfx/components/youtube/channel.py +227 -0
  579. lfx/components/youtube/comments.py +231 -0
  580. lfx/components/youtube/playlist.py +33 -0
  581. lfx/components/youtube/search.py +120 -0
  582. lfx/components/youtube/trending.py +285 -0
  583. lfx/components/youtube/video_details.py +263 -0
  584. lfx/components/youtube/youtube_transcripts.py +206 -0
  585. lfx/components/zep/__init__.py +3 -0
  586. lfx/components/zep/zep.py +45 -0
  587. lfx/constants.py +6 -0
  588. lfx/custom/__init__.py +7 -0
  589. lfx/custom/attributes.py +87 -0
  590. lfx/custom/code_parser/__init__.py +3 -0
  591. lfx/custom/code_parser/code_parser.py +361 -0
  592. lfx/custom/custom_component/__init__.py +0 -0
  593. lfx/custom/custom_component/base_component.py +128 -0
  594. lfx/custom/custom_component/component.py +1890 -0
  595. lfx/custom/custom_component/component_with_cache.py +8 -0
  596. lfx/custom/custom_component/custom_component.py +650 -0
  597. lfx/custom/dependency_analyzer.py +165 -0
  598. lfx/custom/directory_reader/__init__.py +3 -0
  599. lfx/custom/directory_reader/directory_reader.py +359 -0
  600. lfx/custom/directory_reader/utils.py +171 -0
  601. lfx/custom/eval.py +12 -0
  602. lfx/custom/schema.py +32 -0
  603. lfx/custom/tree_visitor.py +21 -0
  604. lfx/custom/utils.py +877 -0
  605. lfx/custom/validate.py +523 -0
  606. lfx/events/__init__.py +1 -0
  607. lfx/events/event_manager.py +110 -0
  608. lfx/exceptions/__init__.py +0 -0
  609. lfx/exceptions/component.py +15 -0
  610. lfx/field_typing/__init__.py +91 -0
  611. lfx/field_typing/constants.py +216 -0
  612. lfx/field_typing/range_spec.py +35 -0
  613. lfx/graph/__init__.py +6 -0
  614. lfx/graph/edge/__init__.py +0 -0
  615. lfx/graph/edge/base.py +300 -0
  616. lfx/graph/edge/schema.py +119 -0
  617. lfx/graph/edge/utils.py +0 -0
  618. lfx/graph/graph/__init__.py +0 -0
  619. lfx/graph/graph/ascii.py +202 -0
  620. lfx/graph/graph/base.py +2298 -0
  621. lfx/graph/graph/constants.py +63 -0
  622. lfx/graph/graph/runnable_vertices_manager.py +133 -0
  623. lfx/graph/graph/schema.py +53 -0
  624. lfx/graph/graph/state_model.py +66 -0
  625. lfx/graph/graph/utils.py +1024 -0
  626. lfx/graph/schema.py +75 -0
  627. lfx/graph/state/__init__.py +0 -0
  628. lfx/graph/state/model.py +250 -0
  629. lfx/graph/utils.py +206 -0
  630. lfx/graph/vertex/__init__.py +0 -0
  631. lfx/graph/vertex/base.py +826 -0
  632. lfx/graph/vertex/constants.py +0 -0
  633. lfx/graph/vertex/exceptions.py +4 -0
  634. lfx/graph/vertex/param_handler.py +316 -0
  635. lfx/graph/vertex/schema.py +26 -0
  636. lfx/graph/vertex/utils.py +19 -0
  637. lfx/graph/vertex/vertex_types.py +489 -0
  638. lfx/helpers/__init__.py +141 -0
  639. lfx/helpers/base_model.py +71 -0
  640. lfx/helpers/custom.py +13 -0
  641. lfx/helpers/data.py +167 -0
  642. lfx/helpers/flow.py +308 -0
  643. lfx/inputs/__init__.py +68 -0
  644. lfx/inputs/constants.py +2 -0
  645. lfx/inputs/input_mixin.py +352 -0
  646. lfx/inputs/inputs.py +718 -0
  647. lfx/inputs/validators.py +19 -0
  648. lfx/interface/__init__.py +6 -0
  649. lfx/interface/components.py +897 -0
  650. lfx/interface/importing/__init__.py +5 -0
  651. lfx/interface/importing/utils.py +39 -0
  652. lfx/interface/initialize/__init__.py +3 -0
  653. lfx/interface/initialize/loading.py +317 -0
  654. lfx/interface/listing.py +26 -0
  655. lfx/interface/run.py +16 -0
  656. lfx/interface/utils.py +111 -0
  657. lfx/io/__init__.py +63 -0
  658. lfx/io/schema.py +295 -0
  659. lfx/load/__init__.py +8 -0
  660. lfx/load/load.py +256 -0
  661. lfx/load/utils.py +99 -0
  662. lfx/log/__init__.py +5 -0
  663. lfx/log/logger.py +411 -0
  664. lfx/logging/__init__.py +11 -0
  665. lfx/logging/logger.py +24 -0
  666. lfx/memory/__init__.py +70 -0
  667. lfx/memory/stubs.py +302 -0
  668. lfx/processing/__init__.py +1 -0
  669. lfx/processing/process.py +238 -0
  670. lfx/processing/utils.py +25 -0
  671. lfx/py.typed +0 -0
  672. lfx/schema/__init__.py +66 -0
  673. lfx/schema/artifact.py +83 -0
  674. lfx/schema/content_block.py +62 -0
  675. lfx/schema/content_types.py +91 -0
  676. lfx/schema/cross_module.py +80 -0
  677. lfx/schema/data.py +309 -0
  678. lfx/schema/dataframe.py +210 -0
  679. lfx/schema/dotdict.py +74 -0
  680. lfx/schema/encoders.py +13 -0
  681. lfx/schema/graph.py +47 -0
  682. lfx/schema/image.py +184 -0
  683. lfx/schema/json_schema.py +186 -0
  684. lfx/schema/log.py +62 -0
  685. lfx/schema/message.py +493 -0
  686. lfx/schema/openai_responses_schemas.py +74 -0
  687. lfx/schema/properties.py +41 -0
  688. lfx/schema/schema.py +180 -0
  689. lfx/schema/serialize.py +13 -0
  690. lfx/schema/table.py +142 -0
  691. lfx/schema/validators.py +114 -0
  692. lfx/serialization/__init__.py +5 -0
  693. lfx/serialization/constants.py +2 -0
  694. lfx/serialization/serialization.py +314 -0
  695. lfx/services/__init__.py +26 -0
  696. lfx/services/base.py +28 -0
  697. lfx/services/cache/__init__.py +6 -0
  698. lfx/services/cache/base.py +183 -0
  699. lfx/services/cache/service.py +166 -0
  700. lfx/services/cache/utils.py +169 -0
  701. lfx/services/chat/__init__.py +1 -0
  702. lfx/services/chat/config.py +2 -0
  703. lfx/services/chat/schema.py +10 -0
  704. lfx/services/database/__init__.py +5 -0
  705. lfx/services/database/service.py +25 -0
  706. lfx/services/deps.py +194 -0
  707. lfx/services/factory.py +19 -0
  708. lfx/services/initialize.py +19 -0
  709. lfx/services/interfaces.py +103 -0
  710. lfx/services/manager.py +185 -0
  711. lfx/services/mcp_composer/__init__.py +6 -0
  712. lfx/services/mcp_composer/factory.py +16 -0
  713. lfx/services/mcp_composer/service.py +1441 -0
  714. lfx/services/schema.py +21 -0
  715. lfx/services/session.py +87 -0
  716. lfx/services/settings/__init__.py +3 -0
  717. lfx/services/settings/auth.py +133 -0
  718. lfx/services/settings/base.py +668 -0
  719. lfx/services/settings/constants.py +43 -0
  720. lfx/services/settings/factory.py +23 -0
  721. lfx/services/settings/feature_flags.py +11 -0
  722. lfx/services/settings/service.py +35 -0
  723. lfx/services/settings/utils.py +40 -0
  724. lfx/services/shared_component_cache/__init__.py +1 -0
  725. lfx/services/shared_component_cache/factory.py +30 -0
  726. lfx/services/shared_component_cache/service.py +9 -0
  727. lfx/services/storage/__init__.py +5 -0
  728. lfx/services/storage/local.py +185 -0
  729. lfx/services/storage/service.py +177 -0
  730. lfx/services/tracing/__init__.py +1 -0
  731. lfx/services/tracing/service.py +21 -0
  732. lfx/settings.py +6 -0
  733. lfx/template/__init__.py +6 -0
  734. lfx/template/field/__init__.py +0 -0
  735. lfx/template/field/base.py +260 -0
  736. lfx/template/field/prompt.py +15 -0
  737. lfx/template/frontend_node/__init__.py +6 -0
  738. lfx/template/frontend_node/base.py +214 -0
  739. lfx/template/frontend_node/constants.py +65 -0
  740. lfx/template/frontend_node/custom_components.py +79 -0
  741. lfx/template/template/__init__.py +0 -0
  742. lfx/template/template/base.py +100 -0
  743. lfx/template/utils.py +217 -0
  744. lfx/type_extraction/__init__.py +19 -0
  745. lfx/type_extraction/type_extraction.py +75 -0
  746. lfx/type_extraction.py +80 -0
  747. lfx/utils/__init__.py +1 -0
  748. lfx/utils/async_helpers.py +42 -0
  749. lfx/utils/component_utils.py +154 -0
  750. lfx/utils/concurrency.py +60 -0
  751. lfx/utils/connection_string_parser.py +11 -0
  752. lfx/utils/constants.py +233 -0
  753. lfx/utils/data_structure.py +212 -0
  754. lfx/utils/exceptions.py +22 -0
  755. lfx/utils/helpers.py +34 -0
  756. lfx/utils/image.py +79 -0
  757. lfx/utils/langflow_utils.py +52 -0
  758. lfx/utils/lazy_load.py +15 -0
  759. lfx/utils/request_utils.py +18 -0
  760. lfx/utils/schemas.py +139 -0
  761. lfx/utils/ssrf_protection.py +384 -0
  762. lfx/utils/util.py +626 -0
  763. lfx/utils/util_strings.py +56 -0
  764. lfx/utils/validate_cloud.py +26 -0
  765. lfx/utils/version.py +24 -0
  766. lfx_nightly-0.2.0.dev25.dist-info/METADATA +312 -0
  767. lfx_nightly-0.2.0.dev25.dist-info/RECORD +769 -0
  768. lfx_nightly-0.2.0.dev25.dist-info/WHEEL +4 -0
  769. lfx_nightly-0.2.0.dev25.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,548 @@
1
+ import asyncio
2
+ import json
3
+ from contextlib import suppress
4
+ from typing import Any
5
+ from urllib.parse import urljoin
6
+
7
+ import httpx
8
+ from langchain_ollama import ChatOllama
9
+
10
+ from lfx.base.models.model import LCModelComponent
11
+ from lfx.field_typing import LanguageModel
12
+ from lfx.field_typing.range_spec import RangeSpec
13
+ from lfx.helpers.base_model import build_model_from_schema
14
+ from lfx.io import (
15
+ BoolInput,
16
+ DictInput,
17
+ DropdownInput,
18
+ FloatInput,
19
+ IntInput,
20
+ MessageTextInput,
21
+ Output,
22
+ SecretStrInput,
23
+ SliderInput,
24
+ TableInput,
25
+ )
26
+ from lfx.log.logger import logger
27
+ from lfx.schema.data import Data
28
+ from lfx.schema.dataframe import DataFrame
29
+ from lfx.schema.table import EditMode
30
+ from lfx.utils.util import transform_localhost_url
31
+
32
+ HTTP_STATUS_OK = 200
33
+ TABLE_ROW_PLACEHOLDER = {"name": "field", "description": "description of field", "type": "str", "multiple": "False"}
34
+
35
+
36
+ class ChatOllamaComponent(LCModelComponent):
37
+ display_name = "Ollama"
38
+ description = "Generate text using Ollama Local LLMs."
39
+ icon = "Ollama"
40
+ name = "OllamaModel"
41
+
42
+ # Define constants for JSON keys
43
+ JSON_MODELS_KEY = "models"
44
+ JSON_NAME_KEY = "name"
45
+ JSON_CAPABILITIES_KEY = "capabilities"
46
+ DESIRED_CAPABILITY = "completion"
47
+ TOOL_CALLING_CAPABILITY = "tools"
48
+
49
+ # Define the table schema for the format input
50
+ TABLE_SCHEMA = [
51
+ {
52
+ "name": "name",
53
+ "display_name": "Name",
54
+ "type": "str",
55
+ "description": "Specify the name of the output field.",
56
+ "default": "field",
57
+ "edit_mode": EditMode.INLINE,
58
+ },
59
+ {
60
+ "name": "description",
61
+ "display_name": "Description",
62
+ "type": "str",
63
+ "description": "Describe the purpose of the output field.",
64
+ "default": "description of field",
65
+ "edit_mode": EditMode.POPOVER,
66
+ },
67
+ {
68
+ "name": "type",
69
+ "display_name": "Type",
70
+ "type": "str",
71
+ "edit_mode": EditMode.INLINE,
72
+ "description": ("Indicate the data type of the output field (e.g., str, int, float, bool, dict)."),
73
+ "options": ["str", "int", "float", "bool", "dict"],
74
+ "default": "str",
75
+ },
76
+ {
77
+ "name": "multiple",
78
+ "display_name": "As List",
79
+ "type": "boolean",
80
+ "description": "Set to True if this output field should be a list of the specified type.",
81
+ "edit_mode": EditMode.INLINE,
82
+ "options": ["True", "False"],
83
+ "default": "False",
84
+ },
85
+ ]
86
+ default_table_row = {row["name"]: row.get("default", None) for row in TABLE_SCHEMA}
87
+ default_table_row_schema = build_model_from_schema([default_table_row]).model_json_schema()
88
+
89
+ inputs = [
90
+ MessageTextInput(
91
+ name="base_url",
92
+ display_name="Ollama API URL",
93
+ info="Endpoint of the Ollama API. Defaults to http://localhost:11434.",
94
+ value="http://localhost:11434",
95
+ real_time_refresh=True,
96
+ ),
97
+ DropdownInput(
98
+ name="model_name",
99
+ display_name="Model Name",
100
+ options=[],
101
+ info="Refer to https://ollama.com/library for more models.",
102
+ refresh_button=True,
103
+ real_time_refresh=True,
104
+ required=True,
105
+ ),
106
+ SecretStrInput(
107
+ name="api_key",
108
+ display_name="Ollama API Key",
109
+ info="Your Ollama API key.",
110
+ value=None,
111
+ required=False,
112
+ real_time_refresh=True,
113
+ advanced=True,
114
+ ),
115
+ SliderInput(
116
+ name="temperature",
117
+ display_name="Temperature",
118
+ value=0.1,
119
+ range_spec=RangeSpec(min=0, max=1, step=0.01),
120
+ advanced=True,
121
+ ),
122
+ TableInput(
123
+ name="format",
124
+ display_name="Format",
125
+ info="Specify the format of the output.",
126
+ table_schema=TABLE_SCHEMA,
127
+ value=default_table_row,
128
+ show=False,
129
+ ),
130
+ DictInput(name="metadata", display_name="Metadata", info="Metadata to add to the run trace.", advanced=True),
131
+ DropdownInput(
132
+ name="mirostat",
133
+ display_name="Mirostat",
134
+ options=["Disabled", "Mirostat", "Mirostat 2.0"],
135
+ info="Enable/disable Mirostat sampling for controlling perplexity.",
136
+ value="Disabled",
137
+ advanced=True,
138
+ real_time_refresh=True,
139
+ ),
140
+ FloatInput(
141
+ name="mirostat_eta",
142
+ display_name="Mirostat Eta",
143
+ info="Learning rate for Mirostat algorithm. (Default: 0.1)",
144
+ advanced=True,
145
+ ),
146
+ FloatInput(
147
+ name="mirostat_tau",
148
+ display_name="Mirostat Tau",
149
+ info="Controls the balance between coherence and diversity of the output. (Default: 5.0)",
150
+ advanced=True,
151
+ ),
152
+ IntInput(
153
+ name="num_ctx",
154
+ display_name="Context Window Size",
155
+ info="Size of the context window for generating tokens. (Default: 2048)",
156
+ advanced=True,
157
+ ),
158
+ IntInput(
159
+ name="num_gpu",
160
+ display_name="Number of GPUs",
161
+ info="Number of GPUs to use for computation. (Default: 1 on macOS, 0 to disable)",
162
+ advanced=True,
163
+ ),
164
+ IntInput(
165
+ name="num_thread",
166
+ display_name="Number of Threads",
167
+ info="Number of threads to use during computation. (Default: detected for optimal performance)",
168
+ advanced=True,
169
+ ),
170
+ IntInput(
171
+ name="repeat_last_n",
172
+ display_name="Repeat Last N",
173
+ info="How far back the model looks to prevent repetition. (Default: 64, 0 = disabled, -1 = num_ctx)",
174
+ advanced=True,
175
+ ),
176
+ FloatInput(
177
+ name="repeat_penalty",
178
+ display_name="Repeat Penalty",
179
+ info="Penalty for repetitions in generated text. (Default: 1.1)",
180
+ advanced=True,
181
+ ),
182
+ FloatInput(name="tfs_z", display_name="TFS Z", info="Tail free sampling value. (Default: 1)", advanced=True),
183
+ IntInput(name="timeout", display_name="Timeout", info="Timeout for the request stream.", advanced=True),
184
+ IntInput(
185
+ name="top_k", display_name="Top K", info="Limits token selection to top K. (Default: 40)", advanced=True
186
+ ),
187
+ FloatInput(name="top_p", display_name="Top P", info="Works together with top-k. (Default: 0.9)", advanced=True),
188
+ BoolInput(
189
+ name="enable_verbose_output",
190
+ display_name="Ollama Verbose Output",
191
+ info="Whether to print out response text.",
192
+ advanced=True,
193
+ ),
194
+ MessageTextInput(
195
+ name="tags",
196
+ display_name="Tags",
197
+ info="Comma-separated list of tags to add to the run trace.",
198
+ advanced=True,
199
+ ),
200
+ MessageTextInput(
201
+ name="stop_tokens",
202
+ display_name="Stop Tokens",
203
+ info="Comma-separated list of tokens to signal the model to stop generating text.",
204
+ advanced=True,
205
+ ),
206
+ MessageTextInput(
207
+ name="system", display_name="System", info="System to use for generating text.", advanced=True
208
+ ),
209
+ BoolInput(
210
+ name="tool_model_enabled",
211
+ display_name="Tool Model Enabled",
212
+ info="Whether to enable tool calling in the model.",
213
+ value=True,
214
+ real_time_refresh=True,
215
+ ),
216
+ MessageTextInput(
217
+ name="template", display_name="Template", info="Template to use for generating text.", advanced=True
218
+ ),
219
+ BoolInput(
220
+ name="enable_structured_output",
221
+ display_name="Enable Structured Output",
222
+ info="Whether to enable structured output in the model.",
223
+ value=False,
224
+ advanced=False,
225
+ real_time_refresh=True,
226
+ ),
227
+ *LCModelComponent.get_base_inputs(),
228
+ ]
229
+
230
+ outputs = [
231
+ Output(display_name="Text", name="text_output", method="text_response"),
232
+ Output(display_name="Language Model", name="model_output", method="build_model"),
233
+ Output(display_name="Data", name="data_output", method="build_data_output"),
234
+ Output(display_name="DataFrame", name="dataframe_output", method="build_dataframe_output"),
235
+ ]
236
+
237
+ def build_model(self) -> LanguageModel: # type: ignore[type-var]
238
+ # Mapping mirostat settings to their corresponding values
239
+ mirostat_options = {"Mirostat": 1, "Mirostat 2.0": 2}
240
+
241
+ # Default to None for 'Disabled'
242
+ mirostat_value = mirostat_options.get(self.mirostat, None)
243
+
244
+ # Set mirostat_eta and mirostat_tau to None if mirostat is disabled
245
+ if mirostat_value is None:
246
+ mirostat_eta = None
247
+ mirostat_tau = None
248
+ else:
249
+ mirostat_eta = self.mirostat_eta
250
+ mirostat_tau = self.mirostat_tau
251
+
252
+ transformed_base_url = transform_localhost_url(self.base_url)
253
+
254
+ # Check if URL contains /v1 suffix (OpenAI-compatible mode)
255
+ if transformed_base_url and transformed_base_url.rstrip("/").endswith("/v1"):
256
+ # Strip /v1 suffix and log warning
257
+ transformed_base_url = transformed_base_url.rstrip("/").removesuffix("/v1")
258
+ logger.warning(
259
+ "Detected '/v1' suffix in base URL. The Ollama component uses the native Ollama API, "
260
+ "not the OpenAI-compatible API. The '/v1' suffix has been automatically removed. "
261
+ "If you want to use the OpenAI-compatible API, please use the OpenAI component instead. "
262
+ "Learn more at https://docs.ollama.com/openai#openai-compatibility"
263
+ )
264
+
265
+ try:
266
+ output_format = self._parse_format_field(self.format) if self.enable_structured_output else None
267
+ except Exception as e:
268
+ msg = f"Failed to parse the format field: {e}"
269
+ raise ValueError(msg) from e
270
+
271
+ # Mapping system settings to their corresponding values
272
+ llm_params = {
273
+ "base_url": transformed_base_url,
274
+ "model": self.model_name,
275
+ "mirostat": mirostat_value,
276
+ "format": output_format or None,
277
+ "metadata": self.metadata,
278
+ "tags": self.tags.split(",") if self.tags else None,
279
+ "mirostat_eta": mirostat_eta,
280
+ "mirostat_tau": mirostat_tau,
281
+ "num_ctx": self.num_ctx or None,
282
+ "num_gpu": self.num_gpu or None,
283
+ "num_thread": self.num_thread or None,
284
+ "repeat_last_n": self.repeat_last_n or None,
285
+ "repeat_penalty": self.repeat_penalty or None,
286
+ "temperature": self.temperature or None,
287
+ "stop": self.stop_tokens.split(",") if self.stop_tokens else None,
288
+ "system": self.system,
289
+ "tfs_z": self.tfs_z or None,
290
+ "timeout": self.timeout or None,
291
+ "top_k": self.top_k or None,
292
+ "top_p": self.top_p or None,
293
+ "verbose": self.enable_verbose_output or False,
294
+ "template": self.template,
295
+ }
296
+ headers = self.headers
297
+ if headers is not None:
298
+ llm_params["client_kwargs"] = {"headers": headers}
299
+
300
+ # Remove parameters with None values
301
+ llm_params = {k: v for k, v in llm_params.items() if v is not None}
302
+
303
+ try:
304
+ output = ChatOllama(**llm_params)
305
+ except Exception as e:
306
+ msg = (
307
+ "Unable to connect to the Ollama API. "
308
+ "Please verify the base URL, ensure the relevant Ollama model is pulled, and try again."
309
+ )
310
+ raise ValueError(msg) from e
311
+
312
+ return output
313
+
314
+ async def is_valid_ollama_url(self, url: str) -> bool:
315
+ try:
316
+ async with httpx.AsyncClient() as client:
317
+ url = transform_localhost_url(url)
318
+ if not url:
319
+ return False
320
+ # Strip /v1 suffix if present, as Ollama API endpoints are at root level
321
+ url = url.rstrip("/").removesuffix("/v1")
322
+ if not url.endswith("/"):
323
+ url = url + "/"
324
+ return (
325
+ await client.get(url=urljoin(url, "api/tags"), headers=self.headers)
326
+ ).status_code == HTTP_STATUS_OK
327
+ except httpx.RequestError:
328
+ return False
329
+
330
+ async def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None):
331
+ if field_name == "enable_structured_output": # bind enable_structured_output boolean to format show value
332
+ build_config["format"]["show"] = field_value
333
+
334
+ if field_name == "mirostat":
335
+ if field_value == "Disabled":
336
+ build_config["mirostat_eta"]["advanced"] = True
337
+ build_config["mirostat_tau"]["advanced"] = True
338
+ build_config["mirostat_eta"]["value"] = None
339
+ build_config["mirostat_tau"]["value"] = None
340
+
341
+ else:
342
+ build_config["mirostat_eta"]["advanced"] = False
343
+ build_config["mirostat_tau"]["advanced"] = False
344
+
345
+ if field_value == "Mirostat 2.0":
346
+ build_config["mirostat_eta"]["value"] = 0.2
347
+ build_config["mirostat_tau"]["value"] = 10
348
+ else:
349
+ build_config["mirostat_eta"]["value"] = 0.1
350
+ build_config["mirostat_tau"]["value"] = 5
351
+
352
+ if field_name in {"model_name", "base_url", "tool_model_enabled"}:
353
+ logger.warning(f"Fetching Ollama models from updated URL: {build_config['base_url']}")
354
+
355
+ if await self.is_valid_ollama_url(self.base_url):
356
+ tool_model_enabled = build_config["tool_model_enabled"].get("value", False) or self.tool_model_enabled
357
+ build_config["model_name"]["options"] = await self.get_models(
358
+ self.base_url, tool_model_enabled=tool_model_enabled
359
+ )
360
+ else:
361
+ build_config["model_name"]["options"] = []
362
+ if field_name == "keep_alive_flag":
363
+ if field_value == "Keep":
364
+ build_config["keep_alive"]["value"] = "-1"
365
+ build_config["keep_alive"]["advanced"] = True
366
+ elif field_value == "Immediately":
367
+ build_config["keep_alive"]["value"] = "0"
368
+ build_config["keep_alive"]["advanced"] = True
369
+ else:
370
+ build_config["keep_alive"]["advanced"] = False
371
+
372
+ return build_config
373
+
374
+ async def get_models(self, base_url_value: str, *, tool_model_enabled: bool | None = None) -> list[str]:
375
+ """Fetches a list of models from the Ollama API that do not have the "embedding" capability.
376
+
377
+ Args:
378
+ base_url_value (str): The base URL of the Ollama API.
379
+ tool_model_enabled (bool | None, optional): If True, filters the models further to include
380
+ only those that support tool calling. Defaults to None.
381
+
382
+ Returns:
383
+ list[str]: A list of model names that do not have the "embedding" capability. If
384
+ `tool_model_enabled` is True, only models supporting tool calling are included.
385
+
386
+ Raises:
387
+ ValueError: If there is an issue with the API request or response, or if the model
388
+ names cannot be retrieved.
389
+ """
390
+ try:
391
+ # Strip /v1 suffix if present, as Ollama API endpoints are at root level
392
+ base_url = base_url_value.rstrip("/").removesuffix("/v1")
393
+ if not base_url.endswith("/"):
394
+ base_url = base_url + "/"
395
+ base_url = transform_localhost_url(base_url)
396
+
397
+ # Ollama REST API to return models
398
+ tags_url = urljoin(base_url, "api/tags")
399
+
400
+ # Ollama REST API to return model capabilities
401
+ show_url = urljoin(base_url, "api/show")
402
+
403
+ async with httpx.AsyncClient() as client:
404
+ headers = self.headers
405
+ # Fetch available models
406
+ tags_response = await client.get(url=tags_url, headers=headers)
407
+ tags_response.raise_for_status()
408
+ models = tags_response.json()
409
+ if asyncio.iscoroutine(models):
410
+ models = await models
411
+ await logger.adebug(f"Available models: {models}")
412
+
413
+ # Filter models that are NOT embedding models
414
+ model_ids = []
415
+ for model in models[self.JSON_MODELS_KEY]:
416
+ model_name = model[self.JSON_NAME_KEY]
417
+ await logger.adebug(f"Checking model: {model_name}")
418
+
419
+ payload = {"model": model_name}
420
+ show_response = await client.post(url=show_url, json=payload, headers=headers)
421
+ show_response.raise_for_status()
422
+ json_data = show_response.json()
423
+ if asyncio.iscoroutine(json_data):
424
+ json_data = await json_data
425
+
426
+ capabilities = json_data.get(self.JSON_CAPABILITIES_KEY, [])
427
+ await logger.adebug(f"Model: {model_name}, Capabilities: {capabilities}")
428
+
429
+ if self.DESIRED_CAPABILITY in capabilities and (
430
+ not tool_model_enabled or self.TOOL_CALLING_CAPABILITY in capabilities
431
+ ):
432
+ model_ids.append(model_name)
433
+
434
+ except (httpx.RequestError, ValueError) as e:
435
+ msg = "Could not get model names from Ollama."
436
+ raise ValueError(msg) from e
437
+
438
+ return model_ids
439
+
440
+ def _parse_format_field(self, format_value: Any) -> Any:
441
+ """Parse the format field to handle both string and dict inputs.
442
+
443
+ The format field can be:
444
+ - A simple string like "json" (backward compatibility)
445
+ - A JSON string from NestedDictInput that needs parsing
446
+ - A dict/JSON schema (already parsed)
447
+ - None or empty
448
+
449
+ Args:
450
+ format_value: The raw format value from the input field
451
+
452
+ Returns:
453
+ Parsed format value as string, dict, or None
454
+ """
455
+ if not format_value:
456
+ return None
457
+
458
+ schema = format_value
459
+ if isinstance(format_value, list):
460
+ schema = build_model_from_schema(format_value).model_json_schema()
461
+ if schema == self.default_table_row_schema:
462
+ return None # the rows are generic placeholder rows
463
+ elif isinstance(format_value, str): # parse as json if string
464
+ with suppress(json.JSONDecodeError): # e.g., literal "json" is valid for format field
465
+ schema = json.loads(format_value)
466
+
467
+ return schema or None
468
+
469
+ async def _parse_json_response(self) -> Any:
470
+ """Parse the JSON response from the model.
471
+
472
+ This method gets the text response and attempts to parse it as JSON.
473
+ Works with models that have format='json' or a JSON schema set.
474
+
475
+ Returns:
476
+ Parsed JSON (dict, list, or primitive type)
477
+
478
+ Raises:
479
+ ValueError: If the response is not valid JSON
480
+ """
481
+ message = await self.text_response()
482
+ text = message.text if hasattr(message, "text") else str(message)
483
+
484
+ if not text:
485
+ msg = "No response from model"
486
+ raise ValueError(msg)
487
+
488
+ try:
489
+ return json.loads(text)
490
+ except json.JSONDecodeError as e:
491
+ msg = f"Invalid JSON response. Ensure model supports JSON output. Error: {e}"
492
+ raise ValueError(msg) from e
493
+
494
+ async def build_data_output(self) -> Data:
495
+ """Build a Data output from the model's JSON response.
496
+
497
+ Returns:
498
+ Data: A Data object containing the parsed JSON response
499
+ """
500
+ parsed = await self._parse_json_response()
501
+
502
+ # If the response is already a dict, wrap it in Data
503
+ if isinstance(parsed, dict):
504
+ return Data(data=parsed)
505
+
506
+ # If it's a list, wrap in a results container
507
+ if isinstance(parsed, list):
508
+ if len(parsed) == 1:
509
+ return Data(data=parsed[0])
510
+ return Data(data={"results": parsed})
511
+
512
+ # For primitive types, wrap in a value container
513
+ return Data(data={"value": parsed})
514
+
515
+ async def build_dataframe_output(self) -> DataFrame:
516
+ """Build a DataFrame output from the model's JSON response.
517
+
518
+ Returns:
519
+ DataFrame: A DataFrame containing the parsed JSON response
520
+
521
+ Raises:
522
+ ValueError: If the response cannot be converted to a DataFrame
523
+ """
524
+ parsed = await self._parse_json_response()
525
+
526
+ # If it's a list of dicts, convert directly to DataFrame
527
+ if isinstance(parsed, list):
528
+ if not parsed:
529
+ return DataFrame()
530
+ # Ensure all items are dicts for proper DataFrame conversion
531
+ if all(isinstance(item, dict) for item in parsed):
532
+ return DataFrame(parsed)
533
+ msg = "List items must be dictionaries to convert to DataFrame"
534
+ raise ValueError(msg)
535
+
536
+ # If it's a single dict, wrap in a list to create a single-row DataFrame
537
+ if isinstance(parsed, dict):
538
+ return DataFrame([parsed])
539
+
540
+ # For primitive types, create a single-column DataFrame
541
+ return DataFrame([{"value": parsed}])
542
+
543
+ @property
544
+ def headers(self) -> dict[str, str] | None:
545
+ """Get the headers for the Ollama API."""
546
+ if self.api_key and self.api_key.strip():
547
+ return {"Authorization": f"Bearer {self.api_key}"}
548
+ return None
@@ -0,0 +1,103 @@
1
+ from typing import Any
2
+ from urllib.parse import urljoin
3
+
4
+ import httpx
5
+ from langchain_ollama import OllamaEmbeddings
6
+
7
+ from lfx.base.models.model import LCModelComponent
8
+ from lfx.base.models.ollama_constants import OLLAMA_EMBEDDING_MODELS
9
+ from lfx.field_typing import Embeddings
10
+ from lfx.io import DropdownInput, MessageTextInput, Output
11
+ from lfx.utils.util import transform_localhost_url
12
+
13
+ HTTP_STATUS_OK = 200
14
+
15
+
16
+ class OllamaEmbeddingsComponent(LCModelComponent):
17
+ display_name: str = "Ollama Embeddings"
18
+ description: str = "Generate embeddings using Ollama models."
19
+ documentation = "https://python.langchain.com/docs/integrations/text_embedding/ollama"
20
+ icon = "Ollama"
21
+ name = "OllamaEmbeddings"
22
+
23
+ inputs = [
24
+ DropdownInput(
25
+ name="model_name",
26
+ display_name="Ollama Model",
27
+ value="",
28
+ options=[],
29
+ real_time_refresh=True,
30
+ refresh_button=True,
31
+ combobox=True,
32
+ required=True,
33
+ ),
34
+ MessageTextInput(
35
+ name="base_url",
36
+ display_name="Ollama Base URL",
37
+ value="",
38
+ required=True,
39
+ ),
40
+ ]
41
+
42
+ outputs = [
43
+ Output(display_name="Embeddings", name="embeddings", method="build_embeddings"),
44
+ ]
45
+
46
+ def build_embeddings(self) -> Embeddings:
47
+ transformed_base_url = transform_localhost_url(self.base_url)
48
+ try:
49
+ output = OllamaEmbeddings(model=self.model_name, base_url=transformed_base_url)
50
+ except Exception as e:
51
+ msg = (
52
+ "Unable to connect to the Ollama API. ",
53
+ "Please verify the base URL, ensure the relevant Ollama model is pulled, and try again.",
54
+ )
55
+ raise ValueError(msg) from e
56
+ return output
57
+
58
+ async def update_build_config(self, build_config: dict, _field_value: Any, field_name: str | None = None):
59
+ if field_name in {"base_url", "model_name"} and not await self.is_valid_ollama_url(self.base_url):
60
+ msg = "Ollama is not running on the provided base URL. Please start Ollama and try again."
61
+ raise ValueError(msg)
62
+ if field_name in {"model_name", "base_url", "tool_model_enabled"}:
63
+ if await self.is_valid_ollama_url(self.base_url):
64
+ build_config["model_name"]["options"] = await self.get_model(self.base_url)
65
+ else:
66
+ build_config["model_name"]["options"] = []
67
+
68
+ return build_config
69
+
70
+ async def get_model(self, base_url_value: str) -> list[str]:
71
+ """Get the model names from Ollama."""
72
+ model_ids = []
73
+ try:
74
+ base_url_value = transform_localhost_url(base_url_value)
75
+ url = urljoin(base_url_value, "/api/tags")
76
+ async with httpx.AsyncClient() as client:
77
+ response = await client.get(url)
78
+ response.raise_for_status()
79
+ data = response.json()
80
+
81
+ model_ids = [model["name"] for model in data.get("models", [])]
82
+ # this to ensure that not embedding models are included.
83
+ # not even the base models since models can have 1b 2b etc
84
+ # handles cases when embeddings models have tags like :latest - etc.
85
+ model_ids = [
86
+ model
87
+ for model in model_ids
88
+ if any(model.startswith(f"{embedding_model}") for embedding_model in OLLAMA_EMBEDDING_MODELS)
89
+ ]
90
+
91
+ except (ImportError, ValueError, httpx.RequestError) as e:
92
+ msg = "Could not get model names from Ollama."
93
+ raise ValueError(msg) from e
94
+
95
+ return model_ids
96
+
97
+ async def is_valid_ollama_url(self, url: str) -> bool:
98
+ try:
99
+ async with httpx.AsyncClient() as client:
100
+ url = transform_localhost_url(url)
101
+ return (await client.get(f"{url}/api/tags")).status_code == HTTP_STATUS_OK
102
+ except httpx.RequestError:
103
+ return False
@@ -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.openai.openai import OpenAIEmbeddingsComponent
9
+ from lfx.components.openai.openai_chat_model import OpenAIModelComponent
10
+
11
+ _dynamic_imports = {
12
+ "OpenAIEmbeddingsComponent": "openai",
13
+ "OpenAIModelComponent": "openai_chat_model",
14
+ }
15
+
16
+ __all__ = [
17
+ "OpenAIEmbeddingsComponent",
18
+ "OpenAIModelComponent",
19
+ ]
20
+
21
+
22
+ def __getattr__(attr_name: str) -> Any:
23
+ """Lazily import OpenAI 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__)