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/function.py CHANGED
@@ -1,13 +1,14 @@
1
1
  from dataclasses import dataclass
2
2
  from functools import partial
3
3
  from importlib.metadata import version
4
- from typing import Any, Callable, Dict, List, Literal, Optional, Type, TypeVar, get_type_hints
4
+ from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Type, TypeVar, get_type_hints
5
5
 
6
6
  from docstring_parser import parse
7
7
  from packaging.version import Version
8
8
  from pydantic import BaseModel, Field, validate_call
9
9
 
10
10
  from agno.exceptions import AgentRunException
11
+ from agno.media import Audio, File, Image, Video
11
12
  from agno.utils.log import log_debug, log_error, log_exception, log_warning
12
13
 
13
14
  T = TypeVar("T")
@@ -84,8 +85,6 @@ class Function(BaseModel):
84
85
  entrypoint: Optional[Callable] = None
85
86
  # If True, the entrypoint processing is skipped and the Function is used as is.
86
87
  skip_entrypoint_processing: bool = False
87
- # If True, the arguments are sanitized before being passed to the function. (Deprecated)
88
- sanitize_arguments: bool = False
89
88
  # If True, the function call will show the result along with sending it to the model.
90
89
  show_result: bool = False
91
90
  # If True, the agent will stop after the function call.
@@ -123,6 +122,14 @@ class Function(BaseModel):
123
122
  _agent: Optional[Any] = None
124
123
  # The team that the function is associated with
125
124
  _team: Optional[Any] = None
125
+ # The session state that the function is associated with
126
+ _session_state: Optional[Dict[str, Any]] = None
127
+
128
+ # Media context that the function is associated with
129
+ _images: Optional[Sequence[Image]] = None
130
+ _videos: Optional[Sequence[Video]] = None
131
+ _audios: Optional[Sequence[Audio]] = None
132
+ _files: Optional[Sequence[File]] = None
126
133
 
127
134
  def to_dict(self) -> Dict[str, Any]:
