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,408 @@
1
+ import json
2
+ import subprocess
3
+ import time
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+ from tenacity import retry, stop_after_attempt, wait_exponential
8
+ from twelvelabs import TwelveLabs
9
+
10
+ from lfx.custom import Component
11
+ from lfx.field_typing.range_spec import RangeSpec
12
+ from lfx.inputs import DataInput, DropdownInput, MessageInput, MultilineInput, SecretStrInput, SliderInput
13
+ from lfx.io import Output
14
+ from lfx.schema.message import Message
15
+
16
+
17
+ class TaskError(Exception):
18
+ """Error raised when a task fails."""
19
+
20
+
21
+ class TaskTimeoutError(Exception):
22
+ """Error raised when a task times out."""
23
+
24
+
25
+ class IndexCreationError(Exception):
26
+ """Error raised when there's an issue with an index."""
27
+
28
+
29
+ class ApiRequestError(Exception):
30
+ """Error raised when an API request fails."""
31
+
32
+
33
+ class VideoValidationError(Exception):
34
+ """Error raised when video validation fails."""
35
+
36
+
37
+ class TwelveLabsPegasus(Component):
38
+ display_name = "TwelveLabs Pegasus"
39
+ description = "Chat with videos using TwelveLabs Pegasus API."
40
+ icon = "TwelveLabs"
41
+ name = "TwelveLabsPegasus"
42
+ documentation = "https://github.com/twelvelabs-io/twelvelabs-developer-experience/blob/main/integrations/Langflow/TWELVE_LABS_COMPONENTS_README.md"
43
+
44
+ inputs = [
45
+ DataInput(name="videodata", display_name="Video Data", info="Video Data", is_list=True),
46
+ SecretStrInput(
47
+ name="api_key", display_name="TwelveLabs API Key", info="Enter your TwelveLabs API Key.", required=True
48
+ ),
49
+ MessageInput(
50
+ name="video_id",
51
+ display_name="Pegasus Video ID",
52
+ info="Enter a Video ID for a previously indexed video.",
53
+ ),
54
+ MessageInput(
55
+ name="index_name",
56
+ display_name="Index Name",
57
+ info="Name of the index to use. If the index doesn't exist, it will be created.",
58
+ required=False,
59
+ ),
60
+ MessageInput(
61
+ name="index_id",
62
+ display_name="Index ID",
63
+ info="ID of an existing index to use. If provided, index_name will be ignored.",
64
+ required=False,
65
+ ),
66
+ DropdownInput(
67
+ name="model_name",
68
+ display_name="Model",
69
+ info="Pegasus model to use for indexing",
70
+ options=["pegasus1.2"],
71
+ value="pegasus1.2",
72
+ advanced=False,
73
+ ),
74
+ MultilineInput(
75
+ name="message",
76
+ display_name="Prompt",
77
+ info="Message to chat with the video.",
78
+ required=True,
79
+ ),
80
+ SliderInput(
81
+ name="temperature",
82
+ display_name="Temperature",
83
+ value=0.7,
84
+ range_spec=RangeSpec(min=0, max=1, step=0.01),
85
+ info=(
86
+ "Controls randomness in responses. Lower values are more deterministic, "
87
+ "higher values are more creative."
88
+ ),
89
+ ),
90
+ ]
91
+
92
+ outputs = [
93
+ Output(
94
+ display_name="Message",
95
+ name="response",
96
+ method="process_video",
97
+ type_=Message,
98
+ ),
99
+ Output(
100
+ display_name="Video ID",
101
+ name="processed_video_id",
102
+ method="get_video_id",
103
+ type_=Message,
104
+ ),
105
+ ]
106
+
107
+ def __init__(self, **kwargs) -> None:
108
+ super().__init__(**kwargs)
109
+
110
+ self._task_id: str | None = None
111
+ self._video_id: str | None = None
112
+ self._index_id: str | None = None
113
+ self._index_name: str | None = None
114
+ self._message: str | None = None
115
+
116
+ def _get_or_create_index(self, client: TwelveLabs) -> tuple[str, str]:
117
+ """Get existing index or create new one.
118
+
119
+ Returns (index_id, index_name).
120
+ """
121
+ # First check if index_id is provided and valid
122
+ if hasattr(self, "_index_id") and self._index_id:
123
+ try:
124
+ index = client.index.retrieve(id=self._index_id)
125
+ self.log(f"Found existing index with ID: {self._index_id}")
126
+ except (ValueError, KeyError) as e:
127
+ self.log(f"Error retrieving index with ID {self._index_id}: {e!s}", "WARNING")
128
+ else:
129
+ return self._index_id, index.name
130
+
131
+ # If index_name is provided, try to find it
132
+ if hasattr(self, "_index_name") and self._index_name:
133
+ try:
134
+ # List all indexes and find by name
135
+ indexes = client.index.list()
136
+ for idx in indexes:
137
+ if idx.name == self._index_name:
138
+ self.log(f"Found existing index: {self._index_name} (ID: {idx.id})")
139
+ return idx.id, idx.name
140
+
141
+ # If we get here, index wasn't found - create it
142
+ self.log(f"Creating new index: {self._index_name}")
143
+ index = client.index.create(
144
+ name=self._index_name,
145
+ models=[
146
+ {
147
+ "name": self.model_name if hasattr(self, "model_name") else "pegasus1.2",
148
+ "options": ["visual", "audio"],
149
+ }
150
+ ],
151
+ )
152
+ except (ValueError, KeyError) as e:
153
+ self.log(f"Error with index name {self._index_name}: {e!s}", "ERROR")
154
+ error_message = f"Error with index name {self._index_name}"
155
+ raise IndexCreationError(error_message) from e
156
+ else:
157
+ return index.id, index.name
158
+
159
+ # If neither is provided, create a new index with timestamp
160
+ try:
161
+ index_name = f"index_{int(time.time())}"
162
+ self.log(f"Creating new index: {index_name}")
163
+ index = client.index.create(
164
+ name=index_name,
165
+ models=[
166
+ {
167
+ "name": self.model_name if hasattr(self, "model_name") else "pegasus1.2",
168
+ "options": ["visual", "audio"],
169
+ }
170
+ ],
171
+ )
172
+ except (ValueError, KeyError) as e:
173
+ self.log(f"Failed to create new index: {e!s}", "ERROR")
174
+ error_message = "Failed to create new index"
175
+ raise IndexCreationError(error_message) from e
176
+ else:
177
+ return index.id, index.name
178
+
179
+ @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10), reraise=True)
180
+ async def _make_api_request(self, method: Any, *args: Any, **kwargs: Any) -> Any:
181
+ """Make API request with retry logic.
182
+
183
+ Retries failed requests with exponential backoff.
184
+ """
185
+ try:
186
+ return await method(*args, **kwargs)
187
+ except (ValueError, KeyError) as e:
188
+ self.log(f"API request failed: {e!s}", "ERROR")
189
+ error_message = "API request failed"
190
+ raise ApiRequestError(error_message) from e
191
+
192
+ def wait_for_task_completion(
193
+ self, client: TwelveLabs, task_id: str, max_retries: int = 120, sleep_time: int = 5
194
+ ) -> Any:
195
+ """Wait for task completion with timeout and improved error handling.
196
+
197
+ Polls the task status until completion or timeout.
198
+ """
199
+ retries = 0
200
+ consecutive_errors = 0
201
+ max_consecutive_errors = 3
202
+
203
+ while retries < max_retries:
204
+ try:
205
+ self.log(f"Checking task status (attempt {retries + 1})")
206
+ result = client.task.retrieve(id=task_id)
207
+ consecutive_errors = 0 # Reset error counter on success
208
+
209
+ if result.status == "ready":
210
+ self.log("Task completed successfully!")
211
+ return result
212
+ if result.status == "failed":
213
+ error_msg = f"Task failed with status: {result.status}"
214
+ self.log(error_msg, "ERROR")
215
+ raise TaskError(error_msg)
216
+ if result.status == "error":
217
+ error_msg = f"Task encountered an error: {getattr(result, 'error', 'Unknown error')}"
218
+ self.log(error_msg, "ERROR")
219
+ raise TaskError(error_msg)
220
+
221
+ time.sleep(sleep_time)
222
+ retries += 1
223
+ status_msg = f"Processing video... {retries * sleep_time}s elapsed"
224
+ self.status = status_msg
225
+ self.log(status_msg)
226
+
227
+ except (ValueError, KeyError) as e:
228
+ consecutive_errors += 1
229
+ error_msg = f"Error checking task status: {e!s}"
230
+ self.log(error_msg, "WARNING")
231
+
232
+ if consecutive_errors >= max_consecutive_errors:
233
+ too_many_errors = "Too many consecutive errors"
234
+ raise TaskError(too_many_errors) from e
235
+
236
+ time.sleep(sleep_time * 2)
237
+ continue
238
+
239
+ timeout_msg = f"Timeout after {max_retries * sleep_time} seconds"
240
+ self.log(timeout_msg, "ERROR")
241
+ raise TaskTimeoutError(timeout_msg)
242
+
243
+ def validate_video_file(self, filepath: str) -> tuple[bool, str]:
244
+ """Validate video file using ffprobe.
245
+
246
+ Returns (is_valid, error_message).
247
+ """
248
+ # Ensure filepath is a string and doesn't contain shell metacharacters
249
+ if not isinstance(filepath, str) or any(c in filepath for c in ";&|`$(){}[]<>*?!#~"):
250
+ return False, "Invalid filepath"
251
+
252
+ try:
253
+ cmd = [
254
+ "ffprobe",
255
+ "-loglevel",
256
+ "error",
257
+ "-show_entries",
258
+ "stream=codec_type,codec_name",
259
+ "-of",
260
+ "default=nw=1",
261
+ "-print_format",
262
+ "json",
263
+ "-show_format",
264
+ filepath,
265
+ ]
266
+
267
+ # Use subprocess with a list of arguments to avoid shell injection
268
+ # We need to skip the S603 warning here as we're taking proper precautions
269
+ # with input validation and using shell=False
270
+ result = subprocess.run( # noqa: S603
271
+ cmd,
272
+ capture_output=True,
273
+ text=True,
274
+ check=False,
275
+ shell=False, # Explicitly set shell=False for security
276
+ )
277
+
278
+ if result.returncode != 0:
279
+ return False, f"FFprobe error: {result.stderr}"
280
+
281
+ probe_data = json.loads(result.stdout)
282
+
283
+ has_video = any(stream.get("codec_type") == "video" for stream in probe_data.get("streams", []))
284
+
285
+ if not has_video:
286
+ return False, "No video stream found in file"
287
+
288
+ self.log(f"Video validation successful: {json.dumps(probe_data, indent=2)}")
289
+ except subprocess.SubprocessError as e:
290
+ return False, f"FFprobe process error: {e!s}"
291
+ except json.JSONDecodeError as e:
292
+ return False, f"FFprobe output parsing error: {e!s}"
293
+ except (ValueError, OSError) as e:
294
+ return False, f"Validation error: {e!s}"
295
+ else:
296
+ return True, ""
297
+
298
+ def on_task_update(self, task: Any) -> None:
299
+ """Callback for task status updates.
300
+
301
+ Updates the component status with the current task status.
302
+ """
303
+ self.status = f"Processing video... Status: {task.status}"
304
+ self.log(self.status)
305
+
306
+ def process_video(self) -> Message:
307
+ """Process video using Pegasus and generate response if message is provided.
308
+
309
+ Handles video indexing and question answering using the TwelveLabs API.
310
+ """
311
+ # Check and initialize inputs
312
+ if hasattr(self, "index_id") and self.index_id:
313
+ self._index_id = self.index_id.text if hasattr(self.index_id, "text") else self.index_id
314
+
315
+ if hasattr(self, "index_name") and self.index_name:
316
+ self._index_name = self.index_name.text if hasattr(self.index_name, "text") else self.index_name
317
+
318
+ if hasattr(self, "video_id") and self.video_id:
319
+ self._video_id = self.video_id.text if hasattr(self.video_id, "text") else self.video_id
320
+
321
+ if hasattr(self, "message") and self.message:
322
+ self._message = self.message.text if hasattr(self.message, "text") else self.message
323
+
324
+ try:
325
+ # If we have a message and already processed video, use existing video_id
326
+ if self._message and self._video_id and self._video_id != "":
327
+ self.status = f"Have video id: {self._video_id}"
328
+
329
+ client = TwelveLabs(api_key=self.api_key)
330
+
331
+ self.status = f"Processing query (w/ video ID): {self._video_id} {self._message}"
332
+ self.log(self.status)
333
+
334
+ response = client.generate.text(
335
+ video_id=self._video_id,
336
+ prompt=self._message,
337
+ temperature=self.temperature,
338
+ )
339
+ return Message(text=response.data)
340
+
341
+ # Otherwise process new video
342
+ if not self.videodata or not isinstance(self.videodata, list) or len(self.videodata) != 1:
343
+ return Message(text="Please provide exactly one video")
344
+
345
+ video_path = self.videodata[0].data.get("text")
346
+ if not video_path or not Path(video_path).exists():
347
+ return Message(text="Invalid video path")
348
+
349
+ if not self.api_key:
350
+ return Message(text="No API key provided")
351
+
352
+ client = TwelveLabs(api_key=self.api_key)
353
+
354
+ # Get or create index
355
+ try:
356
+ index_id, index_name = self._get_or_create_index(client)
357
+ self.status = f"Using index: {index_name} (ID: {index_id})"
358
+ self.log(f"Using index: {index_name} (ID: {index_id})")
359
+ self._index_id = index_id
360
+ self._index_name = index_name
361
+ except IndexCreationError as e:
362
+ return Message(text=f"Failed to get/create index: {e}")
363
+
364
+ with Path(video_path).open("rb") as video_file:
365
+ task = client.task.create(index_id=self._index_id, file=video_file)
366
+ self._task_id = task.id
367
+
368
+ # Wait for processing to complete
369
+ task.wait_for_done(sleep_interval=5, callback=self.on_task_update)
370
+
371
+ if task.status != "ready":
372
+ return Message(text=f"Processing failed with status {task.status}")
373
+
374
+ # Store video_id for future use
375
+ self._video_id = task.video_id
376
+
377
+ # Generate response if message provided
378
+ if self._message:
379
+ self.status = f"Processing query: {self._message}"
380
+ self.log(self.status)
381
+
382
+ response = client.generate.text(
383
+ video_id=self._video_id,
384
+ prompt=self._message,
385
+ temperature=self.temperature,
386
+ )
387
+ return Message(text=response.data)
388
+
389
+ success_msg = (
390
+ f"Video processed successfully. You can now ask questions about the video. Video ID: {self._video_id}"
391
+ )
392
+ return Message(text=success_msg)
393
+
394
+ except (ValueError, KeyError, IndexCreationError, TaskError, TaskTimeoutError) as e:
395
+ self.log(f"Error: {e!s}", "ERROR")
396
+ # Clear stored IDs on error
397
+ self._video_id = None
398
+ self._index_id = None
399
+ self._task_id = None
400
+ return Message(text=f"Error: {e!s}")
401
+
402
+ def get_video_id(self) -> Message:
403
+ """Return the video ID of the processed video as a Message.
404
+
405
+ Returns an empty string if no video has been processed.
406
+ """
407
+ video_id = self._video_id or ""
408
+ return Message(text=video_id)
@@ -0,0 +1,100 @@
1
+ import time
2
+ from pathlib import Path
3
+ from typing import Any, cast
4
+
5
+ from twelvelabs import TwelveLabs
6
+
7
+ from lfx.base.embeddings.model import LCEmbeddingsModel
8
+ from lfx.field_typing import Embeddings
9
+ from lfx.io import DropdownInput, IntInput, SecretStrInput
10
+
11
+
12
+ class TwelveLabsVideoEmbeddings(Embeddings):
13
+ def __init__(self, api_key: str, model_name: str = "Marengo-retrieval-2.7") -> None:
14
+ self.client = TwelveLabs(api_key=api_key)
15
+ self.model_name = model_name
16
+
17
+ def _wait_for_task_completion(self, task_id: str) -> Any:
18
+ while True:
19
+ result = self.client.embed.task.retrieve(id=task_id)
20
+ if result.status == "ready":
21
+ return result
22
+ time.sleep(5)
23
+
24
+ def embed_documents(self, texts: list[str]) -> list[list[float]]:
25
+ embeddings: list[list[float]] = []
26
+ for text in texts:
27
+ video_path = text.page_content if hasattr(text, "page_content") else str(text)
28
+ result = self.embed_video(video_path)
29
+
30
+ # First try to use video embedding, then fall back to clip embedding if available
31
+ if result["video_embedding"] is not None:
32
+ embeddings.append(cast("list[float]", result["video_embedding"]))
33
+ elif result["clip_embeddings"] and len(result["clip_embeddings"]) > 0:
34
+ embeddings.append(cast("list[float]", result["clip_embeddings"][0]))
35
+ else:
36
+ # If neither is available, raise an error
37
+ error_msg = "No embeddings were generated for the video"
38
+ raise ValueError(error_msg)
39
+
40
+ return embeddings
41
+
42
+ def embed_query(self, text: str) -> list[float]:
43
+ video_path = text.page_content if hasattr(text, "page_content") else str(text)
44
+ result = self.embed_video(video_path)
45
+
46
+ # First try to use video embedding, then fall back to clip embedding if available
47
+ if result["video_embedding"] is not None:
48
+ return cast("list[float]", result["video_embedding"])
49
+ if result["clip_embeddings"] and len(result["clip_embeddings"]) > 0:
50
+ return cast("list[float]", result["clip_embeddings"][0])
51
+ # If neither is available, raise an error
52
+ error_msg = "No embeddings were generated for the video"
53
+ raise ValueError(error_msg)
54
+
55
+ def embed_video(self, video_path: str) -> dict[str, list[float] | list[list[float]]]:
56
+ file_path = Path(video_path)
57
+ with file_path.open("rb") as video_file:
58
+ task = self.client.embed.task.create(
59
+ model_name=self.model_name,
60
+ video_file=video_file,
61
+ video_embedding_scopes=["video", "clip"],
62
+ )
63
+
64
+ result = self._wait_for_task_completion(task.id)
65
+
66
+ video_embedding: dict[str, list[float] | list[list[float]]] = {
67
+ "video_embedding": [], # Initialize as empty list instead of None
68
+ "clip_embeddings": [],
69
+ }
70
+
71
+ if hasattr(result.video_embedding, "segments") and result.video_embedding.segments:
72
+ for seg in result.video_embedding.segments:
73
+ # Check for embeddings_float attribute (this is the correct attribute name)
74
+ if hasattr(seg, "embeddings_float") and seg.embedding_scope == "video":
75
+ # Convert to list of floats
76
+ video_embedding["video_embedding"] = [float(x) for x in seg.embeddings_float]
77
+
78
+ return video_embedding
79
+
80
+
81
+ class TwelveLabsVideoEmbeddingsComponent(LCEmbeddingsModel):
82
+ display_name = "TwelveLabs Video Embeddings"
83
+ description = "Generate embeddings from videos using TwelveLabs video embedding models."
84
+ name = "TwelveLabsVideoEmbeddings"
85
+ icon = "TwelveLabs"
86
+ documentation = "https://github.com/twelvelabs-io/twelvelabs-developer-experience/blob/main/integrations/Langflow/TWELVE_LABS_COMPONENTS_README.md"
87
+ inputs = [
88
+ SecretStrInput(name="api_key", display_name="API Key", required=True),
89
+ DropdownInput(
90
+ name="model_name",
91
+ display_name="Model",
92
+ advanced=False,
93
+ options=["Marengo-retrieval-2.7"],
94
+ value="Marengo-retrieval-2.7",
95
+ ),
96
+ IntInput(name="request_timeout", display_name="Request Timeout", advanced=True),
97
+ ]
98
+
99
+ def build_embeddings(self) -> Embeddings:
100
+ return TwelveLabsVideoEmbeddings(api_key=self.api_key, model_name=self.model_name)
@@ -0,0 +1,179 @@
1
+ from pathlib import Path
2
+
3
+ from lfx.base.data import BaseFileComponent
4
+ from lfx.io import FileInput
5
+ from lfx.schema import Data, DataFrame
6
+
7
+
8
+ class VideoFileComponent(BaseFileComponent):
9
+ """Handles loading and processing of video files.
10
+
11
+ This component supports processing video files in common video formats.
12
+ """
13
+
14
+ display_name = "Video File"
15
+ description = "Load a video file in common video formats."
16
+ icon = "TwelveLabs"
17
+ name = "VideoFile"
18
+ documentation = "https://github.com/twelvelabs-io/twelvelabs-developer-experience/blob/main/integrations/Langflow/TWELVE_LABS_COMPONENTS_README.md"
19
+
20
+ VALID_EXTENSIONS = [
21
+ # Common video formats
22
+ "mp4",
23
+ "avi",
24
+ "mov",
25
+ "mkv",
26
+ "webm",
27
+ "flv",
28
+ "wmv",
29
+ "mpg",
30
+ "mpeg",
31
+ "m4v",
32
+ "3gp",
33
+ "3g2",
34
+ "m2v",
35
+ # Professional video formats
36
+ "mxf",
37
+ "dv",
38
+ "vob",
39
+ # Additional video formats
40
+ "ogv",
41
+ "rm",
42
+ "rmvb",
43
+ "amv",
44
+ "divx",
45
+ "m2ts",
46
+ "mts",
47
+ "ts",
48
+ "qt",
49
+ "yuv",
50
+ "y4m",
51
+ ]
52
+
53
+ inputs = [
54
+ FileInput(
55
+ display_name="Video File",
56
+ name="file_path",
57
+ file_types=[
58
+ # Common video formats
59
+ "mp4",
60
+ "avi",
61
+ "mov",
62
+ "mkv",
63
+ "webm",
64
+ "flv",
65
+ "wmv",
66
+ "mpg",
67
+ "mpeg",
68
+ "m4v",
69
+ "3gp",
70
+ "3g2",
71
+ "m2v",
72
+ # Professional video formats
73
+ "mxf",
74
+ "dv",
75
+ "vob",
76
+ # Additional video formats
77
+ "ogv",
78
+ "rm",
79
+ "rmvb",
80
+ "amv",
81
+ "divx",
82
+ "m2ts",
83
+ "mts",
84
+ "ts",
85
+ "qt",
86
+ "yuv",
87
+ "y4m",
88
+ ],
89
+ required=True,
90
+ info="Upload a video file in any common video format supported by ffmpeg",
91
+ ),
92
+ ]
93
+
94
+ outputs = [
95
+ *BaseFileComponent.get_base_outputs(),
96
+ ]
97
+
98
+ def process_files(self, file_list: list[BaseFileComponent.BaseFile]) -> list[BaseFileComponent.BaseFile]:
99
+ """Process video files."""
100
+ self.log(f"DEBUG: Processing video files: {len(file_list)}")
101
+
102
+ if not file_list:
103
+ msg = "No files to process."
104
+ raise ValueError(msg)
105
+
106
+ processed_files = []
107
+ for file in file_list:
108
+ try:
109
+ file_path = str(file.path)
110
+ self.log(f"DEBUG: Processing video file: {file_path}")
111
+
112
+ # Verify file exists
113
+ file_path_obj = Path(file_path)
114
+ if not file_path_obj.exists():
115
+ error_msg = f"Video file not found: {file_path}"
116
+ raise FileNotFoundError(error_msg)
117
+
118
+ # Verify extension
119
+ if not file_path.lower().endswith(tuple(self.VALID_EXTENSIONS)):
120
+ error_msg = f"Invalid file type. Expected: {', '.join(self.VALID_EXTENSIONS)}"
121
+ raise ValueError(error_msg)
122
+
123
+ # Create a dictionary instead of a Document
124
+ doc_data = {"text": file_path, "metadata": {"source": file_path, "type": "video"}}
125
+
126
+ # Pass the dictionary to Data
127
+ file.data = Data(data=doc_data)
128
+
129
+ self.log(f"DEBUG: Created data: {doc_data}")
130
+ processed_files.append(file)
131
+
132
+ except Exception as e:
133
+ self.log(f"Error processing video file: {e!s}", "ERROR")
134
+ raise
135
+
136
+ return processed_files
137
+
138
+ def load_files(self) -> DataFrame:
139
+ """Load video files and return a list of Data objects."""
140
+ try:
141
+ self.log("DEBUG: Starting video file load")
142
+ if not hasattr(self, "file_path") or not self.file_path:
143
+ self.log("DEBUG: No video file path provided")
144
+ return DataFrame()
145
+
146
+ self.log(f"DEBUG: Loading video from path: {self.file_path}")
147
+
148
+ # Verify file exists
149
+ file_path_obj = Path(self.file_path)
150
+ if not file_path_obj.exists():
151
+ self.log(f"DEBUG: Video file not found at path: {self.file_path}")
152
+ return DataFrame()
153
+
154
+ # Verify file size
155
+ file_size = file_path_obj.stat().st_size
156
+ self.log(f"DEBUG: Video file size: {file_size} bytes")
157
+
158
+ # Create a proper Data object with the video path
159
+ video_data = {
160
+ "text": self.file_path,
161
+ "metadata": {"source": self.file_path, "type": "video", "size": file_size},
162
+ }
163
+
164
+ self.log(f"DEBUG: Created video data: {video_data}")
165
+ result = DataFrame(data=[video_data])
166
+
167
+ # Log the result to verify it's a proper Data object
168
+ self.log("DEBUG: Returning list with Data objects")
169
+ except (FileNotFoundError, PermissionError, OSError) as e:
170
+ self.log(f"DEBUG: File error in video load_files: {e!s}", "ERROR")
171
+ return DataFrame()
172
+ except ImportError as e:
173
+ self.log(f"DEBUG: Import error in video load_files: {e!s}", "ERROR")
174
+ return DataFrame()
175
+ except (ValueError, TypeError) as e:
176
+ self.log(f"DEBUG: Value or type error in video load_files: {e!s}", "ERROR")
177
+ return DataFrame()
178
+ else:
179
+ return result
@@ -0,0 +1,3 @@
1
+ from .unstructured import UnstructuredComponent
2
+
3
+ __all__ = ["UnstructuredComponent"]