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,108 @@
1
+ import ast
2
+ import operator
3
+
4
+ import pytest
5
+ from langchain_core.tools import ToolException
6
+ from pydantic import BaseModel, Field
7
+
8
+ from lfx.base.langchain_utilities.model import LCToolComponent
9
+ from lfx.field_typing import Tool
10
+ from lfx.inputs.inputs import MessageTextInput
11
+ from lfx.log.logger import logger
12
+ from lfx.schema.data import Data
13
+
14
+
15
+ class CalculatorToolComponent(LCToolComponent):
16
+ display_name = "Calculator [DEPRECATED]"
17
+ description = "Perform basic arithmetic operations on a given expression."
18
+ icon = "calculator"
19
+ name = "CalculatorTool"
20
+ legacy = True
21
+
22
+ inputs = [
23
+ MessageTextInput(
24
+ name="expression",
25
+ display_name="Expression",
26
+ info="The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').",
27
+ ),
28
+ ]
29
+
30
+ class CalculatorToolSchema(BaseModel):
31
+ expression: str = Field(..., description="The arithmetic expression to evaluate.")
32
+
33
+ def run_model(self) -> list[Data]:
34
+ return self._evaluate_expression(self.expression)
35
+
36
+ def build_tool(self) -> Tool:
37
+ try:
38
+ from langchain.tools import StructuredTool
39
+ except Exception: # noqa: BLE001
40
+ pytest.skip("langchain is not available")
41
+
42
+ return StructuredTool.from_function(
43
+ name="calculator",
44
+ description="Evaluate basic arithmetic expressions. Input should be a string containing the expression.",
45
+ func=self._eval_expr_with_error,
46
+ args_schema=self.CalculatorToolSchema,
47
+ )
48
+
49
+ def _eval_expr(self, node):
50
+ if isinstance(node, ast.Num):
51
+ return node.n
52
+ if isinstance(node, ast.BinOp):
53
+ left_val = self._eval_expr(node.left)
54
+ right_val = self._eval_expr(node.right)
55
+ return self.operators[type(node.op)](left_val, right_val)
56
+ if isinstance(node, ast.UnaryOp):
57
+ operand_val = self._eval_expr(node.operand)
58
+ return self.operators[type(node.op)](operand_val)
59
+ if isinstance(node, ast.Call):
60
+ msg = (
61
+ "Function calls like sqrt(), sin(), cos() etc. are not supported. "
62
+ "Only basic arithmetic operations (+, -, *, /, **) are allowed."
63
+ )
64
+ raise TypeError(msg)
65
+ msg = f"Unsupported operation or expression type: {type(node).__name__}"
66
+ raise TypeError(msg)
67
+
68
+ def _eval_expr_with_error(self, expression: str) -> list[Data]:
69
+ try:
70
+ return self._evaluate_expression(expression)
71
+ except Exception as e:
72
+ raise ToolException(str(e)) from e
73
+
74
+ def _evaluate_expression(self, expression: str) -> list[Data]:
75
+ try:
76
+ # Parse the expression and evaluate it
77
+ tree = ast.parse(expression, mode="eval")
78
+ result = self._eval_expr(tree.body)
79
+
80
+ # Format the result to a reasonable number of decimal places
81
+ formatted_result = f"{result:.6f}".rstrip("0").rstrip(".")
82
+
83
+ self.status = formatted_result
84
+ return [Data(data={"result": formatted_result})]
85
+
86
+ except (SyntaxError, TypeError, KeyError) as e:
87
+ error_message = f"Invalid expression: {e}"
88
+ self.status = error_message
89
+ return [Data(data={"error": error_message, "input": expression})]
90
+ except ZeroDivisionError:
91
+ error_message = "Error: Division by zero"
92
+ self.status = error_message
93
+ return [Data(data={"error": error_message, "input": expression})]
94
+ except Exception as e: # noqa: BLE001
95
+ logger.debug("Error evaluating expression", exc_info=True)
96
+ error_message = f"Error: {e}"
97
+ self.status = error_message
98
+ return [Data(data={"error": error_message, "input": expression})]
99
+
100
+ def __init__(self, *args, **kwargs):
101
+ super().__init__(*args, **kwargs)
102
+ self.operators = {
103
+ ast.Add: operator.add,
104
+ ast.Sub: operator.sub,
105
+ ast.Mult: operator.mul,
106
+ ast.Div: operator.truediv,
107
+ ast.Pow: operator.pow,
108
+ }
@@ -0,0 +1,45 @@
1
+ from langchain_core.tools import Tool
2
+
3
+ from lfx.base.langchain_utilities.model import LCToolComponent
4
+ from lfx.inputs.inputs import IntInput, MultilineInput, SecretStrInput
5
+ from lfx.schema.data import Data
6
+
7
+
8
+ class GoogleSearchAPIComponent(LCToolComponent):
9
+ display_name = "Google Search API [DEPRECATED]"
10
+ description = "Call Google Search API."
11
+ name = "GoogleSearchAPI"
12
+ icon = "Google"
13
+ legacy = True
14
+ inputs = [
15
+ SecretStrInput(name="google_api_key", display_name="Google API Key", required=True),
16
+ SecretStrInput(name="google_cse_id", display_name="Google CSE ID", required=True),
17
+ MultilineInput(
18
+ name="input_value",
19
+ display_name="Input",
20
+ ),
21
+ IntInput(name="k", display_name="Number of results", value=4, required=True),
22
+ ]
23
+
24
+ def run_model(self) -> Data | list[Data]:
25
+ wrapper = self._build_wrapper()
26
+ results = wrapper.results(query=self.input_value, num_results=self.k)
27
+ data = [Data(data=result, text=result["snippet"]) for result in results]
28
+ self.status = data
29
+ return data
30
+
31
+ def build_tool(self) -> Tool:
32
+ wrapper = self._build_wrapper()
33
+ return Tool(
34
+ name="google_search",
35
+ description="Search Google for recent results.",
36
+ func=wrapper.run,
37
+ )
38
+
39
+ def _build_wrapper(self):
40
+ try:
41
+ from langchain_google_community import GoogleSearchAPIWrapper
42
+ except ImportError as e:
43
+ msg = "Please install langchain-google-community to use GoogleSearchAPIWrapper."
44
+ raise ImportError(msg) from e
45
+ return GoogleSearchAPIWrapper(google_api_key=self.google_api_key, google_cse_id=self.google_cse_id, k=self.k)
@@ -0,0 +1,115 @@
1
+ from typing import Any
2
+
3
+ from langchain.tools import StructuredTool
4
+ from langchain_community.utilities.google_serper import GoogleSerperAPIWrapper
5
+ from pydantic import BaseModel, Field
6
+
7
+ from lfx.base.langchain_utilities.model import LCToolComponent
8
+ from lfx.field_typing import Tool
9
+ from lfx.inputs.inputs import (
10
+ DictInput,
11
+ DropdownInput,
12
+ IntInput,
13
+ MultilineInput,
14
+ SecretStrInput,
15
+ )
16
+ from lfx.schema.data import Data
17
+
18
+
19
+ class QuerySchema(BaseModel):
20
+ query: str = Field(..., description="The query to search for.")
21
+ query_type: str = Field(
22
+ "search",
23
+ description="The type of search to perform (e.g., 'news' or 'search').",
24
+ )
25
+ k: int = Field(4, description="The number of results to return.")
26
+ query_params: dict[str, Any] = Field({}, description="Additional query parameters to pass to the API.")
27
+
28
+
29
+ class GoogleSerperAPIComponent(LCToolComponent):
30
+ display_name = "Google Serper API [DEPRECATED]"
31
+ description = "Call the Serper.dev Google Search API."
32
+ name = "GoogleSerperAPI"
33
+ icon = "Google"
34
+ legacy = True
35
+ inputs = [
36
+ SecretStrInput(name="serper_api_key", display_name="Serper API Key", required=True),
37
+ MultilineInput(
38
+ name="query",
39
+ display_name="Query",
40
+ ),
41
+ IntInput(name="k", display_name="Number of results", value=4, required=True),
42
+ DropdownInput(
43
+ name="query_type",
44
+ display_name="Query Type",
45
+ required=False,
46
+ options=["news", "search"],
47
+ value="search",
48
+ ),
49
+ DictInput(
50
+ name="query_params",
51
+ display_name="Query Params",
52
+ required=False,
53
+ value={
54
+ "gl": "us",
55
+ "hl": "en",
56
+ },
57
+ list=True,
58
+ ),
59
+ ]
60
+
61
+ def run_model(self) -> Data | list[Data]:
62
+ wrapper = self._build_wrapper(self.k, self.query_type, self.query_params)
63
+ results = wrapper.results(query=self.query)
64
+
65
+ # Adjust the extraction based on the `type`
66
+ if self.query_type == "search":
67
+ list_results = results.get("organic", [])
68
+ elif self.query_type == "news":
69
+ list_results = results.get("news", [])
70
+ else:
71
+ list_results = []
72
+
73
+ data_list = []
74
+ for result in list_results:
75
+ result["text"] = result.pop("snippet", "")
76
+ data_list.append(Data(data=result))
77
+ self.status = data_list
78
+ return data_list
79
+
80
+ def build_tool(self) -> Tool:
81
+ return StructuredTool.from_function(
82
+ name="google_search",
83
+ description="Search Google for recent results.",
84
+ func=self._search,
85
+ args_schema=self.QuerySchema,
86
+ )
87
+
88
+ def _build_wrapper(
89
+ self,
90
+ k: int = 5,
91
+ query_type: str = "search",
92
+ query_params: dict | None = None,
93
+ ) -> GoogleSerperAPIWrapper:
94
+ wrapper_args = {
95
+ "serper_api_key": self.serper_api_key,
96
+ "k": k,
97
+ "type": query_type,
98
+ }
99
+
100
+ # Add query_params if provided
101
+ if query_params:
102
+ wrapper_args.update(query_params) # Merge with additional query params
103
+
104
+ # Dynamically pass parameters to the wrapper
105
+ return GoogleSerperAPIWrapper(**wrapper_args)
106
+
107
+ def _search(
108
+ self,
109
+ query: str,
110
+ k: int = 5,
111
+ query_type: str = "search",
112
+ query_params: dict | None = None,
113
+ ) -> dict:
114
+ wrapper = self._build_wrapper(k, query_type, query_params)
115
+ return wrapper.results(query=query)
@@ -0,0 +1,327 @@
1
+ import ast
2
+ import json
3
+ from typing import Any
4
+
5
+ from langchain.agents import Tool
6
+ from langchain_core.tools import StructuredTool
7
+ from pydantic.v1 import Field, create_model
8
+ from pydantic.v1.fields import Undefined
9
+ from typing_extensions import override
10
+
11
+ from lfx.base.langchain_utilities.model import LCToolComponent
12
+ from lfx.inputs.inputs import BoolInput, DropdownInput, FieldTypes, HandleInput, MessageTextInput, MultilineInput
13
+ from lfx.io import Output
14
+ from lfx.log.logger import logger
15
+ from lfx.schema.data import Data
16
+ from lfx.schema.dotdict import dotdict
17
+
18
+
19
+ class PythonCodeStructuredTool(LCToolComponent):
20
+ DEFAULT_KEYS = [
21
+ "code",
22
+ "_type",
23
+ "text_key",
24
+ "tool_code",
25
+ "tool_name",
26
+ "tool_description",
27
+ "return_direct",
28
+ "tool_function",
29
+ "global_variables",
30
+ "_classes",
31
+ "_functions",
32
+ ]
33
+ display_name = "Python Code Structured"
34
+ description = "structuredtool dataclass code to tool"
35
+ documentation = "https://python.langchain.com/docs/modules/tools/custom_tools/#structuredtool-dataclass"
36
+ name = "PythonCodeStructuredTool"
37
+ icon = "Python"
38
+ field_order = ["name", "description", "tool_code", "return_direct", "tool_function"]
39
+ legacy: bool = True
40
+
41
+ inputs = [
42
+ MultilineInput(
43
+ name="tool_code",
44
+ display_name="Tool Code",
45
+ info="Enter the dataclass code.",
46
+ placeholder="def my_function(args):\n pass",
47
+ required=True,
48
+ real_time_refresh=True,
49
+ refresh_button=True,
50
+ ),
51
+ MessageTextInput(
52
+ name="tool_name",
53
+ display_name="Tool Name",
54
+ info="Enter the name of the tool.",
55
+ required=True,
56
+ ),
57
+ MessageTextInput(
58
+ name="tool_description",
59
+ display_name="Description",
60
+ info="Enter the description of the tool.",
61
+ required=True,
62
+ ),
63
+ BoolInput(
64
+ name="return_direct",
65
+ display_name="Return Directly",
66
+ info="Should the tool return the function output directly?",
67
+ ),
68
+ DropdownInput(
69
+ name="tool_function",
70
+ display_name="Tool Function",
71
+ info="Select the function for additional expressions.",
72
+ options=[],
73
+ required=True,
74
+ real_time_refresh=True,
75
+ refresh_button=True,
76
+ ),
77
+ HandleInput(
78
+ name="global_variables",
79
+ display_name="Global Variables",
80
+ info="Enter the global variables or Create Data Component.",
81
+ input_types=["Data"],
82
+ field_type=FieldTypes.DICT,
83
+ is_list=True,
84
+ ),
85
+ MessageTextInput(name="_classes", display_name="Classes", advanced=True),
86
+ MessageTextInput(name="_functions", display_name="Functions", advanced=True),
87
+ ]
88
+
89
+ outputs = [
90
+ Output(display_name="Tool", name="result_tool", method="build_tool"),
91
+ ]
92
+
93
+ @override
94
+ async def update_build_config(
95
+ self, build_config: dotdict, field_value: Any, field_name: str | None = None
96
+ ) -> dotdict:
97
+ if field_name is None:
98
+ return build_config
99
+
100
+ if field_name not in {"tool_code", "tool_function"}:
101
+ return build_config
102
+
103
+ try:
104
+ named_functions = {}
105
+ [classes, functions] = self._parse_code(build_config["tool_code"]["value"])
106
+ existing_fields = {}
107
+ if len(build_config) > len(self.DEFAULT_KEYS):
108
+ for key in build_config.copy():
109
+ if key not in self.DEFAULT_KEYS:
110
+ existing_fields[key] = build_config.pop(key)
111
+
112
+ names = []
113
+ for func in functions:
114
+ named_functions[func["name"]] = func
115
+ names.append(func["name"])
116
+
117
+ for arg in func["args"]:
118
+ field_name = f"{func['name']}|{arg['name']}"
119
+ if field_name in existing_fields:
120
+ build_config[field_name] = existing_fields[field_name]
121
+ continue
122
+
123
+ field = MessageTextInput(
124
+ display_name=f"{arg['name']}: Description",
125
+ name=field_name,
126
+ info=f"Enter the description for {arg['name']}",
127
+ required=True,
128
+ )
129
+ build_config[field_name] = field.to_dict()
130
+ build_config["_functions"]["value"] = json.dumps(named_functions)
131
+ build_config["_classes"]["value"] = json.dumps(classes)
132
+ build_config["tool_function"]["options"] = names
133
+ except Exception as e: # noqa: BLE001
134
+ self.status = f"Failed to extract names: {e}"
135
+ logger.debug(self.status, exc_info=True)
136
+ build_config["tool_function"]["options"] = ["Failed to parse", str(e)]
137
+ return build_config
138
+
139
+ async def build_tool(self) -> Tool:
140
+ local_namespace = {} # type: ignore[var-annotated]
141
+ modules = self._find_imports(self.tool_code)
142
+ import_code = ""
143
+ for module in modules["imports"]:
144
+ import_code += f"global {module}\nimport {module}\n"
145
+ for from_module in modules["from_imports"]:
146
+ for alias in from_module.names:
147
+ import_code += f"global {alias.name}\n"
148
+ import_code += (
149
+ f"from {from_module.module} import {', '.join([alias.name for alias in from_module.names])}\n"
150
+ )
151
+ exec(import_code, globals())
152
+ exec(self.tool_code, globals(), local_namespace)
153
+
154
+ class PythonCodeToolFunc:
155
+ params: dict = {}
156
+
157
+ def run(**kwargs):
158
+ for key, arg in kwargs.items():
159
+ if key not in PythonCodeToolFunc.params:
160
+ PythonCodeToolFunc.params[key] = arg
161
+ return local_namespace[self.tool_function](**PythonCodeToolFunc.params)
162
+
163
+ globals_ = globals()
164
+ local = {}
165
+ local[self.tool_function] = PythonCodeToolFunc
166
+ globals_.update(local)
167
+
168
+ if isinstance(self.global_variables, list):
169
+ for data in self.global_variables:
170
+ if isinstance(data, Data):
171
+ globals_.update(data.data)
172
+ elif isinstance(self.global_variables, dict):
173
+ globals_.update(self.global_variables)
174
+
175
+ classes = json.loads(self._attributes["_classes"])
176
+ for class_dict in classes:
177
+ exec("\n".join(class_dict["code"]), globals_)
178
+
179
+ named_functions = json.loads(self._attributes["_functions"])
180
+ schema_fields = {}
181
+
182
+ for attr in self._attributes:
183
+ if attr in self.DEFAULT_KEYS:
184
+ continue
185
+
186
+ func_name = attr.split("|")[0]
187
+ field_name = attr.split("|")[1]
188
+ func_arg = self._find_arg(named_functions, func_name, field_name)
189
+ if func_arg is None:
190
+ msg = f"Failed to find arg: {field_name}"
191
+ raise ValueError(msg)
192
+
193
+ field_annotation = func_arg["annotation"]
194
+ field_description = self._get_value(self._attributes[attr], str)
195
+
196
+ if field_annotation:
197
+ exec(f"temp_annotation_type = {field_annotation}", globals_)
198
+ schema_annotation = globals_["temp_annotation_type"]
199
+ else:
200
+ schema_annotation = Any
201
+ schema_fields[field_name] = (
202
+ schema_annotation,
203
+ Field(
204
+ default=func_arg.get("default", Undefined),
205
+ description=field_description,
206
+ ),
207
+ )
208
+
209
+ if "temp_annotation_type" in globals_:
210
+ globals_.pop("temp_annotation_type")
211
+
212
+ python_code_tool_schema = None
213
+ if schema_fields:
214
+ python_code_tool_schema = create_model("PythonCodeToolSchema", **schema_fields)
215
+
216
+ return StructuredTool.from_function(
217
+ func=local[self.tool_function].run,
218
+ args_schema=python_code_tool_schema,
219
+ name=self.tool_name,
220
+ description=self.tool_description,
221
+ return_direct=self.return_direct,
222
+ )
223
+
224
+ async def update_frontend_node(self, new_frontend_node: dict, current_frontend_node: dict):
225
+ """This function is called after the code validation is done."""
226
+ frontend_node = await super().update_frontend_node(new_frontend_node, current_frontend_node)
227
+ frontend_node["template"] = await self.update_build_config(
228
+ frontend_node["template"],
229
+ frontend_node["template"]["tool_code"]["value"],
230
+ "tool_code",
231
+ )
232
+ frontend_node = await super().update_frontend_node(new_frontend_node, current_frontend_node)
233
+ for key in frontend_node["template"]:
234
+ if key in self.DEFAULT_KEYS:
235
+ continue
236
+ frontend_node["template"] = await self.update_build_config(
237
+ frontend_node["template"], frontend_node["template"][key]["value"], key
238
+ )
239
+ frontend_node = await super().update_frontend_node(new_frontend_node, current_frontend_node)
240
+ return frontend_node
241
+
242
+ def _parse_code(self, code: str) -> tuple[list[dict], list[dict]]:
243
+ parsed_code = ast.parse(code)
244
+ lines = code.split("\n")
245
+ classes = []
246
+ functions = []
247
+ for node in parsed_code.body:
248
+ if isinstance(node, ast.ClassDef):
249
+ class_lines = lines[node.lineno - 1 : node.end_lineno]
250
+ class_lines[-1] = class_lines[-1][: node.end_col_offset]
251
+ class_lines[0] = class_lines[0][node.col_offset :]
252
+ classes.append(
253
+ {
254
+ "name": node.name,
255
+ "code": class_lines,
256
+ }
257
+ )
258
+ continue
259
+
260
+ if not isinstance(node, ast.FunctionDef):
261
+ continue
262
+
263
+ func = {"name": node.name, "args": []}
264
+ for arg in node.args.args:
265
+ if arg.lineno != arg.end_lineno:
266
+ msg = "Multiline arguments are not supported"
267
+ raise ValueError(msg)
268
+
269
+ func_arg = {
270
+ "name": arg.arg,
271
+ "annotation": None,
272
+ }
273
+
274
+ for default in node.args.defaults:
275
+ if (
276
+ arg.lineno > default.lineno
277
+ or arg.col_offset > default.col_offset
278
+ or (
279
+ arg.end_lineno is not None
280
+ and default.end_lineno is not None
281
+ and arg.end_lineno < default.end_lineno
282
+ )
283
+ or (
284
+ arg.end_col_offset is not None
285
+ and default.end_col_offset is not None
286
+ and arg.end_col_offset < default.end_col_offset
287
+ )
288
+ ):
289
+ continue
290
+
291
+ if isinstance(default, ast.Name):
292
+ func_arg["default"] = default.id
293
+ elif isinstance(default, ast.Constant):
294
+ func_arg["default"] = str(default.value) if default.value is not None else None
295
+
296
+ if arg.annotation:
297
+ annotation_line = lines[arg.annotation.lineno - 1]
298
+ annotation_line = annotation_line[: arg.annotation.end_col_offset]
299
+ annotation_line = annotation_line[arg.annotation.col_offset :]
300
+ func_arg["annotation"] = annotation_line
301
+ if isinstance(func_arg["annotation"], str) and func_arg["annotation"].count("=") > 0:
302
+ func_arg["annotation"] = "=".join(func_arg["annotation"].split("=")[:-1]).strip()
303
+ if isinstance(func["args"], list):
304
+ func["args"].append(func_arg)
305
+ functions.append(func)
306
+
307
+ return classes, functions
308
+
309
+ def _find_imports(self, code: str) -> dotdict:
310
+ imports: list[str] = []
311
+ from_imports = []
312
+ parsed_code = ast.parse(code)
313
+ for node in parsed_code.body:
314
+ if isinstance(node, ast.Import):
315
+ imports.extend(alias.name for alias in node.names)
316
+ elif isinstance(node, ast.ImportFrom):
317
+ from_imports.append(node)
318
+ return dotdict({"imports": imports, "from_imports": from_imports})
319
+
320
+ def _get_value(self, value: Any, annotation: Any) -> Any:
321
+ return value if isinstance(value, annotation) else value["value"]
322
+
323
+ def _find_arg(self, named_functions: dict, func_name: str, arg_name: str) -> dict | None:
324
+ for arg in named_functions[func_name]["args"]:
325
+ if arg["name"] == arg_name:
326
+ return arg
327
+ return None
@@ -0,0 +1,97 @@
1
+ import importlib
2
+
3
+ from langchain.tools import StructuredTool
4
+ from langchain_core.tools import ToolException
5
+ from langchain_experimental.utilities import PythonREPL
6
+ from pydantic import BaseModel, Field
7
+
8
+ from lfx.base.langchain_utilities.model import LCToolComponent
9
+ from lfx.field_typing import Tool
10
+ from lfx.inputs.inputs import StrInput
11
+ from lfx.log.logger import logger
12
+ from lfx.schema.data import Data
13
+
14
+
15
+ class PythonREPLToolComponent(LCToolComponent):
16
+ display_name = "Python REPL [DEPRECATED]"
17
+ description = "A tool for running Python code in a REPL environment."
18
+ name = "PythonREPLTool"
19
+ icon = "Python"
20
+ legacy = True
21
+
22
+ inputs = [
23
+ StrInput(
24
+ name="name",
25
+ display_name="Tool Name",
26
+ info="The name of the tool.",
27
+ value="python_repl",
28
+ ),
29
+ StrInput(
30
+ name="description",
31
+ display_name="Tool Description",
32
+ info="A description of the tool.",
33
+ value="A Python shell. Use this to execute python commands. "
34
+ "Input should be a valid python command. "
35
+ "If you want to see the output of a value, you should print it out with `print(...)`.",
36
+ ),
37
+ StrInput(
38
+ name="global_imports",
39
+ display_name="Global Imports",
40
+ info="A comma-separated list of modules to import globally, e.g. 'math,numpy'.",
41
+ value="math",
42
+ ),
43
+ StrInput(
44
+ name="code",
45
+ display_name="Python Code",
46
+ info="The Python code to execute.",
47
+ value="print('Hello, World!')",
48
+ ),
49
+ ]
50
+
51
+ class PythonREPLSchema(BaseModel):
52
+ code: str = Field(..., description="The Python code to execute.")
53
+
54
+ def get_globals(self, global_imports: str | list[str]) -> dict:
55
+ global_dict = {}
56
+ if isinstance(global_imports, str):
57
+ modules = [module.strip() for module in global_imports.split(",")]
58
+ elif isinstance(global_imports, list):
59
+ modules = global_imports
60
+ else:
61
+ msg = "global_imports must be either a string or a list"
62
+ raise TypeError(msg)
63
+
64
+ for module in modules:
65
+ try:
66
+ imported_module = importlib.import_module(module)
67
+ global_dict[imported_module.__name__] = imported_module
68
+ except ImportError as e:
69
+ msg = f"Could not import module {module}"
70
+ raise ImportError(msg) from e
71
+ return global_dict
72
+
73
+ def build_tool(self) -> Tool:
74
+ globals_ = self.get_globals(self.global_imports)
75
+ python_repl = PythonREPL(_globals=globals_)
76
+
77
+ def run_python_code(code: str) -> str:
78
+ try:
79
+ return python_repl.run(code)
80
+ except Exception as e:
81
+ logger.debug("Error running Python code", exc_info=True)
82
+ raise ToolException(str(e)) from e
83
+
84
+ tool = StructuredTool.from_function(
85
+ name=self.name,
86
+ description=self.description,
87
+ func=run_python_code,
88
+ args_schema=self.PythonREPLSchema,
89
+ )
90
+
91
+ self.status = f"Python REPL Tool created with global imports: {self.global_imports}"
92
+ return tool
93
+
94
+ def run_model(self) -> list[Data]:
95
+ tool = self.build_tool()
96
+ result = tool.run(self.code)
97
+ return [Data(data={"result": result})]