agno 2.2.13__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 (575) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +51 -0
  3. agno/agent/agent.py +10405 -0
  4. agno/api/__init__.py +0 -0
  5. agno/api/agent.py +28 -0
  6. agno/api/api.py +40 -0
  7. agno/api/evals.py +22 -0
  8. agno/api/os.py +17 -0
  9. agno/api/routes.py +13 -0
  10. agno/api/schemas/__init__.py +9 -0
  11. agno/api/schemas/agent.py +16 -0
  12. agno/api/schemas/evals.py +16 -0
  13. agno/api/schemas/os.py +14 -0
  14. agno/api/schemas/response.py +6 -0
  15. agno/api/schemas/team.py +16 -0
  16. agno/api/schemas/utils.py +21 -0
  17. agno/api/schemas/workflows.py +16 -0
  18. agno/api/settings.py +53 -0
  19. agno/api/team.py +30 -0
  20. agno/api/workflow.py +28 -0
  21. agno/cloud/aws/base.py +214 -0
  22. agno/cloud/aws/s3/__init__.py +2 -0
  23. agno/cloud/aws/s3/api_client.py +43 -0
  24. agno/cloud/aws/s3/bucket.py +195 -0
  25. agno/cloud/aws/s3/object.py +57 -0
  26. agno/culture/__init__.py +3 -0
  27. agno/culture/manager.py +956 -0
  28. agno/db/__init__.py +24 -0
  29. agno/db/async_postgres/__init__.py +3 -0
  30. agno/db/base.py +598 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2042 -0
  33. agno/db/dynamo/schemas.py +314 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +1795 -0
  37. agno/db/firestore/schemas.py +140 -0
  38. agno/db/firestore/utils.py +376 -0
  39. agno/db/gcs_json/__init__.py +3 -0
  40. agno/db/gcs_json/gcs_json_db.py +1335 -0
  41. agno/db/gcs_json/utils.py +228 -0
  42. agno/db/in_memory/__init__.py +3 -0
  43. agno/db/in_memory/in_memory_db.py +1160 -0
  44. agno/db/in_memory/utils.py +230 -0
  45. agno/db/json/__init__.py +3 -0
  46. agno/db/json/json_db.py +1328 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/__init__.py +0 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/mongo/__init__.py +17 -0
  51. agno/db/mongo/async_mongo.py +2026 -0
  52. agno/db/mongo/mongo.py +1982 -0
  53. agno/db/mongo/schemas.py +87 -0
  54. agno/db/mongo/utils.py +259 -0
  55. agno/db/mysql/__init__.py +3 -0
  56. agno/db/mysql/mysql.py +2308 -0
  57. agno/db/mysql/schemas.py +138 -0
  58. agno/db/mysql/utils.py +355 -0
  59. agno/db/postgres/__init__.py +4 -0
  60. agno/db/postgres/async_postgres.py +1927 -0
  61. agno/db/postgres/postgres.py +2260 -0
  62. agno/db/postgres/schemas.py +139 -0
  63. agno/db/postgres/utils.py +442 -0
  64. agno/db/redis/__init__.py +3 -0
  65. agno/db/redis/redis.py +1660 -0
  66. agno/db/redis/schemas.py +123 -0
  67. agno/db/redis/utils.py +346 -0
  68. agno/db/schemas/__init__.py +4 -0
  69. agno/db/schemas/culture.py +120 -0
  70. agno/db/schemas/evals.py +33 -0
  71. agno/db/schemas/knowledge.py +40 -0
  72. agno/db/schemas/memory.py +46 -0
  73. agno/db/schemas/metrics.py +0 -0
  74. agno/db/singlestore/__init__.py +3 -0
  75. agno/db/singlestore/schemas.py +130 -0
  76. agno/db/singlestore/singlestore.py +2272 -0
  77. agno/db/singlestore/utils.py +384 -0
  78. agno/db/sqlite/__init__.py +4 -0
  79. agno/db/sqlite/async_sqlite.py +2293 -0
  80. agno/db/sqlite/schemas.py +133 -0
  81. agno/db/sqlite/sqlite.py +2288 -0
  82. agno/db/sqlite/utils.py +431 -0
  83. agno/db/surrealdb/__init__.py +3 -0
  84. agno/db/surrealdb/metrics.py +292 -0
  85. agno/db/surrealdb/models.py +309 -0
  86. agno/db/surrealdb/queries.py +71 -0
  87. agno/db/surrealdb/surrealdb.py +1353 -0
  88. agno/db/surrealdb/utils.py +147 -0
  89. agno/db/utils.py +116 -0
  90. agno/debug.py +18 -0
  91. agno/eval/__init__.py +14 -0
  92. agno/eval/accuracy.py +834 -0
  93. agno/eval/performance.py +773 -0
  94. agno/eval/reliability.py +306 -0
  95. agno/eval/utils.py +119 -0
  96. agno/exceptions.py +161 -0
  97. agno/filters.py +354 -0
  98. agno/guardrails/__init__.py +6 -0
  99. agno/guardrails/base.py +19 -0
  100. agno/guardrails/openai.py +144 -0
  101. agno/guardrails/pii.py +94 -0
  102. agno/guardrails/prompt_injection.py +52 -0
  103. agno/integrations/__init__.py +0 -0
  104. agno/integrations/discord/__init__.py +3 -0
  105. agno/integrations/discord/client.py +203 -0
  106. agno/knowledge/__init__.py +5 -0
  107. agno/knowledge/chunking/__init__.py +0 -0
  108. agno/knowledge/chunking/agentic.py +79 -0
  109. agno/knowledge/chunking/document.py +91 -0
  110. agno/knowledge/chunking/fixed.py +57 -0
  111. agno/knowledge/chunking/markdown.py +151 -0
  112. agno/knowledge/chunking/recursive.py +63 -0
  113. agno/knowledge/chunking/row.py +39 -0
  114. agno/knowledge/chunking/semantic.py +86 -0
  115. agno/knowledge/chunking/strategy.py +165 -0
  116. agno/knowledge/content.py +74 -0
  117. agno/knowledge/document/__init__.py +5 -0
  118. agno/knowledge/document/base.py +58 -0
  119. agno/knowledge/embedder/__init__.py +5 -0
  120. agno/knowledge/embedder/aws_bedrock.py +343 -0
  121. agno/knowledge/embedder/azure_openai.py +210 -0
  122. agno/knowledge/embedder/base.py +23 -0
  123. agno/knowledge/embedder/cohere.py +323 -0
  124. agno/knowledge/embedder/fastembed.py +62 -0
  125. agno/knowledge/embedder/fireworks.py +13 -0
  126. agno/knowledge/embedder/google.py +258 -0
  127. agno/knowledge/embedder/huggingface.py +94 -0
  128. agno/knowledge/embedder/jina.py +182 -0
  129. agno/knowledge/embedder/langdb.py +22 -0
  130. agno/knowledge/embedder/mistral.py +206 -0
  131. agno/knowledge/embedder/nebius.py +13 -0
  132. agno/knowledge/embedder/ollama.py +154 -0
  133. agno/knowledge/embedder/openai.py +195 -0
  134. agno/knowledge/embedder/sentence_transformer.py +63 -0
  135. agno/knowledge/embedder/together.py +13 -0
  136. agno/knowledge/embedder/vllm.py +262 -0
  137. agno/knowledge/embedder/voyageai.py +165 -0
  138. agno/knowledge/knowledge.py +1988 -0
  139. agno/knowledge/reader/__init__.py +7 -0
  140. agno/knowledge/reader/arxiv_reader.py +81 -0
  141. agno/knowledge/reader/base.py +95 -0
  142. agno/knowledge/reader/csv_reader.py +166 -0
  143. agno/knowledge/reader/docx_reader.py +82 -0
  144. agno/knowledge/reader/field_labeled_csv_reader.py +292 -0
  145. agno/knowledge/reader/firecrawl_reader.py +201 -0
  146. agno/knowledge/reader/json_reader.py +87 -0
  147. agno/knowledge/reader/markdown_reader.py +137 -0
  148. agno/knowledge/reader/pdf_reader.py +431 -0
  149. agno/knowledge/reader/pptx_reader.py +101 -0
  150. agno/knowledge/reader/reader_factory.py +313 -0
  151. agno/knowledge/reader/s3_reader.py +89 -0
  152. agno/knowledge/reader/tavily_reader.py +194 -0
  153. agno/knowledge/reader/text_reader.py +115 -0
  154. agno/knowledge/reader/web_search_reader.py +372 -0
  155. agno/knowledge/reader/website_reader.py +455 -0
  156. agno/knowledge/reader/wikipedia_reader.py +59 -0
  157. agno/knowledge/reader/youtube_reader.py +78 -0
  158. agno/knowledge/remote_content/__init__.py +0 -0
  159. agno/knowledge/remote_content/remote_content.py +88 -0
  160. agno/knowledge/reranker/__init__.py +3 -0
  161. agno/knowledge/reranker/base.py +14 -0
  162. agno/knowledge/reranker/cohere.py +64 -0
  163. agno/knowledge/reranker/infinity.py +195 -0
  164. agno/knowledge/reranker/sentence_transformer.py +54 -0
  165. agno/knowledge/types.py +39 -0
  166. agno/knowledge/utils.py +189 -0
  167. agno/media.py +462 -0
  168. agno/memory/__init__.py +3 -0
  169. agno/memory/manager.py +1327 -0
  170. agno/models/__init__.py +0 -0
  171. agno/models/aimlapi/__init__.py +5 -0
  172. agno/models/aimlapi/aimlapi.py +45 -0
  173. agno/models/anthropic/__init__.py +5 -0
  174. agno/models/anthropic/claude.py +757 -0
  175. agno/models/aws/__init__.py +15 -0
  176. agno/models/aws/bedrock.py +701 -0
  177. agno/models/aws/claude.py +378 -0
  178. agno/models/azure/__init__.py +18 -0
  179. agno/models/azure/ai_foundry.py +485 -0
  180. agno/models/azure/openai_chat.py +131 -0
  181. agno/models/base.py +2175 -0
  182. agno/models/cerebras/__init__.py +12 -0
  183. agno/models/cerebras/cerebras.py +501 -0
  184. agno/models/cerebras/cerebras_openai.py +112 -0
  185. agno/models/cohere/__init__.py +5 -0
  186. agno/models/cohere/chat.py +389 -0
  187. agno/models/cometapi/__init__.py +5 -0
  188. agno/models/cometapi/cometapi.py +57 -0
  189. agno/models/dashscope/__init__.py +5 -0
  190. agno/models/dashscope/dashscope.py +91 -0
  191. agno/models/deepinfra/__init__.py +5 -0
  192. agno/models/deepinfra/deepinfra.py +28 -0
  193. agno/models/deepseek/__init__.py +5 -0
  194. agno/models/deepseek/deepseek.py +61 -0
  195. agno/models/defaults.py +1 -0
  196. agno/models/fireworks/__init__.py +5 -0
  197. agno/models/fireworks/fireworks.py +26 -0
  198. agno/models/google/__init__.py +5 -0
  199. agno/models/google/gemini.py +1085 -0
  200. agno/models/groq/__init__.py +5 -0
  201. agno/models/groq/groq.py +556 -0
  202. agno/models/huggingface/__init__.py +5 -0
  203. agno/models/huggingface/huggingface.py +491 -0
  204. agno/models/ibm/__init__.py +5 -0
  205. agno/models/ibm/watsonx.py +422 -0
  206. agno/models/internlm/__init__.py +3 -0
  207. agno/models/internlm/internlm.py +26 -0
  208. agno/models/langdb/__init__.py +1 -0
  209. agno/models/langdb/langdb.py +48 -0
  210. agno/models/litellm/__init__.py +14 -0
  211. agno/models/litellm/chat.py +468 -0
  212. agno/models/litellm/litellm_openai.py +25 -0
  213. agno/models/llama_cpp/__init__.py +5 -0
  214. agno/models/llama_cpp/llama_cpp.py +22 -0
  215. agno/models/lmstudio/__init__.py +5 -0
  216. agno/models/lmstudio/lmstudio.py +25 -0
  217. agno/models/message.py +434 -0
  218. agno/models/meta/__init__.py +12 -0
  219. agno/models/meta/llama.py +475 -0
  220. agno/models/meta/llama_openai.py +78 -0
  221. agno/models/metrics.py +120 -0
  222. agno/models/mistral/__init__.py +5 -0
  223. agno/models/mistral/mistral.py +432 -0
  224. agno/models/nebius/__init__.py +3 -0
  225. agno/models/nebius/nebius.py +54 -0
  226. agno/models/nexus/__init__.py +3 -0
  227. agno/models/nexus/nexus.py +22 -0
  228. agno/models/nvidia/__init__.py +5 -0
  229. agno/models/nvidia/nvidia.py +28 -0
  230. agno/models/ollama/__init__.py +5 -0
  231. agno/models/ollama/chat.py +441 -0
  232. agno/models/openai/__init__.py +9 -0
  233. agno/models/openai/chat.py +883 -0
  234. agno/models/openai/like.py +27 -0
  235. agno/models/openai/responses.py +1050 -0
  236. agno/models/openrouter/__init__.py +5 -0
  237. agno/models/openrouter/openrouter.py +66 -0
  238. agno/models/perplexity/__init__.py +5 -0
  239. agno/models/perplexity/perplexity.py +187 -0
  240. agno/models/portkey/__init__.py +3 -0
  241. agno/models/portkey/portkey.py +81 -0
  242. agno/models/requesty/__init__.py +5 -0
  243. agno/models/requesty/requesty.py +52 -0
  244. agno/models/response.py +199 -0
  245. agno/models/sambanova/__init__.py +5 -0
  246. agno/models/sambanova/sambanova.py +28 -0
  247. agno/models/siliconflow/__init__.py +5 -0
  248. agno/models/siliconflow/siliconflow.py +25 -0
  249. agno/models/together/__init__.py +5 -0
  250. agno/models/together/together.py +25 -0
  251. agno/models/utils.py +266 -0
  252. agno/models/vercel/__init__.py +3 -0
  253. agno/models/vercel/v0.py +26 -0
  254. agno/models/vertexai/__init__.py +0 -0
  255. agno/models/vertexai/claude.py +70 -0
  256. agno/models/vllm/__init__.py +3 -0
  257. agno/models/vllm/vllm.py +78 -0
  258. agno/models/xai/__init__.py +3 -0
  259. agno/models/xai/xai.py +113 -0
  260. agno/os/__init__.py +3 -0
  261. agno/os/app.py +876 -0
  262. agno/os/auth.py +57 -0
  263. agno/os/config.py +104 -0
  264. agno/os/interfaces/__init__.py +1 -0
  265. agno/os/interfaces/a2a/__init__.py +3 -0
  266. agno/os/interfaces/a2a/a2a.py +42 -0
  267. agno/os/interfaces/a2a/router.py +250 -0
  268. agno/os/interfaces/a2a/utils.py +924 -0
  269. agno/os/interfaces/agui/__init__.py +3 -0
  270. agno/os/interfaces/agui/agui.py +47 -0
  271. agno/os/interfaces/agui/router.py +144 -0
  272. agno/os/interfaces/agui/utils.py +534 -0
  273. agno/os/interfaces/base.py +25 -0
  274. agno/os/interfaces/slack/__init__.py +3 -0
  275. agno/os/interfaces/slack/router.py +148 -0
  276. agno/os/interfaces/slack/security.py +30 -0
  277. agno/os/interfaces/slack/slack.py +47 -0
  278. agno/os/interfaces/whatsapp/__init__.py +3 -0
  279. agno/os/interfaces/whatsapp/router.py +211 -0
  280. agno/os/interfaces/whatsapp/security.py +53 -0
  281. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  282. agno/os/mcp.py +292 -0
  283. agno/os/middleware/__init__.py +7 -0
  284. agno/os/middleware/jwt.py +233 -0
  285. agno/os/router.py +1763 -0
  286. agno/os/routers/__init__.py +3 -0
  287. agno/os/routers/evals/__init__.py +3 -0
  288. agno/os/routers/evals/evals.py +430 -0
  289. agno/os/routers/evals/schemas.py +142 -0
  290. agno/os/routers/evals/utils.py +162 -0
  291. agno/os/routers/health.py +31 -0
  292. agno/os/routers/home.py +52 -0
  293. agno/os/routers/knowledge/__init__.py +3 -0
  294. agno/os/routers/knowledge/knowledge.py +997 -0
  295. agno/os/routers/knowledge/schemas.py +178 -0
  296. agno/os/routers/memory/__init__.py +3 -0
  297. agno/os/routers/memory/memory.py +515 -0
  298. agno/os/routers/memory/schemas.py +62 -0
  299. agno/os/routers/metrics/__init__.py +3 -0
  300. agno/os/routers/metrics/metrics.py +190 -0
  301. agno/os/routers/metrics/schemas.py +47 -0
  302. agno/os/routers/session/__init__.py +3 -0
  303. agno/os/routers/session/session.py +997 -0
  304. agno/os/schema.py +1055 -0
  305. agno/os/settings.py +43 -0
  306. agno/os/utils.py +630 -0
  307. agno/py.typed +0 -0
  308. agno/reasoning/__init__.py +0 -0
  309. agno/reasoning/anthropic.py +80 -0
  310. agno/reasoning/azure_ai_foundry.py +67 -0
  311. agno/reasoning/deepseek.py +63 -0
  312. agno/reasoning/default.py +97 -0
  313. agno/reasoning/gemini.py +73 -0
  314. agno/reasoning/groq.py +71 -0
  315. agno/reasoning/helpers.py +63 -0
  316. agno/reasoning/ollama.py +67 -0
  317. agno/reasoning/openai.py +86 -0
  318. agno/reasoning/step.py +31 -0
  319. agno/reasoning/vertexai.py +76 -0
  320. agno/run/__init__.py +6 -0
  321. agno/run/agent.py +787 -0
  322. agno/run/base.py +229 -0
  323. agno/run/cancel.py +81 -0
  324. agno/run/messages.py +32 -0
  325. agno/run/team.py +753 -0
  326. agno/run/workflow.py +708 -0
  327. agno/session/__init__.py +10 -0
  328. agno/session/agent.py +295 -0
  329. agno/session/summary.py +265 -0
  330. agno/session/team.py +392 -0
  331. agno/session/workflow.py +205 -0
  332. agno/team/__init__.py +37 -0
  333. agno/team/team.py +8793 -0
  334. agno/tools/__init__.py +10 -0
  335. agno/tools/agentql.py +120 -0
  336. agno/tools/airflow.py +69 -0
  337. agno/tools/api.py +122 -0
  338. agno/tools/apify.py +314 -0
  339. agno/tools/arxiv.py +127 -0
  340. agno/tools/aws_lambda.py +53 -0
  341. agno/tools/aws_ses.py +66 -0
  342. agno/tools/baidusearch.py +89 -0
  343. agno/tools/bitbucket.py +292 -0
  344. agno/tools/brandfetch.py +213 -0
  345. agno/tools/bravesearch.py +106 -0
  346. agno/tools/brightdata.py +367 -0
  347. agno/tools/browserbase.py +209 -0
  348. agno/tools/calcom.py +255 -0
  349. agno/tools/calculator.py +151 -0
  350. agno/tools/cartesia.py +187 -0
  351. agno/tools/clickup.py +244 -0
  352. agno/tools/confluence.py +240 -0
  353. agno/tools/crawl4ai.py +158 -0
  354. agno/tools/csv_toolkit.py +185 -0
  355. agno/tools/dalle.py +110 -0
  356. agno/tools/daytona.py +475 -0
  357. agno/tools/decorator.py +262 -0
  358. agno/tools/desi_vocal.py +108 -0
  359. agno/tools/discord.py +161 -0
  360. agno/tools/docker.py +716 -0
  361. agno/tools/duckdb.py +379 -0
  362. agno/tools/duckduckgo.py +91 -0
  363. agno/tools/e2b.py +703 -0
  364. agno/tools/eleven_labs.py +196 -0
  365. agno/tools/email.py +67 -0
  366. agno/tools/evm.py +129 -0
  367. agno/tools/exa.py +396 -0
  368. agno/tools/fal.py +127 -0
  369. agno/tools/file.py +240 -0
  370. agno/tools/file_generation.py +350 -0
  371. agno/tools/financial_datasets.py +288 -0
  372. agno/tools/firecrawl.py +143 -0
  373. agno/tools/function.py +1187 -0
  374. agno/tools/giphy.py +93 -0
  375. agno/tools/github.py +1760 -0
  376. agno/tools/gmail.py +922 -0
  377. agno/tools/google_bigquery.py +117 -0
  378. agno/tools/google_drive.py +270 -0
  379. agno/tools/google_maps.py +253 -0
  380. agno/tools/googlecalendar.py +674 -0
  381. agno/tools/googlesearch.py +98 -0
  382. agno/tools/googlesheets.py +377 -0
  383. agno/tools/hackernews.py +77 -0
  384. agno/tools/jina.py +101 -0
  385. agno/tools/jira.py +170 -0
  386. agno/tools/knowledge.py +218 -0
  387. agno/tools/linear.py +426 -0
  388. agno/tools/linkup.py +58 -0
  389. agno/tools/local_file_system.py +90 -0
  390. agno/tools/lumalab.py +183 -0
  391. agno/tools/mcp/__init__.py +10 -0
  392. agno/tools/mcp/mcp.py +331 -0
  393. agno/tools/mcp/multi_mcp.py +347 -0
  394. agno/tools/mcp/params.py +24 -0
  395. agno/tools/mcp_toolbox.py +284 -0
  396. agno/tools/mem0.py +193 -0
  397. agno/tools/memori.py +339 -0
  398. agno/tools/memory.py +419 -0
  399. agno/tools/mlx_transcribe.py +139 -0
  400. agno/tools/models/__init__.py +0 -0
  401. agno/tools/models/azure_openai.py +190 -0
  402. agno/tools/models/gemini.py +203 -0
  403. agno/tools/models/groq.py +158 -0
  404. agno/tools/models/morph.py +186 -0
  405. agno/tools/models/nebius.py +124 -0
  406. agno/tools/models_labs.py +195 -0
  407. agno/tools/moviepy_video.py +349 -0
  408. agno/tools/neo4j.py +134 -0
  409. agno/tools/newspaper.py +46 -0
  410. agno/tools/newspaper4k.py +93 -0
  411. agno/tools/notion.py +204 -0
  412. agno/tools/openai.py +202 -0
  413. agno/tools/openbb.py +160 -0
  414. agno/tools/opencv.py +321 -0
  415. agno/tools/openweather.py +233 -0
  416. agno/tools/oxylabs.py +385 -0
  417. agno/tools/pandas.py +102 -0
  418. agno/tools/parallel.py +314 -0
  419. agno/tools/postgres.py +257 -0
  420. agno/tools/pubmed.py +188 -0
  421. agno/tools/python.py +205 -0
  422. agno/tools/reasoning.py +283 -0
  423. agno/tools/reddit.py +467 -0
  424. agno/tools/replicate.py +117 -0
  425. agno/tools/resend.py +62 -0
  426. agno/tools/scrapegraph.py +222 -0
  427. agno/tools/searxng.py +152 -0
  428. agno/tools/serpapi.py +116 -0
  429. agno/tools/serper.py +255 -0
  430. agno/tools/shell.py +53 -0
  431. agno/tools/slack.py +136 -0
  432. agno/tools/sleep.py +20 -0
  433. agno/tools/spider.py +116 -0
  434. agno/tools/sql.py +154 -0
  435. agno/tools/streamlit/__init__.py +0 -0
  436. agno/tools/streamlit/components.py +113 -0
  437. agno/tools/tavily.py +254 -0
  438. agno/tools/telegram.py +48 -0
  439. agno/tools/todoist.py +218 -0
  440. agno/tools/tool_registry.py +1 -0
  441. agno/tools/toolkit.py +146 -0
  442. agno/tools/trafilatura.py +388 -0
  443. agno/tools/trello.py +274 -0
  444. agno/tools/twilio.py +186 -0
  445. agno/tools/user_control_flow.py +78 -0
  446. agno/tools/valyu.py +228 -0
  447. agno/tools/visualization.py +467 -0
  448. agno/tools/webbrowser.py +28 -0
  449. agno/tools/webex.py +76 -0
  450. agno/tools/website.py +54 -0
  451. agno/tools/webtools.py +45 -0
  452. agno/tools/whatsapp.py +286 -0
  453. agno/tools/wikipedia.py +63 -0
  454. agno/tools/workflow.py +278 -0
  455. agno/tools/x.py +335 -0
  456. agno/tools/yfinance.py +257 -0
  457. agno/tools/youtube.py +184 -0
  458. agno/tools/zendesk.py +82 -0
  459. agno/tools/zep.py +454 -0
  460. agno/tools/zoom.py +382 -0
  461. agno/utils/__init__.py +0 -0
  462. agno/utils/agent.py +820 -0
  463. agno/utils/audio.py +49 -0
  464. agno/utils/certs.py +27 -0
  465. agno/utils/code_execution.py +11 -0
  466. agno/utils/common.py +132 -0
  467. agno/utils/dttm.py +13 -0
  468. agno/utils/enum.py +22 -0
  469. agno/utils/env.py +11 -0
  470. agno/utils/events.py +696 -0
  471. agno/utils/format_str.py +16 -0
  472. agno/utils/functions.py +166 -0
  473. agno/utils/gemini.py +426 -0
  474. agno/utils/hooks.py +57 -0
  475. agno/utils/http.py +74 -0
  476. agno/utils/json_schema.py +234 -0
  477. agno/utils/knowledge.py +36 -0
  478. agno/utils/location.py +19 -0
  479. agno/utils/log.py +255 -0
  480. agno/utils/mcp.py +214 -0
  481. agno/utils/media.py +352 -0
  482. agno/utils/merge_dict.py +41 -0
  483. agno/utils/message.py +118 -0
  484. agno/utils/models/__init__.py +0 -0
  485. agno/utils/models/ai_foundry.py +43 -0
  486. agno/utils/models/claude.py +358 -0
  487. agno/utils/models/cohere.py +87 -0
  488. agno/utils/models/llama.py +78 -0
  489. agno/utils/models/mistral.py +98 -0
  490. agno/utils/models/openai_responses.py +140 -0
  491. agno/utils/models/schema_utils.py +153 -0
  492. agno/utils/models/watsonx.py +41 -0
  493. agno/utils/openai.py +257 -0
  494. agno/utils/pickle.py +32 -0
  495. agno/utils/pprint.py +178 -0
  496. agno/utils/print_response/__init__.py +0 -0
  497. agno/utils/print_response/agent.py +842 -0
  498. agno/utils/print_response/team.py +1724 -0
  499. agno/utils/print_response/workflow.py +1668 -0
  500. agno/utils/prompts.py +111 -0
  501. agno/utils/reasoning.py +108 -0
  502. agno/utils/response.py +163 -0
  503. agno/utils/response_iterator.py +17 -0
  504. agno/utils/safe_formatter.py +24 -0
  505. agno/utils/serialize.py +32 -0
  506. agno/utils/shell.py +22 -0
  507. agno/utils/streamlit.py +487 -0
  508. agno/utils/string.py +231 -0
  509. agno/utils/team.py +139 -0
  510. agno/utils/timer.py +41 -0
  511. agno/utils/tools.py +102 -0
  512. agno/utils/web.py +23 -0
  513. agno/utils/whatsapp.py +305 -0
  514. agno/utils/yaml_io.py +25 -0
  515. agno/vectordb/__init__.py +3 -0
  516. agno/vectordb/base.py +127 -0
  517. agno/vectordb/cassandra/__init__.py +5 -0
  518. agno/vectordb/cassandra/cassandra.py +501 -0
  519. agno/vectordb/cassandra/extra_param_mixin.py +11 -0
  520. agno/vectordb/cassandra/index.py +13 -0
  521. agno/vectordb/chroma/__init__.py +5 -0
  522. agno/vectordb/chroma/chromadb.py +929 -0
  523. agno/vectordb/clickhouse/__init__.py +9 -0
  524. agno/vectordb/clickhouse/clickhousedb.py +835 -0
  525. agno/vectordb/clickhouse/index.py +9 -0
  526. agno/vectordb/couchbase/__init__.py +3 -0
  527. agno/vectordb/couchbase/couchbase.py +1442 -0
  528. agno/vectordb/distance.py +7 -0
  529. agno/vectordb/lancedb/__init__.py +6 -0
  530. agno/vectordb/lancedb/lance_db.py +995 -0
  531. agno/vectordb/langchaindb/__init__.py +5 -0
  532. agno/vectordb/langchaindb/langchaindb.py +163 -0
  533. agno/vectordb/lightrag/__init__.py +5 -0
  534. agno/vectordb/lightrag/lightrag.py +388 -0
  535. agno/vectordb/llamaindex/__init__.py +3 -0
  536. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  537. agno/vectordb/milvus/__init__.py +4 -0
  538. agno/vectordb/milvus/milvus.py +1182 -0
  539. agno/vectordb/mongodb/__init__.py +9 -0
  540. agno/vectordb/mongodb/mongodb.py +1417 -0
  541. agno/vectordb/pgvector/__init__.py +12 -0
  542. agno/vectordb/pgvector/index.py +23 -0
  543. agno/vectordb/pgvector/pgvector.py +1462 -0
  544. agno/vectordb/pineconedb/__init__.py +5 -0
  545. agno/vectordb/pineconedb/pineconedb.py +747 -0
  546. agno/vectordb/qdrant/__init__.py +5 -0
  547. agno/vectordb/qdrant/qdrant.py +1134 -0
  548. agno/vectordb/redis/__init__.py +9 -0
  549. agno/vectordb/redis/redisdb.py +694 -0
  550. agno/vectordb/search.py +7 -0
  551. agno/vectordb/singlestore/__init__.py +10 -0
  552. agno/vectordb/singlestore/index.py +41 -0
  553. agno/vectordb/singlestore/singlestore.py +763 -0
  554. agno/vectordb/surrealdb/__init__.py +3 -0
  555. agno/vectordb/surrealdb/surrealdb.py +699 -0
  556. agno/vectordb/upstashdb/__init__.py +5 -0
  557. agno/vectordb/upstashdb/upstashdb.py +718 -0
  558. agno/vectordb/weaviate/__init__.py +8 -0
  559. agno/vectordb/weaviate/index.py +15 -0
  560. agno/vectordb/weaviate/weaviate.py +1005 -0
  561. agno/workflow/__init__.py +23 -0
  562. agno/workflow/agent.py +299 -0
  563. agno/workflow/condition.py +738 -0
  564. agno/workflow/loop.py +735 -0
  565. agno/workflow/parallel.py +824 -0
  566. agno/workflow/router.py +702 -0
  567. agno/workflow/step.py +1432 -0
  568. agno/workflow/steps.py +592 -0
  569. agno/workflow/types.py +520 -0
  570. agno/workflow/workflow.py +4321 -0
  571. agno-2.2.13.dist-info/METADATA +614 -0
  572. agno-2.2.13.dist-info/RECORD +575 -0
  573. agno-2.2.13.dist-info/WHEEL +5 -0
  574. agno-2.2.13.dist-info/licenses/LICENSE +201 -0
  575. agno-2.2.13.dist-info/top_level.txt +1 -0
