agno 1.8.2__py3-none-any.whl → 2.0.0__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 (589) hide show
  1. agno/agent/__init__.py +19 -27
  2. agno/agent/agent.py +3143 -4170
  3. agno/api/agent.py +11 -67
  4. agno/api/api.py +5 -46
  5. agno/api/evals.py +8 -19
  6. agno/api/os.py +17 -0
  7. agno/api/routes.py +6 -41
  8. agno/api/schemas/__init__.py +9 -0
  9. agno/api/schemas/agent.py +5 -21
  10. agno/api/schemas/evals.py +7 -16
  11. agno/api/schemas/os.py +14 -0
  12. agno/api/schemas/team.py +5 -21
  13. agno/api/schemas/utils.py +21 -0
  14. agno/api/schemas/workflows.py +11 -7
  15. agno/api/settings.py +53 -0
  16. agno/api/team.py +11 -66
  17. agno/api/workflow.py +28 -0
  18. agno/cloud/aws/base.py +214 -0
  19. agno/cloud/aws/s3/__init__.py +2 -0
  20. agno/cloud/aws/s3/api_client.py +43 -0
  21. agno/cloud/aws/s3/bucket.py +195 -0
  22. agno/cloud/aws/s3/object.py +57 -0
  23. agno/db/__init__.py +24 -0
  24. agno/db/base.py +245 -0
  25. agno/db/dynamo/__init__.py +3 -0
  26. agno/db/dynamo/dynamo.py +1743 -0
  27. agno/db/dynamo/schemas.py +278 -0
  28. agno/db/dynamo/utils.py +684 -0
  29. agno/db/firestore/__init__.py +3 -0
  30. agno/db/firestore/firestore.py +1432 -0
  31. agno/db/firestore/schemas.py +130 -0
  32. agno/db/firestore/utils.py +278 -0
  33. agno/db/gcs_json/__init__.py +3 -0
  34. agno/db/gcs_json/gcs_json_db.py +1001 -0
  35. agno/db/gcs_json/utils.py +194 -0
  36. agno/db/in_memory/__init__.py +3 -0
  37. agno/db/in_memory/in_memory_db.py +882 -0
  38. agno/db/in_memory/utils.py +172 -0
  39. agno/db/json/__init__.py +3 -0
  40. agno/db/json/json_db.py +1045 -0
  41. agno/db/json/utils.py +196 -0
  42. agno/db/migrations/v1_to_v2.py +162 -0
  43. agno/db/mongo/__init__.py +3 -0
  44. agno/db/mongo/mongo.py +1416 -0
  45. agno/db/mongo/schemas.py +77 -0
  46. agno/db/mongo/utils.py +204 -0
  47. agno/db/mysql/__init__.py +3 -0
  48. agno/db/mysql/mysql.py +1719 -0
  49. agno/db/mysql/schemas.py +124 -0
  50. agno/db/mysql/utils.py +297 -0
  51. agno/db/postgres/__init__.py +3 -0
  52. agno/db/postgres/postgres.py +1710 -0
  53. agno/db/postgres/schemas.py +124 -0
  54. agno/db/postgres/utils.py +280 -0
  55. agno/db/redis/__init__.py +3 -0
  56. agno/db/redis/redis.py +1367 -0
  57. agno/db/redis/schemas.py +109 -0
  58. agno/db/redis/utils.py +288 -0
  59. agno/db/schemas/__init__.py +3 -0
  60. agno/db/schemas/evals.py +33 -0
  61. agno/db/schemas/knowledge.py +40 -0
  62. agno/db/schemas/memory.py +46 -0
  63. agno/db/singlestore/__init__.py +3 -0
  64. agno/db/singlestore/schemas.py +116 -0
  65. agno/db/singlestore/singlestore.py +1712 -0
  66. agno/db/singlestore/utils.py +326 -0
  67. agno/db/sqlite/__init__.py +3 -0
  68. agno/db/sqlite/schemas.py +119 -0
  69. agno/db/sqlite/sqlite.py +1676 -0
  70. agno/db/sqlite/utils.py +268 -0
  71. agno/db/utils.py +88 -0
  72. agno/eval/__init__.py +14 -0
  73. agno/eval/accuracy.py +154 -48
  74. agno/eval/performance.py +88 -23
  75. agno/eval/reliability.py +73 -20
  76. agno/eval/utils.py +23 -13
  77. agno/integrations/discord/__init__.py +3 -0
  78. agno/{app → integrations}/discord/client.py +10 -10
  79. agno/knowledge/__init__.py +2 -2
  80. agno/{document → knowledge}/chunking/agentic.py +2 -2
  81. agno/{document → knowledge}/chunking/document.py +2 -2
  82. agno/{document → knowledge}/chunking/fixed.py +3 -3
  83. agno/{document → knowledge}/chunking/markdown.py +2 -2
  84. agno/{document → knowledge}/chunking/recursive.py +2 -2
  85. agno/{document → knowledge}/chunking/row.py +2 -2
  86. agno/knowledge/chunking/semantic.py +59 -0
  87. agno/knowledge/chunking/strategy.py +121 -0
  88. agno/knowledge/content.py +74 -0
  89. agno/knowledge/document/__init__.py +5 -0
  90. agno/{document → knowledge/document}/base.py +12 -2
  91. agno/knowledge/embedder/__init__.py +5 -0
  92. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  93. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  94. agno/{embedder → knowledge/embedder}/base.py +6 -0
  95. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  96. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  97. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  98. agno/{embedder → knowledge/embedder}/google.py +74 -1
  99. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  100. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  101. agno/knowledge/embedder/langdb.py +22 -0
  102. agno/knowledge/embedder/mistral.py +139 -0
  103. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  104. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  105. agno/knowledge/embedder/openai.py +223 -0
  106. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  107. agno/{embedder → knowledge/embedder}/together.py +1 -1
  108. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  109. agno/knowledge/knowledge.py +1551 -0
  110. agno/knowledge/reader/__init__.py +7 -0
  111. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  112. agno/knowledge/reader/base.py +88 -0
  113. agno/{document → knowledge}/reader/csv_reader.py +47 -65
  114. agno/knowledge/reader/docx_reader.py +83 -0
  115. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  116. agno/{document → knowledge}/reader/json_reader.py +30 -9
  117. agno/{document → knowledge}/reader/markdown_reader.py +58 -9
  118. agno/{document → knowledge}/reader/pdf_reader.py +71 -126
  119. agno/knowledge/reader/reader_factory.py +268 -0
  120. agno/knowledge/reader/s3_reader.py +101 -0
  121. agno/{document → knowledge}/reader/text_reader.py +31 -10
  122. agno/knowledge/reader/url_reader.py +128 -0
  123. agno/knowledge/reader/web_search_reader.py +366 -0
  124. agno/{document → knowledge}/reader/website_reader.py +37 -10
  125. agno/knowledge/reader/wikipedia_reader.py +59 -0
  126. agno/knowledge/reader/youtube_reader.py +78 -0
  127. agno/knowledge/remote_content/remote_content.py +88 -0
  128. agno/{reranker → knowledge/reranker}/base.py +1 -1
  129. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  130. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  131. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  132. agno/knowledge/types.py +30 -0
  133. agno/knowledge/utils.py +169 -0
  134. agno/media.py +269 -268
  135. agno/memory/__init__.py +2 -10
  136. agno/memory/manager.py +1003 -148
  137. agno/models/aimlapi/__init__.py +2 -2
  138. agno/models/aimlapi/aimlapi.py +6 -6
  139. agno/models/anthropic/claude.py +128 -72
  140. agno/models/aws/bedrock.py +107 -175
  141. agno/models/aws/claude.py +64 -18
  142. agno/models/azure/ai_foundry.py +73 -23
  143. agno/models/base.py +346 -290
  144. agno/models/cerebras/cerebras.py +84 -27
  145. agno/models/cohere/chat.py +106 -98
  146. agno/models/google/gemini.py +105 -46
  147. agno/models/groq/groq.py +97 -35
  148. agno/models/huggingface/huggingface.py +92 -27
  149. agno/models/ibm/watsonx.py +72 -13
  150. agno/models/litellm/chat.py +85 -13
  151. agno/models/message.py +46 -151
  152. agno/models/meta/llama.py +85 -49
  153. agno/models/metrics.py +120 -0
  154. agno/models/mistral/mistral.py +90 -21
  155. agno/models/ollama/__init__.py +0 -2
  156. agno/models/ollama/chat.py +85 -47
  157. agno/models/openai/chat.py +154 -37
  158. agno/models/openai/responses.py +178 -105
  159. agno/models/perplexity/perplexity.py +26 -2
  160. agno/models/portkey/portkey.py +0 -7
  161. agno/models/response.py +15 -9
  162. agno/models/utils.py +20 -0
  163. agno/models/vercel/__init__.py +2 -2
  164. agno/models/vercel/v0.py +1 -1
  165. agno/models/vllm/__init__.py +2 -2
  166. agno/models/vllm/vllm.py +3 -3
  167. agno/models/xai/xai.py +10 -10
  168. agno/os/__init__.py +3 -0
  169. agno/os/app.py +497 -0
  170. agno/os/auth.py +47 -0
  171. agno/os/config.py +103 -0
  172. agno/os/interfaces/agui/__init__.py +3 -0
  173. agno/os/interfaces/agui/agui.py +31 -0
  174. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  175. agno/{app → os/interfaces}/agui/utils.py +65 -28
  176. agno/os/interfaces/base.py +21 -0
  177. agno/os/interfaces/slack/__init__.py +3 -0
  178. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  179. agno/os/interfaces/slack/slack.py +32 -0
  180. agno/os/interfaces/whatsapp/__init__.py +3 -0
  181. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  182. agno/os/interfaces/whatsapp/whatsapp.py +29 -0
  183. agno/os/mcp.py +235 -0
  184. agno/os/router.py +1400 -0
  185. agno/os/routers/__init__.py +3 -0
  186. agno/os/routers/evals/__init__.py +3 -0
  187. agno/os/routers/evals/evals.py +393 -0
  188. agno/os/routers/evals/schemas.py +142 -0
  189. agno/os/routers/evals/utils.py +161 -0
  190. agno/os/routers/knowledge/__init__.py +3 -0
  191. agno/os/routers/knowledge/knowledge.py +850 -0
  192. agno/os/routers/knowledge/schemas.py +118 -0
  193. agno/os/routers/memory/__init__.py +3 -0
  194. agno/os/routers/memory/memory.py +410 -0
  195. agno/os/routers/memory/schemas.py +58 -0
  196. agno/os/routers/metrics/__init__.py +3 -0
  197. agno/os/routers/metrics/metrics.py +178 -0
  198. agno/os/routers/metrics/schemas.py +47 -0
  199. agno/os/routers/session/__init__.py +3 -0
  200. agno/os/routers/session/session.py +536 -0
  201. agno/os/schema.py +945 -0
  202. agno/{app/playground → os}/settings.py +7 -15
  203. agno/os/utils.py +270 -0
  204. agno/reasoning/azure_ai_foundry.py +4 -4
  205. agno/reasoning/deepseek.py +4 -4
  206. agno/reasoning/default.py +6 -11
  207. agno/reasoning/groq.py +4 -4
  208. agno/reasoning/helpers.py +4 -6
  209. agno/reasoning/ollama.py +4 -4
  210. agno/reasoning/openai.py +4 -4
  211. agno/run/agent.py +633 -0
  212. agno/run/base.py +53 -77
  213. agno/run/cancel.py +81 -0
  214. agno/run/team.py +243 -96
  215. agno/run/workflow.py +550 -12
  216. agno/session/__init__.py +10 -0
  217. agno/session/agent.py +244 -0
  218. agno/session/summary.py +225 -0
  219. agno/session/team.py +262 -0
  220. agno/{storage/session/v2 → session}/workflow.py +47 -24
  221. agno/team/__init__.py +15 -16
  222. agno/team/team.py +3260 -4824
  223. agno/tools/agentql.py +14 -5
  224. agno/tools/airflow.py +9 -4
  225. agno/tools/api.py +7 -3
  226. agno/tools/apify.py +2 -46
  227. agno/tools/arxiv.py +8 -3
  228. agno/tools/aws_lambda.py +7 -5
  229. agno/tools/aws_ses.py +7 -1
  230. agno/tools/baidusearch.py +4 -1
  231. agno/tools/bitbucket.py +4 -4
  232. agno/tools/brandfetch.py +14 -11
  233. agno/tools/bravesearch.py +4 -1
  234. agno/tools/brightdata.py +43 -23
  235. agno/tools/browserbase.py +13 -4
  236. agno/tools/calcom.py +12 -10
  237. agno/tools/calculator.py +10 -27
  238. agno/tools/cartesia.py +20 -17
  239. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  240. agno/tools/confluence.py +8 -8
  241. agno/tools/crawl4ai.py +7 -1
  242. agno/tools/csv_toolkit.py +9 -8
  243. agno/tools/dalle.py +22 -12
  244. agno/tools/daytona.py +13 -16
  245. agno/tools/decorator.py +6 -3
  246. agno/tools/desi_vocal.py +17 -8
  247. agno/tools/discord.py +11 -8
  248. agno/tools/docker.py +30 -42
  249. agno/tools/duckdb.py +34 -53
  250. agno/tools/duckduckgo.py +8 -7
  251. agno/tools/e2b.py +62 -62
  252. agno/tools/eleven_labs.py +36 -29
  253. agno/tools/email.py +4 -1
  254. agno/tools/evm.py +7 -1
  255. agno/tools/exa.py +19 -14
  256. agno/tools/fal.py +30 -30
  257. agno/tools/file.py +9 -8
  258. agno/tools/financial_datasets.py +25 -44
  259. agno/tools/firecrawl.py +17 -18
  260. agno/tools/function.py +127 -18
  261. agno/tools/giphy.py +23 -11
  262. agno/tools/github.py +48 -126
  263. agno/tools/gmail.py +45 -61
  264. agno/tools/google_bigquery.py +7 -6
  265. agno/tools/google_maps.py +11 -26
  266. agno/tools/googlesearch.py +7 -2
  267. agno/tools/googlesheets.py +21 -17
  268. agno/tools/hackernews.py +9 -5
  269. agno/tools/jina.py +5 -4
  270. agno/tools/jira.py +18 -9
  271. agno/tools/knowledge.py +31 -32
  272. agno/tools/linear.py +18 -33
  273. agno/tools/linkup.py +5 -1
  274. agno/tools/local_file_system.py +8 -5
  275. agno/tools/lumalab.py +32 -20
  276. agno/tools/mcp.py +1 -2
  277. agno/tools/mem0.py +18 -12
  278. agno/tools/memori.py +14 -10
  279. agno/tools/mlx_transcribe.py +3 -2
  280. agno/tools/models/azure_openai.py +33 -15
  281. agno/tools/models/gemini.py +59 -32
  282. agno/tools/models/groq.py +30 -23
  283. agno/tools/models/nebius.py +28 -12
  284. agno/tools/models_labs.py +40 -16
  285. agno/tools/moviepy_video.py +7 -6
  286. agno/tools/neo4j.py +10 -8
  287. agno/tools/newspaper.py +7 -2
  288. agno/tools/newspaper4k.py +8 -3
  289. agno/tools/openai.py +58 -32
  290. agno/tools/openbb.py +12 -11
  291. agno/tools/opencv.py +63 -47
  292. agno/tools/openweather.py +14 -12
  293. agno/tools/pandas.py +11 -3
  294. agno/tools/postgres.py +4 -12
  295. agno/tools/pubmed.py +4 -1
  296. agno/tools/python.py +9 -22
  297. agno/tools/reasoning.py +35 -27
  298. agno/tools/reddit.py +11 -26
  299. agno/tools/replicate.py +55 -42
  300. agno/tools/resend.py +4 -1
  301. agno/tools/scrapegraph.py +15 -14
  302. agno/tools/searxng.py +10 -23
  303. agno/tools/serpapi.py +6 -3
  304. agno/tools/serper.py +13 -4
  305. agno/tools/shell.py +9 -2
  306. agno/tools/slack.py +12 -11
  307. agno/tools/sleep.py +3 -2
  308. agno/tools/spider.py +24 -4
  309. agno/tools/sql.py +7 -6
  310. agno/tools/tavily.py +6 -4
  311. agno/tools/telegram.py +12 -4
  312. agno/tools/todoist.py +11 -31
  313. agno/tools/toolkit.py +1 -1
  314. agno/tools/trafilatura.py +22 -6
  315. agno/tools/trello.py +9 -22
  316. agno/tools/twilio.py +10 -3
  317. agno/tools/user_control_flow.py +6 -1
  318. agno/tools/valyu.py +34 -5
  319. agno/tools/visualization.py +19 -28
  320. agno/tools/webbrowser.py +4 -3
  321. agno/tools/webex.py +11 -7
  322. agno/tools/website.py +15 -46
  323. agno/tools/webtools.py +12 -4
  324. agno/tools/whatsapp.py +5 -9
  325. agno/tools/wikipedia.py +20 -13
  326. agno/tools/x.py +14 -13
  327. agno/tools/yfinance.py +13 -40
  328. agno/tools/youtube.py +26 -20
  329. agno/tools/zendesk.py +7 -2
  330. agno/tools/zep.py +10 -7
  331. agno/tools/zoom.py +10 -9
  332. agno/utils/common.py +1 -19
  333. agno/utils/events.py +100 -123
  334. agno/utils/gemini.py +1 -1
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/log.py +54 -4
  337. agno/utils/mcp.py +68 -10
  338. agno/utils/media.py +39 -0
  339. agno/utils/message.py +12 -1
  340. agno/utils/models/aws_claude.py +1 -1
  341. agno/utils/models/claude.py +6 -12
  342. agno/utils/models/cohere.py +1 -1
  343. agno/utils/models/mistral.py +8 -7
  344. agno/utils/models/schema_utils.py +3 -3
  345. agno/utils/models/watsonx.py +1 -1
  346. agno/utils/openai.py +1 -1
  347. agno/utils/pprint.py +33 -32
  348. agno/utils/print_response/agent.py +779 -0
  349. agno/utils/print_response/team.py +1669 -0
  350. agno/utils/print_response/workflow.py +1451 -0
  351. agno/utils/prompts.py +14 -14
  352. agno/utils/reasoning.py +87 -0
  353. agno/utils/response.py +42 -42
  354. agno/utils/streamlit.py +481 -0
  355. agno/utils/string.py +8 -22
  356. agno/utils/team.py +50 -0
  357. agno/utils/timer.py +2 -2
  358. agno/vectordb/base.py +33 -21
  359. agno/vectordb/cassandra/cassandra.py +287 -23
  360. agno/vectordb/chroma/chromadb.py +482 -59
  361. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  362. agno/vectordb/couchbase/couchbase.py +309 -29
  363. agno/vectordb/lancedb/lance_db.py +360 -21
  364. agno/vectordb/langchaindb/__init__.py +5 -0
  365. agno/vectordb/langchaindb/langchaindb.py +145 -0
  366. agno/vectordb/lightrag/__init__.py +5 -0
  367. agno/vectordb/lightrag/lightrag.py +374 -0
  368. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  369. agno/vectordb/milvus/milvus.py +242 -32
  370. agno/vectordb/mongodb/mongodb.py +200 -24
  371. agno/vectordb/pgvector/pgvector.py +319 -37
  372. agno/vectordb/pineconedb/pineconedb.py +221 -27
  373. agno/vectordb/qdrant/qdrant.py +334 -14
  374. agno/vectordb/singlestore/singlestore.py +286 -29
  375. agno/vectordb/surrealdb/surrealdb.py +187 -7
  376. agno/vectordb/upstashdb/upstashdb.py +342 -26
  377. agno/vectordb/weaviate/weaviate.py +227 -165
  378. agno/workflow/__init__.py +17 -13
  379. agno/workflow/{v2/condition.py → condition.py} +135 -32
  380. agno/workflow/{v2/loop.py → loop.py} +115 -28
  381. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  382. agno/workflow/{v2/router.py → router.py} +133 -32
  383. agno/workflow/{v2/step.py → step.py} +207 -49
  384. agno/workflow/{v2/steps.py → steps.py} +147 -66
  385. agno/workflow/types.py +482 -0
  386. agno/workflow/workflow.py +2410 -696
  387. agno-2.0.0.dist-info/METADATA +494 -0
  388. agno-2.0.0.dist-info/RECORD +515 -0
  389. agno-2.0.0.dist-info/licenses/LICENSE +201 -0
  390. agno/agent/metrics.py +0 -110
  391. agno/api/app.py +0 -35
  392. agno/api/playground.py +0 -92
  393. agno/api/schemas/app.py +0 -12
  394. agno/api/schemas/playground.py +0 -22
  395. agno/api/schemas/user.py +0 -35
  396. agno/api/schemas/workspace.py +0 -46
  397. agno/api/user.py +0 -160
  398. agno/api/workflows.py +0 -33
  399. agno/api/workspace.py +0 -175
  400. agno/app/agui/__init__.py +0 -3
  401. agno/app/agui/app.py +0 -17
  402. agno/app/agui/sync_router.py +0 -120
  403. agno/app/base.py +0 -186
  404. agno/app/discord/__init__.py +0 -3
  405. agno/app/fastapi/__init__.py +0 -3
  406. agno/app/fastapi/app.py +0 -107
  407. agno/app/fastapi/async_router.py +0 -457
  408. agno/app/fastapi/sync_router.py +0 -448
  409. agno/app/playground/app.py +0 -228
  410. agno/app/playground/async_router.py +0 -1053
  411. agno/app/playground/deploy.py +0 -249
  412. agno/app/playground/operator.py +0 -183
  413. agno/app/playground/schemas.py +0 -223
  414. agno/app/playground/serve.py +0 -55
  415. agno/app/playground/sync_router.py +0 -1045
  416. agno/app/playground/utils.py +0 -46
  417. agno/app/settings.py +0 -15
  418. agno/app/slack/__init__.py +0 -3
  419. agno/app/slack/app.py +0 -19
  420. agno/app/slack/sync_router.py +0 -92
  421. agno/app/utils.py +0 -54
  422. agno/app/whatsapp/__init__.py +0 -3
  423. agno/app/whatsapp/app.py +0 -15
  424. agno/app/whatsapp/sync_router.py +0 -197
  425. agno/cli/auth_server.py +0 -249
  426. agno/cli/config.py +0 -274
  427. agno/cli/console.py +0 -88
  428. agno/cli/credentials.py +0 -23
  429. agno/cli/entrypoint.py +0 -571
  430. agno/cli/operator.py +0 -357
  431. agno/cli/settings.py +0 -96
  432. agno/cli/ws/ws_cli.py +0 -817
  433. agno/constants.py +0 -13
  434. agno/document/__init__.py +0 -5
  435. agno/document/chunking/semantic.py +0 -45
  436. agno/document/chunking/strategy.py +0 -31
  437. agno/document/reader/__init__.py +0 -5
  438. agno/document/reader/base.py +0 -47
  439. agno/document/reader/docx_reader.py +0 -60
  440. agno/document/reader/gcs/pdf_reader.py +0 -44
  441. agno/document/reader/s3/pdf_reader.py +0 -59
  442. agno/document/reader/s3/text_reader.py +0 -63
  443. agno/document/reader/url_reader.py +0 -59
  444. agno/document/reader/youtube_reader.py +0 -58
  445. agno/embedder/__init__.py +0 -5
  446. agno/embedder/langdb.py +0 -80
  447. agno/embedder/mistral.py +0 -82
  448. agno/embedder/openai.py +0 -78
  449. agno/file/__init__.py +0 -5
  450. agno/file/file.py +0 -16
  451. agno/file/local/csv.py +0 -32
  452. agno/file/local/txt.py +0 -19
  453. agno/infra/app.py +0 -240
  454. agno/infra/base.py +0 -144
  455. agno/infra/context.py +0 -20
  456. agno/infra/db_app.py +0 -52
  457. agno/infra/resource.py +0 -205
  458. agno/infra/resources.py +0 -55
  459. agno/knowledge/agent.py +0 -702
  460. agno/knowledge/arxiv.py +0 -33
  461. agno/knowledge/combined.py +0 -36
  462. agno/knowledge/csv.py +0 -144
  463. agno/knowledge/csv_url.py +0 -124
  464. agno/knowledge/document.py +0 -223
  465. agno/knowledge/docx.py +0 -137
  466. agno/knowledge/firecrawl.py +0 -34
  467. agno/knowledge/gcs/__init__.py +0 -0
  468. agno/knowledge/gcs/base.py +0 -39
  469. agno/knowledge/gcs/pdf.py +0 -125
  470. agno/knowledge/json.py +0 -137
  471. agno/knowledge/langchain.py +0 -71
  472. agno/knowledge/light_rag.py +0 -273
  473. agno/knowledge/llamaindex.py +0 -66
  474. agno/knowledge/markdown.py +0 -154
  475. agno/knowledge/pdf.py +0 -164
  476. agno/knowledge/pdf_bytes.py +0 -42
  477. agno/knowledge/pdf_url.py +0 -148
  478. agno/knowledge/s3/__init__.py +0 -0
  479. agno/knowledge/s3/base.py +0 -64
  480. agno/knowledge/s3/pdf.py +0 -33
  481. agno/knowledge/s3/text.py +0 -34
  482. agno/knowledge/text.py +0 -141
  483. agno/knowledge/url.py +0 -46
  484. agno/knowledge/website.py +0 -179
  485. agno/knowledge/wikipedia.py +0 -32
  486. agno/knowledge/youtube.py +0 -35
  487. agno/memory/agent.py +0 -423
  488. agno/memory/classifier.py +0 -104
  489. agno/memory/db/__init__.py +0 -5
  490. agno/memory/db/base.py +0 -42
  491. agno/memory/db/mongodb.py +0 -189
  492. agno/memory/db/postgres.py +0 -203
  493. agno/memory/db/sqlite.py +0 -193
  494. agno/memory/memory.py +0 -22
  495. agno/memory/row.py +0 -36
  496. agno/memory/summarizer.py +0 -201
  497. agno/memory/summary.py +0 -19
  498. agno/memory/team.py +0 -415
  499. agno/memory/v2/__init__.py +0 -2
  500. agno/memory/v2/db/__init__.py +0 -1
  501. agno/memory/v2/db/base.py +0 -42
  502. agno/memory/v2/db/firestore.py +0 -339
  503. agno/memory/v2/db/mongodb.py +0 -196
  504. agno/memory/v2/db/postgres.py +0 -214
  505. agno/memory/v2/db/redis.py +0 -187
  506. agno/memory/v2/db/schema.py +0 -54
  507. agno/memory/v2/db/sqlite.py +0 -209
  508. agno/memory/v2/manager.py +0 -437
  509. agno/memory/v2/memory.py +0 -1097
  510. agno/memory/v2/schema.py +0 -55
  511. agno/memory/v2/summarizer.py +0 -215
  512. agno/memory/workflow.py +0 -38
  513. agno/models/ollama/tools.py +0 -430
  514. agno/models/qwen/__init__.py +0 -5
  515. agno/playground/__init__.py +0 -10
  516. agno/playground/deploy.py +0 -3
  517. agno/playground/playground.py +0 -3
  518. agno/playground/serve.py +0 -3
  519. agno/playground/settings.py +0 -3
  520. agno/reranker/__init__.py +0 -0
  521. agno/run/response.py +0 -467
  522. agno/run/v2/__init__.py +0 -0
  523. agno/run/v2/workflow.py +0 -567
  524. agno/storage/__init__.py +0 -0
  525. agno/storage/agent/__init__.py +0 -0
  526. agno/storage/agent/dynamodb.py +0 -1
  527. agno/storage/agent/json.py +0 -1
  528. agno/storage/agent/mongodb.py +0 -1
  529. agno/storage/agent/postgres.py +0 -1
  530. agno/storage/agent/singlestore.py +0 -1
  531. agno/storage/agent/sqlite.py +0 -1
  532. agno/storage/agent/yaml.py +0 -1
  533. agno/storage/base.py +0 -60
  534. agno/storage/dynamodb.py +0 -673
  535. agno/storage/firestore.py +0 -297
  536. agno/storage/gcs_json.py +0 -261
  537. agno/storage/in_memory.py +0 -234
  538. agno/storage/json.py +0 -237
  539. agno/storage/mongodb.py +0 -328
  540. agno/storage/mysql.py +0 -685
  541. agno/storage/postgres.py +0 -682
  542. agno/storage/redis.py +0 -336
  543. agno/storage/session/__init__.py +0 -16
  544. agno/storage/session/agent.py +0 -64
  545. agno/storage/session/team.py +0 -63
  546. agno/storage/session/v2/__init__.py +0 -5
  547. agno/storage/session/workflow.py +0 -61
  548. agno/storage/singlestore.py +0 -606
  549. agno/storage/sqlite.py +0 -646
  550. agno/storage/workflow/__init__.py +0 -0
  551. agno/storage/workflow/mongodb.py +0 -1
  552. agno/storage/workflow/postgres.py +0 -1
  553. agno/storage/workflow/sqlite.py +0 -1
  554. agno/storage/yaml.py +0 -241
  555. agno/tools/thinking.py +0 -73
  556. agno/utils/defaults.py +0 -57
  557. agno/utils/filesystem.py +0 -39
  558. agno/utils/git.py +0 -52
  559. agno/utils/json_io.py +0 -30
  560. agno/utils/load_env.py +0 -19
  561. agno/utils/py_io.py +0 -19
  562. agno/utils/pyproject.py +0 -18
  563. agno/utils/resource_filter.py +0 -31
  564. agno/workflow/v2/__init__.py +0 -21
  565. agno/workflow/v2/types.py +0 -357
  566. agno/workflow/v2/workflow.py +0 -3313
  567. agno/workspace/__init__.py +0 -0
  568. agno/workspace/config.py +0 -325
  569. agno/workspace/enums.py +0 -6
  570. agno/workspace/helpers.py +0 -52
  571. agno/workspace/operator.py +0 -757
  572. agno/workspace/settings.py +0 -158
  573. agno-1.8.2.dist-info/METADATA +0 -982
  574. agno-1.8.2.dist-info/RECORD +0 -566
  575. agno-1.8.2.dist-info/entry_points.txt +0 -3
  576. agno-1.8.2.dist-info/licenses/LICENSE +0 -375
  577. /agno/{app → db/migrations}/__init__.py +0 -0
  578. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  579. /agno/{cli → integrations}/__init__.py +0 -0
  580. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  581. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  582. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  583. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  584. /agno/{app → os/interfaces}/slack/security.py +0 -0
  585. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  586. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  587. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  588. {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
  589. {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
agno/tools/linkup.py CHANGED
@@ -16,6 +16,8 @@ class LinkupTools(Toolkit):
16
16
  api_key: Optional[str] = None,
17
17
  depth: Literal["standard", "deep"] = "standard",
18
18
  output_type: Literal["sourcedAnswer", "searchResults"] = "searchResults",
19
+ enable_web_search_with_linkup: bool = True,
20
+ all: bool = False,
19
21
  **kwargs,
20
22
  ):
21
23
  self.api_key = api_key or getenv("LINKUP_API_KEY")
@@ -26,7 +28,9 @@ class LinkupTools(Toolkit):
26
28
  self.depth = depth
27
29
  self.output_type = output_type
28
30
 
29
- tools: List[Any] = [self.web_search_with_linkup]
31
+ tools: List[Any] = []
32
+ if all or enable_web_search_with_linkup:
33
+ tools.append(self.web_search_with_linkup)
30
34
 
31
35
  super().__init__(name="linkup_tools", tools=tools, **kwargs)
32
36
 
@@ -1,4 +1,3 @@
1
- import os
2
1
  from pathlib import Path
3
2
  from typing import Optional
4
3
  from uuid import uuid4
@@ -12,6 +11,8 @@ class LocalFileSystemTools(Toolkit):
12
11
  self,
13
12
  target_directory: Optional[str] = None,
14
13
  default_extension: str = "txt",
14
+ enable_write_file: bool = True,
15
+ all: bool = False,
15
16
  **kwargs,
16
17
  ):
