agno 1.8.0__py3-none-any.whl → 2.0.0a1__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 (583) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +2781 -4126
  4. agno/api/agent.py +9 -65
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +6 -17
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -41
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +5 -21
  11. agno/api/schemas/evals.py +7 -16
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +5 -21
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +11 -7
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +9 -64
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/db/__init__.py +24 -0
  25. agno/db/base.py +245 -0
  26. agno/db/dynamo/__init__.py +3 -0
  27. agno/db/dynamo/dynamo.py +1749 -0
  28. agno/db/dynamo/schemas.py +278 -0
  29. agno/db/dynamo/utils.py +684 -0
  30. agno/db/firestore/__init__.py +3 -0
  31. agno/db/firestore/firestore.py +1438 -0
  32. agno/db/firestore/schemas.py +130 -0
  33. agno/db/firestore/utils.py +278 -0
  34. agno/db/gcs_json/__init__.py +3 -0
  35. agno/db/gcs_json/gcs_json_db.py +1001 -0
  36. agno/db/gcs_json/utils.py +194 -0
  37. agno/db/in_memory/__init__.py +3 -0
  38. agno/db/in_memory/in_memory_db.py +888 -0
  39. agno/db/in_memory/utils.py +172 -0
  40. agno/db/json/__init__.py +3 -0
  41. agno/db/json/json_db.py +1051 -0
  42. agno/db/json/utils.py +196 -0
  43. agno/db/migrations/v1_to_v2.py +162 -0
  44. agno/db/mongo/__init__.py +3 -0
  45. agno/db/mongo/mongo.py +1417 -0
  46. agno/db/mongo/schemas.py +77 -0
  47. agno/db/mongo/utils.py +204 -0
  48. agno/db/mysql/__init__.py +3 -0
  49. agno/db/mysql/mysql.py +1719 -0
  50. agno/db/mysql/schemas.py +124 -0
  51. agno/db/mysql/utils.py +298 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1720 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +281 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1371 -0
  58. agno/db/redis/schemas.py +109 -0
  59. agno/db/redis/utils.py +288 -0
  60. agno/db/schemas/__init__.py +3 -0
  61. agno/db/schemas/evals.py +33 -0
  62. agno/db/schemas/knowledge.py +40 -0
  63. agno/db/schemas/memory.py +46 -0
  64. agno/db/singlestore/__init__.py +3 -0
  65. agno/db/singlestore/schemas.py +116 -0
  66. agno/db/singlestore/singlestore.py +1722 -0
  67. agno/db/singlestore/utils.py +327 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1680 -0
  71. agno/db/sqlite/utils.py +269 -0
  72. agno/db/utils.py +88 -0
  73. agno/eval/__init__.py +14 -0
  74. agno/eval/accuracy.py +142 -43
  75. agno/eval/performance.py +88 -23
  76. agno/eval/reliability.py +73 -20
  77. agno/eval/utils.py +23 -13
  78. agno/integrations/discord/__init__.py +3 -0
  79. agno/{app → integrations}/discord/client.py +10 -10
  80. agno/knowledge/__init__.py +2 -2
  81. agno/{document → knowledge}/chunking/agentic.py +2 -2
  82. agno/{document → knowledge}/chunking/document.py +2 -2
  83. agno/{document → knowledge}/chunking/fixed.py +3 -3
  84. agno/{document → knowledge}/chunking/markdown.py +2 -2
  85. agno/{document → knowledge}/chunking/recursive.py +2 -2
  86. agno/{document → knowledge}/chunking/row.py +2 -2
  87. agno/knowledge/chunking/semantic.py +59 -0
  88. agno/knowledge/chunking/strategy.py +121 -0
  89. agno/knowledge/content.py +74 -0
  90. agno/knowledge/document/__init__.py +5 -0
  91. agno/{document → knowledge/document}/base.py +12 -2
  92. agno/knowledge/embedder/__init__.py +5 -0
  93. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  94. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  95. agno/{embedder → knowledge/embedder}/base.py +6 -0
  96. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  97. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  98. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  99. agno/{embedder → knowledge/embedder}/google.py +74 -1
  100. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  101. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  102. agno/knowledge/embedder/langdb.py +22 -0
  103. agno/knowledge/embedder/mistral.py +139 -0
  104. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  105. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  106. agno/knowledge/embedder/openai.py +223 -0
  107. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  108. agno/{embedder → knowledge/embedder}/together.py +1 -1
  109. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  110. agno/knowledge/knowledge.py +1515 -0
  111. agno/knowledge/reader/__init__.py +7 -0
  112. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  113. agno/knowledge/reader/base.py +88 -0
  114. agno/{document → knowledge}/reader/csv_reader.py +68 -15
  115. agno/knowledge/reader/docx_reader.py +83 -0
  116. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  117. agno/knowledge/reader/gcs_reader.py +67 -0
  118. agno/{document → knowledge}/reader/json_reader.py +30 -9
  119. agno/{document → knowledge}/reader/markdown_reader.py +36 -9
  120. agno/{document → knowledge}/reader/pdf_reader.py +79 -21
  121. agno/knowledge/reader/reader_factory.py +275 -0
  122. agno/knowledge/reader/s3_reader.py +171 -0
  123. agno/{document → knowledge}/reader/text_reader.py +31 -10
  124. agno/knowledge/reader/url_reader.py +84 -0
  125. agno/knowledge/reader/web_search_reader.py +389 -0
  126. agno/{document → knowledge}/reader/website_reader.py +37 -10
  127. agno/knowledge/reader/wikipedia_reader.py +59 -0
  128. agno/knowledge/reader/youtube_reader.py +78 -0
  129. agno/knowledge/remote_content/remote_content.py +88 -0
  130. agno/{reranker → knowledge/reranker}/base.py +1 -1
  131. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  132. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  133. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  134. agno/knowledge/types.py +30 -0
  135. agno/knowledge/utils.py +169 -0
  136. agno/media.py +2 -2
  137. agno/memory/__init__.py +2 -10
  138. agno/memory/manager.py +1003 -148
  139. agno/models/aimlapi/__init__.py +2 -2
  140. agno/models/aimlapi/aimlapi.py +6 -6
  141. agno/models/anthropic/claude.py +129 -82
  142. agno/models/aws/bedrock.py +107 -175
  143. agno/models/aws/claude.py +64 -18
  144. agno/models/azure/ai_foundry.py +73 -23
  145. agno/models/base.py +347 -287
  146. agno/models/cerebras/cerebras.py +84 -27
  147. agno/models/cohere/chat.py +106 -98
  148. agno/models/dashscope/dashscope.py +14 -5
  149. agno/models/google/gemini.py +123 -53
  150. agno/models/groq/groq.py +97 -35
  151. agno/models/huggingface/huggingface.py +92 -27
  152. agno/models/ibm/watsonx.py +72 -13
  153. agno/models/litellm/chat.py +85 -13
  154. agno/models/message.py +38 -144
  155. agno/models/meta/llama.py +85 -49
  156. agno/models/metrics.py +120 -0
  157. agno/models/mistral/mistral.py +90 -21
  158. agno/models/ollama/__init__.py +0 -2
  159. agno/models/ollama/chat.py +84 -46
  160. agno/models/openai/chat.py +135 -27
  161. agno/models/openai/responses.py +233 -115
  162. agno/models/perplexity/perplexity.py +26 -2
  163. agno/models/portkey/portkey.py +0 -7
  164. agno/models/response.py +14 -8
  165. agno/models/utils.py +20 -0
  166. agno/models/vercel/__init__.py +2 -2
  167. agno/models/vercel/v0.py +1 -1
  168. agno/models/vllm/__init__.py +2 -2
  169. agno/models/vllm/vllm.py +3 -3
  170. agno/models/xai/xai.py +10 -10
  171. agno/os/__init__.py +3 -0
  172. agno/os/app.py +393 -0
  173. agno/os/auth.py +47 -0
  174. agno/os/config.py +103 -0
  175. agno/os/interfaces/agui/__init__.py +3 -0
  176. agno/os/interfaces/agui/agui.py +31 -0
  177. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  178. agno/{app → os/interfaces}/agui/utils.py +65 -28
  179. agno/os/interfaces/base.py +21 -0
  180. agno/os/interfaces/slack/__init__.py +3 -0
  181. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  182. agno/os/interfaces/slack/slack.py +33 -0
  183. agno/os/interfaces/whatsapp/__init__.py +3 -0
  184. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  185. agno/os/interfaces/whatsapp/whatsapp.py +30 -0
  186. agno/os/router.py +843 -0
  187. agno/os/routers/__init__.py +3 -0
  188. agno/os/routers/evals/__init__.py +3 -0
  189. agno/os/routers/evals/evals.py +204 -0
  190. agno/os/routers/evals/schemas.py +142 -0
  191. agno/os/routers/evals/utils.py +161 -0
  192. agno/os/routers/knowledge/__init__.py +3 -0
  193. agno/os/routers/knowledge/knowledge.py +413 -0
  194. agno/os/routers/knowledge/schemas.py +118 -0
  195. agno/os/routers/memory/__init__.py +3 -0
  196. agno/os/routers/memory/memory.py +179 -0
  197. agno/os/routers/memory/schemas.py +58 -0
  198. agno/os/routers/metrics/__init__.py +3 -0
  199. agno/os/routers/metrics/metrics.py +58 -0
  200. agno/os/routers/metrics/schemas.py +47 -0
  201. agno/os/routers/session/__init__.py +3 -0
  202. agno/os/routers/session/session.py +163 -0
  203. agno/os/schema.py +892 -0
  204. agno/{app/playground → os}/settings.py +8 -15
  205. agno/os/utils.py +270 -0
  206. agno/reasoning/azure_ai_foundry.py +4 -4
  207. agno/reasoning/deepseek.py +4 -4
  208. agno/reasoning/default.py +6 -11
  209. agno/reasoning/groq.py +4 -4
  210. agno/reasoning/helpers.py +4 -6
  211. agno/reasoning/ollama.py +4 -4
  212. agno/reasoning/openai.py +4 -4
  213. agno/run/{response.py → agent.py} +144 -72
  214. agno/run/base.py +44 -58
  215. agno/run/cancel.py +83 -0
  216. agno/run/team.py +133 -77
  217. agno/run/workflow.py +537 -12
  218. agno/session/__init__.py +10 -0
  219. agno/session/agent.py +244 -0
  220. agno/session/summary.py +225 -0
  221. agno/session/team.py +262 -0
  222. agno/{storage/session/v2 → session}/workflow.py +47 -24
  223. agno/team/__init__.py +15 -16
  224. agno/team/team.py +2967 -4243
  225. agno/tools/agentql.py +14 -5
  226. agno/tools/airflow.py +9 -4
  227. agno/tools/api.py +7 -3
  228. agno/tools/apify.py +2 -46
  229. agno/tools/arxiv.py +8 -3
  230. agno/tools/aws_lambda.py +7 -5
  231. agno/tools/aws_ses.py +7 -1
  232. agno/tools/baidusearch.py +4 -1
  233. agno/tools/bitbucket.py +4 -4
  234. agno/tools/brandfetch.py +14 -11
  235. agno/tools/bravesearch.py +4 -1
  236. agno/tools/brightdata.py +42 -22
  237. agno/tools/browserbase.py +13 -4
  238. agno/tools/calcom.py +12 -10
  239. agno/tools/calculator.py +10 -27
  240. agno/tools/cartesia.py +18 -13
  241. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  242. agno/tools/confluence.py +71 -18
  243. agno/tools/crawl4ai.py +7 -1
  244. agno/tools/csv_toolkit.py +9 -8
  245. agno/tools/dalle.py +18 -11
  246. agno/tools/daytona.py +13 -16
  247. agno/tools/decorator.py +6 -3
  248. agno/tools/desi_vocal.py +16 -7
  249. agno/tools/discord.py +11 -8
  250. agno/tools/docker.py +30 -42
  251. agno/tools/duckdb.py +34 -53
  252. agno/tools/duckduckgo.py +8 -7
  253. agno/tools/e2b.py +62 -62
  254. agno/tools/eleven_labs.py +35 -28
  255. agno/tools/email.py +4 -1
  256. agno/tools/evm.py +7 -1
  257. agno/tools/exa.py +19 -14
  258. agno/tools/fal.py +29 -29
  259. agno/tools/file.py +9 -8
  260. agno/tools/financial_datasets.py +25 -44
  261. agno/tools/firecrawl.py +22 -22
  262. agno/tools/function.py +68 -17
  263. agno/tools/giphy.py +22 -10
  264. agno/tools/github.py +48 -126
  265. agno/tools/gmail.py +46 -62
  266. agno/tools/google_bigquery.py +7 -6
  267. agno/tools/google_maps.py +11 -26
  268. agno/tools/googlesearch.py +7 -2
  269. agno/tools/googlesheets.py +21 -17
  270. agno/tools/hackernews.py +9 -5
  271. agno/tools/jina.py +5 -4
  272. agno/tools/jira.py +18 -9
  273. agno/tools/knowledge.py +31 -32
  274. agno/tools/linear.py +18 -33
  275. agno/tools/linkup.py +5 -1
  276. agno/tools/local_file_system.py +8 -5
  277. agno/tools/lumalab.py +31 -19
  278. agno/tools/mem0.py +18 -12
  279. agno/tools/memori.py +14 -10
  280. agno/tools/mlx_transcribe.py +3 -2
  281. agno/tools/models/azure_openai.py +32 -14
  282. agno/tools/models/gemini.py +58 -31
  283. agno/tools/models/groq.py +29 -20
  284. agno/tools/models/nebius.py +27 -11
  285. agno/tools/models_labs.py +39 -15
  286. agno/tools/moviepy_video.py +7 -6
  287. agno/tools/neo4j.py +134 -0
  288. agno/tools/newspaper.py +7 -2
  289. agno/tools/newspaper4k.py +8 -3
  290. agno/tools/openai.py +57 -26
  291. agno/tools/openbb.py +12 -11
  292. agno/tools/opencv.py +62 -46
  293. agno/tools/openweather.py +14 -12
  294. agno/tools/pandas.py +11 -3
  295. agno/tools/postgres.py +4 -12
  296. agno/tools/pubmed.py +4 -1
  297. agno/tools/python.py +9 -22
  298. agno/tools/reasoning.py +35 -27
  299. agno/tools/reddit.py +11 -26
  300. agno/tools/replicate.py +54 -41
  301. agno/tools/resend.py +4 -1
  302. agno/tools/scrapegraph.py +15 -14
  303. agno/tools/searxng.py +10 -23
  304. agno/tools/serpapi.py +6 -3
  305. agno/tools/serper.py +13 -4
  306. agno/tools/shell.py +9 -2
  307. agno/tools/slack.py +12 -11
  308. agno/tools/sleep.py +3 -2
  309. agno/tools/spider.py +24 -4
  310. agno/tools/sql.py +7 -6
  311. agno/tools/tavily.py +6 -4
  312. agno/tools/telegram.py +12 -4
  313. agno/tools/todoist.py +11 -31
  314. agno/tools/toolkit.py +1 -1
  315. agno/tools/trafilatura.py +22 -6
  316. agno/tools/trello.py +9 -22
  317. agno/tools/twilio.py +10 -3
  318. agno/tools/user_control_flow.py +6 -1
  319. agno/tools/valyu.py +34 -5
  320. agno/tools/visualization.py +19 -28
  321. agno/tools/webbrowser.py +4 -3
  322. agno/tools/webex.py +11 -7
  323. agno/tools/website.py +15 -46
  324. agno/tools/webtools.py +12 -4
  325. agno/tools/whatsapp.py +5 -9
  326. agno/tools/wikipedia.py +20 -13
  327. agno/tools/x.py +14 -13
  328. agno/tools/yfinance.py +13 -40
  329. agno/tools/youtube.py +26 -20
  330. agno/tools/zendesk.py +7 -2
  331. agno/tools/zep.py +10 -7
  332. agno/tools/zoom.py +10 -9
  333. agno/utils/common.py +1 -19
  334. agno/utils/events.py +95 -118
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/location.py +2 -2
  337. agno/utils/log.py +2 -2
  338. agno/utils/mcp.py +11 -5
  339. agno/utils/media.py +39 -0
  340. agno/utils/message.py +12 -1
  341. agno/utils/models/claude.py +6 -4
  342. agno/utils/models/mistral.py +8 -7
  343. agno/utils/models/schema_utils.py +3 -3
  344. agno/utils/pprint.py +33 -32
  345. agno/utils/print_response/agent.py +779 -0
  346. agno/utils/print_response/team.py +1565 -0
  347. agno/utils/print_response/workflow.py +1451 -0
  348. agno/utils/prompts.py +14 -14
  349. agno/utils/reasoning.py +87 -0
  350. agno/utils/response.py +42 -42
  351. agno/utils/string.py +8 -22
  352. agno/utils/team.py +50 -0
  353. agno/utils/timer.py +2 -2
  354. agno/vectordb/base.py +33 -21
  355. agno/vectordb/cassandra/cassandra.py +287 -23
  356. agno/vectordb/chroma/chromadb.py +482 -59
  357. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  358. agno/vectordb/couchbase/couchbase.py +309 -29
  359. agno/vectordb/lancedb/lance_db.py +360 -21
  360. agno/vectordb/langchaindb/__init__.py +5 -0
  361. agno/vectordb/langchaindb/langchaindb.py +145 -0
  362. agno/vectordb/lightrag/__init__.py +5 -0
  363. agno/vectordb/lightrag/lightrag.py +374 -0
  364. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  365. agno/vectordb/milvus/milvus.py +242 -32
  366. agno/vectordb/mongodb/mongodb.py +200 -24
  367. agno/vectordb/pgvector/pgvector.py +319 -37
  368. agno/vectordb/pineconedb/pineconedb.py +221 -27
  369. agno/vectordb/qdrant/qdrant.py +356 -14
  370. agno/vectordb/singlestore/singlestore.py +286 -29
  371. agno/vectordb/surrealdb/surrealdb.py +187 -7
  372. agno/vectordb/upstashdb/upstashdb.py +342 -26
  373. agno/vectordb/weaviate/weaviate.py +227 -165
  374. agno/workflow/__init__.py +17 -13
  375. agno/workflow/{v2/condition.py → condition.py} +135 -32
  376. agno/workflow/{v2/loop.py → loop.py} +115 -28
  377. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  378. agno/workflow/{v2/router.py → router.py} +133 -32
  379. agno/workflow/{v2/step.py → step.py} +200 -42
  380. agno/workflow/{v2/steps.py → steps.py} +147 -66
  381. agno/workflow/types.py +482 -0
  382. agno/workflow/workflow.py +2394 -696
  383. agno-2.0.0a1.dist-info/METADATA +355 -0
  384. agno-2.0.0a1.dist-info/RECORD +514 -0
  385. agno/agent/metrics.py +0 -107
  386. agno/api/app.py +0 -35
  387. agno/api/playground.py +0 -92
  388. agno/api/schemas/app.py +0 -12
  389. agno/api/schemas/playground.py +0 -22
  390. agno/api/schemas/user.py +0 -35
  391. agno/api/schemas/workspace.py +0 -46
  392. agno/api/user.py +0 -160
  393. agno/api/workflows.py +0 -33
  394. agno/api/workspace.py +0 -175
  395. agno/app/agui/__init__.py +0 -3
  396. agno/app/agui/app.py +0 -17
  397. agno/app/agui/sync_router.py +0 -120
  398. agno/app/base.py +0 -186
  399. agno/app/discord/__init__.py +0 -3
  400. agno/app/fastapi/__init__.py +0 -3
  401. agno/app/fastapi/app.py +0 -107
  402. agno/app/fastapi/async_router.py +0 -457
  403. agno/app/fastapi/sync_router.py +0 -448
  404. agno/app/playground/app.py +0 -228
  405. agno/app/playground/async_router.py +0 -1050
  406. agno/app/playground/deploy.py +0 -249
  407. agno/app/playground/operator.py +0 -183
  408. agno/app/playground/schemas.py +0 -220
  409. agno/app/playground/serve.py +0 -55
  410. agno/app/playground/sync_router.py +0 -1042
  411. agno/app/playground/utils.py +0 -46
  412. agno/app/settings.py +0 -15
  413. agno/app/slack/__init__.py +0 -3
  414. agno/app/slack/app.py +0 -19
  415. agno/app/slack/sync_router.py +0 -92
  416. agno/app/utils.py +0 -54
  417. agno/app/whatsapp/__init__.py +0 -3
  418. agno/app/whatsapp/app.py +0 -15
  419. agno/app/whatsapp/sync_router.py +0 -197
  420. agno/cli/auth_server.py +0 -249
  421. agno/cli/config.py +0 -274
  422. agno/cli/console.py +0 -88
  423. agno/cli/credentials.py +0 -23
  424. agno/cli/entrypoint.py +0 -571
  425. agno/cli/operator.py +0 -357
  426. agno/cli/settings.py +0 -96
  427. agno/cli/ws/ws_cli.py +0 -817
  428. agno/constants.py +0 -13
  429. agno/document/__init__.py +0 -5
  430. agno/document/chunking/semantic.py +0 -45
  431. agno/document/chunking/strategy.py +0 -31
  432. agno/document/reader/__init__.py +0 -5
  433. agno/document/reader/base.py +0 -47
  434. agno/document/reader/docx_reader.py +0 -60
  435. agno/document/reader/gcs/pdf_reader.py +0 -44
  436. agno/document/reader/s3/pdf_reader.py +0 -59
  437. agno/document/reader/s3/text_reader.py +0 -63
  438. agno/document/reader/url_reader.py +0 -59
  439. agno/document/reader/youtube_reader.py +0 -58
  440. agno/embedder/__init__.py +0 -5
  441. agno/embedder/langdb.py +0 -80
  442. agno/embedder/mistral.py +0 -82
  443. agno/embedder/openai.py +0 -78
  444. agno/file/__init__.py +0 -5
  445. agno/file/file.py +0 -16
  446. agno/file/local/csv.py +0 -32
  447. agno/file/local/txt.py +0 -19
  448. agno/infra/app.py +0 -240
  449. agno/infra/base.py +0 -144
  450. agno/infra/context.py +0 -20
  451. agno/infra/db_app.py +0 -52
  452. agno/infra/resource.py +0 -205
  453. agno/infra/resources.py +0 -55
  454. agno/knowledge/agent.py +0 -698
  455. agno/knowledge/arxiv.py +0 -33
  456. agno/knowledge/combined.py +0 -36
  457. agno/knowledge/csv.py +0 -144
  458. agno/knowledge/csv_url.py +0 -124
  459. agno/knowledge/document.py +0 -223
  460. agno/knowledge/docx.py +0 -137
  461. agno/knowledge/firecrawl.py +0 -34
  462. agno/knowledge/gcs/__init__.py +0 -0
  463. agno/knowledge/gcs/base.py +0 -39
  464. agno/knowledge/gcs/pdf.py +0 -125
  465. agno/knowledge/json.py +0 -137
  466. agno/knowledge/langchain.py +0 -71
  467. agno/knowledge/light_rag.py +0 -273
  468. agno/knowledge/llamaindex.py +0 -66
  469. agno/knowledge/markdown.py +0 -154
  470. agno/knowledge/pdf.py +0 -164
  471. agno/knowledge/pdf_bytes.py +0 -42
  472. agno/knowledge/pdf_url.py +0 -148
  473. agno/knowledge/s3/__init__.py +0 -0
  474. agno/knowledge/s3/base.py +0 -64
  475. agno/knowledge/s3/pdf.py +0 -33
  476. agno/knowledge/s3/text.py +0 -34
  477. agno/knowledge/text.py +0 -141
  478. agno/knowledge/url.py +0 -46
  479. agno/knowledge/website.py +0 -179
  480. agno/knowledge/wikipedia.py +0 -32
  481. agno/knowledge/youtube.py +0 -35
  482. agno/memory/agent.py +0 -423
  483. agno/memory/classifier.py +0 -104
  484. agno/memory/db/__init__.py +0 -5
  485. agno/memory/db/base.py +0 -42
  486. agno/memory/db/mongodb.py +0 -189
  487. agno/memory/db/postgres.py +0 -203
  488. agno/memory/db/sqlite.py +0 -193
  489. agno/memory/memory.py +0 -22
  490. agno/memory/row.py +0 -36
  491. agno/memory/summarizer.py +0 -201
  492. agno/memory/summary.py +0 -19
  493. agno/memory/team.py +0 -415
  494. agno/memory/v2/__init__.py +0 -2
  495. agno/memory/v2/db/__init__.py +0 -1
  496. agno/memory/v2/db/base.py +0 -42
  497. agno/memory/v2/db/firestore.py +0 -339
  498. agno/memory/v2/db/mongodb.py +0 -196
  499. agno/memory/v2/db/postgres.py +0 -214
  500. agno/memory/v2/db/redis.py +0 -187
  501. agno/memory/v2/db/schema.py +0 -54
  502. agno/memory/v2/db/sqlite.py +0 -209
  503. agno/memory/v2/manager.py +0 -437
  504. agno/memory/v2/memory.py +0 -1097
  505. agno/memory/v2/schema.py +0 -55
  506. agno/memory/v2/summarizer.py +0 -215
  507. agno/memory/workflow.py +0 -38
  508. agno/models/ollama/tools.py +0 -430
  509. agno/models/qwen/__init__.py +0 -5
  510. agno/playground/__init__.py +0 -10
  511. agno/playground/deploy.py +0 -3
  512. agno/playground/playground.py +0 -3
  513. agno/playground/serve.py +0 -3
  514. agno/playground/settings.py +0 -3
  515. agno/reranker/__init__.py +0 -0
  516. agno/run/v2/__init__.py +0 -0
  517. agno/run/v2/workflow.py +0 -567
  518. agno/storage/__init__.py +0 -0
  519. agno/storage/agent/__init__.py +0 -0
  520. agno/storage/agent/dynamodb.py +0 -1
  521. agno/storage/agent/json.py +0 -1
  522. agno/storage/agent/mongodb.py +0 -1
  523. agno/storage/agent/postgres.py +0 -1
  524. agno/storage/agent/singlestore.py +0 -1
  525. agno/storage/agent/sqlite.py +0 -1
  526. agno/storage/agent/yaml.py +0 -1
  527. agno/storage/base.py +0 -60
  528. agno/storage/dynamodb.py +0 -673
  529. agno/storage/firestore.py +0 -297
  530. agno/storage/gcs_json.py +0 -261
  531. agno/storage/in_memory.py +0 -234
  532. agno/storage/json.py +0 -237
  533. agno/storage/mongodb.py +0 -328
  534. agno/storage/mysql.py +0 -685
  535. agno/storage/postgres.py +0 -682
  536. agno/storage/redis.py +0 -336
  537. agno/storage/session/__init__.py +0 -16
  538. agno/storage/session/agent.py +0 -64
  539. agno/storage/session/team.py +0 -63
  540. agno/storage/session/v2/__init__.py +0 -5
  541. agno/storage/session/workflow.py +0 -61
  542. agno/storage/singlestore.py +0 -606
  543. agno/storage/sqlite.py +0 -646
  544. agno/storage/workflow/__init__.py +0 -0
  545. agno/storage/workflow/mongodb.py +0 -1
  546. agno/storage/workflow/postgres.py +0 -1
  547. agno/storage/workflow/sqlite.py +0 -1
  548. agno/storage/yaml.py +0 -241
  549. agno/tools/thinking.py +0 -73
  550. agno/utils/defaults.py +0 -57
  551. agno/utils/filesystem.py +0 -39
  552. agno/utils/git.py +0 -52
  553. agno/utils/json_io.py +0 -30
  554. agno/utils/load_env.py +0 -19
  555. agno/utils/py_io.py +0 -19
  556. agno/utils/pyproject.py +0 -18
  557. agno/utils/resource_filter.py +0 -31
  558. agno/workflow/v2/__init__.py +0 -21
  559. agno/workflow/v2/types.py +0 -357
  560. agno/workflow/v2/workflow.py +0 -3312
  561. agno/workspace/__init__.py +0 -0
  562. agno/workspace/config.py +0 -325
  563. agno/workspace/enums.py +0 -6
  564. agno/workspace/helpers.py +0 -52
  565. agno/workspace/operator.py +0 -757
  566. agno/workspace/settings.py +0 -158
  567. agno-1.8.0.dist-info/METADATA +0 -979
  568. agno-1.8.0.dist-info/RECORD +0 -565
  569. agno-1.8.0.dist-info/entry_points.txt +0 -3
  570. /agno/{app → db/migrations}/__init__.py +0 -0
  571. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  572. /agno/{cli → integrations}/__init__.py +0 -0
  573. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  574. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  575. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  576. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  577. /agno/{app → os/interfaces}/slack/security.py +0 -0
  578. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  579. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  580. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  581. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
  582. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
  583. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/top_level.txt +0 -0