128
135
  return self.model_dump(
@@ -143,17 +150,29 @@ class Function(BaseModel):
143
150
  type_hints = get_type_hints(c)
144
151
 
145
152
  # If function has an the agent argument, remove the agent parameter from the type hints
146
- if "agent" in sig.parameters:
153
+ if "agent" in sig.parameters and "agent" in type_hints:
147
154
  del type_hints["agent"]
148
- if "team" in sig.parameters:
155
+ if "team" in sig.parameters and "team" in type_hints:
149
156
  del type_hints["team"]
157
+ if "session_state" in sig.parameters and "session_state" in type_hints:
158
+ del type_hints["session_state"]
159
+ # Remove media parameters from type hints as they are injected automatically
160
+ if "images" in sig.parameters and "images" in type_hints:
161
+ del type_hints["images"]
162
+ if "videos" in sig.parameters and "videos" in type_hints:
163
+ del type_hints["videos"]
164
+ if "audios" in sig.parameters and "audios" in type_hints:
165
+ del type_hints["audios"]
166
+ if "files" in sig.parameters and "files" in type_hints:
167
+ del type_hints["files"]
150
168
  # log_info(f"Type hints for {function_name}: {type_hints}")
151
169
 
152
170
  # Filter out return type and only process parameters
153
171
  param_type_hints = {
154
172
  name: type_hints.get(name)
155
173
  for name in sig.parameters
156
- if name != "return" and name not in ["agent", "team", "self"]
174
+ if name != "return"
175
+ and name not in ["agent", "team", "session_state", "self", "images", "videos", "audios", "files"]
157
176
  }
158
177
 
159
178
  # Parse docstring for parameters
@@ -180,14 +199,17 @@ class Function(BaseModel):
180
199
  # See: https://platform.openai.com/docs/guides/structured-outputs/supported-schemas#all-fields-must-be-required
181
200
  if strict:
182
201
  parameters["required"] = [
183
- name for name in parameters["properties"] if name not in ["agent", "team", "self"]
202
+ name
203
+ for name in parameters["properties"]
204
+ if name not in ["agent", "team", "session_state", "self", "images", "videos", "audios", "files"]
184
205
  ]
185
206
  else:
186
207
  # Mark a field as required if it has no default value (this would include optional fields)
187
208
  parameters["required"] = [
188
209
  name
189
210
  for name, param in sig.parameters.items()
190
- if param.default == param.empty and name != "self" and name not in ["agent", "team"]
211
+ if param.default == param.empty
212
+ and name not in ["agent", "team", "session_state", "self", "images", "videos", "audios", "files"]
191
213
  ]
192
214
 
193
215
  # log_debug(f"JSON schema for {function_name}: {parameters}")
@@ -232,14 +254,34 @@ class Function(BaseModel):
232
254
  type_hints = get_type_hints(self.entrypoint)
233
255
 
234
256
  # If function has an the agent argument, remove the agent parameter from the type hints
235
- if "agent" in sig.parameters:
257
+ if "agent" in sig.parameters and "agent" in type_hints:
236
258
  del type_hints["agent"]
237
- if "team" in sig.parameters:
259
+ if "team" in sig.parameters and "team" in type_hints:
238
260
  del type_hints["team"]
261
+ if "session_state" in sig.parameters and "session_state" in type_hints:
262
+ del type_hints["session_state"]
263
+ if "images" in sig.parameters and "images" in type_hints:
264
+ del type_hints["images"]
265
+ if "videos" in sig.parameters and "videos" in type_hints:
266
+ del type_hints["videos"]
267
+ if "audios" in sig.parameters and "audios" in type_hints:
268
+ del type_hints["audios"]
269
+ if "files" in sig.parameters and "files" in type_hints:
270
+ del type_hints["files"]
239
271
  # log_info(f"Type hints for {self.name}: {type_hints}")
240
272
 
241
273
  # Filter out return type and only process parameters
242
- excluded_params = ["return", "agent", "team", "self"]
274
+ excluded_params = [
275
+ "return",
276
+ "agent",
277
+ "team",
278
+ "session_state",
279
+ "self",
280
+ "images",
281
+ "videos",
282
+ "audios",
283
+ "files",
284
+ ]
243
285
  if self.requires_user_input and self.user_input_fields:
244
286
  if len(self.user_input_fields) == 0:
245
287
  excluded_params.extend(list(type_hints.keys()))
@@ -352,7 +394,9 @@ class Function(BaseModel):
352
394
  def process_schema_for_strict(self):
353
395
  self.parameters["additionalProperties"] = False
354
396
  self.parameters["required"] = [
355
- name for name in self.parameters["properties"] if name not in ["agent", "team", "self"]
397
+ name
398
+ for name in self.parameters["properties"]
399
+ if name not in ["agent", "team", "session_state", "images", "videos", "audios", "files", "self"]
356
400
  ]
357
401
 
358
402
  def _get_cache_key(self, entrypoint_args: Dict[str, Any], call_args: Optional[Dict[str, Any]] = None) -> str:
@@ -365,6 +409,16 @@ class Function(BaseModel):
365
409
  del copy_entrypoint_args["agent"]
366
410
  if "team" in copy_entrypoint_args:
367
411
  del copy_entrypoint_args["team"]
412
+ if "session_state" in copy_entrypoint_args:
413
+ del copy_entrypoint_args["session_state"]
414
+ if "images" in copy_entrypoint_args:
415
+ del copy_entrypoint_args["images"]
416
+ if "videos" in copy_entrypoint_args:
417
+ del copy_entrypoint_args["videos"]
418
+ if "audios" in copy_entrypoint_args:
419
+ del copy_entrypoint_args["audios"]
420
+ if "files" in copy_entrypoint_args:
421
+ del copy_entrypoint_args["files"]
368
422
  args_str = str(copy_entrypoint_args)
369
423
 
370
424
  kwargs_str = str(sorted((call_args or {}).items()))
@@ -425,6 +479,13 @@ class FunctionExecutionResult(BaseModel):
425
479
  result: Optional[Any] = None
426
480
  error: Optional[str] = None
427
481
 
482
+ updated_session_state: Optional[Dict[str, Any]] = None
483
+
484
+ # New fields for media artifacts
485
+ images: Optional[List[Image]] = None
486
+ videos: Optional[List[Video]] = None
487
+ audios: Optional[List[Audio]] = None
488
+
428
489
 
429
490
  class FunctionCall(BaseModel):
430
491
  """Model for Function Calls"""
@@ -480,6 +541,9 @@ class FunctionCall(BaseModel):
480
541
  # Check if the pre-hook has an team argument
481
542
  if "team" in signature(self.function.pre_hook).parameters:
482
543
  pre_hook_args["team"] = self.function._team
544
+ # Check if the pre-hook has an session_state argument
545
+ if "session_state" in signature(self.function.pre_hook).parameters:
546
+ pre_hook_args["session_state"] = self.function._session_state
483
547
  # Check if the pre-hook has an fc argument
484
548
  if "fc" in signature(self.function.pre_hook).parameters:
485
549
  pre_hook_args["fc"] = self
@@ -505,6 +569,9 @@ class FunctionCall(BaseModel):
505
569
  # Check if the post-hook has an team argument
506
570
  if "team" in signature(self.function.post_hook).parameters:
507
571
  post_hook_args["team"] = self.function._team
572
+ # Check if the post-hook has an session_state argument
573
+ if "session_state" in signature(self.function.post_hook).parameters:
574
+ post_hook_args["session_state"] = self.function._session_state
508
575
  # Check if the post-hook has an fc argument
509
576
  if "fc" in signature(self.function.post_hook).parameters:
510
577
  post_hook_args["fc"] = self
@@ -528,9 +595,23 @@ class FunctionCall(BaseModel):
528
595
  # Check if the entrypoint has an team argument
529
596
  if "team" in signature(self.function.entrypoint).parameters: # type: ignore
530
597
  entrypoint_args["team"] = self.function._team
598
+ # Check if the entrypoint has an session_state argument
599
+ if "session_state" in signature(self.function.entrypoint).parameters: # type: ignore
600
+ entrypoint_args["session_state"] = self.function._session_state
531
601
  # Check if the entrypoint has an fc argument
532
602
  if "fc" in signature(self.function.entrypoint).parameters: # type: ignore
533
603
  entrypoint_args["fc"] = self
604
+
605
+ # Check if the entrypoint has media arguments
606
+ if "images" in signature(self.function.entrypoint).parameters: # type: ignore
607
+ entrypoint_args["images"] = self.function._images
608
+ if "videos" in signature(self.function.entrypoint).parameters: # type: ignore
609
+ entrypoint_args["videos"] = self.function._videos
610
+ if "audios" in signature(self.function.entrypoint).parameters: # type: ignore
611
+ entrypoint_args["audios"] = self.function._audios
612
+ if "files" in signature(self.function.entrypoint).parameters: # type: ignore
613
+ entrypoint_args["files"] = self.function._files
614
+
534
615
  return entrypoint_args
535
616
 
536
617
  def _build_hook_args(self, hook: Callable, name: str, func: Callable, args: Dict[str, Any]) -> Dict[str, Any]:
@@ -544,6 +625,9 @@ class FunctionCall(BaseModel):
544
625
  # Check if the hook has an team argument
545
626
  if "team" in signature(hook).parameters:
546
627
  hook_args["team"] = self.function._team
628
+ # Check if the hook has an session_state argument
629
+ if "session_state" in signature(hook).parameters:
630
+ hook_args["session_state"] = self.function._session_state
547
631
 
548
632
  if "name" in signature(hook).parameters:
549
633
  hook_args["name"] = name
@@ -641,10 +725,11 @@ class FunctionCall(BaseModel):
641
725
  execution_chain = self._build_nested_execution_chain(entrypoint_args=entrypoint_args)
642
726
  result = execution_chain(self.function.name, self.function.entrypoint, self.arguments or {})
643
727
  else:
644
- arguments = entrypoint_args
645
- if self.arguments is not None:
646
- arguments.update(self.arguments)
647
- result = self.function.entrypoint(**arguments)
728
+ result = self.function.entrypoint(**entrypoint_args, **self.arguments) # type: ignore
729
+
730
+ updated_session_state = None
731
+ if entrypoint_args.get("session_state") is not None:
732
+ updated_session_state = entrypoint_args.get("session_state")
648
733
 
649
734
  # Handle generator case
650
735
  if isgenerator(result):
@@ -670,7 +755,9 @@ class FunctionCall(BaseModel):
670
755
  # Execute post-hook if it exists
671
756
  self._handle_post_hook()
672
757
 
673
- return FunctionExecutionResult(status="success", result=self.result)
758
+ return FunctionExecutionResult(
759
+ status="success", result=self.result, updated_session_state=updated_session_state
760
+ )
674
761
 
675
762
  async def _handle_pre_hook_async(self):
676
763
  """Handles the async pre-hook for the function call."""
@@ -685,6 +772,9 @@ class FunctionCall(BaseModel):
685
772
  # Check if the pre-hook has an team argument
686
773
  if "team" in signature(self.function.pre_hook).parameters:
687
774
  pre_hook_args["team"] = self.function._team
775
+ # Check if the pre-hook has an session_state argument
776
+ if "session_state" in signature(self.function.pre_hook).parameters:
777
+ pre_hook_args["session_state"] = self.function._session_state
688
778
  # Check if the pre-hook has an fc argument
689
779
  if "fc" in signature(self.function.pre_hook).parameters:
690
780
  pre_hook_args["fc"] = self
@@ -711,6 +801,10 @@ class FunctionCall(BaseModel):
711
801
  # Check if the post-hook has an team argument
712
802
  if "team" in signature(self.function.post_hook).parameters:
713
803
  post_hook_args["team"] = self.function._team
804
+ # Check if the post-hook has an session_state argument
805
+ if "session_state" in signature(self.function.post_hook).parameters:
806
+ post_hook_args["session_state"] = self.function._session_state
807
+
714
808
  # Check if the post-hook has an fc argument
715
809
  if "fc" in signature(self.function.post_hook).parameters:
716
810
  post_hook_args["fc"] = self
@@ -839,6 +933,10 @@ class FunctionCall(BaseModel):
839
933
  cache_file = self.function._get_cache_file_path(cache_key)
840
934
  self.function._save_to_cache(cache_file, self.result)
841
935
 
936
+ updated_session_state = None
937
+ if entrypoint_args.get("session_state") is not None:
938
+ updated_session_state = entrypoint_args.get("session_state")
939
+
842
940
  except AgentRunException as e:
843
941
  log_debug(f"{e.__class__.__name__}: {e}")
844
942
  self.error = str(e)
@@ -855,4 +953,15 @@ class FunctionCall(BaseModel):
855
953
  else:
856
954
  self._handle_post_hook()
857
955
 
858
- return FunctionExecutionResult(status="success", result=self.result)
956
+ return FunctionExecutionResult(
957
+ status="success", result=self.result, updated_session_state=updated_session_state
958
+ )
959
+
960
+
961
+ class ToolResult(BaseModel):
962
+ """Result from a tool that can include media artifacts."""
963
+
964
+ content: str
965
+ images: Optional[List[Image]] = None
966
+ videos: Optional[List[Video]] = None
967
+ audios: Optional[List[Audio]] = None
agno/tools/giphy.py CHANGED
@@ -1,13 +1,14 @@
1
- import os
2
1
  import uuid
2
+ from os import getenv
3
3
  from typing import Any, List, Optional, Union
4
4
 
5
5
  import httpx
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.team.team import Team
10
10
  from agno.tools import Toolkit
11
+ from agno.tools.function import ToolResult
11
12
  from agno.utils.log import logger
12
13
 
13
14
 
@@ -16,6 +17,8 @@ class GiphyTools(Toolkit):
16
17
  self,
17
18
  api_key: Optional[str] = None,
18
19
  limit: int = 1,
20
+ enable_search_gifs: bool = True,
21
+ all: bool = False,
19
22
  **kwargs,
20
23
  ):
