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/models/aws/claude.py CHANGED
@@ -1,19 +1,17 @@
1
1
  from dataclasses import dataclass
2
2
  from os import getenv
3
- from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, Type, Union
3
+ from typing import Any, Dict, List, Optional, Type, Union
4
4
 
5
+ import httpx
5
6
  from pydantic import BaseModel
6
7
 
7
- from agno.exceptions import ModelProviderError, ModelRateLimitError
8
8
  from agno.models.anthropic import Claude as AnthropicClaude
9
- from agno.models.message import Message
10
- from agno.models.response import ModelResponse
11
- from agno.run.agent import RunOutput
12
- from agno.utils.log import log_debug, log_error, log_warning
13
- from agno.utils.models.claude import format_messages
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
14
12
 
15
13
  try:
16
- from anthropic import AnthropicBedrock, APIConnectionError, APIStatusError, AsyncAnthropicBedrock, RateLimitError
14
+ from anthropic import AnthropicBedrock, AsyncAnthropicBedrock
17
15
  except ImportError:
18
16
  raise ImportError("`anthropic[bedrock]` not installed. Please install using `pip install anthropic[bedrock]`")
19
17
 
@@ -31,44 +29,69 @@ class Claude(AnthropicClaude):
31
29
  For more information, see: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic.html
32
30
  """
33
31
 
34
- id: str = "anthropic.claude-3-5-sonnet-20240620-v1:0"
32
+ id: str = "global.anthropic.claude-sonnet-4-5-20250929-v1:0"
35
33
  name: str = "AwsBedrockAnthropicClaude"
36
34
  provider: str = "AwsBedrock"
37
35
 
38
36
  aws_access_key: Optional[str] = None
39
37
  aws_secret_key: Optional[str] = None
40
38
  aws_region: Optional[str] = None
39
+ api_key: Optional[str] = None
41
40
  session: Optional[Session] = None
42
41
 
43
- # -*- Request parameters
44
- max_tokens: int = 4096
45
- temperature: Optional[float] = None
46
- top_p: Optional[float] = None
47
- top_k: Optional[int] = None
48
- stop_sequences: Optional[List[str]] = None
42
+ client: Optional[AnthropicBedrock] = None # type: ignore
43
+ async_client: Optional[AsyncAnthropicBedrock] = None # type: ignore
49
44
 
50
- # -*- Request parameters
51
- request_params: Optional[Dict[str, Any]] = None
52
- # -*- Client parameters
53
- client_params: Optional[Dict[str, Any]] = None
45
+ def __post_init__(self):
46
+ """Validate model configuration after initialization"""
47
+ # Validate thinking support immediately at model creation
48
+ if self.thinking:
49
+ self._validate_thinking_support()
50
+ # Overwrite output schema support for AWS Bedrock Claude
51
+ self.supports_native_structured_outputs = False
52
+ self.supports_json_schema_outputs = False
54
53
 
55
- def to_dict(self) -> Dict[str, Any]:
56
- """
57
- Convert the model to a dictionary.
54
+ def _get_client_params(self) -> Dict[str, Any]:
55
+ if self.session:
56
+ credentials = self.session.get_credentials()
57
+ client_params: Dict[str, Any] = {
58
+ "aws_access_key": credentials.access_key,
59
+ "aws_secret_key": credentials.secret_key,
60
+ "aws_session_token": credentials.token,
61
+ "aws_region": self.session.region_name,
62
+ }
63
+ else:
64
+ self.api_key = self.api_key or getenv("AWS_BEDROCK_API_KEY")
65
+ if self.api_key:
66
+ self.aws_region = self.aws_region or getenv("AWS_REGION")
67
+ client_params = {
68
+ "api_key": self.api_key,
69
+ }
70
+ if self.aws_region:
71
+ client_params["aws_region"] = self.aws_region
72
+ else:
73
+ self.aws_access_key = self.aws_access_key or getenv("AWS_ACCESS_KEY_ID") or getenv("AWS_ACCESS_KEY")
74
+ self.aws_secret_key = self.aws_secret_key or getenv("AWS_SECRET_ACCESS_KEY") or getenv("AWS_SECRET_KEY")
75
+ self.aws_region = self.aws_region or getenv("AWS_REGION")
76
+
77
+ client_params = {
78
+ "aws_secret_key": self.aws_secret_key,
79
+ "aws_access_key": self.aws_access_key,
80
+ "aws_region": self.aws_region,
81
+ }
82
+
83
+ if not (self.api_key or (self.aws_access_key and self.aws_secret_key)):
84
+ log_warning(
85
+ "AWS credentials not found. Please set AWS_BEDROCK_API_KEY or AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables or provide a boto3 session."
86
+ )
87
+
88
+ if self.timeout is not None:
89
+ client_params["timeout"] = self.timeout
58
90
 
