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,3 @@
1
+ from agno.os.routers.session.session import get_session_router
2
+
3
+ __all__ = ["get_session_router"]
@@ -0,0 +1,3 @@
1
+ from agno.os.routers.evals.evals import get_eval_router
2
+
3
+ __all__ = ["get_eval_router"]
@@ -0,0 +1,430 @@
1
+ import logging
2
+ from copy import deepcopy
3
+ from typing import List, Optional, Union, cast
4
+
5
+ from fastapi import APIRouter, Depends, HTTPException, Query
6
+
7
+ from agno.agent.agent import Agent
8
+ from agno.db.base import AsyncBaseDb, BaseDb
9
+ from agno.db.schemas.evals import EvalFilterType, EvalType
10
+ from agno.models.utils import get_model
11
+ from agno.os.auth import get_authentication_dependency
12
+ from agno.os.routers.evals.schemas import (
13
+ DeleteEvalRunsRequest,
14
+ EvalRunInput,
15
+ EvalSchema,
16
+ UpdateEvalRunRequest,
17
+ )
18
+ from agno.os.routers.evals.utils import run_accuracy_eval, run_performance_eval, run_reliability_eval
19
+ from agno.os.schema import (
20
+ BadRequestResponse,
21
+ InternalServerErrorResponse,
22
+ NotFoundResponse,
23
+ PaginatedResponse,
24
+ PaginationInfo,
25
+ SortOrder,
26
+ UnauthenticatedResponse,
27
+ ValidationErrorResponse,
28
+ )
29
+ from agno.os.settings import AgnoAPISettings
30
+ from agno.os.utils import get_agent_by_id, get_db, get_team_by_id
31
+ from agno.team.team import Team
32
+
33
+ logger = logging.getLogger(__name__)
34
+
35
+
36
+ def get_eval_router(
37
+ dbs: dict[str, list[Union[BaseDb, AsyncBaseDb]]],
38
+ agents: Optional[List[Agent]] = None,
39
+ teams: Optional[List[Team]] = None,
40
+ settings: AgnoAPISettings = AgnoAPISettings(),
41
+ ) -> APIRouter:
42
+ """Create eval router with comprehensive OpenAPI documentation for agent/team evaluation endpoints."""
43
+ router = APIRouter(
44
+ dependencies=[Depends(get_authentication_dependency(settings))],
45
+ tags=["Evals"],
46
+ responses={
47
+ 400: {"description": "Bad Request", "model": BadRequestResponse},
48
+ 401: {"description": "Unauthorized", "model": UnauthenticatedResponse},
49
+ 404: {"description": "Not Found", "model": NotFoundResponse},
50
+ 422: {"description": "Validation Error", "model": ValidationErrorResponse},
51
+ 500: {"description": "Internal Server Error", "model": InternalServerErrorResponse},
52
+ },
53
+ )
54
+ return attach_routes(router=router, dbs=dbs, agents=agents, teams=teams)
55
+
56
+
57
+ def attach_routes(
58
+ router: APIRouter,
59
+ dbs: dict[str, list[Union[BaseDb, AsyncBaseDb]]],
60
+ agents: Optional[List[Agent]] = None,
61
+ teams: Optional[List[Team]] = None,
62
+ ) -> APIRouter:
63
+ @router.get(
64
+ "/eval-runs",
65
+ response_model=PaginatedResponse[EvalSchema],
66
+ status_code=200,
67
+ operation_id="get_eval_runs",
68
+ summary="List Evaluation Runs",
69
+ description=(
70
+ "Retrieve paginated evaluation runs with filtering and sorting options. "
71
+ "Filter by agent, team, workflow, model, or evaluation type."
72
+ ),
73
+ responses={
74
+ 200: {
75
+ "description": "Evaluation runs retrieved successfully",
76
+ "content": {
77
+ "application/json": {
78
+ "example": {
79
+ "data": [
80
+ {
81
+ "id": "a03fa2f4-900d-482d-afe0-470d4cd8d1f4",
82
+ "agent_id": "basic-agent",
83
+ "model_id": "gpt-4o",
84
+ "model_provider": "OpenAI",
85
+ "team_id": None,
86
+ "workflow_id": None,
87
+ "name": "Test ",
88
+ "evaluated_component_name": None,
89
+ "eval_type": "reliability",
90
+ "eval_data": {
91
+ "eval_status": "PASSED",
92
+ "failed_tool_calls": [],
93
+ "passed_tool_calls": ["multiply"],
94
+ },
95
+ "eval_input": {"expected_tool_calls": ["multiply"]},
96
+ "created_at": "2025-08-27T15:41:59Z",
97
+ "updated_at": "2025-08-27T15:41:59Z",
98
+ }
99
+ ]
100
+ }
101
+ }
102
+ },
103
+ }
104
+ },
105
+ )
106
+ async def get_eval_runs(
107
+ agent_id: Optional[str] = Query(default=None, description="Agent ID"),
108
+ team_id: Optional[str] = Query(default=None, description="Team ID"),
109
+ workflow_id: Optional[str] = Query(default=None, description="Workflow ID"),
110
+ model_id: Optional[str] = Query(default=None, description="Model ID"),
111
+ filter_type: Optional[EvalFilterType] = Query(default=None, description="Filter type", alias="type"),
112
+ eval_types: Optional[List[EvalType]] = Depends(parse_eval_types_filter),
113
+ limit: Optional[int] = Query(default=20, description="Number of eval runs to return"),
114
+ page: Optional[int] = Query(default=1, description="Page number"),
115
+ sort_by: Optional[str] = Query(default="created_at", description="Field to sort by"),
116
+ sort_order: Optional[SortOrder] = Query(default="desc", description="Sort order (asc or desc)"),
117
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
118
+ table: Optional[str] = Query(default=None, description="The database table to use"),
119
+ ) -> PaginatedResponse[EvalSchema]:
120
+ db = await get_db(dbs, db_id, table)
121
+
122
+ if isinstance(db, AsyncBaseDb):
123
+ db = cast(AsyncBaseDb, db)
124
+ eval_runs, total_count = await db.get_eval_runs(
125
+ limit=limit,
126
+ page=page,
127
+ sort_by=sort_by,
128
+ sort_order=sort_order,
129
+ agent_id=agent_id,
130
+ team_id=team_id,
131
+ workflow_id=workflow_id,
132
+ model_id=model_id,
133
+ eval_type=eval_types,
134
+ filter_type=filter_type,
135
+ deserialize=False,
136
+ )
137
+ else:
138
+ eval_runs, total_count = db.get_eval_runs( # type: ignore
139
+ limit=limit,
140
+ page=page,
141
+ sort_by=sort_by,
142
+ sort_order=sort_order,
143
+ agent_id=agent_id,
144
+ team_id=team_id,
145
+ workflow_id=workflow_id,
146
+ model_id=model_id,
147
+ eval_type=eval_types,
148
+ filter_type=filter_type,
149
+ deserialize=False,
150
+ )
151
+
152
+ return PaginatedResponse(
153
+ data=[EvalSchema.from_dict(eval_run) for eval_run in eval_runs], # type: ignore
154
+ meta=PaginationInfo(
155
+ page=page,
156
+ limit=limit,
157
+ total_count=total_count, # type: ignore
158
+ total_pages=(total_count + limit - 1) // limit if limit is not None and limit > 0 else 0, # type: ignore
159
+ ),
160
+ )
161
+
162
+ @router.get(
163
+ "/eval-runs/{eval_run_id}",
164
+ response_model=EvalSchema,
165
+ status_code=200,
166
+ operation_id="get_eval_run",
167
+ summary="Get Evaluation Run",
168
+ description="Retrieve detailed results and metrics for a specific evaluation run.",
169
+ responses={
170
+ 200: {
171
+ "description": "Evaluation run details retrieved successfully",
172
+ "content": {
173
+ "application/json": {
174
+ "example": {
175
+ "id": "a03fa2f4-900d-482d-afe0-470d4cd8d1f4",
176
+ "agent_id": "basic-agent",
177
+ "model_id": "gpt-4o",
178
+ "model_provider": "OpenAI",
179
+ "team_id": None,
180
+ "workflow_id": None,
181
+ "name": "Test ",
182
+ "evaluated_component_name": None,
183
+ "eval_type": "reliability",
184
+ "eval_data": {
185
+ "eval_status": "PASSED",
186
+ "failed_tool_calls": [],
187
+ "passed_tool_calls": ["multiply"],
188
+ },
189
+ "eval_input": {"expected_tool_calls": ["multiply"]},
190
+ "created_at": "2025-08-27T15:41:59Z",
191
+ "updated_at": "2025-08-27T15:41:59Z",
192
+ }
193
+ }
194
+ },
195
+ },
196
+ 404: {"description": "Evaluation run not found", "model": NotFoundResponse},
197
+ },
198
+ )
199
+ async def get_eval_run(
200
+ eval_run_id: str,
201
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
202
+ table: Optional[str] = Query(default=None, description="Table to query eval run from"),
203
+ ) -> EvalSchema:
204
+ db = await get_db(dbs, db_id, table)
205
+ if isinstance(db, AsyncBaseDb):
206
+ db = cast(AsyncBaseDb, db)
207
+ eval_run = await db.get_eval_run(eval_run_id=eval_run_id, deserialize=False)
208
+ else:
209
+ eval_run = db.get_eval_run(eval_run_id=eval_run_id, deserialize=False)
210
+ if not eval_run:
211
+ raise HTTPException(status_code=404, detail=f"Eval run with id '{eval_run_id}' not found")
212
+
213
+ return EvalSchema.from_dict(eval_run) # type: ignore
214
+
215
+ @router.delete(
216
+ "/eval-runs",
217
+ status_code=204,
218
+ operation_id="delete_eval_runs",
219
+ summary="Delete Evaluation Runs",
220
+ description="Delete multiple evaluation runs by their IDs. This action cannot be undone.",
221
+ responses={
222
+ 204: {},
223
+ 500: {"description": "Failed to delete evaluation runs", "model": InternalServerErrorResponse},
224
+ },
225
+ )
226
+ async def delete_eval_runs(
227
+ request: DeleteEvalRunsRequest,
228
+ db_id: Optional[str] = Query(default=None, description="Database ID to use for deletion"),
229
+ table: Optional[str] = Query(default=None, description="Table to use for deletion"),
230
+ ) -> None:
231
+ try:
232
+ db = await get_db(dbs, db_id, table)
233
+ if isinstance(db, AsyncBaseDb):
234
+ db = cast(AsyncBaseDb, db)
235
+ await db.delete_eval_runs(eval_run_ids=request.eval_run_ids)
236
+ else:
237
+ db.delete_eval_runs(eval_run_ids=request.eval_run_ids)
238
+ except Exception as e:
239
+ raise HTTPException(status_code=500, detail=f"Failed to delete eval runs: {e}")
240
+
241
+ @router.patch(
242
+ "/eval-runs/{eval_run_id}",
243
+ response_model=EvalSchema,
244
+ status_code=200,
245
+ operation_id="update_eval_run",
246
+ summary="Update Evaluation Run",
247
+ description="Update the name or other properties of an existing evaluation run.",
248
+ responses={
249
+ 200: {
250
+ "description": "Evaluation run updated successfully",
251
+ "content": {
252
+ "application/json": {
253
+ "example": {
254
+ "id": "a03fa2f4-900d-482d-afe0-470d4cd8d1f4",
255
+ "agent_id": "basic-agent",
256
+ "model_id": "gpt-4o",
257
+ "model_provider": "OpenAI",
258
+ "team_id": None,
259
+ "workflow_id": None,
260
+ "name": "Test ",
261
+ "evaluated_component_name": None,
262
+ "eval_type": "reliability",
263
+ "eval_data": {
264
+ "eval_status": "PASSED",
265
+ "failed_tool_calls": [],
266
+ "passed_tool_calls": ["multiply"],
267
+ },
268
+ "eval_input": {"expected_tool_calls": ["multiply"]},
269
+ "created_at": "2025-08-27T15:41:59Z",
270
+ "updated_at": "2025-08-27T15:41:59Z",
271
+ }
272
+ }
273
+ },
274
+ },
275
+ 404: {"description": "Evaluation run not found", "model": NotFoundResponse},
276
+ 500: {"description": "Failed to update evaluation run", "model": InternalServerErrorResponse},
277
+ },
278
+ )
279
+ async def update_eval_run(
280
+ eval_run_id: str,
281
+ request: UpdateEvalRunRequest,
282
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
283
+ table: Optional[str] = Query(default=None, description="Table to use for rename operation"),
284
+ ) -> EvalSchema:
285
+ try:
286
+ db = await get_db(dbs, db_id, table)
287
+ if isinstance(db, AsyncBaseDb):
288
+ db = cast(AsyncBaseDb, db)
289
+ eval_run = await db.rename_eval_run(eval_run_id=eval_run_id, name=request.name, deserialize=False)
290
+ else:
291
+ eval_run = db.rename_eval_run(eval_run_id=eval_run_id, name=request.name, deserialize=False)
292
+ except Exception as e:
293
+ raise HTTPException(status_code=500, detail=f"Failed to rename eval run: {e}")
294
+
295
+ if not eval_run:
296
+ raise HTTPException(status_code=404, detail=f"Eval run with id '{eval_run_id}' not found")
297
+
298
+ return EvalSchema.from_dict(eval_run) # type: ignore
299
+
300
+ @router.post(
301
+ "/eval-runs",
302
+ response_model=EvalSchema,
303
+ status_code=200,
304
+ operation_id="run_eval",
305
+ summary="Execute Evaluation",
306
+ description=(
307
+ "Run evaluation tests on agents or teams. Supports accuracy, performance, and reliability evaluations. "
308
+ "Requires either agent_id or team_id, but not both."
309
+ ),
310
+ responses={
311
+ 200: {
312
+ "description": "Evaluation executed successfully",
313
+ "content": {
314
+ "application/json": {
315
+ "example": {
316
+ "id": "f2b2d72f-e9e2-4f0e-8810-0a7e1ff58614",
317
+ "agent_id": "basic-agent",
318
+ "model_id": "gpt-4o",
319
+ "model_provider": "OpenAI",
320
+ "team_id": None,
321
+ "workflow_id": None,
322
+ "name": None,
323
+ "evaluated_component_name": None,
324
+ "eval_type": "reliability",
325
+ "eval_data": {
326
+ "eval_status": "PASSED",
327
+ "failed_tool_calls": [],
328
+ "passed_tool_calls": ["multiply"],
329
+ },
330
+ "created_at": "2025-08-27T15:41:59Z",
331
+ "updated_at": "2025-08-27T15:41:59Z",
332
+ }
333
+ }
334
+ },
335
+ },
336
+ 400: {"description": "Invalid request - provide either agent_id or team_id", "model": BadRequestResponse},
337
+ 404: {"description": "Agent or team not found", "model": NotFoundResponse},
338
+ },
339
+ )
340
+ async def run_eval(
341
+ eval_run_input: EvalRunInput,
342
+ db_id: Optional[str] = Query(default=None, description="Database ID to use for evaluation"),
343
+ table: Optional[str] = Query(default=None, description="Table to use for evaluation"),
344
+ ) -> Optional[EvalSchema]:
345
+ db = await get_db(dbs, db_id, table)
346
+
347
+ if eval_run_input.agent_id and eval_run_input.team_id:
348
+ raise HTTPException(status_code=400, detail="Only one of agent_id or team_id must be provided")
349
+
350
+ if eval_run_input.agent_id:
351
+ agent = get_agent_by_id(agent_id=eval_run_input.agent_id, agents=agents)
352
+ if not agent:
353
+ raise HTTPException(status_code=404, detail=f"Agent with id '{eval_run_input.agent_id}' not found")
354
+
355
+ default_model = None
356
+ if (
357
+ hasattr(agent, "model")
358
+ and agent.model is not None
359
+ and eval_run_input.model_id is not None
360
+ and eval_run_input.model_provider is not None
361
+ ):
362
+ default_model = deepcopy(agent.model)
363
+ if eval_run_input.model_id != agent.model.id or eval_run_input.model_provider != agent.model.provider:
364
+ model_provider = eval_run_input.model_provider.lower()
365
+ model_id = eval_run_input.model_id.lower()
366
+ model_string = f"{model_provider}:{model_id}"
367
+ model = get_model(model_string)
368
+ agent.model = model
369
+
370
+ team = None
371
+
372
+ elif eval_run_input.team_id:
373
+ team = get_team_by_id(team_id=eval_run_input.team_id, teams=teams)
374
+ if not team:
375
+ raise HTTPException(status_code=404, detail=f"Team with id '{eval_run_input.team_id}' not found")
376
+
377
+ default_model = None
378
+ if (
379
+ hasattr(team, "model")
380
+ and team.model is not None
381
+ and eval_run_input.model_id is not None
382
+ and eval_run_input.model_provider is not None
383
+ ):
384
+ default_model = deepcopy(team.model)
385
+ if eval_run_input.model_id != team.model.id or eval_run_input.model_provider != team.model.provider:
386
+ model_provider = eval_run_input.model_provider.lower()
387
+ model_id = eval_run_input.model_id.lower()
388
+ model_string = f"{model_provider}:{model_id}"
389
+ model = get_model(model_string)
390
+ team.model = model
391
+
392
+ agent = None
393
+
394
+ else:
395
+ raise HTTPException(status_code=400, detail="One of agent_id or team_id must be provided")
396
+
397
+ # Run the evaluation
398
+ if eval_run_input.eval_type == EvalType.ACCURACY:
399
+ return await run_accuracy_eval(
400
+ eval_run_input=eval_run_input, db=db, agent=agent, team=team, default_model=default_model
401
+ )
402
+
403
+ elif eval_run_input.eval_type == EvalType.PERFORMANCE:
404
+ return await run_performance_eval(
405
+ eval_run_input=eval_run_input, db=db, agent=agent, team=team, default_model=default_model
406
+ )
407
+
408
+ else:
409
+ return await run_reliability_eval(
410
+ eval_run_input=eval_run_input, db=db, agent=agent, team=team, default_model=default_model
411
+ )
412
+
413
+ return router
414
+
415
+
416
+ def parse_eval_types_filter(
417
+ eval_types: Optional[str] = Query(
418
+ default=None,
419
+ description="Comma-separated eval types (accuracy,performance,reliability)",
420
+ examples=["accuracy,performance"],
421
+ ),
422
+ ) -> Optional[List[EvalType]]:
423
+ """Parse comma-separated eval types into EvalType enums for filtering evaluation runs."""
424
+ if not eval_types:
425
+ return None
426
+ try:
427
+ return [EvalType(item.strip()) for item in eval_types.split(",")]
428
+ except ValueError as e:
429
+ valid_types = ", ".join([t.value for t in EvalType])
430
+ raise HTTPException(status_code=422, detail=f"Invalid eval_type: {e}. Valid types: {valid_types}")
@@ -0,0 +1,142 @@
1
+ from dataclasses import asdict
2
+ from datetime import datetime, timezone
3
+ from typing import Any, Dict, List, Optional
4
+
5
+ from pydantic import BaseModel, Field
6
+
7
+ from agno.db.schemas.evals import EvalType
8
+ from agno.eval import AccuracyResult, PerformanceResult, ReliabilityResult
9
+ from agno.eval.accuracy import AccuracyEval
10
+ from agno.eval.performance import PerformanceEval
11
+ from agno.eval.reliability import ReliabilityEval
12
+
13
+
14
+ class EvalRunInput(BaseModel):
15
+ agent_id: Optional[str] = Field(None, description="Agent ID to evaluate")
16
+ team_id: Optional[str] = Field(None, description="Team ID to evaluate")
17
+
18
+ model_id: Optional[str] = Field(None, description="Model ID to use for evaluation")
19
+ model_provider: Optional[str] = Field(None, description="Model provider name")
20
+ eval_type: EvalType = Field(..., description="Type of evaluation to run (accuracy, performance, or reliability)")
21
+ input: str = Field(..., description="Input text/query for the evaluation", min_length=1)
22
+ additional_guidelines: Optional[str] = Field(None, description="Additional guidelines for the evaluation")
23
+ additional_context: Optional[str] = Field(None, description="Additional context for the evaluation")
24
+ num_iterations: int = Field(1, description="Number of times to run the evaluation", ge=1, le=100)
25
+ name: Optional[str] = Field(None, description="Name for this evaluation run")
26
+
27
+ # Accuracy eval specific fields
28
+ expected_output: Optional[str] = Field(None, description="Expected output for accuracy evaluation")
29
+
30
+ # Performance eval specific fields
31
+ warmup_runs: int = Field(0, description="Number of warmup runs before measuring performance", ge=0, le=10)
32
+
33
+ # Reliability eval specific fields
34
+ expected_tool_calls: Optional[List[str]] = Field(None, description="Expected tool calls for reliability evaluation")
35
+
36
+
37
+ class EvalSchema(BaseModel):
38
+ id: str = Field(..., description="Unique identifier for the evaluation run")
39
+
40
+ agent_id: Optional[str] = Field(None, description="Agent ID that was evaluated")
41
+ model_id: Optional[str] = Field(None, description="Model ID used in evaluation")
42
+ model_provider: Optional[str] = Field(None, description="Model provider name")
43
+ team_id: Optional[str] = Field(None, description="Team ID that was evaluated")
44
+ workflow_id: Optional[str] = Field(None, description="Workflow ID that was evaluated")
45
+ name: Optional[str] = Field(None, description="Name of the evaluation run")
46
+ evaluated_component_name: Optional[str] = Field(None, description="Name of the evaluated component")
47
+ eval_type: EvalType = Field(..., description="Type of evaluation (accuracy, performance, or reliability)")
48
+ eval_data: Dict[str, Any] = Field(..., description="Evaluation results and metrics")
49
+ eval_input: Optional[Dict[str, Any]] = Field(None, description="Input parameters used for the evaluation")
50
+ created_at: Optional[datetime] = Field(None, description="Timestamp when evaluation was created")
51
+ updated_at: Optional[datetime] = Field(None, description="Timestamp when evaluation was last updated")
52
+
53
+ @classmethod
54
+ def from_dict(cls, eval_run: Dict[str, Any]) -> "EvalSchema":
55
+ return cls(
56
+ id=eval_run["run_id"],
57
+ name=eval_run.get("name"),
58
+ agent_id=eval_run.get("agent_id"),
59
+ model_id=eval_run.get("model_id"),
60
+ model_provider=eval_run.get("model_provider"),
61
+ team_id=eval_run.get("team_id"),
62
+ workflow_id=eval_run.get("workflow_id"),
63
+ evaluated_component_name=eval_run.get("evaluated_component_name"),
64
+ eval_type=eval_run["eval_type"],
65
+ eval_data=eval_run["eval_data"],
66
+ eval_input=eval_run.get("eval_input"),
67
+ created_at=datetime.fromtimestamp(eval_run["created_at"], tz=timezone.utc),
68
+ updated_at=datetime.fromtimestamp(eval_run["updated_at"], tz=timezone.utc),
69
+ )
70
+
71
+ @classmethod
72
+ def from_accuracy_eval(cls, accuracy_eval: AccuracyEval, result: AccuracyResult) -> "EvalSchema":
73
+ model_provider = (
74
+ accuracy_eval.agent.model.provider
75
+ if accuracy_eval.agent and accuracy_eval.agent.model
76
+ else accuracy_eval.team.model.provider
77
+ if accuracy_eval.team and accuracy_eval.team.model
78
+ else None
79
+ )
80
+ return cls(
81
+ id=accuracy_eval.eval_id,
82
+ name=accuracy_eval.name,
83
+ agent_id=accuracy_eval.agent.id if accuracy_eval.agent else None,
84
+ team_id=accuracy_eval.team.id if accuracy_eval.team else None,
85
+ workflow_id=None,
86
+ model_id=accuracy_eval.agent.model.id if accuracy_eval.agent else accuracy_eval.team.model.id, # type: ignore
87
+ model_provider=model_provider,
88
+ eval_type=EvalType.ACCURACY,
89
+ eval_data=asdict(result),
90
+ )
91
+
92
+ @classmethod
93
+ def from_performance_eval(
94
+ cls,
95
+ performance_eval: PerformanceEval,
96
+ result: PerformanceResult,
97
+ model_id: Optional[str] = None,
98
+ model_provider: Optional[str] = None,
99
+ agent_id: Optional[str] = None,
100
+ team_id: Optional[str] = None,
101
+ ) -> "EvalSchema":
102
+ return cls(
103
+ id=performance_eval.eval_id,
104
+ name=performance_eval.name,
105
+ agent_id=agent_id,
106
+ team_id=team_id,
107
+ workflow_id=None,
108
+ model_id=model_id,
109
+ model_provider=model_provider,
110
+ eval_type=EvalType.PERFORMANCE,
111
+ eval_data=asdict(result),
112
+ )
113
+
114
+ @classmethod
115
+ def from_reliability_eval(
116
+ cls,
117
+ reliability_eval: ReliabilityEval,
118
+ result: ReliabilityResult,
119
+ model_id: Optional[str] = None,
120
+ model_provider: Optional[str] = None,
121
+ agent_id: Optional[str] = None,
122
+ team_id: Optional[str] = None,
123
+ ) -> "EvalSchema":
124
+ return cls(
125
+ id=reliability_eval.eval_id,
126
+ name=reliability_eval.name,
127
+ agent_id=agent_id,
128
+ team_id=team_id,
129
+ workflow_id=None,
130
+ model_id=model_id,
131
+ model_provider=model_provider,
132
+ eval_type=EvalType.RELIABILITY,
133
+ eval_data=asdict(result),
134
+ )
135
+
136
+
137
+ class DeleteEvalRunsRequest(BaseModel):
138
+ eval_run_ids: List[str] = Field(..., description="List of evaluation run IDs to delete", min_length=1)
139
+
140
+
141
+ class UpdateEvalRunRequest(BaseModel):
142
+ name: str = Field(..., description="New name for the evaluation run", min_length=1, max_length=255)