17
18
  """
@@ -21,14 +22,15 @@ class LocalFileSystemTools(Toolkit):
21
22
  default_extension (str): Default file extension to use if none specified.
22
23
  """
23
24
 
24
- self.target_directory = target_directory or os.getcwd()
25
+ self.target_directory = target_directory or str(Path.cwd())
25
26
  self.default_extension = default_extension.lstrip(".")
26
27
 
27
28
  target_path = Path(self.target_directory)
28
29
  target_path.mkdir(parents=True, exist_ok=True)
29
30
 
30
31
  tools = []
31
- tools.append(self.write_file)
32
+ if all or enable_write_file:
33
+ tools.append(self.write_file)
32
34
 
33
35
  super().__init__(name="write_to_local", tools=tools, **kwargs)
34
36
 
@@ -53,8 +55,9 @@ class LocalFileSystemTools(Toolkit):
53
55
  filename = filename or str(uuid4())
54
56
  directory = directory or self.target_directory
55
57
  if filename and "." in filename:
56
- filename, file_ext = os.path.splitext(filename)
57
- extension = extension or file_ext.lstrip(".")
58
+ path_obj = Path(filename)
59
+ filename = path_obj.stem
60
+ extension = extension or path_obj.suffix.lstrip(".")
58
61
 
59
62
  log_debug(f"Writing file to local system: {filename}")
