agno 2.2.13__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 (575) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +51 -0
  3. agno/agent/agent.py +10405 -0
  4. agno/api/__init__.py +0 -0
  5. agno/api/agent.py +28 -0
  6. agno/api/api.py +40 -0
  7. agno/api/evals.py +22 -0
  8. agno/api/os.py +17 -0
  9. agno/api/routes.py +13 -0
  10. agno/api/schemas/__init__.py +9 -0
  11. agno/api/schemas/agent.py +16 -0
  12. agno/api/schemas/evals.py +16 -0
  13. agno/api/schemas/os.py +14 -0
  14. agno/api/schemas/response.py +6 -0
  15. agno/api/schemas/team.py +16 -0
  16. agno/api/schemas/utils.py +21 -0
  17. agno/api/schemas/workflows.py +16 -0
  18. agno/api/settings.py +53 -0
  19. agno/api/team.py +30 -0
  20. agno/api/workflow.py +28 -0
  21. agno/cloud/aws/base.py +214 -0
  22. agno/cloud/aws/s3/__init__.py +2 -0
  23. agno/cloud/aws/s3/api_client.py +43 -0
  24. agno/cloud/aws/s3/bucket.py +195 -0
  25. agno/cloud/aws/s3/object.py +57 -0
  26. agno/culture/__init__.py +3 -0
  27. agno/culture/manager.py +956 -0
  28. agno/db/__init__.py +24 -0
  29. agno/db/async_postgres/__init__.py +3 -0
  30. agno/db/base.py +598 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2042 -0
  33. agno/db/dynamo/schemas.py +314 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +1795 -0
  37. agno/db/firestore/schemas.py +140 -0
  38. agno/db/firestore/utils.py +376 -0
  39. agno/db/gcs_json/__init__.py +3 -0
  40. agno/db/gcs_json/gcs_json_db.py +1335 -0
  41. agno/db/gcs_json/utils.py +228 -0
  42. agno/db/in_memory/__init__.py +3 -0
  43. agno/db/in_memory/in_memory_db.py +1160 -0
  44. agno/db/in_memory/utils.py +230 -0
  45. agno/db/json/__init__.py +3 -0
  46. agno/db/json/json_db.py +1328 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/__init__.py +0 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/mongo/__init__.py +17 -0
  51. agno/db/mongo/async_mongo.py +2026 -0
  52. agno/db/mongo/mongo.py +1982 -0
  53. agno/db/mongo/schemas.py +87 -0
  54. agno/db/mongo/utils.py +259 -0
  55. agno/db/mysql/__init__.py +3 -0
  56. agno/db/mysql/mysql.py +2308 -0
  57. agno/db/mysql/schemas.py +138 -0
  58. agno/db/mysql/utils.py +355 -0
  59. agno/db/postgres/__init__.py +4 -0
  60. agno/db/postgres/async_postgres.py +1927 -0
  61. agno/db/postgres/postgres.py +2260 -0
  62. agno/db/postgres/schemas.py +139 -0
  63. agno/db/postgres/utils.py +442 -0
  64. agno/db/redis/__init__.py +3 -0
  65. agno/db/redis/redis.py +1660 -0
  66. agno/db/redis/schemas.py +123 -0
  67. agno/db/redis/utils.py +346 -0
  68. agno/db/schemas/__init__.py +4 -0
  69. agno/db/schemas/culture.py +120 -0
  70. agno/db/schemas/evals.py +33 -0
  71. agno/db/schemas/knowledge.py +40 -0
  72. agno/db/schemas/memory.py +46 -0
  73. agno/db/schemas/metrics.py +0 -0
  74. agno/db/singlestore/__init__.py +3 -0
  75. agno/db/singlestore/schemas.py +130 -0
  76. agno/db/singlestore/singlestore.py +2272 -0
  77. agno/db/singlestore/utils.py +384 -0
  78. agno/db/sqlite/__init__.py +4 -0
  79. agno/db/sqlite/async_sqlite.py +2293 -0
  80. agno/db/sqlite/schemas.py +133 -0
  81. agno/db/sqlite/sqlite.py +2288 -0
  82. agno/db/sqlite/utils.py +431 -0
  83. agno/db/surrealdb/__init__.py +3 -0
  84. agno/db/surrealdb/metrics.py +292 -0
  85. agno/db/surrealdb/models.py +309 -0
  86. agno/db/surrealdb/queries.py +71 -0
  87. agno/db/surrealdb/surrealdb.py +1353 -0
  88. agno/db/surrealdb/utils.py +147 -0
  89. agno/db/utils.py +116 -0
  90. agno/debug.py +18 -0
  91. agno/eval/__init__.py +14 -0
  92. agno/eval/accuracy.py +834 -0
  93. agno/eval/performance.py +773 -0
  94. agno/eval/reliability.py +306 -0
  95. agno/eval/utils.py +119 -0
  96. agno/exceptions.py +161 -0
  97. agno/filters.py +354 -0
  98. agno/guardrails/__init__.py +6 -0
  99. agno/guardrails/base.py +19 -0
  100. agno/guardrails/openai.py +144 -0
  101. agno/guardrails/pii.py +94 -0
  102. agno/guardrails/prompt_injection.py +52 -0
  103. agno/integrations/__init__.py +0 -0
  104. agno/integrations/discord/__init__.py +3 -0
  105. agno/integrations/discord/client.py +203 -0
  106. agno/knowledge/__init__.py +5 -0
  107. agno/knowledge/chunking/__init__.py +0 -0
  108. agno/knowledge/chunking/agentic.py +79 -0
  109. agno/knowledge/chunking/document.py +91 -0
  110. agno/knowledge/chunking/fixed.py +57 -0
  111. agno/knowledge/chunking/markdown.py +151 -0
  112. agno/knowledge/chunking/recursive.py +63 -0
  113. agno/knowledge/chunking/row.py +39 -0
  114. agno/knowledge/chunking/semantic.py +86 -0
  115. agno/knowledge/chunking/strategy.py +165 -0
  116. agno/knowledge/content.py +74 -0
  117. agno/knowledge/document/__init__.py +5 -0
  118. agno/knowledge/document/base.py +58 -0
  119. agno/knowledge/embedder/__init__.py +5 -0
  120. agno/knowledge/embedder/aws_bedrock.py +343 -0
  121. agno/knowledge/embedder/azure_openai.py +210 -0
  122. agno/knowledge/embedder/base.py +23 -0
  123. agno/knowledge/embedder/cohere.py +323 -0
  124. agno/knowledge/embedder/fastembed.py +62 -0
  125. agno/knowledge/embedder/fireworks.py +13 -0
  126. agno/knowledge/embedder/google.py +258 -0
  127. agno/knowledge/embedder/huggingface.py +94 -0
  128. agno/knowledge/embedder/jina.py +182 -0
  129. agno/knowledge/embedder/langdb.py +22 -0
  130. agno/knowledge/embedder/mistral.py +206 -0
  131. agno/knowledge/embedder/nebius.py +13 -0
  132. agno/knowledge/embedder/ollama.py +154 -0
  133. agno/knowledge/embedder/openai.py +195 -0
  134. agno/knowledge/embedder/sentence_transformer.py +63 -0
  135. agno/knowledge/embedder/together.py +13 -0
  136. agno/knowledge/embedder/vllm.py +262 -0
  137. agno/knowledge/embedder/voyageai.py +165 -0
  138. agno/knowledge/knowledge.py +1988 -0
  139. agno/knowledge/reader/__init__.py +7 -0
  140. agno/knowledge/reader/arxiv_reader.py +81 -0
  141. agno/knowledge/reader/base.py +95 -0
  142. agno/knowledge/reader/csv_reader.py +166 -0
  143. agno/knowledge/reader/docx_reader.py +82 -0
  144. agno/knowledge/reader/field_labeled_csv_reader.py +292 -0
  145. agno/knowledge/reader/firecrawl_reader.py +201 -0
  146. agno/knowledge/reader/json_reader.py +87 -0
  147. agno/knowledge/reader/markdown_reader.py +137 -0
  148. agno/knowledge/reader/pdf_reader.py +431 -0
  149. agno/knowledge/reader/pptx_reader.py +101 -0
  150. agno/knowledge/reader/reader_factory.py +313 -0
  151. agno/knowledge/reader/s3_reader.py +89 -0
  152. agno/knowledge/reader/tavily_reader.py +194 -0
  153. agno/knowledge/reader/text_reader.py +115 -0
  154. agno/knowledge/reader/web_search_reader.py +372 -0
  155. agno/knowledge/reader/website_reader.py +455 -0
  156. agno/knowledge/reader/wikipedia_reader.py +59 -0
  157. agno/knowledge/reader/youtube_reader.py +78 -0
  158. agno/knowledge/remote_content/__init__.py +0 -0
  159. agno/knowledge/remote_content/remote_content.py +88 -0
  160. agno/knowledge/reranker/__init__.py +3 -0
  161. agno/knowledge/reranker/base.py +14 -0
  162. agno/knowledge/reranker/cohere.py +64 -0
  163. agno/knowledge/reranker/infinity.py +195 -0
  164. agno/knowledge/reranker/sentence_transformer.py +54 -0
  165. agno/knowledge/types.py +39 -0
  166. agno/knowledge/utils.py +189 -0
  167. agno/media.py +462 -0
  168. agno/memory/__init__.py +3 -0
  169. agno/memory/manager.py +1327 -0
  170. agno/models/__init__.py +0 -0
  171. agno/models/aimlapi/__init__.py +5 -0
  172. agno/models/aimlapi/aimlapi.py +45 -0
  173. agno/models/anthropic/__init__.py +5 -0
  174. agno/models/anthropic/claude.py +757 -0
  175. agno/models/aws/__init__.py +15 -0
  176. agno/models/aws/bedrock.py +701 -0
  177. agno/models/aws/claude.py +378 -0
  178. agno/models/azure/__init__.py +18 -0
  179. agno/models/azure/ai_foundry.py +485 -0
  180. agno/models/azure/openai_chat.py +131 -0
  181. agno/models/base.py +2175 -0
  182. agno/models/cerebras/__init__.py +12 -0
  183. agno/models/cerebras/cerebras.py +501 -0
  184. agno/models/cerebras/cerebras_openai.py +112 -0
  185. agno/models/cohere/__init__.py +5 -0
  186. agno/models/cohere/chat.py +389 -0
  187. agno/models/cometapi/__init__.py +5 -0
  188. agno/models/cometapi/cometapi.py +57 -0
  189. agno/models/dashscope/__init__.py +5 -0
  190. agno/models/dashscope/dashscope.py +91 -0
  191. agno/models/deepinfra/__init__.py +5 -0
  192. agno/models/deepinfra/deepinfra.py +28 -0
  193. agno/models/deepseek/__init__.py +5 -0
  194. agno/models/deepseek/deepseek.py +61 -0
  195. agno/models/defaults.py +1 -0
  196. agno/models/fireworks/__init__.py +5 -0
  197. agno/models/fireworks/fireworks.py +26 -0
  198. agno/models/google/__init__.py +5 -0
  199. agno/models/google/gemini.py +1085 -0
  200. agno/models/groq/__init__.py +5 -0
  201. agno/models/groq/groq.py +556 -0
  202. agno/models/huggingface/__init__.py +5 -0
  203. agno/models/huggingface/huggingface.py +491 -0
  204. agno/models/ibm/__init__.py +5 -0
  205. agno/models/ibm/watsonx.py +422 -0
  206. agno/models/internlm/__init__.py +3 -0
  207. agno/models/internlm/internlm.py +26 -0
  208. agno/models/langdb/__init__.py +1 -0
  209. agno/models/langdb/langdb.py +48 -0
  210. agno/models/litellm/__init__.py +14 -0
  211. agno/models/litellm/chat.py +468 -0
  212. agno/models/litellm/litellm_openai.py +25 -0
  213. agno/models/llama_cpp/__init__.py +5 -0
  214. agno/models/llama_cpp/llama_cpp.py +22 -0
  215. agno/models/lmstudio/__init__.py +5 -0
  216. agno/models/lmstudio/lmstudio.py +25 -0
  217. agno/models/message.py +434 -0
  218. agno/models/meta/__init__.py +12 -0
  219. agno/models/meta/llama.py +475 -0
  220. agno/models/meta/llama_openai.py +78 -0
  221. agno/models/metrics.py +120 -0
  222. agno/models/mistral/__init__.py +5 -0
  223. agno/models/mistral/mistral.py +432 -0
  224. agno/models/nebius/__init__.py +3 -0
  225. agno/models/nebius/nebius.py +54 -0
  226. agno/models/nexus/__init__.py +3 -0
  227. agno/models/nexus/nexus.py +22 -0
  228. agno/models/nvidia/__init__.py +5 -0
  229. agno/models/nvidia/nvidia.py +28 -0
  230. agno/models/ollama/__init__.py +5 -0
  231. agno/models/ollama/chat.py +441 -0
  232. agno/models/openai/__init__.py +9 -0
  233. agno/models/openai/chat.py +883 -0
  234. agno/models/openai/like.py +27 -0
  235. agno/models/openai/responses.py +1050 -0
  236. agno/models/openrouter/__init__.py +5 -0
  237. agno/models/openrouter/openrouter.py +66 -0
  238. agno/models/perplexity/__init__.py +5 -0
  239. agno/models/perplexity/perplexity.py +187 -0
  240. agno/models/portkey/__init__.py +3 -0
  241. agno/models/portkey/portkey.py +81 -0
  242. agno/models/requesty/__init__.py +5 -0
  243. agno/models/requesty/requesty.py +52 -0
  244. agno/models/response.py +199 -0
  245. agno/models/sambanova/__init__.py +5 -0
  246. agno/models/sambanova/sambanova.py +28 -0
  247. agno/models/siliconflow/__init__.py +5 -0
  248. agno/models/siliconflow/siliconflow.py +25 -0
  249. agno/models/together/__init__.py +5 -0
  250. agno/models/together/together.py +25 -0
  251. agno/models/utils.py +266 -0
  252. agno/models/vercel/__init__.py +3 -0
  253. agno/models/vercel/v0.py +26 -0
  254. agno/models/vertexai/__init__.py +0 -0
  255. agno/models/vertexai/claude.py +70 -0
  256. agno/models/vllm/__init__.py +3 -0
  257. agno/models/vllm/vllm.py +78 -0
  258. agno/models/xai/__init__.py +3 -0
  259. agno/models/xai/xai.py +113 -0
  260. agno/os/__init__.py +3 -0
  261. agno/os/app.py +876 -0
  262. agno/os/auth.py +57 -0
  263. agno/os/config.py +104 -0
  264. agno/os/interfaces/__init__.py +1 -0
  265. agno/os/interfaces/a2a/__init__.py +3 -0
  266. agno/os/interfaces/a2a/a2a.py +42 -0
  267. agno/os/interfaces/a2a/router.py +250 -0
  268. agno/os/interfaces/a2a/utils.py +924 -0
  269. agno/os/interfaces/agui/__init__.py +3 -0
  270. agno/os/interfaces/agui/agui.py +47 -0
  271. agno/os/interfaces/agui/router.py +144 -0
  272. agno/os/interfaces/agui/utils.py +534 -0
  273. agno/os/interfaces/base.py +25 -0
  274. agno/os/interfaces/slack/__init__.py +3 -0
  275. agno/os/interfaces/slack/router.py +148 -0
  276. agno/os/interfaces/slack/security.py +30 -0
  277. agno/os/interfaces/slack/slack.py +47 -0
  278. agno/os/interfaces/whatsapp/__init__.py +3 -0
  279. agno/os/interfaces/whatsapp/router.py +211 -0
  280. agno/os/interfaces/whatsapp/security.py +53 -0
  281. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  282. agno/os/mcp.py +292 -0
  283. agno/os/middleware/__init__.py +7 -0
  284. agno/os/middleware/jwt.py +233 -0
  285. agno/os/router.py +1763 -0
  286. agno/os/routers/__init__.py +3 -0
  287. agno/os/routers/evals/__init__.py +3 -0
  288. agno/os/routers/evals/evals.py +430 -0
  289. agno/os/routers/evals/schemas.py +142 -0
  290. agno/os/routers/evals/utils.py +162 -0
  291. agno/os/routers/health.py +31 -0
  292. agno/os/routers/home.py +52 -0
  293. agno/os/routers/knowledge/__init__.py +3 -0
  294. agno/os/routers/knowledge/knowledge.py +997 -0
  295. agno/os/routers/knowledge/schemas.py +178 -0
  296. agno/os/routers/memory/__init__.py +3 -0
  297. agno/os/routers/memory/memory.py +515 -0
  298. agno/os/routers/memory/schemas.py +62 -0
  299. agno/os/routers/metrics/__init__.py +3 -0
  300. agno/os/routers/metrics/metrics.py +190 -0
  301. agno/os/routers/metrics/schemas.py +47 -0
  302. agno/os/routers/session/__init__.py +3 -0
  303. agno/os/routers/session/session.py +997 -0
  304. agno/os/schema.py +1055 -0
  305. agno/os/settings.py +43 -0
  306. agno/os/utils.py +630 -0
  307. agno/py.typed +0 -0
  308. agno/reasoning/__init__.py +0 -0
  309. agno/reasoning/anthropic.py +80 -0
  310. agno/reasoning/azure_ai_foundry.py +67 -0
  311. agno/reasoning/deepseek.py +63 -0
  312. agno/reasoning/default.py +97 -0
  313. agno/reasoning/gemini.py +73 -0
  314. agno/reasoning/groq.py +71 -0
  315. agno/reasoning/helpers.py +63 -0
  316. agno/reasoning/ollama.py +67 -0
  317. agno/reasoning/openai.py +86 -0
  318. agno/reasoning/step.py +31 -0
  319. agno/reasoning/vertexai.py +76 -0
  320. agno/run/__init__.py +6 -0
  321. agno/run/agent.py +787 -0
  322. agno/run/base.py +229 -0
  323. agno/run/cancel.py +81 -0
  324. agno/run/messages.py +32 -0
  325. agno/run/team.py +753 -0
  326. agno/run/workflow.py +708 -0
  327. agno/session/__init__.py +10 -0
  328. agno/session/agent.py +295 -0
  329. agno/session/summary.py +265 -0
  330. agno/session/team.py +392 -0
  331. agno/session/workflow.py +205 -0
  332. agno/team/__init__.py +37 -0
  333. agno/team/team.py +8793 -0
  334. agno/tools/__init__.py +10 -0
  335. agno/tools/agentql.py +120 -0
  336. agno/tools/airflow.py +69 -0
  337. agno/tools/api.py +122 -0
  338. agno/tools/apify.py +314 -0
  339. agno/tools/arxiv.py +127 -0
  340. agno/tools/aws_lambda.py +53 -0
  341. agno/tools/aws_ses.py +66 -0
  342. agno/tools/baidusearch.py +89 -0
  343. agno/tools/bitbucket.py +292 -0
  344. agno/tools/brandfetch.py +213 -0
  345. agno/tools/bravesearch.py +106 -0
  346. agno/tools/brightdata.py +367 -0
  347. agno/tools/browserbase.py +209 -0
  348. agno/tools/calcom.py +255 -0
  349. agno/tools/calculator.py +151 -0
  350. agno/tools/cartesia.py +187 -0
  351. agno/tools/clickup.py +244 -0
  352. agno/tools/confluence.py +240 -0
  353. agno/tools/crawl4ai.py +158 -0
  354. agno/tools/csv_toolkit.py +185 -0
  355. agno/tools/dalle.py +110 -0
  356. agno/tools/daytona.py +475 -0
  357. agno/tools/decorator.py +262 -0
  358. agno/tools/desi_vocal.py +108 -0
  359. agno/tools/discord.py +161 -0
  360. agno/tools/docker.py +716 -0
  361. agno/tools/duckdb.py +379 -0
  362. agno/tools/duckduckgo.py +91 -0
  363. agno/tools/e2b.py +703 -0
  364. agno/tools/eleven_labs.py +196 -0
  365. agno/tools/email.py +67 -0
  366. agno/tools/evm.py +129 -0
  367. agno/tools/exa.py +396 -0
  368. agno/tools/fal.py +127 -0
  369. agno/tools/file.py +240 -0
  370. agno/tools/file_generation.py +350 -0
  371. agno/tools/financial_datasets.py +288 -0
  372. agno/tools/firecrawl.py +143 -0
  373. agno/tools/function.py +1187 -0
  374. agno/tools/giphy.py +93 -0
  375. agno/tools/github.py +1760 -0
  376. agno/tools/gmail.py +922 -0
  377. agno/tools/google_bigquery.py +117 -0
  378. agno/tools/google_drive.py +270 -0
  379. agno/tools/google_maps.py +253 -0
  380. agno/tools/googlecalendar.py +674 -0
  381. agno/tools/googlesearch.py +98 -0
  382. agno/tools/googlesheets.py +377 -0
  383. agno/tools/hackernews.py +77 -0
  384. agno/tools/jina.py +101 -0
  385. agno/tools/jira.py +170 -0
  386. agno/tools/knowledge.py +218 -0
  387. agno/tools/linear.py +426 -0
  388. agno/tools/linkup.py +58 -0
  389. agno/tools/local_file_system.py +90 -0
  390. agno/tools/lumalab.py +183 -0
  391. agno/tools/mcp/__init__.py +10 -0
  392. agno/tools/mcp/mcp.py +331 -0
  393. agno/tools/mcp/multi_mcp.py +347 -0
  394. agno/tools/mcp/params.py +24 -0
  395. agno/tools/mcp_toolbox.py +284 -0
  396. agno/tools/mem0.py +193 -0
  397. agno/tools/memori.py +339 -0
  398. agno/tools/memory.py +419 -0
  399. agno/tools/mlx_transcribe.py +139 -0
  400. agno/tools/models/__init__.py +0 -0
  401. agno/tools/models/azure_openai.py +190 -0
  402. agno/tools/models/gemini.py +203 -0
  403. agno/tools/models/groq.py +158 -0
  404. agno/tools/models/morph.py +186 -0
  405. agno/tools/models/nebius.py +124 -0
  406. agno/tools/models_labs.py +195 -0
  407. agno/tools/moviepy_video.py +349 -0
  408. agno/tools/neo4j.py +134 -0
  409. agno/tools/newspaper.py +46 -0
  410. agno/tools/newspaper4k.py +93 -0
  411. agno/tools/notion.py +204 -0
  412. agno/tools/openai.py +202 -0
  413. agno/tools/openbb.py +160 -0
  414. agno/tools/opencv.py +321 -0
  415. agno/tools/openweather.py +233 -0
  416. agno/tools/oxylabs.py +385 -0
  417. agno/tools/pandas.py +102 -0
  418. agno/tools/parallel.py +314 -0
  419. agno/tools/postgres.py +257 -0
  420. agno/tools/pubmed.py +188 -0
  421. agno/tools/python.py +205 -0
  422. agno/tools/reasoning.py +283 -0
  423. agno/tools/reddit.py +467 -0
  424. agno/tools/replicate.py +117 -0
  425. agno/tools/resend.py +62 -0
  426. agno/tools/scrapegraph.py +222 -0
  427. agno/tools/searxng.py +152 -0
  428. agno/tools/serpapi.py +116 -0
  429. agno/tools/serper.py +255 -0
  430. agno/tools/shell.py +53 -0
  431. agno/tools/slack.py +136 -0
  432. agno/tools/sleep.py +20 -0
  433. agno/tools/spider.py +116 -0
  434. agno/tools/sql.py +154 -0
  435. agno/tools/streamlit/__init__.py +0 -0
  436. agno/tools/streamlit/components.py +113 -0
  437. agno/tools/tavily.py +254 -0
  438. agno/tools/telegram.py +48 -0
  439. agno/tools/todoist.py +218 -0
  440. agno/tools/tool_registry.py +1 -0
  441. agno/tools/toolkit.py +146 -0
  442. agno/tools/trafilatura.py +388 -0
  443. agno/tools/trello.py +274 -0
  444. agno/tools/twilio.py +186 -0
  445. agno/tools/user_control_flow.py +78 -0
  446. agno/tools/valyu.py +228 -0
  447. agno/tools/visualization.py +467 -0
  448. agno/tools/webbrowser.py +28 -0
  449. agno/tools/webex.py +76 -0
  450. agno/tools/website.py +54 -0
  451. agno/tools/webtools.py +45 -0
  452. agno/tools/whatsapp.py +286 -0
  453. agno/tools/wikipedia.py +63 -0
  454. agno/tools/workflow.py +278 -0
  455. agno/tools/x.py +335 -0
  456. agno/tools/yfinance.py +257 -0
  457. agno/tools/youtube.py +184 -0
  458. agno/tools/zendesk.py +82 -0
  459. agno/tools/zep.py +454 -0
  460. agno/tools/zoom.py +382 -0
  461. agno/utils/__init__.py +0 -0
  462. agno/utils/agent.py +820 -0
  463. agno/utils/audio.py +49 -0
  464. agno/utils/certs.py +27 -0
  465. agno/utils/code_execution.py +11 -0
  466. agno/utils/common.py +132 -0
  467. agno/utils/dttm.py +13 -0
  468. agno/utils/enum.py +22 -0
  469. agno/utils/env.py +11 -0
  470. agno/utils/events.py +696 -0
  471. agno/utils/format_str.py +16 -0
  472. agno/utils/functions.py +166 -0
  473. agno/utils/gemini.py +426 -0
  474. agno/utils/hooks.py +57 -0
  475. agno/utils/http.py +74 -0
  476. agno/utils/json_schema.py +234 -0
  477. agno/utils/knowledge.py +36 -0
  478. agno/utils/location.py +19 -0
  479. agno/utils/log.py +255 -0
  480. agno/utils/mcp.py +214 -0
  481. agno/utils/media.py +352 -0
  482. agno/utils/merge_dict.py +41 -0
  483. agno/utils/message.py +118 -0
  484. agno/utils/models/__init__.py +0 -0
  485. agno/utils/models/ai_foundry.py +43 -0
  486. agno/utils/models/claude.py +358 -0
  487. agno/utils/models/cohere.py +87 -0
  488. agno/utils/models/llama.py +78 -0
  489. agno/utils/models/mistral.py +98 -0
  490. agno/utils/models/openai_responses.py +140 -0
  491. agno/utils/models/schema_utils.py +153 -0
  492. agno/utils/models/watsonx.py +41 -0
  493. agno/utils/openai.py +257 -0
  494. agno/utils/pickle.py +32 -0
  495. agno/utils/pprint.py +178 -0
  496. agno/utils/print_response/__init__.py +0 -0
  497. agno/utils/print_response/agent.py +842 -0
  498. agno/utils/print_response/team.py +1724 -0
  499. agno/utils/print_response/workflow.py +1668 -0
  500. agno/utils/prompts.py +111 -0
  501. agno/utils/reasoning.py +108 -0
  502. agno/utils/response.py +163 -0
  503. agno/utils/response_iterator.py +17 -0
  504. agno/utils/safe_formatter.py +24 -0
  505. agno/utils/serialize.py +32 -0
  506. agno/utils/shell.py +22 -0
  507. agno/utils/streamlit.py +487 -0
  508. agno/utils/string.py +231 -0
  509. agno/utils/team.py +139 -0
  510. agno/utils/timer.py +41 -0
  511. agno/utils/tools.py +102 -0
  512. agno/utils/web.py +23 -0
  513. agno/utils/whatsapp.py +305 -0
  514. agno/utils/yaml_io.py +25 -0
  515. agno/vectordb/__init__.py +3 -0
  516. agno/vectordb/base.py +127 -0
  517. agno/vectordb/cassandra/__init__.py +5 -0
  518. agno/vectordb/cassandra/cassandra.py +501 -0
  519. agno/vectordb/cassandra/extra_param_mixin.py +11 -0
  520. agno/vectordb/cassandra/index.py +13 -0
  521. agno/vectordb/chroma/__init__.py +5 -0
  522. agno/vectordb/chroma/chromadb.py +929 -0
  523. agno/vectordb/clickhouse/__init__.py +9 -0
  524. agno/vectordb/clickhouse/clickhousedb.py +835 -0
  525. agno/vectordb/clickhouse/index.py +9 -0
  526. agno/vectordb/couchbase/__init__.py +3 -0
  527. agno/vectordb/couchbase/couchbase.py +1442 -0
  528. agno/vectordb/distance.py +7 -0
  529. agno/vectordb/lancedb/__init__.py +6 -0
  530. agno/vectordb/lancedb/lance_db.py +995 -0
  531. agno/vectordb/langchaindb/__init__.py +5 -0
  532. agno/vectordb/langchaindb/langchaindb.py +163 -0
  533. agno/vectordb/lightrag/__init__.py +5 -0
  534. agno/vectordb/lightrag/lightrag.py +388 -0
  535. agno/vectordb/llamaindex/__init__.py +3 -0
  536. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  537. agno/vectordb/milvus/__init__.py +4 -0
  538. agno/vectordb/milvus/milvus.py +1182 -0
  539. agno/vectordb/mongodb/__init__.py +9 -0
  540. agno/vectordb/mongodb/mongodb.py +1417 -0
  541. agno/vectordb/pgvector/__init__.py +12 -0
  542. agno/vectordb/pgvector/index.py +23 -0
  543. agno/vectordb/pgvector/pgvector.py +1462 -0
  544. agno/vectordb/pineconedb/__init__.py +5 -0
  545. agno/vectordb/pineconedb/pineconedb.py +747 -0
  546. agno/vectordb/qdrant/__init__.py +5 -0
  547. agno/vectordb/qdrant/qdrant.py +1134 -0
  548. agno/vectordb/redis/__init__.py +9 -0
  549. agno/vectordb/redis/redisdb.py +694 -0
  550. agno/vectordb/search.py +7 -0
  551. agno/vectordb/singlestore/__init__.py +10 -0
  552. agno/vectordb/singlestore/index.py +41 -0
  553. agno/vectordb/singlestore/singlestore.py +763 -0
  554. agno/vectordb/surrealdb/__init__.py +3 -0
  555. agno/vectordb/surrealdb/surrealdb.py +699 -0
  556. agno/vectordb/upstashdb/__init__.py +5 -0
  557. agno/vectordb/upstashdb/upstashdb.py +718 -0
  558. agno/vectordb/weaviate/__init__.py +8 -0
  559. agno/vectordb/weaviate/index.py +15 -0
  560. agno/vectordb/weaviate/weaviate.py +1005 -0
  561. agno/workflow/__init__.py +23 -0
  562. agno/workflow/agent.py +299 -0
  563. agno/workflow/condition.py +738 -0
  564. agno/workflow/loop.py +735 -0
  565. agno/workflow/parallel.py +824 -0
  566. agno/workflow/router.py +702 -0
  567. agno/workflow/step.py +1432 -0
  568. agno/workflow/steps.py +592 -0
  569. agno/workflow/types.py +520 -0
  570. agno/workflow/workflow.py +4321 -0
  571. agno-2.2.13.dist-info/METADATA +614 -0
  572. agno-2.2.13.dist-info/RECORD +575 -0
  573. agno-2.2.13.dist-info/WHEEL +5 -0
  574. agno-2.2.13.dist-info/licenses/LICENSE +201 -0
  575. agno-2.2.13.dist-info/top_level.txt +1 -0