21
24
  """Initialize Giphy tools.
@@ -23,27 +26,29 @@ class GiphyTools(Toolkit):
23
26
  Args:
24
27
  api_key: Giphy API key. Defaults to GIPHY_API_KEY environment variable.
25
28
  limit: Number of GIFs to return. Defaults to 1.
26
- search_gifs: Whether to enable GIF search functionality. Defaults to True.
29
+ enable_search_gifs: Whether to enable GIF search functionality. Defaults to True.
30
+ all: Enable all functions. Defaults to False.
27
31
  """
28
- self.api_key = api_key or os.getenv("GIPHY_API_KEY")
32
+ self.api_key = api_key or getenv("GIPHY_API_KEY")
29
33
  if not self.api_key:
30
34
  logger.error("No Giphy API key provided")
31
35
 
32
36
  self.limit: int = limit
33
37
 
34
38
  tools: List[Any] = []
35
- tools.append(self.search_gifs)
39
+ if all or enable_search_gifs:
40
+ tools.append(self.search_gifs)
36
41
 
37
42
  super().__init__(name="giphy_tools", tools=tools, **kwargs)
38
43
 
39
- def search_gifs(self, agent: Union[Agent, Team], query: str) -> str:
44
+ def search_gifs(self, agent: Union[Agent, Team], query: str) -> ToolResult:
40
45
  """Find a GIPHY gif
41
46
 
42
47
  Args:
43
48
  query (str): A text description of the required gif.
44
49
 
45
50
  Returns:
46
- result (str): A string containing urls of GIFs found
51
+ ToolResult: Contains the found GIF images or error message.
47
52
  """