60
63
 
agno/tools/lumalab.py CHANGED
@@ -4,8 +4,9 @@ from os import getenv
4
4
  from typing import Any, Dict, List, Literal, Optional, TypedDict
5
5
 
6
6
  from agno.agent import Agent
7
- from agno.media import VideoArtifact
7
+ from agno.media import Video
8
8
  from agno.tools import Toolkit
9
+ from agno.tools.function import ToolResult
9
10
  from agno.utils.log import log_info, logger
10
11
 
11
12
  try:
@@ -30,6 +31,9 @@ class LumaLabTools(Toolkit):
30
31
  wait_for_completion: bool = True,
31
32
  poll_interval: int = 3,
32
33
  max_wait_time: int = 300, # 5 minutes
34
+ enable_generate_video: bool = True,
35
+ enable_image_to_video: bool = True,
36
+ all: bool = False,
33
37
  **kwargs,
34
38
  ):
35
39
  self.wait_for_completion = wait_for_completion
@@ -43,8 +47,10 @@ class LumaLabTools(Toolkit):
43
47
  self.client = LumaAI(auth_token=self.api_key)
44
48
 
45
49
  tools: List[Any] = []
46
- tools.append(self.generate_video)
47
- tools.append(self.image_to_video)
50
+ if all or enable_generate_video:
51
+ tools.append(self.generate_video)
52
+ if all or enable_image_to_video:
53
+ tools.append(self.image_to_video)
48
54
 
