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,430 @@
1
+ # Add helper functions for each event type
2
+ import asyncio
3
+ from collections.abc import AsyncIterator
4
+ from time import perf_counter
5
+ from typing import Any, Protocol
6
+
7
+ from langchain_core.agents import AgentFinish
8
+ from langchain_core.messages import AIMessageChunk, BaseMessage
9
+ from typing_extensions import TypedDict
10
+
11
+ from lfx.schema.content_block import ContentBlock
12
+ from lfx.schema.content_types import TextContent, ToolContent
13
+ from lfx.schema.log import OnTokenFunctionType, SendMessageFunctionType
14
+ from lfx.schema.message import Message
15
+
16
+
17
+ class ExceptionWithMessageError(Exception):
18
+ def __init__(self, agent_message: Message, message: str):
19
+ self.agent_message = agent_message
20
+ super().__init__(message)
21
+ self.message = message
22
+
23
+ def __str__(self):
24
+ return (
25
+ f"Agent message: {self.agent_message.text} \nError: {self.message}."
26
+ if self.agent_message.error or self.agent_message.text
27
+ else f"{self.message}."
28
+ )
29
+
30
+
31
+ class InputDict(TypedDict):
32
+ input: str
33
+ chat_history: list[BaseMessage]
34
+
35
+
36
+ def _build_agent_input_text_content(agent_input_dict: InputDict) -> str:
37
+ final_input = agent_input_dict.get("input", "")
38
+ return f"{final_input}"
39
+
40
+
41
+ def _calculate_duration(start_time: float) -> int:
42
+ """Calculate duration in milliseconds from start time to now."""
43
+ # Handle the calculation
44
+ current_time = perf_counter()
45
+ if isinstance(start_time, int):
46
+ # If we got an integer, treat it as milliseconds
47
+ duration = current_time - (start_time / 1000)
48
+ result = int(duration * 1000)
49
+ else:
50
+ # If we got a float, treat it as perf_counter time
51
+ result = int((current_time - start_time) * 1000)
52
+
53
+ return result
54
+
55
+
56
+ async def handle_on_chain_start(
57
+ event: dict[str, Any],
58
+ agent_message: Message,
59
+ send_message_callback: SendMessageFunctionType,
60
+ send_token_callback: OnTokenFunctionType | None, # noqa: ARG001
61
+ start_time: float,
62
+ *,
63
+ had_streaming: bool = False, # noqa: ARG001
64
+ message_id: str | None = None, # noqa: ARG001
65
+ ) -> tuple[Message, float]:
66
+ # Create content blocks if they don't exist
67
+ if not agent_message.content_blocks:
68
+ agent_message.content_blocks = [ContentBlock(title="Agent Steps", contents=[])]
69
+
70
+ if event["data"].get("input"):
71
+ input_data = event["data"].get("input")
72
+ if isinstance(input_data, dict) and "input" in input_data:
73
+ # Cast the input_data to InputDict
74
+ input_message = input_data.get("input", "")
75
+ if isinstance(input_message, BaseMessage):
76
+ input_message = input_message.text()
77
+ elif not isinstance(input_message, str):
78
+ input_message = str(input_message)
79
+
80
+ input_dict: InputDict = {
81
+ "input": input_message,
82
+ "chat_history": input_data.get("chat_history", []),
83
+ }
84
+ text_content = TextContent(
85
+ type="text",
86
+ text=_build_agent_input_text_content(input_dict),
87
+ duration=_calculate_duration(start_time),
88
+ header={"title": "Input", "icon": "MessageSquare"},
89
+ )
90
+ agent_message.content_blocks[0].contents.append(text_content)
91
+ agent_message = await send_message_callback(message=agent_message, skip_db_update=True)
92
+ start_time = perf_counter()
93
+ return agent_message, start_time
94
+
95
+
96
+ def _extract_output_text(output: str | list) -> str:
97
+ if isinstance(output, str):
98
+ return output
99
+ if isinstance(output, list) and len(output) == 0:
100
+ return ""
101
+
102
+ # Handle lists of various lengths and formats
103
+ if isinstance(output, list):
104
+ # Handle single item lists
105
+ if len(output) == 1:
106
+ item = output[0]
107
+ if isinstance(item, str):
108
+ return item
109
+ if isinstance(item, dict):
110
+ if "text" in item:
111
+ return item["text"] or ""
112
+ if "content" in item:
113
+ return str(item["content"])
114
+ if "message" in item:
115
+ return str(item["message"])
116
+
117
+ # Special case handling for non-text-like dicts
118
+ if (
119
+ item.get("type") == "tool_use" # Handle tool use items
120
+ or ("index" in item and len(item) == 1) # Handle index-only items
121
+ or "partial_json" in item # Handle partial json items
122
+ # Handle index-only items
123
+ or ("index" in item and not any(k in item for k in ("text", "content", "message")))
124
+ # Handle other metadata-only chunks that don't contain meaningful text
125
+ or not any(key in item for key in ["text", "content", "message"])
126
+ ):
127
+ return ""
128
+
129
+ # For any other dict format, return empty string
130
+ return ""
131
+ # For any other single item type (not str or dict), return empty string
132
+ return ""
133
+
134
+ # Handle multiple items - extract text from all text-type items
135
+ text_parts = []
136
+ for item in output:
137
+ if isinstance(item, str):
138
+ text_parts.append(item)
139
+ elif isinstance(item, dict):
140
+ if "text" in item and item["text"] is not None:
141
+ text_parts.append(item["text"])
142
+ # Skip tool_use, index-only, and partial_json items
143
+ elif item.get("type") == "tool_use" or "partial_json" in item or ("index" in item and len(item) == 1):
144
+ continue
145
+ return "".join(text_parts)
146
+
147
+ # If we get here, the format is unexpected but try to be graceful
148
+ return ""
149
+
150
+
151
+ async def handle_on_chain_end(
152
+ event: dict[str, Any],
153
+ agent_message: Message,
154
+ send_message_callback: SendMessageFunctionType,
155
+ send_token_callback: OnTokenFunctionType | None, # noqa: ARG001
156
+ start_time: float,
157
+ *,
158
+ had_streaming: bool = False,
159
+ message_id: str | None = None, # noqa: ARG001
160
+ ) -> tuple[Message, float]:
161
+ data_output = event["data"].get("output")
162
+ if data_output and isinstance(data_output, AgentFinish) and data_output.return_values.get("output"):
163
+ output = data_output.return_values.get("output")
164
+
165
+ agent_message.text = _extract_output_text(output)
166
+ agent_message.properties.state = "complete"
167
+ # Add duration to the last content if it exists
168
+ if agent_message.content_blocks:
169
+ duration = _calculate_duration(start_time)
170
+ text_content = TextContent(
171
+ type="text",
172
+ text=agent_message.text,
173
+ duration=duration,
174
+ header={"title": "Output", "icon": "MessageSquare"},
175
+ )
176
+ agent_message.content_blocks[0].contents.append(text_content)
177
+
178
+ # Only send final message if we didn't have streaming chunks
179
+ # If we had streaming, frontend already accumulated the chunks
180
+ if not had_streaming:
181
+ agent_message = await send_message_callback(message=agent_message)
182
+ start_time = perf_counter()
183
+ return agent_message, start_time
184
+
185
+
186
+ async def handle_on_tool_start(
187
+ event: dict[str, Any],
188
+ agent_message: Message,
189
+ tool_blocks_map: dict[str, ToolContent],
190
+ send_message_callback: SendMessageFunctionType,
191
+ start_time: float,
192
+ ) -> tuple[Message, float]:
193
+ tool_name = event["name"]
194
+ tool_input = event["data"].get("input")
195
+ run_id = event.get("run_id", "")
196
+ tool_key = f"{tool_name}_{run_id}"
197
+
198
+ # Create content blocks if they don't exist
199
+ if not agent_message.content_blocks:
200
+ agent_message.content_blocks = [ContentBlock(title="Agent Steps", contents=[])]
201
+
202
+ duration = _calculate_duration(start_time)
203
+ new_start_time = perf_counter() # Get new start time for next operation
204
+
205
+ # Create new tool content with the input exactly as received
206
+ tool_content = ToolContent(
207
+ type="tool_use",
208
+ name=tool_name,
209
+ tool_input=tool_input,
210
+ output=None,
211
+ error=None,
212
+ header={"title": f"Accessing **{tool_name}**", "icon": "Hammer"},
213
+ duration=duration, # Store the actual duration
214
+ )
215
+
216
+ # Store in map and append to message
217
+ tool_blocks_map[tool_key] = tool_content
218
+ agent_message.content_blocks[0].contents.append(tool_content)
219
+
220
+ agent_message = await send_message_callback(message=agent_message, skip_db_update=True)
221
+ if agent_message.content_blocks and agent_message.content_blocks[0].contents:
222
+ tool_blocks_map[tool_key] = agent_message.content_blocks[0].contents[-1]
223
+ return agent_message, new_start_time
224
+
225
+
226
+ async def handle_on_tool_end(
227
+ event: dict[str, Any],
228
+ agent_message: Message,
229
+ tool_blocks_map: dict[str, ToolContent],
230
+ send_message_callback: SendMessageFunctionType,
231
+ start_time: float,
232
+ ) -> tuple[Message, float]:
233
+ run_id = event.get("run_id", "")
234
+ tool_name = event.get("name", "")
235
+ tool_key = f"{tool_name}_{run_id}"
236
+ tool_content = tool_blocks_map.get(tool_key)
237
+
238
+ if tool_content and isinstance(tool_content, ToolContent):
239
+ # Call send_message_callback first to get the updated message structure
240
+ agent_message = await send_message_callback(message=agent_message, skip_db_update=True)
241
+ new_start_time = perf_counter()
242
+
243
+ # Now find and update the tool content in the current message
244
+ duration = _calculate_duration(start_time)
245
+ tool_key = f"{tool_name}_{run_id}"
246
+
247
+ # Find the corresponding tool content in the updated message
248
+ updated_tool_content = None
249
+ if agent_message.content_blocks and agent_message.content_blocks[0].contents:
250
+ for content in agent_message.content_blocks[0].contents:
251
+ if (
252
+ isinstance(content, ToolContent)
253
+ and content.name == tool_name
254
+ and content.tool_input == tool_content.tool_input
255
+ ):
256
+ updated_tool_content = content
257
+ break
258
+
259
+ # Update the tool content that's actually in the message
260
+ if updated_tool_content:
261
+ updated_tool_content.duration = duration
262
+ updated_tool_content.header = {"title": f"Executed **{updated_tool_content.name}**", "icon": "Hammer"}
263
+ updated_tool_content.output = event["data"].get("output")
264
+
265
+ # Update the map reference
266
+ tool_blocks_map[tool_key] = updated_tool_content
267
+
268
+ return agent_message, new_start_time
269
+ return agent_message, start_time
270
+
271
+
272
+ async def handle_on_tool_error(
273
+ event: dict[str, Any],
274
+ agent_message: Message,
275
+ tool_blocks_map: dict[str, ToolContent],
276
+ send_message_callback: SendMessageFunctionType,
277
+ start_time: float,
278
+ ) -> tuple[Message, float]:
279
+ run_id = event.get("run_id", "")
280
+ tool_name = event.get("name", "")
281
+ tool_key = f"{tool_name}_{run_id}"
282
+ tool_content = tool_blocks_map.get(tool_key)
283
+
284
+ if tool_content and isinstance(tool_content, ToolContent):
285
+ tool_content.error = event["data"].get("error", "Unknown error")
286
+ tool_content.duration = _calculate_duration(start_time)
287
+ tool_content.header = {"title": f"Error using **{tool_content.name}**", "icon": "Hammer"}
288
+ agent_message = await send_message_callback(message=agent_message, skip_db_update=True)
289
+ start_time = perf_counter()
290
+ return agent_message, start_time
291
+
292
+
293
+ async def handle_on_chain_stream(
294
+ event: dict[str, Any],
295
+ agent_message: Message,
296
+ send_message_callback: SendMessageFunctionType, # noqa: ARG001
297
+ send_token_callback: OnTokenFunctionType | None,
298
+ start_time: float,
299
+ *,
300
+ had_streaming: bool = False, # noqa: ARG001
301
+ message_id: str | None = None,
302
+ ) -> tuple[Message, float]:
303
+ data_chunk = event["data"].get("chunk", {})
304
+ if isinstance(data_chunk, dict) and data_chunk.get("output"):
305
+ output = data_chunk.get("output")
306
+ if output and isinstance(output, str | list):
307
+ agent_message.text = _extract_output_text(output)
308
+ agent_message.properties.state = "complete"
309
+ # Don't call send_message_callback here - we must update in place
310
+ # in order to keep the message id consistent throughout the stream.
311
+ # The final message will be sent after the loop completes
312
+ start_time = perf_counter()
313
+ elif isinstance(data_chunk, AIMessageChunk):
314
+ output_text = _extract_output_text(data_chunk.content)
315
+ # For streaming, send token event if callback is available
316
+ # Note: we should expect the callback, but we keep it optional for backwards compatibility
317
+ # as of v1.6.5
318
+ if output_text and output_text.strip() and send_token_callback and message_id:
319
+ await asyncio.to_thread(
320
+ send_token_callback,
321
+ data={
322
+ "chunk": output_text,
323
+ "id": str(message_id),
324
+ },
325
+ )
326
+
327
+ if not agent_message.text:
328
+ # Starts the timer when the first message is starting to be generated
329
+ start_time = perf_counter()
330
+ return agent_message, start_time
331
+
332
+
333
+ class ToolEventHandler(Protocol):
334
+ async def __call__(
335
+ self,
336
+ event: dict[str, Any],
337
+ agent_message: Message,
338
+ tool_blocks_map: dict[str, ContentBlock],
339
+ send_message_callback: SendMessageFunctionType,
340
+ start_time: float,
341
+ ) -> tuple[Message, float]: ...
342
+
343
+
344
+ class ChainEventHandler(Protocol):
345
+ async def __call__(
346
+ self,
347
+ event: dict[str, Any],
348
+ agent_message: Message,
349
+ send_message_callback: SendMessageFunctionType,
350
+ send_token_callback: OnTokenFunctionType | None,
351
+ start_time: float,
352
+ *,
353
+ had_streaming: bool = False,
354
+ message_id: str | None = None,
355
+ ) -> tuple[Message, float]: ...
356
+
357
+
358
+ EventHandler = ToolEventHandler | ChainEventHandler
359
+
360
+ # Define separate mappings of event types to their respective handler functions
361
+ CHAIN_EVENT_HANDLERS: dict[str, ChainEventHandler] = {
362
+ "on_chain_start": handle_on_chain_start,
363
+ "on_chain_end": handle_on_chain_end,
364
+ "on_chain_stream": handle_on_chain_stream,
365
+ "on_chat_model_stream": handle_on_chain_stream,
366
+ }
367
+
368
+ TOOL_EVENT_HANDLERS: dict[str, ToolEventHandler] = {
369
+ "on_tool_start": handle_on_tool_start,
370
+ "on_tool_end": handle_on_tool_end,
371
+ "on_tool_error": handle_on_tool_error,
372
+ }
373
+
374
+
375
+ async def process_agent_events(
376
+ agent_executor: AsyncIterator[dict[str, Any]],
377
+ agent_message: Message,
378
+ send_message_callback: SendMessageFunctionType,
379
+ send_token_callback: OnTokenFunctionType | None = None,
380
+ ) -> Message:
381
+ """Process agent events and return the final output."""
382
+ if isinstance(agent_message.properties, dict):
383
+ agent_message.properties.update({"icon": "Bot", "state": "partial"})
384
+ else:
385
+ agent_message.properties.icon = "Bot"
386
+ agent_message.properties.state = "partial"
387
+ # Store the initial message and capture the message id
388
+ agent_message = await send_message_callback(message=agent_message)
389
+ # Capture the original message id - this must stay consistent throughout if streaming
390
+ # Message may not contain id if the Agent is not connected to a Chat Output (_should_skip_message is True)
391
+ initial_message_id = agent_message.id if hasattr(agent_message, "id") else None
392
+ try:
393
+ # Create a mapping of run_ids to tool contents
394
+ tool_blocks_map: dict[str, ToolContent] = {}
395
+ had_streaming = False
396
+ start_time = perf_counter()
397
+
398
+ async for event in agent_executor:
399
+ if event["event"] in TOOL_EVENT_HANDLERS:
400
+ tool_handler = TOOL_EVENT_HANDLERS[event["event"]]
401
+ # Use skip_db_update=True during streaming to avoid DB round-trips
402
+ agent_message, start_time = await tool_handler(
403
+ event, agent_message, tool_blocks_map, send_message_callback, start_time
404
+ )
405
+ elif event["event"] in CHAIN_EVENT_HANDLERS:
406
+ chain_handler = CHAIN_EVENT_HANDLERS[event["event"]]
407
+
408
+ # Check if this is a streaming event
409
+ if event["event"] in ("on_chain_stream", "on_chat_model_stream"):
410
+ had_streaming = True
411
+ agent_message, start_time = await chain_handler(
412
+ event,
413
+ agent_message,
414
+ send_message_callback,
415
+ send_token_callback,
416
+ start_time,
417
+ had_streaming=had_streaming,
418
+ message_id=initial_message_id,
419
+ )
420
+ else:
421
+ agent_message, start_time = await chain_handler(
422
+ event, agent_message, send_message_callback, None, start_time, had_streaming=had_streaming
423
+ )
424
+
425
+ agent_message.properties.state = "complete"
426
+ # Final DB update with the complete message (skip_db_update=False by default)
427
+ agent_message = await send_message_callback(message=agent_message)
428
+ except Exception as e:
429
+ raise ExceptionWithMessageError(agent_message, str(e)) from e
430
+ return await Message.create(**agent_message.model_dump())
@@ -0,0 +1,237 @@
1
+ import re
2
+ from collections.abc import Callable, Sequence
3
+ from typing import Any
4
+
5
+ from langchain.agents import (
6
+ create_json_chat_agent,
7
+ create_openai_tools_agent,
8
+ create_tool_calling_agent,
9
+ create_xml_agent,
10
+ )
11
+ from langchain.agents.xml.base import render_text_description
12
+ from langchain_core.language_models import BaseLanguageModel
13
+ from langchain_core.messages import BaseMessage
14
+ from langchain_core.prompts import BasePromptTemplate, ChatPromptTemplate
15
+ from langchain_core.tools import BaseTool
16
+ from pydantic import BaseModel
17
+
18
+ from lfx.log.logger import logger
19
+ from lfx.schema.data import Data
20
+ from lfx.schema.message import Message
21
+ from lfx.services.cache.base import CacheService
22
+ from lfx.services.cache.utils import CacheMiss
23
+
24
+ from .default_prompts import XML_AGENT_PROMPT
25
+
26
+
27
+ class AgentSpec(BaseModel):
28
+ func: Callable[
29
+ [
30
+ BaseLanguageModel,
31
+ Sequence[BaseTool],
32
+ BasePromptTemplate | ChatPromptTemplate,
33
+ Callable[[list[BaseTool]], str] | None,
34
+ bool | list[str] | None,
35
+ ],
36
+ Any,
37
+ ]
38
+ prompt: Any | None = None
39
+ fields: list[str]
40
+ hub_repo: str | None = None
41
+
42
+
43
+ def data_to_messages(data: list[Data | Message]) -> list[BaseMessage]:
44
+ """Convert a list of data to a list of messages.
45
+
46
+ Args:
47
+ data (List[Data | Message]): The data to convert.
48
+
49
+ Returns:
50
+ List[BaseMessage]: The data as messages, filtering out any with empty content.
51
+ """
52
+ messages = []
53
+ for value in data:
54
+ try:
55
+ lc_message = value.to_lc_message()
56
+ # Only add messages with non-empty content (prevents Anthropic API errors)
57
+ content = lc_message.content
58
+ if content and ((isinstance(content, str) and content.strip()) or (isinstance(content, list) and content)):
59
+ messages.append(lc_message)
60
+ else:
61
+ logger.warning("Skipping message with empty content in chat history")
62
+ except (ValueError, AttributeError) as e:
63
+ logger.warning(f"Failed to convert message to BaseMessage: {e}")
64
+ continue
65
+ return messages
66
+
67
+
68
+ def validate_and_create_xml_agent(
69
+ llm: BaseLanguageModel,
70
+ tools: Sequence[BaseTool],
71
+ prompt: BasePromptTemplate,
72
+ tools_renderer: Callable[[list[BaseTool]], str] = render_text_description,
73
+ *,
74
+ stop_sequence: bool | list[str] = True,
75
+ ):
76
+ return create_xml_agent(
77
+ llm=llm,
78
+ tools=tools,
79
+ prompt=prompt,
80
+ tools_renderer=tools_renderer,
81
+ stop_sequence=stop_sequence,
82
+ )
83
+
84
+
85
+ def validate_and_create_openai_tools_agent(
86
+ llm: BaseLanguageModel,
87
+ tools: Sequence[BaseTool],
88
+ prompt: ChatPromptTemplate,
89
+ _tools_renderer: Callable[[list[BaseTool]], str] = render_text_description,
90
+ *,
91
+ _stop_sequence: bool | list[str] = True,
92
+ ):
93
+ return create_openai_tools_agent(
94
+ llm=llm,
95
+ tools=tools,
96
+ prompt=prompt,
97
+ )
98
+
99
+
100
+ def validate_and_create_tool_calling_agent(
101
+ llm: BaseLanguageModel,
102
+ tools: Sequence[BaseTool],
103
+ prompt: ChatPromptTemplate,
104
+ _tools_renderer: Callable[[list[BaseTool]], str] = render_text_description,
105
+ *,
106
+ _stop_sequence: bool | list[str] = True,
107
+ ):
108
+ return create_tool_calling_agent(
109
+ llm=llm,
110
+ tools=tools,
111
+ prompt=prompt,
112
+ )
113
+
114
+
115
+ def validate_and_create_json_chat_agent(
116
+ llm: BaseLanguageModel,
117
+ tools: Sequence[BaseTool],
118
+ prompt: ChatPromptTemplate,
119
+ tools_renderer: Callable[[list[BaseTool]], str] = render_text_description,
120
+ *,
121
+ stop_sequence: bool | list[str] = True,
122
+ ):
123
+ return create_json_chat_agent(
124
+ llm=llm,
125
+ tools=tools,
126
+ prompt=prompt,
127
+ tools_renderer=tools_renderer,
128
+ stop_sequence=stop_sequence,
129
+ )
130
+
131
+
132
+ AGENTS: dict[str, AgentSpec] = {
133
+ "Tool Calling Agent": AgentSpec(
134
+ func=validate_and_create_tool_calling_agent,
135
+ prompt=None,
136
+ fields=["llm", "tools", "prompt"],
137
+ hub_repo=None,
138
+ ),
139
+ "XML Agent": AgentSpec(
140
+ func=validate_and_create_xml_agent,
141
+ prompt=XML_AGENT_PROMPT, # Ensure XML_AGENT_PROMPT is properly defined and typed.
142
+ fields=["llm", "tools", "prompt", "tools_renderer", "stop_sequence"],
143
+ hub_repo="hwchase17/xml-agent-convo",
144
+ ),
145
+ "OpenAI Tools Agent": AgentSpec(
146
+ func=validate_and_create_openai_tools_agent,
147
+ prompt=None,
148
+ fields=["llm", "tools", "prompt"],
149
+ hub_repo=None,
150
+ ),
151
+ "JSON Chat Agent": AgentSpec(
152
+ func=validate_and_create_json_chat_agent,
153
+ prompt=None,
154
+ fields=["llm", "tools", "prompt", "tools_renderer", "stop_sequence"],
155
+ hub_repo="hwchase17/react-chat-json",
156
+ ),
157
+ }
158
+
159
+
160
+ def get_agents_list():
161
+ return list(AGENTS.keys())
162
+
163
+
164
+ def safe_cache_get(cache: CacheService, key, default=None):
165
+ """Safely get a value from cache, handling CacheMiss objects."""
166
+ try:
167
+ value = cache.get(key)
168
+ if isinstance(value, CacheMiss):
169
+ return default
170
+ except (AttributeError, KeyError, TypeError):
171
+ return default
172
+ else:
173
+ return value
174
+
175
+
176
+ def safe_cache_set(cache: CacheService, key, value):
177
+ """Safely set a value in cache, handling potential errors."""
178
+ try:
179
+ cache.set(key, value)
180
+ except (AttributeError, TypeError) as e:
181
+ logger.warning(f"Failed to set cache key '{key}': {e}")
182
+
183
+
184
+ def maybe_unflatten_dict(flat: dict[str, Any]) -> dict[str, Any]:
185
+ """If any key looks nested (contains a dot or "[index]"), rebuild the.
186
+
187
+ full nested structure; otherwise return flat as is.
188
+ """
189
+ # Quick check: do we have any nested keys?
190
+ if not any(re.search(r"\.|\[\d+\]", key) for key in flat):
191
+ return flat
192
+
193
+ # Otherwise, unflatten into dicts/lists
194
+ nested: dict[str, Any] = {}
195
+ array_re = re.compile(r"^(.+)\[(\d+)\]$")
196
+
197
+ for key, val in flat.items():
198
+ parts = key.split(".")
199
+ cur = nested
200
+ for i, part in enumerate(parts):
201
+ m = array_re.match(part)
202
+ # Array segment?
203
+ if m:
204
+ name, idx = m.group(1), int(m.group(2))
205
+ lst = cur.setdefault(name, [])
206
+ # Ensure list is big enough
207
+ while len(lst) <= idx:
208
+ lst.append({})
209
+ if i == len(parts) - 1:
210
+ lst[idx] = val
211
+ else:
212
+ cur = lst[idx]
213
+ # Normal object key
214
+ elif i == len(parts) - 1:
215
+ cur[part] = val
216
+ else:
217
+ cur = cur.setdefault(part, {})
218
+
219
+ return nested
220
+
221
+
222
+ def get_chat_output_sender_name(self) -> str | None:
223
+ """Get sender_name from ChatOutput component."""
224
+ if not hasattr(self, "graph") or not self.graph:
225
+ return None
226
+
227
+ for vertex in self.graph.vertices:
228
+ # Safely check if vertex has data attribute, correct type, and raw_params
229
+ if (
230
+ hasattr(vertex, "data")
231
+ and vertex.data.get("type") == "ChatOutput"
232
+ and hasattr(vertex, "raw_params")
233
+ and vertex.raw_params
234
+ ):
235
+ return vertex.raw_params.get("sender_name")
236
+
237
+ return None
File without changes