48
53
 
49
54
  base_url = "https://api.giphy.com/v1/gifs/search"
@@ -60,6 +65,8 @@ class GiphyTools(Toolkit):
60
65
  # Extract the GIF URLs
61
66
  data = response.json()
62
67
  gif_urls = []
68
+ image_artifacts = []
69
+
63
70
  for gif in data.get("data", []):
64
71
  images = gif.get("images", {})
65
72
  original_image = images["original"]
@@ -69,13 +76,18 @@ class GiphyTools(Toolkit):
69
76
  alt_text = gif["alt_text"]
70
77
  gif_urls.append(gif_url)
71
78
 
72
- agent.add_image(ImageArtifact(id=media_id, url=gif_url, alt_text=alt_text, revised_prompt=query))
79
+ # Create ImageArtifact for the GIF
80
+ image_artifact = Image(id=media_id, url=gif_url, alt_text=alt_text, revised_prompt=query)
81
+ image_artifacts.append(image_artifact)
73
82
 
74
- return f"These are the found gifs {gif_urls}"
83
+ if image_artifacts:
84
+ return ToolResult(content=f"Found {len(gif_urls)} GIF(s): {gif_urls}", images=image_artifacts)
85
+ else:
86
+ return ToolResult(content="No gifs found")
75
87
 