49
55
  super().__init__(name="luma_lab", tools=tools, **kwargs)
50
56
 
@@ -56,7 +62,7 @@ class LumaLabTools(Toolkit):
56
62
  end_image_url: Optional[str] = None,
57
63
  loop: bool = False,
58
64
  aspect_ratio: Literal["1:1", "16:9", "9:16", "4:3", "3:4", "21:9", "9:21"] = "16:9",
59
- ) -> str:
65
+ ) -> ToolResult:
60
66
  """Generate a video from one or two images with a prompt.
61
67
 
62
68
  Args:
@@ -68,7 +74,7 @@ class LumaLabTools(Toolkit):
68
74
  aspect_ratio: Aspect ratio of the output video
69
75
 
70
76
  Returns:
71
- str: Status message or error
77
+ ToolResult: A ToolResult containing the generated video or error message.
72
78
  """
73
79
 
74
80
  try:
@@ -90,33 +96,36 @@ class LumaLabTools(Toolkit):
90
96
  video_id = str(uuid.uuid4())
91
97
 
92
98
  if not self.wait_for_completion:
93
- return "Async generation unsupported"
99
+ return ToolResult(content="Async generation unsupported")
94
100
 
95
101
  # Poll for completion
96
102
  seconds_waited = 0
97
103
  while seconds_waited < self.max_wait_time:
98
104
  if not generation or not generation.id:
99
- return "Failed to get generation ID"
105
+ return ToolResult(content="Failed to get generation ID")
100
106
 
101
107
  generation = self.client.generations.get(generation.id)
102
108
 
103
109
  if generation.state == "completed" and generation.assets:
104
110
  video_url = generation.assets.video
105
111
  if video_url:
106
- agent.add_video(VideoArtifact(id=video_id, url=video_url, eta="completed"))
107
- return f"Video generated successfully: {video_url}"
112
+ video_artifact = Video(id=video_id, url=video_url, eta="completed")
113
+ return ToolResult(
114
+ content=f"Video generated successfully: {video_url}",
115
+ videos=[video_artifact],
116
+ )
108
117
  elif generation.state == "failed":
109
- return f"Generation failed: {generation.failure_reason}"
118
+ return ToolResult(content=f"Generation failed: {generation.failure_reason}")
110
119
 
111
120
  log_info(f"Generation in progress... State: {generation.state}")
112
121
  time.sleep(self.poll_interval)
113
122
  seconds_waited += self.poll_interval
114
123
 
115
- return f"Video generation timed out after {self.max_wait_time} seconds"
124
+ return ToolResult(content=f"Video generation timed out after {self.max_wait_time} seconds")
116
125
 
