agno 0.1.2__py3-none-any.whl → 2.3.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 (723) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +44 -5
  3. agno/agent/agent.py +10531 -2975
  4. agno/api/agent.py +14 -53
  5. agno/api/api.py +7 -46
  6. agno/api/evals.py +22 -0
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -25
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +6 -9
  11. agno/api/schemas/evals.py +16 -0
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +10 -10
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +16 -0
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +22 -26
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/compression/__init__.py +3 -0
  25. agno/compression/manager.py +247 -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 +946 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2781 -0
  33. agno/db/dynamo/schemas.py +442 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +2379 -0
  37. agno/db/firestore/schemas.py +181 -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 +1791 -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 +1312 -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 +1777 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/manager.py +199 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/migrations/versions/v2_3_0.py +938 -0
  51. agno/db/mongo/__init__.py +17 -0
  52. agno/db/mongo/async_mongo.py +2760 -0
  53. agno/db/mongo/mongo.py +2597 -0
  54. agno/db/mongo/schemas.py +119 -0
  55. agno/db/mongo/utils.py +276 -0
  56. agno/db/mysql/__init__.py +4 -0
  57. agno/db/mysql/async_mysql.py +2912 -0
  58. agno/db/mysql/mysql.py +2923 -0
  59. agno/db/mysql/schemas.py +186 -0
  60. agno/db/mysql/utils.py +488 -0
  61. agno/db/postgres/__init__.py +4 -0
  62. agno/db/postgres/async_postgres.py +2579 -0
  63. agno/db/postgres/postgres.py +2870 -0
  64. agno/db/postgres/schemas.py +187 -0
  65. agno/db/postgres/utils.py +442 -0
  66. agno/db/redis/__init__.py +3 -0
  67. agno/db/redis/redis.py +2141 -0
  68. agno/db/redis/schemas.py +159 -0
  69. agno/db/redis/utils.py +346 -0
  70. agno/db/schemas/__init__.py +4 -0
  71. agno/db/schemas/culture.py +120 -0
  72. agno/db/schemas/evals.py +34 -0
  73. agno/db/schemas/knowledge.py +40 -0
  74. agno/db/schemas/memory.py +61 -0
  75. agno/db/singlestore/__init__.py +3 -0
  76. agno/db/singlestore/schemas.py +179 -0
  77. agno/db/singlestore/singlestore.py +2877 -0
  78. agno/db/singlestore/utils.py +384 -0
  79. agno/db/sqlite/__init__.py +4 -0
  80. agno/db/sqlite/async_sqlite.py +2911 -0
  81. agno/db/sqlite/schemas.py +181 -0
  82. agno/db/sqlite/sqlite.py +2908 -0
  83. agno/db/sqlite/utils.py +429 -0
  84. agno/db/surrealdb/__init__.py +3 -0
  85. agno/db/surrealdb/metrics.py +292 -0
  86. agno/db/surrealdb/models.py +334 -0
  87. agno/db/surrealdb/queries.py +71 -0
  88. agno/db/surrealdb/surrealdb.py +1908 -0
  89. agno/db/surrealdb/utils.py +147 -0
  90. agno/db/utils.py +118 -0
  91. agno/eval/__init__.py +24 -0
  92. agno/eval/accuracy.py +666 -276
  93. agno/eval/agent_as_judge.py +861 -0
  94. agno/eval/base.py +29 -0
  95. agno/eval/performance.py +779 -0
  96. agno/eval/reliability.py +241 -62
  97. agno/eval/utils.py +120 -0
  98. agno/exceptions.py +143 -1
  99. agno/filters.py +354 -0
  100. agno/guardrails/__init__.py +6 -0
  101. agno/guardrails/base.py +19 -0
  102. agno/guardrails/openai.py +144 -0
  103. agno/guardrails/pii.py +94 -0
  104. agno/guardrails/prompt_injection.py +52 -0
  105. agno/hooks/__init__.py +3 -0
  106. agno/hooks/decorator.py +164 -0
  107. agno/integrations/discord/__init__.py +3 -0
  108. agno/integrations/discord/client.py +203 -0
  109. agno/knowledge/__init__.py +5 -1
  110. agno/{document → knowledge}/chunking/agentic.py +22 -14
  111. agno/{document → knowledge}/chunking/document.py +2 -2
  112. agno/{document → knowledge}/chunking/fixed.py +7 -6
  113. agno/knowledge/chunking/markdown.py +151 -0
  114. agno/{document → knowledge}/chunking/recursive.py +15 -3
  115. agno/knowledge/chunking/row.py +39 -0
  116. agno/knowledge/chunking/semantic.py +91 -0
  117. agno/knowledge/chunking/strategy.py +165 -0
  118. agno/knowledge/content.py +74 -0
  119. agno/knowledge/document/__init__.py +5 -0
  120. agno/{document → knowledge/document}/base.py +12 -2
  121. agno/knowledge/embedder/__init__.py +5 -0
  122. agno/knowledge/embedder/aws_bedrock.py +343 -0
  123. agno/knowledge/embedder/azure_openai.py +210 -0
  124. agno/{embedder → knowledge/embedder}/base.py +8 -0
  125. agno/knowledge/embedder/cohere.py +323 -0
  126. agno/knowledge/embedder/fastembed.py +62 -0
  127. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  128. agno/knowledge/embedder/google.py +258 -0
  129. agno/knowledge/embedder/huggingface.py +94 -0
  130. agno/knowledge/embedder/jina.py +182 -0
  131. agno/knowledge/embedder/langdb.py +22 -0
  132. agno/knowledge/embedder/mistral.py +206 -0
  133. agno/knowledge/embedder/nebius.py +13 -0
  134. agno/knowledge/embedder/ollama.py +154 -0
  135. agno/knowledge/embedder/openai.py +195 -0
  136. agno/knowledge/embedder/sentence_transformer.py +63 -0
  137. agno/{embedder → knowledge/embedder}/together.py +1 -1
  138. agno/knowledge/embedder/vllm.py +262 -0
  139. agno/knowledge/embedder/voyageai.py +165 -0
  140. agno/knowledge/knowledge.py +3006 -0
  141. agno/knowledge/reader/__init__.py +7 -0
  142. agno/knowledge/reader/arxiv_reader.py +81 -0
  143. agno/knowledge/reader/base.py +95 -0
  144. agno/knowledge/reader/csv_reader.py +164 -0
  145. agno/knowledge/reader/docx_reader.py +82 -0
  146. agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
  147. agno/knowledge/reader/firecrawl_reader.py +201 -0
  148. agno/knowledge/reader/json_reader.py +88 -0
  149. agno/knowledge/reader/markdown_reader.py +137 -0
  150. agno/knowledge/reader/pdf_reader.py +431 -0
  151. agno/knowledge/reader/pptx_reader.py +101 -0
  152. agno/knowledge/reader/reader_factory.py +313 -0
  153. agno/knowledge/reader/s3_reader.py +89 -0
  154. agno/knowledge/reader/tavily_reader.py +193 -0
  155. agno/knowledge/reader/text_reader.py +127 -0
  156. agno/knowledge/reader/web_search_reader.py +325 -0
  157. agno/knowledge/reader/website_reader.py +455 -0
  158. agno/knowledge/reader/wikipedia_reader.py +91 -0
  159. agno/knowledge/reader/youtube_reader.py +78 -0
  160. agno/knowledge/remote_content/remote_content.py +88 -0
  161. agno/knowledge/reranker/__init__.py +3 -0
  162. agno/{reranker → knowledge/reranker}/base.py +1 -1
  163. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  164. agno/knowledge/reranker/infinity.py +195 -0
  165. agno/knowledge/reranker/sentence_transformer.py +54 -0
  166. agno/knowledge/types.py +39 -0
  167. agno/knowledge/utils.py +234 -0
  168. agno/media.py +439 -95
  169. agno/memory/__init__.py +16 -3
  170. agno/memory/manager.py +1474 -123
  171. agno/memory/strategies/__init__.py +15 -0
  172. agno/memory/strategies/base.py +66 -0
  173. agno/memory/strategies/summarize.py +196 -0
  174. agno/memory/strategies/types.py +37 -0
  175. agno/models/aimlapi/__init__.py +5 -0
  176. agno/models/aimlapi/aimlapi.py +62 -0
  177. agno/models/anthropic/__init__.py +4 -0
  178. agno/models/anthropic/claude.py +960 -496
  179. agno/models/aws/__init__.py +15 -0
  180. agno/models/aws/bedrock.py +686 -451
  181. agno/models/aws/claude.py +190 -183
  182. agno/models/azure/__init__.py +18 -1
  183. agno/models/azure/ai_foundry.py +489 -0
  184. agno/models/azure/openai_chat.py +89 -40
  185. agno/models/base.py +2477 -550
  186. agno/models/cerebras/__init__.py +12 -0
  187. agno/models/cerebras/cerebras.py +565 -0
  188. agno/models/cerebras/cerebras_openai.py +131 -0
  189. agno/models/cohere/__init__.py +4 -0
  190. agno/models/cohere/chat.py +306 -492
  191. agno/models/cometapi/__init__.py +5 -0
  192. agno/models/cometapi/cometapi.py +74 -0
  193. agno/models/dashscope/__init__.py +5 -0
  194. agno/models/dashscope/dashscope.py +90 -0
  195. agno/models/deepinfra/__init__.py +5 -0
  196. agno/models/deepinfra/deepinfra.py +45 -0
  197. agno/models/deepseek/__init__.py +4 -0
  198. agno/models/deepseek/deepseek.py +110 -9
  199. agno/models/fireworks/__init__.py +4 -0
  200. agno/models/fireworks/fireworks.py +19 -22
  201. agno/models/google/__init__.py +3 -7
  202. agno/models/google/gemini.py +1717 -662
  203. agno/models/google/utils.py +22 -0
  204. agno/models/groq/__init__.py +4 -0
  205. agno/models/groq/groq.py +391 -666
  206. agno/models/huggingface/__init__.py +4 -0
  207. agno/models/huggingface/huggingface.py +266 -538
  208. agno/models/ibm/__init__.py +5 -0
  209. agno/models/ibm/watsonx.py +432 -0
  210. agno/models/internlm/__init__.py +3 -0
  211. agno/models/internlm/internlm.py +20 -3
  212. agno/models/langdb/__init__.py +1 -0
  213. agno/models/langdb/langdb.py +60 -0
  214. agno/models/litellm/__init__.py +14 -0
  215. agno/models/litellm/chat.py +503 -0
  216. agno/models/litellm/litellm_openai.py +42 -0
  217. agno/models/llama_cpp/__init__.py +5 -0
  218. agno/models/llama_cpp/llama_cpp.py +22 -0
  219. agno/models/lmstudio/__init__.py +5 -0
  220. agno/models/lmstudio/lmstudio.py +25 -0
  221. agno/models/message.py +361 -39
  222. agno/models/meta/__init__.py +12 -0
  223. agno/models/meta/llama.py +502 -0
  224. agno/models/meta/llama_openai.py +79 -0
  225. agno/models/metrics.py +120 -0
  226. agno/models/mistral/__init__.py +4 -0
  227. agno/models/mistral/mistral.py +293 -393
  228. agno/models/nebius/__init__.py +3 -0
  229. agno/models/nebius/nebius.py +53 -0
  230. agno/models/nexus/__init__.py +3 -0
  231. agno/models/nexus/nexus.py +22 -0
  232. agno/models/nvidia/__init__.py +4 -0
  233. agno/models/nvidia/nvidia.py +22 -3
  234. agno/models/ollama/__init__.py +4 -2
  235. agno/models/ollama/chat.py +257 -492
  236. agno/models/openai/__init__.py +7 -0
  237. agno/models/openai/chat.py +725 -770
  238. agno/models/openai/like.py +16 -2
  239. agno/models/openai/responses.py +1121 -0
  240. agno/models/openrouter/__init__.py +4 -0
  241. agno/models/openrouter/openrouter.py +62 -5
  242. agno/models/perplexity/__init__.py +5 -0
  243. agno/models/perplexity/perplexity.py +203 -0
  244. agno/models/portkey/__init__.py +3 -0
  245. agno/models/portkey/portkey.py +82 -0
  246. agno/models/requesty/__init__.py +5 -0
  247. agno/models/requesty/requesty.py +69 -0
  248. agno/models/response.py +177 -7
  249. agno/models/sambanova/__init__.py +4 -0
  250. agno/models/sambanova/sambanova.py +23 -4
  251. agno/models/siliconflow/__init__.py +5 -0
  252. agno/models/siliconflow/siliconflow.py +42 -0
  253. agno/models/together/__init__.py +4 -0
  254. agno/models/together/together.py +21 -164
  255. agno/models/utils.py +266 -0
  256. agno/models/vercel/__init__.py +3 -0
  257. agno/models/vercel/v0.py +43 -0
  258. agno/models/vertexai/__init__.py +0 -1
  259. agno/models/vertexai/claude.py +190 -0
  260. agno/models/vllm/__init__.py +3 -0
  261. agno/models/vllm/vllm.py +83 -0
  262. agno/models/xai/__init__.py +2 -0
  263. agno/models/xai/xai.py +111 -7
  264. agno/os/__init__.py +3 -0
  265. agno/os/app.py +1027 -0
  266. agno/os/auth.py +244 -0
  267. agno/os/config.py +126 -0
  268. agno/os/interfaces/__init__.py +1 -0
  269. agno/os/interfaces/a2a/__init__.py +3 -0
  270. agno/os/interfaces/a2a/a2a.py +42 -0
  271. agno/os/interfaces/a2a/router.py +249 -0
  272. agno/os/interfaces/a2a/utils.py +924 -0
  273. agno/os/interfaces/agui/__init__.py +3 -0
  274. agno/os/interfaces/agui/agui.py +47 -0
  275. agno/os/interfaces/agui/router.py +147 -0
  276. agno/os/interfaces/agui/utils.py +574 -0
  277. agno/os/interfaces/base.py +25 -0
  278. agno/os/interfaces/slack/__init__.py +3 -0
  279. agno/os/interfaces/slack/router.py +148 -0
  280. agno/os/interfaces/slack/security.py +30 -0
  281. agno/os/interfaces/slack/slack.py +47 -0
  282. agno/os/interfaces/whatsapp/__init__.py +3 -0
  283. agno/os/interfaces/whatsapp/router.py +210 -0
  284. agno/os/interfaces/whatsapp/security.py +55 -0
  285. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  286. agno/os/mcp.py +293 -0
  287. agno/os/middleware/__init__.py +9 -0
  288. agno/os/middleware/jwt.py +797 -0
  289. agno/os/router.py +258 -0
  290. agno/os/routers/__init__.py +3 -0
  291. agno/os/routers/agents/__init__.py +3 -0
  292. agno/os/routers/agents/router.py +599 -0
  293. agno/os/routers/agents/schema.py +261 -0
  294. agno/os/routers/evals/__init__.py +3 -0
  295. agno/os/routers/evals/evals.py +450 -0
  296. agno/os/routers/evals/schemas.py +174 -0
  297. agno/os/routers/evals/utils.py +231 -0
  298. agno/os/routers/health.py +31 -0
  299. agno/os/routers/home.py +52 -0
  300. agno/os/routers/knowledge/__init__.py +3 -0
  301. agno/os/routers/knowledge/knowledge.py +1008 -0
  302. agno/os/routers/knowledge/schemas.py +178 -0
  303. agno/os/routers/memory/__init__.py +3 -0
  304. agno/os/routers/memory/memory.py +661 -0
  305. agno/os/routers/memory/schemas.py +88 -0
  306. agno/os/routers/metrics/__init__.py +3 -0
  307. agno/os/routers/metrics/metrics.py +190 -0
  308. agno/os/routers/metrics/schemas.py +47 -0
  309. agno/os/routers/session/__init__.py +3 -0
  310. agno/os/routers/session/session.py +997 -0
  311. agno/os/routers/teams/__init__.py +3 -0
  312. agno/os/routers/teams/router.py +512 -0
  313. agno/os/routers/teams/schema.py +257 -0
  314. agno/os/routers/traces/__init__.py +3 -0
  315. agno/os/routers/traces/schemas.py +414 -0
  316. agno/os/routers/traces/traces.py +499 -0
  317. agno/os/routers/workflows/__init__.py +3 -0
  318. agno/os/routers/workflows/router.py +624 -0
  319. agno/os/routers/workflows/schema.py +75 -0
  320. agno/os/schema.py +534 -0
  321. agno/os/scopes.py +469 -0
  322. agno/{playground → os}/settings.py +7 -15
  323. agno/os/utils.py +973 -0
  324. agno/reasoning/anthropic.py +80 -0
  325. agno/reasoning/azure_ai_foundry.py +67 -0
  326. agno/reasoning/deepseek.py +63 -0
  327. agno/reasoning/default.py +97 -0
  328. agno/reasoning/gemini.py +73 -0
  329. agno/reasoning/groq.py +71 -0
  330. agno/reasoning/helpers.py +24 -1
  331. agno/reasoning/ollama.py +67 -0
  332. agno/reasoning/openai.py +86 -0
  333. agno/reasoning/step.py +2 -1
  334. agno/reasoning/vertexai.py +76 -0
  335. agno/run/__init__.py +6 -0
  336. agno/run/agent.py +822 -0
  337. agno/run/base.py +247 -0
  338. agno/run/cancel.py +81 -0
  339. agno/run/requirement.py +181 -0
  340. agno/run/team.py +767 -0
  341. agno/run/workflow.py +708 -0
  342. agno/session/__init__.py +10 -0
  343. agno/session/agent.py +260 -0
  344. agno/session/summary.py +265 -0
  345. agno/session/team.py +342 -0
  346. agno/session/workflow.py +501 -0
  347. agno/table.py +10 -0
  348. agno/team/__init__.py +37 -0
  349. agno/team/team.py +9536 -0
  350. agno/tools/__init__.py +7 -0
  351. agno/tools/agentql.py +120 -0
  352. agno/tools/airflow.py +22 -12
  353. agno/tools/api.py +122 -0
  354. agno/tools/apify.py +276 -83
  355. agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
  356. agno/tools/aws_lambda.py +28 -7
  357. agno/tools/aws_ses.py +66 -0
  358. agno/tools/baidusearch.py +11 -4
  359. agno/tools/bitbucket.py +292 -0
  360. agno/tools/brandfetch.py +213 -0
  361. agno/tools/bravesearch.py +106 -0
  362. agno/tools/brightdata.py +367 -0
  363. agno/tools/browserbase.py +209 -0
  364. agno/tools/calcom.py +32 -23
  365. agno/tools/calculator.py +24 -37
  366. agno/tools/cartesia.py +187 -0
  367. agno/tools/{clickup_tool.py → clickup.py} +17 -28
  368. agno/tools/confluence.py +91 -26
  369. agno/tools/crawl4ai.py +139 -43
  370. agno/tools/csv_toolkit.py +28 -22
  371. agno/tools/dalle.py +36 -22
  372. agno/tools/daytona.py +475 -0
  373. agno/tools/decorator.py +169 -14
  374. agno/tools/desi_vocal.py +23 -11
  375. agno/tools/discord.py +32 -29
  376. agno/tools/docker.py +716 -0
  377. agno/tools/duckdb.py +76 -81
  378. agno/tools/duckduckgo.py +43 -40
  379. agno/tools/e2b.py +703 -0
  380. agno/tools/eleven_labs.py +65 -54
  381. agno/tools/email.py +13 -5
  382. agno/tools/evm.py +129 -0
  383. agno/tools/exa.py +324 -42
  384. agno/tools/fal.py +39 -35
  385. agno/tools/file.py +196 -30
  386. agno/tools/file_generation.py +356 -0
  387. agno/tools/financial_datasets.py +288 -0
  388. agno/tools/firecrawl.py +108 -33
  389. agno/tools/function.py +960 -122
  390. agno/tools/giphy.py +34 -12
  391. agno/tools/github.py +1294 -97
  392. agno/tools/gmail.py +922 -0
  393. agno/tools/google_bigquery.py +117 -0
  394. agno/tools/google_drive.py +271 -0
  395. agno/tools/google_maps.py +253 -0
  396. agno/tools/googlecalendar.py +607 -107
  397. agno/tools/googlesheets.py +377 -0
  398. agno/tools/hackernews.py +20 -12
  399. agno/tools/jina.py +24 -14
  400. agno/tools/jira.py +48 -19
  401. agno/tools/knowledge.py +218 -0
  402. agno/tools/linear.py +82 -43
  403. agno/tools/linkup.py +58 -0
  404. agno/tools/local_file_system.py +15 -7
  405. agno/tools/lumalab.py +41 -26
  406. agno/tools/mcp/__init__.py +10 -0
  407. agno/tools/mcp/mcp.py +331 -0
  408. agno/tools/mcp/multi_mcp.py +347 -0
  409. agno/tools/mcp/params.py +24 -0
  410. agno/tools/mcp_toolbox.py +284 -0
  411. agno/tools/mem0.py +193 -0
  412. agno/tools/memory.py +419 -0
  413. agno/tools/mlx_transcribe.py +11 -9
  414. agno/tools/models/azure_openai.py +190 -0
  415. agno/tools/models/gemini.py +203 -0
  416. agno/tools/models/groq.py +158 -0
  417. agno/tools/models/morph.py +186 -0
  418. agno/tools/models/nebius.py +124 -0
  419. agno/tools/models_labs.py +163 -82
  420. agno/tools/moviepy_video.py +18 -13
  421. agno/tools/nano_banana.py +151 -0
  422. agno/tools/neo4j.py +134 -0
  423. agno/tools/newspaper.py +15 -4
  424. agno/tools/newspaper4k.py +19 -6
  425. agno/tools/notion.py +204 -0
  426. agno/tools/openai.py +181 -17
  427. agno/tools/openbb.py +27 -20
  428. agno/tools/opencv.py +321 -0
  429. agno/tools/openweather.py +233 -0
  430. agno/tools/oxylabs.py +385 -0
  431. agno/tools/pandas.py +25 -15
  432. agno/tools/parallel.py +314 -0
  433. agno/tools/postgres.py +238 -185
  434. agno/tools/pubmed.py +125 -13
  435. agno/tools/python.py +48 -35
  436. agno/tools/reasoning.py +283 -0
  437. agno/tools/reddit.py +207 -29
  438. agno/tools/redshift.py +406 -0
  439. agno/tools/replicate.py +69 -26
  440. agno/tools/resend.py +11 -6
  441. agno/tools/scrapegraph.py +179 -19
  442. agno/tools/searxng.py +23 -31
  443. agno/tools/serpapi.py +15 -10
  444. agno/tools/serper.py +255 -0
  445. agno/tools/shell.py +23 -12
  446. agno/tools/shopify.py +1519 -0
  447. agno/tools/slack.py +56 -14
  448. agno/tools/sleep.py +8 -6
  449. agno/tools/spider.py +35 -11
  450. agno/tools/spotify.py +919 -0
  451. agno/tools/sql.py +34 -19
  452. agno/tools/tavily.py +158 -8
  453. agno/tools/telegram.py +18 -8
  454. agno/tools/todoist.py +218 -0
  455. agno/tools/toolkit.py +134 -9
  456. agno/tools/trafilatura.py +388 -0
  457. agno/tools/trello.py +25 -28
  458. agno/tools/twilio.py +18 -9
  459. agno/tools/user_control_flow.py +78 -0
  460. agno/tools/valyu.py +228 -0
  461. agno/tools/visualization.py +467 -0
  462. agno/tools/webbrowser.py +28 -0
  463. agno/tools/webex.py +76 -0
  464. agno/tools/website.py +23 -19
  465. agno/tools/webtools.py +45 -0
  466. agno/tools/whatsapp.py +286 -0
  467. agno/tools/wikipedia.py +28 -19
  468. agno/tools/workflow.py +285 -0
  469. agno/tools/{twitter.py → x.py} +142 -46
  470. agno/tools/yfinance.py +41 -39
  471. agno/tools/youtube.py +34 -17
  472. agno/tools/zendesk.py +15 -5
  473. agno/tools/zep.py +454 -0
  474. agno/tools/zoom.py +86 -37
  475. agno/tracing/__init__.py +12 -0
  476. agno/tracing/exporter.py +157 -0
  477. agno/tracing/schemas.py +276 -0
  478. agno/tracing/setup.py +111 -0
  479. agno/utils/agent.py +938 -0
  480. agno/utils/audio.py +37 -1
  481. agno/utils/certs.py +27 -0
  482. agno/utils/code_execution.py +11 -0
  483. agno/utils/common.py +103 -20
  484. agno/utils/cryptography.py +22 -0
  485. agno/utils/dttm.py +33 -0
  486. agno/utils/events.py +700 -0
  487. agno/utils/functions.py +107 -37
  488. agno/utils/gemini.py +426 -0
  489. agno/utils/hooks.py +171 -0
  490. agno/utils/http.py +185 -0
  491. agno/utils/json_schema.py +159 -37
  492. agno/utils/knowledge.py +36 -0
  493. agno/utils/location.py +19 -0
  494. agno/utils/log.py +221 -8
  495. agno/utils/mcp.py +214 -0
  496. agno/utils/media.py +335 -14
  497. agno/utils/merge_dict.py +22 -1
  498. agno/utils/message.py +77 -2
  499. agno/utils/models/ai_foundry.py +50 -0
  500. agno/utils/models/claude.py +373 -0
  501. agno/utils/models/cohere.py +94 -0
  502. agno/utils/models/llama.py +85 -0
  503. agno/utils/models/mistral.py +100 -0
  504. agno/utils/models/openai_responses.py +140 -0
  505. agno/utils/models/schema_utils.py +153 -0
  506. agno/utils/models/watsonx.py +41 -0
  507. agno/utils/openai.py +257 -0
  508. agno/utils/pickle.py +1 -1
  509. agno/utils/pprint.py +124 -8
  510. agno/utils/print_response/agent.py +930 -0
  511. agno/utils/print_response/team.py +1914 -0
  512. agno/utils/print_response/workflow.py +1668 -0
  513. agno/utils/prompts.py +111 -0
  514. agno/utils/reasoning.py +108 -0
  515. agno/utils/response.py +163 -0
  516. agno/utils/serialize.py +32 -0
  517. agno/utils/shell.py +4 -4
  518. agno/utils/streamlit.py +487 -0
  519. agno/utils/string.py +204 -51
  520. agno/utils/team.py +139 -0
  521. agno/utils/timer.py +9 -2
  522. agno/utils/tokens.py +657 -0
  523. agno/utils/tools.py +19 -1
  524. agno/utils/whatsapp.py +305 -0
  525. agno/utils/yaml_io.py +3 -3
  526. agno/vectordb/__init__.py +2 -0
  527. agno/vectordb/base.py +87 -9
  528. agno/vectordb/cassandra/__init__.py +5 -1
  529. agno/vectordb/cassandra/cassandra.py +383 -27
  530. agno/vectordb/chroma/__init__.py +4 -0
  531. agno/vectordb/chroma/chromadb.py +748 -83
  532. agno/vectordb/clickhouse/__init__.py +7 -1
  533. agno/vectordb/clickhouse/clickhousedb.py +554 -53
  534. agno/vectordb/couchbase/__init__.py +3 -0
  535. agno/vectordb/couchbase/couchbase.py +1446 -0
  536. agno/vectordb/lancedb/__init__.py +5 -0
  537. agno/vectordb/lancedb/lance_db.py +730 -98
  538. agno/vectordb/langchaindb/__init__.py +5 -0
  539. agno/vectordb/langchaindb/langchaindb.py +163 -0
  540. agno/vectordb/lightrag/__init__.py +5 -0
  541. agno/vectordb/lightrag/lightrag.py +388 -0
  542. agno/vectordb/llamaindex/__init__.py +3 -0
  543. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  544. agno/vectordb/milvus/__init__.py +3 -0
  545. agno/vectordb/milvus/milvus.py +966 -78
  546. agno/vectordb/mongodb/__init__.py +9 -1
  547. agno/vectordb/mongodb/mongodb.py +1175 -172
  548. agno/vectordb/pgvector/__init__.py +8 -0
  549. agno/vectordb/pgvector/pgvector.py +599 -115
  550. agno/vectordb/pineconedb/__init__.py +5 -1
  551. agno/vectordb/pineconedb/pineconedb.py +406 -43
  552. agno/vectordb/qdrant/__init__.py +4 -0
  553. agno/vectordb/qdrant/qdrant.py +914 -61
  554. agno/vectordb/redis/__init__.py +9 -0
  555. agno/vectordb/redis/redisdb.py +682 -0
  556. agno/vectordb/singlestore/__init__.py +8 -1
  557. agno/vectordb/singlestore/singlestore.py +771 -0
  558. agno/vectordb/surrealdb/__init__.py +3 -0
  559. agno/vectordb/surrealdb/surrealdb.py +663 -0
  560. agno/vectordb/upstashdb/__init__.py +5 -0
  561. agno/vectordb/upstashdb/upstashdb.py +718 -0
  562. agno/vectordb/weaviate/__init__.py +8 -0
  563. agno/vectordb/weaviate/index.py +15 -0
  564. agno/vectordb/weaviate/weaviate.py +1009 -0
  565. agno/workflow/__init__.py +23 -1
  566. agno/workflow/agent.py +299 -0
  567. agno/workflow/condition.py +759 -0
  568. agno/workflow/loop.py +756 -0
  569. agno/workflow/parallel.py +853 -0
  570. agno/workflow/router.py +723 -0
  571. agno/workflow/step.py +1564 -0
  572. agno/workflow/steps.py +613 -0
  573. agno/workflow/types.py +556 -0
  574. agno/workflow/workflow.py +4327 -514
  575. agno-2.3.13.dist-info/METADATA +639 -0
  576. agno-2.3.13.dist-info/RECORD +613 -0
  577. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
  578. agno-2.3.13.dist-info/licenses/LICENSE +201 -0
  579. agno/api/playground.py +0 -91
  580. agno/api/schemas/playground.py +0 -22
  581. agno/api/schemas/user.py +0 -22
  582. agno/api/schemas/workspace.py +0 -46
  583. agno/api/user.py +0 -160
  584. agno/api/workspace.py +0 -151
  585. agno/cli/auth_server.py +0 -118
  586. agno/cli/config.py +0 -275
  587. agno/cli/console.py +0 -88
  588. agno/cli/credentials.py +0 -23
  589. agno/cli/entrypoint.py +0 -571
  590. agno/cli/operator.py +0 -355
  591. agno/cli/settings.py +0 -85
  592. agno/cli/ws/ws_cli.py +0 -817
  593. agno/constants.py +0 -13
  594. agno/document/__init__.py +0 -1
  595. agno/document/chunking/semantic.py +0 -47
  596. agno/document/chunking/strategy.py +0 -31
  597. agno/document/reader/__init__.py +0 -1
  598. agno/document/reader/arxiv_reader.py +0 -41
  599. agno/document/reader/base.py +0 -22
  600. agno/document/reader/csv_reader.py +0 -84
  601. agno/document/reader/docx_reader.py +0 -46
  602. agno/document/reader/firecrawl_reader.py +0 -99
  603. agno/document/reader/json_reader.py +0 -43
  604. agno/document/reader/pdf_reader.py +0 -219
  605. agno/document/reader/s3/pdf_reader.py +0 -46
  606. agno/document/reader/s3/text_reader.py +0 -51
  607. agno/document/reader/text_reader.py +0 -41
  608. agno/document/reader/website_reader.py +0 -175
  609. agno/document/reader/youtube_reader.py +0 -50
  610. agno/embedder/__init__.py +0 -1
  611. agno/embedder/azure_openai.py +0 -86
  612. agno/embedder/cohere.py +0 -72
  613. agno/embedder/fastembed.py +0 -37
  614. agno/embedder/google.py +0 -73
  615. agno/embedder/huggingface.py +0 -54
  616. agno/embedder/mistral.py +0 -80
  617. agno/embedder/ollama.py +0 -57
  618. agno/embedder/openai.py +0 -74
  619. agno/embedder/sentence_transformer.py +0 -38
  620. agno/embedder/voyageai.py +0 -64
  621. agno/eval/perf.py +0 -201
  622. agno/file/__init__.py +0 -1
  623. agno/file/file.py +0 -16
  624. agno/file/local/csv.py +0 -32
  625. agno/file/local/txt.py +0 -19
  626. agno/infra/app.py +0 -240
  627. agno/infra/base.py +0 -144
  628. agno/infra/context.py +0 -20
  629. agno/infra/db_app.py +0 -52
  630. agno/infra/resource.py +0 -205
  631. agno/infra/resources.py +0 -55
  632. agno/knowledge/agent.py +0 -230
  633. agno/knowledge/arxiv.py +0 -22
  634. agno/knowledge/combined.py +0 -22
  635. agno/knowledge/csv.py +0 -28
  636. agno/knowledge/csv_url.py +0 -19
  637. agno/knowledge/document.py +0 -20
  638. agno/knowledge/docx.py +0 -30
  639. agno/knowledge/json.py +0 -28
  640. agno/knowledge/langchain.py +0 -71
  641. agno/knowledge/llamaindex.py +0 -66
  642. agno/knowledge/pdf.py +0 -28
  643. agno/knowledge/pdf_url.py +0 -26
  644. agno/knowledge/s3/base.py +0 -60
  645. agno/knowledge/s3/pdf.py +0 -21
  646. agno/knowledge/s3/text.py +0 -23
  647. agno/knowledge/text.py +0 -30
  648. agno/knowledge/website.py +0 -88
  649. agno/knowledge/wikipedia.py +0 -31
  650. agno/knowledge/youtube.py +0 -22
  651. agno/memory/agent.py +0 -392
  652. agno/memory/classifier.py +0 -104
  653. agno/memory/db/__init__.py +0 -1
  654. agno/memory/db/base.py +0 -42
  655. agno/memory/db/mongodb.py +0 -189
  656. agno/memory/db/postgres.py +0 -203
  657. agno/memory/db/sqlite.py +0 -193
  658. agno/memory/memory.py +0 -15
  659. agno/memory/row.py +0 -36
  660. agno/memory/summarizer.py +0 -192
  661. agno/memory/summary.py +0 -19
  662. agno/memory/workflow.py +0 -38
  663. agno/models/google/gemini_openai.py +0 -26
  664. agno/models/ollama/hermes.py +0 -221
  665. agno/models/ollama/tools.py +0 -362
  666. agno/models/vertexai/gemini.py +0 -595
  667. agno/playground/__init__.py +0 -3
  668. agno/playground/async_router.py +0 -421
  669. agno/playground/deploy.py +0 -249
  670. agno/playground/operator.py +0 -92
  671. agno/playground/playground.py +0 -91
  672. agno/playground/schemas.py +0 -76
  673. agno/playground/serve.py +0 -55
  674. agno/playground/sync_router.py +0 -405
  675. agno/reasoning/agent.py +0 -68
  676. agno/run/response.py +0 -112
  677. agno/storage/agent/__init__.py +0 -0
  678. agno/storage/agent/base.py +0 -38
  679. agno/storage/agent/dynamodb.py +0 -350
  680. agno/storage/agent/json.py +0 -92
  681. agno/storage/agent/mongodb.py +0 -228
  682. agno/storage/agent/postgres.py +0 -367
  683. agno/storage/agent/session.py +0 -79
  684. agno/storage/agent/singlestore.py +0 -303
  685. agno/storage/agent/sqlite.py +0 -357
  686. agno/storage/agent/yaml.py +0 -93
  687. agno/storage/workflow/__init__.py +0 -0
  688. agno/storage/workflow/base.py +0 -40
  689. agno/storage/workflow/mongodb.py +0 -233
  690. agno/storage/workflow/postgres.py +0 -366
  691. agno/storage/workflow/session.py +0 -60
  692. agno/storage/workflow/sqlite.py +0 -359
  693. agno/tools/googlesearch.py +0 -88
  694. agno/utils/defaults.py +0 -57
  695. agno/utils/filesystem.py +0 -39
  696. agno/utils/git.py +0 -52
  697. agno/utils/json_io.py +0 -30
  698. agno/utils/load_env.py +0 -19
  699. agno/utils/py_io.py +0 -19
  700. agno/utils/pyproject.py +0 -18
  701. agno/utils/resource_filter.py +0 -31
  702. agno/vectordb/singlestore/s2vectordb.py +0 -390
  703. agno/vectordb/singlestore/s2vectordb2.py +0 -355
  704. agno/workspace/__init__.py +0 -0
  705. agno/workspace/config.py +0 -325
  706. agno/workspace/enums.py +0 -6
  707. agno/workspace/helpers.py +0 -48
  708. agno/workspace/operator.py +0 -758
  709. agno/workspace/settings.py +0 -63
  710. agno-0.1.2.dist-info/LICENSE +0 -375
  711. agno-0.1.2.dist-info/METADATA +0 -502
  712. agno-0.1.2.dist-info/RECORD +0 -352
  713. agno-0.1.2.dist-info/entry_points.txt +0 -3
  714. /agno/{cli → db/migrations}/__init__.py +0 -0
  715. /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
  716. /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
  717. /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
  718. /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
  719. /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
  720. /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
  721. /agno/{reranker → utils/models}/__init__.py +0 -0
  722. /agno/{storage → utils/print_response}/__init__.py +0 -0
  723. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