76
88
  except httpx.HTTPStatusError as e:
77
89
  logger.error(f"HTTP error occurred: {e.response.status_code} - {e.response.text}")
90
+ return ToolResult(content=f"HTTP error occurred: {e.response.status_code}")
78
91
  except Exception as e:
79
92
  logger.error(f"An error occurred: {e}")
80
-
81
- return "No gifs found"
93
+ return ToolResult(content=f"An error occurred: {e}")
agno/tools/github.py CHANGED
@@ -7,7 +7,6 @@ from agno.utils.log import log_debug, logger
7
7
 
8
8
  try:
9
9
  from github import Auth, Github, GithubException
10
- from github.GithubObject import NotSet
11
10
 
12
11
  except ImportError:
13
12
  raise ImportError("`PyGithub` not installed. Please install using `pip install pygithub`")
@@ -18,45 +17,6 @@ class GithubTools(Toolkit):
18
17
  self,
19
18
  access_token: Optional[str] = None,
20
19
  base_url: Optional[str] = None,
21
- search_repositories: bool = True,
22
- list_repositories: bool = False,
23
- get_repository: bool = False,
24
- get_pull_request: bool = False,
25
- get_pull_request_changes: bool = False,
26
- create_issue: bool = False,
27
- create_repository: bool = False,
28
- delete_repository: bool = False,
29
- get_repository_languages: bool = False,
30
- list_branches: bool = False,
31
- get_pull_request_count: bool = False,
32
- get_repository_stars: bool = False,
33
- get_pull_requests: bool = False,
34
- get_pull_request_comments: bool = False,
35
- create_pull_request_comment: bool = False,
36
- edit_pull_request_comment: bool = False,
37
- get_pull_request_with_details: bool = False,
38
- get_repository_with_stats: bool = False,
39
- list_issues: bool = False,
40
- get_issue: bool = False,
41
- comment_on_issue: bool = False,
42
- close_issue: bool = False,
43
- reopen_issue: bool = False,
44
- assign_issue: bool = False,
45
- label_issue: bool = False,
46
- list_issue_comments: bool = False,
47
- edit_issue: bool = False,
48
- create_pull_request: bool = False,
49
- create_file: bool = False,
50
- get_file_content: bool = False,
51
- update_file: bool = True,
52
- delete_file: bool = False,
53
- get_directory_content: bool = False,
54
- get_branch_content: bool = False,
55
- create_branch: bool = False,
56
- set_default_branch: bool = False,
57
- search_code: bool = False,
58
- search_issues_and_prs: bool = False,
59
- create_review_request: bool = False,
60
20
  **kwargs,