@@ -7,6 +7,7 @@ from requests import post
7
7
  from agno.agent import Agent
8
8
  from agno.media import ImageArtifact
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 = ImageArtifact(
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}")
@@ -7,6 +7,7 @@ from uuid import uuid4
7
7
  from agno.agent import Agent
8
8
  from agno.media import ImageArtifact, VideoArtifact
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 = ImageArtifact(
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 = VideoArtifact(
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}")
agno/tools/models/groq.py CHANGED
@@ -1,12 +1,13 @@
1
1
  import base64
2
- import os
3
2
  from os import getenv
4
- from typing import Optional
3
+ from pathlib import Path
4
+ from typing import Any, List, Optional
5
5
  from uuid import uuid4
6
6
 
7
7
  from agno.agent import Agent
8
8
  from agno.media import AudioArtifact
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
11
12
 
12
13
  try:
@@ -25,11 +26,21 @@ class GroqTools(Toolkit):
25
26
  translation_model: str = "whisper-large-v3",
26
27
  tts_model: str = "playai-tts",
27
28
  tts_voice: str = "Chip-PlayAI",
29
+ enable_transcribe_audio: bool = True,
30
+ enable_translate_audio: bool = True,
31
+ enable_generate_speech: bool = True,
32
+ all: bool = False,
28
33
  **kwargs,
29
34
  ):