@@ -0,0 +1,12 @@
1
+ from agno.models.cerebras.cerebras import Cerebras
2
+
3
+ try:
4
+ from agno.models.cerebras.cerebras_openai import CerebrasOpenAI
5
+ except ImportError:
6
+
7
+ class CerebrasOpenAI: # type: ignore
8
+ def __init__(self, *args, **kwargs):
9
+ raise ImportError("`openai` not installed. Please install it via `pip install openai`")
10
+
11
+
12
+ __all__ = ["Cerebras", "CerebrasOpenAI"]
@@ -0,0 +1,501 @@
1
+ import json
2
+ from collections.abc import AsyncIterator
3
+ from dataclasses import dataclass
4
+ from os import getenv
5
+ from typing import Any, Dict, Iterator, List, Optional, Type, Union
6
+
7
+ import httpx
8
+ from pydantic import BaseModel
9
+
10
+ from agno.models.base import Model
11
+ from agno.models.message import Message
12
+ from agno.models.metrics import Metrics
13
+ from agno.models.response import ModelResponse
14
+ from agno.run.agent import RunOutput
15
+ from agno.utils.log import log_debug, log_error, log_warning
16
+
17
+ try:
18
+ from cerebras.cloud.sdk import AsyncCerebras as AsyncCerebrasClient
19
+ from cerebras.cloud.sdk import Cerebras as CerebrasClient
20
+ from cerebras.cloud.sdk.types.chat.chat_completion import (
21
+ ChatChunkResponse,
22
+ ChatChunkResponseChoice,
23
+ ChatChunkResponseChoiceDelta,
24
+ ChatChunkResponseUsage,
25
+ ChatCompletionResponse,
26
+ ChatCompletionResponseChoice,
27
+ ChatCompletionResponseChoiceMessage,
28
+ ChatCompletionResponseUsage,
29
+ )
30
+ except (ImportError, ModuleNotFoundError):
31
+ raise ImportError("`cerebras-cloud-sdk` not installed. Please install using `pip install cerebras-cloud-sdk`")
32
+
33
+
34
+ @dataclass
35
+ class Cerebras(Model):
36
+ """
37
+ A class for interacting with models using the Cerebras API.
38
+ """
39
+
40
+ id: str = "llama-4-scout-17b-16e-instruct"
41
+ name: str = "Cerebras"
42
+ provider: str = "Cerebras"
43
+
44
+ supports_native_structured_outputs: bool = False
45
+ supports_json_schema_outputs: bool = True
46
+
47
+ # Request parameters
48
+ parallel_tool_calls: Optional[bool] = None
49
+ max_completion_tokens: Optional[int] = None
50
+ repetition_penalty: Optional[float] = None
51
+ temperature: Optional[float] = None
52
+ top_p: Optional[float] = None
53
+ top_k: Optional[int] = None
54
+ strict_output: bool = True # When True, guarantees schema adherence for structured outputs. When False, attempts to follow schema as a guide but may occasionally deviate
55
+ extra_headers: Optional[Any] = None
56
+ extra_query: Optional[Any] = None
57
+ extra_body: Optional[Any] = None
58
+ request_params: Optional[Dict[str, Any]] = None
59
+
60
+ # Client parameters
61
+ api_key: Optional[str] = None
62
+ base_url: Optional[Union[str, httpx.URL]] = None
63
+ timeout: Optional[float] = None
64
+ max_retries: Optional[int] = None
65
+ default_headers: Optional[Any] = None
66
+ default_query: Optional[Any] = None
67
+ http_client: Optional[Union[httpx.Client, httpx.AsyncClient]] = None
68
+ client_params: Optional[Dict[str, Any]] = None
69
+
70
+ # Cerebras clients
71
+ client: Optional[CerebrasClient] = None
72
+ async_client: Optional[AsyncCerebrasClient] = None
73
+
74
+ def _get_client_params(self) -> Dict[str, Any]:
75
+ # Fetch API key from env if not already set
76
+ if not self.api_key:
77
+ self.api_key = getenv("CEREBRAS_API_KEY")
78
+ if not self.api_key:
79
+ log_error("CEREBRAS_API_KEY not set. Please set the CEREBRAS_API_KEY environment variable.")
80
+
81
+ # Define base client params
82
+ base_params = {
83
+ "api_key": self.api_key,
84
+ "base_url": self.base_url,
85
+ "timeout": self.timeout,
86
+ "max_retries": self.max_retries,
87
+ "default_headers": self.default_headers,
88
+ "default_query": self.default_query,
89
+ }
90
+
91
+ # Create client_params dict with non-None values
92
+ client_params = {k: v for k, v in base_params.items() if v is not None}
93
+
94
+ # Add additional client params if provided
95
+ if self.client_params:
96
+ client_params.update(self.client_params)
97
+ return client_params
98
+
99
+ def get_client(self) -> CerebrasClient:
100
+ """
101
+ Returns a Cerebras client.
102
+
103
+ Returns:
104
+ CerebrasClient: An instance of the Cerebras client.
105
+ """
106
+ if self.client and not self.client.is_closed():
107
+ return self.client
108
+
109
+ client_params: Dict[str, Any] = self._get_client_params()
110
+ if self.http_client:
111
+ if isinstance(self.http_client, httpx.Client):
112
+ client_params["http_client"] = self.http_client
113
+ else:
114
+ log_debug("http_client is not an instance of httpx.Client.")
115
+ self.client = CerebrasClient(**client_params)
116
+ return self.client
117
+
118
+ def get_async_client(self) -> AsyncCerebrasClient:
119
+ """
120
+ Returns an asynchronous Cerebras client.
121
+
122
+ Returns:
123
+ AsyncCerebras: An instance of the asynchronous Cerebras client.
124
+ """
125
+ if self.async_client and not self.async_client.is_closed():
126
+ return self.async_client
127
+
128
+ client_params: Dict[str, Any] = self._get_client_params()
129
+ if self.http_client and isinstance(self.http_client, httpx.AsyncClient):
130
+ client_params["http_client"] = self.http_client
131
+ else:
132
+ if self.http_client:
133
+ log_debug("The current http_client is not async. A default httpx.AsyncClient will be used instead.")
134
+ # Create a new async HTTP client with custom limits
135
+ client_params["http_client"] = httpx.AsyncClient(
136
+ limits=httpx.Limits(max_connections=1000, max_keepalive_connections=100)
137
+ )
138
+ self.async_client = AsyncCerebrasClient(**client_params)
139
+ return self.async_client
140
+
141
+ def get_request_params(
142
+ self,
143
+ tools: Optional[List[Dict[str, Any]]] = None,
144
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
145
+ **kwargs: Any,
146
+ ) -> Dict[str, Any]:
147
+ """
148
+ Returns keyword arguments for API requests.
149
+
150
+ Returns:
151
+ Dict[str, Any]: A dictionary of keyword arguments for API requests.
152
+ """
153
+ # Define base request parameters
154
+ base_params = {
155
+ "max_completion_tokens": self.max_completion_tokens,
156
+ "repetition_penalty": self.repetition_penalty,
157
+ "temperature": self.temperature,
158
+ "top_p": self.top_p,
159
+ "top_k": self.top_k,
160
+ "extra_headers": self.extra_headers,
161
+ "extra_query": self.extra_query,
162
+ "extra_body": self.extra_body,
163
+ "request_params": self.request_params,
164
+ }
165
+
166
+ # Filter out None values
167
+ request_params: Dict[str, Any] = {k: v for k, v in base_params.items() if v is not None}
168
+
169
+ # Add tools
170
+ if tools is not None and len(tools) > 0:
171
+ request_params["tools"] = [
172
+ {
173
+ "type": "function",
174
+ "function": {
175
+ "name": tool["function"]["name"],
176
+ "description": tool["function"]["description"],
177
+ "parameters": tool["function"]["parameters"],
178
+ },
179
+ }
180
+ for tool in tools
181
+ ]
182
+ # Cerebras requires parallel_tool_calls=False for llama-4-scout-17b-16e-instruct
183
+ if self.id == "llama-4-scout-17b-16e-instruct":
184
+ request_params["parallel_tool_calls"] = False
185
+ elif self.parallel_tool_calls is not None:
186
+ request_params["parallel_tool_calls"] = self.parallel_tool_calls
187
+
188
+ # Handle response format for structured outputs
189
+ if response_format is not None:
190
+ if (
191
+ isinstance(response_format, dict)
192
+ and response_format.get("type") == "json_schema"
193
+ and isinstance(response_format.get("json_schema"), dict)
194
+ ):
195
+ # Ensure json_schema has strict parameter set
196
+ schema = response_format["json_schema"]
197
+ if isinstance(schema.get("schema"), dict) and "strict" not in schema:
198
+ schema["strict"] = self.strict_output
199
+
200
+ request_params["response_format"] = response_format
201
+
202
+ # Add additional request params if provided
203
+ if self.request_params:
204
+ request_params.update(self.request_params)
205
+
206
+ if request_params:
207
+ log_debug(f"Calling {self.provider} with request parameters: {request_params}", log_level=2)
208
+ return request_params
209
+
210
+ def invoke(
211
+ self,
212
+ messages: List[Message],
213
+ assistant_message: Message,
214
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
215
+ tools: Optional[List[Dict[str, Any]]] = None,
216
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
217
+ run_response: Optional[RunOutput] = None,
218
+ ) -> ModelResponse:
219
+ """
220
+ Send a chat completion request to the Cerebras API.
221
+
222
+ Args:
223
+ messages (List[Message]): A list of messages to send to the model.
224
+
225
+ Returns:
226
+ CompletionResponse: The chat completion response from the API.
227
+ """
228
+ if run_response and run_response.metrics:
229
+ run_response.metrics.set_time_to_first_token()
230
+
231
+ assistant_message.metrics.start_timer()
232
+ provider_response = self.get_client().chat.completions.create(
233
+ model=self.id,
234
+ messages=[self._format_message(m) for m in messages], # type: ignore
235
+ **self.get_request_params(response_format=response_format, tools=tools),
236
+ )
237
+ assistant_message.metrics.stop_timer()
238
+
239
+ model_response = self._parse_provider_response(provider_response, response_format=response_format) # type: ignore
240
+
241
+ return model_response
242
+
243
+ async def ainvoke(
244
+ self,
245
+ messages: List[Message],
246
+ assistant_message: Message,
247
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
248
+ tools: Optional[List[Dict[str, Any]]] = None,
249
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
250
+ run_response: Optional[RunOutput] = None,
251
+ ) -> ModelResponse:
252
+ """
253
+ Sends an asynchronous chat completion request to the Cerebras API.
254
+
255
+ Args:
256
+ messages (List[Message]): A list of messages to send to the model.
257
+
258
+ Returns:
259
+ ChatCompletion: The chat completion response from the API.
260
+ """
261
+ if run_response and run_response.metrics:
262
+ run_response.metrics.set_time_to_first_token()
263
+
264
+ assistant_message.metrics.start_timer()
265
+ provider_response = await self.get_async_client().chat.completions.create(
266
+ model=self.id,
267
+ messages=[self._format_message(m) for m in messages], # type: ignore
268
+ **self.get_request_params(response_format=response_format, tools=tools),
269
+ )
270
+ assistant_message.metrics.stop_timer()
271
+
272
+ model_response = self._parse_provider_response(provider_response, response_format=response_format) # type: ignore
273
+
274
+ return model_response
275
+
276
+ def invoke_stream(
277
+ self,
278
+ messages: List[Message],
279
+ assistant_message: Message,
280
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
281
+ tools: Optional[List[Dict[str, Any]]] = None,
282
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
283
+ run_response: Optional[RunOutput] = None,
284
+ ) -> Iterator[ModelResponse]:
285
+ """
286
+ Send a streaming chat completion request to the Cerebras API.
287
+
288
+ Args:
289
+ messages (List[Message]): A list of messages to send to the model.
290
+
291
+ Returns:
292
+ Iterator[ChatChunkResponse]: An iterator of chat completion chunks.
293
+ """
294
+ if run_response and run_response.metrics:
295
+ run_response.metrics.set_time_to_first_token()
296
+
297
+ assistant_message.metrics.start_timer()
298
+
299
+ for chunk in self.get_client().chat.completions.create(
300
+ model=self.id,
301
+ messages=[self._format_message(m) for m in messages], # type: ignore
302
+ stream=True,
303
+ **self.get_request_params(response_format=response_format, tools=tools),
304
+ ):
305
+ yield self._parse_provider_response_delta(chunk) # type: ignore
306
+
307
+ assistant_message.metrics.stop_timer()
308
+
309
+ async def ainvoke_stream(
310
+ self,
311
+ messages: List[Message],
312
+ assistant_message: Message,
313
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
314
+ tools: Optional[List[Dict[str, Any]]] = None,
315
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
316
+ run_response: Optional[RunOutput] = None,
317
+ ) -> AsyncIterator[ModelResponse]:
318
+ """
319
+ Sends an asynchronous streaming chat completion request to the Cerebras API.
320
+
321
+ Args:
322
+ messages (List[Message]): A list of messages to send to the model.
323
+
324
+ Returns:
325
+ AsyncIterator[ChatChunkResponse]: An asynchronous iterator of chat completion chunks.
326
+ """
327
+ if run_response and run_response.metrics:
328
+ run_response.metrics.set_time_to_first_token()
329
+
330
+ assistant_message.metrics.start_timer()
331
+
332
+ async_stream = await self.get_async_client().chat.completions.create(
333
+ model=self.id,
334
+ messages=[self._format_message(m) for m in messages], # type: ignore
335
+ stream=True,
336
+ **self.get_request_params(response_format=response_format, tools=tools),
337
+ )
338
+
339
+ async for chunk in async_stream: # type: ignore
340
+ yield self._parse_provider_response_delta(chunk) # type: ignore
341
+
342
+ assistant_message.metrics.stop_timer()
343
+
344
+ def _format_message(self, message: Message) -> Dict[str, Any]:
345
+ """
346
+ Format a message into the format expected by the Cerebras API.
347
+
348
+ Args:
349
+ message (Message): The message to format.
350
+
351
+ Returns:
352
+ Dict[str, Any]: The formatted message.
353
+ """
354
+ # Basic message content
355
+ message_dict: Dict[str, Any] = {
356
+ "role": message.role,
357
+ "content": message.content if message.content is not None else "",
358
+ }
359
+
360
+ # Add name if present
361
+ if message.name:
362
+ message_dict["name"] = message.name
363
+
364
+ # Handle tool calls
365
+ if message.tool_calls:
366
+ # Ensure tool_calls is properly formatted
367
+ message_dict["tool_calls"] = [
368
+ {
369
+ "id": tool_call["id"],
370
+ "type": tool_call["type"],
371
+ "function": {
372
+ "name": tool_call["function"]["name"],
373
+ "arguments": json.dumps(tool_call["function"]["arguments"])
374
+ if isinstance(tool_call["function"]["arguments"], (dict, list))
375
+ else tool_call["function"]["arguments"],
376
+ },
377
+ }
378
+ for tool_call in message.tool_calls
379
+ ]
380
+
381
+ # Handle tool responses
382
+ if message.role == "tool" and message.tool_call_id:
383
+ message_dict = {
384
+ "role": "tool",
385
+ "tool_call_id": message.tool_call_id,
386
+ "content": message.content if message.content is not None else "",
387
+ }
388
+
389
+ # Ensure no None values in the message
390
+ message_dict = {k: v for k, v in message_dict.items() if v is not None}
391
+
392
+ return message_dict
393
+
394
+ def _parse_provider_response(self, response: ChatCompletionResponse, **kwargs) -> ModelResponse:
395
+ """
396
+ Parse the Cerebras response into a ModelResponse.
397
+
398
+ Args:
399
+ response (CompletionResponse): The response from the Cerebras API.
400
+
401
+ Returns:
402
+ ModelResponse: The parsed response.
403
+ """
404
+ model_response = ModelResponse()
405
+
406
+ # Get the first choice (assuming single response)
407
+ choice: ChatCompletionResponseChoice = response.choices[0]
408
+ message: ChatCompletionResponseChoiceMessage = choice.message
409
+
410
+ # Add role
411
+ if message.role is not None:
412
+ model_response.role = message.role
413
+
414
+ # Add content
415
+ if message.content is not None:
416
+ model_response.content = message.content
417
+
418
+ # Add tool calls
419
+ if message.tool_calls is not None:
420
+ try:
421
+ model_response.tool_calls = [
422
+ {
423
+ "id": tool_call.id,
424
+ "type": tool_call.type,
425
+ "function": {
426
+ "name": tool_call.function.name,
427
+ "arguments": tool_call.function.arguments,
428
+ },
429
+ }
430
+ for tool_call in message.tool_calls
431
+ ]
432
+ except Exception as e:
433
+ log_warning(f"Error processing tool calls: {e}")
434
+
435
+ # Add usage metrics
436
+ if response.usage:
437
+ model_response.response_usage = self._get_metrics(response.usage)
438
+
439
+ return model_response
440
+
441
+ def _parse_provider_response_delta(
442
+ self, response: Union[ChatChunkResponse, ChatCompletionResponse]
443
+ ) -> ModelResponse:
444
+ """
445
+ Parse the streaming response from the Cerebras API into a ModelResponse.
446
+
447
+ Args:
448
+ response (ChatChunkResponse): The streaming response chunk.
449
+
450
+ Returns:
451
+ ModelResponse: The parsed response.
452
+ """
453
+ model_response = ModelResponse()
454
+
455
+ # Get the first choice (assuming single response)
456
+ if response.choices is not None:
457
+ choice: Union[ChatChunkResponseChoice, ChatCompletionResponseChoice] = response.choices[0]
458
+ choice_delta: ChatChunkResponseChoiceDelta = choice.delta # type: ignore
459
+
460
+ if choice_delta:
461
+ # Add content
462
+ if choice_delta.content:
463
+ model_response.content = choice_delta.content
464
+
465
+ # Add tool calls
466
+ if choice_delta.tool_calls:
467
+ model_response.tool_calls = [
468
+ {
469
+ "id": tool_call.id,
470
+ "type": tool_call.type,
471
+ "function": {
472
+ "name": tool_call.function.name,
473
+ "arguments": tool_call.function.arguments,
474
+ },
475
+ }
476
+ for tool_call in choice_delta.tool_calls
477
+ ]
478
+
479
+ # Add usage metrics
480
+ if response.usage:
481
+ model_response.response_usage = self._get_metrics(response.usage)
482
+
483
+ return model_response
484
+
485
+ def _get_metrics(self, response_usage: Union[ChatCompletionResponseUsage, ChatChunkResponseUsage]) -> Metrics:
486
+ """
487
+ Parse the given Cerebras usage into an Agno Metrics object.
488
+
489
+ Args:
490
+ response_usage: Usage data from Cerebras
491
+
492
+ Returns:
493
+ Metrics: Parsed metrics data
494
+ """
495
+ metrics = Metrics()
496
+
497
+ metrics.input_tokens = response_usage.prompt_tokens or 0
498
+ metrics.output_tokens = response_usage.completion_tokens or 0
499
+ metrics.total_tokens = metrics.input_tokens + metrics.output_tokens
500
+
501
+ return metrics
@@ -0,0 +1,112 @@
1
+ import json
2
+ from dataclasses import dataclass, field
3
+ from os import getenv
4
+ from typing import Any, Dict, List, Optional, Type, Union
5
+
6
+ from pydantic import BaseModel
7
+
8
+ from agno.models.message import Message
9
+ from agno.models.openai.like import OpenAILike
10
+ from agno.utils.log import log_debug
11
+
12
+
13
+ @dataclass
14
+ class CerebrasOpenAI(OpenAILike):
15
+ id: str = "llama-4-scout-17b-16e-instruct"
16
+ name: str = "CerebrasOpenAI"
17
+ provider: str = "CerebrasOpenAI"
18
+
19
+ parallel_tool_calls: Optional[bool] = None
20
+ base_url: str = "https://api.cerebras.ai/v1"
21
+ api_key: Optional[str] = field(default_factory=lambda: getenv("CEREBRAS_API_KEY", None))
22
+
23
+ def get_request_params(
24
+ self,
25
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
26
+ tools: Optional[List[Dict[str, Any]]] = None,
27
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
28
+ **kwargs: Any,
29
+ ) -> Dict[str, Any]:
30
+ """
31
+ Returns keyword arguments for API requests.
32
+
33
+ Returns:
34
+ Dict[str, Any]: A dictionary of keyword arguments for API requests.
35
+ """
36
+ # Get base request kwargs from the parent class
37
+ request_params = super().get_request_params(
38
+ response_format=response_format, tools=tools, tool_choice=tool_choice
39
+ )
40
+
41
+ # Add tools with proper formatting
42
+ if tools is not None and len(tools) > 0:
43
+ request_params["tools"] = [
44
+ {
45
+ "type": "function",
46
+ "function": {
47
+ "name": tool["function"]["name"],
48
+ "description": tool["function"]["description"],
49
+ "parameters": tool["function"]["parameters"],
50
+ },
51
+ }
52
+ for tool in tools
53
+ ]
54
+ # Cerebras requires parallel_tool_calls=False for llama-4-scout-17b-16e-instruct
55
+ if self.id == "llama-4-scout-17b-16e-instruct":
56
+ request_params["parallel_tool_calls"] = False
57
+ elif self.parallel_tool_calls is not None:
58
+ request_params["parallel_tool_calls"] = self.parallel_tool_calls
59
+
60
+ if request_params:
61
+ log_debug(f"Calling {self.provider} with request parameters: {request_params}", log_level=2)
62
+ return request_params
63
+
64
+ def _format_message(self, message: Message) -> Dict[str, Any]:
65
+ """
66
+ Format a message into the format expected by the Cerebras API.
67
+
68
+ Args:
69
+ message (Message): The message to format.
70
+
71
+ Returns:
72
+ Dict[str, Any]: The formatted message.
73
+ """
74
+ # Basic message content
75
+ message_dict: Dict[str, Any] = {
76
+ "role": message.role,
77
+ "content": message.content if message.content is not None else "",
78
+ }
79
+
80
+ # Add name if present
81
+ if message.name:
82
+ message_dict["name"] = message.name
83
+
84
+ # Handle tool calls
85
+ if message.tool_calls:
86
+ # Ensure tool_calls is properly formatted
87
+ message_dict["tool_calls"] = [
88
+ {
89
+ "id": tool_call["id"],
90
+ "type": tool_call["type"],
91
+ "function": {
92
+ "name": tool_call["function"]["name"],
93
+ "arguments": json.dumps(tool_call["function"]["arguments"])
94
+ if isinstance(tool_call["function"]["arguments"], (dict, list))
95
+ else tool_call["function"]["arguments"],
96
+ },
97
+ }
98
+ for tool_call in message.tool_calls
99
+ ]
100
+
101
+ # Handle tool responses
102
+ if message.role == "tool" and message.tool_call_id:
103
+ message_dict = {
104
+ "role": "tool",
105
+ "tool_call_id": message.tool_call_id,
106
+ "content": message.content if message.content is not None else "",
107
+ }
108
+
109
+ # Ensure no None values in the message
110
+ message_dict = {k: v for k, v in message_dict.items() if v is not None}
111
+
112
+ return message_dict
@@ -0,0 +1,5 @@
1
+ from agno.models.cohere.chat import Cohere
2
+
3
+ __all__ = [
4
+ "Cohere",
5
+ ]