59
- Returns:
60
- Dict[str, Any]: The dictionary representation of the model.
61
- """
62
- _dict = super().to_dict()
63
- _dict["max_tokens"] = self.max_tokens
64
- _dict["temperature"] = self.temperature
65
- _dict["top_p"] = self.top_p
66
- _dict["top_k"] = self.top_k
67
- _dict["stop_sequences"] = self.stop_sequences
68
- return _dict
91
+ if self.client_params:
92
+ client_params.update(self.client_params)
69
93
 
70
- client: Optional[AnthropicBedrock] = None # type: ignore
71
- async_client: Optional[AsyncAnthropicBedrock] = None # type: ignore
94
+ return client_params
72
95
 
73
96
  def get_client(self):
74
97
  """
@@ -80,27 +103,18 @@ class Claude(AnthropicClaude):
80
103
  if self.client is not None and not self.client.is_closed():
81
104
  return self.client
82
105
 
83
- if self.session:
84
- credentials = self.session.get_credentials()
85
- client_params = {
86
- "aws_access_key": credentials.access_key,
87
- "aws_secret_key": credentials.secret_key,
88
- "aws_session_token": credentials.token,
89
- "aws_region": self.session.region_name,
90
- }
91
- else:
92
- self.aws_access_key = self.aws_access_key or getenv("AWS_ACCESS_KEY")
93
- self.aws_secret_key = self.aws_secret_key or getenv("AWS_SECRET_KEY")
94
- self.aws_region = self.aws_region or getenv("AWS_REGION")
95
-
96
- client_params = {
97
- "aws_secret_key": self.aws_secret_key,
98
- "aws_access_key": self.aws_access_key,
99
- "aws_region": self.aws_region,
100
- }
106
+ client_params = self._get_client_params()
101
107
 
102
- if self.client_params:
103
- client_params.update(self.client_params)
108
+ if self.http_client:
109
+ if isinstance(self.http_client, httpx.Client):
110
+ client_params["http_client"] = self.http_client
111
+ else:
112
+ log_warning("http_client is not an instance of httpx.Client. Using default global httpx.Client.")
113
+ # Use global sync client when user http_client is invalid
114
+ client_params["http_client"] = get_default_sync_client()
115
+ else:
116
+ # Use global sync client when no custom http_client is provided
117
+ client_params["http_client"] = get_default_sync_client()
104
118
 
