agno 2.2.13__py3-none-any.whl → 2.4.3__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 (383) hide show
  1. agno/agent/__init__.py +6 -0
  2. agno/agent/agent.py +5252 -3145
  3. agno/agent/remote.py +525 -0
  4. agno/api/api.py +2 -0
  5. agno/client/__init__.py +3 -0
  6. agno/client/a2a/__init__.py +10 -0
  7. agno/client/a2a/client.py +554 -0
  8. agno/client/a2a/schemas.py +112 -0
  9. agno/client/a2a/utils.py +369 -0
  10. agno/client/os.py +2669 -0
  11. agno/compression/__init__.py +3 -0
  12. agno/compression/manager.py +247 -0
  13. agno/culture/manager.py +2 -2
  14. agno/db/base.py +927 -6
  15. agno/db/dynamo/dynamo.py +788 -2
  16. agno/db/dynamo/schemas.py +128 -0
  17. agno/db/dynamo/utils.py +26 -3
  18. agno/db/firestore/firestore.py +674 -50
  19. agno/db/firestore/schemas.py +41 -0
  20. agno/db/firestore/utils.py +25 -10
  21. agno/db/gcs_json/gcs_json_db.py +506 -3
  22. agno/db/gcs_json/utils.py +14 -2
  23. agno/db/in_memory/in_memory_db.py +203 -4
  24. agno/db/in_memory/utils.py +14 -2
  25. agno/db/json/json_db.py +498 -2
  26. agno/db/json/utils.py +14 -2
  27. agno/db/migrations/manager.py +199 -0
  28. agno/db/migrations/utils.py +19 -0
  29. agno/db/migrations/v1_to_v2.py +54 -16
  30. agno/db/migrations/versions/__init__.py +0 -0
  31. agno/db/migrations/versions/v2_3_0.py +977 -0
  32. agno/db/mongo/async_mongo.py +1013 -39
  33. agno/db/mongo/mongo.py +684 -4
  34. agno/db/mongo/schemas.py +48 -0
  35. agno/db/mongo/utils.py +17 -0
  36. agno/db/mysql/__init__.py +2 -1
  37. agno/db/mysql/async_mysql.py +2958 -0
  38. agno/db/mysql/mysql.py +722 -53
  39. agno/db/mysql/schemas.py +77 -11
  40. agno/db/mysql/utils.py +151 -8
  41. agno/db/postgres/async_postgres.py +1254 -137
  42. agno/db/postgres/postgres.py +2316 -93
  43. agno/db/postgres/schemas.py +153 -21
  44. agno/db/postgres/utils.py +22 -7
  45. agno/db/redis/redis.py +531 -3
  46. agno/db/redis/schemas.py +36 -0
  47. agno/db/redis/utils.py +31 -15
  48. agno/db/schemas/evals.py +1 -0
  49. agno/db/schemas/memory.py +20 -9
  50. agno/db/singlestore/schemas.py +70 -1
  51. agno/db/singlestore/singlestore.py +737 -74
  52. agno/db/singlestore/utils.py +13 -3
  53. agno/db/sqlite/async_sqlite.py +1069 -89
  54. agno/db/sqlite/schemas.py +133 -1
  55. agno/db/sqlite/sqlite.py +2203 -165
  56. agno/db/sqlite/utils.py +21 -11
  57. agno/db/surrealdb/models.py +25 -0
  58. agno/db/surrealdb/surrealdb.py +603 -1
  59. agno/db/utils.py +60 -0
  60. agno/eval/__init__.py +26 -3
  61. agno/eval/accuracy.py +25 -12
  62. agno/eval/agent_as_judge.py +871 -0
  63. agno/eval/base.py +29 -0
  64. agno/eval/performance.py +10 -4
  65. agno/eval/reliability.py +22 -13
  66. agno/eval/utils.py +2 -1
  67. agno/exceptions.py +42 -0
  68. agno/hooks/__init__.py +3 -0
  69. agno/hooks/decorator.py +164 -0
  70. agno/integrations/discord/client.py +13 -2
  71. agno/knowledge/__init__.py +4 -0
  72. agno/knowledge/chunking/code.py +90 -0
  73. agno/knowledge/chunking/document.py +65 -4
  74. agno/knowledge/chunking/fixed.py +4 -1
  75. agno/knowledge/chunking/markdown.py +102 -11
  76. agno/knowledge/chunking/recursive.py +2 -2
  77. agno/knowledge/chunking/semantic.py +130 -48
  78. agno/knowledge/chunking/strategy.py +18 -0
  79. agno/knowledge/embedder/azure_openai.py +0 -1
  80. agno/knowledge/embedder/google.py +1 -1
  81. agno/knowledge/embedder/mistral.py +1 -1
  82. agno/knowledge/embedder/nebius.py +1 -1
  83. agno/knowledge/embedder/openai.py +16 -12
  84. agno/knowledge/filesystem.py +412 -0
  85. agno/knowledge/knowledge.py +4261 -1199
  86. agno/knowledge/protocol.py +134 -0
  87. agno/knowledge/reader/arxiv_reader.py +3 -2
  88. agno/knowledge/reader/base.py +9 -7
  89. agno/knowledge/reader/csv_reader.py +91 -42
  90. agno/knowledge/reader/docx_reader.py +9 -10
  91. agno/knowledge/reader/excel_reader.py +225 -0
  92. agno/knowledge/reader/field_labeled_csv_reader.py +38 -48
  93. agno/knowledge/reader/firecrawl_reader.py +3 -2
  94. agno/knowledge/reader/json_reader.py +16 -22
  95. agno/knowledge/reader/markdown_reader.py +15 -14
  96. agno/knowledge/reader/pdf_reader.py +33 -28
  97. agno/knowledge/reader/pptx_reader.py +9 -10
  98. agno/knowledge/reader/reader_factory.py +135 -1
  99. agno/knowledge/reader/s3_reader.py +8 -16
  100. agno/knowledge/reader/tavily_reader.py +3 -3
  101. agno/knowledge/reader/text_reader.py +15 -14
  102. agno/knowledge/reader/utils/__init__.py +17 -0
  103. agno/knowledge/reader/utils/spreadsheet.py +114 -0
  104. agno/knowledge/reader/web_search_reader.py +8 -65
  105. agno/knowledge/reader/website_reader.py +16 -13
  106. agno/knowledge/reader/wikipedia_reader.py +36 -3
  107. agno/knowledge/reader/youtube_reader.py +3 -2
  108. agno/knowledge/remote_content/__init__.py +33 -0
  109. agno/knowledge/remote_content/config.py +266 -0
  110. agno/knowledge/remote_content/remote_content.py +105 -17
  111. agno/knowledge/utils.py +76 -22
  112. agno/learn/__init__.py +71 -0
  113. agno/learn/config.py +463 -0
  114. agno/learn/curate.py +185 -0
  115. agno/learn/machine.py +725 -0
  116. agno/learn/schemas.py +1114 -0
  117. agno/learn/stores/__init__.py +38 -0
  118. agno/learn/stores/decision_log.py +1156 -0
  119. agno/learn/stores/entity_memory.py +3275 -0
  120. agno/learn/stores/learned_knowledge.py +1583 -0
  121. agno/learn/stores/protocol.py +117 -0
  122. agno/learn/stores/session_context.py +1217 -0
  123. agno/learn/stores/user_memory.py +1495 -0
  124. agno/learn/stores/user_profile.py +1220 -0
  125. agno/learn/utils.py +209 -0
  126. agno/media.py +22 -6
  127. agno/memory/__init__.py +14 -1
  128. agno/memory/manager.py +223 -8
  129. agno/memory/strategies/__init__.py +15 -0
  130. agno/memory/strategies/base.py +66 -0
  131. agno/memory/strategies/summarize.py +196 -0
  132. agno/memory/strategies/types.py +37 -0
  133. agno/models/aimlapi/aimlapi.py +17 -0
  134. agno/models/anthropic/claude.py +434 -59
  135. agno/models/aws/bedrock.py +121 -20
  136. agno/models/aws/claude.py +131 -274
  137. agno/models/azure/ai_foundry.py +10 -6
  138. agno/models/azure/openai_chat.py +33 -10
  139. agno/models/base.py +1162 -561
  140. agno/models/cerebras/cerebras.py +120 -24
  141. agno/models/cerebras/cerebras_openai.py +21 -2
  142. agno/models/cohere/chat.py +65 -6
  143. agno/models/cometapi/cometapi.py +18 -1
  144. agno/models/dashscope/dashscope.py +2 -3
  145. agno/models/deepinfra/deepinfra.py +18 -1
  146. agno/models/deepseek/deepseek.py +69 -3
  147. agno/models/fireworks/fireworks.py +18 -1
  148. agno/models/google/gemini.py +959 -89
  149. agno/models/google/utils.py +22 -0
  150. agno/models/groq/groq.py +48 -18
  151. agno/models/huggingface/huggingface.py +17 -6
  152. agno/models/ibm/watsonx.py +16 -6
  153. agno/models/internlm/internlm.py +18 -1
  154. agno/models/langdb/langdb.py +13 -1
  155. agno/models/litellm/chat.py +88 -9
  156. agno/models/litellm/litellm_openai.py +18 -1
  157. agno/models/message.py +24 -5
  158. agno/models/meta/llama.py +40 -13
  159. agno/models/meta/llama_openai.py +22 -21
  160. agno/models/metrics.py +12 -0
  161. agno/models/mistral/mistral.py +8 -4
  162. agno/models/n1n/__init__.py +3 -0
  163. agno/models/n1n/n1n.py +57 -0
  164. agno/models/nebius/nebius.py +6 -7
  165. agno/models/nvidia/nvidia.py +20 -3
  166. agno/models/ollama/__init__.py +2 -0
  167. agno/models/ollama/chat.py +17 -6
  168. agno/models/ollama/responses.py +100 -0
  169. agno/models/openai/__init__.py +2 -0
  170. agno/models/openai/chat.py +117 -26
  171. agno/models/openai/open_responses.py +46 -0
  172. agno/models/openai/responses.py +110 -32
  173. agno/models/openrouter/__init__.py +2 -0
  174. agno/models/openrouter/openrouter.py +67 -2
  175. agno/models/openrouter/responses.py +146 -0
  176. agno/models/perplexity/perplexity.py +19 -1
  177. agno/models/portkey/portkey.py +7 -6
  178. agno/models/requesty/requesty.py +19 -2
  179. agno/models/response.py +20 -2
  180. agno/models/sambanova/sambanova.py +20 -3
  181. agno/models/siliconflow/siliconflow.py +19 -2
  182. agno/models/together/together.py +20 -3
  183. agno/models/vercel/v0.py +20 -3
  184. agno/models/vertexai/claude.py +124 -4
  185. agno/models/vllm/vllm.py +19 -14
  186. agno/models/xai/xai.py +19 -2
  187. agno/os/app.py +467 -137
  188. agno/os/auth.py +253 -5
  189. agno/os/config.py +22 -0
  190. agno/os/interfaces/a2a/a2a.py +7 -6
  191. agno/os/interfaces/a2a/router.py +635 -26
  192. agno/os/interfaces/a2a/utils.py +32 -33
  193. agno/os/interfaces/agui/agui.py +5 -3
  194. agno/os/interfaces/agui/router.py +26 -16
  195. agno/os/interfaces/agui/utils.py +97 -57
  196. agno/os/interfaces/base.py +7 -7
  197. agno/os/interfaces/slack/router.py +16 -7
  198. agno/os/interfaces/slack/slack.py +7 -7
  199. agno/os/interfaces/whatsapp/router.py +35 -7
  200. agno/os/interfaces/whatsapp/security.py +3 -1
  201. agno/os/interfaces/whatsapp/whatsapp.py +11 -8
  202. agno/os/managers.py +326 -0
  203. agno/os/mcp.py +652 -79
  204. agno/os/middleware/__init__.py +4 -0
  205. agno/os/middleware/jwt.py +718 -115
  206. agno/os/middleware/trailing_slash.py +27 -0
  207. agno/os/router.py +105 -1558
  208. agno/os/routers/agents/__init__.py +3 -0
  209. agno/os/routers/agents/router.py +655 -0
  210. agno/os/routers/agents/schema.py +288 -0
  211. agno/os/routers/components/__init__.py +3 -0
  212. agno/os/routers/components/components.py +475 -0
  213. agno/os/routers/database.py +155 -0
  214. agno/os/routers/evals/evals.py +111 -18
  215. agno/os/routers/evals/schemas.py +38 -5
  216. agno/os/routers/evals/utils.py +80 -11
  217. agno/os/routers/health.py +3 -3
  218. agno/os/routers/knowledge/knowledge.py +284 -35
  219. agno/os/routers/knowledge/schemas.py +14 -2
  220. agno/os/routers/memory/memory.py +274 -11
  221. agno/os/routers/memory/schemas.py +44 -3
  222. agno/os/routers/metrics/metrics.py +30 -15
  223. agno/os/routers/metrics/schemas.py +10 -6
  224. agno/os/routers/registry/__init__.py +3 -0
  225. agno/os/routers/registry/registry.py +337 -0
  226. agno/os/routers/session/session.py +143 -14
  227. agno/os/routers/teams/__init__.py +3 -0
  228. agno/os/routers/teams/router.py +550 -0
  229. agno/os/routers/teams/schema.py +280 -0
  230. agno/os/routers/traces/__init__.py +3 -0
  231. agno/os/routers/traces/schemas.py +414 -0
  232. agno/os/routers/traces/traces.py +549 -0
  233. agno/os/routers/workflows/__init__.py +3 -0
  234. agno/os/routers/workflows/router.py +757 -0
  235. agno/os/routers/workflows/schema.py +139 -0
  236. agno/os/schema.py +157 -584
  237. agno/os/scopes.py +469 -0
  238. agno/os/settings.py +3 -0
  239. agno/os/utils.py +574 -185
  240. agno/reasoning/anthropic.py +85 -1
  241. agno/reasoning/azure_ai_foundry.py +93 -1
  242. agno/reasoning/deepseek.py +102 -2
  243. agno/reasoning/default.py +6 -7
  244. agno/reasoning/gemini.py +87 -3
  245. agno/reasoning/groq.py +109 -2
  246. agno/reasoning/helpers.py +6 -7
  247. agno/reasoning/manager.py +1238 -0
  248. agno/reasoning/ollama.py +93 -1
  249. agno/reasoning/openai.py +115 -1
  250. agno/reasoning/vertexai.py +85 -1
  251. agno/registry/__init__.py +3 -0
  252. agno/registry/registry.py +68 -0
  253. agno/remote/__init__.py +3 -0
  254. agno/remote/base.py +581 -0
  255. agno/run/__init__.py +2 -4
  256. agno/run/agent.py +134 -19
  257. agno/run/base.py +49 -1
  258. agno/run/cancel.py +65 -52
  259. agno/run/cancellation_management/__init__.py +9 -0
  260. agno/run/cancellation_management/base.py +78 -0
  261. agno/run/cancellation_management/in_memory_cancellation_manager.py +100 -0
  262. agno/run/cancellation_management/redis_cancellation_manager.py +236 -0
  263. agno/run/requirement.py +181 -0
  264. agno/run/team.py +111 -19
  265. agno/run/workflow.py +2 -1
  266. agno/session/agent.py +57 -92
  267. agno/session/summary.py +1 -1
  268. agno/session/team.py +62 -115
  269. agno/session/workflow.py +353 -57
  270. agno/skills/__init__.py +17 -0
  271. agno/skills/agent_skills.py +377 -0
  272. agno/skills/errors.py +32 -0
  273. agno/skills/loaders/__init__.py +4 -0
  274. agno/skills/loaders/base.py +27 -0
  275. agno/skills/loaders/local.py +216 -0
  276. agno/skills/skill.py +65 -0
  277. agno/skills/utils.py +107 -0
  278. agno/skills/validator.py +277 -0
  279. agno/table.py +10 -0
  280. agno/team/__init__.py +5 -1
  281. agno/team/remote.py +447 -0
  282. agno/team/team.py +3769 -2202
  283. agno/tools/brandfetch.py +27 -18
  284. agno/tools/browserbase.py +225 -16
  285. agno/tools/crawl4ai.py +3 -0
  286. agno/tools/duckduckgo.py +25 -71
  287. agno/tools/exa.py +0 -21
  288. agno/tools/file.py +14 -13
  289. agno/tools/file_generation.py +12 -6
  290. agno/tools/firecrawl.py +15 -7
  291. agno/tools/function.py +94 -113
  292. agno/tools/google_bigquery.py +11 -2
  293. agno/tools/google_drive.py +4 -3
  294. agno/tools/knowledge.py +9 -4
  295. agno/tools/mcp/mcp.py +301 -18
  296. agno/tools/mcp/multi_mcp.py +269 -14
  297. agno/tools/mem0.py +11 -10
  298. agno/tools/memory.py +47 -46
  299. agno/tools/mlx_transcribe.py +10 -7
  300. agno/tools/models/nebius.py +5 -5
  301. agno/tools/models_labs.py +20 -10
  302. agno/tools/nano_banana.py +151 -0
  303. agno/tools/parallel.py +0 -7
  304. agno/tools/postgres.py +76 -36
  305. agno/tools/python.py +14 -6
  306. agno/tools/reasoning.py +30 -23
  307. agno/tools/redshift.py +406 -0
  308. agno/tools/shopify.py +1519 -0
  309. agno/tools/spotify.py +919 -0
  310. agno/tools/tavily.py +4 -1
  311. agno/tools/toolkit.py +253 -18
  312. agno/tools/websearch.py +93 -0
  313. agno/tools/website.py +1 -1
  314. agno/tools/wikipedia.py +1 -1
  315. agno/tools/workflow.py +56 -48
  316. agno/tools/yfinance.py +12 -11
  317. agno/tracing/__init__.py +12 -0
  318. agno/tracing/exporter.py +161 -0
  319. agno/tracing/schemas.py +276 -0
  320. agno/tracing/setup.py +112 -0
  321. agno/utils/agent.py +251 -10
  322. agno/utils/cryptography.py +22 -0
  323. agno/utils/dttm.py +33 -0
  324. agno/utils/events.py +264 -7
  325. agno/utils/hooks.py +111 -3
  326. agno/utils/http.py +161 -2
  327. agno/utils/mcp.py +49 -8
  328. agno/utils/media.py +22 -1
  329. agno/utils/models/ai_foundry.py +9 -2
  330. agno/utils/models/claude.py +20 -5
  331. agno/utils/models/cohere.py +9 -2
  332. agno/utils/models/llama.py +9 -2
  333. agno/utils/models/mistral.py +4 -2
  334. agno/utils/os.py +0 -0
  335. agno/utils/print_response/agent.py +99 -16
  336. agno/utils/print_response/team.py +223 -24
  337. agno/utils/print_response/workflow.py +0 -2
  338. agno/utils/prompts.py +8 -6
  339. agno/utils/remote.py +23 -0
  340. agno/utils/response.py +1 -13
  341. agno/utils/string.py +91 -2
  342. agno/utils/team.py +62 -12
  343. agno/utils/tokens.py +657 -0
  344. agno/vectordb/base.py +15 -2
  345. agno/vectordb/cassandra/cassandra.py +1 -1
  346. agno/vectordb/chroma/__init__.py +2 -1
  347. agno/vectordb/chroma/chromadb.py +468 -23
  348. agno/vectordb/clickhouse/clickhousedb.py +1 -1
  349. agno/vectordb/couchbase/couchbase.py +6 -2
  350. agno/vectordb/lancedb/lance_db.py +7 -38
  351. agno/vectordb/lightrag/lightrag.py +7 -6
  352. agno/vectordb/milvus/milvus.py +118 -84
  353. agno/vectordb/mongodb/__init__.py +2 -1
  354. agno/vectordb/mongodb/mongodb.py +14 -31
  355. agno/vectordb/pgvector/pgvector.py +120 -66
  356. agno/vectordb/pineconedb/pineconedb.py +2 -19
  357. agno/vectordb/qdrant/__init__.py +2 -1
  358. agno/vectordb/qdrant/qdrant.py +33 -56
  359. agno/vectordb/redis/__init__.py +2 -1
  360. agno/vectordb/redis/redisdb.py +19 -31
  361. agno/vectordb/singlestore/singlestore.py +17 -9
  362. agno/vectordb/surrealdb/surrealdb.py +2 -38
  363. agno/vectordb/weaviate/__init__.py +2 -1
  364. agno/vectordb/weaviate/weaviate.py +7 -3
  365. agno/workflow/__init__.py +5 -1
  366. agno/workflow/agent.py +2 -2
  367. agno/workflow/condition.py +12 -10
  368. agno/workflow/loop.py +28 -9
  369. agno/workflow/parallel.py +21 -13
  370. agno/workflow/remote.py +362 -0
  371. agno/workflow/router.py +12 -9
  372. agno/workflow/step.py +261 -36
  373. agno/workflow/steps.py +12 -8
  374. agno/workflow/types.py +40 -77
  375. agno/workflow/workflow.py +939 -213
  376. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/METADATA +134 -181
  377. agno-2.4.3.dist-info/RECORD +677 -0
  378. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/WHEEL +1 -1
  379. agno/tools/googlesearch.py +0 -98
  380. agno/tools/memori.py +0 -339
  381. agno-2.2.13.dist-info/RECORD +0 -575
  382. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/licenses/LICENSE +0 -0
  383. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/top_level.txt +0 -0
