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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (699) hide show
  1. lfx/__init__.py +0 -0
  2. lfx/__main__.py +25 -0
  3. lfx/base/__init__.py +0 -0
  4. lfx/base/agents/__init__.py +0 -0
  5. lfx/base/agents/agent.py +268 -0
  6. lfx/base/agents/callback.py +130 -0
  7. lfx/base/agents/context.py +109 -0
  8. lfx/base/agents/crewai/__init__.py +0 -0
  9. lfx/base/agents/crewai/crew.py +231 -0
  10. lfx/base/agents/crewai/tasks.py +12 -0
  11. lfx/base/agents/default_prompts.py +23 -0
  12. lfx/base/agents/errors.py +15 -0
  13. lfx/base/agents/events.py +346 -0
  14. lfx/base/agents/utils.py +205 -0
  15. lfx/base/astra_assistants/__init__.py +0 -0
  16. lfx/base/astra_assistants/util.py +171 -0
  17. lfx/base/chains/__init__.py +0 -0
  18. lfx/base/chains/model.py +19 -0
  19. lfx/base/composio/__init__.py +0 -0
  20. lfx/base/composio/composio_base.py +1291 -0
  21. lfx/base/compressors/__init__.py +0 -0
  22. lfx/base/compressors/model.py +60 -0
  23. lfx/base/constants.py +46 -0
  24. lfx/base/curl/__init__.py +0 -0
  25. lfx/base/curl/parse.py +188 -0
  26. lfx/base/data/__init__.py +5 -0
  27. lfx/base/data/base_file.py +685 -0
  28. lfx/base/data/docling_utils.py +245 -0
  29. lfx/base/data/utils.py +198 -0
  30. lfx/base/document_transformers/__init__.py +0 -0
  31. lfx/base/document_transformers/model.py +43 -0
  32. lfx/base/embeddings/__init__.py +0 -0
  33. lfx/base/embeddings/aiml_embeddings.py +62 -0
  34. lfx/base/embeddings/model.py +26 -0
  35. lfx/base/flow_processing/__init__.py +0 -0
  36. lfx/base/flow_processing/utils.py +86 -0
  37. lfx/base/huggingface/__init__.py +0 -0
  38. lfx/base/huggingface/model_bridge.py +133 -0
  39. lfx/base/io/__init__.py +0 -0
  40. lfx/base/io/chat.py +20 -0
  41. lfx/base/io/text.py +22 -0
  42. lfx/base/langchain_utilities/__init__.py +0 -0
  43. lfx/base/langchain_utilities/model.py +35 -0
  44. lfx/base/langchain_utilities/spider_constants.py +1 -0
  45. lfx/base/langwatch/__init__.py +0 -0
  46. lfx/base/langwatch/utils.py +18 -0
  47. lfx/base/mcp/__init__.py +0 -0
  48. lfx/base/mcp/constants.py +2 -0
  49. lfx/base/mcp/util.py +1398 -0
  50. lfx/base/memory/__init__.py +0 -0
  51. lfx/base/memory/memory.py +49 -0
  52. lfx/base/memory/model.py +38 -0
  53. lfx/base/models/__init__.py +3 -0
  54. lfx/base/models/aiml_constants.py +51 -0
  55. lfx/base/models/anthropic_constants.py +47 -0
  56. lfx/base/models/aws_constants.py +151 -0
  57. lfx/base/models/chat_result.py +76 -0
  58. lfx/base/models/google_generative_ai_constants.py +70 -0
  59. lfx/base/models/groq_constants.py +134 -0
  60. lfx/base/models/model.py +375 -0
  61. lfx/base/models/model_input_constants.py +307 -0
  62. lfx/base/models/model_metadata.py +41 -0
  63. lfx/base/models/model_utils.py +8 -0
  64. lfx/base/models/novita_constants.py +35 -0
  65. lfx/base/models/ollama_constants.py +49 -0
  66. lfx/base/models/openai_constants.py +122 -0
  67. lfx/base/models/sambanova_constants.py +18 -0
  68. lfx/base/processing/__init__.py +0 -0
  69. lfx/base/prompts/__init__.py +0 -0
  70. lfx/base/prompts/api_utils.py +224 -0
  71. lfx/base/prompts/utils.py +61 -0
  72. lfx/base/textsplitters/__init__.py +0 -0
  73. lfx/base/textsplitters/model.py +28 -0
  74. lfx/base/tools/__init__.py +0 -0
  75. lfx/base/tools/base.py +26 -0
  76. lfx/base/tools/component_tool.py +325 -0
  77. lfx/base/tools/constants.py +49 -0
  78. lfx/base/tools/flow_tool.py +132 -0
  79. lfx/base/tools/run_flow.py +224 -0
  80. lfx/base/vectorstores/__init__.py +0 -0
  81. lfx/base/vectorstores/model.py +193 -0
  82. lfx/base/vectorstores/utils.py +22 -0
  83. lfx/base/vectorstores/vector_store_connection_decorator.py +52 -0
  84. lfx/cli/__init__.py +5 -0
  85. lfx/cli/commands.py +319 -0
  86. lfx/cli/common.py +650 -0
  87. lfx/cli/run.py +441 -0
  88. lfx/cli/script_loader.py +247 -0
  89. lfx/cli/serve_app.py +546 -0
  90. lfx/cli/validation.py +69 -0
  91. lfx/components/FAISS/__init__.py +34 -0
  92. lfx/components/FAISS/faiss.py +111 -0
  93. lfx/components/Notion/__init__.py +19 -0
  94. lfx/components/Notion/add_content_to_page.py +269 -0
  95. lfx/components/Notion/create_page.py +94 -0
  96. lfx/components/Notion/list_database_properties.py +68 -0
  97. lfx/components/Notion/list_pages.py +122 -0
  98. lfx/components/Notion/list_users.py +77 -0
  99. lfx/components/Notion/page_content_viewer.py +93 -0
  100. lfx/components/Notion/search.py +111 -0
  101. lfx/components/Notion/update_page_property.py +114 -0
  102. lfx/components/__init__.py +411 -0
  103. lfx/components/_importing.py +42 -0
  104. lfx/components/agentql/__init__.py +3 -0
  105. lfx/components/agentql/agentql_api.py +151 -0
  106. lfx/components/agents/__init__.py +34 -0
  107. lfx/components/agents/agent.py +558 -0
  108. lfx/components/agents/mcp_component.py +501 -0
  109. lfx/components/aiml/__init__.py +37 -0
  110. lfx/components/aiml/aiml.py +112 -0
  111. lfx/components/aiml/aiml_embeddings.py +37 -0
  112. lfx/components/amazon/__init__.py +36 -0
  113. lfx/components/amazon/amazon_bedrock_embedding.py +109 -0
  114. lfx/components/amazon/amazon_bedrock_model.py +124 -0
  115. lfx/components/amazon/s3_bucket_uploader.py +211 -0
  116. lfx/components/anthropic/__init__.py +34 -0
  117. lfx/components/anthropic/anthropic.py +187 -0
  118. lfx/components/apify/__init__.py +5 -0
  119. lfx/components/apify/apify_actor.py +325 -0
  120. lfx/components/arxiv/__init__.py +3 -0
  121. lfx/components/arxiv/arxiv.py +163 -0
  122. lfx/components/assemblyai/__init__.py +46 -0
  123. lfx/components/assemblyai/assemblyai_get_subtitles.py +83 -0
  124. lfx/components/assemblyai/assemblyai_lemur.py +183 -0
  125. lfx/components/assemblyai/assemblyai_list_transcripts.py +95 -0
  126. lfx/components/assemblyai/assemblyai_poll_transcript.py +72 -0
  127. lfx/components/assemblyai/assemblyai_start_transcript.py +188 -0
  128. lfx/components/azure/__init__.py +37 -0
  129. lfx/components/azure/azure_openai.py +95 -0
  130. lfx/components/azure/azure_openai_embeddings.py +83 -0
  131. lfx/components/baidu/__init__.py +32 -0
  132. lfx/components/baidu/baidu_qianfan_chat.py +113 -0
  133. lfx/components/bing/__init__.py +3 -0
  134. lfx/components/bing/bing_search_api.py +61 -0
  135. lfx/components/cassandra/__init__.py +40 -0
  136. lfx/components/cassandra/cassandra.py +264 -0
  137. lfx/components/cassandra/cassandra_chat.py +92 -0
  138. lfx/components/cassandra/cassandra_graph.py +238 -0
  139. lfx/components/chains/__init__.py +3 -0
  140. lfx/components/chroma/__init__.py +34 -0
  141. lfx/components/chroma/chroma.py +167 -0
  142. lfx/components/cleanlab/__init__.py +40 -0
  143. lfx/components/cleanlab/cleanlab_evaluator.py +155 -0
  144. lfx/components/cleanlab/cleanlab_rag_evaluator.py +254 -0
  145. lfx/components/cleanlab/cleanlab_remediator.py +131 -0
  146. lfx/components/clickhouse/__init__.py +34 -0
  147. lfx/components/clickhouse/clickhouse.py +135 -0
  148. lfx/components/cloudflare/__init__.py +32 -0
  149. lfx/components/cloudflare/cloudflare.py +81 -0
  150. lfx/components/cohere/__init__.py +40 -0
  151. lfx/components/cohere/cohere_embeddings.py +81 -0
  152. lfx/components/cohere/cohere_models.py +46 -0
  153. lfx/components/cohere/cohere_rerank.py +51 -0
  154. lfx/components/composio/__init__.py +74 -0
  155. lfx/components/composio/composio_api.py +268 -0
  156. lfx/components/composio/dropbox_compnent.py +11 -0
  157. lfx/components/composio/github_composio.py +11 -0
  158. lfx/components/composio/gmail_composio.py +38 -0
  159. lfx/components/composio/googlecalendar_composio.py +11 -0
  160. lfx/components/composio/googlemeet_composio.py +11 -0
  161. lfx/components/composio/googletasks_composio.py +8 -0
  162. lfx/components/composio/linear_composio.py +11 -0
  163. lfx/components/composio/outlook_composio.py +11 -0
  164. lfx/components/composio/reddit_composio.py +11 -0
  165. lfx/components/composio/slack_composio.py +582 -0
  166. lfx/components/composio/slackbot_composio.py +11 -0
  167. lfx/components/composio/supabase_composio.py +11 -0
  168. lfx/components/composio/todoist_composio.py +11 -0
  169. lfx/components/composio/youtube_composio.py +11 -0
  170. lfx/components/confluence/__init__.py +3 -0
  171. lfx/components/confluence/confluence.py +84 -0
  172. lfx/components/couchbase/__init__.py +34 -0
  173. lfx/components/couchbase/couchbase.py +102 -0
  174. lfx/components/crewai/__init__.py +49 -0
  175. lfx/components/crewai/crewai.py +107 -0
  176. lfx/components/crewai/hierarchical_crew.py +46 -0
  177. lfx/components/crewai/hierarchical_task.py +44 -0
  178. lfx/components/crewai/sequential_crew.py +52 -0
  179. lfx/components/crewai/sequential_task.py +73 -0
  180. lfx/components/crewai/sequential_task_agent.py +143 -0
  181. lfx/components/custom_component/__init__.py +34 -0
  182. lfx/components/custom_component/custom_component.py +31 -0
  183. lfx/components/data/__init__.py +64 -0
  184. lfx/components/data/api_request.py +544 -0
  185. lfx/components/data/csv_to_data.py +95 -0
  186. lfx/components/data/directory.py +113 -0
  187. lfx/components/data/file.py +577 -0
  188. lfx/components/data/json_to_data.py +98 -0
  189. lfx/components/data/news_search.py +164 -0
  190. lfx/components/data/rss.py +69 -0
  191. lfx/components/data/sql_executor.py +101 -0
  192. lfx/components/data/url.py +311 -0
  193. lfx/components/data/web_search.py +112 -0
  194. lfx/components/data/webhook.py +56 -0
  195. lfx/components/datastax/__init__.py +70 -0
  196. lfx/components/datastax/astra_assistant_manager.py +306 -0
  197. lfx/components/datastax/astra_db.py +75 -0
  198. lfx/components/datastax/astra_vectorize.py +124 -0
  199. lfx/components/datastax/astradb.py +1285 -0
  200. lfx/components/datastax/astradb_cql.py +314 -0
  201. lfx/components/datastax/astradb_graph.py +330 -0
  202. lfx/components/datastax/astradb_tool.py +414 -0
  203. lfx/components/datastax/astradb_vectorstore.py +1285 -0
  204. lfx/components/datastax/cassandra.py +92 -0
  205. lfx/components/datastax/create_assistant.py +58 -0
  206. lfx/components/datastax/create_thread.py +32 -0
  207. lfx/components/datastax/dotenv.py +35 -0
  208. lfx/components/datastax/get_assistant.py +37 -0
  209. lfx/components/datastax/getenvvar.py +30 -0
  210. lfx/components/datastax/graph_rag.py +141 -0
  211. lfx/components/datastax/hcd.py +314 -0
  212. lfx/components/datastax/list_assistants.py +25 -0
  213. lfx/components/datastax/run.py +89 -0
  214. lfx/components/deactivated/__init__.py +15 -0
  215. lfx/components/deactivated/amazon_kendra.py +66 -0
  216. lfx/components/deactivated/chat_litellm_model.py +158 -0
  217. lfx/components/deactivated/code_block_extractor.py +26 -0
  218. lfx/components/deactivated/documents_to_data.py +22 -0
  219. lfx/components/deactivated/embed.py +16 -0
  220. lfx/components/deactivated/extract_key_from_data.py +46 -0
  221. lfx/components/deactivated/json_document_builder.py +57 -0
  222. lfx/components/deactivated/list_flows.py +20 -0
  223. lfx/components/deactivated/mcp_sse.py +61 -0
  224. lfx/components/deactivated/mcp_stdio.py +62 -0
  225. lfx/components/deactivated/merge_data.py +93 -0
  226. lfx/components/deactivated/message.py +37 -0
  227. lfx/components/deactivated/metal.py +54 -0
  228. lfx/components/deactivated/multi_query.py +59 -0
  229. lfx/components/deactivated/retriever.py +43 -0
  230. lfx/components/deactivated/selective_passthrough.py +77 -0
  231. lfx/components/deactivated/should_run_next.py +40 -0
  232. lfx/components/deactivated/split_text.py +63 -0
  233. lfx/components/deactivated/store_message.py +24 -0
  234. lfx/components/deactivated/sub_flow.py +124 -0
  235. lfx/components/deactivated/vectara_self_query.py +76 -0
  236. lfx/components/deactivated/vector_store.py +24 -0
  237. lfx/components/deepseek/__init__.py +34 -0
  238. lfx/components/deepseek/deepseek.py +136 -0
  239. lfx/components/docling/__init__.py +43 -0
  240. lfx/components/docling/chunk_docling_document.py +186 -0
  241. lfx/components/docling/docling_inline.py +231 -0
  242. lfx/components/docling/docling_remote.py +193 -0
  243. lfx/components/docling/export_docling_document.py +117 -0
  244. lfx/components/documentloaders/__init__.py +3 -0
  245. lfx/components/duckduckgo/__init__.py +3 -0
  246. lfx/components/duckduckgo/duck_duck_go_search_run.py +92 -0
  247. lfx/components/elastic/__init__.py +37 -0
  248. lfx/components/elastic/elasticsearch.py +267 -0
  249. lfx/components/elastic/opensearch.py +243 -0
  250. lfx/components/embeddings/__init__.py +37 -0
  251. lfx/components/embeddings/similarity.py +76 -0
  252. lfx/components/embeddings/text_embedder.py +64 -0
  253. lfx/components/exa/__init__.py +3 -0
  254. lfx/components/exa/exa_search.py +68 -0
  255. lfx/components/firecrawl/__init__.py +43 -0
  256. lfx/components/firecrawl/firecrawl_crawl_api.py +88 -0
  257. lfx/components/firecrawl/firecrawl_extract_api.py +136 -0
  258. lfx/components/firecrawl/firecrawl_map_api.py +89 -0
  259. lfx/components/firecrawl/firecrawl_scrape_api.py +73 -0
  260. lfx/components/git/__init__.py +4 -0
  261. lfx/components/git/git.py +262 -0
  262. lfx/components/git/gitextractor.py +196 -0
  263. lfx/components/glean/__init__.py +3 -0
  264. lfx/components/glean/glean_search_api.py +173 -0
  265. lfx/components/google/__init__.py +17 -0
  266. lfx/components/google/gmail.py +192 -0
  267. lfx/components/google/google_bq_sql_executor.py +157 -0
  268. lfx/components/google/google_drive.py +92 -0
  269. lfx/components/google/google_drive_search.py +152 -0
  270. lfx/components/google/google_generative_ai.py +147 -0
  271. lfx/components/google/google_generative_ai_embeddings.py +141 -0
  272. lfx/components/google/google_oauth_token.py +89 -0
  273. lfx/components/google/google_search_api_core.py +68 -0
  274. lfx/components/google/google_serper_api_core.py +74 -0
  275. lfx/components/groq/__init__.py +34 -0
  276. lfx/components/groq/groq.py +136 -0
  277. lfx/components/helpers/__init__.py +52 -0
  278. lfx/components/helpers/calculator_core.py +89 -0
  279. lfx/components/helpers/create_list.py +40 -0
  280. lfx/components/helpers/current_date.py +42 -0
  281. lfx/components/helpers/id_generator.py +42 -0
  282. lfx/components/helpers/memory.py +251 -0
  283. lfx/components/helpers/output_parser.py +45 -0
  284. lfx/components/helpers/store_message.py +90 -0
  285. lfx/components/homeassistant/__init__.py +7 -0
  286. lfx/components/homeassistant/home_assistant_control.py +152 -0
  287. lfx/components/homeassistant/list_home_assistant_states.py +137 -0
  288. lfx/components/huggingface/__init__.py +37 -0
  289. lfx/components/huggingface/huggingface.py +197 -0
  290. lfx/components/huggingface/huggingface_inference_api.py +106 -0
  291. lfx/components/ibm/__init__.py +34 -0
  292. lfx/components/ibm/watsonx.py +203 -0
  293. lfx/components/ibm/watsonx_embeddings.py +135 -0
  294. lfx/components/icosacomputing/__init__.py +5 -0
  295. lfx/components/icosacomputing/combinatorial_reasoner.py +84 -0
  296. lfx/components/input_output/__init__.py +38 -0
  297. lfx/components/input_output/chat.py +120 -0
  298. lfx/components/input_output/chat_output.py +200 -0
  299. lfx/components/input_output/text.py +27 -0
  300. lfx/components/input_output/text_output.py +29 -0
  301. lfx/components/jigsawstack/__init__.py +23 -0
  302. lfx/components/jigsawstack/ai_scrape.py +126 -0
  303. lfx/components/jigsawstack/ai_web_search.py +136 -0
  304. lfx/components/jigsawstack/file_read.py +115 -0
  305. lfx/components/jigsawstack/file_upload.py +94 -0
  306. lfx/components/jigsawstack/image_generation.py +205 -0
  307. lfx/components/jigsawstack/nsfw.py +60 -0
  308. lfx/components/jigsawstack/object_detection.py +124 -0
  309. lfx/components/jigsawstack/sentiment.py +112 -0
  310. lfx/components/jigsawstack/text_to_sql.py +90 -0
  311. lfx/components/jigsawstack/text_translate.py +77 -0
  312. lfx/components/jigsawstack/vocr.py +107 -0
  313. lfx/components/langchain_utilities/__init__.py +109 -0
  314. lfx/components/langchain_utilities/character.py +53 -0
  315. lfx/components/langchain_utilities/conversation.py +59 -0
  316. lfx/components/langchain_utilities/csv_agent.py +107 -0
  317. lfx/components/langchain_utilities/fake_embeddings.py +26 -0
  318. lfx/components/langchain_utilities/html_link_extractor.py +35 -0
  319. lfx/components/langchain_utilities/json_agent.py +45 -0
  320. lfx/components/langchain_utilities/langchain_hub.py +126 -0
  321. lfx/components/langchain_utilities/language_recursive.py +49 -0
  322. lfx/components/langchain_utilities/language_semantic.py +138 -0
  323. lfx/components/langchain_utilities/llm_checker.py +39 -0
  324. lfx/components/langchain_utilities/llm_math.py +42 -0
  325. lfx/components/langchain_utilities/natural_language.py +61 -0
  326. lfx/components/langchain_utilities/openai_tools.py +53 -0
  327. lfx/components/langchain_utilities/openapi.py +48 -0
  328. lfx/components/langchain_utilities/recursive_character.py +60 -0
  329. lfx/components/langchain_utilities/retrieval_qa.py +83 -0
  330. lfx/components/langchain_utilities/runnable_executor.py +137 -0
  331. lfx/components/langchain_utilities/self_query.py +80 -0
  332. lfx/components/langchain_utilities/spider.py +142 -0
  333. lfx/components/langchain_utilities/sql.py +40 -0
  334. lfx/components/langchain_utilities/sql_database.py +35 -0
  335. lfx/components/langchain_utilities/sql_generator.py +78 -0
  336. lfx/components/langchain_utilities/tool_calling.py +59 -0
  337. lfx/components/langchain_utilities/vector_store_info.py +49 -0
  338. lfx/components/langchain_utilities/vector_store_router.py +33 -0
  339. lfx/components/langchain_utilities/xml_agent.py +71 -0
  340. lfx/components/langwatch/__init__.py +3 -0
  341. lfx/components/langwatch/langwatch.py +278 -0
  342. lfx/components/link_extractors/__init__.py +3 -0
  343. lfx/components/lmstudio/__init__.py +34 -0
  344. lfx/components/lmstudio/lmstudioembeddings.py +89 -0
  345. lfx/components/lmstudio/lmstudiomodel.py +129 -0
  346. lfx/components/logic/__init__.py +52 -0
  347. lfx/components/logic/conditional_router.py +171 -0
  348. lfx/components/logic/data_conditional_router.py +125 -0
  349. lfx/components/logic/flow_tool.py +110 -0
  350. lfx/components/logic/listen.py +29 -0
  351. lfx/components/logic/loop.py +125 -0
  352. lfx/components/logic/notify.py +88 -0
  353. lfx/components/logic/pass_message.py +35 -0
  354. lfx/components/logic/run_flow.py +71 -0
  355. lfx/components/logic/sub_flow.py +114 -0
  356. lfx/components/maritalk/__init__.py +32 -0
  357. lfx/components/maritalk/maritalk.py +52 -0
  358. lfx/components/mem0/__init__.py +3 -0
  359. lfx/components/mem0/mem0_chat_memory.py +136 -0
  360. lfx/components/milvus/__init__.py +34 -0
  361. lfx/components/milvus/milvus.py +115 -0
  362. lfx/components/mistral/__init__.py +37 -0
  363. lfx/components/mistral/mistral.py +114 -0
  364. lfx/components/mistral/mistral_embeddings.py +58 -0
  365. lfx/components/models/__init__.py +34 -0
  366. lfx/components/models/embedding_model.py +114 -0
  367. lfx/components/models/language_model.py +144 -0
  368. lfx/components/mongodb/__init__.py +34 -0
  369. lfx/components/mongodb/mongodb_atlas.py +213 -0
  370. lfx/components/needle/__init__.py +3 -0
  371. lfx/components/needle/needle.py +104 -0
  372. lfx/components/notdiamond/__init__.py +34 -0
  373. lfx/components/notdiamond/notdiamond.py +228 -0
  374. lfx/components/novita/__init__.py +32 -0
  375. lfx/components/novita/novita.py +130 -0
  376. lfx/components/nvidia/__init__.py +57 -0
  377. lfx/components/nvidia/nvidia.py +157 -0
  378. lfx/components/nvidia/nvidia_embedding.py +77 -0
  379. lfx/components/nvidia/nvidia_ingest.py +317 -0
  380. lfx/components/nvidia/nvidia_rerank.py +63 -0
  381. lfx/components/nvidia/system_assist.py +65 -0
  382. lfx/components/olivya/__init__.py +3 -0
  383. lfx/components/olivya/olivya.py +116 -0
  384. lfx/components/ollama/__init__.py +37 -0
  385. lfx/components/ollama/ollama.py +330 -0
  386. lfx/components/ollama/ollama_embeddings.py +106 -0
  387. lfx/components/openai/__init__.py +37 -0
  388. lfx/components/openai/openai.py +100 -0
  389. lfx/components/openai/openai_chat_model.py +176 -0
  390. lfx/components/openrouter/__init__.py +32 -0
  391. lfx/components/openrouter/openrouter.py +202 -0
  392. lfx/components/output_parsers/__init__.py +3 -0
  393. lfx/components/perplexity/__init__.py +34 -0
  394. lfx/components/perplexity/perplexity.py +75 -0
  395. lfx/components/pgvector/__init__.py +34 -0
  396. lfx/components/pgvector/pgvector.py +72 -0
  397. lfx/components/pinecone/__init__.py +34 -0
  398. lfx/components/pinecone/pinecone.py +134 -0
  399. lfx/components/processing/__init__.py +117 -0
  400. lfx/components/processing/alter_metadata.py +108 -0
  401. lfx/components/processing/batch_run.py +205 -0
  402. lfx/components/processing/combine_text.py +39 -0
  403. lfx/components/processing/converter.py +159 -0
  404. lfx/components/processing/create_data.py +110 -0
  405. lfx/components/processing/data_operations.py +438 -0
  406. lfx/components/processing/data_to_dataframe.py +70 -0
  407. lfx/components/processing/dataframe_operations.py +313 -0
  408. lfx/components/processing/extract_key.py +53 -0
  409. lfx/components/processing/filter_data.py +42 -0
  410. lfx/components/processing/filter_data_values.py +88 -0
  411. lfx/components/processing/json_cleaner.py +103 -0
  412. lfx/components/processing/lambda_filter.py +154 -0
  413. lfx/components/processing/llm_router.py +499 -0
  414. lfx/components/processing/merge_data.py +90 -0
  415. lfx/components/processing/message_to_data.py +36 -0
  416. lfx/components/processing/parse_data.py +70 -0
  417. lfx/components/processing/parse_dataframe.py +68 -0
  418. lfx/components/processing/parse_json_data.py +90 -0
  419. lfx/components/processing/parser.py +143 -0
  420. lfx/components/processing/prompt.py +67 -0
  421. lfx/components/processing/python_repl_core.py +98 -0
  422. lfx/components/processing/regex.py +82 -0
  423. lfx/components/processing/save_file.py +225 -0
  424. lfx/components/processing/select_data.py +48 -0
  425. lfx/components/processing/split_text.py +141 -0
  426. lfx/components/processing/structured_output.py +202 -0
  427. lfx/components/processing/update_data.py +160 -0
  428. lfx/components/prototypes/__init__.py +34 -0
  429. lfx/components/prototypes/python_function.py +73 -0
  430. lfx/components/qdrant/__init__.py +34 -0
  431. lfx/components/qdrant/qdrant.py +109 -0
  432. lfx/components/redis/__init__.py +37 -0
  433. lfx/components/redis/redis.py +89 -0
  434. lfx/components/redis/redis_chat.py +43 -0
  435. lfx/components/sambanova/__init__.py +32 -0
  436. lfx/components/sambanova/sambanova.py +84 -0
  437. lfx/components/scrapegraph/__init__.py +40 -0
  438. lfx/components/scrapegraph/scrapegraph_markdownify_api.py +64 -0
  439. lfx/components/scrapegraph/scrapegraph_search_api.py +64 -0
  440. lfx/components/scrapegraph/scrapegraph_smart_scraper_api.py +71 -0
  441. lfx/components/searchapi/__init__.py +34 -0
  442. lfx/components/searchapi/search.py +79 -0
  443. lfx/components/serpapi/__init__.py +3 -0
  444. lfx/components/serpapi/serp.py +115 -0
  445. lfx/components/supabase/__init__.py +34 -0
  446. lfx/components/supabase/supabase.py +76 -0
  447. lfx/components/tavily/__init__.py +4 -0
  448. lfx/components/tavily/tavily_extract.py +117 -0
  449. lfx/components/tavily/tavily_search.py +212 -0
  450. lfx/components/textsplitters/__init__.py +3 -0
  451. lfx/components/toolkits/__init__.py +3 -0
  452. lfx/components/tools/__init__.py +72 -0
  453. lfx/components/tools/calculator.py +108 -0
  454. lfx/components/tools/google_search_api.py +45 -0
  455. lfx/components/tools/google_serper_api.py +115 -0
  456. lfx/components/tools/python_code_structured_tool.py +327 -0
  457. lfx/components/tools/python_repl.py +97 -0
  458. lfx/components/tools/search_api.py +87 -0
  459. lfx/components/tools/searxng.py +145 -0
  460. lfx/components/tools/serp_api.py +119 -0
  461. lfx/components/tools/tavily_search_tool.py +344 -0
  462. lfx/components/tools/wikidata_api.py +102 -0
  463. lfx/components/tools/wikipedia_api.py +49 -0
  464. lfx/components/tools/yahoo_finance.py +129 -0
  465. lfx/components/twelvelabs/__init__.py +52 -0
  466. lfx/components/twelvelabs/convert_astra_results.py +84 -0
  467. lfx/components/twelvelabs/pegasus_index.py +311 -0
  468. lfx/components/twelvelabs/split_video.py +291 -0
  469. lfx/components/twelvelabs/text_embeddings.py +57 -0
  470. lfx/components/twelvelabs/twelvelabs_pegasus.py +408 -0
  471. lfx/components/twelvelabs/video_embeddings.py +100 -0
  472. lfx/components/twelvelabs/video_file.py +179 -0
  473. lfx/components/unstructured/__init__.py +3 -0
  474. lfx/components/unstructured/unstructured.py +121 -0
  475. lfx/components/upstash/__init__.py +34 -0
  476. lfx/components/upstash/upstash.py +124 -0
  477. lfx/components/vectara/__init__.py +37 -0
  478. lfx/components/vectara/vectara.py +97 -0
  479. lfx/components/vectara/vectara_rag.py +164 -0
  480. lfx/components/vectorstores/__init__.py +40 -0
  481. lfx/components/vectorstores/astradb.py +1285 -0
  482. lfx/components/vectorstores/astradb_graph.py +319 -0
  483. lfx/components/vectorstores/cassandra.py +264 -0
  484. lfx/components/vectorstores/cassandra_graph.py +238 -0
  485. lfx/components/vectorstores/chroma.py +167 -0
  486. lfx/components/vectorstores/clickhouse.py +135 -0
  487. lfx/components/vectorstores/couchbase.py +102 -0
  488. lfx/components/vectorstores/elasticsearch.py +267 -0
  489. lfx/components/vectorstores/faiss.py +111 -0
  490. lfx/components/vectorstores/graph_rag.py +141 -0
  491. lfx/components/vectorstores/hcd.py +314 -0
  492. lfx/components/vectorstores/local_db.py +261 -0
  493. lfx/components/vectorstores/milvus.py +115 -0
  494. lfx/components/vectorstores/mongodb_atlas.py +213 -0
  495. lfx/components/vectorstores/opensearch.py +243 -0
  496. lfx/components/vectorstores/pgvector.py +72 -0
  497. lfx/components/vectorstores/pinecone.py +134 -0
  498. lfx/components/vectorstores/qdrant.py +109 -0
  499. lfx/components/vectorstores/supabase.py +76 -0
  500. lfx/components/vectorstores/upstash.py +124 -0
  501. lfx/components/vectorstores/vectara.py +97 -0
  502. lfx/components/vectorstores/vectara_rag.py +164 -0
  503. lfx/components/vectorstores/weaviate.py +89 -0
  504. lfx/components/vertexai/__init__.py +37 -0
  505. lfx/components/vertexai/vertexai.py +71 -0
  506. lfx/components/vertexai/vertexai_embeddings.py +67 -0
  507. lfx/components/weaviate/__init__.py +34 -0
  508. lfx/components/weaviate/weaviate.py +89 -0
  509. lfx/components/wikipedia/__init__.py +4 -0
  510. lfx/components/wikipedia/wikidata.py +86 -0
  511. lfx/components/wikipedia/wikipedia.py +53 -0
  512. lfx/components/wolframalpha/__init__.py +3 -0
  513. lfx/components/wolframalpha/wolfram_alpha_api.py +54 -0
  514. lfx/components/xai/__init__.py +32 -0
  515. lfx/components/xai/xai.py +167 -0
  516. lfx/components/yahoosearch/__init__.py +3 -0
  517. lfx/components/yahoosearch/yahoo.py +137 -0
  518. lfx/components/youtube/__init__.py +52 -0
  519. lfx/components/youtube/channel.py +227 -0
  520. lfx/components/youtube/comments.py +231 -0
  521. lfx/components/youtube/playlist.py +33 -0
  522. lfx/components/youtube/search.py +120 -0
  523. lfx/components/youtube/trending.py +285 -0
  524. lfx/components/youtube/video_details.py +263 -0
  525. lfx/components/youtube/youtube_transcripts.py +118 -0
  526. lfx/components/zep/__init__.py +3 -0
  527. lfx/components/zep/zep.py +44 -0
  528. lfx/constants.py +6 -0
  529. lfx/custom/__init__.py +7 -0
  530. lfx/custom/attributes.py +86 -0
  531. lfx/custom/code_parser/__init__.py +3 -0
  532. lfx/custom/code_parser/code_parser.py +361 -0
  533. lfx/custom/custom_component/__init__.py +0 -0
  534. lfx/custom/custom_component/base_component.py +128 -0
  535. lfx/custom/custom_component/component.py +1808 -0
  536. lfx/custom/custom_component/component_with_cache.py +8 -0
  537. lfx/custom/custom_component/custom_component.py +588 -0
  538. lfx/custom/dependency_analyzer.py +165 -0
  539. lfx/custom/directory_reader/__init__.py +3 -0
  540. lfx/custom/directory_reader/directory_reader.py +359 -0
  541. lfx/custom/directory_reader/utils.py +171 -0
  542. lfx/custom/eval.py +12 -0
  543. lfx/custom/schema.py +32 -0
  544. lfx/custom/tree_visitor.py +21 -0
  545. lfx/custom/utils.py +877 -0
  546. lfx/custom/validate.py +488 -0
  547. lfx/events/__init__.py +1 -0
  548. lfx/events/event_manager.py +110 -0
  549. lfx/exceptions/__init__.py +0 -0
  550. lfx/exceptions/component.py +15 -0
  551. lfx/field_typing/__init__.py +91 -0
  552. lfx/field_typing/constants.py +215 -0
  553. lfx/field_typing/range_spec.py +35 -0
  554. lfx/graph/__init__.py +6 -0
  555. lfx/graph/edge/__init__.py +0 -0
  556. lfx/graph/edge/base.py +277 -0
  557. lfx/graph/edge/schema.py +119 -0
  558. lfx/graph/edge/utils.py +0 -0
  559. lfx/graph/graph/__init__.py +0 -0
  560. lfx/graph/graph/ascii.py +202 -0
  561. lfx/graph/graph/base.py +2238 -0
  562. lfx/graph/graph/constants.py +63 -0
  563. lfx/graph/graph/runnable_vertices_manager.py +133 -0
  564. lfx/graph/graph/schema.py +52 -0
  565. lfx/graph/graph/state_model.py +66 -0
  566. lfx/graph/graph/utils.py +1024 -0
  567. lfx/graph/schema.py +75 -0
  568. lfx/graph/state/__init__.py +0 -0
  569. lfx/graph/state/model.py +237 -0
  570. lfx/graph/utils.py +200 -0
  571. lfx/graph/vertex/__init__.py +0 -0
  572. lfx/graph/vertex/base.py +823 -0
  573. lfx/graph/vertex/constants.py +0 -0
  574. lfx/graph/vertex/exceptions.py +4 -0
  575. lfx/graph/vertex/param_handler.py +264 -0
  576. lfx/graph/vertex/schema.py +26 -0
  577. lfx/graph/vertex/utils.py +19 -0
  578. lfx/graph/vertex/vertex_types.py +489 -0
  579. lfx/helpers/__init__.py +1 -0
  580. lfx/helpers/base_model.py +71 -0
  581. lfx/helpers/custom.py +13 -0
  582. lfx/helpers/data.py +167 -0
  583. lfx/helpers/flow.py +194 -0
  584. lfx/inputs/__init__.py +68 -0
  585. lfx/inputs/constants.py +2 -0
  586. lfx/inputs/input_mixin.py +328 -0
  587. lfx/inputs/inputs.py +714 -0
  588. lfx/inputs/validators.py +19 -0
  589. lfx/interface/__init__.py +6 -0
  590. lfx/interface/components.py +489 -0
  591. lfx/interface/importing/__init__.py +5 -0
  592. lfx/interface/importing/utils.py +39 -0
  593. lfx/interface/initialize/__init__.py +3 -0
  594. lfx/interface/initialize/loading.py +224 -0
  595. lfx/interface/listing.py +26 -0
  596. lfx/interface/run.py +16 -0
  597. lfx/interface/utils.py +111 -0
  598. lfx/io/__init__.py +63 -0
  599. lfx/io/schema.py +289 -0
  600. lfx/load/__init__.py +8 -0
  601. lfx/load/load.py +256 -0
  602. lfx/load/utils.py +99 -0
  603. lfx/log/__init__.py +5 -0
  604. lfx/log/logger.py +385 -0
  605. lfx/memory/__init__.py +90 -0
  606. lfx/memory/stubs.py +283 -0
  607. lfx/processing/__init__.py +1 -0
  608. lfx/processing/process.py +238 -0
  609. lfx/processing/utils.py +25 -0
  610. lfx/py.typed +0 -0
  611. lfx/schema/__init__.py +66 -0
  612. lfx/schema/artifact.py +83 -0
  613. lfx/schema/content_block.py +62 -0
  614. lfx/schema/content_types.py +91 -0
  615. lfx/schema/data.py +308 -0
  616. lfx/schema/dataframe.py +210 -0
  617. lfx/schema/dotdict.py +74 -0
  618. lfx/schema/encoders.py +13 -0
  619. lfx/schema/graph.py +47 -0
  620. lfx/schema/image.py +131 -0
  621. lfx/schema/json_schema.py +141 -0
  622. lfx/schema/log.py +61 -0
  623. lfx/schema/message.py +473 -0
  624. lfx/schema/openai_responses_schemas.py +74 -0
  625. lfx/schema/properties.py +41 -0
  626. lfx/schema/schema.py +171 -0
  627. lfx/schema/serialize.py +13 -0
  628. lfx/schema/table.py +140 -0
  629. lfx/schema/validators.py +114 -0
  630. lfx/serialization/__init__.py +5 -0
  631. lfx/serialization/constants.py +2 -0
  632. lfx/serialization/serialization.py +314 -0
  633. lfx/services/__init__.py +23 -0
  634. lfx/services/base.py +28 -0
  635. lfx/services/cache/__init__.py +6 -0
  636. lfx/services/cache/base.py +183 -0
  637. lfx/services/cache/service.py +166 -0
  638. lfx/services/cache/utils.py +169 -0
  639. lfx/services/chat/__init__.py +1 -0
  640. lfx/services/chat/config.py +2 -0
  641. lfx/services/chat/schema.py +10 -0
  642. lfx/services/deps.py +129 -0
  643. lfx/services/factory.py +19 -0
  644. lfx/services/initialize.py +19 -0
  645. lfx/services/interfaces.py +103 -0
  646. lfx/services/manager.py +172 -0
  647. lfx/services/schema.py +20 -0
  648. lfx/services/session.py +82 -0
  649. lfx/services/settings/__init__.py +3 -0
  650. lfx/services/settings/auth.py +130 -0
  651. lfx/services/settings/base.py +539 -0
  652. lfx/services/settings/constants.py +31 -0
  653. lfx/services/settings/factory.py +23 -0
  654. lfx/services/settings/feature_flags.py +12 -0
  655. lfx/services/settings/service.py +35 -0
  656. lfx/services/settings/utils.py +40 -0
  657. lfx/services/shared_component_cache/__init__.py +1 -0
  658. lfx/services/shared_component_cache/factory.py +30 -0
  659. lfx/services/shared_component_cache/service.py +9 -0
  660. lfx/services/storage/__init__.py +5 -0
  661. lfx/services/storage/local.py +155 -0
  662. lfx/services/storage/service.py +54 -0
  663. lfx/services/tracing/__init__.py +1 -0
  664. lfx/services/tracing/service.py +21 -0
  665. lfx/settings.py +6 -0
  666. lfx/template/__init__.py +6 -0
  667. lfx/template/field/__init__.py +0 -0
  668. lfx/template/field/base.py +257 -0
  669. lfx/template/field/prompt.py +15 -0
  670. lfx/template/frontend_node/__init__.py +6 -0
  671. lfx/template/frontend_node/base.py +212 -0
  672. lfx/template/frontend_node/constants.py +65 -0
  673. lfx/template/frontend_node/custom_components.py +79 -0
  674. lfx/template/template/__init__.py +0 -0
  675. lfx/template/template/base.py +100 -0
  676. lfx/template/utils.py +217 -0
  677. lfx/type_extraction/__init__.py +19 -0
  678. lfx/type_extraction/type_extraction.py +75 -0
  679. lfx/type_extraction.py +80 -0
  680. lfx/utils/__init__.py +1 -0
  681. lfx/utils/async_helpers.py +42 -0
  682. lfx/utils/component_utils.py +154 -0
  683. lfx/utils/concurrency.py +60 -0
  684. lfx/utils/connection_string_parser.py +11 -0
  685. lfx/utils/constants.py +205 -0
  686. lfx/utils/data_structure.py +212 -0
  687. lfx/utils/exceptions.py +22 -0
  688. lfx/utils/helpers.py +28 -0
  689. lfx/utils/image.py +73 -0
  690. lfx/utils/lazy_load.py +15 -0
  691. lfx/utils/request_utils.py +18 -0
  692. lfx/utils/schemas.py +139 -0
  693. lfx/utils/util.py +481 -0
  694. lfx/utils/util_strings.py +56 -0
  695. lfx/utils/version.py +24 -0
  696. lfx_nightly-0.1.11.dev0.dist-info/METADATA +293 -0
  697. lfx_nightly-0.1.11.dev0.dist-info/RECORD +699 -0
  698. lfx_nightly-0.1.11.dev0.dist-info/WHEEL +4 -0
  699. lfx_nightly-0.1.11.dev0.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,489 @@