105
119
  self.client = AnthropicBedrock(
106
120
  **client_params, # type: ignore
@@ -117,39 +131,46 @@ class Claude(AnthropicClaude):
117
131
  if self.async_client is not None:
118
132
  return self.async_client
119
133
 
120
- if self.session:
121
- credentials = self.session.get_credentials()
122
- client_params = {
123
- "aws_access_key": credentials.access_key,
124
- "aws_secret_key": credentials.secret_key,
125
- "aws_session_token": credentials.token,
126
- "aws_region": self.session.region_name,
127
- }
134
+ client_params = self._get_client_params()
135
+
136
+ if self.http_client:
137
+ if isinstance(self.http_client, httpx.AsyncClient):
138
+ client_params["http_client"] = self.http_client
139
+ else:
140
+ log_warning(
141
+ "http_client is not an instance of httpx.AsyncClient. Using default global httpx.AsyncClient."
142
+ )
143
+ # Use global async client when user http_client is invalid
144
+ client_params["http_client"] = get_default_async_client()
128
145
  else:
129
- client_params = {
130
- "aws_secret_key": self.aws_secret_key,
131
- "aws_access_key": self.aws_access_key,
132
- "aws_region": self.aws_region,
133
- }
134
-
135
- if self.client_params:
136
- client_params.update(self.client_params)
146
+ # Use global async client when no custom http_client is provided
147
+ client_params["http_client"] = get_default_async_client()
137
148
 
138
149
  self.async_client = AsyncAnthropicBedrock(
139
150
  **client_params, # type: ignore
140
151
  )
141
152
  return self.async_client
142
153
 
143
- def get_request_params(self) -> Dict[str, Any]:
154
+ def get_request_params(
155
+ self,
156
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
157
+ tools: Optional[List[Dict[str, Any]]] = None,
158
+ ) -> Dict[str, Any]:
144
159
  """
145
160
  Generate keyword arguments for API requests.
146
161
 
147
162
  Returns:
148
163
  Dict[str, Any]: The keyword arguments for API requests.
149
164
  """
165
+ # Validate thinking support if thinking is enabled
166
+ if self.thinking:
167
+ self._validate_thinking_support()
168
+
150
169
  _request_params: Dict[str, Any] = {}
151
170
  if self.max_tokens:
152
171
  _request_params["max_tokens"] = self.max_tokens
172
+ if self.thinking:
173
+ _request_params["thinking"] = self.thinking
153
174
  if self.temperature:
154
175
  _request_params["temperature"] = self.temperature
155
176
  if self.stop_sequences:
@@ -158,6 +179,16 @@ class Claude(AnthropicClaude):
158
179
  _request_params["top_p"] = self.top_p
159
180
  if self.top_k:
160
181
  _request_params["top_k"] = self.top_k
182
+ if self.timeout:
183
+ _request_params["timeout"] = self.timeout
184
+
185
+ # Build betas list - include existing betas and add new one if needed
186
+ betas_list = list(self.betas) if self.betas else []
187
+
188
+ # Include betas if any are present
189
+ if betas_list:
190
+ _request_params["betas"] = betas_list
191
+
161
192
  if self.request_params:
162
193
  _request_params.update(self.request_params)
163
194
 
@@ -165,214 +196,40 @@ class Claude(AnthropicClaude):
165
196
  log_debug(f"Calling {self.provider} with request parameters: {_request_params}", log_level=2)
166
197
  return _request_params
167
198
 
168
- def invoke(
169
- self,
170
- messages: List[Message],
171
- assistant_message: Message,
172
- response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
173
- tools: Optional[List[Dict[str, Any]]] = None,
174
- tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
175
- run_response: Optional[RunOutput] = None,
176
- ) -> ModelResponse:
177
- """
178
- Send a request to the Anthropic API to generate a response.
179
- """
180
-
181
- try:
182
- chat_messages, system_message = format_messages(messages)
183
- request_kwargs = self._prepare_request_kwargs(system_message, tools)
184
-
185
- if run_response and run_response.metrics:
186
- run_response.metrics.set_time_to_first_token()
187
-
188
- assistant_message.metrics.start_timer()
189
- response = self.get_client().messages.create(
190
- model=self.id,
191
- messages=chat_messages, # type: ignore
192
- **request_kwargs,
193
- )
194
- assistant_message.metrics.stop_timer()
195
-
196
- model_response = self._parse_provider_response(response, response_format=response_format)
197
-
198
- return model_response
199
-
200
- except APIConnectionError as e:
201
- log_error(f"Connection error while calling Claude API: {str(e)}")
202
- raise ModelProviderError(message=e.message, model_name=self.name, model_id=self.id) from e
203
- except RateLimitError as e:
204
- log_warning(f"Rate limit exceeded: {str(e)}")
205
- raise ModelRateLimitError(message=e.message, model_name=self.name, model_id=self.id) from e
206
- except APIStatusError as e:
207
- log_error(f"Claude API error (status {e.status_code}): {str(e)}")
208
- raise ModelProviderError(
209
- message=e.message, status_code=e.status_code, model_name=self.name, model_id=self.id
210
- ) from e
211
- except Exception as e:
212
- log_error(f"Unexpected error calling Claude API: {str(e)}")
213
- raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
214
-
215
- def invoke_stream(
216
- self,
217
- messages: List[Message],
218
- assistant_message: Message,
219
- response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
220
- tools: Optional[List[Dict[str, Any]]] = None,
221
- tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
222
- run_response: Optional[RunOutput] = None,
223
- ) -> Iterator[ModelResponse]:
224
- """
225
- Stream a response from the Anthropic API.
226
-
227
- Args:
228
- messages (List[Message]): A list of messages to send to the model.
229
-
230
- Returns:
231
- Any: The streamed response from the model.
232
-
233
- Raises:
234
- APIConnectionError: If there are network connectivity issues
235
- RateLimitError: If the API rate limit is exceeded
236
- APIStatusError: For other API-related errors
237
- """
238
-
239
- chat_messages, system_message = format_messages(messages)
240
- request_kwargs = self._prepare_request_kwargs(system_message, tools)
241
-
242
- try:
243
- if run_response and run_response.metrics:
244
- run_response.metrics.set_time_to_first_token()
245
-
246
- assistant_message.metrics.start_timer()
247
-
248
- with self.get_client().messages.stream(
249
- model=self.id,
250
- messages=chat_messages, # type: ignore
251
- **request_kwargs,
252
- ) as stream:
253
- for chunk in stream:
254
- yield self._parse_provider_response_delta(chunk)
255
-
256
- assistant_message.metrics.stop_timer()
257
-
258
- except APIConnectionError as e:
259
- log_error(f"Connection error while calling Claude API: {str(e)}")
260
- raise ModelProviderError(message=e.message, model_name=self.name, model_id=self.id) from e
261
- except RateLimitError as e:
262
- log_warning(f"Rate limit exceeded: {str(e)}")
263
- raise ModelRateLimitError(message=e.message, model_name=self.name, model_id=self.id) from e
264
- except APIStatusError as e:
265
- log_error(f"Claude API error (status {e.status_code}): {str(e)}")
266
- raise ModelProviderError(
267
- message=e.message, status_code=e.status_code, model_name=self.name, model_id=self.id
268
- ) from e
269
- except Exception as e:
270
- log_error(f"Unexpected error calling Claude API: {str(e)}")
271
- raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
272
-
273
- async def ainvoke(
199
+ def _prepare_request_kwargs(
274
200
  self,
275
- messages: List[Message],
276
- assistant_message: Message,
277
- response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
201
+ system_message: str,
278
202
  tools: Optional[List[Dict[str, Any]]] = None,
279
- tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
280
- run_response: Optional[RunOutput] = None,
281
- ) -> ModelResponse:
282
- """
283
- Send an asynchronous request to the Anthropic API to generate a response.
284
- """
285
-
286
- try:
287
- chat_messages, system_message = format_messages(messages)
288
- request_kwargs = self._prepare_request_kwargs(system_message, tools)
289
-
290
- if run_response and run_response.metrics:
291
- run_response.metrics.set_time_to_first_token()
292
-
293
- assistant_message.metrics.start_timer()
294
-
295
- response = await self.get_async_client().messages.create(
296
- model=self.id,
297
- messages=chat_messages, # type: ignore
298
- **request_kwargs,
299
- )
300
-
301
- assistant_message.metrics.stop_timer()
302
-
303
- model_response = self._parse_provider_response(response, response_format=response_format)
304
-
305
- return model_response
306
-
307
- except APIConnectionError as e:
308
- log_error(f"Connection error while calling Claude API: {str(e)}")
309
- raise ModelProviderError(message=e.message, model_name=self.name, model_id=self.id) from e
310
- except RateLimitError as e:
311
- log_warning(f"Rate limit exceeded: {str(e)}")
312
- raise ModelRateLimitError(message=e.message, model_name=self.name, model_id=self.id) from e
313
- except APIStatusError as e:
314
- log_error(f"Claude API error (status {e.status_code}): {str(e)}")
315
- raise ModelProviderError(
316
- message=e.message, status_code=e.status_code, model_name=self.name, model_id=self.id
317
- ) from e
318
- except Exception as e:
319
- log_error(f"Unexpected error calling Claude API: {str(e)}")
320
- raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
321
-
322
- async def ainvoke_stream(
323
- self,
324
- messages: List[Message],
325
- assistant_message: Message,
326
203
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
327
- tools: Optional[List[Dict[str, Any]]] = None,
328
- tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
329
- run_response: Optional[RunOutput] = None,
330
- ) -> AsyncIterator[ModelResponse]:
204
+ ) -> Dict[str, Any]:
331
205
  """
332
- Stream an asynchronous response from the Anthropic API.
206
+ Prepare the request keyword arguments for the API call.
333
207
 
334
208
  Args:
335
- messages (List[Message]): A list of messages to send to the model.
209
+ system_message (str): The concatenated system messages.
210
+ tools: Optional list of tools
211
+ response_format: Optional response format (Pydantic model or dict)
336
212
 
337
213
  Returns:
338
- Any: The streamed response from the model.
339
-
340
- Raises:
341
- APIConnectionError: If there are network connectivity issues
342
- RateLimitError: If the API rate limit is exceeded
343
- APIStatusError: For other API-related errors
344
- """
345
-
346
- try:
347
- chat_messages, system_message = format_messages(messages)
348
- request_kwargs = self._prepare_request_kwargs(system_message, tools)
349
-
350
- if run_response and run_response.metrics:
351
- run_response.metrics.set_time_to_first_token()
352
-
353
- assistant_message.metrics.start_timer()
354
-
355
- async with self.get_async_client().messages.stream(
356
- model=self.id,
357
- messages=chat_messages, # type: ignore
358
- **request_kwargs,
359
- ) as stream:
360
- async for chunk in stream:
361
- yield self._parse_provider_response_delta(chunk)
362
-
363
- assistant_message.metrics.stop_timer()
364
-
365
- except APIConnectionError as e:
366
- log_error(f"Connection error while calling Claude API: {str(e)}")
367
- raise ModelProviderError(message=e.message, model_name=self.name, model_id=self.id) from e
368
- except RateLimitError as e:
369
- log_warning(f"Rate limit exceeded: {str(e)}")
370
- raise ModelRateLimitError(message=e.message, model_name=self.name, model_id=self.id) from e
371
- except APIStatusError as e:
372
- log_error(f"Claude API error (status {e.status_code}): {str(e)}")
373
- raise ModelProviderError(
374
- message=e.message, status_code=e.status_code, model_name=self.name, model_id=self.id
375
- ) from e
376
- except Exception as e:
377
- log_error(f"Unexpected error calling Claude API: {str(e)}")
378
- raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
214
+ Dict[str, Any]: The request keyword arguments.
215
+ """
216
+ # Pass response_format and tools to get_request_params for beta header handling
217
+ request_kwargs = self.get_request_params(response_format=response_format, tools=tools).copy()
218
+ if system_message:
219
+ if self.cache_system_prompt:
220
+ cache_control = (
221
+ {"type": "ephemeral", "ttl": "1h"}
222
+ if self.extended_cache_time is not None and self.extended_cache_time is True
223
+ else {"type": "ephemeral"}
224
+ )
225
+ request_kwargs["system"] = [{"text": system_message, "type": "text", "cache_control": cache_control}]
226
+ else:
227
+ request_kwargs["system"] = [{"text": system_message, "type": "text"}]
228
+
229
+ # Format tools (this will handle strict mode)
230
+ if tools:
231
+ request_kwargs["tools"] = format_tools_for_model(tools)
232
+
233
+ if request_kwargs:
234
+ log_debug(f"Calling {self.provider} with request parameters: {request_kwargs}", log_level=2)
235
+ return request_kwargs
@@ -136,9 +136,9 @@ class AzureAIFoundry(Model):
136
136
  self.azure_endpoint = self.azure_endpoint or getenv("AZURE_ENDPOINT")
137
137
 
138
138
  if not self.api_key:
139
- raise ValueError("API key is required")
139
+ log_error("AZURE_API_KEY not set. Please set the AZURE_API_KEY environment variable.")
140
140
  if not self.azure_endpoint:
141
- raise ValueError("Endpoint URL is required")
141
+ log_error("AZURE_ENDPOINT not set. Please set the AZURE_ENDPOINT environment variable.")
142
142
 
143
143
  base_params = {
144
144
  "endpoint": self.azure_endpoint,
@@ -207,6 +207,7 @@ class AzureAIFoundry(Model):
207
207
  tools: Optional[List[Dict[str, Any]]] = None,
208
208
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
209
209
  run_response: Optional[RunOutput] = None,
210
+ compress_tool_results: bool = False,
210
211
  ) -> ModelResponse:
211
212
  """
212
213
  Send a chat completion request to the Azure AI API.
@@ -217,7 +218,7 @@ class AzureAIFoundry(Model):
217
218
 
218
219
  assistant_message.metrics.start_timer()
219
220
  provider_response = self.get_client().complete(
220
- messages=[format_message(m) for m in messages],
221
+ messages=[format_message(m, compress_tool_results) for m in messages],
221
222
  **self.get_request_params(tools=tools, response_format=response_format, tool_choice=tool_choice),
222
223
  )
223
224
  assistant_message.metrics.stop_timer()
@@ -246,6 +247,7 @@ class AzureAIFoundry(Model):
246
247
  tools: Optional[List[Dict[str, Any]]] = None,
247
248
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
248
249
  run_response: Optional[RunOutput] = None,
250
+ compress_tool_results: bool = False,
249
251
  ) -> ModelResponse:
250
252
  """
251
253
  Sends an asynchronous chat completion request to the Azure AI API.
@@ -257,7 +259,7 @@ class AzureAIFoundry(Model):
257
259
 
258
260
  assistant_message.metrics.start_timer()
259
261
  provider_response = await self.get_async_client().complete(
260
- messages=[format_message(m) for m in messages],
262
+ messages=[format_message(m, compress_tool_results) for m in messages],
261
263
  **self.get_request_params(tools=tools, response_format=response_format, tool_choice=tool_choice),
262
264
  )
263
265
  assistant_message.metrics.stop_timer()
@@ -286,6 +288,7 @@ class AzureAIFoundry(Model):
286
288
  tools: Optional[List[Dict[str, Any]]] = None,
287
289
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
288
290
  run_response: Optional[RunOutput] = None,
291
+ compress_tool_results: bool = False,
289
292
  ) -> Iterator[ModelResponse]:
290
293
  """
291
294
  Send a streaming chat completion request to the Azure AI API.
@@ -297,7 +300,7 @@ class AzureAIFoundry(Model):
297
300
  assistant_message.metrics.start_timer()
298
301
 
299
302
  for chunk in self.get_client().complete(
300
- messages=[format_message(m) for m in messages],
303
+ messages=[format_message(m, compress_tool_results) for m in messages],
301
304
  stream=True,
302
305
  **self.get_request_params(tools=tools, response_format=response_format, tool_choice=tool_choice),
303
306
  ):