117
126
  except Exception as e:
118
127
  logger.error(f"Failed to generate video: {e}")
119
- return f"Error: {e}"
128
+ return ToolResult(content=f"Error: {e}")
120
129
 
121
130
  def generate_video(
122
131
  self,
@@ -125,7 +134,7 @@ class LumaLabTools(Toolkit):
125
134
  loop: bool = False,
126
135
  aspect_ratio: Literal["1:1", "16:9", "9:16", "4:3", "3:4", "21:9", "9:21"] = "16:9",
127
136
  keyframes: Optional[Dict[str, Dict[str, str]]] = None,
128
- ) -> str:
137
+ ) -> ToolResult:
129
138
  """Use this function to generate a video given a prompt."""
130
139
 
131
140
  try:
@@ -142,30 +151,33 @@ class LumaLabTools(Toolkit):
142
151
 
143
152
  video_id = str(uuid.uuid4())
144
153
  if not self.wait_for_completion:
145
- return "Async generation unsupported"
154
+ return ToolResult(content="Async generation unsupported")
146
155
 
147
156
  # Poll for completion
148
157
  seconds_waited = 0
149
158
  while seconds_waited < self.max_wait_time:
150
159
  if not generation or not generation.id:
151
- return "Failed to get generation ID"
160
+ return ToolResult(content="Failed to get generation ID")
152
161
 
153
162
  generation = self.client.generations.get(generation.id)
154
163
 
155
164
  if generation.state == "completed" and generation.assets:
156
165
  video_url = generation.assets.video
157
166
  if video_url:
158
- agent.add_video(VideoArtifact(id=video_id, url=video_url, state="completed"))
159
- return f"Video generated successfully: {video_url}"
167
+ video_artifact = Video(id=video_id, url=video_url, state="completed")
168
+ return ToolResult(
169
+ content=f"Video generated successfully: {video_url}",
170
+ videos=[video_artifact],
171
+ )
160
172
  elif generation.state == "failed":
161
- return f"Generation failed: {generation.failure_reason}"
173
+ return ToolResult(content=f"Generation failed: {generation.failure_reason}")
162
174
 
163
175
  log_info(f"Generation in progress... State: {generation.state}")
164
176
  time.sleep(self.poll_interval)
165
177
  seconds_waited += self.poll_interval
166
178
 
167
- return f"Video generation timed out after {self.max_wait_time} seconds"
179
+ return ToolResult(content=f"Video generation timed out after {self.max_wait_time} seconds")
168
180
 
169
181
  except Exception as e:
170
182
  logger.error(f"Failed to generate video: {e}")
171
- return f"Error: {e}"
183
+ return ToolResult(content=f"Error: {e}")
agno/tools/mcp.py CHANGED
@@ -365,7 +365,7 @@ class MultiMCPTools(Toolkit):
365
365
  *,
366
366
  env: Optional[dict[str, str]] = None,
367
367
  server_params_list: Optional[
368
- List[Union[SSEClientParams, StdioServerParameters, StreamableHTTPClientParams]]
368
+ list[Union[SSEClientParams, StdioServerParameters, StreamableHTTPClientParams]]
369
369
  ] = None,
370
370
  timeout_seconds: int = 5,
371
371
  client=None,
@@ -531,7 +531,6 @@ class MultiMCPTools(Toolkit):
531
531
  session = await self._async_exit_stack.enter_async_context(ClientSession(read, write))
532
532
  self._active_contexts.append(session)
533
533
  await self.initialize(session)
534
-
535
534
  # Handle Streamable HTTP connections
536
535
  elif isinstance(server_params, StreamableHTTPClientParams):
537
536
  client_connection = await self._async_exit_stack.enter_async_context(
agno/tools/mem0.py CHANGED
@@ -1,9 +1,9 @@
1
1
  import json
2
2
  from os import getenv
3
- from typing import Any, Dict, Optional, Union
3
+ from typing import Any, Dict, List, Optional, Union
4
4
 
5
5
  from agno.agent import Agent
6
- from agno.tools.toolkit import Toolkit
6
+ from agno.tools import Toolkit
7
7
  from agno.utils.log import log_debug, log_error, log_warning
8
8
 
9
9
  try:
@@ -22,18 +22,24 @@ class Mem0Tools(Toolkit):
22
22
  org_id: Optional[str] = None,
23
23
  project_id: Optional[str] = None,
24
24
  infer: bool = True,
25
+ enable_add_memory: bool = True,
26
+ enable_search_memory: bool = True,
27
+ enable_get_all_memories: bool = True,
28
+ enable_delete_all_memories: bool = True,
29
+ all: bool = False,
25
30
  **kwargs,
26
31
  ):
27
- super().__init__(
28
- name="mem0_tools",
29
- tools=[
30
- self.add_memory,
31
- self.search_memory,
32
- self.get_all_memories,
33
- self.delete_all_memories,
34
- ],
35
- **kwargs,
36
- )
32
+ tools: List[Any] = []
33
+ if enable_add_memory or all:
34
+ tools.append(self.add_memory)
35
+ if enable_search_memory or all:
36
+ tools.append(self.search_memory)
37
+ if enable_get_all_memories or all:
38
+ tools.append(self.get_all_memories)
39
+ if enable_delete_all_memories or all:
40
+ tools.append(self.delete_all_memories)
41
+
42
+ super().__init__(name="mem0_tools", tools=tools, **kwargs)
37
43
  self.api_key = api_key or getenv("MEM0_API_KEY")
38
44
  self.user_id = user_id
39
45
  self.org_id = org_id or getenv("MEM0_ORG_ID")
agno/tools/memori.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import json
2
- from typing import Any, Dict, Optional
2
+ from typing import Any, Dict, List, Optional
3
3
 
4
4
  from agno.agent import Agent
5
5
  from agno.tools.toolkit import Toolkit
@@ -54,6 +54,10 @@ class MemoriTools(Toolkit):
54
54
  verbose: bool = False,
55
55
  config: Optional[Dict[str, Any]] = None,
56
56
  auto_enable: bool = True,
