agno 1.8.1__py3-none-any.whl → 2.0.0a1__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 (580) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +2778 -4123
  4. agno/api/agent.py +9 -65
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +6 -17
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -41
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +5 -21
  11. agno/api/schemas/evals.py +7 -16
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +5 -21
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +11 -7
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +9 -64
  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/db/__init__.py +24 -0
  25. agno/db/base.py +245 -0
  26. agno/db/dynamo/__init__.py +3 -0
  27. agno/db/dynamo/dynamo.py +1749 -0
  28. agno/db/dynamo/schemas.py +278 -0
  29. agno/db/dynamo/utils.py +684 -0
  30. agno/db/firestore/__init__.py +3 -0
  31. agno/db/firestore/firestore.py +1438 -0
  32. agno/db/firestore/schemas.py +130 -0
  33. agno/db/firestore/utils.py +278 -0
  34. agno/db/gcs_json/__init__.py +3 -0
  35. agno/db/gcs_json/gcs_json_db.py +1001 -0
  36. agno/db/gcs_json/utils.py +194 -0
  37. agno/db/in_memory/__init__.py +3 -0
  38. agno/db/in_memory/in_memory_db.py +888 -0
  39. agno/db/in_memory/utils.py +172 -0
  40. agno/db/json/__init__.py +3 -0
  41. agno/db/json/json_db.py +1051 -0
  42. agno/db/json/utils.py +196 -0
  43. agno/db/migrations/v1_to_v2.py +162 -0
  44. agno/db/mongo/__init__.py +3 -0
  45. agno/db/mongo/mongo.py +1417 -0
  46. agno/db/mongo/schemas.py +77 -0
  47. agno/db/mongo/utils.py +204 -0
  48. agno/db/mysql/__init__.py +3 -0
  49. agno/db/mysql/mysql.py +1719 -0
  50. agno/db/mysql/schemas.py +124 -0
  51. agno/db/mysql/utils.py +298 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1720 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +281 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1371 -0
  58. agno/db/redis/schemas.py +109 -0
  59. agno/db/redis/utils.py +288 -0
  60. agno/db/schemas/__init__.py +3 -0
  61. agno/db/schemas/evals.py +33 -0
  62. agno/db/schemas/knowledge.py +40 -0
  63. agno/db/schemas/memory.py +46 -0
  64. agno/db/singlestore/__init__.py +3 -0
  65. agno/db/singlestore/schemas.py +116 -0
  66. agno/db/singlestore/singlestore.py +1722 -0
  67. agno/db/singlestore/utils.py +327 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1680 -0
  71. agno/db/sqlite/utils.py +269 -0
  72. agno/db/utils.py +88 -0
  73. agno/eval/__init__.py +14 -0
  74. agno/eval/accuracy.py +142 -43
  75. agno/eval/performance.py +88 -23
  76. agno/eval/reliability.py +73 -20
  77. agno/eval/utils.py +23 -13
  78. agno/integrations/discord/__init__.py +3 -0
  79. agno/{app → integrations}/discord/client.py +10 -10
  80. agno/knowledge/__init__.py +2 -2
  81. agno/{document → knowledge}/chunking/agentic.py +2 -2
  82. agno/{document → knowledge}/chunking/document.py +2 -2
  83. agno/{document → knowledge}/chunking/fixed.py +3 -3
  84. agno/{document → knowledge}/chunking/markdown.py +2 -2
  85. agno/{document → knowledge}/chunking/recursive.py +2 -2
  86. agno/{document → knowledge}/chunking/row.py +2 -2
  87. agno/knowledge/chunking/semantic.py +59 -0
  88. agno/knowledge/chunking/strategy.py +121 -0
  89. agno/knowledge/content.py +74 -0
  90. agno/knowledge/document/__init__.py +5 -0
  91. agno/{document → knowledge/document}/base.py +12 -2
  92. agno/knowledge/embedder/__init__.py +5 -0
  93. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  94. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  95. agno/{embedder → knowledge/embedder}/base.py +6 -0
  96. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  97. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  98. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  99. agno/{embedder → knowledge/embedder}/google.py +74 -1
  100. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  101. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  102. agno/knowledge/embedder/langdb.py +22 -0
  103. agno/knowledge/embedder/mistral.py +139 -0
  104. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  105. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  106. agno/knowledge/embedder/openai.py +223 -0
  107. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  108. agno/{embedder → knowledge/embedder}/together.py +1 -1
  109. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  110. agno/knowledge/knowledge.py +1515 -0
  111. agno/knowledge/reader/__init__.py +7 -0
  112. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  113. agno/knowledge/reader/base.py +88 -0
  114. agno/{document → knowledge}/reader/csv_reader.py +68 -15
  115. agno/knowledge/reader/docx_reader.py +83 -0
  116. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  117. agno/knowledge/reader/gcs_reader.py +67 -0
  118. agno/{document → knowledge}/reader/json_reader.py +30 -9
  119. agno/{document → knowledge}/reader/markdown_reader.py +36 -9
  120. agno/{document → knowledge}/reader/pdf_reader.py +79 -21
  121. agno/knowledge/reader/reader_factory.py +275 -0
  122. agno/knowledge/reader/s3_reader.py +171 -0
  123. agno/{document → knowledge}/reader/text_reader.py +31 -10
  124. agno/knowledge/reader/url_reader.py +84 -0
  125. agno/knowledge/reader/web_search_reader.py +389 -0
  126. agno/{document → knowledge}/reader/website_reader.py +37 -10
  127. agno/knowledge/reader/wikipedia_reader.py +59 -0
  128. agno/knowledge/reader/youtube_reader.py +78 -0
  129. agno/knowledge/remote_content/remote_content.py +88 -0
  130. agno/{reranker → knowledge/reranker}/base.py +1 -1
  131. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  132. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  133. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  134. agno/knowledge/types.py +30 -0
  135. agno/knowledge/utils.py +169 -0
  136. agno/memory/__init__.py +2 -10
  137. agno/memory/manager.py +1003 -148
  138. agno/models/aimlapi/__init__.py +2 -2
  139. agno/models/aimlapi/aimlapi.py +6 -6
  140. agno/models/anthropic/claude.py +129 -82
  141. agno/models/aws/bedrock.py +107 -175
  142. agno/models/aws/claude.py +64 -18
  143. agno/models/azure/ai_foundry.py +73 -23
  144. agno/models/base.py +347 -287
  145. agno/models/cerebras/cerebras.py +84 -27
  146. agno/models/cohere/chat.py +106 -98
  147. agno/models/google/gemini.py +100 -42
  148. agno/models/groq/groq.py +97 -35
  149. agno/models/huggingface/huggingface.py +92 -27
  150. agno/models/ibm/watsonx.py +72 -13
  151. agno/models/litellm/chat.py +85 -13
  152. agno/models/message.py +38 -144
  153. agno/models/meta/llama.py +85 -49
  154. agno/models/metrics.py +120 -0
  155. agno/models/mistral/mistral.py +90 -21
  156. agno/models/ollama/__init__.py +0 -2
  157. agno/models/ollama/chat.py +84 -46
  158. agno/models/openai/chat.py +121 -23
  159. agno/models/openai/responses.py +178 -105
  160. agno/models/perplexity/perplexity.py +26 -2
  161. agno/models/portkey/portkey.py +0 -7
  162. agno/models/response.py +14 -8
  163. agno/models/utils.py +20 -0
  164. agno/models/vercel/__init__.py +2 -2
  165. agno/models/vercel/v0.py +1 -1
  166. agno/models/vllm/__init__.py +2 -2
  167. agno/models/vllm/vllm.py +3 -3
  168. agno/models/xai/xai.py +10 -10
  169. agno/os/__init__.py +3 -0
  170. agno/os/app.py +393 -0
  171. agno/os/auth.py +47 -0
  172. agno/os/config.py +103 -0
  173. agno/os/interfaces/agui/__init__.py +3 -0
  174. agno/os/interfaces/agui/agui.py +31 -0
  175. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  176. agno/{app → os/interfaces}/agui/utils.py +65 -28
  177. agno/os/interfaces/base.py +21 -0
  178. agno/os/interfaces/slack/__init__.py +3 -0
  179. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  180. agno/os/interfaces/slack/slack.py +33 -0
  181. agno/os/interfaces/whatsapp/__init__.py +3 -0
  182. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  183. agno/os/interfaces/whatsapp/whatsapp.py +30 -0
  184. agno/os/router.py +843 -0
  185. agno/os/routers/__init__.py +3 -0
  186. agno/os/routers/evals/__init__.py +3 -0
  187. agno/os/routers/evals/evals.py +204 -0
  188. agno/os/routers/evals/schemas.py +142 -0
  189. agno/os/routers/evals/utils.py +161 -0
  190. agno/os/routers/knowledge/__init__.py +3 -0
  191. agno/os/routers/knowledge/knowledge.py +413 -0
  192. agno/os/routers/knowledge/schemas.py +118 -0
  193. agno/os/routers/memory/__init__.py +3 -0
  194. agno/os/routers/memory/memory.py +179 -0
  195. agno/os/routers/memory/schemas.py +58 -0
  196. agno/os/routers/metrics/__init__.py +3 -0
  197. agno/os/routers/metrics/metrics.py +58 -0
  198. agno/os/routers/metrics/schemas.py +47 -0
  199. agno/os/routers/session/__init__.py +3 -0
  200. agno/os/routers/session/session.py +163 -0
  201. agno/os/schema.py +892 -0
  202. agno/{app/playground → os}/settings.py +8 -15
  203. agno/os/utils.py +270 -0
  204. agno/reasoning/azure_ai_foundry.py +4 -4
  205. agno/reasoning/deepseek.py +4 -4
  206. agno/reasoning/default.py +6 -11
  207. agno/reasoning/groq.py +4 -4
  208. agno/reasoning/helpers.py +4 -6
  209. agno/reasoning/ollama.py +4 -4
  210. agno/reasoning/openai.py +4 -4
  211. agno/run/{response.py → agent.py} +144 -72
  212. agno/run/base.py +44 -58
  213. agno/run/cancel.py +83 -0
  214. agno/run/team.py +133 -77
  215. agno/run/workflow.py +537 -12
  216. agno/session/__init__.py +10 -0
  217. agno/session/agent.py +244 -0
  218. agno/session/summary.py +225 -0
  219. agno/session/team.py +262 -0
  220. agno/{storage/session/v2 → session}/workflow.py +47 -24
  221. agno/team/__init__.py +15 -16
  222. agno/team/team.py +2961 -4253
  223. agno/tools/agentql.py +14 -5
  224. agno/tools/airflow.py +9 -4
  225. agno/tools/api.py +7 -3
  226. agno/tools/apify.py +2 -46
  227. agno/tools/arxiv.py +8 -3
  228. agno/tools/aws_lambda.py +7 -5
  229. agno/tools/aws_ses.py +7 -1
  230. agno/tools/baidusearch.py +4 -1
  231. agno/tools/bitbucket.py +4 -4
  232. agno/tools/brandfetch.py +14 -11
  233. agno/tools/bravesearch.py +4 -1
  234. agno/tools/brightdata.py +42 -22
  235. agno/tools/browserbase.py +13 -4
  236. agno/tools/calcom.py +12 -10
  237. agno/tools/calculator.py +10 -27
  238. agno/tools/cartesia.py +18 -13
  239. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  240. agno/tools/confluence.py +8 -8
  241. agno/tools/crawl4ai.py +7 -1
  242. agno/tools/csv_toolkit.py +9 -8
  243. agno/tools/dalle.py +18 -11
  244. agno/tools/daytona.py +13 -16
  245. agno/tools/decorator.py +6 -3
  246. agno/tools/desi_vocal.py +16 -7
  247. agno/tools/discord.py +11 -8
  248. agno/tools/docker.py +30 -42
  249. agno/tools/duckdb.py +34 -53
  250. agno/tools/duckduckgo.py +8 -7
  251. agno/tools/e2b.py +61 -61
  252. agno/tools/eleven_labs.py +35 -28
  253. agno/tools/email.py +4 -1
  254. agno/tools/evm.py +7 -1
  255. agno/tools/exa.py +19 -14
  256. agno/tools/fal.py +29 -29
  257. agno/tools/file.py +9 -8
  258. agno/tools/financial_datasets.py +25 -44
  259. agno/tools/firecrawl.py +22 -22
  260. agno/tools/function.py +68 -17
  261. agno/tools/giphy.py +22 -10
  262. agno/tools/github.py +48 -126
  263. agno/tools/gmail.py +45 -61
  264. agno/tools/google_bigquery.py +7 -6
  265. agno/tools/google_maps.py +11 -26
  266. agno/tools/googlesearch.py +7 -2
  267. agno/tools/googlesheets.py +21 -17
  268. agno/tools/hackernews.py +9 -5
  269. agno/tools/jina.py +5 -4
  270. agno/tools/jira.py +18 -9
  271. agno/tools/knowledge.py +31 -32
  272. agno/tools/linear.py +18 -33
  273. agno/tools/linkup.py +5 -1
  274. agno/tools/local_file_system.py +8 -5
  275. agno/tools/lumalab.py +31 -19
  276. agno/tools/mem0.py +18 -12
  277. agno/tools/memori.py +14 -10
  278. agno/tools/mlx_transcribe.py +3 -2
  279. agno/tools/models/azure_openai.py +32 -14
  280. agno/tools/models/gemini.py +58 -31
  281. agno/tools/models/groq.py +29 -20
  282. agno/tools/models/nebius.py +27 -11
  283. agno/tools/models_labs.py +39 -15
  284. agno/tools/moviepy_video.py +7 -6
  285. agno/tools/neo4j.py +10 -8
  286. agno/tools/newspaper.py +7 -2
  287. agno/tools/newspaper4k.py +8 -3
  288. agno/tools/openai.py +57 -26
  289. agno/tools/openbb.py +12 -11
  290. agno/tools/opencv.py +62 -46
  291. agno/tools/openweather.py +14 -12
  292. agno/tools/pandas.py +11 -3
  293. agno/tools/postgres.py +4 -12
  294. agno/tools/pubmed.py +4 -1
  295. agno/tools/python.py +9 -22
  296. agno/tools/reasoning.py +35 -27
  297. agno/tools/reddit.py +11 -26
  298. agno/tools/replicate.py +54 -41
  299. agno/tools/resend.py +4 -1
  300. agno/tools/scrapegraph.py +15 -14
  301. agno/tools/searxng.py +10 -23
  302. agno/tools/serpapi.py +6 -3
  303. agno/tools/serper.py +13 -4
  304. agno/tools/shell.py +9 -2
  305. agno/tools/slack.py +12 -11
  306. agno/tools/sleep.py +3 -2
  307. agno/tools/spider.py +24 -4
  308. agno/tools/sql.py +7 -6
  309. agno/tools/tavily.py +6 -4
  310. agno/tools/telegram.py +12 -4
  311. agno/tools/todoist.py +11 -31
  312. agno/tools/toolkit.py +1 -1
  313. agno/tools/trafilatura.py +22 -6
  314. agno/tools/trello.py +9 -22
  315. agno/tools/twilio.py +10 -3
  316. agno/tools/user_control_flow.py +6 -1
  317. agno/tools/valyu.py +34 -5
  318. agno/tools/visualization.py +19 -28
  319. agno/tools/webbrowser.py +4 -3
  320. agno/tools/webex.py +11 -7
  321. agno/tools/website.py +15 -46
  322. agno/tools/webtools.py +12 -4
  323. agno/tools/whatsapp.py +5 -9
  324. agno/tools/wikipedia.py +20 -13
  325. agno/tools/x.py +14 -13
  326. agno/tools/yfinance.py +13 -40
  327. agno/tools/youtube.py +26 -20
  328. agno/tools/zendesk.py +7 -2
  329. agno/tools/zep.py +10 -7
  330. agno/tools/zoom.py +10 -9
  331. agno/utils/common.py +1 -19
  332. agno/utils/events.py +95 -118
  333. agno/utils/knowledge.py +29 -0
  334. agno/utils/log.py +2 -2
  335. agno/utils/mcp.py +11 -5
  336. agno/utils/media.py +39 -0
  337. agno/utils/message.py +12 -1
  338. agno/utils/models/claude.py +6 -4
  339. agno/utils/models/mistral.py +8 -7
  340. agno/utils/models/schema_utils.py +3 -3
  341. agno/utils/pprint.py +33 -32
  342. agno/utils/print_response/agent.py +779 -0
  343. agno/utils/print_response/team.py +1565 -0
  344. agno/utils/print_response/workflow.py +1451 -0
  345. agno/utils/prompts.py +14 -14
  346. agno/utils/reasoning.py +87 -0
  347. agno/utils/response.py +42 -42
  348. agno/utils/string.py +8 -22
  349. agno/utils/team.py +50 -0
  350. agno/utils/timer.py +2 -2
  351. agno/vectordb/base.py +33 -21
  352. agno/vectordb/cassandra/cassandra.py +287 -23
  353. agno/vectordb/chroma/chromadb.py +482 -59
  354. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  355. agno/vectordb/couchbase/couchbase.py +309 -29
  356. agno/vectordb/lancedb/lance_db.py +360 -21
  357. agno/vectordb/langchaindb/__init__.py +5 -0
  358. agno/vectordb/langchaindb/langchaindb.py +145 -0
  359. agno/vectordb/lightrag/__init__.py +5 -0
  360. agno/vectordb/lightrag/lightrag.py +374 -0
  361. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  362. agno/vectordb/milvus/milvus.py +242 -32
  363. agno/vectordb/mongodb/mongodb.py +200 -24
  364. agno/vectordb/pgvector/pgvector.py +319 -37
  365. agno/vectordb/pineconedb/pineconedb.py +221 -27
  366. agno/vectordb/qdrant/qdrant.py +334 -14
  367. agno/vectordb/singlestore/singlestore.py +286 -29
  368. agno/vectordb/surrealdb/surrealdb.py +187 -7
  369. agno/vectordb/upstashdb/upstashdb.py +342 -26
  370. agno/vectordb/weaviate/weaviate.py +227 -165
  371. agno/workflow/__init__.py +17 -13
  372. agno/workflow/{v2/condition.py → condition.py} +135 -32
  373. agno/workflow/{v2/loop.py → loop.py} +115 -28
  374. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  375. agno/workflow/{v2/router.py → router.py} +133 -32
  376. agno/workflow/{v2/step.py → step.py} +200 -42
  377. agno/workflow/{v2/steps.py → steps.py} +147 -66
  378. agno/workflow/types.py +482 -0
  379. agno/workflow/workflow.py +2394 -696
  380. agno-2.0.0a1.dist-info/METADATA +355 -0
  381. agno-2.0.0a1.dist-info/RECORD +514 -0
  382. agno/agent/metrics.py +0 -107
  383. agno/api/app.py +0 -35
  384. agno/api/playground.py +0 -92
  385. agno/api/schemas/app.py +0 -12
  386. agno/api/schemas/playground.py +0 -22
  387. agno/api/schemas/user.py +0 -35
  388. agno/api/schemas/workspace.py +0 -46
  389. agno/api/user.py +0 -160
  390. agno/api/workflows.py +0 -33
  391. agno/api/workspace.py +0 -175
  392. agno/app/agui/__init__.py +0 -3
  393. agno/app/agui/app.py +0 -17
  394. agno/app/agui/sync_router.py +0 -120
  395. agno/app/base.py +0 -186
  396. agno/app/discord/__init__.py +0 -3
  397. agno/app/fastapi/__init__.py +0 -3
  398. agno/app/fastapi/app.py +0 -107
  399. agno/app/fastapi/async_router.py +0 -457
  400. agno/app/fastapi/sync_router.py +0 -448
  401. agno/app/playground/app.py +0 -228
  402. agno/app/playground/async_router.py +0 -1050
  403. agno/app/playground/deploy.py +0 -249
  404. agno/app/playground/operator.py +0 -183
  405. agno/app/playground/schemas.py +0 -220
  406. agno/app/playground/serve.py +0 -55
  407. agno/app/playground/sync_router.py +0 -1042
  408. agno/app/playground/utils.py +0 -46
  409. agno/app/settings.py +0 -15
  410. agno/app/slack/__init__.py +0 -3
  411. agno/app/slack/app.py +0 -19
  412. agno/app/slack/sync_router.py +0 -92
  413. agno/app/utils.py +0 -54
  414. agno/app/whatsapp/__init__.py +0 -3
  415. agno/app/whatsapp/app.py +0 -15
  416. agno/app/whatsapp/sync_router.py +0 -197
  417. agno/cli/auth_server.py +0 -249
  418. agno/cli/config.py +0 -274
  419. agno/cli/console.py +0 -88
  420. agno/cli/credentials.py +0 -23
  421. agno/cli/entrypoint.py +0 -571
  422. agno/cli/operator.py +0 -357
  423. agno/cli/settings.py +0 -96
  424. agno/cli/ws/ws_cli.py +0 -817
  425. agno/constants.py +0 -13
  426. agno/document/__init__.py +0 -5
  427. agno/document/chunking/semantic.py +0 -45
  428. agno/document/chunking/strategy.py +0 -31
  429. agno/document/reader/__init__.py +0 -5
  430. agno/document/reader/base.py +0 -47
  431. agno/document/reader/docx_reader.py +0 -60
  432. agno/document/reader/gcs/pdf_reader.py +0 -44
  433. agno/document/reader/s3/pdf_reader.py +0 -59
  434. agno/document/reader/s3/text_reader.py +0 -63
  435. agno/document/reader/url_reader.py +0 -59
  436. agno/document/reader/youtube_reader.py +0 -58
  437. agno/embedder/__init__.py +0 -5
  438. agno/embedder/langdb.py +0 -80
  439. agno/embedder/mistral.py +0 -82
  440. agno/embedder/openai.py +0 -78
  441. agno/file/__init__.py +0 -5
  442. agno/file/file.py +0 -16
  443. agno/file/local/csv.py +0 -32
  444. agno/file/local/txt.py +0 -19
  445. agno/infra/app.py +0 -240
  446. agno/infra/base.py +0 -144
  447. agno/infra/context.py +0 -20
  448. agno/infra/db_app.py +0 -52
  449. agno/infra/resource.py +0 -205
  450. agno/infra/resources.py +0 -55
  451. agno/knowledge/agent.py +0 -702
  452. agno/knowledge/arxiv.py +0 -33
  453. agno/knowledge/combined.py +0 -36
  454. agno/knowledge/csv.py +0 -144
  455. agno/knowledge/csv_url.py +0 -124
  456. agno/knowledge/document.py +0 -223
  457. agno/knowledge/docx.py +0 -137
  458. agno/knowledge/firecrawl.py +0 -34
  459. agno/knowledge/gcs/__init__.py +0 -0
  460. agno/knowledge/gcs/base.py +0 -39
  461. agno/knowledge/gcs/pdf.py +0 -125
  462. agno/knowledge/json.py +0 -137
  463. agno/knowledge/langchain.py +0 -71
  464. agno/knowledge/light_rag.py +0 -273
  465. agno/knowledge/llamaindex.py +0 -66
  466. agno/knowledge/markdown.py +0 -154
  467. agno/knowledge/pdf.py +0 -164
  468. agno/knowledge/pdf_bytes.py +0 -42
  469. agno/knowledge/pdf_url.py +0 -148
  470. agno/knowledge/s3/__init__.py +0 -0
  471. agno/knowledge/s3/base.py +0 -64
  472. agno/knowledge/s3/pdf.py +0 -33
  473. agno/knowledge/s3/text.py +0 -34
  474. agno/knowledge/text.py +0 -141
  475. agno/knowledge/url.py +0 -46
  476. agno/knowledge/website.py +0 -179
  477. agno/knowledge/wikipedia.py +0 -32
  478. agno/knowledge/youtube.py +0 -35
  479. agno/memory/agent.py +0 -423
  480. agno/memory/classifier.py +0 -104
  481. agno/memory/db/__init__.py +0 -5
  482. agno/memory/db/base.py +0 -42
  483. agno/memory/db/mongodb.py +0 -189
  484. agno/memory/db/postgres.py +0 -203
  485. agno/memory/db/sqlite.py +0 -193
  486. agno/memory/memory.py +0 -22
  487. agno/memory/row.py +0 -36
  488. agno/memory/summarizer.py +0 -201
  489. agno/memory/summary.py +0 -19
  490. agno/memory/team.py +0 -415
  491. agno/memory/v2/__init__.py +0 -2
  492. agno/memory/v2/db/__init__.py +0 -1
  493. agno/memory/v2/db/base.py +0 -42
  494. agno/memory/v2/db/firestore.py +0 -339
  495. agno/memory/v2/db/mongodb.py +0 -196
  496. agno/memory/v2/db/postgres.py +0 -214
  497. agno/memory/v2/db/redis.py +0 -187
  498. agno/memory/v2/db/schema.py +0 -54
  499. agno/memory/v2/db/sqlite.py +0 -209
  500. agno/memory/v2/manager.py +0 -437
  501. agno/memory/v2/memory.py +0 -1097
  502. agno/memory/v2/schema.py +0 -55
  503. agno/memory/v2/summarizer.py +0 -215
  504. agno/memory/workflow.py +0 -38
  505. agno/models/ollama/tools.py +0 -430
  506. agno/models/qwen/__init__.py +0 -5
  507. agno/playground/__init__.py +0 -10
  508. agno/playground/deploy.py +0 -3
  509. agno/playground/playground.py +0 -3
  510. agno/playground/serve.py +0 -3
  511. agno/playground/settings.py +0 -3
  512. agno/reranker/__init__.py +0 -0
  513. agno/run/v2/__init__.py +0 -0
  514. agno/run/v2/workflow.py +0 -567
  515. agno/storage/__init__.py +0 -0
  516. agno/storage/agent/__init__.py +0 -0
  517. agno/storage/agent/dynamodb.py +0 -1
  518. agno/storage/agent/json.py +0 -1
  519. agno/storage/agent/mongodb.py +0 -1
  520. agno/storage/agent/postgres.py +0 -1
  521. agno/storage/agent/singlestore.py +0 -1
  522. agno/storage/agent/sqlite.py +0 -1
  523. agno/storage/agent/yaml.py +0 -1
  524. agno/storage/base.py +0 -60
  525. agno/storage/dynamodb.py +0 -673
  526. agno/storage/firestore.py +0 -297
  527. agno/storage/gcs_json.py +0 -261
  528. agno/storage/in_memory.py +0 -234
  529. agno/storage/json.py +0 -237
  530. agno/storage/mongodb.py +0 -328
  531. agno/storage/mysql.py +0 -685
  532. agno/storage/postgres.py +0 -682
  533. agno/storage/redis.py +0 -336
  534. agno/storage/session/__init__.py +0 -16
  535. agno/storage/session/agent.py +0 -64
  536. agno/storage/session/team.py +0 -63
  537. agno/storage/session/v2/__init__.py +0 -5
  538. agno/storage/session/workflow.py +0 -61
  539. agno/storage/singlestore.py +0 -606
  540. agno/storage/sqlite.py +0 -646
  541. agno/storage/workflow/__init__.py +0 -0
  542. agno/storage/workflow/mongodb.py +0 -1
  543. agno/storage/workflow/postgres.py +0 -1
  544. agno/storage/workflow/sqlite.py +0 -1
  545. agno/storage/yaml.py +0 -241
  546. agno/tools/thinking.py +0 -73
  547. agno/utils/defaults.py +0 -57
  548. agno/utils/filesystem.py +0 -39
  549. agno/utils/git.py +0 -52
  550. agno/utils/json_io.py +0 -30
  551. agno/utils/load_env.py +0 -19
  552. agno/utils/py_io.py +0 -19
  553. agno/utils/pyproject.py +0 -18
  554. agno/utils/resource_filter.py +0 -31
  555. agno/workflow/v2/__init__.py +0 -21
  556. agno/workflow/v2/types.py +0 -357
  557. agno/workflow/v2/workflow.py +0 -3312
  558. agno/workspace/__init__.py +0 -0
  559. agno/workspace/config.py +0 -325
  560. agno/workspace/enums.py +0 -6
  561. agno/workspace/helpers.py +0 -52
  562. agno/workspace/operator.py +0 -757
  563. agno/workspace/settings.py +0 -158
  564. agno-1.8.1.dist-info/METADATA +0 -982
  565. agno-1.8.1.dist-info/RECORD +0 -566
  566. agno-1.8.1.dist-info/entry_points.txt +0 -3
  567. /agno/{app → db/migrations}/__init__.py +0 -0
  568. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  569. /agno/{cli → integrations}/__init__.py +0 -0
  570. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  571. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  572. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  573. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  574. /agno/{app → os/interfaces}/slack/security.py +0 -0
  575. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  576. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  577. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  578. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
  579. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
  580. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,179 @@