61
21
  ):
62
22
  self.access_token = access_token or getenv("GITHUB_ACCESS_TOKEN")
@@ -64,85 +24,47 @@ class GithubTools(Toolkit):
64
24
 
65
25
  self.g = self.authenticate()
66
26
 
67
- tools: List[Any] = []
68
- if search_repositories:
69
- tools.append(self.search_repositories)
70
- if list_repositories:
71
- tools.append(self.list_repositories)
72
- if get_repository:
73
- tools.append(self.get_repository)
74
- if get_pull_request:
75
- tools.append(self.get_pull_request)
76
- if get_pull_request_changes:
77
- tools.append(self.get_pull_request_changes)
78
- if create_issue:
79
- tools.append(self.create_issue)
80
- if create_repository:
81
- tools.append(self.create_repository)
82
- if delete_repository:
83
- tools.append(self.delete_repository)
84
- if list_branches:
85
- tools.append(self.list_branches)
86
- if get_repository_languages:
87
- tools.append(self.get_repository_languages)
88
- if get_pull_request_count:
89
- tools.append(self.get_pull_request_count)
90
- if get_repository_stars:
91
- tools.append(self.get_repository_stars)
92
- if get_pull_requests:
93
- tools.append(self.get_pull_requests)
94
- if get_pull_request_comments:
95
- tools.append(self.get_pull_request_comments)
96
- if create_pull_request_comment:
97
- tools.append(self.create_pull_request_comment)
98
- if edit_pull_request_comment:
99
- tools.append(self.edit_pull_request_comment)
100
- if get_pull_request_with_details:
101
- tools.append(self.get_pull_request_with_details)
102
- if get_repository_with_stats:
103
- tools.append(self.get_repository_with_stats)
104
- if list_issues:
105
- tools.append(self.list_issues)
106
- if get_issue:
107
- tools.append(self.get_issue)
108
- if comment_on_issue:
109
- tools.append(self.comment_on_issue)
110
- if close_issue:
111
- tools.append(self.close_issue)
112
- if reopen_issue:
113
- tools.append(self.reopen_issue)
114
- if assign_issue:
115
- tools.append(self.assign_issue)
116
- if label_issue:
117
- tools.append(self.label_issue)
118
- if list_issue_comments:
119
- tools.append(self.list_issue_comments)
120
- if edit_issue:
121
- tools.append(self.edit_issue)
122
- if create_pull_request:
123
- tools.append(self.create_pull_request)
124
- if create_file:
125
- tools.append(self.create_file)
126
- if get_file_content:
127
- tools.append(self.get_file_content)
128
- if update_file:
129
- tools.append(self.update_file)
130
- if delete_file:
131
- tools.append(self.delete_file)
132
- if get_directory_content:
133
- tools.append(self.get_directory_content)
134
- if get_branch_content:
135
- tools.append(self.get_branch_content)
136
- if create_branch:
137
- tools.append(self.create_branch)
138
- if set_default_branch:
139
- tools.append(self.set_default_branch)
140
- if search_code:
141
- tools.append(self.search_code)
142
- if search_issues_and_prs:
143
- tools.append(self.search_issues_and_prs)
144
- if create_review_request:
145
- tools.append(self.create_review_request)
27
+ tools: List[Any] = [
28
+ self.search_repositories,
29
+ self.list_repositories,
30
+ self.get_repository,
31
+ self.get_pull_request,
32
+ self.get_pull_request_changes,
33
+ self.create_issue,
34
+ self.create_repository,
35
+ self.delete_repository,
36
+ self.list_branches,
37
+ self.get_repository_languages,
38
+ self.get_pull_request_count,
39
+ self.get_repository_stars,
40
+ self.get_pull_requests,
41
+ self.get_pull_request_comments,
42
+ self.create_pull_request_comment,
43
+ self.edit_pull_request_comment,
44
+ self.get_pull_request_with_details,
45
+ self.get_repository_with_stats,
46
+ self.list_issues,
47
+ self.get_issue,
48
+ self.comment_on_issue,
49
+ self.close_issue,
50
+ self.reopen_issue,
51
+ self.assign_issue,
52
+ self.label_issue,
53
+ self.list_issue_comments,
54
+ self.edit_issue,
55
+ self.create_pull_request,
56
+ self.create_file,
57
+ self.get_file_content,
58
+ self.update_file,
59
+ self.delete_file,
60
+ self.get_directory_content,
61
+ self.get_branch_content,
62
+ self.create_branch,
63
+ self.set_default_branch,
64
+ self.search_code,
65
+ self.search_issues_and_prs,
66
+ self.create_review_request,
67
+ ]
146
68
 