agno/tools/exa.py ADDED
@@ -0,0 +1,396 @@
1
+ import json
2
+ from concurrent.futures import ThreadPoolExecutor, TimeoutError
3
+ from os import getenv
4
+ from typing import Any, Dict, List, Literal, Optional
5
+
6
+ from agno.tools import Toolkit
7
+ from agno.utils.log import log_debug, log_info, logger
8
+
9
+ try:
10
+ from exa_py import Exa
11
+ from exa_py.api import SearchResponse
12
+ except ImportError:
13
+ raise ImportError("`exa_py` not installed. Please install using `pip install exa_py`")
14
+
15
+
16
+ class ExaTools(Toolkit):
17
+ """
18
+ ExaTools is a toolkit for interfacing with the Exa web search engine, providing
19
+ functionalities to perform categorized searches and retrieve structured results.
20
+
21
+ Args:
22
+ enable_search (bool): Enable search functionality. Default is True.
23
+ enable_get_contents (bool): Enable get contents functionality. Default is True.
24
+ enable_find_similar (bool): Enable find similar functionality. Default is True.
25
+ enable_answer (bool): Enable answer generation. Default is True.
26
+ enable_research (bool): Enable research tool functionality. Default is False.
27
+ all (bool): Enable all tools. Overrides individual flags when True. Default is False.
28
+ text (bool): Retrieve text content from results. Default is True.
29
+ text_length_limit (int): Max length of text content per result. Default is 1000.
30
+ highlights (bool): Include highlighted snippets. Deprecated since it was removed in the Exa API. It will be removed from Agno in a future release.
31
+ api_key (Optional[str]): Exa API key. Retrieved from `EXA_API_KEY` env variable if not provided.
32
+ num_results (Optional[int]): Default number of search results. Overrides individual searches if set.
33
+ start_crawl_date (Optional[str]): Include results crawled on/after this date (`YYYY-MM-DD`).
34
+ end_crawl_date (Optional[str]): Include results crawled on/before this date (`YYYY-MM-DD`).
35
+ start_published_date (Optional[str]): Include results published on/after this date (`YYYY-MM-DD`).
36
+ end_published_date (Optional[str]): Include results published on/before this date (`YYYY-MM-DD`).
37
+ use_autoprompt (Optional[bool]): Enable autoprompt features in queries. Deprecated since it was removed in the Exa API. It will be removed from Agno in a future release.
38
+ type (Optional[str]): Specify content type (e.g., article, blog, video).
39
+ category (Optional[str]): Filter results by category. Options are "company", "research paper", "news", "pdf", "github", "tweet", "personal site", "linkedin profile", "financial report".
40
+ include_domains (Optional[List[str]]): Restrict results to these domains.
41
+ exclude_domains (Optional[List[str]]): Exclude results from these domains.
42
+ show_results (bool): Log search results for debugging. Default is False.
43
+ model (Optional[str]): The search model to use. Options are 'exa' or 'exa-pro'.
44
+ timeout (int): Maximum time in seconds to wait for API responses. Default is 30 seconds.
45
+ """
46
+
47
+ def __init__(
48
+ self,
49
+ enable_search: bool = True,
50
+ enable_get_contents: bool = True,
51
+ enable_find_similar: bool = True,
52
+ enable_answer: bool = True,
53
+ enable_research: bool = False,
54
+ all: bool = False,
55
+ text: bool = True,
56
+ text_length_limit: int = 1000,
57
+ highlights: Optional[bool] = None, # Deprecated
58
+ summary: bool = False,
59
+ api_key: Optional[str] = None,
60
+ num_results: Optional[int] = None,
61
+ livecrawl: str = "always",
62
+ start_crawl_date: Optional[str] = None,
63
+ end_crawl_date: Optional[str] = None,
64
+ start_published_date: Optional[str] = None,
65
+ end_published_date: Optional[str] = None,
66
+ use_autoprompt: Optional[bool] = None,
67
+ type: Optional[str] = None,
68
+ category: Optional[str] = None,
69
+ include_domains: Optional[List[str]] = None,
70
+ exclude_domains: Optional[List[str]] = None,
71
+ show_results: bool = False,
72
+ model: Optional[str] = None,
73
+ timeout: int = 30,
74
+ research_model: Literal["exa-research", "exa-research-pro"] = "exa-research",
75
+ **kwargs,
76
+ ):
77
+ self.api_key = api_key or getenv("EXA_API_KEY")
78
+ if not self.api_key:
79
+ logger.error("EXA_API_KEY not set. Please set the EXA_API_KEY environment variable.")
80
+
81
+ self.exa = Exa(self.api_key)
82
+ self.show_results = show_results
83
+ self.timeout = timeout
84
+
85
+ self.text: bool = text
86
+ self.text_length_limit: int = text_length_limit
87
+
88
+ if highlights:
89
+ import warnings
90
+
91
+ warnings.warn(
92
+ "The 'highlights' parameter is deprecated since it was removed in the Exa API. It will be removed from Agno in a future release.",
93
+ DeprecationWarning,
94
+ stacklevel=2,
95
+ )
96
+ if use_autoprompt:
97
+ import warnings
98
+
99
+ warnings.warn(
100
+ "The 'use_autoprompt' parameter is deprecated since it was removed in the Exa API. It will be removed from Agno in a future release.",
101
+ DeprecationWarning,
102
+ stacklevel=2,
103
+ )
104
+
105
+ self.summary: bool = summary
106
+ self.num_results: Optional[int] = num_results
107
+ self.livecrawl: str = livecrawl
108
+ self.start_crawl_date: Optional[str] = start_crawl_date
109
+ self.end_crawl_date: Optional[str] = end_crawl_date
110
+ self.start_published_date: Optional[str] = start_published_date
111
+ self.end_published_date: Optional[str] = end_published_date
112
+ self.type: Optional[str] = type
113
+ self.category: Optional[str] = category
114
+ self.include_domains: Optional[List[str]] = include_domains
115
+ self.exclude_domains: Optional[List[str]] = exclude_domains
116
+ self.model: Optional[str] = model
117
+ self.research_model: Literal["exa-research", "exa-research-pro"] = research_model
118
+
119
+ tools: List[Any] = []
120
+ if all or enable_search:
121
+ tools.append(self.search_exa)
122
+ if all or enable_get_contents:
123
+ tools.append(self.get_contents)
124
+ if all or enable_find_similar:
125
+ tools.append(self.find_similar)
126
+ if all or enable_answer:
127
+ tools.append(self.exa_answer)
128
+ if all or enable_research:
129
+ tools.append(self.research)
130
+
131
+ super().__init__(name="exa", tools=tools, **kwargs)
132
+
133
+ def _execute_with_timeout(self, func, *args, **kwargs):
134
+ """Execute a function with a timeout using a temporary ThreadPoolExecutor."""
135
+ with ThreadPoolExecutor(max_workers=1) as executor:
136
+ future = executor.submit(func, *args, **kwargs)
137
+ try:
138
+ return future.result(timeout=self.timeout)
139
+ except TimeoutError:
140
+ raise TimeoutError(f"Operation timed out after {self.timeout} seconds")
141
+ except Exception as e:
142
+ raise e
143
+
144
+ def _parse_results(self, exa_results: SearchResponse) -> str:
145
+ exa_results_parsed = []
146
+ for result in exa_results.results:
147
+ result_dict = {"url": result.url}
148
+ if result.title:
149
+ result_dict["title"] = result.title
150
+ if result.author and result.author != "":
151
+ result_dict["author"] = result.author
152
+ if result.published_date:
153
+ result_dict["published_date"] = result.published_date
154
+ if result.text:
155
+ _text = result.text
156
+ if self.text_length_limit:
157
+ _text = _text[: self.text_length_limit]
158
+ result_dict["text"] = _text
159
+ exa_results_parsed.append(result_dict)
160
+ return json.dumps(exa_results_parsed, indent=4, ensure_ascii=False)
161
+
162
+ def search_exa(self, query: str, num_results: int = 5, category: Optional[str] = None) -> str:
163
+ """Use this function to search Exa (a web search engine) for a query.
164
+
165
+ Args:
166
+ query (str): The query to search for.
167
+ num_results (int): Number of results to return. Defaults to 5.
168
+ category (Optional[str]): The category to filter search results.
169
+ Options are "company", "research paper", "news", "pdf", "github",
170
+ "tweet", "personal site", "linkedin profile", "financial report".
171
+
172
+ Returns:
173
+ str: The search results in JSON format.
174
+ """
175
+ try:
176
+ if self.show_results:
177
+ log_info(f"Searching exa for: {query}")
178
+ search_kwargs: Dict[str, Any] = {
179
+ "text": self.text,
180
+ "summary": self.summary,
181
+ "num_results": self.num_results or num_results,
182
+ "start_crawl_date": self.start_crawl_date,
183
+ "end_crawl_date": self.end_crawl_date,
184
+ "start_published_date": self.start_published_date,
185
+ "end_published_date": self.end_published_date,
186
+ "type": self.type,
187
+ "category": self.category or category, # Prefer a user-set category
188
+ "include_domains": self.include_domains,
189
+ "exclude_domains": self.exclude_domains,
190
+ }
191
+ # Clean up the kwargs
192
+ search_kwargs = {k: v for k, v in search_kwargs.items() if v is not None}
193
+
194
+ # Execute search with timeout
195
+ exa_results = self._execute_with_timeout(self.exa.search_and_contents, query, **search_kwargs)
196
+
197
+ parsed_results = self._parse_results(exa_results)
198
+ # Extract search results
199
+ if self.show_results:
200
+ log_info(parsed_results)
201
+ return parsed_results
202
+ except TimeoutError as e:
203
+ logger.error(f"Search timed out after {self.timeout} seconds")
204
+ return f"Error: {str(e)}"
205
+ except Exception as e:
206
+ logger.error(f"Failed to search exa {e}")
207
+ return f"Error: {e}"
208
+
209
+ def get_contents(self, urls: list[str]) -> str:
210
+ """
211
+ Retrieve detailed content from specific URLs using the Exa API.
212
+
213
+ Args:
214
+ urls (list(str)): A list of URLs from which to fetch content.
215
+
216
+ Returns:
217
+ str: The search results in JSON format.
218
+ """
219
+
220
+ query_kwargs: Dict[str, Any] = {
221
+ "text": self.text,
222
+ "summary": self.summary,
223
+ }
224
+
225
+ try:
226
+ if self.show_results:
227
+ log_info(f"Fetching contents for URLs: {urls}")
228
+
229
+ # Execute get_contents with timeout
230
+ exa_results = self._execute_with_timeout(self.exa.get_contents, urls=urls, **query_kwargs)
231
+
232
+ parsed_results = self._parse_results(exa_results)
233
+ if self.show_results:
234
+ log_info(parsed_results)
235
+
236
+ return parsed_results
237
+ except TimeoutError as e:
238
+ logger.error(f"Get contents timed out after {self.timeout} seconds")
239
+ return f"Error: {str(e)}"
240
+ except Exception as e:
241
+ logger.error(f"Failed to get contents from Exa: {e}")
242
+ return f"Error: {e}"
243
+
244
+ def find_similar(self, url: str, num_results: int = 5) -> str:
245
+ """
246
+ Find similar links to a given URL using the Exa API.
247
+
248
+ Args:
249
+ url (str): The URL for which to find similar links.
250
+ num_results (int, optional): The number of similar links to return. Defaults to 5.
251
+
252
+ Returns:
253
+ str: The search results in JSON format.
254
+ """
255
+
256
+ query_kwargs: Dict[str, Any] = {
257
+ "text": self.text,
258
+ "summary": self.summary,
259
+ "include_domains": self.include_domains,
260
+ "exclude_domains": self.exclude_domains,
261
+ "start_crawl_date": self.start_crawl_date,
262
+ "end_crawl_date": self.end_crawl_date,
263
+ "start_published_date": self.start_published_date,
264
+ "end_published_date": self.end_published_date,
265
+ "num_results": self.num_results or num_results,
266
+ }
267
+
268
+ try:
269
+ if self.show_results:
270
+ log_info(f"Finding similar links to: {url}")
271
+
272
+ # Execute find_similar with timeout
273
+ exa_results = self._execute_with_timeout(self.exa.find_similar_and_contents, url=url, **query_kwargs)
274
+
275
+ parsed_results = self._parse_results(exa_results)
276
+ if self.show_results:
277
+ log_info(parsed_results)
278
+
279
+ return parsed_results
280
+ except TimeoutError as e:
281
+ logger.error(f"Find similar timed out after {self.timeout} seconds")
282
+ return f"Error: {str(e)}"
283
+ except Exception as e:
284
+ logger.error(f"Failed to get similar links from Exa: {e}")
285
+ return f"Error: {e}"
286
+
287
+ def exa_answer(self, query: str, text: bool = False) -> str:
288
+ """
289
+ Get an LLM answer to a question informed by Exa search results.
290
+
291
+ Args:
292
+ query (str): The question or query to answer.
293
+ text (bool): Include full text from citation. Default is False.
294
+ Returns:
295
+ str: The answer results in JSON format with both generated answer and sources.
296
+ """
297
+
298
+ if self.model and self.model not in ["exa", "exa-pro"]:
299
+ raise ValueError("Model must be either 'exa' or 'exa-pro'")
300
+ try:
301
+ if self.show_results:
302
+ log_info(f"Generating answer for query: {query}")
303
+ answer_kwargs: Dict[str, Any] = {
304
+ "model": self.model,
305
+ "text": text,
306
+ }
307
+ answer_kwargs = {k: v for k, v in answer_kwargs.items() if v is not None}
308
+
309
+ # Execute answer with timeout
310
+ answer = self._execute_with_timeout(self.exa.answer, query=query, **answer_kwargs)
311
+
312
+ result = {
313
+ "answer": answer.answer, # type: ignore
314
+ "citations": [
315
+ {
316
+ "id": citation.id,
317
+ "url": citation.url,
318
+ "title": citation.title,
319
+ "published_date": citation.published_date,
320
+ "author": citation.author,
321
+ "text": citation.text if text else None,
322
+ }
323
+ for citation in answer.citations # type: ignore
324
+ ],
325
+ }
326
+ if self.show_results:
327
+ log_info(json.dumps(result))
328
+
329
+ return json.dumps(result, indent=4)
330
+
331
+ except TimeoutError as e:
332
+ logger.error(f"Answer generation timed out after {self.timeout} seconds")
333
+ return f"Error: {str(e)}"
334
+ except Exception as e:
335
+ logger.error(f"Failed to get answer from Exa: {e}")
336
+ return f"Error: {e}"
337
+
338
+ def research(
339
+ self,
340
+ instructions: str,
341
+ output_schema: Optional[Dict[str, Any]] = None,
342
+ ) -> str:
343
+ """
344
+ Perform deep research on a topic.
345
+
346
+ Args:
347
+ instructions (str): Research instructions.
348
+ output_schema (Optional[Dict[str, Any]]): JSON schema for structured output. If not provided, the API will auto-infer an appropriate schema.
349
+ Returns:
350
+ str: JSON formatted research results including data and citations.
351
+ """
352
+ try:
353
+ log_debug(f"Creating research task with instructions: {instructions}")
354
+ log_debug(f"Output schema: {output_schema}")
355
+
356
+ task_kwargs: Dict[str, Any] = {
357
+ "instructions": instructions,
358
+ "model": self.research_model,
359
+ }
360
+
361
+ if output_schema is not None:
362
+ task_kwargs["output_schema"] = output_schema
363
+ else:
364
+ task_kwargs["output_infer_schema"] = True
365
+
366
+ task_result = self._execute_with_timeout(self.exa.research.create_task, **task_kwargs) # type: ignore
367
+ task_id = task_result.id
368
+
369
+ if self.show_results:
370
+ log_info(f"Research task created with ID: {task_id}")
371
+
372
+ # Step 2: Poll until complete (using default polling settings)
373
+ task = self.exa.research.poll_task(task_id) # type: ignore
374
+
375
+ # Step 3: Format and return results
376
+ result: Dict[str, Any] = {"data": task.data, "citations": {}}
377
+
378
+ # Process citations by field
379
+ for field, sources in task.citations.items():
380
+ result["citations"][field] = [
381
+ {"url": source.url, "title": source.title, "id": source.id} for source in sources
382
+ ]
383
+
384
+ if self.show_results:
385
+ log_info("Research completed successfully")
386
+
387
+ return json.dumps(result, indent=4)
388
+
389
+ except TimeoutError:
390
+ error_msg = "Research task timed out"
391
+ logger.error(error_msg)
392
+ return json.dumps({"error": error_msg}, indent=4)
393
+ except Exception as e:
394
+ error_msg = f"Research failed: {str(e)}"
395
+ logger.error(error_msg)
396
+ return json.dumps({"error": error_msg}, indent=4)
agno/tools/fal.py ADDED
@@ -0,0 +1,127 @@
1
+ """
2
+ pip install fal-client
3
+ """
4
+
5
+ from os import getenv
6
+ from typing import Optional, Union
7
+ from uuid import uuid4
8
+
9
+ from agno.agent import Agent
10
+ from agno.media import Image, Video
11
+ from agno.team.team import Team
12
+ from agno.tools import Toolkit
13
+ from agno.tools.function import ToolResult
14
+ from agno.utils.log import log_info, logger
15
+
16
+ try:
17
+ import fal_client # type: ignore
18
+ except ImportError:
19
+ raise ImportError("`fal_client` not installed. Please install using `pip install fal-client`")
20
+
21
+
22
+ class FalTools(Toolkit):
23
+ def __init__(
24
+ self,
25
+ api_key: Optional[str] = None,
26
+ model: str = "fal-ai/hunyuan-video",
27
+ enable_generate_media: bool = True,
28
+ enable_image_to_image: bool = False,
29
+ all: bool = False,
30
+ **kwargs,
31
+ ):
32
+ self.api_key = api_key or getenv("FAL_API_KEY")
33
+ if not self.api_key:
34
+ logger.error("FAL_API_KEY not set. Please set the FAL_API_KEY environment variable.")
35
+ self.model = model
36
+ self.seen_logs: set[str] = set()
37
+
38
+ tools = []
39
+ if all or enable_generate_media:
40
+ tools.append(self.generate_media)
41
+ if all or enable_image_to_image:
42
+ tools.append(self.image_to_image)
43
+
44
+ super().__init__(name="fal-tools", tools=tools, **kwargs)
45
+
46
+ def on_queue_update(self, update):
47
+ if isinstance(update, fal_client.InProgress) and update.logs:
48
+ for log in update.logs:
49
+ message = log["message"]
50
+ if message not in self.seen_logs:
51
+ log_info(message)
52
+ self.seen_logs.add(message)
53
+
54
+ def generate_media(self, agent: Union[Agent, Team], prompt: str) -> ToolResult:
55
+ """
56
+ Use this function to run a model with a given prompt.
57
+
58
+ Args:
59
+ prompt (str): A text description of the task.
60
+ Returns:
61
+ ToolResult: Contains the generated media and success message.
62
+ """
63
+ try:
64
+ result = fal_client.subscribe(
65
+ self.model,
66
+ arguments={"prompt": prompt},
67
+ with_logs=True,
68
+ on_queue_update=self.on_queue_update,
69
+ )
70
+
71
+ media_id = str(uuid4())
72
+
73
+ if "image" in result:
74
+ url = result.get("image", {}).get("url", "")
75
+ image_artifact = Image(
76
+ id=media_id,
77
+ url=url,
78
+ )
79
+ return ToolResult(content=f"Image generated successfully at {url}", images=[image_artifact])
80
+ elif "video" in result:
81
+ url = result.get("video", {}).get("url", "")
82
+ video_artifact = Video(
83
+ id=media_id,
84
+ url=url,
85
+ )
86
+ return ToolResult(content=f"Video generated successfully at {url}", videos=[video_artifact])
87
+ else:
88
+ logger.error(f"Unsupported type in result: {result}")
89
+ return ToolResult(content=f"Unsupported type in result: {result}")
90
+
91
+ except Exception as e:
92
+ logger.error(f"Failed to run model: {e}")
93
+ return ToolResult(content=f"Error: {e}")
94
+
95
+ def image_to_image(self, agent: Union[Agent, Team], prompt: str, image_url: Optional[str] = None) -> ToolResult:
96
+ """
97
+ Use this function to transform an input image based on a text prompt using the Fal AI image-to-image model.
98
+ The model takes an existing image and generates a new version modified according to your prompt.
99
+ See https://fal.ai/models/fal-ai/flux/dev/image-to-image/api for more details about the image-to-image capabilities.
100
+
101
+ Args:
102
+ prompt (str): A text description of the task.
103
+ image_url (str): The URL of the image to use for the generation.
104
+
105
+ Returns:
106
+ ToolResult: Contains the generated image and success message.
107
+ """
108
+
109
+ try:
110
+ result = fal_client.subscribe(
111
+ "fal-ai/flux/dev/image-to-image",
112
+ arguments={"image_url": image_url, "prompt": prompt},
113
+ with_logs=True,
114
+ on_queue_update=self.on_queue_update,
115
+ )
116
+ url = result.get("images", [{}])[0].get("url", "")
117
+ media_id = str(uuid4())
118
+ image_artifact = Image(
119
+ id=media_id,
120
+ url=url,
121
+ )
122
+
123
+ return ToolResult(content=f"Image generated successfully at {url}", images=[image_artifact])
124
+
125
+ except Exception as e:
126
+ logger.error(f"Failed to generate image: {e}")
127
+ return ToolResult(content=f"Error: {e}")