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
@@ -1,8 +1,8 @@
1
- from dataclasses import dataclass, field
1
+ from dataclasses import dataclass
2
2
  from os import getenv
3
3
  from typing import Any, Dict, Optional, cast
4
4
 
5
- from agno.exceptions import ModelProviderError
5
+ from agno.exceptions import ModelAuthenticationError
6
6
  from agno.models.openai.like import OpenAILike
7
7
 
8
8
  try:
@@ -30,20 +30,21 @@ class Portkey(OpenAILike):
30
30
  name: str = "Portkey"
31
31
  provider: str = "Portkey"
32
32
 
33
- portkey_api_key: Optional[str] = field(default_factory=lambda: getenv("PORTKEY_API_KEY"))
34
- virtual_key: Optional[str] = field(default_factory=lambda: getenv("PORTKEY_VIRTUAL_KEY"))
33
+ portkey_api_key: Optional[str] = None
34
+ virtual_key: Optional[str] = None
35
35
  config: Optional[Dict[str, Any]] = None
36
36
  base_url: str = PORTKEY_GATEWAY_URL
37
37
 
38
38
  def _get_client_params(self) -> Dict[str, Any]:
39
39
  # Check for required keys
40
40
  if not self.portkey_api_key:
41
- raise ModelProviderError(
41
+ raise ModelAuthenticationError(
42
42
  message="PORTKEY_API_KEY not set. Please set the PORTKEY_API_KEY environment variable.",
43
43
  model_name=self.name,
44
- model_id=self.id,
45
44
  )
46
45
 
46
+ self.virtual_key = self.virtual_key or getenv("PORTKEY_VIRTUAL_KEY")
47
+
47
48
  # Create headers using Portkey's createHeaders function
48
49
  header_params: Dict[str, Any] = {
49
50
  "api_key": self.portkey_api_key,
@@ -1,9 +1,10 @@
1
- from dataclasses import dataclass, field
1
+ from dataclasses import dataclass
2
2
  from os import getenv
3
3
  from typing import Any, Dict, List, Optional, Type, Union
4
4
 
5
5
  from pydantic import BaseModel
6
6
 
7
+ from agno.exceptions import ModelAuthenticationError
7
8
  from agno.models.openai.like import OpenAILike
8
9
  from agno.run.agent import RunOutput
9
10
  from agno.run.team import TeamRunOutput
@@ -26,10 +27,26 @@ class Requesty(OpenAILike):
26
27
  name: str = "Requesty"
27
28
  provider: str = "Requesty"
28
29
 
29
- api_key: Optional[str] = field(default_factory=lambda: getenv("REQUESTY_API_KEY"))
30
+ api_key: Optional[str] = None
30
31
  base_url: str = "https://router.requesty.ai/v1"
31
32
  max_tokens: int = 1024
32
33
 
34
+ def _get_client_params(self) -> Dict[str, Any]:
35
+ """
36
+ Returns client parameters for API requests, checking for REQUESTY_API_KEY.
37
+
38
+ Returns:
39
+ Dict[str, Any]: A dictionary of client parameters for API requests.
40
+ """
41
+ if not self.api_key:
42
+ self.api_key = getenv("REQUESTY_API_KEY")
43
+ if not self.api_key:
44
+ raise ModelAuthenticationError(
45
+ message="REQUESTY_API_KEY not set. Please set the REQUESTY_API_KEY environment variable.",
46
+ model_name=self.name,
47
+ )
48
+ return super()._get_client_params()
49
+
33
50
  def get_request_params(
34
51
  self,
35
52
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
agno/models/response.py CHANGED
@@ -16,6 +16,10 @@ class ModelResponseEvent(str, Enum):
16
16
  tool_call_started = "ToolCallStarted"
17
17
  tool_call_completed = "ToolCallCompleted"
18
18
  assistant_response = "AssistantResponse"
19
+ compression_started = "CompressionStarted"
20
+ compression_completed = "CompressionCompleted"
21
+ model_request_started = "ModelRequestStarted"
22
+ model_request_completed = "ModelRequestCompleted"
19
23
 
20
24
 
21
25
  @dataclass
@@ -35,9 +39,9 @@ class ToolExecution:
35
39
  # If True, the agent will stop executing after this tool call.
36
40
  stop_after_tool_call: bool = False
37
41
 
38
- created_at: int = int(time())
42
+ created_at: int = field(default_factory=lambda: int(time()))
39
43
 
40
- # User control flow requirements
44
+ # User control flow (HITL) fields
41
45
  requires_confirmation: Optional[bool] = None
42
46
  confirmed: Optional[bool] = None
43
47
  confirmation_note: Optional[str] = None
@@ -81,6 +85,7 @@ class ToolExecution:
81
85
  else None,
82
86
  external_execution_required=data.get("external_execution_required"),
83
87
  metrics=Metrics(**(data.get("metrics", {}) or {})),
88
+ **{"created_at": data["created_at"]} if "created_at" in data else {},
84
89
  )
85
90
 
86
91
 
@@ -123,6 +128,18 @@ class ModelResponse:
123
128
 
124
129
  updated_session_state: Optional[Dict[str, Any]] = None
125
130
 
131
+ # Compression stats
132
+ compression_stats: Optional[Dict[str, Any]] = None
133
+
134
+ # Model request metrics (for model_request_completed events)
135
+ input_tokens: Optional[int] = None
136
+ output_tokens: Optional[int] = None
137
+ total_tokens: Optional[int] = None
138
+ time_to_first_token: Optional[float] = None
139
+ reasoning_tokens: Optional[int] = None
140
+ cache_read_tokens: Optional[int] = None
141
+ cache_write_tokens: Optional[int] = None
142
+
126
143
  def to_dict(self) -> Dict[str, Any]:
127
144
  """Serialize ModelResponse to dictionary for caching."""
128
145
  _dict = asdict(self)
@@ -197,3 +214,4 @@ class FileType(str, Enum):
197
214
  MP4 = "mp4"
198
215
  GIF = "gif"
199
216
  MP3 = "mp3"
217
+ WAV = "wav"
@@ -1,7 +1,8 @@
1
- from dataclasses import dataclass, field
1
+ from dataclasses import dataclass
2
2
  from os import getenv
3
- from typing import Optional
3
+ from typing import Any, Dict, Optional
4
4
 
5
+ from agno.exceptions import ModelAuthenticationError
5
6
  from agno.models.openai.like import OpenAILike
6
7
 
7
8
 
@@ -22,7 +23,23 @@ class Sambanova(OpenAILike):
22
23
  name: str = "Sambanova"
23
24
  provider: str = "Sambanova"
24
25
 
25
- api_key: Optional[str] = field(default_factory=lambda: getenv("SAMBANOVA_API_KEY"))
26
+ api_key: Optional[str] = None
26
27
  base_url: str = "https://api.sambanova.ai/v1"
27
28
 
28
29
  supports_native_structured_outputs: bool = False
30
+
31
+ def _get_client_params(self) -> Dict[str, Any]:
32
+ """
33
+ Returns client parameters for API requests, checking for SAMBANOVA_API_KEY.
34
+
35
+ Returns:
36
+ Dict[str, Any]: A dictionary of client parameters for API requests.
37
+ """
38
+ if not self.api_key:
39
+ self.api_key = getenv("SAMBANOVA_API_KEY")
40
+ if not self.api_key:
41
+ raise ModelAuthenticationError(
42
+ message="SAMBANOVA_API_KEY not set. Please set the SAMBANOVA_API_KEY environment variable.",
43
+ model_name=self.name,
44
+ )
45
+ return super()._get_client_params()
@@ -1,7 +1,8 @@
1
1
  from dataclasses import dataclass
2
2
  from os import getenv
3
- from typing import Optional
3
+ from typing import Any, Dict, Optional
4
4
 
5
+ from agno.exceptions import ModelAuthenticationError
5
6
  from agno.models.openai.like import OpenAILike
6
7
 
7
8
 
@@ -21,5 +22,21 @@ class Siliconflow(OpenAILike):
21
22
  id: str = "Qwen/QwQ-32B"
22
23
  name: str = "Siliconflow"
23
24
  provider: str = "Siliconflow"
24
- api_key: Optional[str] = getenv("SILICONFLOW_API_KEY")
25
+ api_key: Optional[str] = None
25
26
  base_url: str = "https://api.siliconflow.com/v1"
27
+
28
+ def _get_client_params(self) -> Dict[str, Any]:
29
+ """
30
+ Returns client parameters for API requests, checking for SILICONFLOW_API_KEY.
31
+
32
+ Returns:
33
+ Dict[str, Any]: A dictionary of client parameters for API requests.
34
+ """
35
+ if not self.api_key:
36
+ self.api_key = getenv("SILICONFLOW_API_KEY")
37
+ if not self.api_key:
38
+ raise ModelAuthenticationError(
39
+ message="SILICONFLOW_API_KEY not set. Please set the SILICONFLOW_API_KEY environment variable.",
40
+ model_name=self.name,
41
+ )
42
+ return super()._get_client_params()
@@ -1,7 +1,8 @@
1
- from dataclasses import dataclass, field
1
+ from dataclasses import dataclass
2
2
  from os import getenv
3
- from typing import Optional
3
+ from typing import Any, Dict, Optional
4
4
 
5
+ from agno.exceptions import ModelAuthenticationError
5
6
  from agno.models.openai.like import OpenAILike
6
7
 
7
8
 
@@ -21,5 +22,21 @@ class Together(OpenAILike):
21
22
  id: str = "mistralai/Mixtral-8x7B-Instruct-v0.1"
22
23
  name: str = "Together"
23
24
  provider: str = "Together"
24
- api_key: Optional[str] = field(default_factory=lambda: getenv("TOGETHER_API_KEY"))
25
+ api_key: Optional[str] = None
25
26
  base_url: str = "https://api.together.xyz/v1"
27
+
28
+ def _get_client_params(self) -> Dict[str, Any]:
29
+ """
30
+ Returns client parameters for API requests, checking for TOGETHER_API_KEY.
31
+
32
+ Returns:
33
+ Dict[str, Any]: A dictionary of client parameters for API requests.
34
+ """
35
+ if not self.api_key:
36
+ self.api_key = getenv("TOGETHER_API_KEY")
37
+ if not self.api_key:
38
+ raise ModelAuthenticationError(
39
+ message="TOGETHER_API_KEY not set. Please set the TOGETHER_API_KEY environment variable.",
40
+ model_name=self.name,
41
+ )
42
+ return super()._get_client_params()
agno/models/vercel/v0.py CHANGED
@@ -1,7 +1,8 @@
1
- from dataclasses import dataclass, field
1
+ from dataclasses import dataclass
2
2
  from os import getenv
3
- from typing import Optional
3
+ from typing import Any, Dict, Optional
4
4
 
5
+ from agno.exceptions import ModelAuthenticationError
5
6
  from agno.models.openai.like import OpenAILike
6
7
 
7
8
 
@@ -22,5 +23,21 @@ class V0(OpenAILike):
22
23
  name: str = "v0"
23
24
  provider: str = "Vercel"
24
25
 
25
- api_key: Optional[str] = field(default_factory=lambda: getenv("V0_API_KEY"))
26
+ api_key: Optional[str] = None
26
27
  base_url: str = "https://api.v0.dev/v1/"
28
+
29
+ def _get_client_params(self) -> Dict[str, Any]:
30
+ """
31
+ Returns client parameters for API requests, checking for V0_API_KEY.
32
+
33
+ Returns:
34
+ Dict[str, Any]: A dictionary of client parameters for API requests.
35
+ """
36
+ if not self.api_key:
37
+ self.api_key = getenv("V0_API_KEY")
38
+ if not self.api_key:
39
+ raise ModelAuthenticationError(
40
+ message="V0_API_KEY not set. Please set the V0_API_KEY environment variable.",
41
+ model_name=self.name,
42
+ )
43
+ return super()._get_client_params()
@@ -1,8 +1,14 @@
1
1
  from dataclasses import dataclass
2
2
  from os import getenv
3
- from typing import Any, Dict, Optional
3
+ from typing import Any, Dict, List, Optional, Type, Union
4
+
5
+ import httpx
6
+ from pydantic import BaseModel
4
7
 
5
8
  from agno.models.anthropic import Claude as AnthropicClaude
9
+ from agno.utils.http import get_default_async_client, get_default_sync_client
10
+ from agno.utils.log import log_debug, log_warning
11
+ from agno.utils.models.claude import format_tools_for_model
6
12
 
7
13
  try:
8
14
  from anthropic import AnthropicVertex, AsyncAnthropicVertex
@@ -22,14 +28,23 @@ class Claude(AnthropicClaude):
22
28
  name: str = "Claude"
23
29
  provider: str = "VertexAI"
24
30
 
25
- client: Optional[AnthropicVertex] = None # type: ignore
26
- async_client: Optional[AsyncAnthropicVertex] = None # type: ignore
27
-
28
31
  # Client parameters
29
32
  region: Optional[str] = None
30
33
  project_id: Optional[str] = None
31
34
  base_url: Optional[str] = None
32
35
 
36
+ client: Optional[AnthropicVertex] = None # type: ignore
37
+ async_client: Optional[AsyncAnthropicVertex] = None # type: ignore
38
+
39
+ def __post_init__(self):
40
+ """Validate model configuration after initialization"""
41
+ # Validate thinking support immediately at model creation
42
+ if self.thinking:
43
+ self._validate_thinking_support()
44
+ # Overwrite output schema support for VertexAI Claude
45
+ self.supports_native_structured_outputs = False
46
+ self.supports_json_schema_outputs = False
47
+
33
48
  def _get_client_params(self) -> Dict[str, Any]:
34
49
  client_params: Dict[str, Any] = {}
35
50
 
@@ -55,6 +70,16 @@ class Claude(AnthropicClaude):
55
70
  return self.client
56
71
 
57
72
  _client_params = self._get_client_params()
73
+ if self.http_client:
74
+ if isinstance(self.http_client, httpx.Client):
75
+ _client_params["http_client"] = self.http_client
76
+ else:
77
+ log_warning("http_client is not an instance of httpx.Client. Using default global httpx.Client.")
78
+ # Use global sync client when user http_client is invalid
79
+ _client_params["http_client"] = get_default_sync_client()
80
+ else:
81
+ # Use global sync client when no custom http_client is provided
82
+ _client_params["http_client"] = get_default_sync_client()
58
83
  self.client = AnthropicVertex(**_client_params)
59
84
  return self.client
60
85
 
@@ -66,5 +91,100 @@ class Claude(AnthropicClaude):
66
91
  return self.async_client
67
92
 
68
93
  _client_params = self._get_client_params()
94
+ if self.http_client:
95
+ if isinstance(self.http_client, httpx.AsyncClient):
96
+ _client_params["http_client"] = self.http_client
97
+ else:
98
+ log_warning(
99
+ "http_client is not an instance of httpx.AsyncClient. Using default global httpx.AsyncClient."
100
+ )
101
+ # Use global async client when user http_client is invalid
102
+ _client_params["http_client"] = get_default_async_client()
103
+ else:
104
+ # Use global async client when no custom http_client is provided
105
+ _client_params["http_client"] = get_default_async_client()
69
106
  self.async_client = AsyncAnthropicVertex(**_client_params)
70
107
  return self.async_client
108
+
109
+ def get_request_params(
110
+ self,
111
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
112
+ tools: Optional[List[Dict[str, Any]]] = None,
113
+ ) -> Dict[str, Any]:
114
+ """
115
+ Generate keyword arguments for API requests.
116
+
117
+ Returns:
118
+ Dict[str, Any]: The keyword arguments for API requests.
119
+ """
120
+ # Validate thinking support if thinking is enabled
121
+ if self.thinking:
122
+ self._validate_thinking_support()
123
+
124
+ _request_params: Dict[str, Any] = {}
125
+ if self.max_tokens:
126
+ _request_params["max_tokens"] = self.max_tokens
127
+ if self.thinking:
128
+ _request_params["thinking"] = self.thinking
129
+ if self.temperature:
130
+ _request_params["temperature"] = self.temperature
131
+ if self.stop_sequences:
132
+ _request_params["stop_sequences"] = self.stop_sequences
133
+ if self.top_p:
134
+ _request_params["top_p"] = self.top_p
135
+ if self.top_k:
136
+ _request_params["top_k"] = self.top_k
137
+ if self.timeout:
138
+ _request_params["timeout"] = self.timeout
139
+
140
+ # Build betas list - include existing betas and add new one if needed
141
+ betas_list = list(self.betas) if self.betas else []
142
+
143
+ # Include betas if any are present
144
+ if betas_list:
145
+ _request_params["betas"] = betas_list
146
+
147
+ if self.request_params:
148
+ _request_params.update(self.request_params)
149
+
150
+ if _request_params:
151
+ log_debug(f"Calling {self.provider} with request parameters: {_request_params}", log_level=2)
152
+ return _request_params
153
+
154
+ def _prepare_request_kwargs(
155
+ self,
156
+ system_message: str,
157
+ tools: Optional[List[Dict[str, Any]]] = None,
158
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
159
+ ) -> Dict[str, Any]:
160
+ """
161
+ Prepare the request keyword arguments for the API call.
162
+
163
+ Args:
164
+ system_message (str): The concatenated system messages.
165
+ tools: Optional list of tools
166
+ response_format: Optional response format (Pydantic model or dict)
167
+
168
+ Returns:
169
+ Dict[str, Any]: The request keyword arguments.
170
+ """
171
+ # Pass response_format and tools to get_request_params for beta header handling
172
+ request_kwargs = self.get_request_params(response_format=response_format, tools=tools).copy()
173
+ if system_message:
174
+ if self.cache_system_prompt:
175
+ cache_control = (
176
+ {"type": "ephemeral", "ttl": "1h"}
177
+ if self.extended_cache_time is not None and self.extended_cache_time is True
178
+ else {"type": "ephemeral"}
179
+ )
180
+ request_kwargs["system"] = [{"text": system_message, "type": "text", "cache_control": cache_control}]
181
+ else:
182
+ request_kwargs["system"] = [{"text": system_message, "type": "text"}]
183
+
184
+ # Format tools (this will handle strict mode)
185
+ if tools:
186
+ request_kwargs["tools"] = format_tools_for_model(tools)
187
+
188
+ if request_kwargs:
189
+ log_debug(f"Calling {self.provider} with request parameters: {request_kwargs}", log_level=2)
190
+ return request_kwargs
agno/models/vllm/vllm.py CHANGED
@@ -4,6 +4,7 @@ from typing import Any, Dict, List, Optional, Type, Union
4
4
 
5
5
  from pydantic import BaseModel
6
6
 
7
+ from agno.exceptions import ModelAuthenticationError
7
8
  from agno.models.openai.like import OpenAILike
8
9
  from agno.utils.log import log_debug
9
10
 
@@ -29,8 +30,8 @@ class VLLM(OpenAILike):
29
30
  name: str = "VLLM"
30
31
  provider: str = "VLLM"
31
32
 
32
- api_key: Optional[str] = getenv("VLLM_API_KEY") or "EMPTY"
33
- base_url: Optional[str] = getenv("VLLM_BASE_URL", "http://localhost:8000/v1/")
33
+ api_key: Optional[str] = None
34
+ base_url: Optional[str] = None
34
35
 
35
36
  temperature: float = 0.7
36
37
  top_p: float = 0.8
@@ -38,19 +39,23 @@ class VLLM(OpenAILike):
38
39
  top_k: Optional[int] = None
39
40
  enable_thinking: Optional[bool] = None
40
41
 
41
- def __post_init__(self):
42
- """Validate required configuration"""
43
- if not self.base_url:
44
- raise ValueError("VLLM_BASE_URL must be set via environment variable or explicit initialization")
45
- if self.id == "not-set":
46
- raise ValueError("Model ID must be set via environment variable or explicit initialization")
42
+ def _get_client_params(self) -> Dict[str, Any]:
43
+ """
44
+ Returns client parameters for API requests, checking for VLLM_API_KEY.
47
45
 
48
- body: Dict[str, Any] = {}
49
- if self.top_k is not None:
50
- body["top_k"] = self.top_k
51
- if self.enable_thinking is not None:
52
- body["chat_template_kwargs"] = {"enable_thinking": self.enable_thinking}
53
- self.extra_body = body or None
46
+ Returns:
47
+ Dict[str, Any]: A dictionary of client parameters for API requests.
48
+ """
49
+ if not self.api_key:
50
+ self.api_key = getenv("VLLM_API_KEY")
51
+ if not self.api_key:
52
+ raise ModelAuthenticationError(
53
+ message="VLLM_API_KEY not set. Please set the VLLM_API_KEY environment variable.",
54
+ model_name=self.name,
55
+ )
56
+ if not self.base_url:
57
+ self.base_url = getenv("VLLM_BASE_URL", "http://localhost:8000/v1/")
58
+ return super()._get_client_params()
54
59
 
55
60
  def get_request_params(
56
61
  self,
agno/models/xai/xai.py CHANGED
@@ -1,9 +1,10 @@
1
- from dataclasses import dataclass, field
1
+ from dataclasses import dataclass
2
2
  from os import getenv
3
3
  from typing import Any, Dict, List, Optional, Type, Union
4
4
 
5
5
  from pydantic import BaseModel
6
6
 
7
+ from agno.exceptions import ModelAuthenticationError
7
8
  from agno.models.message import Citations, UrlCitation
8
9
  from agno.models.openai.like import OpenAILike
9
10
  from agno.models.response import ModelResponse
@@ -34,11 +35,27 @@ class xAI(OpenAILike):
34
35
  name: str = "xAI"
35
36
  provider: str = "xAI"
36
37
 
37
- api_key: Optional[str] = field(default_factory=lambda: getenv("XAI_API_KEY"))
38
+ api_key: Optional[str] = None
38
39
  base_url: str = "https://api.x.ai/v1"
39
40
 
40
41
  search_parameters: Optional[Dict[str, Any]] = None
41
42
 
43
+ def _get_client_params(self) -> Dict[str, Any]:
44
+ """
45
+ Returns client parameters for API requests, checking for XAI_API_KEY.
46
+
47
+ Returns:
48
+ Dict[str, Any]: A dictionary of client parameters for API requests.
49
+ """
50
+ if not self.api_key:
51
+ self.api_key = getenv("XAI_API_KEY")
52
+ if not self.api_key:
53
+ raise ModelAuthenticationError(
54
+ message="XAI_API_KEY not set. Please set the XAI_API_KEY environment variable.",
55
+ model_name=self.name,
56
+ )
57
+ return super()._get_client_params()
58
+
42
59
  def get_request_params(
43
60
  self,
44
61
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,