1
+ import logging
2
+ import math
3
+ from typing import List, Optional
4
+ from uuid import uuid4
5
+
6
+ from fastapi import Depends, HTTPException, Path, Query
7
+ from fastapi.routing import APIRouter
8
+
9
+ from agno.db.base import BaseDb
10
+ from agno.db.schemas import UserMemory
11
+ from agno.os.auth import get_authentication_dependency
12
+ from agno.os.routers.memory.schemas import (
13
+ DeleteMemoriesRequest,
14
+ UserMemoryCreateSchema,
15
+ UserMemorySchema,
16
+ UserStatsSchema,
17
+ )
18
+ from agno.os.schema import PaginatedResponse, PaginationInfo, SortOrder
19
+ from agno.os.settings import AgnoAPISettings
20
+ from agno.os.utils import get_db
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+
25
+ def get_memory_router(dbs: dict[str, BaseDb], settings: AgnoAPISettings = AgnoAPISettings(), **kwargs) -> APIRouter:
26
+ router = APIRouter(dependencies=[Depends(get_authentication_dependency(settings))], tags=["Memory"])
27
+ return attach_routes(router=router, dbs=dbs)
28
+
29
+
30
+ def attach_routes(router: APIRouter, dbs: dict[str, BaseDb]) -> APIRouter:
31
+ @router.post("/memories", response_model=UserMemorySchema, status_code=200)
32
+ async def create_memory(
33
+ payload: UserMemoryCreateSchema,
34
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
35
+ ) -> UserMemorySchema:
36
+ db = get_db(dbs, db_id)
37
+ user_memory = db.upsert_user_memory(
38
+ memory=UserMemory(
39
+ memory_id=str(uuid4()),
40
+ memory=payload.memory,
41
+ topics=payload.topics or [],
42
+ user_id=payload.user_id,
43
+ ),
44
+ deserialize=False,
45
+ )
46
+ if not user_memory:
47
+ raise HTTPException(status_code=500, detail="Failed to create memory")
48
+
49
+ return UserMemorySchema.from_dict(user_memory) # type: ignore
50
+
51
+ @router.delete("/memories/{memory_id}", status_code=204)
52
+ async def delete_memory(
53
+ memory_id: str = Path(), db_id: Optional[str] = Query(default=None, description="The ID of the database to use")
54
+ ) -> None:
55
+ db = get_db(dbs, db_id)
56
+ db.delete_user_memory(memory_id=memory_id)
57
+
58
+ @router.delete("/memories", status_code=204)
59
+ async def delete_memories(
60
+ request: DeleteMemoriesRequest,
61
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
62
+ ) -> None:
63
+ db = get_db(dbs, db_id)
64
+ db.delete_user_memories(memory_ids=request.memory_ids)
65
+
66
+ @router.get("/memories", response_model=PaginatedResponse[UserMemorySchema], status_code=200)
67
+ async def get_memories(
68
+ user_id: Optional[str] = Query(default=None, description="Filter memories by user ID"),
69
+ agent_id: Optional[str] = Query(default=None, description="Filter memories by agent ID"),
70
+ team_id: Optional[str] = Query(default=None, description="Filter memories by team ID"),
71
+ topics: Optional[List[str]] = Depends(parse_topics),
72
+ search_content: Optional[str] = Query(default=None, description="Fuzzy search memory content"),
73
+ limit: Optional[int] = Query(default=20, description="Number of memories to return"),
74
+ page: Optional[int] = Query(default=1, description="Page number"),
75
+ sort_by: Optional[str] = Query(default="updated_at", description="Field to sort by"),
76
+ sort_order: Optional[SortOrder] = Query(default="desc", description="Sort order (asc or desc)"),
77
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
78
+ ) -> PaginatedResponse[UserMemorySchema]:
79
+ db = get_db(dbs, db_id)
80
+ user_memories, total_count = db.get_user_memories(
81
+ limit=limit,
82
+ page=page,
83
+ user_id=user_id,
84
+ agent_id=agent_id,
85
+ team_id=team_id,
86
+ topics=topics,
87
+ search_content=search_content,
88
+ sort_by=sort_by,
89
+ sort_order=sort_order,
90
+ deserialize=False,
91
+ )
92
+ return PaginatedResponse(
93
+ data=[UserMemorySchema.from_dict(user_memory) for user_memory in user_memories], # type: ignore
94
+ meta=PaginationInfo(
95
+ page=page,
96
+ limit=limit,
97
+ total_count=total_count, # type: ignore
98
+ total_pages=math.ceil(total_count / limit) if limit is not None and limit > 0 else 0, # type: ignore
99
+ ),
100
+ )
101
+
102
+ @router.get("/memories/{memory_id}", response_model=UserMemorySchema, status_code=200)
103
+ async def get_memory(
104
+ memory_id: str = Path(),
105
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
106
+ ) -> UserMemorySchema:
107
+ db = get_db(dbs, db_id)
108
+ user_memory = db.get_user_memory(memory_id=memory_id, deserialize=False)
109
+ if not user_memory:
110
+ raise HTTPException(status_code=404, detail=f"Memory with ID {memory_id} not found")
111
+
112
+ return UserMemorySchema.from_dict(user_memory) # type: ignore
113
+
114
+ @router.get("/memories/topics", response_model=List[str], status_code=200)
115
+ async def get_topics(
116
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
117
+ ) -> List[str]:
118
+ db = get_db(dbs, db_id)
119
+ return db.get_all_memory_topics()
120
+
121
+ @router.patch("/memories/{memory_id}", response_model=UserMemorySchema, status_code=200)
122
+ async def update_memory(
123
+ payload: UserMemoryCreateSchema,
124
+ memory_id: str = Path(),
125
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
126
+ ) -> UserMemorySchema:
127
+ db = get_db(dbs, db_id)
128
+ user_memory = db.upsert_user_memory(
129
+ memory=UserMemory(
130
+ memory_id=memory_id,
131
+ memory=payload.memory,
132
+ topics=payload.topics or [],
133
+ user_id=payload.user_id,
134
+ ),
135
+ deserialize=False,
136
+ )
137
+ if not user_memory:
138
+ raise HTTPException(status_code=500, detail="Failed to update memory")
139
+
140
+ return UserMemorySchema.from_dict(user_memory) # type: ignore
141
+
142
+ @router.get("/user_memory_stats", response_model=PaginatedResponse[UserStatsSchema], status_code=200)
143
+ async def get_user_memory_stats(
144
+ limit: Optional[int] = Query(default=20, description="Number of items to return"),
145
+ page: Optional[int] = Query(default=1, description="Page number"),
146
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
147
+ ) -> PaginatedResponse[UserStatsSchema]:
148
+ db = get_db(dbs, db_id)
149
+ try:
150
+ user_stats, total_count = db.get_user_memory_stats(
151
+ limit=limit,
152
+ page=page,
153
+ )
154
+ return PaginatedResponse(
155
+ data=[UserStatsSchema.from_dict(stats) for stats in user_stats],
156
+ meta=PaginationInfo(
157
+ page=page,
158
+ limit=limit,
159
+ total_count=total_count,
160
+ total_pages=(total_count + limit - 1) // limit if limit is not None and limit > 0 else 0,
161
+ ),
162
+ )
163
+
164
+ except Exception as e:
165
+ raise HTTPException(status_code=500, detail=f"Failed to get user statistics: {str(e)}")
166
+
167
+ return router
168
+
169
+
170
+ def parse_topics(topics: Optional[List[str]] = Query(default=None)) -> Optional[List[str]]:
171
+ """Parse a comma-separated string of topics into a list of topics"""
172
+ if not topics:
173
+ return None
174
+
175
+ try:
176
+ return [topic.strip() for topic in topics[0].split(",") if topic.strip()]
177
+
178
+ except Exception as e:
179
+ raise HTTPException(status_code=422, detail=f"Invalid topics: {e}")
@@ -0,0 +1,58 @@
1
+ from datetime import datetime, timezone
2
+ from typing import Any, Dict, List, Optional
3
+
4
+ from pydantic import BaseModel
5
+
6
+
7
+ class DeleteMemoriesRequest(BaseModel):
8
+ memory_ids: List[str]
9
+
10
+
11
+ class UserMemorySchema(BaseModel):
12
+ memory_id: str
13
+ memory: str
14
+ topics: Optional[List[str]]
15
+
16
+ agent_id: Optional[str]
17
+ team_id: Optional[str]
18
+ user_id: Optional[str]
19
+
20
+ updated_at: Optional[datetime]
21
+
22
+ @classmethod
23
+ def from_dict(cls, memory_dict: Dict[str, Any]) -> "UserMemorySchema":
24
+ return cls(
25
+ memory_id=memory_dict["memory_id"],
26
+ user_id=str(memory_dict["user_id"]),
27
+ agent_id=memory_dict.get("agent_id"),
28
+ team_id=memory_dict.get("team_id"),
29
+ memory=memory_dict["memory"],
30
+ topics=memory_dict.get("topics", []),
31
+ updated_at=memory_dict["updated_at"],
32
+ )
33
+
34
+
35
+ class UserMemoryCreateSchema(BaseModel):
36
+ """Define the payload expected for creating a new user memory"""
37
+
38
+ memory: str
39
+ user_id: str
40
+ topics: Optional[List[str]] = None
41
+
42
+
43
+ class UserStatsSchema(BaseModel):
44
+ """Schema for user memory statistics"""
45
+
46
+ user_id: str
47
+ total_memories: int
48
+ last_memory_updated_at: Optional[datetime] = None
49
+
50
+ @classmethod
51
+ def from_dict(cls, user_stats_dict: Dict[str, Any]) -> "UserStatsSchema":
52
+ updated_at = user_stats_dict.get("last_memory_updated_at")
53
+
54
+ return cls(
55
+ user_id=str(user_stats_dict["user_id"]),
56
+ total_memories=user_stats_dict["total_memories"],
57
+ last_memory_updated_at=datetime.fromtimestamp(updated_at, tz=timezone.utc) if updated_at else None,
58
+ )
@@ -0,0 +1,3 @@
1
+ from agno.os.routers.metrics.metrics import get_metrics_router
2
+
3
+ __all__ = ["get_metrics_router"]
@@ -0,0 +1,58 @@
1
+ import logging
2
+ from datetime import date, datetime, timezone
3
+ from typing import List, Optional
4
+
5
+ from fastapi import Depends, HTTPException, Query
6
+ from fastapi.routing import APIRouter
7
+
8
+ from agno.db.base import BaseDb
9
+ from agno.os.auth import get_authentication_dependency
10
+ from agno.os.routers.metrics.schemas import DayAggregatedMetrics, MetricsResponse
11
+ from agno.os.settings import AgnoAPISettings
12
+ from agno.os.utils import get_db
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ def get_metrics_router(dbs: dict[str, BaseDb], settings: AgnoAPISettings = AgnoAPISettings(), **kwargs) -> APIRouter:
18
+ router = APIRouter(dependencies=[Depends(get_authentication_dependency(settings))], tags=["Metrics"])
19
+ return attach_routes(router=router, dbs=dbs)
20
+
21
+
22
+ def attach_routes(router: APIRouter, dbs: dict[str, BaseDb]) -> APIRouter:
23
+ @router.get("/metrics", response_model=MetricsResponse, status_code=200)
24
+ async def get_metrics(
25
+ starting_date: Optional[date] = Query(default=None, description="Starting date to filter metrics (YYYY-MM-DD)"),
26
+ ending_date: Optional[date] = Query(default=None, description="Ending date to filter metrics (YYYY-MM-DD)"),
27
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
28
+ ) -> MetricsResponse:
29
+ try:
30
+ db = get_db(dbs, db_id)
31
+ metrics, latest_updated_at = db.get_metrics(starting_date=starting_date, ending_date=ending_date)
32
+
33
+ return MetricsResponse(
34
+ metrics=[DayAggregatedMetrics.from_dict(metric) for metric in metrics],
35
+ updated_at=datetime.fromtimestamp(latest_updated_at, tz=timezone.utc)
36
+ if latest_updated_at is not None
37
+ else None,
38
+ )
39
+
40
+ except Exception as e:
41
+ raise HTTPException(status_code=500, detail=f"Error getting metrics: {str(e)}")
42
+
43
+ @router.post("/metrics/refresh", response_model=List[DayAggregatedMetrics], status_code=200)
44
+ async def calculate_metrics(
45
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
46
+ ) -> List[DayAggregatedMetrics]:
47
+ try:
48
+ db = get_db(dbs, db_id)
49
+ result = db.calculate_metrics()
50
+ if result is None:
51
+ return []
52
+
53
+ return [DayAggregatedMetrics.from_dict(metric) for metric in result]
54
+
55
+ except Exception as e:
56
+ raise HTTPException(status_code=500, detail=f"Error refreshing metrics: {str(e)}")
57
+
58
+ return router
@@ -0,0 +1,47 @@
1
+ from datetime import datetime
2
+ from typing import Any, Dict, List, Optional
3
+
4
+ from pydantic import BaseModel
5
+
6
+
7
+ class DayAggregatedMetrics(BaseModel):
8
+ """Aggregated metrics for a given day"""
9
+
10
+ id: str
11
+
12
+ agent_runs_count: int
13
+ agent_sessions_count: int
14
+ team_runs_count: int
15
+ team_sessions_count: int
16
+ workflow_runs_count: int
17
+ workflow_sessions_count: int
18
+ users_count: int
19
+ token_metrics: Dict[str, Any]
20
+ model_metrics: List[Dict[str, Any]]
21
+
22
+ date: datetime
23
+ created_at: int
24
+ updated_at: int
25
+
26
+ @classmethod
27
+ def from_dict(cls, metrics_dict: Dict[str, Any]) -> "DayAggregatedMetrics":
28
+ return cls(
29
+ agent_runs_count=metrics_dict.get("agent_runs_count", 0),
30
+ agent_sessions_count=metrics_dict.get("agent_sessions_count", 0),
31
+ created_at=metrics_dict.get("created_at", 0),
32
+ date=metrics_dict.get("date", datetime.now()),
33
+ id=metrics_dict.get("id", ""),
34
+ model_metrics=metrics_dict.get("model_metrics", {}),
35
+ team_runs_count=metrics_dict.get("team_runs_count", 0),
36
+ team_sessions_count=metrics_dict.get("team_sessions_count", 0),
37
+ token_metrics=metrics_dict.get("token_metrics", {}),
38
+ updated_at=metrics_dict.get("updated_at", 0),
39
+ users_count=metrics_dict.get("users_count", 0),
40
+ workflow_runs_count=metrics_dict.get("workflow_runs_count", 0),
41
+ workflow_sessions_count=metrics_dict.get("workflow_sessions_count", 0),
42
+ )
43
+
44
+
45
+ class MetricsResponse(BaseModel):
46
+ metrics: List[DayAggregatedMetrics]
47
+ updated_at: Optional[datetime]
@@ -0,0 +1,3 @@
1
+ from agno.os.routers.session.session import get_session_router
2
+
3
+ __all__ = ["get_session_router"]
@@ -0,0 +1,163 @@
1
+ import logging
2
+ from typing import List, Optional, Union
3
+
4
+ from fastapi import APIRouter, Body, Depends, HTTPException, Path, Query
5
+
6
+ from agno.db.base import BaseDb, SessionType
7
+ from agno.os.auth import get_authentication_dependency
8
+ from agno.os.schema import (
9
+ AgentSessionDetailSchema,
10
+ DeleteSessionRequest,
11
+ PaginatedResponse,
12
+ PaginationInfo,
13
+ RunSchema,
14
+ SessionSchema,
15
+ SortOrder,
16
+ TeamRunSchema,
17
+ TeamSessionDetailSchema,
18
+ WorkflowRunSchema,
19
+ WorkflowSessionDetailSchema,
20
+ )
21
+ from agno.os.settings import AgnoAPISettings
22
+ from agno.os.utils import get_db
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ def get_session_router(dbs: dict[str, BaseDb], settings: AgnoAPISettings = AgnoAPISettings()) -> APIRouter:
28
+ session_router = APIRouter(dependencies=[Depends(get_authentication_dependency(settings))], tags=["Sessions"])
29
+ return attach_routes(router=session_router, dbs=dbs)
30
+
31
+
32
+ def attach_routes(router: APIRouter, dbs: dict[str, BaseDb]) -> APIRouter:
33
+ @router.get("/sessions", response_model=PaginatedResponse[SessionSchema], status_code=200)
34
+ async def get_sessions(
35
+ session_type: SessionType = Query(default=SessionType.AGENT, alias="type"),
36
+ component_id: Optional[str] = Query(default=None, description="Filter sessions by component ID"),
37
+ user_id: Optional[str] = Query(default=None, description="Filter sessions by user ID"),
38
+ session_name: Optional[str] = Query(default=None, description="Filter sessions by name"),
39
+ limit: Optional[int] = Query(default=20, description="Number of sessions to return"),
40
+ page: Optional[int] = Query(default=1, description="Page number"),
41
+ sort_by: Optional[str] = Query(default="created_at", description="Field to sort by"),
42
+ sort_order: Optional[SortOrder] = Query(default="desc", description="Sort order (asc or desc)"),
43
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
44
+ ) -> PaginatedResponse[SessionSchema]:
45
+ db = get_db(dbs, db_id)
46
+ sessions, total_count = db.get_sessions(
47
+ session_type=session_type,
48
+ component_id=component_id,
49
+ user_id=user_id,
50
+ session_name=session_name,
51
+ limit=limit,
52
+ page=page,
53
+ sort_by=sort_by,
54
+ sort_order=sort_order,
55
+ deserialize=False,
56
+ )
57
+
58
+ return PaginatedResponse(
59
+ data=[SessionSchema.from_dict(session) for session in sessions], # type: ignore
60
+ meta=PaginationInfo(
61
+ page=page,
62
+ limit=limit,
63
+ total_count=total_count, # type: ignore
64
+ total_pages=(total_count + limit - 1) // limit if limit is not None and limit > 0 else 0, # type: ignore
65
+ ),
66
+ )
67
+
68
+ @router.get(
69
+ "/sessions/{session_id}",
70
+ response_model=Union[AgentSessionDetailSchema, TeamSessionDetailSchema, WorkflowSessionDetailSchema],
71
+ status_code=200,
72
+ )
73
+ async def get_session_by_id(
74
+ session_id: str = Path(...),
75
+ session_type: SessionType = Query(default=SessionType.AGENT, description="Session type filter", alias="type"),
76
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
77
+ ) -> Union[AgentSessionDetailSchema, TeamSessionDetailSchema, WorkflowSessionDetailSchema]:
78
+ db = get_db(dbs, db_id)
79
+ session = db.get_session(session_id=session_id, session_type=session_type)
80
+ if not session:
81
+ raise HTTPException(status_code=404, detail=f"Session with id '{session_id}' not found")
82
+
83
+ if session_type == SessionType.AGENT:
84
+ return AgentSessionDetailSchema.from_session(session) # type: ignore
85
+ elif session_type == SessionType.TEAM:
86
+ return TeamSessionDetailSchema.from_session(session) # type: ignore
87
+ else:
88
+ return WorkflowSessionDetailSchema.from_session(session) # type: ignore
89
+
90
+ @router.get(
91
+ "/sessions/{session_id}/runs",
92
+ response_model=Union[List[RunSchema], List[TeamRunSchema], List[WorkflowRunSchema]],
93
+ status_code=200,
94
+ )
95
+ async def get_session_runs(
96
+ session_id: str = Path(..., description="Session ID", alias="session_id"),
97
+ session_type: SessionType = Query(default=SessionType.AGENT, description="Session type filter", alias="type"),
98
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
99
+ ) -> Union[List[RunSchema], List[TeamRunSchema], List[WorkflowRunSchema]]:
100
+ db = get_db(dbs, db_id)
101
+ session = db.get_session(session_id=session_id, session_type=session_type, deserialize=False)
102
+ if not session:
103
+ raise HTTPException(status_code=404, detail=f"Session with ID {session_id} not found")
104
+
105
+ runs = session.get("runs") # type: ignore
106
+ if not runs:
107
+ raise HTTPException(status_code=404, detail=f"Session with ID {session_id} has no runs")
108
+
109
+ if session_type == SessionType.AGENT:
110
+ return [RunSchema.from_dict(run) for run in runs]
111
+
112
+ elif session_type == SessionType.TEAM:
113
+ return [TeamRunSchema.from_dict(run) for run in runs]
114
+
115
+ elif session_type == SessionType.WORKFLOW:
116
+ return [WorkflowRunSchema.from_dict(run) for run in runs]
117
+
118
+ else:
119
+ return [RunSchema.from_dict(run) for run in runs]
120
+
121
+ @router.delete("/sessions/{session_id}", status_code=204)
122
+ async def delete_session(
123
+ session_id: str = Path(...),
124
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
125
+ ) -> None:
126
+ db = get_db(dbs, db_id)
127
+ db.delete_session(session_id=session_id)
128
+
129
+ @router.delete("/sessions", status_code=204)
130
+ async def delete_sessions(
131
+ request: DeleteSessionRequest,
132
+ session_type: SessionType = Query(default=SessionType.AGENT, description="Session type filter", alias="type"),
133
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
134
+ ) -> None:
135
+ if len(request.session_ids) != len(request.session_types):
136
+ raise HTTPException(status_code=400, detail="Session IDs and session types must have the same length")
137
+
138
+ db = get_db(dbs, db_id)
139
+ db.delete_sessions(session_ids=request.session_ids)
140
+
141
+ @router.post(
142
+ "/sessions/{session_id}/rename",
143
+ response_model=Union[AgentSessionDetailSchema, TeamSessionDetailSchema, WorkflowSessionDetailSchema],
144
+ )
145
+ async def rename_session(
146
+ session_id: str = Path(...),
147
+ session_type: SessionType = Query(default=SessionType.AGENT, description="Session type filter", alias="type"),
148
+ session_name: str = Body(embed=True),
149
+ db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
150
+ ) -> Union[AgentSessionDetailSchema, TeamSessionDetailSchema, WorkflowSessionDetailSchema]:
151
+ db = get_db(dbs, db_id)
152
+ session = db.rename_session(session_id=session_id, session_type=session_type, session_name=session_name)
153
+ if not session:
154
+ raise HTTPException(status_code=404, detail=f"Session with id '{session_id}' not found")
155
+
156
+ if session_type == SessionType.AGENT:
157
+ return AgentSessionDetailSchema.from_session(session) # type: ignore
158
+ elif session_type == SessionType.TEAM:
159
+ return TeamSessionDetailSchema.from_session(session) # type: ignore
160
+ else:
161
+ return WorkflowSessionDetailSchema.from_session(session) # type: ignore
162
+
163
+ return router