57
+ enable_search_memory: bool = True,
58
+ enable_record_conversation: bool = True,
59
+ enable_get_memory_stats: bool = True,
60
+ all: bool = False,
57
61
  **kwargs,
58
62
  ):
59
63
  """
@@ -69,15 +73,15 @@ class MemoriTools(Toolkit):
69
73
  auto_enable: Automatically enable the memory system on initialization
70
74
  **kwargs: Additional arguments passed to Toolkit base class
71
75
  """
72
- super().__init__(
73
- name="memori_tools",
74
- tools=[
75
- self.search_memory,
76
- self.record_conversation,
77
- self.get_memory_stats,
78
- ],
79
- **kwargs,
80
- )
76
+ tools: List[Any] = []
77
+ if all or enable_search_memory:
78
+ tools.append(self.search_memory)
79
+ if all or enable_record_conversation:
80
+ tools.append(self.record_conversation)
81
+ if all or enable_get_memory_stats:
82
+ tools.append(self.get_memory_stats)
83
+
84
+ super().__init__(name="memori_tools", tools=tools, **kwargs)
81
85
 
82
86
  # Set default database connection if not provided
83
87
  if not database_connect:
@@ -32,7 +32,7 @@ class MLXTranscribeTools(Toolkit):
32
32
  def __init__(
33
33
  self,
34
34
  base_dir: Optional[Path] = None,
35
- read_files_in_base_dir: bool = True,
35
+ enable_read_files_in_base_dir: bool = True,
36
36
  path_or_hf_repo: str = "mlx-community/whisper-large-v3-turbo",
37
37
  verbose: Optional[bool] = None,
38
38
  temperature: Optional[Union[float, Tuple[float, ...]]] = None,
@@ -47,6 +47,7 @@ class MLXTranscribeTools(Toolkit):
47
47
  clip_timestamps: Optional[Union[str, List[float]]] = None,
48
48
  hallucination_silence_threshold: Optional[float] = None,
49
49
  decode_options: Optional[dict] = None,
50
+ all: bool = False,
50
51
  **kwargs,
51
52
  ):
52
53
  self.base_dir: Path = base_dir or Path.cwd()
@@ -66,7 +67,7 @@ class MLXTranscribeTools(Toolkit):
66
67
  self.decode_options: Optional[dict] = decode_options
67
68
 
68
69
  tools: List[Any] = [self.transcribe]
69
- if read_files_in_base_dir:
70
+ if enable_read_files_in_base_dir or all:
70
71
  tools.append(self.read_files)
71
72
 
72
73
  super().__init__(name="mlx_transcribe", tools=tools, **kwargs)
@@ -5,8 +5,9 @@ from uuid import uuid4
5
5
  from requests import post
6
6
 
7
7
  from agno.agent import Agent
8
- from agno.media import ImageArtifact
8
+ from agno.media import Image
9
9
  from agno.tools import Toolkit
10
+ from agno.tools.function import ToolResult
10
11
  from agno.utils.log import log_debug, logger
11
12
 
12
13
 
@@ -31,9 +32,9 @@ class AzureOpenAITools(Toolkit):
31
32
  image_deployment: Optional[str] = None,
32
33
  image_model: str = "dall-e-3",
33
34
  image_quality: Literal["standard", "hd"] = "standard", # Note: "hd" quality is only available for dall-e-3.
35
+ enable_generate_image: bool = True,
36
+ all: bool = False,
34
37
  ):
35
- super().__init__(name="azure_openai")
36
-
37
38
  # Set credentials from parameters or environment variables
38
39
  self.api_key = api_key or getenv("AZURE_OPENAI_API_KEY")
39
40
  self.azure_endpoint = azure_endpoint or getenv("AZURE_OPENAI_ENDPOINT")
@@ -49,15 +50,20 @@ class AzureOpenAITools(Toolkit):
49
50
  self.image_deployment = image_deployment or getenv("AZURE_OPENAI_IMAGE_DEPLOYMENT")
50
51
  self.image_model = image_model
51
52
 
53
+ # Build tools list based on available services
54
+ tools = []
55
+
52
56
  # Validate image generation parameters
53
57
  if self.image_deployment and self.image_model in self.VALID_MODELS:
54
58
  # Create and store the base URL
55
59
  self.image_base_url = f"{self.azure_endpoint}/openai/deployments/{self.image_deployment}/images/generations?api-version={self.api_version}"
56
- # Register the image generation tool
57
- self.register(self.generate_image)
60
+ if all or enable_generate_image:
61
+ tools.append(self.generate_image)
58
62
  else:
59
63
  logger.error("Missing required image generation parameters or invalid model")
60
64
 
65
+ super().__init__(name="azure_openai_tools", tools=tools)
66
+
61
67
  self.image_quality = image_quality
62
68
 
63
69
  # Validate quality
@@ -98,7 +104,7 @@ class AzureOpenAITools(Toolkit):
98
104
  n: int = 1,
99
105
  size: Optional[Literal["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]] = "1024x1024",
100
106
  style: Literal["vivid", "natural"] = "vivid",
101
- ) -> str:
107
+ ) -> ToolResult:
102
108
  """Generate an image using Azure OpenAI image generation.
103
109
 
104
110
  Args:
@@ -114,7 +120,7 @@ class AzureOpenAITools(Toolkit):
114
120
  Note: "vivid" produces more dramatic images, while "natural" produces more realistic ones.
115
121
 
116
122
  Returns:
117
- A message with image URLs or an error message
123
+ ToolResult: A ToolResult containing the generated images or error message.
118
124
 
119
125
  Note:
120
126
  Invalid parameters will be automatically corrected to valid values. For example:
@@ -125,7 +131,9 @@ class AzureOpenAITools(Toolkit):
125
131
  """
126
132
  # Check if image generation is properly initialized
127
133
  if not hasattr(self, "image_base_url"):
128
- return "Image generation tool not properly initialized. Please check your configuration."
134
+ return ToolResult(
135
+ content="Image generation tool not properly initialized. Please check your configuration."
136
+ )
129
137
 
130
138
  # Enforce valid parameters
