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,196 @@
1
+ import os
2
+ import shutil
3
+ import tempfile
4
+ from contextlib import asynccontextmanager
5
+ from pathlib import Path
6
+
7
+ import aiofiles
8
+ import git
9
+
10
+ from lfx.custom.custom_component.component import Component
11
+ from lfx.io import MessageTextInput, Output
12
+ from lfx.schema.data import Data
13
+ from lfx.schema.message import Message
14
+
15
+
16
+ class GitExtractorComponent(Component):
17
+ display_name = "GitExtractor"
18
+ description = "Analyzes a Git repository and returns file contents and complete repository information"
19
+ icon = "GitLoader"
20
+
21
+ inputs = [
22
+ MessageTextInput(
23
+ name="repository_url",
24
+ display_name="Repository URL",
25
+ info="URL of the Git repository (e.g., https://github.com/username/repo)",
26
+ value="",
27
+ ),
28
+ ]
29
+
30
+ outputs = [
31
+ Output(
32
+ display_name="Text-Based File Contents",
33
+ name="text_based_file_contents",
34
+ method="get_text_based_file_contents",
35
+ ),
36
+ Output(display_name="Directory Structure", name="directory_structure", method="get_directory_structure"),
37
+ Output(display_name="Repository Info", name="repository_info", method="get_repository_info"),
38
+ Output(display_name="Statistics", name="statistics", method="get_statistics"),
39
+ Output(display_name="Files Content", name="files_content", method="get_files_content"),
40
+ ]
41
+
42
+ @asynccontextmanager
43
+ async def temp_git_repo(self):
44
+ """Async context manager for temporary git repository cloning."""
45
+ temp_dir = tempfile.mkdtemp()
46
+ try:
47
+ # Clone is still sync but wrapped in try/finally
48
+ git.Repo.clone_from(self.repository_url, temp_dir)
49
+ yield temp_dir
50
+ finally:
51
+ shutil.rmtree(temp_dir, ignore_errors=True)
52
+
53
+ async def get_repository_info(self) -> list[Data]:
54
+ try:
55
+ async with self.temp_git_repo() as temp_dir:
56
+ repo = git.Repo(temp_dir)
57
+ repo_info = {
58
+ "name": self.repository_url.split("/")[-1],
59
+ "url": self.repository_url,
60
+ "default_branch": repo.active_branch.name,
61
+ "remote_urls": [remote.url for remote in repo.remotes],
62
+ "last_commit": {
63
+ "hash": repo.head.commit.hexsha,
64
+ "author": str(repo.head.commit.author),
65
+ "message": repo.head.commit.message.strip(),
66
+ "date": str(repo.head.commit.committed_datetime),
67
+ },
68
+ "branches": [str(branch) for branch in repo.branches],
69
+ }
70
+ result = [Data(data=repo_info)]
71
+ self.status = result
72
+ return result
73
+ except git.GitError as e:
74
+ error_result = [Data(data={"error": f"Error getting repository info: {e!s}"})]
75
+ self.status = error_result
76
+ return error_result
77
+
78
+ async def get_statistics(self) -> list[Data]:
79
+ try:
80
+ async with self.temp_git_repo() as temp_dir:
81
+ total_files = 0
82
+ total_size = 0
83
+ total_lines = 0
84
+ binary_files = 0
85
+ directories = 0
86
+
87
+ for root, dirs, files in os.walk(temp_dir):
88
+ total_files += len(files)
89
+ directories += len(dirs)
90
+ for file in files:
91
+ file_path = Path(root) / file
92
+ total_size += file_path.stat().st_size
93
+ try:
94
+ async with aiofiles.open(file_path, encoding="utf-8") as f:
95
+ total_lines += sum(1 for _ in await f.readlines())
96
+ except UnicodeDecodeError:
97
+ binary_files += 1
98
+
99
+ statistics = {
100
+ "total_files": total_files,
101
+ "total_size_bytes": total_size,
102
+ "total_size_kb": round(total_size / 1024, 2),
103
+ "total_size_mb": round(total_size / (1024 * 1024), 2),
104
+ "total_lines": total_lines,
105
+ "binary_files": binary_files,
106
+ "directories": directories,
107
+ }
108
+ result = [Data(data=statistics)]
109
+ self.status = result
110
+ return result
111
+ except git.GitError as e:
112
+ error_result = [Data(data={"error": f"Error calculating statistics: {e!s}"})]
113
+ self.status = error_result
114
+ return error_result
115
+
116
+ async def get_directory_structure(self) -> Message:
117
+ try:
118
+ async with self.temp_git_repo() as temp_dir:
119
+ tree = ["Directory structure:"]
120
+ for root, _dirs, files in os.walk(temp_dir):
121
+ level = root.replace(temp_dir, "").count(os.sep)
122
+ indent = " " * level
123
+ if level == 0:
124
+ tree.append(f"└── {Path(root).name}")
125
+ else:
126
+ tree.append(f"{indent}├── {Path(root).name}")
127
+ subindent = " " * (level + 1)
128
+ tree.extend(f"{subindent}├── {f}" for f in files)
129
+ directory_structure = "\n".join(tree)
130
+ self.status = directory_structure
131
+ return Message(text=directory_structure)
132
+ except git.GitError as e:
133
+ error_message = f"Error getting directory structure: {e!s}"
134
+ self.status = error_message
135
+ return Message(text=error_message)
136
+
137
+ async def get_files_content(self) -> list[Data]:
138
+ try:
139
+ async with self.temp_git_repo() as temp_dir:
140
+ content_list = []
141
+ for root, _, files in os.walk(temp_dir):
142
+ for file in files:
143
+ file_path = Path(root) / file
144
+ relative_path = file_path.relative_to(temp_dir)
145
+ file_size = file_path.stat().st_size
146
+ try:
147
+ async with aiofiles.open(file_path, encoding="utf-8") as f:
148
+ file_content = await f.read()
149
+ except UnicodeDecodeError:
150
+ file_content = "[BINARY FILE]"
151
+ content_list.append(
152
+ Data(data={"path": str(relative_path), "size": file_size, "content": file_content})
153
+ )
154
+ self.status = content_list
155
+ return content_list
156
+ except git.GitError as e:
157
+ error_result = [Data(data={"error": f"Error getting files content: {e!s}"})]
158
+ self.status = error_result
159
+ return error_result
160
+
161
+ async def get_text_based_file_contents(self) -> Message:
162
+ try:
163
+ async with self.temp_git_repo() as temp_dir:
164
+ content_list = ["(Files content cropped to 300k characters, download full ingest to see more)"]
165
+ total_chars = 0
166
+ char_limit = 300000
167
+
168
+ for root, _, files in os.walk(temp_dir):
169
+ for file in files:
170
+ file_path = Path(root) / file
171
+ relative_path = file_path.relative_to(temp_dir)
172
+ content_list.extend(["=" * 50, f"File: /{relative_path}", "=" * 50])
173
+
174
+ try:
175
+ async with aiofiles.open(file_path, encoding="utf-8") as f:
176
+ file_content = await f.read()
177
+ if total_chars + len(file_content) > char_limit:
178
+ remaining_chars = char_limit - total_chars
179
+ file_content = file_content[:remaining_chars] + "\n... (content truncated)"
180
+ content_list.append(file_content)
181
+ total_chars += len(file_content)
182
+ except UnicodeDecodeError:
183
+ content_list.append("[BINARY FILE]")
184
+
185
+ content_list.append("")
186
+
187
+ if total_chars >= char_limit:
188
+ break
189
+
190
+ text_content = "\n".join(content_list)
191
+ self.status = text_content
192
+ return Message(text=text_content)
193
+ except git.GitError as e:
194
+ error_message = f"Error getting text-based file contents: {e!s}"
195
+ self.status = error_message
196
+ return Message(text=error_message)
@@ -0,0 +1,3 @@
1
+ from .glean_search_api import GleanSearchAPISchema
2
+
3
+ __all__ = ["GleanSearchAPISchema"]
@@ -0,0 +1,173 @@
1
+ import json
2
+ from typing import Any
3
+ from urllib.parse import urljoin
4
+
5
+ import httpx
6
+ from langchain_core.tools import StructuredTool, ToolException
7
+ from pydantic import BaseModel
8
+ from pydantic.v1 import Field
9
+
10
+ from lfx.base.langchain_utilities.model import LCToolComponent
11
+ from lfx.field_typing import Tool
12
+ from lfx.inputs.inputs import IntInput, MultilineInput, NestedDictInput, SecretStrInput, StrInput
13
+ from lfx.io import Output
14
+ from lfx.schema.data import Data
15
+ from lfx.schema.dataframe import DataFrame
16
+
17
+
18
+ class GleanSearchAPISchema(BaseModel):
19
+ query: str = Field(..., description="The search query")
20
+ page_size: int = Field(10, description="Maximum number of results to return")
21
+ request_options: dict[str, Any] | None = Field(default_factory=dict, description="Request Options")
22
+
23
+
24
+ class GleanAPIWrapper(BaseModel):
25
+ """Wrapper around Glean API."""
26
+
27
+ glean_api_url: str
28
+ glean_access_token: str
29
+ act_as: str = "langflow-component@datastax.com" # TODO: Detect this
30
+
31
+ def _prepare_request(
32
+ self,
33
+ query: str,
34
+ page_size: int = 10,
35
+ request_options: dict[str, Any] | None = None,
36
+ ) -> dict:
37
+ # Ensure there's a trailing slash
38
+ url = self.glean_api_url
39
+ if not url.endswith("/"):
40
+ url += "/"
41
+
42
+ return {
43
+ "url": urljoin(url, "search"),
44
+ "headers": {
45
+ "Authorization": f"Bearer {self.glean_access_token}",
46
+ "X-Scio-ActAs": self.act_as,
47
+ },
48
+ "payload": {
49
+ "query": query,
50
+ "pageSize": page_size,
51
+ "requestOptions": request_options,
52
+ },
53
+ }
54
+
55
+ def results(self, query: str, **kwargs: Any) -> list[dict[str, Any]]:
56
+ results = self._search_api_results(query, **kwargs)
57
+
58
+ if len(results) == 0:
59
+ msg = "No good Glean Search Result was found"
60
+ raise AssertionError(msg)
61
+
62
+ return results
63
+
64
+ def run(self, query: str, **kwargs: Any) -> list[dict[str, Any]]:
65
+ try:
66
+ results = self.results(query, **kwargs)
67
+
68
+ processed_results = []
69
+ for result in results:
70
+ if "title" in result:
71
+ result["snippets"] = result.get("snippets", [{"snippet": {"text": result["title"]}}])
72
+ if "text" not in result["snippets"][0]:
73
+ result["snippets"][0]["text"] = result["title"]
74
+
75
+ processed_results.append(result)
76
+ except Exception as e:
77
+ error_message = f"Error in Glean Search API: {e!s}"
78
+ raise ToolException(error_message) from e
79
+
80
+ return processed_results
81
+
82
+ def _search_api_results(self, query: str, **kwargs: Any) -> list[dict[str, Any]]:
83
+ request_details = self._prepare_request(query, **kwargs)
84
+
85
+ response = httpx.post(
86
+ request_details["url"],
87
+ json=request_details["payload"],
88
+ headers=request_details["headers"],
89
+ )
90
+
91
+ response.raise_for_status()
92
+ response_json = response.json()
93
+
94
+ return response_json.get("results", [])
95
+
96
+ @staticmethod
97
+ def _result_as_string(result: dict) -> str:
98
+ return json.dumps(result, indent=4)
99
+
100
+
101
+ class GleanSearchAPIComponent(LCToolComponent):
102
+ display_name: str = "Glean Search API"
103
+ description: str = "Search using Glean's API."
104
+ documentation: str = "https://docs.langflow.org/Components/components-tools#glean-search-api"
105
+ icon: str = "Glean"
106
+
107
+ outputs = [
108
+ Output(display_name="DataFrame", name="dataframe", method="fetch_content_dataframe"),
109
+ ]
110
+
111
+ inputs = [
112
+ StrInput(name="glean_api_url", display_name="Glean API URL", required=True),
113
+ SecretStrInput(name="glean_access_token", display_name="Glean Access Token", required=True),
114
+ MultilineInput(name="query", display_name="Query", required=True, tool_mode=True),
115
+ IntInput(name="page_size", display_name="Page Size", value=10),
116
+ NestedDictInput(name="request_options", display_name="Request Options", required=False),
117
+ ]
118
+
119
+ def build_tool(self) -> Tool:
120
+ wrapper = self._build_wrapper(
121
+ glean_api_url=self.glean_api_url,
122
+ glean_access_token=self.glean_access_token,
123
+ )
124
+
125
+ tool = StructuredTool.from_function(
126
+ name="glean_search_api",
127
+ description="Search Glean for relevant results.",
128
+ func=wrapper.run,
129
+ args_schema=GleanSearchAPISchema,
130
+ )
131
+
132
+ self.status = "Glean Search API Tool for Langchain"
133
+
134
+ return tool
135
+
136
+ def run_model(self) -> DataFrame:
137
+ return self.fetch_content_dataframe()
138
+
139
+ def fetch_content(self) -> list[Data]:
140
+ tool = self.build_tool()
141
+
142
+ results = tool.run(
143
+ {
144
+ "query": self.query,
145
+ "page_size": self.page_size,
146
+ "request_options": self.request_options,
147
+ }
148
+ )
149
+
150
+ # Build the data
151
+ data = [Data(data=result, text=result["snippets"][0]["text"]) for result in results]
152
+ self.status = data # type: ignore[assignment]
153
+
154
+ return data
155
+
156
+ def _build_wrapper(
157
+ self,
158
+ glean_api_url: str,
159
+ glean_access_token: str,
160
+ ):
161
+ return GleanAPIWrapper(
162
+ glean_api_url=glean_api_url,
163
+ glean_access_token=glean_access_token,
164
+ )
165
+
166
+ def fetch_content_dataframe(self) -> DataFrame:
167
+ """Convert the Glean search results to a DataFrame.
168
+
169
+ Returns:
170
+ DataFrame: A DataFrame containing the search results.
171
+ """
172
+ data = self.fetch_content()
173
+ return DataFrame(data)
@@ -0,0 +1,17 @@
1
+ from .gmail import GmailLoaderComponent
2
+ from .google_bq_sql_executor import BigQueryExecutorComponent
3
+ from .google_drive import GoogleDriveComponent
4
+ from .google_drive_search import GoogleDriveSearchComponent
5
+ from .google_generative_ai import GoogleGenerativeAIComponent
6
+ from .google_generative_ai_embeddings import GoogleGenerativeAIEmbeddingsComponent
7
+ from .google_oauth_token import GoogleOAuthToken
8
+
9
+ __all__ = [
10
+ "BigQueryExecutorComponent",
11
+ "GmailLoaderComponent",
12
+ "GoogleDriveComponent",
13
+ "GoogleDriveSearchComponent",
14
+ "GoogleGenerativeAIComponent",
15
+ "GoogleGenerativeAIEmbeddingsComponent",
16
+ "GoogleOAuthToken",
17
+ ]
@@ -0,0 +1,192 @@
1
+ import base64
2
+ import json
3
+ import re
4
+ from collections.abc import Iterator
5
+ from json.decoder import JSONDecodeError
6
+ from typing import Any
7
+
8
+ from google.auth.exceptions import RefreshError
9
+ from google.oauth2.credentials import Credentials
10
+ from googleapiclient.discovery import build
11
+ from langchain_core.chat_sessions import ChatSession
12
+ from langchain_core.messages import HumanMessage
13
+ from langchain_google_community.gmail.loader import GMailLoader
14
+
15
+ from lfx.custom.custom_component.component import Component
16
+ from lfx.inputs.inputs import MessageTextInput
17
+ from lfx.io import SecretStrInput
18
+ from lfx.log.logger import logger
19
+ from lfx.schema.data import Data
20
+ from lfx.template.field.base import Output
21
+
22
+
23
+ class GmailLoaderComponent(Component):
24
+ display_name = "Gmail Loader"
25
+ description = "Loads emails from Gmail using provided credentials."
26
+ icon = "Google"
27
+ legacy: bool = True
28
+
29
+ inputs = [
30
+ SecretStrInput(
31
+ name="json_string",
32
+ display_name="JSON String of the Service Account Token",
33
+ info="JSON string containing OAuth 2.0 access token information for service account access",
34
+ required=True,
35
+ value="""{
36
+ "account": "",
37
+ "client_id": "",
38
+ "client_secret": "",
39
+ "expiry": "",
40
+ "refresh_token": "",
41
+ "scopes": [
42
+ "https://www.googleapis.com/auth/gmail.readonly",
43
+ ],
44
+ "token": "",
45
+ "token_uri": "https://oauth2.googleapis.com/token",
46
+ "universe_domain": "googleapis.com"
47
+ }""",
48
+ ),
49
+ MessageTextInput(
50
+ name="label_ids",
51
+ display_name="Label IDs",
52
+ info="Comma-separated list of label IDs to filter emails.",
53
+ required=True,
54
+ value="INBOX,SENT,UNREAD,IMPORTANT",
55
+ ),
56
+ MessageTextInput(
57
+ name="max_results",
58
+ display_name="Max Results",
59
+ info="Maximum number of emails to load.",
60
+ required=True,
61
+ value="10",
62
+ ),
63
+ ]
64
+
65
+ outputs = [
66
+ Output(display_name="Data", name="data", method="load_emails"),
67
+ ]
68
+
69
+ def load_emails(self) -> Data:
70
+ class CustomGMailLoader(GMailLoader):
71
+ def __init__(
72
+ self, creds: Any, *, n: int = 100, label_ids: list[str] | None = None, raise_error: bool = False
73
+ ) -> None:
74
+ super().__init__(creds, n, raise_error)
75
+ self.label_ids = label_ids if label_ids is not None else ["SENT"]
76
+
77
+ def clean_message_content(self, message):
78
+ # Remove URLs
79
+ message = re.sub(r"http\S+|www\S+|https\S+", "", message, flags=re.MULTILINE)
80
+
81
+ # Remove email addresses
82
+ message = re.sub(r"\S+@\S+", "", message)
83
+
84
+ # Remove special characters and excessive whitespace
85
+ message = re.sub(r"[^A-Za-z0-9\s]+", " ", message)
86
+ message = re.sub(r"\s{2,}", " ", message)
87
+
88
+ # Trim leading and trailing whitespace
89
+ return message.strip()
90
+
91
+ def _extract_email_content(self, msg: Any) -> HumanMessage:
92
+ from_email = None
93
+ for values in msg["payload"]["headers"]:
94
+ name = values["name"]
95
+ if name == "From":
96
+ from_email = values["value"]
97
+ if from_email is None:
98
+ msg = "From email not found."
99
+ raise ValueError(msg)
100
+
101
+ parts = msg["payload"]["parts"] if "parts" in msg["payload"] else [msg["payload"]]
102
+
103
+ for part in parts:
104
+ if part["mimeType"] == "text/plain":
105
+ data = part["body"]["data"]
106
+ data = base64.urlsafe_b64decode(data).decode("utf-8")
107
+ pattern = re.compile(r"\r\nOn .+(\r\n)*wrote:\r\n")
108
+ newest_response = re.split(pattern, data)[0]
109
+ return HumanMessage(
110
+ content=self.clean_message_content(newest_response),
111
+ additional_kwargs={"sender": from_email},
112
+ )
113
+ msg = "No plain text part found in the email."
114
+ raise ValueError(msg)
115
+
116
+ def _get_message_data(self, service: Any, message: Any) -> ChatSession:
117
+ msg = service.users().messages().get(userId="me", id=message["id"]).execute()
118
+ message_content = self._extract_email_content(msg)
119
+
120
+ in_reply_to = None
121
+ email_data = msg["payload"]["headers"]
122
+ for values in email_data:
123
+ name = values["name"]
124
+ if name == "In-Reply-To":
125
+ in_reply_to = values["value"]
126
+
127
+ thread_id = msg["threadId"]
128
+
129
+ if in_reply_to:
130
+ thread = service.users().threads().get(userId="me", id=thread_id).execute()
131
+ messages = thread["messages"]
132
+
133
+ response_email = None
134
+ for _message in messages:
135
+ email_data = _message["payload"]["headers"]
136
+ for values in email_data:
137
+ if values["name"] == "Message-ID":
138
+ message_id = values["value"]
139
+ if message_id == in_reply_to:
140
+ response_email = _message
141
+ if response_email is None:
142
+ msg = "Response email not found in the thread."
143
+ raise ValueError(msg)
144
+ starter_content = self._extract_email_content(response_email)
145
+ return ChatSession(messages=[starter_content, message_content])
146
+ return ChatSession(messages=[message_content])
147
+
148
+ def lazy_load(self) -> Iterator[ChatSession]:
149
+ service = build("gmail", "v1", credentials=self.creds)
150
+ results = (
151
+ service.users().messages().list(userId="me", labelIds=self.label_ids, maxResults=self.n).execute()
152
+ )
153
+ messages = results.get("messages", [])
154
+ if not messages:
155
+ logger.warning("No messages found with the specified labels.")
156
+ for message in messages:
157
+ try:
158
+ yield self._get_message_data(service, message)
159
+ except Exception:
160
+ if self.raise_error:
161
+ raise
162
+ else:
163
+ logger.exception(f"Error processing message {message['id']}")
164
+
165
+ json_string = self.json_string
166
+ label_ids = self.label_ids.split(",") if self.label_ids else ["INBOX"]
167
+ max_results = int(self.max_results) if self.max_results else 100
168
+
169
+ # Load the token information from the JSON string
170
+ try:
171
+ token_info = json.loads(json_string)
172
+ except JSONDecodeError as e:
173
+ msg = "Invalid JSON string"
174
+ raise ValueError(msg) from e
175
+
176
+ creds = Credentials.from_authorized_user_info(token_info)
177
+
178
+ # Initialize the custom loader with the provided credentials
179
+ loader = CustomGMailLoader(creds=creds, n=max_results, label_ids=label_ids)
180
+
181
+ try:
182
+ docs = loader.load()
183
+ except RefreshError as e:
184
+ msg = "Authentication error: Unable to refresh authentication token. Please try to reauthenticate."
185
+ raise ValueError(msg) from e
186
+ except Exception as e:
187
+ msg = f"Error loading documents: {e}"
188
+ raise ValueError(msg) from e
189
+
190
+ # Return the loaded documents
191
+ self.status = docs
192
+ return Data(data={"text": docs})