@@ -325,6 +328,7 @@ class AzureAIFoundry(Model):
325
328
  tools: Optional[List[Dict[str, Any]]] = None,
326
329
  tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
327
330
  run_response: Optional[RunOutput] = None,
331
+ compress_tool_results: bool = False,
328
332
  ) -> AsyncIterator[ModelResponse]:
329
333
  """
330
334
  Sends an asynchronous streaming chat completion request to the Azure AI API.
@@ -336,7 +340,7 @@ class AzureAIFoundry(Model):
336
340
  assistant_message.metrics.start_timer()
337
341
 
338
342
  async_stream = await self.get_async_client().complete(
339
- messages=[format_message(m) for m in messages],
343
+ messages=[format_message(m, compress_tool_results) for m in messages],
340
344
  stream=True,
341
345
  **self.get_request_params(tools=tools, response_format=response_format, tool_choice=tool_choice),
342
346
  )
@@ -4,8 +4,10 @@ from typing import Any, Dict, Optional
4
4
 
5
5
  import httpx
6
6
 
7
+ from agno.exceptions import ModelAuthenticationError
7
8
  from agno.models.openai.like import OpenAILike
8
- from agno.utils.log import log_debug
9
+ from agno.utils.http import get_default_async_client, get_default_sync_client
10
+ from agno.utils.log import log_warning
9
11
 
10
12
  try:
11
13
  from openai import AsyncAzureOpenAI as AsyncAzureOpenAIClient
@@ -62,6 +64,19 @@ class AzureOpenAI(OpenAILike):
62
64
  self.api_key = self.api_key or getenv("AZURE_OPENAI_API_KEY")
63
65
  self.azure_endpoint = self.azure_endpoint or getenv("AZURE_OPENAI_ENDPOINT")
64
66
  self.azure_deployment = self.azure_deployment or getenv("AZURE_OPENAI_DEPLOYMENT")
67
+
68
+ if not (self.api_key or self.azure_ad_token):
69
+ if not self.api_key:
70
+ raise ModelAuthenticationError(
71
+ message="AZURE_OPENAI_API_KEY not set. Please set the AZURE_OPENAI_API_KEY environment variable.",
72
+ model_name=self.name,
73
+ )
74
+ if not self.azure_ad_token:
75
+ raise ModelAuthenticationError(
76
+ message="AZURE_AD_TOKEN not set. Please set the AZURE_AD_TOKEN environment variable.",
77
+ model_name=self.name,
78
+ )
79
+
65
80
  params_mapping = {
66
81
  "api_key": self.api_key,
67
82
  "api_version": self.api_version,
@@ -99,7 +114,12 @@ class AzureOpenAI(OpenAILike):
99
114
  if isinstance(self.http_client, httpx.Client):
100
115
  _client_params["http_client"] = self.http_client
101
116
  else:
102
- log_debug("http_client is not an instance of httpx.Client.")
117
+ log_warning("http_client is not an instance of httpx.Client. Using default global httpx.Client.")
118
+ # Use global sync client when user http_client is invalid
119
+ _client_params["http_client"] = get_default_sync_client()
120
+ else:
121
+ # Use global sync client when no custom http_client is provided
122
+ _client_params["http_client"] = get_default_sync_client()
103
123
 
104
124
  # Create client
105
125
  self.client = AzureOpenAIClient(**_client_params)
@@ -117,15 +137,18 @@ class AzureOpenAI(OpenAILike):
117
137
 
118
138
  _client_params: Dict[str, Any] = self._get_client_params()
119
139
 
120
- if self.http_client and isinstance(self.http_client, httpx.AsyncClient):
121
- _client_params["http_client"] = self.http_client
140
+ if self.http_client:
141
+ if isinstance(self.http_client, httpx.AsyncClient):
142
+ _client_params["http_client"] = self.http_client
143
+ else:
144
+ log_warning(
145
+ "http_client is not an instance of httpx.AsyncClient. Using default global httpx.AsyncClient."
146
+ )
147
+ # Use global async client when user http_client is invalid
148
+ _client_params["http_client"] = get_default_async_client()
122
149
  else:
123
- if self.http_client:
124
- log_debug("The current http_client is not async. A default httpx.AsyncClient will be used instead.")
125
- # Create a new async HTTP client with custom limits
126
- _client_params["http_client"] = httpx.AsyncClient(
127
- limits=httpx.Limits(max_connections=1000, max_keepalive_connections=100)
128
- )
150
+ # Use global async client when no custom http_client is provided
151
+ _client_params["http_client"] = get_default_async_client()
129
152
 
130
153
  self.async_client = AsyncAzureOpenAIClient(**_client_params)
131
154
  return self.async_client