30
- super().__init__(
31
- name="groq_tools", tools=[self.transcribe_audio, self.translate_audio, self.generate_speech], **kwargs
32
- )
35
+ tools: List[Any] = []
36
+ if all or enable_transcribe_audio:
37
+ tools.append(self.transcribe_audio)
38
+ if all or enable_translate_audio:
39
+ tools.append(self.translate_audio)
40
+ if all or enable_generate_speech:
41
+ tools.append(self.generate_speech)
42
+
43
+ super().__init__(name="groq_tools", tools=tools, **kwargs)
33
44
 
34
45
  self.api_key = api_key or getenv("GROQ_API_KEY")
35
46
  if not self.api_key:
@@ -52,7 +63,7 @@ class GroqTools(Toolkit):
52
63
  log_debug(f"Transcribing audio from {audio_source} using Groq model {self.transcription_model}")
53
64
  try:
54
65
  # Check if the audio source as a local file or a URL
55
- if not os.path.exists(audio_source):
66
+ if not Path(audio_source).exists():
56
67
  log_debug(f"Audio source '{audio_source}' not found locally, attempting as URL.")
57
68
  transcription_text = self.client.audio.transcriptions.create(
58
69
  url=audio_source,
@@ -63,7 +74,7 @@ class GroqTools(Toolkit):
63
74
  log_debug(f"Transcribing local file: {audio_source}")
64
75
  with open(audio_source, "rb") as audio_file:
65
76
  transcription_text = self.client.audio.transcriptions.create(
66
- file=(os.path.basename(audio_source), audio_file.read()),
77
+ file=(Path(audio_source).name, audio_file.read()),
67
78
  model=self.transcription_model,
68
79
  response_format="text",
69
80
  )
@@ -83,7 +94,7 @@ class GroqTools(Toolkit):
83
94
  """
84
95
  log_debug(f"Translating audio from {audio_source} to English using Groq model {self.translation_model}")
85
96
  try:
86
- if not os.path.exists(audio_source):
97
+ if not Path(audio_source).exists():
87
98
  log_debug(f"Audio source '{audio_source}' not found locally.")
88
99
  translation = self.client.audio.translations.create(
89
100
  url=audio_source,
@@ -94,7 +105,7 @@ class GroqTools(Toolkit):
94
105
  log_debug(f"Translating local file: {audio_source}")
95
106
  with open(audio_source, "rb") as audio_file:
96
107
  translation = self.client.audio.translations.create(
97
- file=(os.path.basename(audio_source), audio_file.read()),
108
+ file=(Path(audio_source).name, audio_file.read()),
98
109
  model=self.translation_model,
99
110
  response_format="text",
100
111
  )
@@ -109,14 +120,13 @@ class GroqTools(Toolkit):
109
120
  self,
110
121
  agent: Agent,
111
122
  text_input: str,
112
- ) -> str:
123
+ ) -> ToolResult:
113
124
  """Generate speech from text using Groq's Text-to-Speech API.
114
- Adds the generated audio as an AudioArtifact to the agent.
115
125
 
116
126
  Args:
117
127
  text_input: The text to synthesize into speech.
118
128
  Returns:
119
- str: A success message with the audio artifact ID or an error message.
129
+ ToolResult: Contains the generated audio artifact or error message.
120
130
  """
121
131
  log_debug(
122
132
  f"Generating speech for text: '{text_input[:50]}...' using Groq model {self.tts_model}, voice {self.tts_voice}"
@@ -136,16 +146,15 @@ class GroqTools(Toolkit):
136
146
  base64_encoded_audio = base64.b64encode(audio_data).decode("utf-8")
137
147
 
138
148
  media_id = str(uuid4())
139
- agent.add_audio(
140
- AudioArtifact(
141
- id=media_id,
142
- base64_audio=base64_encoded_audio,
143
- mime_type="audio/wav",
144
- )
149
+ audio_artifact = AudioArtifact(
150
+ id=media_id,
151
+ base64_audio=base64_encoded_audio,
152
+ mime_type="audio/wav",
145
153
  )
154
+
146
155
  log_debug(f"Successfully generated speech artifact with ID: {media_id}")
147
- return f"Speech generated successfully with ID: {media_id}"
156
+ return ToolResult(content=f"Speech generated successfully with ID: {media_id}", audios=[audio_artifact])
148
157
 
149
158
  except Exception as e:
150
159
  log_error(f"Failed to generate speech with Groq: {str(e)}")
151
- return f"Failed to generate speech with Groq: {str(e)}"
160
+ return ToolResult(content=f"Failed to generate speech with Groq: {str(e)}")
@@ -7,6 +7,7 @@ from agno.agent import Agent
7
7
  from agno.media import ImageArtifact
8
8
  from agno.models.nebius import Nebius
9
9
  from agno.tools import Toolkit
10
+ from agno.tools.function import ToolResult
10
11
  from agno.utils.log import log_error, log_warning
11
12
 
12
13
 
@@ -21,6 +22,8 @@ class NebiusTools(Toolkit):
21
22
  image_quality: Optional[str] = "standard",
22
23
  image_size: Optional[str] = "1024x1024",
23
24
  image_style: Optional[str] = None,
25
+ enable_generate_image: bool = True,
26
+ all: bool = False,
24
27
  **kwargs,
25
28
  ):
26
29
  """Initialize Nebius AI Studio text-to-image tools.
@@ -35,9 +38,15 @@ class NebiusTools(Toolkit):
35
38
  image_quality: Image quality. Options: "standard", "hd".
36
39
  image_size: Image size in format "WIDTHxHEIGHT". Max supported: 2000x2000.
37
40
  image_style: Optional style preset to apply.
41
+ enable_generate_image: Enable image generation functionality.
42
+ all: Enable all functions.
38
43
  **kwargs: Additional arguments to pass to Toolkit.
39
44
  """
40
- super().__init__(name="nebius_tools", tools=[self.generate_image], **kwargs)
45
+ tools = []
46
+ if all or enable_generate_image:
47
+ tools.append(self.generate_image)
48
+
49
+ super().__init__(name="nebius_tools", tools=tools, **kwargs)
41
50
 
42
51
  self.api_key = api_key or getenv("NEBIUS_API_KEY")
43
52
  if not self.api_key:
@@ -59,7 +68,7 @@ class NebiusTools(Toolkit):
59
68
  self,
60
69
  agent: Agent,
61
70
  prompt: str,
62
- ) -> str:
71
+ ) -> ToolResult:
63
72
  """Generate images based on a text prompt using Nebius AI Studio.
64
73
 
65
74
  Args:
@@ -67,7 +76,7 @@ class NebiusTools(Toolkit):
67
76
  prompt: The text prompt to generate images from.
68
77
 
69
78
  Returns:
70
- A message indicating success or failure.
79
+ ToolResult: A ToolResult containing the generated image or error message.
71
80
  """
72
81
  try:
73
82
  extra_params = {
@@ -91,18 +100,25 @@ class NebiusTools(Toolkit):
91
100
  data = response.data[0]
92
101
  if data is None:
93
102
  log_warning("Nebius API did not return any data.")
94
- return "Failed to generate image: No data received from API."
103
+ return ToolResult(content="Failed to generate image: No data received from API.")
104
+
95
105
  if hasattr(data, "b64_json") and data.b64_json:
96
106
  image_base64 = data.b64_json
97
107
  image_content_bytes = base64.b64decode(image_base64)
98
108
  media_id = str(uuid4())
99
- agent.add_image(
100
- ImageArtifact(
101
- id=media_id, content=image_content_bytes, mime_type="image/png", original_prompt=prompt
102
- )
109
+
110
+ # Create ImageArtifact with raw bytes
111
+ image_artifact = ImageArtifact(
112
+ id=media_id, content=image_content_bytes, mime_type="image/png", original_prompt=prompt
103
113
  )
104
- return "Image generated successfully."
105
- return "Failed to generate image: No content received from API."
114
+
115
+ return ToolResult(
116
+ content="Image generated successfully.",
117
+ images=[image_artifact],
118
+ )
119
+
120
+ return ToolResult(content="Failed to generate image: No content received from API.")
121
+
106
122
  except Exception as e:
107
123
  log_error(f"Failed to generate image using {self.image_model}: {e}")
108
- return f"Failed to generate image: {e}"
124
+ return ToolResult(content=f"Failed to generate image: {e}")
agno/tools/models_labs.py CHANGED
@@ -9,6 +9,7 @@ from agno.media import AudioArtifact, ImageArtifact, VideoArtifact
9
9
  from agno.models.response import FileType
10
10
  from agno.team import Team
11
11
  from agno.tools import Toolkit
12
+ from agno.tools.function import ToolResult
12
13
  from agno.utils.log import log_debug, log_info, logger
13
14
 
14
15
  try:
@@ -86,16 +87,25 @@ class ModelsLabTools(Toolkit):
86
87
 
87
88
  return base_payload
88
89
 
89
- def _add_media_artifact(
90
- self, agent: Union[Agent, Team], media_id: str, media_url: str, eta: Optional[str] = None
91
- ) -> None:
92
- """Add appropriate media artifact based on file type."""
90
+ def _create_media_artifacts(self, media_id: str, media_url: str, eta: Optional[str] = None) -> Dict[str, List]:
91
+ """Create appropriate media artifacts based on file type."""
92
+ artifacts: Dict[str, List[Union[ImageArtifact, VideoArtifact, AudioArtifact]]] = {
93
+ "images": [],
94
+ "videos": [],
95
+ "audios": [],
96
+ }
97
+
93
98
  if self.file_type == FileType.MP4:
94
- agent.add_video(VideoArtifact(id=str(media_id), url=media_url, eta=str(eta)))
99
+ video_artifact = VideoArtifact(id=str(media_id), url=media_url, eta=str(eta))
100
+ artifacts["videos"].append(video_artifact)
95
101
  elif self.file_type == FileType.GIF:
96
- agent.add_image(ImageArtifact(id=str(media_id), url=media_url))
102
+ image_artifact = ImageArtifact(id=str(media_id), url=media_url)
103
+ artifacts["images"].append(image_artifact)
97
104
  elif self.file_type == FileType.MP3:
98
- agent.add_audio(AudioArtifact(id=str(media_id), url=media_url))
105
+ audio_artifact = AudioArtifact(id=str(media_id), url=media_url)
106
+ artifacts["audios"].append(audio_artifact)
107
+
108
+ return artifacts
99
109
 
100
110
  def _wait_for_media(self, media_id: str, eta: int) -> bool:
101
111
  """Wait for media generation to complete."""
@@ -121,10 +131,10 @@ class ModelsLabTools(Toolkit):
121
131
 
122
132
  return False
123
133
 
124
- def generate_media(self, agent: Union[Agent, Team], prompt: str) -> str:
134
+ def generate_media(self, agent: Union[Agent, Team], prompt: str) -> ToolResult:
125
135
  """Generate media (video, image, or audio) given a prompt."""
126
136
  if not self.api_key:
127
- return "Please set the MODELS_LAB_API_KEY"
137
+ return ToolResult(content="Please set the MODELS_LAB_API_KEY")
128
138
 
129
139
  try:
130
140
  payload = json.dumps(self._create_payload(prompt))
@@ -139,19 +149,27 @@ class ModelsLabTools(Toolkit):
139
149
  status = result.get("status")
140
150
  if status == "error":
141
151
  logger.error(f"Error in response: {result.get('message')}")
142
- return f"Error: {result.get('message')}"
152
+ return ToolResult(content=f"Error: {result.get('message')}")
143
153
 
144
154
  if "error" in result:
145
155
  error_msg = f"Failed to generate {self.file_type.value}: {result['error']}"
146
156
  logger.error(error_msg)
147
- return f"Error: {result['error']}"
157
+ return ToolResult(content=f"Error: {result['error']}")
148
158
 
149
159
  eta = result.get("eta")
150
160
  url_links = result.get("future_links")
151
161
  media_id = str(uuid4())
152
162
 
163
+ # Collect all media artifacts
164
+ all_images = []
165
+ all_videos = []
166
+ all_audios = []
167
+
153
168
  for media_url in url_links:
154
- self._add_media_artifact(agent, media_id, media_url, str(eta))
169
+ artifacts = self._create_media_artifacts(media_id, media_url, str(eta))
170
+ all_images.extend(artifacts["images"])
171
+ all_videos.extend(artifacts["videos"])
172
+ all_audios.extend(artifacts["audios"])
155
173
 
156
174
  if self.wait_for_completion and isinstance(eta, int):
157
175
  if self._wait_for_media(media_id, eta):
@@ -159,13 +177,19 @@ class ModelsLabTools(Toolkit):
159
177
  else:
160
178
  logger.warning("Media generation timed out")
161
179
 
162
- return f"{self.file_type.value.capitalize()} has been generated successfully and will be ready in {eta} seconds"
180
+ # Return ToolResult with appropriate media artifacts
181
+ return ToolResult(
182
+ content=f"{self.file_type.value.capitalize()} has been generated successfully and will be ready in {eta} seconds",
183
+ images=all_images if all_images else None,
184
+ videos=all_videos if all_videos else None,
185
+ audios=all_audios if all_audios else None,
186
+ )
163
187
 
164
188
  except RequestException as e:
165
189
  error_msg = f"Network error while generating {self.file_type.value}: {e}"
166
190
  logger.error(error_msg)
167
- return f"Error: {error_msg}"
191
+ return ToolResult(content=f"Error: {error_msg}")
168
192
  except Exception as e:
169
193
  error_msg = f"Unexpected error while generating {self.file_type.value}: {e}"
170
194
  logger.error(error_msg)
171
- return f"Error: {error_msg}"
195
+ return ToolResult(content=f"Error: {error_msg}")
@@ -14,17 +14,18 @@ class MoviePyVideoTools(Toolkit):
14
14
 
15
15
  def __init__(
16
16
  self,
17
- process_video: bool = True,
18
- generate_captions: bool = True,
19
- embed_captions: bool = True,
17
+ enable_process_video: bool = True,
18
+ enable_generate_captions: bool = True,
19
+ enable_embed_captions: bool = True,
20
+ all: bool = False,
20
21
  **kwargs,
21
22
  ):
22
23
  tools: List[Any] = []
23
- if process_video:
24
+ if enable_process_video or all:
24
25
  tools.append(self.extract_audio)
25
- if generate_captions:
26
+ if enable_generate_captions or all:
26
27
  tools.append(self.create_srt)
27
- if embed_captions:
28
+ if enable_embed_captions or all:
28
29
  tools.append(self.embed_captions)
29
30
 
30
31
  super().__init__(name="video_tools", tools=tools, **kwargs)