agno 1.8.1__py3-none-any.whl → 2.0.0rc1__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 +3181 -4169
  4. agno/api/agent.py +11 -67
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +8 -19
  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 +11 -66
  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 +1743 -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 +1432 -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 +882 -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 +1045 -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 +1411 -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 +297 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1710 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +280 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1367 -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 +1712 -0
  67. agno/db/singlestore/utils.py +326 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1676 -0
  71. agno/db/sqlite/utils.py +268 -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 +15 -11
  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/memory/__init__.py +2 -10
  137. agno/memory/manager.py +1003 -148
  138. agno/models/aimlapi/__init__.py +2 -2
  139. agno/models/aimlapi/aimlapi.py +6 -6
  140. agno/models/anthropic/claude.py +131 -131
  141. agno/models/aws/bedrock.py +107 -175
  142. agno/models/aws/claude.py +64 -18
  143. agno/models/azure/ai_foundry.py +73 -23
  144. agno/models/base.py +347 -287
  145. agno/models/cerebras/cerebras.py +84 -27
  146. agno/models/cohere/chat.py +106 -98
  147. agno/models/google/gemini.py +100 -42
  148. agno/models/groq/groq.py +97 -35
  149. agno/models/huggingface/huggingface.py +92 -27
  150. agno/models/ibm/watsonx.py +72 -13
  151. agno/models/litellm/chat.py +85 -13
  152. agno/models/message.py +45 -150
  153. agno/models/meta/llama.py +85 -49
  154. agno/models/metrics.py +120 -0
  155. agno/models/mistral/mistral.py +90 -21
  156. agno/models/ollama/__init__.py +0 -2
  157. agno/models/ollama/chat.py +84 -46
  158. agno/models/openai/chat.py +121 -23
  159. agno/models/openai/responses.py +178 -105
  160. agno/models/perplexity/perplexity.py +26 -2
  161. agno/models/portkey/portkey.py +0 -7
  162. agno/models/response.py +14 -8
  163. agno/models/utils.py +20 -0
  164. agno/models/vercel/__init__.py +2 -2
  165. agno/models/vercel/v0.py +1 -1
  166. agno/models/vllm/__init__.py +2 -2
  167. agno/models/vllm/vllm.py +3 -3
  168. agno/models/xai/xai.py +10 -10
  169. agno/os/__init__.py +3 -0
  170. agno/os/app.py +489 -0
  171. agno/os/auth.py +47 -0
  172. agno/os/config.py +103 -0
  173. agno/os/interfaces/agui/__init__.py +3 -0
  174. agno/os/interfaces/agui/agui.py +31 -0
  175. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  176. agno/{app → os/interfaces}/agui/utils.py +77 -33
  177. agno/os/interfaces/base.py +21 -0
  178. agno/os/interfaces/slack/__init__.py +3 -0
  179. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  180. agno/os/interfaces/slack/slack.py +32 -0
  181. agno/os/interfaces/whatsapp/__init__.py +3 -0
  182. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  183. agno/os/interfaces/whatsapp/whatsapp.py +29 -0
  184. agno/os/mcp.py +255 -0
  185. agno/os/router.py +869 -0
  186. agno/os/routers/__init__.py +3 -0
  187. agno/os/routers/evals/__init__.py +3 -0
  188. agno/os/routers/evals/evals.py +208 -0
  189. agno/os/routers/evals/schemas.py +142 -0
  190. agno/os/routers/evals/utils.py +161 -0
  191. agno/os/routers/knowledge/__init__.py +3 -0
  192. agno/os/routers/knowledge/knowledge.py +436 -0
  193. agno/os/routers/knowledge/schemas.py +118 -0
  194. agno/os/routers/memory/__init__.py +3 -0
  195. agno/os/routers/memory/memory.py +188 -0
  196. agno/os/routers/memory/schemas.py +58 -0
  197. agno/os/routers/metrics/__init__.py +3 -0
  198. agno/os/routers/metrics/metrics.py +60 -0
  199. agno/os/routers/metrics/schemas.py +47 -0
  200. agno/os/routers/session/__init__.py +3 -0
  201. agno/os/routers/session/session.py +168 -0
  202. agno/os/schema.py +892 -0
  203. agno/{app/playground → os}/settings.py +7 -15
  204. agno/os/utils.py +270 -0
  205. agno/reasoning/azure_ai_foundry.py +4 -4
  206. agno/reasoning/deepseek.py +4 -4
  207. agno/reasoning/default.py +6 -11
  208. agno/reasoning/groq.py +4 -4
  209. agno/reasoning/helpers.py +4 -6
  210. agno/reasoning/ollama.py +4 -4
  211. agno/reasoning/openai.py +4 -4
  212. agno/run/{response.py → agent.py} +231 -74
  213. agno/run/base.py +44 -58
  214. agno/run/cancel.py +81 -0
  215. agno/run/team.py +133 -77
  216. agno/run/workflow.py +537 -12
  217. agno/session/__init__.py +10 -0
  218. agno/session/agent.py +244 -0
  219. agno/session/summary.py +225 -0
  220. agno/session/team.py +262 -0
  221. agno/{storage/session/v2 → session}/workflow.py +47 -24
  222. agno/team/__init__.py +15 -16
  223. agno/team/team.py +2960 -4252
  224. agno/tools/agentql.py +14 -5
  225. agno/tools/airflow.py +9 -4
  226. agno/tools/api.py +7 -3
  227. agno/tools/apify.py +2 -46
  228. agno/tools/arxiv.py +8 -3
  229. agno/tools/aws_lambda.py +7 -5
  230. agno/tools/aws_ses.py +7 -1
  231. agno/tools/baidusearch.py +4 -1
  232. agno/tools/bitbucket.py +4 -4
  233. agno/tools/brandfetch.py +14 -11
  234. agno/tools/bravesearch.py +4 -1
  235. agno/tools/brightdata.py +42 -22
  236. agno/tools/browserbase.py +13 -4
  237. agno/tools/calcom.py +12 -10
  238. agno/tools/calculator.py +10 -27
  239. agno/tools/cartesia.py +18 -13
  240. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  241. agno/tools/confluence.py +8 -8
  242. agno/tools/crawl4ai.py +7 -1
  243. agno/tools/csv_toolkit.py +9 -8
  244. agno/tools/dalle.py +18 -11
  245. agno/tools/daytona.py +13 -16
  246. agno/tools/decorator.py +6 -3
  247. agno/tools/desi_vocal.py +16 -7
  248. agno/tools/discord.py +11 -8
  249. agno/tools/docker.py +30 -42
  250. agno/tools/duckdb.py +34 -53
  251. agno/tools/duckduckgo.py +8 -7
  252. agno/tools/e2b.py +61 -61
  253. agno/tools/eleven_labs.py +35 -28
  254. agno/tools/email.py +4 -1
  255. agno/tools/evm.py +7 -1
  256. agno/tools/exa.py +19 -14
  257. agno/tools/fal.py +29 -29
  258. agno/tools/file.py +9 -8
  259. agno/tools/financial_datasets.py +25 -44
  260. agno/tools/firecrawl.py +22 -22
  261. agno/tools/function.py +127 -18
  262. agno/tools/giphy.py +22 -10
  263. agno/tools/github.py +48 -126
  264. agno/tools/gmail.py +45 -61
  265. agno/tools/google_bigquery.py +7 -6
  266. agno/tools/google_maps.py +11 -26
  267. agno/tools/googlesearch.py +7 -2
  268. agno/tools/googlesheets.py +21 -17
  269. agno/tools/hackernews.py +9 -5
  270. agno/tools/jina.py +5 -4
  271. agno/tools/jira.py +18 -9
  272. agno/tools/knowledge.py +31 -32
  273. agno/tools/linear.py +19 -34
  274. agno/tools/linkup.py +5 -1
  275. agno/tools/local_file_system.py +8 -5
  276. agno/tools/lumalab.py +31 -19
  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 +32 -14
  281. agno/tools/models/gemini.py +58 -31
  282. agno/tools/models/groq.py +29 -20
  283. agno/tools/models/nebius.py +27 -11
  284. agno/tools/models_labs.py +39 -15
  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 +57 -26
  290. agno/tools/openbb.py +12 -11
  291. agno/tools/opencv.py +62 -46
  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 +54 -41
  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 +95 -118
  334. agno/utils/gemini.py +31 -1
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/log.py +2 -2
  337. agno/utils/mcp.py +11 -5
  338. agno/utils/media.py +39 -0
  339. agno/utils/message.py +12 -1
  340. agno/utils/models/claude.py +55 -4
  341. agno/utils/models/mistral.py +8 -7
  342. agno/utils/models/schema_utils.py +3 -3
  343. agno/utils/pprint.py +33 -32
  344. agno/utils/print_response/agent.py +779 -0
  345. agno/utils/print_response/team.py +1565 -0
  346. agno/utils/print_response/workflow.py +1451 -0
  347. agno/utils/prompts.py +14 -14
  348. agno/utils/reasoning.py +87 -0
  349. agno/utils/response.py +42 -42
  350. agno/utils/streamlit.py +454 -0
  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 +334 -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 +2401 -696
  383. agno-2.0.0rc1.dist-info/METADATA +355 -0
  384. agno-2.0.0rc1.dist-info/RECORD +516 -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 -702
  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.1.dist-info/METADATA +0 -982
  568. agno-1.8.1.dist-info/RECORD +0 -566
  569. agno-1.8.1.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.1.dist-info → agno-2.0.0rc1.dist-info}/WHEEL +0 -0
  582. {agno-1.8.1.dist-info → agno-2.0.0rc1.dist-info}/licenses/LICENSE +0 -0
  583. {agno-1.8.1.dist-info → agno-2.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,3 @@
1
+ from agno.os.interfaces.agui.agui import AGUI
2
+
3
+ __all__ = ["AGUI"]
@@ -0,0 +1,31 @@
1
+ """Main class for the AG-UI app, used to expose an Agno Agent or Team in an AG-UI compatible format."""
2
+
3
+ from typing import Optional
4
+
5
+ from fastapi.routing import APIRouter
6
+
7
+ from agno.agent import Agent
8
+ from agno.os.interfaces.agui.router import attach_routes
9
+ from agno.os.interfaces.base import BaseInterface
10
+ from agno.team import Team
11
+
12
+
13
+ class AGUI(BaseInterface):
14
+ type = "agui"
15
+
16
+ router: APIRouter
17
+
18
+ def __init__(self, agent: Optional[Agent] = None, team: Optional[Team] = None):
19
+ self.agent = agent
20
+ self.team = team
21
+
22
+ if not self.agent and not self.team:
23
+ raise ValueError("AGUI requires an agent and a team")
24
+
25
+ def get_router(self, **kwargs) -> APIRouter:
26
+ # Cannot be overridden
27
+ self.router = APIRouter(tags=["AGUI"])
28
+
29
+ self.router = attach_routes(router=self.router, agent=self.agent, team=self.team)
30
+
31
+ return self.router
@@ -16,7 +16,10 @@ from fastapi import APIRouter
16
16
  from fastapi.responses import StreamingResponse
17
17
 
18
18
  from agno.agent.agent import Agent
19
- from agno.app.agui.utils import async_stream_agno_response_as_agui_events, convert_agui_messages_to_agno_messages
19
+ from agno.os.interfaces.agui.utils import (
20
+ async_stream_agno_response_as_agui_events,
21
+ convert_agui_messages_to_agno_messages,
22
+ )
20
23
  from agno.team.team import Team
21
24
 
22
25
  logger = logging.getLogger(__name__)
@@ -32,8 +35,8 @@ async def run_agent(agent: Agent, run_input: RunAgentInput) -> AsyncIterator[Bas
32
35
  yield RunStartedEvent(type=EventType.RUN_STARTED, thread_id=run_input.thread_id, run_id=run_id)
33
36
 
34
37
  # Request streaming response from agent
35
- response_stream = await agent.arun(
36
- messages=messages,
38
+ response_stream = agent.arun(
39
+ input=messages,
37
40
  session_id=run_input.thread_id,
38
41
  stream=True,
39
42
  stream_intermediate_steps=True,
@@ -41,7 +44,9 @@ async def run_agent(agent: Agent, run_input: RunAgentInput) -> AsyncIterator[Bas
41
44
 
42
45
  # Stream the response content in AG-UI format
43
46
  async for event in async_stream_agno_response_as_agui_events(
44
- response_stream=response_stream, thread_id=run_input.thread_id, run_id=run_id
47
+ response_stream=response_stream, # type: ignore
48
+ thread_id=run_input.thread_id,
49
+ run_id=run_id,
45
50
  ):
46
51
  yield event
47
52
 
@@ -60,8 +65,8 @@ async def run_team(team: Team, input: RunAgentInput) -> AsyncIterator[BaseEvent]
60
65
  yield RunStartedEvent(type=EventType.RUN_STARTED, thread_id=input.thread_id, run_id=run_id)
61
66
 
62
67
  # Request streaming response from team
63
- response_stream = await team.arun(
64
- message=messages,
68
+ response_stream = team.arun(
69
+ input=messages,
65
70
  session_id=input.thread_id,
66
71
  stream=True,
67
72
  stream_intermediate_steps=True,
@@ -78,15 +83,14 @@ async def run_team(team: Team, input: RunAgentInput) -> AsyncIterator[BaseEvent]
78
83
  yield RunErrorEvent(type=EventType.RUN_ERROR, message=str(e))
79
84
 
80
85
 
81
- def get_async_agui_router(agent: Optional[Agent] = None, team: Optional[Team] = None) -> APIRouter:
82
- """Return an AG-UI compatible FastAPI router."""
83
- if (agent is None and team is None) or (agent is not None and team is not None):
84
- raise ValueError("One of 'agent' or 'team' must be provided.")
86
+ def attach_routes(router: APIRouter, agent: Optional[Agent] = None, team: Optional[Team] = None) -> APIRouter:
87
+ if agent is None and team is None:
88
+ raise ValueError("Either agent or team must be provided.")
85
89
 
86
- router = APIRouter()
87
90
  encoder = EventEncoder()
88
91
 
89
- async def _run(run_input: RunAgentInput):
92
+ @router.post("/agui")
93
+ async def run_agent_agui(run_input: RunAgentInput):
90
94
  async def event_generator():
91
95
  if agent:
92
96
  async for event in run_agent(agent, run_input):
@@ -109,10 +113,6 @@ def get_async_agui_router(agent: Optional[Agent] = None, team: Optional[Team] =
109
113
  },
110
114
  )
111
115
 
112
- @router.post("/agui")
113
- async def run_agent_agui(run_input: RunAgentInput):
114
- return await _run(run_input)
115
-
116
116
  @router.get("/status")
117
117
  async def get_status():
118
118
  return {"status": "available"}
@@ -24,9 +24,10 @@ from ag_ui.core import (
24
24
  from ag_ui.core.types import Message as AGUIMessage
25
25
 
26
26
  from agno.models.message import Message
27
- from agno.run.response import RunEvent, RunResponseContentEvent, RunResponseEvent, RunResponsePausedEvent
28
- from agno.run.team import RunResponseContentEvent as TeamRunResponseContentEvent
29
- from agno.run.team import TeamRunEvent, TeamRunResponseEvent
27
+ from agno.run.agent import RunContentEvent, RunEvent, RunOutputEvent, RunPausedEvent
28
+ from agno.run.team import RunContentEvent as TeamRunContentEvent
29
+ from agno.run.team import TeamRunEvent, TeamRunOutputEvent
30
+ from agno.utils.message import get_text_from_message
30
31
 
31
32
 
32
33
  @dataclass
@@ -89,38 +90,44 @@ def convert_agui_messages_to_agno_messages(messages: List[AGUIMessage]) -> List[
89
90
  return result
90
91
 
91
92
 
92
- def extract_team_response_chunk_content(response: TeamRunResponseContentEvent) -> str:
93
+ def extract_team_response_chunk_content(response: TeamRunContentEvent) -> str:
93
94
  """Given a response stream chunk, find and extract the content."""
94
95
 
95
96
  # Handle Team members' responses
96
97
  members_content = []
97
98
  if hasattr(response, "member_responses") and response.member_responses: # type: ignore
98
99
  for member_resp in response.member_responses: # type: ignore
99
- if isinstance(member_resp, RunResponseContentEvent):
100
+ if isinstance(member_resp, RunContentEvent):
100
101
  member_content = extract_response_chunk_content(member_resp)
101
102
  if member_content:
102
103
  members_content.append(f"Team member: {member_content}")
103
- elif isinstance(member_resp, TeamRunResponseContentEvent):
104
+ elif isinstance(member_resp, TeamRunContentEvent):
104
105
  member_content = extract_team_response_chunk_content(member_resp)
105
106
  if member_content:
106
107
  members_content.append(f"Team member: {member_content}")
107
108
  members_response = "\n".join(members_content) if members_content else ""
108
109
 
109
- return str(response.content) + members_response
110
+ # Handle structured outputs
111
+ main_content = get_text_from_message(response.content) if response.content is not None else ""
110
112
 
113
+ return main_content + members_response
111
114
 
112
- def extract_response_chunk_content(response: RunResponseContentEvent) -> str:
115
+
116
+ def extract_response_chunk_content(response: RunContentEvent) -> str:
113
117
  """Given a response stream chunk, find and extract the content."""
118
+
114
119
  if hasattr(response, "messages") and response.messages: # type: ignore
115
120
  for msg in reversed(response.messages): # type: ignore
116
121
  if hasattr(msg, "role") and msg.role == "assistant" and hasattr(msg, "content") and msg.content:
117
- return str(msg.content)
122
+ # Handle structured outputs from messages
123
+ return get_text_from_message(msg.content)
118
124
 
119
- return str(response.content) if response.content else ""
125
+ # Handle structured outputs
126
+ return get_text_from_message(response.content) if response.content is not None else ""
120
127
 
121
128
 
122
129
  def _create_events_from_chunk(
123
- chunk: Union[RunResponseEvent, TeamRunResponseEvent],
130
+ chunk: Union[RunOutputEvent, TeamRunOutputEvent],
124
131
  message_id: str,
125
132
  message_started: bool,
126
133
  event_buffer: EventBuffer,
@@ -132,9 +139,9 @@ def _create_events_from_chunk(
132
139
  events_to_emit: List[BaseEvent] = []
133
140
 
134
141
  # Extract content if the contextual event is a content event
135
- if chunk.event == RunEvent.run_response_content:
142
+ if chunk.event == RunEvent.run_content:
136
143
  content = extract_response_chunk_content(chunk) # type: ignore
137
- elif chunk.event == TeamRunEvent.run_response_content:
144
+ elif chunk.event == TeamRunEvent.run_content:
138
145
  content = extract_team_response_chunk_content(chunk) # type: ignore
139
146
  else:
140
147
  content = None
@@ -158,7 +165,7 @@ def _create_events_from_chunk(
158
165
  message_id=message_id,
159
166
  delta=content,
160
167
  )
161
- events_to_emit.append(content_event)
168
+ events_to_emit.append(content_event) # type: ignore
162
169
 
163
170
  # Handle starting a new tool call
164
171
  elif chunk.event == RunEvent.tool_call_started:
@@ -177,7 +184,7 @@ def _create_events_from_chunk(
177
184
  tool_call_id=tool_call.tool_call_id, # type: ignore
178
185
  delta=json.dumps(tool_call.tool_args),
179
186
  )
180
- events_to_emit.append(args_event)
187
+ events_to_emit.append(args_event) # type: ignore
181
188
 
182
189
  # Handle tool call completion
183
190
  elif chunk.event == RunEvent.tool_call_completed:
@@ -188,7 +195,7 @@ def _create_events_from_chunk(
188
195
  type=EventType.TOOL_CALL_END,
189
196
  tool_call_id=tool_call.tool_call_id, # type: ignore
190
197
  )
191
- events_to_emit.append(end_event)
198
+ events_to_emit.append(end_event) # type: ignore
192
199
 
193
200
  if tool_call.result is not None:
194
201
  result_event = ToolCallResultEvent(
@@ -198,21 +205,31 @@ def _create_events_from_chunk(
198
205
  role="tool",
199
206
  message_id=str(uuid.uuid4()),
200
207
  )
201
- events_to_emit.append(result_event)
208
+ events_to_emit.append(result_event) # type: ignore
209
+
210
+ if tool_call.result is not None:
211
+ result_event = ToolCallResultEvent(
212
+ type=EventType.TOOL_CALL_RESULT,
213
+ tool_call_id=tool_call.tool_call_id, # type: ignore
214
+ content=str(tool_call.result),
215
+ role="tool",
216
+ message_id=str(uuid.uuid4()),
217
+ )
218
+ events_to_emit.append(result_event) # type: ignore
202
219
 
203
220
  # Handle reasoning
204
221
  elif chunk.event == RunEvent.reasoning_started:
205
- step_event = StepStartedEvent(type=EventType.STEP_STARTED, step_name="reasoning")
206
- events_to_emit.append(step_event)
222
+ step_started_event = StepStartedEvent(type=EventType.STEP_STARTED, step_name="reasoning") # type: ignore
223
+ events_to_emit.append(step_started_event) # type: ignore
207
224
  elif chunk.event == RunEvent.reasoning_completed:
208
- step_event = StepFinishedEvent(type=EventType.STEP_FINISHED, step_name="reasoning")
209
- events_to_emit.append(step_event)
225
+ step_started_event = StepFinishedEvent(type=EventType.STEP_FINISHED, step_name="reasoning") # type: ignore
226
+ events_to_emit.append(step_started_event) # type: ignore
210
227
 
211
- return events_to_emit, message_started
228
+ return events_to_emit, message_started # type: ignore
212
229
 
213
230
 
214
231
  def _create_completion_events(
215
- chunk: Union[RunResponseEvent, TeamRunResponseEvent],
232
+ chunk: Union[RunOutputEvent, TeamRunOutputEvent],
216
233
  event_buffer: EventBuffer,
217
234
  message_started: bool,
218
235
  message_id: str,
@@ -220,7 +237,7 @@ def _create_completion_events(
220
237
  run_id: str,
221
238
  ) -> List[BaseEvent]:
222
239
  """Create events for run completion."""
223
- events_to_emit = []
240
+ events_to_emit: List[BaseEvent] = []
224
241
 
225
242
  # End remaining active tool calls if needed
226
243
  for tool_call_id in list(event_buffer.active_tool_call_ids):
@@ -234,10 +251,10 @@ def _create_completion_events(
234
251
  # End the message and run, denoting the end of the session
235
252
  if message_started:
236
253
  end_message_event = TextMessageEndEvent(type=EventType.TEXT_MESSAGE_END, message_id=message_id)
237
- events_to_emit.append(end_message_event)
254
+ events_to_emit.append(end_message_event) # type: ignore
238
255
 
239
256
  # emit frontend tool calls, i.e. external_execution=True
240
- if isinstance(chunk, RunResponsePausedEvent) and chunk.tools is not None:
257
+ if isinstance(chunk, RunPausedEvent) and chunk.tools is not None:
241
258
  for tool in chunk.tools:
242
259
  if tool.tool_call_id is None or tool.tool_name is None:
243
260
  continue
@@ -248,14 +265,14 @@ def _create_completion_events(
248
265
  tool_call_name=tool.tool_name,
249
266
  parent_message_id=message_id,
250
267
  )
251
- events_to_emit.append(start_event)
268
+ events_to_emit.append(start_event) # type: ignore
252
269
 
253
270
  args_event = ToolCallArgsEvent(
254
271
  type=EventType.TOOL_CALL_ARGS,
255
272
  tool_call_id=tool.tool_call_id,
256
273
  delta=json.dumps(tool.tool_args),
257
274
  )
258
- events_to_emit.append(args_event)
275
+ events_to_emit.append(args_event) # type: ignore
259
276
 
260
277
  end_event = ToolCallEndEvent(
261
278
  type=EventType.TOOL_CALL_END,
@@ -263,15 +280,42 @@ def _create_completion_events(
263
280
  )
264
281
  events_to_emit.append(end_event)
265
282
 
283
+ # emit frontend tool calls, i.e. external_execution=True
284
+ if isinstance(chunk, RunPausedEvent) and chunk.tools is not None:
285
+ for tool in chunk.tools:
286
+ if tool.tool_call_id is None or tool.tool_name is None:
287
+ continue
288
+
289
+ start_event = ToolCallStartEvent(
290
+ type=EventType.TOOL_CALL_START,
291
+ tool_call_id=tool.tool_call_id,
292
+ tool_call_name=tool.tool_name,
293
+ parent_message_id=message_id,
294
+ )
295
+ events_to_emit.append(start_event) # type: ignore
296
+
297
+ args_event = ToolCallArgsEvent(
298
+ type=EventType.TOOL_CALL_ARGS,
299
+ tool_call_id=tool.tool_call_id,
300
+ delta=json.dumps(tool.tool_args),
301
+ )
302
+ events_to_emit.append(args_event) # type: ignore
303
+
304
+ end_event = ToolCallEndEvent(
305
+ type=EventType.TOOL_CALL_END,
306
+ tool_call_id=tool.tool_call_id,
307
+ )
308
+ events_to_emit.append(end_event) # type: ignore
309
+
266
310
  run_finished_event = RunFinishedEvent(type=EventType.RUN_FINISHED, thread_id=thread_id, run_id=run_id)
267
- events_to_emit.append(run_finished_event)
311
+ events_to_emit.append(run_finished_event) # type: ignore
268
312
 
269
- return events_to_emit
313
+ return events_to_emit # type: ignore
270
314
 
271
315
 
272
316
  def _emit_event_logic(event: BaseEvent, event_buffer: EventBuffer) -> List[BaseEvent]:
273
317
  """Process an event through the buffer and return events to actually emit."""
274
- events_to_emit = []
318
+ events_to_emit: List[BaseEvent] = []
275
319
 
276
320
  if event_buffer.is_blocked():
277
321
  # Handle events related to the current blocking tool call
@@ -320,7 +364,7 @@ def _emit_event_logic(event: BaseEvent, event_buffer: EventBuffer) -> List[BaseE
320
364
 
321
365
 
322
366
  def stream_agno_response_as_agui_events(
323
- response_stream: Iterator[Union[RunResponseEvent, TeamRunResponseEvent]], thread_id: str, run_id: str
367
+ response_stream: Iterator[Union[RunOutputEvent, TeamRunOutputEvent]], thread_id: str, run_id: str
324
368
  ) -> Iterator[BaseEvent]:
325
369
  """Map the Agno response stream to AG-UI format, handling event ordering constraints."""
326
370
  message_id = str(uuid.uuid4())
@@ -355,7 +399,7 @@ def stream_agno_response_as_agui_events(
355
399
 
356
400
  # Async version - thin wrapper
357
401
  async def async_stream_agno_response_as_agui_events(
358
- response_stream: AsyncIterator[Union[RunResponseEvent, TeamRunResponseEvent]],
402
+ response_stream: AsyncIterator[Union[RunOutputEvent, TeamRunOutputEvent]],
359
403
  thread_id: str,
360
404
  run_id: str,
361
405
  ) -> AsyncIterator[BaseEvent]:
@@ -0,0 +1,21 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Optional
3
+
4
+ from fastapi import APIRouter
5
+
6
+ from agno.agent import Agent
7
+ from agno.team import Team
8
+
9
+
10
+ class BaseInterface(ABC):
11
+ type: str
12
+ version: str = "1.0"
13
+ router_prefix: str = ""
14
+ agent: Optional[Agent] = None
15
+ team: Optional[Team] = None
16
+
17
+ router: APIRouter
18
+
19
+ @abstractmethod
20
+ def get_router(self, use_async: bool = True, **kwargs) -> APIRouter:
21
+ pass
@@ -0,0 +1,3 @@
1
+ from agno.os.interfaces.slack.slack import Slack
2
+
3
+ __all__ = ["Slack"]
@@ -3,15 +3,13 @@ from typing import Optional
3
3
  from fastapi import APIRouter, BackgroundTasks, HTTPException, Request
4
4
 
5
5
  from agno.agent.agent import Agent
6
- from agno.app.slack.security import verify_slack_signature
6
+ from agno.os.interfaces.slack.security import verify_slack_signature
7
7
  from agno.team.team import Team
8
8
  from agno.tools.slack import SlackTools
9
9
  from agno.utils.log import log_info
10
10
 
11
11
 
12
- def get_async_router(agent: Optional[Agent] = None, team: Optional[Team] = None) -> APIRouter:
13
- router = APIRouter()
14
-
12
+ def attach_routes(router: APIRouter, agent: Optional[Agent] = None, team: Optional[Team] = None) -> APIRouter:
15
13
  @router.post("/slack/events")
16
14
  async def slack_events(request: Request, background_tasks: BackgroundTasks):
17
15
  body = await request.body()
@@ -44,7 +42,7 @@ def get_async_router(agent: Optional[Agent] = None, team: Optional[Team] = None)
44
42
  async def _process_slack_event(event: dict):
45
43
  if event.get("type") == "message":
46
44
  user = None
47
- message_text = event.get("text")
45
+ message_text = event.get("text", "")
48
46
  channel_id = event.get("channel", "")
49
47
  user = event.get("user")
50
48
  if event.get("thread_ts"):
@@ -0,0 +1,32 @@
1
+ import logging
2
+ from typing import Optional
3
+
4
+ from fastapi.routing import APIRouter
5
+
6
+ from agno.agent.agent import Agent
7
+ from agno.os.interfaces.base import BaseInterface
8
+ from agno.os.interfaces.slack.router import attach_routes
9
+ from agno.team.team import Team
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class Slack(BaseInterface):
15
+ type = "slack"
16
+
17
+ router: APIRouter
18
+
19
+ def __init__(self, agent: Optional[Agent] = None, team: Optional[Team] = None):
20
+ self.agent = agent
21
+ self.team = team
22
+
23
+ if not self.agent and not self.team:
24
+ raise ValueError("Slack requires an agent and a team")
25
+
26
+ def get_router(self, **kwargs) -> APIRouter:
27
+ # Cannot be overridden
28
+ self.router = APIRouter(prefix="/slack", tags=["Slack"])
29
+
30
+ self.router = attach_routes(router=self.router, agent=self.agent, team=self.team)
31
+
32
+ return self.router
@@ -0,0 +1,3 @@
1
+ from agno.os.interfaces.whatsapp.whatsapp import Whatsapp
2
+
3
+ __all__ = ["Whatsapp"]
@@ -15,9 +15,7 @@ from agno.utils.whatsapp import get_media_async, send_image_message_async, typin
15
15
  from .security import validate_webhook_signature
16
16
 
17
17
 
18
- def get_async_router(agent: Optional[Agent] = None, team: Optional[Team] = None) -> APIRouter:
19
- router = APIRouter()
20
-
18
+ def attach_routes(router: APIRouter, agent: Optional[Agent] = None, team: Optional[Team] = None) -> APIRouter:
21
19
  if agent is None and team is None:
22
20
  raise ValueError("Either agent or team must be provided.")
23
21
 
@@ -128,7 +126,7 @@ def get_async_router(agent: Optional[Agent] = None, team: Optional[Team] = None)
128
126
  audio=[Audio(content=await get_media_async(message_audio))] if message_audio else None,
129
127
  )
130
128
  elif team:
131
- response = await team.arun(
129
+ response = await team.arun( # type: ignore
132
130
  message_text,
133
131
  user_id=phone_number,
134
132
  files=[File(content=await get_media_async(message_doc))] if message_doc else None,
@@ -167,9 +165,8 @@ def get_async_router(agent: Optional[Agent] = None, team: Optional[Team] = None)
167
165
  log_warning(
168
166
  f"Could not process image content for user {phone_number}. Type: {type(image_content)}"
169
167
  )
170
- await _send_whatsapp_message(phone_number, response.content) # Send text part if image fails
171
- else:
172
- await _send_whatsapp_message(phone_number, response.content)
168
+ await _send_whatsapp_message(phone_number, response.content) # type: ignore
169
+ await _send_whatsapp_message(phone_number, response.content) # type: ignore
173
170
 
174
171
  except Exception as e:
175
172
  log_error(f"Error processing message: {str(e)}")
@@ -0,0 +1,29 @@
1
+ from typing import Optional
2
+
3
+ from fastapi.routing import APIRouter
4
+
5
+ from agno.agent import Agent
6
+ from agno.os.interfaces.base import BaseInterface
7
+ from agno.os.interfaces.whatsapp.router import attach_routes
8
+ from agno.team import Team
9
+
10
+
11
+ class Whatsapp(BaseInterface):
12
+ type = "whatsapp"
13
+
14
+ router: APIRouter
15
+
16
+ def __init__(self, agent: Optional[Agent] = None, team: Optional[Team] = None):
17
+ self.agent = agent
18
+ self.team = team
19
+
20
+ if not self.agent and not self.team:
21
+ raise ValueError("Whatsapp requires an agent and a team")
22
+
23
+ def get_router(self, **kwargs) -> APIRouter:
24
+ # Cannot be overridden
25
+ self.router = APIRouter(prefix="/whatsapp", tags=["Whatsapp"])
26
+
27
+ self.router = attach_routes(router=self.router, agent=self.agent, team=self.team)
28
+
29
+ return self.router