131
139
  params = self._enforce_valid_image_parameters(
@@ -147,26 +155,36 @@ class AzureOpenAITools(Toolkit):
147
155
  response = post(self.image_base_url, headers=headers, json=params)
148
156
 
149
157
  if response.status_code != 200:
150
- return f"Error {response.status_code}: {response.text}"
158
+ return ToolResult(content=f"Error {response.status_code}: {response.text}")
151
159
 
152
160
  # Process results
153
161
  data = response.json()
154
162
  log_debug("Image generated successfully")
155
163
 
156
- # Add images to agent
164
+ # Create ImageArtifact objects for generated images
165
+ generated_images = []
157
166
  response_str = ""
167
+
158
168
  for img in data.get("data", []):
159
169
  image_url = img.get("url")
160
170
  revised_prompt = img.get("revised_prompt")
161
171
 
162
- # Add image to agent
163
- agent.add_image(
164
- ImageArtifact(id=str(uuid4()), url=image_url, original_prompt=prompt, revised_prompt=revised_prompt)
172
+ # Create ImageArtifact with URL
173
+ image_artifact = Image(
174
+ id=str(uuid4()), url=image_url, original_prompt=prompt, revised_prompt=revised_prompt
165
175
  )
176
+ generated_images.append(image_artifact)
166
177
 
167
178
  response_str += f"Image has been generated at the URL {image_url}\n"
168
- return response_str
179
+
180
+ if generated_images:
181
+ return ToolResult(
182
+ content=response_str.strip(),
183
+ images=generated_images,
184
+ )
185
+ else:
186
+ return ToolResult(content="No images were generated.")
169
187
 
170
188
  except Exception as e:
171
189
  logger.error(f"Failed to generate image: {e}")
172
- return f"Error: {e}"
190
+ return ToolResult(content=f"Error: {e}")
@@ -5,8 +5,9 @@ from typing import Any, Optional
5
5
  from uuid import uuid4
6
6
 
7
7
  from agno.agent import Agent
8
- from agno.media import ImageArtifact, VideoArtifact
8
+ from agno.media import Image, Video
9
9
  from agno.tools import Toolkit
10
+ from agno.tools.function import ToolResult
10
11
  from agno.utils.log import log_debug, log_error, log_info
11
12
 
12
13
  try:
@@ -27,9 +28,18 @@ class GeminiTools(Toolkit):
27
28
  location: Optional[str] = None,
28
29
  image_generation_model: str = "imagen-3.0-generate-002",
29
30
  video_generation_model: str = "veo-2.0-generate-001",
31
+ enable_generate_image: bool = True,
32
+ enable_generate_video: bool = True,
33
+ all: bool = False,
30
34
  **kwargs,
31
35
  ):
32
- super().__init__(name="gemini_tools", tools=[self.generate_image, self.generate_video], **kwargs)
36
+ tools = []
37
+ if all or enable_generate_image:
38
+ tools.append(self.generate_image)
39
+ if all or enable_generate_video:
40
+ tools.append(self.generate_video)
41
+
42
+ super().__init__(name="gemini_tools", tools=tools, **kwargs)
33
43
 
34
44
  # Set mode and credentials: use only provided vertexai parameter
35
45
  self.vertexai = vertexai or getenv("GOOGLE_GENAI_USE_VERTEXAI") == "true"
@@ -67,13 +77,13 @@ class GeminiTools(Toolkit):
67
77
  self,
68
78
  agent: Agent,
69
79
  prompt: str,
70
- ) -> str:
80
+ ) -> ToolResult:
71
81
  """Generate images based on a text prompt using Google Imagen.
72
82
 
73
83
  Args:
74
84
  prompt (str): The text prompt to generate the image from.
75
85
  Returns:
76
- str: A message indicating success (including media ID) or failure.
86
+ ToolResult: A ToolResult containing the generated images or error message.
77
87
  """
78
88
 
79
89
  try:
@@ -87,47 +97,55 @@ class GeminiTools(Toolkit):
87
97
  # Extract image bytes
88
98
  if response.generated_images is None or not response.generated_images:
89
99
  log_info("No images were generated.")
90
- return "Failed to generate image: No images were generated."
100
+ return ToolResult(content="Failed to generate image: No images were generated.")
91
101
 
102
+ generated_images = []
92
103
  for generated_image in response.generated_images:
93
104
  if generated_image.image is None or not generated_image.image.image_bytes:
94
105
  continue
106
+
95
107
  image_bytes = generated_image.image.image_bytes
96
- base64_encoded_image_bytes = base64.b64encode(image_bytes)
97
108
  actual_mime_type = "image/png"
98
-
99
109
  media_id = str(uuid4())
100
- agent.add_image(
101
- ImageArtifact(
102
- id=media_id,
103
- content=base64_encoded_image_bytes,
104
- original_prompt=prompt,
105
- mime_type=actual_mime_type,
106
- )
110
+
111
+ # Create ImageArtifact with raw bytes (not base64 encoded)
112
+ image_artifact = Image(
113
+ id=media_id,
114
+ content=image_bytes,
115
+ original_prompt=prompt,
116
+ mime_type=actual_mime_type,
107
117
  )
118
+ generated_images.append(image_artifact)
108
119
  log_debug(f"Successfully generated image {media_id} with model {self.image_model}")
109
- return "Image generated successfully"
120
+
121
+ if generated_images:
122
+ return ToolResult(
123
+ content="Image generated successfully",
124
+ images=generated_images,
125
+ )
126
+ else:
127
+ return ToolResult(content="Failed to generate image: No valid images were generated.")
110
128
 
111
129
  except Exception as e:
112
130
  log_error(f"Failed to generate image: Client or method not available ({e})")
113
- return f"Failed to generate image: Client or method not available ({e})"
131
+ return ToolResult(content=f"Failed to generate image: Client or method not available ({e})")
114
132
 
115
133
  def generate_video(
116
134
  self,
117
135
  agent: Agent,
118
136
  prompt: str,
119
- ) -> str:
137
+ ) -> ToolResult:
120
138
  """Generate a video based on a text prompt.
121
139
  Args:
122
140
  prompt (str): The text prompt to generate the video from.
123
141
  Returns:
124
- str: A message indicating success or failure.
142
+ ToolResult: A ToolResult containing the generated video or error message.
125
143
  """
126
144
  # Video generation requires Vertex AI mode.
127
145
  if not self.vertexai:
128
146
  log_error("Video generation requires Vertex AI mode. Please enable Vertex AI mode.")
129
- return (
130
- "Video generation requires Vertex AI mode. "
147
+ return ToolResult(
148
+ content="Video generation requires Vertex AI mode. "
131
149
  "Please set `vertexai=True` or environment variable `GOOGLE_GENAI_USE_VERTEXAI=true`."
132
150
  )
133
151
 
@@ -149,28 +167,37 @@ class GeminiTools(Toolkit):
149
167
  result = operation.result
150
168
  if result is None or result.generated_videos is None or not result.generated_videos:
151
169
  log_error("No videos were generated.")
152
- return "Failed to generate video: No videos were generated."
170
+ return ToolResult(content="Failed to generate video: No videos were generated.")
153
171
 
172
+ generated_videos = []
154
173
  for video in result.generated_videos:
155
174
  if video.video is None or not video.video.video_bytes:
156
175
  continue
176
+
157
177
  generated_video = video.video
158
178
  if generated_video.video_bytes is None:
159
179
  continue
160
180
 
161
181
  media_id = str(uuid4())
162
- encoded_video = base64.b64encode(generated_video.video_bytes).decode("utf-8")
163
-
164
- agent.add_video(
165
- VideoArtifact(
166
- id=media_id,
167
- content=encoded_video,
168
- original_prompt=prompt,
169
- mime_type=generated_video.mime_type or "video/mp4",
170
- )
182
+
183
+ # Create VideoArtifact with base64 encoded content
184
+ video_artifact = Video(
185
+ id=media_id,
186
+ content=base64.b64encode(generated_video.video_bytes).decode("utf-8"),
187
+ original_prompt=prompt,
188
+ mime_type=generated_video.mime_type or "video/mp4",
171
189
  )
190
+ generated_videos.append(video_artifact)
172
191
  log_debug(f"Successfully generated video {media_id} with model {self.video_model}")
173
- return "Video generated successfully"
192
+
193
+ if generated_videos:
194
+ return ToolResult(
195
+ content="Video generated successfully",
196
+ videos=generated_videos,
197
+ )
198
+ else:
199
+ return ToolResult(content="Failed to generate video: No valid videos were generated.")
200
+
174
201
  except Exception as e:
175
202
  log_error(f"Failed to generate video: {e}")
176
- return f"Failed to generate video: {e}"
203
+ return ToolResult(content=f"Failed to generate video: {e}")