@@ -1 +1,5 @@
1
1
  from agno.models.openrouter.openrouter import OpenRouter
2
+
3
+ __all__ = [
4
+ "OpenRouter",
5
+ ]
@@ -1,8 +1,12 @@
1
1
  from dataclasses import dataclass
2
2
  from os import getenv
3
- from typing import Optional
3
+ from typing import Any, Dict, List, Optional, Type, Union
4
4
 
5
+ from pydantic import BaseModel
6
+
7
+ from agno.exceptions import ModelAuthenticationError
5
8
  from agno.models.openai.like import OpenAILike
9
+ from agno.run.agent import RunOutput
6
10
 
7
11
 
8
12
  @dataclass
@@ -13,16 +17,69 @@ class OpenRouter(OpenAILike):
13
17
  Attributes:
14
18
  id (str): The model id. Defaults to "gpt-4o".
15
19
  name (str): The model name. Defaults to "OpenRouter".
16
- provider (str): The provider name. Defaults to "OpenRouter: " + id.
17
- api_key (Optional[str]): The API key. Defaults to None.
20
+ provider (str): The provider name. Defaults to "OpenRouter".
21
+ api_key (Optional[str]): The API key.
18
22
  base_url (str): The base URL. Defaults to "https://openrouter.ai/api/v1".
