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,187 @@
1
+ from typing import Any, cast
2
+
3
+ import requests
4
+ from pydantic import ValidationError
5
+
6
+ from lfx.base.models.anthropic_constants import (
7
+ ANTHROPIC_MODELS,
8
+ DEFAULT_ANTHROPIC_API_URL,
9
+ TOOL_CALLING_SUPPORTED_ANTHROPIC_MODELS,
10
+ TOOL_CALLING_UNSUPPORTED_ANTHROPIC_MODELS,
11
+ )
12
+ from lfx.base.models.model import LCModelComponent
13
+ from lfx.field_typing import LanguageModel
14
+ from lfx.field_typing.range_spec import RangeSpec
15
+ from lfx.io import BoolInput, DropdownInput, IntInput, MessageTextInput, SecretStrInput, SliderInput
16
+ from lfx.log.logger import logger
17
+ from lfx.schema.dotdict import dotdict
18
+
19
+
20
+ class AnthropicModelComponent(LCModelComponent):
21
+ display_name = "Anthropic"
22
+ description = "Generate text using Anthropic's Messages API and models."
23
+ icon = "Anthropic"
24
+ name = "AnthropicModel"
25
+
26
+ inputs = [
27
+ *LCModelComponent.get_base_inputs(),
28
+ IntInput(
29
+ name="max_tokens",
30
+ display_name="Max Tokens",
31
+ advanced=True,
32
+ value=4096,
33
+ info="The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
34
+ ),
35
+ DropdownInput(
36
+ name="model_name",
37
+ display_name="Model Name",
38
+ options=ANTHROPIC_MODELS,
39
+ refresh_button=True,
40
+ value=ANTHROPIC_MODELS[0],
41
+ combobox=True,
42
+ ),
43
+ SecretStrInput(
44
+ name="api_key",
45
+ display_name="Anthropic API Key",
46
+ info="Your Anthropic API key.",
47
+ value=None,
48
+ required=True,
49
+ real_time_refresh=True,
50
+ ),
51
+ SliderInput(
52
+ name="temperature",
53
+ display_name="Temperature",
54
+ value=0.1,
55
+ info="Run inference with this temperature. Must by in the closed interval [0.0, 1.0].",
56
+ range_spec=RangeSpec(min=0, max=1, step=0.01),
57
+ advanced=True,
58
+ ),
59
+ MessageTextInput(
60
+ name="base_url",
61
+ display_name="Anthropic API URL",
62
+ info="Endpoint of the Anthropic API. Defaults to 'https://api.anthropic.com' if not specified.",
63
+ value=DEFAULT_ANTHROPIC_API_URL,
64
+ real_time_refresh=True,
65
+ advanced=True,
66
+ ),
67
+ BoolInput(
68
+ name="tool_model_enabled",
69
+ display_name="Enable Tool Models",
70
+ info=(
71
+ "Select if you want to use models that can work with tools. If yes, only those models will be shown."
72
+ ),
73
+ advanced=False,
74
+ value=False,
75
+ real_time_refresh=True,
76
+ ),
77
+ ]
78
+
79
+ def build_model(self) -> LanguageModel: # type: ignore[type-var]
80
+ try:
81
+ from langchain_anthropic.chat_models import ChatAnthropic
82
+ except ImportError as e:
83
+ msg = "langchain_anthropic is not installed. Please install it with `pip install langchain_anthropic`."
84
+ raise ImportError(msg) from e
85
+ try:
86
+ max_tokens_value = getattr(self, "max_tokens", "")
87
+ max_tokens_value = 4096 if max_tokens_value == "" else int(max_tokens_value)
88
+ output = ChatAnthropic(
89
+ model=self.model_name,
90
+ anthropic_api_key=self.api_key,
91
+ max_tokens=max_tokens_value,
92
+ temperature=self.temperature,
93
+ anthropic_api_url=self.base_url or DEFAULT_ANTHROPIC_API_URL,
94
+ streaming=self.stream,
95
+ )
96
+ except ValidationError:
97
+ raise
98
+ except Exception as e:
99
+ msg = "Could not connect to Anthropic API."
100
+ raise ValueError(msg) from e
101
+
102
+ return output
103
+
104
+ def get_models(self, *, tool_model_enabled: bool | None = None) -> list[str]:
105
+ try:
106
+ import anthropic
107
+
108
+ client = anthropic.Anthropic(api_key=self.api_key)
109
+ models = client.models.list(limit=20).data
110
+ model_ids = ANTHROPIC_MODELS + [model.id for model in models]
111
+ except (ImportError, ValueError, requests.exceptions.RequestException) as e:
112
+ logger.exception(f"Error getting model names: {e}")
113
+ model_ids = ANTHROPIC_MODELS
114
+
115
+ if tool_model_enabled:
116
+ try:
117
+ from langchain_anthropic.chat_models import ChatAnthropic
118
+ except ImportError as e:
119
+ msg = "langchain_anthropic is not installed. Please install it with `pip install langchain_anthropic`."
120
+ raise ImportError(msg) from e
121
+
122
+ # Create a new list instead of modifying while iterating
123
+ filtered_models = []
124
+ for model in model_ids:
125
+ if model in TOOL_CALLING_SUPPORTED_ANTHROPIC_MODELS:
126
+ filtered_models.append(model)
127
+ continue
128
+
129
+ model_with_tool = ChatAnthropic(
130
+ model=model, # Use the current model being checked
131
+ anthropic_api_key=self.api_key,
132
+ anthropic_api_url=cast("str", self.base_url) or DEFAULT_ANTHROPIC_API_URL,
133
+ )
134
+
135
+ if (
136
+ not self.supports_tool_calling(model_with_tool)
137
+ or model in TOOL_CALLING_UNSUPPORTED_ANTHROPIC_MODELS
138
+ ):
139
+ continue
140
+
141
+ filtered_models.append(model)
142
+
143
+ return filtered_models
144
+
145
+ return model_ids
146
+
147
+ def _get_exception_message(self, exception: Exception) -> str | None:
148
+ """Get a message from an Anthropic exception.
149
+
150
+ Args:
151
+ exception (Exception): The exception to get the message from.
152
+
153
+ Returns:
154
+ str: The message from the exception.
155
+ """
156
+ try:
157
+ from anthropic import BadRequestError
158
+ except ImportError:
159
+ return None
160
+ if isinstance(exception, BadRequestError):
161
+ message = exception.body.get("error", {}).get("message")
162
+ if message:
163
+ return message
164
+ return None
165
+
166
+ def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None):
167
+ if "base_url" in build_config and build_config["base_url"]["value"] is None:
168
+ build_config["base_url"]["value"] = DEFAULT_ANTHROPIC_API_URL
169
+ self.base_url = DEFAULT_ANTHROPIC_API_URL
170
+ if field_name in {"base_url", "model_name", "tool_model_enabled", "api_key"} and field_value:
171
+ try:
172
+ if len(self.api_key) == 0:
173
+ ids = ANTHROPIC_MODELS
174
+ else:
175
+ try:
176
+ ids = self.get_models(tool_model_enabled=self.tool_model_enabled)
177
+ except (ImportError, ValueError, requests.exceptions.RequestException) as e:
178
+ logger.exception(f"Error getting model names: {e}")
179
+ ids = ANTHROPIC_MODELS
180
+ build_config.setdefault("model_name", {})
181
+ build_config["model_name"]["options"] = ids
182
+ build_config["model_name"].setdefault("value", ids[0])
183
+ build_config["model_name"]["combobox"] = True
184
+ except Exception as e:
185
+ msg = f"Error getting model names: {e}"
186
+ raise ValueError(msg) from e
187
+ return build_config
@@ -0,0 +1,5 @@
1
+ from .apify_actor import ApifyActorsComponent
2
+
3
+ __all__ = [
4
+ "ApifyActorsComponent",
5
+ ]
@@ -0,0 +1,325 @@
1
+ import json
2
+ import string
3
+ from typing import Any, cast
4
+
5
+ from apify_client import ApifyClient
6
+ from langchain_community.document_loaders.apify_dataset import ApifyDatasetLoader
7
+ from langchain_core.tools import BaseTool
8
+ from pydantic import BaseModel, Field, field_serializer
9
+
10
+ from lfx.custom.custom_component.component import Component
11
+ from lfx.field_typing import Tool
12
+ from lfx.inputs.inputs import BoolInput
13
+ from lfx.io import MultilineInput, Output, SecretStrInput, StrInput
14
+ from lfx.schema.data import Data
15
+
16
+ MAX_DESCRIPTION_LEN = 250
17
+
18
+
19
+ class ApifyActorsComponent(Component):
20
+ display_name = "Apify Actors"
21
+ description = (
22
+ "Use Apify Actors to extract data from hundreds of places fast. "
23
+ "This component can be used in a flow to retrieve data or as a tool with an agent."
24
+ )
25
+ documentation: str = "http://docs.langflow.org/integrations-apify"
26
+ icon = "Apify"
27
+ name = "ApifyActors"
28
+
29
+ inputs = [
30
+ SecretStrInput(
31
+ name="apify_token",
32
+ display_name="Apify Token",
33
+ info="The API token for the Apify account.",
34
+ required=True,
35
+ password=True,
36
+ ),
37
+ StrInput(
38
+ name="actor_id",
39
+ display_name="Actor",
40
+ info=(
41
+ "Actor name from Apify store to run. For example 'apify/website-content-crawler' "
42
+ "to use the Website Content Crawler Actor."
43
+ ),
44
+ value="apify/website-content-crawler",
45
+ required=True,
46
+ ),
47
+ # multiline input is more pleasant to use than the nested dict input
48
+ MultilineInput(
49
+ name="run_input",
50
+ display_name="Run input",
51
+ info=(
52
+ 'The JSON input for the Actor run. For example for the "apify/website-content-crawler" Actor: '
53
+ '{"startUrls":[{"url":"https://docs.apify.com/academy/web-scraping-for-beginners"}],"maxCrawlDepth":0}'
54
+ ),
55
+ value='{"startUrls":[{"url":"https://docs.apify.com/academy/web-scraping-for-beginners"}],"maxCrawlDepth":0}',
56
+ required=True,
57
+ ),
58
+ MultilineInput(
59
+ name="dataset_fields",
60
+ display_name="Output fields",
61
+ info=(
62
+ "Fields to extract from the dataset, split by commas. "
63
+ "Other fields will be ignored. Dots in nested structures will be replaced by underscores. "
64
+ "Sample input: 'text, metadata.title'. "
65
+ "Sample output: {'text': 'page content here', 'metadata_title': 'page title here'}. "
66
+ "For example, for the 'apify/website-content-crawler' Actor, you can extract the 'markdown' field, "
67
+ "which is the content of the website in markdown format."
68
+ ),
69
+ ),
70
+ BoolInput(
71
+ name="flatten_dataset",
72
+ display_name="Flatten output",
73
+ info=(
74
+ "The output dataset will be converted from a nested format to a flat structure. "
75
+ "Dots in nested structure will be replaced by underscores. "
76
+ "This is useful for further processing of the Data object. "
77
+ "For example, {'a': {'b': 1}} will be flattened to {'a_b': 1}."
78
+ ),
79
+ ),
80
+ ]
81
+
82
+ outputs = [
83
+ Output(display_name="Output", name="output", type_=list[Data], method="run_model"),
84
+ Output(display_name="Tool", name="tool", type_=Tool, method="build_tool"),
85
+ ]
86
+
87
+ def __init__(self, *args, **kwargs) -> None:
88
+ super().__init__(*args, **kwargs)
89
+ self._apify_client: ApifyClient | None = None
90
+
91
+ def run_model(self) -> list[Data]:
92
+ """Run the Actor and return node output."""
93
+ input_ = json.loads(self.run_input)
94
+ fields = ApifyActorsComponent.parse_dataset_fields(self.dataset_fields) if self.dataset_fields else None
95
+ res = self._run_actor(self.actor_id, input_, fields=fields)
96
+ if self.flatten_dataset:
97
+ res = [ApifyActorsComponent.flatten(item) for item in res]
98
+ data = [Data(data=item) for item in res]
99
+
100
+ self.status = data
101
+ return data
102
+
103
+ def build_tool(self) -> Tool:
104
+ """Build a tool for an agent that runs the Apify Actor."""
105
+ actor_id = self.actor_id
106
+
107
+ build = self._get_actor_latest_build(actor_id)
108
+ readme = build.get("readme", "")[:250] + "..."
109
+ if not (input_schema_str := build.get("inputSchema")):
110
+ msg = "Input schema not found"
111
+ raise ValueError(msg)
112
+ input_schema = json.loads(input_schema_str)
113
+ properties, required = ApifyActorsComponent.get_actor_input_schema_from_build(input_schema)
114
+ properties = {"run_input": properties}
115
+
116
+ # works from input schema
117
+ info_ = [
118
+ (
119
+ "JSON encoded as a string with input schema (STRICTLY FOLLOW JSON FORMAT AND SCHEMA):\n\n"
120
+ f"{json.dumps(properties, separators=(',', ':'))}"
121
+ )
122
+ ]
123
+ if required:
124
+ info_.append("\n\nRequired fields:\n" + "\n".join(required))
125
+
126
+ info = "".join(info_)
127
+
128
+ input_model_cls = ApifyActorsComponent.create_input_model_class(info)
129
+ tool_cls = ApifyActorsComponent.create_tool_class(self, readme, input_model_cls, actor_id)
130
+
131
+ return cast("Tool", tool_cls())
132
+
133
+ @staticmethod
134
+ def create_tool_class(
135
+ parent: "ApifyActorsComponent", readme: str, input_model: type[BaseModel], actor_id: str
136
+ ) -> type[BaseTool]:
137
+ """Create a tool class that runs an Apify Actor."""
138
+
139
+ class ApifyActorRun(BaseTool):
140
+ """Tool that runs Apify Actors."""
141
+
142
+ name: str = f"apify_actor_{ApifyActorsComponent.actor_id_to_tool_name(actor_id)}"
143
+ description: str = (
144
+ "Run an Apify Actor with the given input. "
145
+ "Here is a part of the currently loaded Actor README:\n\n"
146
+ f"{readme}\n\n"
147
+ )
148
+
149
+ args_schema: type[BaseModel] = input_model
150
+
151
+ @field_serializer("args_schema")
152
+ def serialize_args_schema(self, args_schema):
153
+ return args_schema.schema()
154
+
155
+ def _run(self, run_input: str | dict) -> str:
156
+ """Use the Apify Actor."""
157
+ input_dict = json.loads(run_input) if isinstance(run_input, str) else run_input
158
+
159
+ # retrieve if nested, just in case
160
+ input_dict = input_dict.get("run_input", input_dict)
161
+
162
+ res = parent._run_actor(actor_id, input_dict)
163
+ return "\n\n".join([ApifyActorsComponent.dict_to_json_str(item) for item in res])
164
+
165
+ return ApifyActorRun
166
+
167
+ @staticmethod
168
+ def create_input_model_class(description: str) -> type[BaseModel]:
169
+ """Create a Pydantic model class for the Actor input."""
170
+
171
+ class ActorInput(BaseModel):
172
+ """Input for the Apify Actor tool."""
173
+
174
+ run_input: str = Field(..., description=description)
175
+
176
+ return ActorInput
177
+
178
+ def _get_apify_client(self) -> ApifyClient:
179
+ """Get the Apify client.
180
+
181
+ Is created if not exists or token changes.
182
+ """
183
+ if not self.apify_token:
184
+ msg = "API token is required."
185
+ raise ValueError(msg)
186
+ # when token changes, create a new client
187
+ if self._apify_client is None or self._apify_client.token != self.apify_token:
188
+ self._apify_client = ApifyClient(self.apify_token)
189
+ if httpx_client := self._apify_client.http_client.httpx_client:
190
+ httpx_client.headers["user-agent"] += "; Origin/langflow"
191
+ return self._apify_client
192
+
193
+ def _get_actor_latest_build(self, actor_id: str) -> dict:
194
+ """Get the latest build of an Actor from the default build tag."""
195
+ client = self._get_apify_client()
196
+ actor = client.actor(actor_id=actor_id)
197
+ if not (actor_info := actor.get()):
198
+ msg = f"Actor {actor_id} not found."
199
+ raise ValueError(msg)
200
+
201
+ default_build_tag = actor_info.get("defaultRunOptions", {}).get("build")
202
+ latest_build_id = actor_info.get("taggedBuilds", {}).get(default_build_tag, {}).get("buildId")
203
+
204
+ if (build := client.build(latest_build_id).get()) is None:
205
+ msg = f"Build {latest_build_id} not found."
206
+ raise ValueError(msg)
207
+
208
+ return build
209
+
210
+ @staticmethod
211
+ def get_actor_input_schema_from_build(input_schema: dict) -> tuple[dict, list[str]]:
212
+ """Get the input schema from the Actor build.
213
+
214
+ Trim the description to 250 characters.
215
+ """
216
+ properties = input_schema.get("properties", {})
217
+ required = input_schema.get("required", [])
218
+
219
+ properties_out: dict = {}
220
+ for item, meta in properties.items():
221
+ properties_out[item] = {}
222
+ if desc := meta.get("description"):
223
+ properties_out[item]["description"] = (
224
+ desc[:MAX_DESCRIPTION_LEN] + "..." if len(desc) > MAX_DESCRIPTION_LEN else desc
225
+ )
226
+ for key_name in ("type", "default", "prefill", "enum"):
227
+ if value := meta.get(key_name):
228
+ properties_out[item][key_name] = value
229
+
230
+ return properties_out, required
231
+
232
+ def _get_run_dataset_id(self, run_id: str) -> str:
233
+ """Get the dataset id from the run id."""
234
+ client = self._get_apify_client()
235
+ run = client.run(run_id=run_id)
236
+ if (dataset := run.dataset().get()) is None:
237
+ msg = "Dataset not found"
238
+ raise ValueError(msg)
239
+ if (did := dataset.get("id")) is None:
240
+ msg = "Dataset id not found"
241
+ raise ValueError(msg)
242
+ return did
243
+
244
+ @staticmethod
245
+ def dict_to_json_str(d: dict) -> str:
246
+ """Convert a dictionary to a JSON string."""
247
+ return json.dumps(d, separators=(",", ":"), default=lambda _: "<n/a>")
248
+
249
+ @staticmethod
250
+ def actor_id_to_tool_name(actor_id: str) -> str:
251
+ """Turn actor_id into a valid tool name.
252
+
253
+ Tool name must only contain letters, numbers, underscores, dashes,
254
+ and cannot contain spaces.
255
+ """
256
+ valid_chars = string.ascii_letters + string.digits + "_-"
257
+ return "".join(char if char in valid_chars else "_" for char in actor_id)
258
+
259
+ def _run_actor(self, actor_id: str, run_input: dict, fields: list[str] | None = None) -> list[dict]:
260
+ """Run an Apify Actor and return the output dataset.
261
+
262
+ Args:
263
+ actor_id: Actor name from Apify store to run.
264
+ run_input: JSON input for the Actor.
265
+ fields: List of fields to extract from the dataset. Other fields will be ignored.
266
+ """
267
+ client = self._get_apify_client()
268
+ if (details := client.actor(actor_id=actor_id).call(run_input=run_input, wait_secs=1)) is None:
269
+ msg = "Actor run details not found"
270
+ raise ValueError(msg)
271
+ if (run_id := details.get("id")) is None:
272
+ msg = "Run id not found"
273
+ raise ValueError(msg)
274
+
275
+ if (run_client := client.run(run_id)) is None:
276
+ msg = "Run client not found"
277
+ raise ValueError(msg)
278
+
279
+ # stream logs
280
+ with run_client.log().stream() as response:
281
+ if response:
282
+ for line in response.iter_lines():
283
+ self.log(line)
284
+ run_client.wait_for_finish()
285
+
286
+ dataset_id = self._get_run_dataset_id(run_id)
287
+
288
+ loader = ApifyDatasetLoader(
289
+ dataset_id=dataset_id,
290
+ dataset_mapping_function=lambda item: item
291
+ if not fields
292
+ else {k.replace(".", "_"): ApifyActorsComponent.get_nested_value(item, k) for k in fields},
293
+ )
294
+ return loader.load()
295
+
296
+ @staticmethod
297
+ def get_nested_value(data: dict[str, Any], key: str) -> Any:
298
+ """Get a nested value from a dictionary."""
299
+ keys = key.split(".")
300
+ value = data
301
+ for k in keys:
302
+ if not isinstance(value, dict) or k not in value:
303
+ return None
304
+ value = value[k]
305
+ return value
306
+
307
+ @staticmethod
308
+ def parse_dataset_fields(dataset_fields: str) -> list[str]:
309
+ """Convert a string of comma-separated fields into a list of fields."""
310
+ dataset_fields = dataset_fields.replace("'", "").replace('"', "").replace("`", "")
311
+ return [field.strip() for field in dataset_fields.split(",")]
312
+
313
+ @staticmethod
314
+ def flatten(d: dict) -> dict:
315
+ """Flatten a nested dictionary."""
316
+
317
+ def items():
318
+ for key, value in d.items():
319
+ if isinstance(value, dict):
320
+ for subkey, subvalue in ApifyActorsComponent.flatten(value).items():
321
+ yield key + "_" + subkey, subvalue
322
+ else:
323
+ yield key, value
324
+
325
+ return dict(items())
@@ -0,0 +1,3 @@
1
+ from .arxiv import ArXivComponent
2
+
3
+ __all__ = ["ArXivComponent"]
@@ -0,0 +1,163 @@
1
+ import urllib.request
2
+ from urllib.parse import urlparse
3
+ from xml.etree.ElementTree import Element
4
+
5
+ from defusedxml.ElementTree import fromstring
6
+
7
+ from lfx.custom.custom_component.component import Component
8
+ from lfx.io import DropdownInput, IntInput, MessageTextInput, Output
9
+ from lfx.schema.data import Data
10
+ from lfx.schema.dataframe import DataFrame
11
+
12
+
13
+ class ArXivComponent(Component):
14
+ display_name = "arXiv"
15
+ description = "Search and retrieve papers from arXiv.org"
16
+ icon = "arXiv"
17
+
18
+ inputs = [
19
+ MessageTextInput(
20
+ name="search_query",
21
+ display_name="Search Query",
22
+ info="The search query for arXiv papers (e.g., 'quantum computing')",
23
+ tool_mode=True,
24
+ ),
25
+ DropdownInput(
26
+ name="search_type",
27
+ display_name="Search Field",
28
+ info="The field to search in",
29
+ options=["all", "title", "abstract", "author", "cat"], # cat is for category
30
+ value="all",
31
+ ),
32
+ IntInput(
33
+ name="max_results",
34
+ display_name="Max Results",
35
+ info="Maximum number of results to return",
36
+ value=10,
37
+ ),
38
+ ]
39
+
40
+ outputs = [
41
+ Output(display_name="DataFrame", name="dataframe", method="search_papers_dataframe"),
42
+ ]
43
+
44
+ def build_query_url(self) -> str:
45
+ """Build the arXiv API query URL."""
46
+ base_url = "http://export.arxiv.org/api/query?"
47
+
48
+ # Build the search query
49
+ search_query = f"{self.search_type}:{self.search_query}"
50
+
51
+ # URL parameters
52
+ params = {
53
+ "search_query": search_query,
54
+ "max_results": str(self.max_results),
55
+ }
56
+
57
+ # Convert params to URL query string
58
+ query_string = "&".join([f"{k}={urllib.parse.quote(str(v))}" for k, v in params.items()])
59
+
60
+ return base_url + query_string
61
+
62
+ def parse_atom_response(self, response_text: str) -> list[dict]:
63
+ """Parse the Atom XML response from arXiv."""
64
+ # Parse XML safely using defusedxml
65
+ root = fromstring(response_text)
66
+
67
+ # Define namespace dictionary for XML parsing
68
+ ns = {"atom": "http://www.w3.org/2005/Atom", "arxiv": "http://arxiv.org/schemas/atom"}
69
+
70
+ papers = []
71
+ # Process each entry (paper)
72
+ for entry in root.findall("atom:entry", ns):
73
+ paper = {
74
+ "id": self._get_text(entry, "atom:id", ns),
75
+ "title": self._get_text(entry, "atom:title", ns),
76
+ "summary": self._get_text(entry, "atom:summary", ns),
77
+ "published": self._get_text(entry, "atom:published", ns),
78
+ "updated": self._get_text(entry, "atom:updated", ns),
79
+ "authors": [author.find("atom:name", ns).text for author in entry.findall("atom:author", ns)],
80
+ "arxiv_url": self._get_link(entry, "alternate", ns),
81
+ "pdf_url": self._get_link(entry, "related", ns),
82
+ "comment": self._get_text(entry, "arxiv:comment", ns),
83
+ "journal_ref": self._get_text(entry, "arxiv:journal_ref", ns),
84
+ "primary_category": self._get_category(entry, ns),
85
+ "categories": [cat.get("term") for cat in entry.findall("atom:category", ns)],
86
+ }
87
+ papers.append(paper)
88
+
89
+ return papers
90
+
91
+ def _get_text(self, element: Element, path: str, ns: dict) -> str | None:
92
+ """Safely extract text from an XML element."""
93
+ el = element.find(path, ns)
94
+ return el.text.strip() if el is not None and el.text else None
95
+
96
+ def _get_link(self, element: Element, rel: str, ns: dict) -> str | None:
97
+ """Get link URL based on relation type."""
98
+ for link in element.findall("atom:link", ns):
99
+ if link.get("rel") == rel:
100
+ return link.get("href")
101
+ return None
102
+
103
+ def _get_category(self, element: Element, ns: dict) -> str | None:
104
+ """Get primary category."""
105
+ cat = element.find("arxiv:primary_category", ns)
106
+ return cat.get("term") if cat is not None else None
107
+
108
+ def run_model(self) -> DataFrame:
109
+ return self.search_papers_dataframe()
110
+
111
+ def search_papers(self) -> list[Data]:
112
+ """Search arXiv and return results."""
113
+ try:
114
+ # Build the query URL
115
+ url = self.build_query_url()
116
+
117
+ # Validate URL scheme and host
118
+ parsed_url = urlparse(url)
119
+ if parsed_url.scheme not in {"http", "https"}:
120
+ error_msg = f"Invalid URL scheme: {parsed_url.scheme}"
121
+ raise ValueError(error_msg)
122
+ if parsed_url.hostname != "export.arxiv.org":
123
+ error_msg = f"Invalid host: {parsed_url.hostname}"
124
+ raise ValueError(error_msg)
125
+
126
+ # Create a custom opener that only allows http/https schemes
127
+ class RestrictedHTTPHandler(urllib.request.HTTPHandler):
128
+ def http_open(self, req):
129
+ return super().http_open(req)
130
+
131
+ class RestrictedHTTPSHandler(urllib.request.HTTPSHandler):
132
+ def https_open(self, req):
133
+ return super().https_open(req)
134
+
135
+ # Build opener with restricted handlers
136
+ opener = urllib.request.build_opener(RestrictedHTTPHandler, RestrictedHTTPSHandler)
137
+ urllib.request.install_opener(opener)
138
+
139
+ # Make the request with validated URL using restricted opener
140
+ response = opener.open(url)
141
+ response_text = response.read().decode("utf-8")
142
+
143
+ # Parse the response
144
+ papers = self.parse_atom_response(response_text)
145
+
146
+ # Convert to Data objects
147
+ results = [Data(data=paper) for paper in papers]
148
+ self.status = results
149
+ except (urllib.error.URLError, ValueError) as e:
150
+ error_data = Data(data={"error": f"Request error: {e!s}"})
151
+ self.status = error_data
152
+ return [error_data]
153
+ else:
154
+ return results
155
+
156
+ def search_papers_dataframe(self) -> DataFrame:
157
+ """Convert the Arxiv search results to a DataFrame.
158
+
159
+ Returns:
160
+ DataFrame: A DataFrame containing the search results.
161
+ """
162
+ data = self.search_papers()
163
+ return DataFrame(data)