agno/team/remote.py ADDED
@@ -0,0 +1,447 @@
1
+ import json
2
+ from typing import TYPE_CHECKING, Any, AsyncIterator, Dict, List, Literal, Optional, Sequence, Tuple, Union, overload
3
+
4
+ from pydantic import BaseModel
5
+
6
+ from agno.media import Audio, File, Image, Video
7
+ from agno.models.base import Model
8
+ from agno.models.message import Message
9
+ from agno.remote.base import BaseRemote, RemoteDb, RemoteKnowledge
10
+ from agno.run.agent import RunOutputEvent
11
+ from agno.run.team import TeamRunOutput, TeamRunOutputEvent
12
+ from agno.utils.agent import validate_input
13
+ from agno.utils.log import log_warning
14
+ from agno.utils.remote import serialize_input
15
+
16
+ if TYPE_CHECKING:
17
+ from agno.os.routers.teams.schema import TeamResponse
18
+
19
+
20
+ class RemoteTeam(BaseRemote):
21
+ # Private cache for team config with TTL: (config, timestamp)
22
+ _cached_team_config: Optional[Tuple["TeamResponse", float]] = None
23
+
24
+ def __init__(
25
+ self,
26
+ base_url: str,
27
+ team_id: str,
28
+ timeout: float = 300.0,
29
+ protocol: Literal["agentos", "a2a"] = "agentos",
30
+ a2a_protocol: Literal["json-rpc", "rest"] = "rest",
31
+ config_ttl: float = 300.0,
32
+ ):
33
+ """Initialize RemoteTeam for remote execution.
34
+
35
+ Supports two protocols:
36
+ - "agentos": Agno's proprietary AgentOS REST API (default)
37
+ - "a2a": A2A (Agent-to-Agent) protocol for cross-framework communication
38
+
39
+ Args:
40
+ base_url: Base URL for remote instance (e.g., "http://localhost:7777")
41
+ team_id: ID of remote team on the remote server
42
+ timeout: Request timeout in seconds (default: 300)
43
+ protocol: Communication protocol - "agentos" (default) or "a2a"
44
+ a2a_protocol: For A2A protocol only - Whether to use JSON-RPC or REST protocol.
45
+ config_ttl: Time-to-live for cached config in seconds (default: 300)
46
+ """
47
+ super().__init__(base_url, timeout, protocol, a2a_protocol, config_ttl)
48
+ self.team_id = team_id
49
+ self._cached_team_config = None
50
+
51
+ @property
52
+ def id(self) -> str:
53
+ return self.team_id
54
+
55
+ async def get_team_config(self) -> "TeamResponse":
56
+ """
57
+ Get the team config from remote.
58
+
59
+ - For AgentOS protocol, always fetches fresh config from the remote.
60
+ - For A2A protocol, returns a minimal TeamResponse because A2A servers
61
+ do not expose detailed config endpoints.
62
+
63
+ Returns:
64
+ TeamResponse: The remote team configuration.
65
+ """
66
+ from agno.os.routers.teams.schema import TeamResponse
67
+
68
+ if self.a2a_client:
69
+ from agno.client.a2a.schemas import AgentCard
70
+
71
+ agent_card: Optional[AgentCard] = await self.a2a_client.aget_agent_card()
72
+
73
+ return TeamResponse(
74
+ id=self.team_id,
75
+ name=agent_card.name if agent_card else self.team_id,
76
+ description=agent_card.description if agent_card else f"A2A team: {self.team_id}",
77
+ )
78
+
79
+ # Fetch fresh config from remote for AgentOS
80
+ return await self.agentos_client.aget_team(self.team_id) # type: ignore
81
+
82
+ @property
83
+ def _team_config(self) -> Optional["TeamResponse"]:
84
+ """
85
+ Get the team config from remote, cached with TTL.
86
+
87
+ - Returns None for A2A protocol (no config available).
88
+ - For AgentOS protocol, uses TTL caching for efficiency.
89
+ """
90
+ import time
91
+
92
+ from agno.os.routers.teams.schema import TeamResponse
93
+
94
+ if self.a2a_client:
95
+ from agno.client.a2a.schemas import AgentCard
96
+
97
+ agent_card: Optional[AgentCard] = self.a2a_client.get_agent_card()
98
+
99
+ return TeamResponse(
100
+ id=self.team_id,
101
+ name=agent_card.name if agent_card else self.team_id,
102
+ description=agent_card.description if agent_card else f"A2A team: {self.team_id}",
103
+ )
104
+
105
+ current_time = time.time()
106
+ if self._cached_team_config is not None:
107
+ config, cached_at = self._cached_team_config
108
+ if current_time - cached_at < self.config_ttl:
109
+ return config
110
+
111
+ # Fetch fresh config and update cache
112
+ config: TeamResponse = self.agentos_client.get_team(self.team_id) # type: ignore
113
+ self._cached_team_config = (config, current_time)
114
+ return config
115
+
116
+ async def refresh_config(self) -> Optional["TeamResponse"]:
117
+ """
118
+ Force refresh the cached team config from remote.
119
+ """
120
+ import time
121
+
122
+ from agno.os.routers.teams.schema import TeamResponse
123
+
124
+ if self.a2a_client:
125
+ return None
126
+
127
+ config: TeamResponse = await self.agentos_client.aget_team(self.team_id) # type: ignore
128
+ self._cached_team_config = (config, time.time())
129
+ return config
130
+
131
+ @property
132
+ def name(self) -> Optional[str]:
133
+ config = self._team_config
134
+ if config is not None:
135
+ return config.name
136
+ return self.team_id
137
+
138
+ @property
139
+ def description(self) -> Optional[str]:
140
+ config = self._team_config
141
+ if config is not None:
142
+ return config.description
143
+ return ""
144
+
145
+ def role(self) -> Optional[str]:
146
+ if self._team_config is not None:
147
+ return self._team_config.role
148
+ return None
149
+
150
+ @property
151
+ def tools(self) -> Optional[List[Dict[str, Any]]]:
152
+ if self._team_config is not None:
153
+ try:
154
+ return json.loads(self._team_config.tools["tools"]) if self._team_config.tools else None
155
+ except Exception as e:
156
+ log_warning(f"Failed to load tools for team {self.team_id}: {e}")
157
+ return None
158
+ return None
159
+
160
+ @property
161
+ def db(self) -> Optional[RemoteDb]:
162
+ if (
163
+ self.agentos_client
164
+ and self._config
165
+ and self._team_config is not None
166
+ and self._team_config.db_id is not None
167
+ ):
168
+ return RemoteDb.from_config(
169
+ db_id=self._team_config.db_id,
170
+ client=self.agentos_client,
171
+ config=self._config,
172
+ )
173
+ return None
174
+
175
+ @property
176
+ def knowledge(self) -> Optional[RemoteKnowledge]:
177
+ """Whether the team has knowledge enabled."""
178
+ if self.agentos_client and self._team_config is not None and self._team_config.knowledge is not None:
179
+ return RemoteKnowledge(
180
+ client=self.agentos_client,
181
+ contents_db=RemoteDb(
182
+ id=self._team_config.knowledge.get("db_id"), # type: ignore
183
+ client=self.agentos_client,
184
+ knowledge_table_name=self._team_config.knowledge.get("knowledge_table"),
185
+ )
186
+ if self._team_config.knowledge.get("db_id") is not None
187
+ else None,
188
+ )
189
+ return None
190
+
191
+ @property
192
+ def model(self) -> Optional[Model]:
193
+ # We don't expose the remote team's models, since they can't be used by other services in AgentOS.
194
+ return None
195
+
196
+ @property
197
+ def user_id(self) -> Optional[str]:
198
+ return None
199
+
200
+ @overload
201
+ async def arun(
202
+ self,
203
+ input: Union[str, List, Dict, Message, BaseModel, List[Message]],
204
+ *,
205
+ stream: Literal[False] = False,
206
+ user_id: Optional[str] = None,
207
+ session_id: Optional[str] = None,
208
+ session_state: Optional[Dict[str, Any]] = None,
209
+ audio: Optional[Sequence[Audio]] = None,
210
+ images: Optional[Sequence[Image]] = None,
211
+ videos: Optional[Sequence[Video]] = None,
212
+ files: Optional[Sequence[File]] = None,
213
+ stream_events: Optional[bool] = None,
214
+ retries: Optional[int] = None,
215
+ knowledge_filters: Optional[Dict[str, Any]] = None,
216
+ add_history_to_context: Optional[bool] = None,
217
+ add_dependencies_to_context: Optional[bool] = None,
218
+ add_session_state_to_context: Optional[bool] = None,
219
+ dependencies: Optional[Dict[str, Any]] = None,
220
+ metadata: Optional[Dict[str, Any]] = None,
221
+ auth_token: Optional[str] = None,
222
+ **kwargs: Any,
223
+ ) -> TeamRunOutput: ...
224
+
225
+ @overload
226
+ def arun(
227
+ self,
228
+ input: Union[str, List, Dict, Message, BaseModel, List[Message]],
229
+ *,
230
+ stream: Literal[True] = True,
231
+ user_id: Optional[str] = None,
232
+ session_id: Optional[str] = None,
233
+ audio: Optional[Sequence[Audio]] = None,
234
+ images: Optional[Sequence[Image]] = None,
235
+ videos: Optional[Sequence[Video]] = None,
236
+ files: Optional[Sequence[File]] = None,
237
+ stream_events: Optional[bool] = None,
238
+ retries: Optional[int] = None,
239
+ knowledge_filters: Optional[Dict[str, Any]] = None,
240
+ add_history_to_context: Optional[bool] = None,
241
+ add_dependencies_to_context: Optional[bool] = None,
242
+ add_session_state_to_context: Optional[bool] = None,
243
+ dependencies: Optional[Dict[str, Any]] = None,
244
+ metadata: Optional[Dict[str, Any]] = None,
245
+ auth_token: Optional[str] = None,
246
+ **kwargs: Any,
247
+ ) -> AsyncIterator[TeamRunOutputEvent]: ...
248
+
249
+ def arun( # type: ignore
250
+ self,
251
+ input: Union[str, List, Dict, Message, BaseModel, List[Message]],
252
+ *,
253
+ stream: Optional[bool] = None,
254
+ user_id: Optional[str] = None,
255
+ session_id: Optional[str] = None,
256
+ session_state: Optional[Dict[str, Any]] = None,
257
+ audio: Optional[Sequence[Audio]] = None,
258
+ images: Optional[Sequence[Image]] = None,
259
+ videos: Optional[Sequence[Video]] = None,
260
+ files: Optional[Sequence[File]] = None,
261
+ stream_events: Optional[bool] = None,
262
+ retries: Optional[int] = None,
263
+ knowledge_filters: Optional[Dict[str, Any]] = None,
264
+ add_history_to_context: Optional[bool] = None,
265
+ add_dependencies_to_context: Optional[bool] = None,
266
+ add_session_state_to_context: Optional[bool] = None,
267
+ dependencies: Optional[Dict[str, Any]] = None,
268
+ metadata: Optional[Dict[str, Any]] = None,
269
+ auth_token: Optional[str] = None,
270
+ **kwargs: Any,
271
+ ) -> Union[
272
+ TeamRunOutput,
273
+ AsyncIterator[RunOutputEvent],
274
+ ]:
275
+ validated_input = validate_input(input)
276
+ serialized_input = serialize_input(validated_input)
277
+ headers = self._get_auth_headers(auth_token)
278
+
279
+ # A2A protocol path
280
+ if self.a2a_client:
281
+ return self._arun_a2a( # type: ignore[return-value]
282
+ message=serialized_input,
283
+ stream=stream or False,
284
+ user_id=user_id,
285
+ context_id=session_id, # Map session_id → context_id for A2A
286
+ audio=audio,
287
+ images=images,
288
+ videos=videos,
289
+ files=files,
290
+ headers=headers,
291
+ )
292
+
293
+ # AgentOS protocol path (default)
294
+ if self.agentos_client:
295
+ if stream:
296
+ # Handle streaming response
297
+ return self.agentos_client.run_team_stream( # type: ignore
298
+ team_id=self.team_id,
299
+ message=serialized_input,
300
+ session_id=session_id,
301
+ user_id=user_id,
302
+ audio=audio,
303
+ images=images,
304
+ videos=videos,
305
+ files=files,
306
+ session_state=session_state,
307
+ stream_events=stream_events,
308
+ retries=retries,
309
+ knowledge_filters=knowledge_filters,
310
+ add_history_to_context=add_history_to_context,
311
+ add_dependencies_to_context=add_dependencies_to_context,
312
+ add_session_state_to_context=add_session_state_to_context,
313
+ dependencies=dependencies,
314
+ metadata=metadata,
315
+ headers=headers,
316
+ **kwargs,
317
+ )
318
+ else:
319
+ return self.agentos_client.run_team( # type: ignore
320
+ team_id=self.team_id,
321
+ message=serialized_input,
322
+ session_id=session_id,
323
+ user_id=user_id,
324
+ audio=audio,
325
+ images=images,
326
+ videos=videos,
327
+ files=files,
328
+ session_state=session_state,
329
+ stream_events=stream_events,
330
+ retries=retries,
331
+ knowledge_filters=knowledge_filters,
332
+ add_history_to_context=add_history_to_context,
333
+ add_dependencies_to_context=add_dependencies_to_context,
334
+ add_session_state_to_context=add_session_state_to_context,
335
+ dependencies=dependencies,
336
+ metadata=metadata,
337
+ headers=headers,
338
+ **kwargs,
339
+ )
340
+ else:
341
+ raise ValueError("No client available")
342
+
343
+ def _arun_a2a(
344
+ self,
345
+ message: str,
346
+ stream: bool,
347
+ user_id: Optional[str],
348
+ context_id: Optional[str],
349
+ audio: Optional[Sequence[Audio]],
350
+ images: Optional[Sequence[Image]],
351
+ videos: Optional[Sequence[Video]],
352
+ files: Optional[Sequence[File]],
353
+ headers: Optional[Dict[str, str]],
354
+ ) -> Union[TeamRunOutput, AsyncIterator[TeamRunOutputEvent]]:
355
+ """Execute via A2A protocol.
356
+
357
+ Args:
358
+ message: Serialized message string
359
+ stream: Whether to stream the response
360
+ user_id: User identifier
361
+ context_id: Session/context ID (maps to session_id)
362
+ audio: Audio files to include
363
+ images: Images to include
364
+ videos: Videos to include
365
+ files: Files to include
366
+ headers: HTTP headers to include in the request (optional)
367
+ Returns:
368
+ TeamRunOutput for non-streaming, AsyncIterator[TeamRunOutputEvent] for streaming
369
+ """
370
+ from agno.client.a2a.utils import map_stream_events_to_team_run_events
371
+
372
+ if not self.a2a_client:
373
+ raise ValueError("A2A client not available")
374
+ if stream:
375
+ # Return async generator for streaming
376
+ event_stream = self.a2a_client.stream_message(
377
+ message=message,
378
+ context_id=context_id,
379
+ user_id=user_id,
380
+ audio=list(audio) if audio else None,
381
+ images=list(images) if images else None,
382
+ videos=list(videos) if videos else None,
383
+ files=list(files) if files else None,
384
+ headers=headers,
385
+ )
386
+ return map_stream_events_to_team_run_events(event_stream, team_id=self.team_id)
387
+ else:
388
+ # Return coroutine for non-streaming
389
+ return self._arun_a2a_send( # type: ignore[return-value]
390
+ message=message,
391
+ user_id=user_id,
392
+ context_id=context_id,
393
+ audio=audio,
394
+ images=images,
395
+ videos=videos,
396
+ files=files,
397
+ headers=headers,
398
+ )
399
+
400
+ async def _arun_a2a_send(
401
+ self,
402
+ message: str,
403
+ user_id: Optional[str],
404
+ context_id: Optional[str],
405
+ audio: Optional[Sequence[Audio]],
406
+ images: Optional[Sequence[Image]],
407
+ videos: Optional[Sequence[Video]],
408
+ files: Optional[Sequence[File]],
409
+ headers: Optional[Dict[str, str]],
410
+ ) -> TeamRunOutput:
411
+ """Send a non-streaming A2A message and convert response to TeamRunOutput."""
412
+ if not self.a2a_client:
413
+ raise ValueError("A2A client not available")
414
+ from agno.client.a2a.utils import map_task_result_to_team_run_output
415
+
416
+ task_result = await self.a2a_client.send_message(
417
+ message=message,
418
+ context_id=context_id,
419
+ user_id=user_id,
420
+ images=list(images) if images else None,
421
+ audio=list(audio) if audio else None,
422
+ videos=list(videos) if videos else None,
423
+ files=list(files) if files else None,
424
+ headers=headers,
425
+ )
426
+ return map_task_result_to_team_run_output(task_result, team_id=self.team_id, user_id=user_id)
427
+
428
+ async def acancel_run(self, run_id: str, auth_token: Optional[str] = None) -> bool:
429
+ """Cancel a running team execution.
430
+
431
+ Args:
432
+ run_id (str): The run_id to cancel.
433
+ auth_token: Optional JWT token for authentication.
434
+
435
+ Returns:
436
+ bool: True if the run was found and marked for cancellation, False otherwise.
437
+ """
438
+ headers = self._get_auth_headers(auth_token)
439
+ try:
440
+ await self.agentos_client.cancel_team_run( # type: ignore
441
+ team_id=self.team_id,
442
+ run_id=run_id,
443
+ headers=headers,
444
+ )
445
+ return True
446
+ except Exception:
447
+ return False