1
+ from __future__ import annotations
2
+
3
+ import contextlib
4
+ import json
5
+ from collections.abc import AsyncIterator, Generator, Iterator
6
+ from typing import TYPE_CHECKING, Any, cast
7
+
8
+ import yaml
9
+ from langchain_core.messages import AIMessage, AIMessageChunk
10
+
11
+ from lfx.graph.schema import CHAT_COMPONENTS, RECORDS_COMPONENTS, InterfaceComponentTypes, ResultData
12
+ from lfx.graph.utils import UnbuiltObject, log_vertex_build, rewrite_file_path
13
+ from lfx.graph.vertex.base import Vertex
14
+ from lfx.graph.vertex.exceptions import NoComponentInstanceError
15
+ from lfx.log.logger import logger
16
+ from lfx.schema.artifact import ArtifactType
17
+ from lfx.schema.data import Data
18
+ from lfx.schema.message import Message
19
+ from lfx.schema.schema import INPUT_FIELD_NAME
20
+ from lfx.serialization.serialization import serialize
21
+ from lfx.template.field.base import UNDEFINED, Output
22
+ from lfx.utils.schemas import ChatOutputResponse, DataOutputResponse
23
+ from lfx.utils.util import unescape_string
24
+
25
+ if TYPE_CHECKING:
26
+ from lfx.graph.edge.base import CycleEdge
27
+ from lfx.graph.vertex.schema import NodeData
28
+ from lfx.inputs.inputs import InputTypes
29
+
30
+
31
+ class CustomComponentVertex(Vertex):
32
+ def __init__(self, data: NodeData, graph):
33
+ super().__init__(data, graph=graph, base_type="custom_components")
34
+
35
+ def built_object_repr(self):
36
+ if self.artifacts and "repr" in self.artifacts:
37
+ return self.artifacts["repr"] or super().built_object_repr()
38
+ return None
39
+
40
+
41
+ class ComponentVertex(Vertex):
42
+ def __init__(self, data: NodeData, graph):
43
+ super().__init__(data, graph=graph, base_type="component")
44
+
45
+ def get_input(self, name: str) -> InputTypes:
46
+ if self.custom_component is None:
47
+ msg = f"Vertex {self.id} does not have a component instance."
48
+ raise ValueError(msg)
49
+ return self.custom_component.get_input(name)
50
+
51
+ def get_output(self, name: str) -> Output:
52
+ if self.custom_component is None:
53
+ raise NoComponentInstanceError(self.id)
54
+ return self.custom_component.get_output(name)
55
+
56
+ def built_object_repr(self):
57
+ if self.artifacts and "repr" in self.artifacts:
58
+ return self.artifacts["repr"] or super().built_object_repr()
59
+ return None
60
+
61
+ def _update_built_object_and_artifacts(self, result) -> None:
62
+ """Updates the built object and its artifacts."""
63
+ if isinstance(result, tuple):
64
+ if len(result) == 2: # noqa: PLR2004
65
+ self.built_object, self.artifacts = result
66
+ elif len(result) == 3: # noqa: PLR2004
67
+ self.custom_component, self.built_object, self.artifacts = result
68
+ self.logs = self.custom_component._output_logs
69
+ for key in self.artifacts:
70
+ if self.artifacts_raw is None:
71
+ self.artifacts_raw = {}
72
+ self.artifacts_raw[key] = self.artifacts[key].get("raw", None)
73
+ self.artifacts_type[key] = self.artifacts[key].get("type", None) or ArtifactType.UNKNOWN.value
74
+ else:
75
+ self.built_object = result
76
+
77
+ for key, value in self.built_object.items():
78
+ self.add_result(key, value)
79
+
80
+ def get_edge_with_target(self, target_id: str) -> Generator[CycleEdge]:
81
+ """Get the edge with the target id.
82
+
83
+ Args:
84
+ target_id: The target id of the edge.
85
+
86
+ Returns:
87
+ The edge with the target id.
88
+ """
89
+ for edge in self.edges:
90
+ if edge.target_id == target_id:
91
+ yield edge
92
+
93
+ async def _get_result(self, requester: Vertex, target_handle_name: str | None = None) -> Any:
94
+ """Retrieves the result of the built component.
95
+
96
+ If the component has not been built yet, a ValueError is raised.
97
+
98
+ Returns:
99
+ The built result if use_result is True, else the built object.
100
+ """
101
+ flow_id = self.graph.flow_id
102
+ if not self.built:
103
+ default_value: Any = UNDEFINED
104
+ for edge in self.get_edge_with_target(requester.id):
105
+ # We need to check if the edge is a normal edge
106
+ if edge.is_cycle and edge.target_param:
107
+ if edge.target_param in requester.output_names:
108
+ default_value = None
109
+ else:
110
+ default_value = requester.get_value_from_template_dict(edge.target_param)
111
+
112
+ if flow_id:
113
+ await self._log_transaction_async(source=self, target=requester, flow_id=str(flow_id), status="error")
114
+ if default_value is not UNDEFINED:
115
+ return default_value
116
+ msg = f"Component {self.display_name} has not been built yet"
117
+ raise ValueError(msg)
118
+
119
+ if requester is None:
120
+ msg = "Requester Vertex is None"
121
+ raise ValueError(msg)
122
+
123
+ edges = self.get_edge_with_target(requester.id)
124
+ result = UNDEFINED
125
+ for edge in edges:
126
+ if (
127
+ edge is not None
128
+ and edge.source_handle.name in self.results
129
+ and edge.target_handle.field_name == target_handle_name
130
+ ):
131
+ # Get the result from the output instead of the results dict
132
+ try:
133
+ output = self.get_output(edge.source_handle.name)
134
+
135
+ if output.value is UNDEFINED:
136
+ result = self.results[edge.source_handle.name]
137
+ else:
138
+ result = cast("Any", output.value)
139
+ except NoComponentInstanceError:
140
+ result = self.results[edge.source_handle.name]
141
+ break
142
+ if result is UNDEFINED:
143
+ if edge is None:
144
+ msg = f"Edge not found between {self.display_name} and {requester.display_name}"
145
+ raise ValueError(msg)
146
+ if edge.source_handle.name not in self.results:
147
+ msg = f"Result not found for {edge.source_handle.name}. Results: {self.results}"
148
+ raise ValueError(msg)
149
+ msg = f"Result not found for {edge.source_handle.name} in {edge}"
150
+ raise ValueError(msg)
151
+ if flow_id:
152
+ await self._log_transaction_async(source=self, target=requester, flow_id=str(flow_id), status="success")
153
+ return result
154
+
155
+ def extract_messages_from_artifacts(self, artifacts: dict[str, Any]) -> list[dict]:
156
+ """Extracts messages from the artifacts.
157
+
158
+ Args:
159
+ artifacts (Dict[str, Any]): The artifacts to extract messages from.
160
+
161
+ Returns:
162
+ List[str]: The extracted messages.
163
+ """
164
+ messages = []
165
+ for key, artifact in artifacts.items():
166
+ if any(
167
+ k not in artifact for k in ["text", "sender", "sender_name", "session_id", "stream_url"]
168
+ ) and not isinstance(artifact, Message):
169
+ continue
170
+ message_dict = artifact if isinstance(artifact, dict) else artifact.model_dump()
171
+ if not message_dict.get("text"):
172
+ continue
173
+ with contextlib.suppress(KeyError):
174
+ messages.append(
175
+ ChatOutputResponse(
176
+ message=message_dict["text"],
177
+ sender=message_dict.get("sender"),
178
+ sender_name=message_dict.get("sender_name"),
179
+ session_id=message_dict.get("session_id"),
180
+ stream_url=message_dict.get("stream_url"),
181
+ files=[
182
+ {"path": file} if isinstance(file, str) else file for file in message_dict.get("files", [])
183
+ ],
184
+ component_id=self.id,
185
+ type=self.artifacts_type[key],
186
+ ).model_dump(exclude_none=True)
187
+ )
188
+ return messages
189
+
190
+ def finalize_build(self) -> None:
191
+ result_dict = self.get_built_result()
192
+ # We need to set the artifacts to pass information
193
+ # to the frontend
194
+ messages = self.extract_messages_from_artifacts(result_dict)
195
+ result_dict = ResultData(
196
+ results=result_dict,
197
+ artifacts=self.artifacts,
198
+ outputs=self.outputs_logs,
199
+ logs=self.logs,
200
+ messages=messages,
201
+ component_display_name=self.display_name,
202
+ component_id=self.id,
203
+ )
204
+ self.set_result(result_dict)
205
+
206
+
207
+ class InterfaceVertex(ComponentVertex):
208
+ def __init__(self, data: NodeData, graph):
209
+ super().__init__(data, graph=graph)
210
+ self.added_message = None
211
+ self.steps = [self._build, self._run]
212
+ self.is_interface_component = True
213
+
214
+ def build_stream_url(self) -> str:
215
+ return f"/api/v1/build/{self.graph.flow_id}/{self.id}/stream"
216
+
217
+ def built_object_repr(self):
218
+ if self.task_id and self.is_task:
219
+ if task := self.get_task():
220
+ return str(task.info)
221
+ return f"Task {self.task_id} is not running"
222
+ if self.artifacts:
223
+ # dump as a yaml string
224
+ if isinstance(self.artifacts, dict):
225
+ artifacts_ = [self.artifacts]
226
+ elif hasattr(self.artifacts, "data"):
227
+ artifacts_ = self.artifacts.data
228
+ else:
229
+ artifacts_ = self.artifacts
230
+ artifacts = []
231
+ for artifact in artifacts_:
232
+ # artifacts = {k.title().replace("_", " "): v for k, v in self.artifacts.items() if v is not None}
233
+ artifact_ = {k.title().replace("_", " "): v for k, v in artifact.items() if v is not None}
234
+ artifacts.append(artifact_)
235
+ return yaml.dump(artifacts, default_flow_style=False, allow_unicode=True)
236
+ return super().built_object_repr()
237
+
238
+ def _process_chat_component(self):
239
+ """Process the chat component and return the message.
240
+
241
+ This method processes the chat component by extracting the necessary parameters
242
+ such as sender, sender_name, and message from the `params` dictionary. It then
243
+ performs additional operations based on the type of the `built_object` attribute.
244
+ If `built_object` is an instance of `AIMessage`, it creates a `ChatOutputResponse`
245
+ object using the `from_message` method. If `built_object` is not an instance of
246
+ `UnbuiltObject`, it checks the type of `built_object` and performs specific
247
+ operations accordingly. If `built_object` is a dictionary, it converts it into a
248
+ code block. If `built_object` is an instance of `Data`, it assigns the `text`
249
+ attribute to the `message` variable. If `message` is an instance of `AsyncIterator`
250
+ or `Iterator`, it builds a stream URL and sets `message` to an empty string. If
251
+ `built_object` is not a string, it converts it to a string. If `message` is a
252
+ generator or iterator, it assigns it to the `message` variable. Finally, it creates
253
+ a `ChatOutputResponse` object using the extracted parameters and assigns it to the
254
+ `artifacts` attribute. If `artifacts` is not None, it calls the `model_dump` method
255
+ on it and assigns the result to the `artifacts` attribute. It then returns the
256
+ `message` variable.
257
+
258
+ Returns:
259
+ str: The processed message.
260
+ """
261
+ artifacts = None
262
+ sender = self.params.get("sender", None)
263
+ sender_name = self.params.get("sender_name", None)
264
+ message = self.params.get(INPUT_FIELD_NAME, None)
265
+ files = self.params.get("files", [])
266
+ treat_file_path = files is not None and not isinstance(files, list) and isinstance(files, str)
267
+ if treat_file_path:
268
+ self.params["files"] = rewrite_file_path(files)
269
+ files = [{"path": file} if isinstance(file, str) else file for file in self.params.get("files", [])]
270
+ if isinstance(message, str):
271
+ message = unescape_string(message)
272
+ stream_url = None
273
+ if "text" in self.results:
274
+ text_output = self.results["text"]
275
+ elif "message" in self.results:
276
+ text_output = self.results["message"].text
277
+ else:
278
+ text_output = message
279
+ if isinstance(text_output, AIMessage | AIMessageChunk):
280
+ artifacts = ChatOutputResponse.from_message(
281
+ text_output,
282
+ sender=sender,
283
+ sender_name=sender_name,
284
+ )
285
+ elif not isinstance(text_output, UnbuiltObject):
286
+ if isinstance(text_output, dict):
287
+ # Turn the dict into a pleasing to
288
+ # read JSON inside a code block
289
+ message = dict_to_codeblock(text_output)
290
+ elif isinstance(text_output, Data):
291
+ message = text_output.text
292
+ elif isinstance(message, AsyncIterator | Iterator):
293
+ stream_url = self.build_stream_url()
294
+ message = ""
295
+ self.results["text"] = message
296
+ self.results["message"].text = message
297
+ self.built_object = self.results
298
+ elif not isinstance(text_output, str):
299
+ message = str(text_output)
300
+ # if the message is a generator or iterator
301
+ # it means that it is a stream of messages
302
+
303
+ else:
304
+ message = text_output
305
+
306
+ if hasattr(sender_name, "get_text"):
307
+ sender_name = sender_name.get_text()
308
+
309
+ artifact_type = ArtifactType.STREAM if stream_url is not None else ArtifactType.OBJECT
310
+ artifacts = ChatOutputResponse(
311
+ message=message,
312
+ sender=sender,
313
+ sender_name=sender_name,
314
+ stream_url=stream_url,
315
+ files=files,
316
+ type=artifact_type,
317
+ )
318
+
319
+ self.will_stream = stream_url is not None
320
+ if artifacts:
321
+ self.artifacts = artifacts.model_dump(exclude_none=True)
322
+
323
+ return message
324
+
325
+ def _process_data_component(self):
326
+ """Process the record component of the vertex.
327
+
328
+ If the built object is an instance of `Data`, it calls the `model_dump` method
329
+ and assigns the result to the `artifacts` attribute.
330
+
331
+ If the built object is a list, it iterates over each element and checks if it is
332
+ an instance of `Data`. If it is, it calls the `model_dump` method and appends
333
+ the result to the `artifacts` list. If it is not, it raises a `ValueError` if the
334
+ `ignore_errors` parameter is set to `False`, or logs an error message if it is set
335
+ to `True`.
336
+
337
+ Returns:
338
+ The built object.
339
+
340
+ Raises:
341
+ ValueError: If an element in the list is not an instance of `Data` and
342
+ `ignore_errors` is set to `False`.
343
+ """
344
+ if isinstance(self.built_object, Data):
345
+ artifacts = [self.built_object.data]
346
+ elif isinstance(self.built_object, list):
347
+ artifacts = []
348
+ ignore_errors = self.params.get("ignore_errors", False)
349
+ for value in self.built_object:
350
+ if isinstance(value, Data):
351
+ artifacts.append(value.data)
352
+ elif ignore_errors:
353
+ logger.error(f"Data expected, but got {value} of type {type(value)}")
354
+ else:
355
+ msg = f"Data expected, but got {value} of type {type(value)}"
356
+ raise ValueError(msg)
357
+ self.artifacts = DataOutputResponse(data=artifacts)
358
+ return self.built_object
359
+
360
+ async def _run(self, *args, **kwargs) -> None: # noqa: ARG002
361
+ if self.vertex_type in CHAT_COMPONENTS:
362
+ message = self._process_chat_component()
363
+ elif self.vertex_type in RECORDS_COMPONENTS:
364
+ message = self._process_data_component()
365
+ if isinstance(self.built_object, AsyncIterator | Iterator):
366
+ if self.params.get("return_data", False):
367
+ self.built_object = Data(text=message, data=self.artifacts)
368
+ else:
369
+ self.built_object = message
370
+ self.built_result = self.built_object
371
+
372
+ async def stream(self):
373
+ iterator = self.params.get(INPUT_FIELD_NAME, None)
374
+ if not isinstance(iterator, AsyncIterator | Iterator):
375
+ msg = "The message must be an iterator or an async iterator."
376
+ raise TypeError(msg)
377
+ is_async = isinstance(iterator, AsyncIterator)
378
+ complete_message = ""
379
+ if is_async:
380
+ async for message in iterator:
381
+ message_ = message.content if hasattr(message, "content") else message
382
+ message_ = message_.text if hasattr(message_, "text") else message_
383
+ yield message_
384
+ complete_message += message_
385
+ else:
386
+ for message in iterator:
387
+ message_ = message.content if hasattr(message, "content") else message
388
+ message_ = message_.text if hasattr(message_, "text") else message_
389
+ yield message_
390
+ complete_message += message_
391
+
392
+ files = self.params.get("files", [])
393
+
394
+ treat_file_path = files is not None and not isinstance(files, list) and isinstance(files, str)
395
+ if treat_file_path:
396
+ self.params["files"] = rewrite_file_path(files)
397
+
398
+ if hasattr(self.params.get("sender_name"), "get_text"):
399
+ sender_name = self.params.get("sender_name").get_text()
400
+ else:
401
+ sender_name = self.params.get("sender_name")
402
+ self.artifacts = ChatOutputResponse(
403
+ message=complete_message,
404
+ sender=self.params.get("sender", ""),
405
+ sender_name=sender_name,
406
+ files=[{"path": file} if isinstance(file, str) else file for file in self.params.get("files", [])],
407
+ type=ArtifactType.OBJECT.value,
408
+ ).model_dump()
409
+
410
+ message = await Message.create(
411
+ text=complete_message,
412
+ sender=self.params.get("sender", ""),
413
+ sender_name=self.params.get("sender_name", ""),
414
+ files=self.params.get("files", []),
415
+ flow_id=self.graph.flow_id,
416
+ session_id=self.params.get("session_id", ""),
417
+ )
418
+ self.params[INPUT_FIELD_NAME] = complete_message
419
+ if isinstance(self.built_object, dict):
420
+ for key, value in self.built_object.items():
421
+ if hasattr(value, "text") and (isinstance(value.text, AsyncIterator | Iterator) or value.text == ""):
422
+ self.built_object[key] = message
423
+ else:
424
+ self.built_object = message
425
+ self.artifacts_type = ArtifactType.MESSAGE
426
+
427
+ # Update artifacts with the message
428
+ # and remove the stream_url
429
+ self.finalize_build()
430
+ await logger.adebug(f"Streamed message: {complete_message}")
431
+ # Set the result in the vertex of origin
432
+ edges = self.get_edge_with_target(self.id)
433
+ for edge in edges:
434
+ origin_vertex = self.graph.get_vertex(edge.source_id)
435
+ for key, value in origin_vertex.results.items():
436
+ if isinstance(value, AsyncIterator | Iterator):
437
+ origin_vertex.results[key] = complete_message
438
+ if (
439
+ self.custom_component
440
+ and hasattr(self.custom_component, "should_store_message")
441
+ and hasattr(self.custom_component, "store_message")
442
+ ):
443
+ await self.custom_component.store_message(message)
444
+ await log_vertex_build(
445
+ flow_id=self.graph.flow_id,
446
+ vertex_id=self.id,
447
+ valid=True,
448
+ params=self.built_object_repr(),
449
+ data=self.result,
450
+ artifacts=self.artifacts,
451
+ )
452
+
453
+ self._validate_built_object()
454
+ self.built = True
455
+
456
+ async def consume_async_generator(self) -> None:
457
+ async for _ in self.stream():
458
+ pass
459
+
460
+ def _is_chat_input(self):
461
+ return self.vertex_type == InterfaceComponentTypes.ChatInput and self.is_input
462
+
463
+
464
+ class StateVertex(ComponentVertex):
465
+ def __init__(self, data: NodeData, graph):
466
+ """Initializes a StateVertex with the provided node data and graph.
467
+
468
+ Sets up the build steps and marks the vertex as a state vertex.
469
+ """
470
+ super().__init__(data, graph=graph)
471
+ self.steps = [self._build]
472
+ self.is_state = True
473
+
474
+ def built_object_repr(self):
475
+ """Returns a string representation of the built object from the artifacts if available.
476
+
477
+ If the artifacts dictionary contains a non-empty "repr" key, its value is returned.
478
+ If the "repr" value is falsy, falls back to the superclass representation.
479
+ Returns None if no representation is available.
480
+ """
481
+ if self.artifacts and "repr" in self.artifacts:
482
+ return self.artifacts["repr"] or super().built_object_repr()
483
+ return None
484
+
485
+
486
+ def dict_to_codeblock(d: dict) -> str:
487
+ serialized = {key: serialize(val) for key, val in d.items()}
488
+ json_str = json.dumps(serialized, indent=4)
489
+ return f"```json\n{json_str}\n```"
@@ -0,0 +1 @@
1
+ """Helpers module for lfx package."""
@@ -0,0 +1,71 @@
1
+ from typing import Any, TypedDict
2
+
3
+ from pydantic import BaseModel as PydanticBaseModel
4
+ from pydantic import ConfigDict, Field, create_model
5
+
6
+ TRUE_VALUES = ["true", "1", "t", "y", "yes"]
7
+
8
+
9
+ class SchemaField(TypedDict):
10
+ name: str
11
+ type: str
12
+ description: str
13
+ multiple: bool
14
+
15
+
16
+ class BaseModel(PydanticBaseModel):
17
+ model_config = ConfigDict(populate_by_name=True)
18
+
19
+
20
+ def _get_type_annotation(type_str: str, *, multiple: bool) -> type:
21
+ type_mapping = {
22
+ "str": str,
23
+ "int": int,
24
+ "float": float,
25
+ "bool": bool,
26
+ "boolean": bool,
27
+ "list": list[Any],
28
+ "dict": dict[str, Any],
29
+ "number": float,
30
+ "text": str,
31
+ }
32
+ try:
33
+ base_type = type_mapping[type_str]
34
+ except KeyError as e:
35
+ msg = f"Invalid type: {type_str}"
36
+ raise ValueError(msg) from e
37
+ if multiple:
38
+ return list[base_type] # type: ignore[valid-type]
39
+ return base_type # type: ignore[return-value]
40
+
41
+
42
+ def build_model_from_schema(schema: list[SchemaField]) -> type[PydanticBaseModel]:
43
+ fields = {}
44
+ for field in schema:
45
+ field_name = field["name"]
46
+ field_type_str = field["type"]
47
+ description = field.get("description", "")
48
+ multiple = field.get("multiple", False)
49
+ multiple = coalesce_bool(multiple)
50
+ field_type_annotation = _get_type_annotation(field_type_str, multiple=multiple)
51
+ fields[field_name] = (field_type_annotation, Field(description=description))
52
+ return create_model("OutputModel", **fields)
53
+
54
+
55
+ def coalesce_bool(value: Any) -> bool:
56
+ """Coalesces the given value into a boolean.
57
+
58
+ Args:
59
+ value (Any): The value to be coalesced.
60
+
61
+ Returns:
62
+ bool: The coalesced boolean value.
63
+
64
+ """
65
+ if isinstance(value, bool):
66
+ return value
67
+ if isinstance(value, str):
68
+ return value.lower() in TRUE_VALUES
69
+ if isinstance(value, int):
70
+ return bool(value)
71
+ return False
lfx/helpers/custom.py ADDED
@@ -0,0 +1,13 @@
1
+ from typing import Any
2
+
3
+
4
+ def format_type(type_: Any) -> str:
5
+ if type_ is str:
6
+ type_ = "Text"
7
+ elif hasattr(type_, "__name__"):
8
+ type_ = type_.__name__
9
+ elif hasattr(type_, "__class__"):
10
+ type_ = type_.__class__.__name__
11
+ else:
12
+ type_ = str(type_)
13
+ return type_