19
23
  max_tokens (int): The maximum number of tokens. Defaults to 1024.
24
+ fallback_models (Optional[List[str]]): List of fallback model IDs to use if the primary model
25
+ fails due to rate limits, timeouts, or unavailability. OpenRouter will automatically try
26
+ these models in order. Example: ["anthropic/claude-sonnet-4", "deepseek/deepseek-r1"]
20
27
  """
21
28
 
22
29
  id: str = "gpt-4o"
23
30
  name: str = "OpenRouter"
24
- provider: str = "OpenRouter: " + id
31
+ provider: str = "OpenRouter"
25
32
 
26
- api_key: Optional[str] = getenv("OPENROUTER_API_KEY")
33
+ api_key: Optional[str] = None
27
34
  base_url: str = "https://openrouter.ai/api/v1"
28
35
  max_tokens: int = 1024
36
+ models: Optional[List[str]] = None # Dynamic model routing https://openrouter.ai/docs/features/model-routing
37
+
38
+ def _get_client_params(self) -> Dict[str, Any]:
39
+ """
40
+ Returns client parameters for API requests, checking for OPENROUTER_API_KEY.
41
+
42
+ Returns:
43
+ Dict[str, Any]: A dictionary of client parameters for API requests.
44
+ """
45
+ # Fetch API key from env if not already set
46
+ if not self.api_key:
47
+ self.api_key = getenv("OPENROUTER_API_KEY")
48
+ if not self.api_key:
49
+ raise ModelAuthenticationError(
50
+ message="OPENROUTER_API_KEY not set. Please set the OPENROUTER_API_KEY environment variable.",
51
+ model_name=self.name,
52
+ )
53
+
54
+ return super()._get_client_params()
55
+
56
+ def get_request_params(
57
+ self,
58
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
59
+ tools: Optional[List[Dict[str, Any]]] = None,
60
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
61
+ run_response: Optional[RunOutput] = None,
62
+ ) -> Dict[str, Any]:
63
+ """
64
+ Returns keyword arguments for API requests, including fallback models configuration.
65
+
66
+ Returns:
67
+ Dict[str, Any]: A dictionary of keyword arguments for API requests.
68
+ """
69
+ # Get base request params from parent class
70
+ request_params = super().get_request_params(
71
+ response_format=response_format, tools=tools, tool_choice=tool_choice, run_response=run_response
72
+ )
73
+
74
+ # Add fallback models to extra_body if specified
75
+ if self.models:
76
+ # Get existing extra_body or create new dict
77
+ extra_body = request_params.get("extra_body") or {}
78
+
79
+ # Merge fallback models into extra_body
80
+ extra_body["models"] = self.models
81
+
82
+ # Update request params
83
+ request_params["extra_body"] = extra_body
84
+
85
+ return request_params
@@ -0,0 +1,5 @@
1
+ from agno.models.perplexity.perplexity import Perplexity
2
+
3
+ __all__ = [
4
+ "Perplexity",
5
+ ]
@@ -0,0 +1,203 @@
1
+ from dataclasses import dataclass, field
2
+ from os import getenv
3
+ from typing import Any, Dict, Optional, Type, Union
4
+
5
+ from pydantic import BaseModel
6
+
7
+ from agno.exceptions import ModelAuthenticationError, ModelProviderError
8
+ from agno.models.message import Citations, UrlCitation
9
+ from agno.models.metrics import Metrics
10
+ from agno.models.response import ModelResponse
11
+ from agno.utils.log import log_debug, log_warning
12
+
13
+ try:
14
+ from openai.types.chat.chat_completion import ChatCompletion
15
+ from openai.types.chat.chat_completion_chunk import (
16
+ ChatCompletionChunk,
17
+ ChoiceDelta,
18
+ )
19
+ from openai.types.chat.parsed_chat_completion import ParsedChatCompletion
20
+ from openai.types.completion_usage import CompletionUsage
21
+ except ModuleNotFoundError:
22
+ raise ImportError("`openai` not installed. Please install using `pip install openai`")
23
+
24
+ from agno.models.openai.like import OpenAILike
25
+
26
+
27
+ @dataclass
28
+ class Perplexity(OpenAILike):
29
+ """
30
+ A class for using models hosted on Perplexity.
31
+
32
+ Attributes:
33
+ id (str): The model id. Defaults to "sonar".
34
+ name (str): The model name. Defaults to "Perplexity".
35
+ provider (str): The provider name. Defaults to "Perplexity".
36
+ api_key (Optional[str]): The API key.
37
+ base_url (str): The base URL. Defaults to "https://api.perplexity.ai/chat/completions".
38
+ max_tokens (int): The maximum number of tokens. Defaults to 1024.
39
+ """
40
+
41
+ id: str = "sonar"
42
+ name: str = "Perplexity"
43
+ provider: str = "Perplexity"
44
+
45
+ api_key: Optional[str] = field(default_factory=lambda: getenv("PERPLEXITY_API_KEY"))
46
+ base_url: str = "https://api.perplexity.ai/"
47
+ max_tokens: int = 1024
48
+ top_k: Optional[float] = None
49
+
50
+ supports_native_structured_outputs: bool = False
51
+ supports_json_schema_outputs: bool = True
52
+
53
+ def _get_client_params(self) -> Dict[str, Any]:
54
+ """
55
+ Returns client parameters for API requests, checking for PERPLEXITY_API_KEY.
56
+
57
+ Returns:
58
+ Dict[str, Any]: A dictionary of client parameters for API requests.
59
+ """
60
+ if not self.api_key:
61
+ self.api_key = getenv("PERPLEXITY_API_KEY")
62
+ if not self.api_key:
63
+ raise ModelAuthenticationError(
64
+ message="PERPLEXITY_API_KEY not set. Please set the PERPLEXITY_API_KEY environment variable.",
65
+ model_name=self.name,
66
+ )
67
+ return super()._get_client_params()
68
+
69
+ def get_request_params(
70
+ self,
71
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
72
+ **kwargs: Any,
73
+ ) -> Dict[str, Any]:
74
+ """
75
+ Returns keyword arguments for API requests.
76
+ """
77
+ # Define base request parameters
78
+ base_params: Dict[str, Any] = {
79
+ "max_tokens": self.max_tokens,
80
+ "temperature": self.temperature,
81
+ "top_p": self.top_p,
82
+ "top_k": self.top_k,
83
+ "presence_penalty": self.presence_penalty,
84
+ "frequency_penalty": self.frequency_penalty,
85
+ }
86
+
87
+ if response_format is not None:
88
+ base_params["response_format"] = response_format
89
+
90
+ # Filter out None values
91
+ request_params = {k: v for k, v in base_params.items() if v is not None}
92
+ # Add additional request params if provided
93
+ if self.request_params:
94
+ request_params.update(self.request_params)
95
+
96
+ if request_params:
97
+ log_debug(f"Calling {self.provider} with request parameters: {request_params}", log_level=2)
98
+ return request_params
99
+
100
+ def parse_provider_response(self, response: Union[ChatCompletion, ParsedChatCompletion], **kwargs) -> ModelResponse:
101
+ """
102
+ Parse the Perplexity response into a ModelResponse.
103
+
104
+ Args:
105
+ response: Response from invoke() method
106
+
107
+ Returns:
108
+ ModelResponse: Parsed response data
109
+ """
110
+ model_response = ModelResponse()
111
+
112
+ if hasattr(response, "error") and response.error:
113
+ raise ModelProviderError(
114
+ message=response.error.get("message", "Unknown model error"),
115
+ model_name=self.name,
116
+ model_id=self.id,
117
+ )
118
+
119
+ # Get response message
120
+ response_message = response.choices[0].message
121
+
122
+ # Add role
123
+ if response_message.role is not None:
124
+ model_response.role = response_message.role
125
+
126
+ # Add content
127
+ if response_message.content is not None:
128
+ model_response.content = response_message.content
129
+
130
+ # Add tool calls
131
+ if response_message.tool_calls is not None and len(response_message.tool_calls) > 0:
132
+ try:
133
+ model_response.tool_calls = [t.model_dump() for t in response_message.tool_calls]
134
+ except Exception as e:
135
+ log_warning(f"Error processing tool calls: {e}")
136
+
137
+ # Add citations if present
138
+ if hasattr(response, "citations") and response.citations is not None:
139
+ model_response.citations = Citations(
140
+ urls=[UrlCitation(url=c) for c in response.citations],
141
+ )
142
+
143
+ if response.usage is not None:
144
+ model_response.response_usage = self._get_metrics(response.usage)
145
+
146
+ return model_response
147
+
148
+ def parse_provider_response_delta(self, response_delta: ChatCompletionChunk) -> ModelResponse:
149
+ """
150
+ Parse the Perplexity streaming response into a ModelResponse.
151
+
152
+ Args:
153
+ response_delta: Raw response chunk from Perplexity
154
+
155
+ Returns:
156
+ ProviderResponse: Iterator of parsed response data
157
+ """
158
+ model_response = ModelResponse()
159
+ if response_delta.choices and len(response_delta.choices) > 0:
160
+ choice_delta: ChoiceDelta = response_delta.choices[0].delta
161
+
162
+ if choice_delta:
163
+ # Add content
164
+ if choice_delta.content is not None:
165
+ model_response.content = choice_delta.content
166
+
167
+ # Add tool calls
168
+ if choice_delta.tool_calls is not None:
169
+ model_response.tool_calls = choice_delta.tool_calls # type: ignore
170
+
171
+ # Add citations if present
172
+ if hasattr(response_delta, "citations") and response_delta.citations is not None:
173
+ model_response.citations = Citations(
174
+ urls=[UrlCitation(url=c) for c in response_delta.citations],
175
+ )
176
+
177
+ # Add usage metrics if present
178
+ if response_delta.usage is not None:
179
+ model_response.response_usage = self._get_metrics(response_delta.usage)
180
+
181
+ return model_response
182
+
183
+ def _get_metrics(self, response_usage: CompletionUsage) -> Metrics:
184
+ """
185
+ Parse the given Perplexity usage into an Agno Metrics object.
186
+ """
187
+ metrics = Metrics()
188
+
189
+ metrics.input_tokens = response_usage.prompt_tokens or 0
190
+ metrics.output_tokens = response_usage.completion_tokens or 0
191
+ metrics.total_tokens = response_usage.total_tokens or 0
192
+
193
+ # Add the prompt_tokens_details field
194
+ if prompt_token_details := response_usage.prompt_tokens_details:
195
+ metrics.audio_input_tokens = prompt_token_details.audio_tokens or 0
196
+ metrics.cache_read_tokens = prompt_token_details.cached_tokens or 0
197
+
198
+ # Add the completion_tokens_details field
199
+ if completion_tokens_details := response_usage.completion_tokens_details:
200
+ metrics.audio_output_tokens = completion_tokens_details.audio_tokens or 0
201
+ metrics.reasoning_tokens = completion_tokens_details.reasoning_tokens or 0
202
+
203
+ return metrics
@@ -0,0 +1,3 @@
1
+ from agno.models.portkey.portkey import Portkey
2
+
3
+ __all__ = ["Portkey"]
@@ -0,0 +1,82 @@
1
+ from dataclasses import dataclass
2
+ from os import getenv
3
+ from typing import Any, Dict, Optional, cast
4
+
5
+ from agno.exceptions import ModelAuthenticationError
6
+ from agno.models.openai.like import OpenAILike
7
+
8
+ try:
9
+ from portkey_ai import PORTKEY_GATEWAY_URL, createHeaders
10
+ except ImportError:
11
+ raise ImportError("`portkey-ai` not installed. Please install using `pip install portkey-ai`")
12
+
13
+
14
+ @dataclass
15
+ class Portkey(OpenAILike):
16
+ """
17
+ A class for using models through the Portkey AI Gateway.
18
+
19
+ Attributes:
20
+ id (str): The model id. Defaults to "gpt-4o-mini".
21
+ name (str): The model name. Defaults to "Portkey".
22
+ provider (str): The provider name. Defaults to "Portkey".
23
+ portkey_api_key (Optional[str]): The Portkey API key.
24
+ virtual_key (Optional[str]): The virtual key for model routing.
25
+ config (Optional[Dict[str, Any]]): Portkey configuration for routing, retries, etc.
26
+ base_url (str): The Portkey gateway URL.
27
+ """
28
+
29
+ id: str = "gpt-4o-mini"
30
+ name: str = "Portkey"
31
+ provider: str = "Portkey"
32
+
33
+ portkey_api_key: Optional[str] = None
34
+ virtual_key: Optional[str] = None
35
+ config: Optional[Dict[str, Any]] = None
36
+ base_url: str = PORTKEY_GATEWAY_URL
37
+
38
+ def _get_client_params(self) -> Dict[str, Any]:
39
+ # Check for required keys
40
+ if not self.portkey_api_key:
41
+ raise ModelAuthenticationError(
42
+ message="PORTKEY_API_KEY not set. Please set the PORTKEY_API_KEY environment variable.",
43
+ model_name=self.name,
44
+ )
45
+
46
+ self.virtual_key = self.virtual_key or getenv("PORTKEY_VIRTUAL_KEY")
47
+
48
+ # Create headers using Portkey's createHeaders function
49
+ header_params: Dict[str, Any] = {
50
+ "api_key": self.portkey_api_key,
51
+ "virtual_key": self.virtual_key,
52
+ }
53
+
54
+ if self.config is not None:
55
+ header_params["config"] = self.config
56
+
57
+ portkey_headers = cast(Dict[str, Any], createHeaders(**header_params))
58
+
59
+ # Merge with any existing default headers
60
+ default_headers: Dict[str, Any] = {}
61
+ if self.default_headers and isinstance(self.default_headers, dict):
62
+ default_headers.update(self.default_headers)
63
+ default_headers.update(portkey_headers)
64
+
65
+ # Define base client params
66
+ base_params = {
67
+ "api_key": "not-needed", # We use virtual keys instead
68
+ "organization": self.organization,
69
+ "base_url": self.base_url,
70
+ "timeout": self.timeout,
71
+ "max_retries": self.max_retries,
72
+ "default_headers": default_headers,
73
+ "default_query": self.default_query,
74
+ }
75
+
76
+ # Create client_params dict with non-None values
77
+ client_params = {k: v for k, v in base_params.items() if v is not None}
78
+
79
+ # Add additional client params if provided
80
+ if self.client_params:
81
+ client_params.update(self.client_params)
82
+ return client_params
@@ -0,0 +1,5 @@
1
+ from agno.models.requesty.requesty import Requesty
2
+
3
+ __all__ = [
4
+ "Requesty",
5
+ ]
@@ -0,0 +1,69 @@
1
+ from dataclasses import dataclass
2
+ from os import getenv
3
+ from typing import Any, Dict, List, Optional, Type, Union
4
+
5
+ from pydantic import BaseModel
6
+
7
+ from agno.exceptions import ModelAuthenticationError
8
+ from agno.models.openai.like import OpenAILike
9
+ from agno.run.agent import RunOutput
10
+ from agno.run.team import TeamRunOutput
11
+
12
+
13
+ @dataclass
14
+ class Requesty(OpenAILike):
15
+ """
16
+ A class for using models hosted on Requesty.
17
+
18
+ Attributes:
19
+ id (str): The model id. Defaults to "openai/gpt-4.1".
20
+ provider (str): The provider name. Defaults to "Requesty".
21
+ api_key (Optional[str]): The API key.
22
+ base_url (str): The base URL. Defaults to "https://router.requesty.ai/v1".
23
+ max_tokens (int): The maximum number of tokens. Defaults to 1024.
24
+ """
25
+
26
+ id: str = "openai/gpt-4.1"
27
+ name: str = "Requesty"
28
+ provider: str = "Requesty"
29
+
30
+ api_key: Optional[str] = None
31
+ base_url: str = "https://router.requesty.ai/v1"
32
+ max_tokens: int = 1024
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
+
50
+ def get_request_params(
51
+ self,
52
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
53
+ tools: Optional[List[Dict[str, Any]]] = None,
54
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
55
+ run_response: Optional[Union[RunOutput, TeamRunOutput]] = None,
56
+ ) -> Dict[str, Any]:
57
+ params = super().get_request_params(
58
+ response_format=response_format, tools=tools, tool_choice=tool_choice, run_response=run_response
59
+ )
60
+
61
+ if "extra_body" not in params:
62
+ params["extra_body"] = {}
63
+ params["extra_body"]["requesty"] = {}
64
+ if run_response and run_response.user_id:
65
+ params["extra_body"]["requesty"]["user_id"] = run_response.user_id
66
+ if run_response and run_response.session_id:
67
+ params["extra_body"]["requesty"]["trace_id"] = run_response.session_id
68
+
69
+ return params
agno/models/response.py CHANGED
@@ -1,31 +1,201 @@
1
- from dataclasses import dataclass
1
+ from dataclasses import asdict, dataclass, field
2
2
  from enum import Enum
3
3
  from time import time
4
4
  from typing import Any, Dict, List, Optional
5
5
 
6
- from agno.media import AudioOutput
6
+ from agno.media import Audio, File, Image, Video
7
+ from agno.models.message import Citations
8
+ from agno.models.metrics import Metrics
9
+ from agno.tools.function import UserInputField
7
10
 
8
11
 
9
12
  class ModelResponseEvent(str, Enum):
10
- """Events that can be sent by the Model.response() method"""
13
+ """Events that can be sent by the model provider"""
11
14
 
15
+ tool_call_paused = "ToolCallPaused"
12
16
  tool_call_started = "ToolCallStarted"
13
17
  tool_call_completed = "ToolCallCompleted"
14
18
  assistant_response = "AssistantResponse"
15
19
 
16
20
 
21
+ @dataclass
22
+ class ToolExecution:
23
+ """Execution of a tool"""
24
+
25
+ tool_call_id: Optional[str] = None
26
+ tool_name: Optional[str] = None
27
+ tool_args: Optional[Dict[str, Any]] = None
28
+ tool_call_error: Optional[bool] = None
29
+ result: Optional[str] = None
30
+ metrics: Optional[Metrics] = None
31
+
32
+ # In the case where a tool call creates a run of an agent/team/workflow
33
+ child_run_id: Optional[str] = None
34
+
35
+ # If True, the agent will stop executing after this tool call.
36
+ stop_after_tool_call: bool = False
37
+
38
+ created_at: int = field(default_factory=lambda: int(time()))
39
+
40
+ # User control flow (HITL) fields
41
+ requires_confirmation: Optional[bool] = None
42
+ confirmed: Optional[bool] = None
43
+ confirmation_note: Optional[str] = None
44
+
45
+ requires_user_input: Optional[bool] = None
46
+ user_input_schema: Optional[List[UserInputField]] = None
47
+ answered: Optional[bool] = None
48
+
49
+ external_execution_required: Optional[bool] = None
50
+
51
+ @property
52
+ def is_paused(self) -> bool:
53
+ return bool(self.requires_confirmation or self.requires_user_input or self.external_execution_required)
54
+
55
+ def to_dict(self) -> Dict[str, Any]:
56
+ _dict = asdict(self)
57
+ if self.metrics is not None:
58
+ _dict["metrics"] = self.metrics.to_dict()
59
+
60
+ if self.user_input_schema is not None:
61
+ _dict["user_input_schema"] = [field.to_dict() for field in self.user_input_schema]
62
+
63
+ return _dict
64
+
65
+ @classmethod
66
+ def from_dict(cls, data: Dict[str, Any]) -> "ToolExecution":
67
+ return cls(
68
+ tool_call_id=data.get("tool_call_id"),
69
+ tool_name=data.get("tool_name"),
70
+ tool_args=data.get("tool_args"),
71
+ tool_call_error=data.get("tool_call_error"),
72
+ result=data.get("result"),
73
+ child_run_id=data.get("child_run_id"),
74
+ stop_after_tool_call=data.get("stop_after_tool_call", False),
75
+ requires_confirmation=data.get("requires_confirmation"),
76
+ confirmed=data.get("confirmed"),
77
+ confirmation_note=data.get("confirmation_note"),
78
+ requires_user_input=data.get("requires_user_input"),
79
+ user_input_schema=[UserInputField.from_dict(field) for field in data.get("user_input_schema") or []]
80
+ if "user_input_schema" in data
81
+ else None,
82
+ external_execution_required=data.get("external_execution_required"),
83
+ metrics=Metrics(**(data.get("metrics", {}) or {})),
84
+ **{"created_at": data["created_at"]} if "created_at" in data else {},
85
+ )
86
+
87
+
17
88
  @dataclass
18
89
  class ModelResponse:
19
- """Response returned by Model.response()"""
90
+ """Response from the model provider"""
91
+
92
+ role: Optional[str] = None
20
93
 
21
- content: Optional[str] = None
94
+ content: Optional[Any] = None
22
95
  parsed: Optional[Any] = None
23
- audio: Optional[AudioOutput] = None
24
- tool_calls: Optional[List[Dict[str, Any]]] = None
96
+ audio: Optional[Audio] = None
97
+
98
+ # Unified media fields for LLM-generated and tool-generated media artifacts
99
+ images: Optional[List[Image]] = None
100
+ videos: Optional[List[Video]] = None
101
+ audios: Optional[List[Audio]] = None
102
+ files: Optional[List[File]] = None
103
+
104
+ # Model tool calls
105
+ tool_calls: List[Dict[str, Any]] = field(default_factory=list)
106
+
107
+ # Actual tool executions
108
+ tool_executions: Optional[List[ToolExecution]] = field(default_factory=list)
109
+
25
110
  event: str = ModelResponseEvent.assistant_response.value
111
+
112
+ provider_data: Optional[Dict[str, Any]] = None
113
+
114
+ redacted_reasoning_content: Optional[str] = None
115
+ reasoning_content: Optional[str] = None
116
+
117
+ citations: Optional[Citations] = None
118
+
119
+ response_usage: Optional[Metrics] = None
120
+
26
121
  created_at: int = int(time())
27
122
 
123
+ extra: Optional[Dict[str, Any]] = None
124
+
125
+ updated_session_state: Optional[Dict[str, Any]] = None
126
+
127
+ def to_dict(self) -> Dict[str, Any]:
128
+ """Serialize ModelResponse to dictionary for caching."""
129
+ _dict = asdict(self)
130
+
131
+ # Handle special serialization for audio
132
+ if self.audio is not None:
133
+ _dict["audio"] = self.audio.to_dict()
134
+
135
+ # Handle lists of media objects
136
+ if self.images is not None:
137
+ _dict["images"] = [img.to_dict() for img in self.images]
138
+ if self.videos is not None:
139
+ _dict["videos"] = [vid.to_dict() for vid in self.videos]
140
+ if self.audios is not None:
141
+ _dict["audios"] = [aud.to_dict() for aud in self.audios]
142
+ if self.files is not None:
143
+ _dict["files"] = [f.to_dict() for f in self.files]
144
+
145
+ # Handle tool executions
146
+ if self.tool_executions is not None:
147
+ _dict["tool_executions"] = [tool_execution.to_dict() for tool_execution in self.tool_executions]
148
+
149
+ # Handle response usage which might be a Pydantic BaseModel
150
+ response_usage = _dict.pop("response_usage", None)
151
+ if response_usage is not None:
152
+ try:
153
+ from pydantic import BaseModel
154
+
155
+ if isinstance(response_usage, BaseModel):
156
+ _dict["response_usage"] = response_usage.model_dump()
157
+ else:
158
+ _dict["response_usage"] = response_usage
159
+ except ImportError:
160
+ _dict["response_usage"] = response_usage
161
+
162
+ return _dict
163
+
164
+ @classmethod
165
+ def from_dict(cls, data: Dict[str, Any]) -> "ModelResponse":
166
+ """Reconstruct ModelResponse from cached dictionary."""
167
+ # Reconstruct media objects
168
+ if data.get("audio"):
169
+ data["audio"] = Audio(**data["audio"])
170
+
171
+ if data.get("images"):
172
+ data["images"] = [Image(**img) for img in data["images"]]
173
+ if data.get("videos"):
174
+ data["videos"] = [Video(**vid) for vid in data["videos"]]
175
+ if data.get("audios"):
176
+ data["audios"] = [Audio(**aud) for aud in data["audios"]]
177
+ if data.get("files"):
178
+ data["files"] = [File(**f) for f in data["files"]]
179
+
180
+ # Reconstruct tool executions
181
+ if data.get("tool_executions"):
182
+ data["tool_executions"] = [ToolExecution.from_dict(te) for te in data["tool_executions"]]
183
+
184
+ # Reconstruct citations
185
+ if data.get("citations") and isinstance(data["citations"], dict):
186
+ data["citations"] = Citations(**data["citations"])
187
+
188
+ # Reconstruct response usage (Metrics)
189
+ if data.get("response_usage") and isinstance(data["response_usage"], dict):
190
+ from agno.models.metrics import Metrics
191
+
192
+ data["response_usage"] = Metrics(**data["response_usage"])
193
+
194
+ return cls(**data)
195
+
28
196
 
29
197
  class FileType(str, Enum):
30
198
  MP4 = "mp4"
31
199
  GIF = "gif"
200
+ MP3 = "mp3"
201
+ WAV = "wav"
@@ -1 +1,5 @@
1
1
  from agno.models.sambanova.sambanova import Sambanova
2
+
3
+ __all__ = [
4
+ "Sambanova",
5
+ ]