147
69
  super().__init__(name="github", tools=tools, **kwargs)
148
70
 
@@ -428,7 +350,7 @@ class GithubTools(Toolkit):
428
350
  logger.error(f"Error getting pull request changes: {e}")
429
351
  return json.dumps({"error": str(e)})
430
352
 
431
- def create_issue(self, repo_name: str, title: str, body: Optional[str] = NotSet) -> str:
353
+ def create_issue(self, repo_name: str, title: str, body: Optional[str] = None) -> str:
432
354
  """Create an issue in a repository.
433
355
 
434
356
  Args:
@@ -442,7 +364,7 @@ class GithubTools(Toolkit):
442
364
  log_debug(f"Creating issue in repository: {repo_name}")
443
365
  try:
444
366
  repo = self.g.get_repo(repo_name)
445
- issue = repo.create_issue(title=title, body=body)
367
+ issue = repo.create_issue(title=title, body=body) # type: ignore
446
368
  issue_info = {
447
369
  "id": issue.id,
448
370
  "number": issue.number,
@@ -697,8 +619,8 @@ class GithubTools(Toolkit):
697
619
  self,
698
620
  repo_name: str,
699
621
  issue_number: int,
700
- title: Optional[str] = NotSet,
701
- body: Optional[str] = NotSet,
622
+ title: Optional[str] = None,
623
+ body: Optional[str] = None,
702
624
  ) -> str:
703
625
  """Edit the title or body of an issue.
704
626
 
@@ -715,7 +637,7 @@ class GithubTools(Toolkit):
715
637
  try:
716
638
  repo = self.g.get_repo(repo_name)
717
639
  issue = repo.get_issue(number=issue_number)
718
- issue.edit(title=title, body=body)
640
+ issue.edit(title=title, body=body) # type: ignore
719
641
  return json.dumps({"message": f"Issue #{issue_number} updated."}, indent=2)
720
642
  except GithubException as e:
721
643
  logger.error(f"Error editing issue: {e}")
@@ -1324,7 +1246,7 @@ class GithubTools(Toolkit):
1324
1246
  path: str,
1325
1247
  content: str,
1326
1248
  message: str,
1327
- branch: Optional[str] = NotSet,
1249
+ branch: Optional[str] = None,
1328
1250
  ) -> str:
1329
1251
  """Create a new file in a repository.
1330
1252
 
@@ -1350,7 +1272,7 @@ class GithubTools(Toolkit):
1350
1272
 
1351
1273
  # Extract relevant information
1352
1274
  file_info = {
1353
- "path": result["content"].path,
1275
+ "path": result["content"].path, # type: ignore
1354
1276
  "sha": result["content"].sha,
1355
1277
  "url": result["content"].html_url,
1356
1278
  "commit": {