agno 1.8.0__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 (583) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +2781 -4126
  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/media.py +2 -2
  137. agno/memory/__init__.py +2 -10
  138. agno/memory/manager.py +1003 -148
  139. agno/models/aimlapi/__init__.py +2 -2
  140. agno/models/aimlapi/aimlapi.py +6 -6
  141. agno/models/anthropic/claude.py +129 -82
  142. agno/models/aws/bedrock.py +107 -175
  143. agno/models/aws/claude.py +64 -18
  144. agno/models/azure/ai_foundry.py +73 -23
  145. agno/models/base.py +347 -287
  146. agno/models/cerebras/cerebras.py +84 -27
  147. agno/models/cohere/chat.py +106 -98
  148. agno/models/dashscope/dashscope.py +14 -5
  149. agno/models/google/gemini.py +123 -53
  150. agno/models/groq/groq.py +97 -35
  151. agno/models/huggingface/huggingface.py +92 -27
  152. agno/models/ibm/watsonx.py +72 -13
  153. agno/models/litellm/chat.py +85 -13
  154. agno/models/message.py +38 -144
  155. agno/models/meta/llama.py +85 -49
  156. agno/models/metrics.py +120 -0
  157. agno/models/mistral/mistral.py +90 -21
  158. agno/models/ollama/__init__.py +0 -2
  159. agno/models/ollama/chat.py +84 -46
  160. agno/models/openai/chat.py +135 -27
  161. agno/models/openai/responses.py +233 -115
  162. agno/models/perplexity/perplexity.py +26 -2
  163. agno/models/portkey/portkey.py +0 -7
  164. agno/models/response.py +14 -8
  165. agno/models/utils.py +20 -0
  166. agno/models/vercel/__init__.py +2 -2
  167. agno/models/vercel/v0.py +1 -1
  168. agno/models/vllm/__init__.py +2 -2
  169. agno/models/vllm/vllm.py +3 -3
  170. agno/models/xai/xai.py +10 -10
  171. agno/os/__init__.py +3 -0
  172. agno/os/app.py +393 -0
  173. agno/os/auth.py +47 -0
  174. agno/os/config.py +103 -0
  175. agno/os/interfaces/agui/__init__.py +3 -0
  176. agno/os/interfaces/agui/agui.py +31 -0
  177. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  178. agno/{app → os/interfaces}/agui/utils.py +65 -28
  179. agno/os/interfaces/base.py +21 -0
  180. agno/os/interfaces/slack/__init__.py +3 -0
  181. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  182. agno/os/interfaces/slack/slack.py +33 -0
  183. agno/os/interfaces/whatsapp/__init__.py +3 -0
  184. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  185. agno/os/interfaces/whatsapp/whatsapp.py +30 -0
  186. agno/os/router.py +843 -0
  187. agno/os/routers/__init__.py +3 -0
  188. agno/os/routers/evals/__init__.py +3 -0
  189. agno/os/routers/evals/evals.py +204 -0
  190. agno/os/routers/evals/schemas.py +142 -0
  191. agno/os/routers/evals/utils.py +161 -0
  192. agno/os/routers/knowledge/__init__.py +3 -0
  193. agno/os/routers/knowledge/knowledge.py +413 -0
  194. agno/os/routers/knowledge/schemas.py +118 -0
  195. agno/os/routers/memory/__init__.py +3 -0
  196. agno/os/routers/memory/memory.py +179 -0
  197. agno/os/routers/memory/schemas.py +58 -0
  198. agno/os/routers/metrics/__init__.py +3 -0
  199. agno/os/routers/metrics/metrics.py +58 -0
  200. agno/os/routers/metrics/schemas.py +47 -0
  201. agno/os/routers/session/__init__.py +3 -0
  202. agno/os/routers/session/session.py +163 -0
  203. agno/os/schema.py +892 -0
  204. agno/{app/playground → os}/settings.py +8 -15
  205. agno/os/utils.py +270 -0
  206. agno/reasoning/azure_ai_foundry.py +4 -4
  207. agno/reasoning/deepseek.py +4 -4
  208. agno/reasoning/default.py +6 -11
  209. agno/reasoning/groq.py +4 -4
  210. agno/reasoning/helpers.py +4 -6
  211. agno/reasoning/ollama.py +4 -4
  212. agno/reasoning/openai.py +4 -4
  213. agno/run/{response.py → agent.py} +144 -72
  214. agno/run/base.py +44 -58
  215. agno/run/cancel.py +83 -0
  216. agno/run/team.py +133 -77
  217. agno/run/workflow.py +537 -12
  218. agno/session/__init__.py +10 -0
  219. agno/session/agent.py +244 -0
  220. agno/session/summary.py +225 -0
  221. agno/session/team.py +262 -0
  222. agno/{storage/session/v2 → session}/workflow.py +47 -24
  223. agno/team/__init__.py +15 -16
  224. agno/team/team.py +2967 -4243
  225. agno/tools/agentql.py +14 -5
  226. agno/tools/airflow.py +9 -4
  227. agno/tools/api.py +7 -3
  228. agno/tools/apify.py +2 -46
  229. agno/tools/arxiv.py +8 -3
  230. agno/tools/aws_lambda.py +7 -5
  231. agno/tools/aws_ses.py +7 -1
  232. agno/tools/baidusearch.py +4 -1
  233. agno/tools/bitbucket.py +4 -4
  234. agno/tools/brandfetch.py +14 -11
  235. agno/tools/bravesearch.py +4 -1
  236. agno/tools/brightdata.py +42 -22
  237. agno/tools/browserbase.py +13 -4
  238. agno/tools/calcom.py +12 -10
  239. agno/tools/calculator.py +10 -27
  240. agno/tools/cartesia.py +18 -13
  241. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  242. agno/tools/confluence.py +71 -18
  243. agno/tools/crawl4ai.py +7 -1
  244. agno/tools/csv_toolkit.py +9 -8
  245. agno/tools/dalle.py +18 -11
  246. agno/tools/daytona.py +13 -16
  247. agno/tools/decorator.py +6 -3
  248. agno/tools/desi_vocal.py +16 -7
  249. agno/tools/discord.py +11 -8
  250. agno/tools/docker.py +30 -42
  251. agno/tools/duckdb.py +34 -53
  252. agno/tools/duckduckgo.py +8 -7
  253. agno/tools/e2b.py +62 -62
  254. agno/tools/eleven_labs.py +35 -28
  255. agno/tools/email.py +4 -1
  256. agno/tools/evm.py +7 -1
  257. agno/tools/exa.py +19 -14
  258. agno/tools/fal.py +29 -29
  259. agno/tools/file.py +9 -8
  260. agno/tools/financial_datasets.py +25 -44
  261. agno/tools/firecrawl.py +22 -22
  262. agno/tools/function.py +68 -17
  263. agno/tools/giphy.py +22 -10
  264. agno/tools/github.py +48 -126
  265. agno/tools/gmail.py +46 -62
  266. agno/tools/google_bigquery.py +7 -6
  267. agno/tools/google_maps.py +11 -26
  268. agno/tools/googlesearch.py +7 -2
  269. agno/tools/googlesheets.py +21 -17
  270. agno/tools/hackernews.py +9 -5
  271. agno/tools/jina.py +5 -4
  272. agno/tools/jira.py +18 -9
  273. agno/tools/knowledge.py +31 -32
  274. agno/tools/linear.py +18 -33
  275. agno/tools/linkup.py +5 -1
  276. agno/tools/local_file_system.py +8 -5
  277. agno/tools/lumalab.py +31 -19
  278. agno/tools/mem0.py +18 -12
  279. agno/tools/memori.py +14 -10
  280. agno/tools/mlx_transcribe.py +3 -2
  281. agno/tools/models/azure_openai.py +32 -14
  282. agno/tools/models/gemini.py +58 -31
  283. agno/tools/models/groq.py +29 -20
  284. agno/tools/models/nebius.py +27 -11
  285. agno/tools/models_labs.py +39 -15
  286. agno/tools/moviepy_video.py +7 -6
  287. agno/tools/neo4j.py +134 -0
  288. agno/tools/newspaper.py +7 -2
  289. agno/tools/newspaper4k.py +8 -3
  290. agno/tools/openai.py +57 -26
  291. agno/tools/openbb.py +12 -11
  292. agno/tools/opencv.py +62 -46
  293. agno/tools/openweather.py +14 -12
  294. agno/tools/pandas.py +11 -3
  295. agno/tools/postgres.py +4 -12
  296. agno/tools/pubmed.py +4 -1
  297. agno/tools/python.py +9 -22
  298. agno/tools/reasoning.py +35 -27
  299. agno/tools/reddit.py +11 -26
  300. agno/tools/replicate.py +54 -41
  301. agno/tools/resend.py +4 -1
  302. agno/tools/scrapegraph.py +15 -14
  303. agno/tools/searxng.py +10 -23
  304. agno/tools/serpapi.py +6 -3
  305. agno/tools/serper.py +13 -4
  306. agno/tools/shell.py +9 -2
  307. agno/tools/slack.py +12 -11
  308. agno/tools/sleep.py +3 -2
  309. agno/tools/spider.py +24 -4
  310. agno/tools/sql.py +7 -6
  311. agno/tools/tavily.py +6 -4
  312. agno/tools/telegram.py +12 -4
  313. agno/tools/todoist.py +11 -31
  314. agno/tools/toolkit.py +1 -1
  315. agno/tools/trafilatura.py +22 -6
  316. agno/tools/trello.py +9 -22
  317. agno/tools/twilio.py +10 -3
  318. agno/tools/user_control_flow.py +6 -1
  319. agno/tools/valyu.py +34 -5
  320. agno/tools/visualization.py +19 -28
  321. agno/tools/webbrowser.py +4 -3
  322. agno/tools/webex.py +11 -7
  323. agno/tools/website.py +15 -46
  324. agno/tools/webtools.py +12 -4
  325. agno/tools/whatsapp.py +5 -9
  326. agno/tools/wikipedia.py +20 -13
  327. agno/tools/x.py +14 -13
  328. agno/tools/yfinance.py +13 -40
  329. agno/tools/youtube.py +26 -20
  330. agno/tools/zendesk.py +7 -2
  331. agno/tools/zep.py +10 -7
  332. agno/tools/zoom.py +10 -9
  333. agno/utils/common.py +1 -19
  334. agno/utils/events.py +95 -118
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/location.py +2 -2
  337. agno/utils/log.py +2 -2
  338. agno/utils/mcp.py +11 -5
  339. agno/utils/media.py +39 -0
  340. agno/utils/message.py +12 -1
  341. agno/utils/models/claude.py +6 -4
  342. agno/utils/models/mistral.py +8 -7
  343. agno/utils/models/schema_utils.py +3 -3
  344. agno/utils/pprint.py +33 -32
  345. agno/utils/print_response/agent.py +779 -0
  346. agno/utils/print_response/team.py +1565 -0
  347. agno/utils/print_response/workflow.py +1451 -0
  348. agno/utils/prompts.py +14 -14
  349. agno/utils/reasoning.py +87 -0
  350. agno/utils/response.py +42 -42
  351. agno/utils/string.py +8 -22
  352. agno/utils/team.py +50 -0
  353. agno/utils/timer.py +2 -2
  354. agno/vectordb/base.py +33 -21
  355. agno/vectordb/cassandra/cassandra.py +287 -23
  356. agno/vectordb/chroma/chromadb.py +482 -59
  357. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  358. agno/vectordb/couchbase/couchbase.py +309 -29
  359. agno/vectordb/lancedb/lance_db.py +360 -21
  360. agno/vectordb/langchaindb/__init__.py +5 -0
  361. agno/vectordb/langchaindb/langchaindb.py +145 -0
  362. agno/vectordb/lightrag/__init__.py +5 -0
  363. agno/vectordb/lightrag/lightrag.py +374 -0
  364. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  365. agno/vectordb/milvus/milvus.py +242 -32
  366. agno/vectordb/mongodb/mongodb.py +200 -24
  367. agno/vectordb/pgvector/pgvector.py +319 -37
  368. agno/vectordb/pineconedb/pineconedb.py +221 -27
  369. agno/vectordb/qdrant/qdrant.py +356 -14
  370. agno/vectordb/singlestore/singlestore.py +286 -29
  371. agno/vectordb/surrealdb/surrealdb.py +187 -7
  372. agno/vectordb/upstashdb/upstashdb.py +342 -26
  373. agno/vectordb/weaviate/weaviate.py +227 -165
  374. agno/workflow/__init__.py +17 -13
  375. agno/workflow/{v2/condition.py → condition.py} +135 -32
  376. agno/workflow/{v2/loop.py → loop.py} +115 -28
  377. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  378. agno/workflow/{v2/router.py → router.py} +133 -32
  379. agno/workflow/{v2/step.py → step.py} +200 -42
  380. agno/workflow/{v2/steps.py → steps.py} +147 -66
  381. agno/workflow/types.py +482 -0
  382. agno/workflow/workflow.py +2394 -696
  383. agno-2.0.0a1.dist-info/METADATA +355 -0
  384. agno-2.0.0a1.dist-info/RECORD +514 -0
  385. agno/agent/metrics.py +0 -107
  386. agno/api/app.py +0 -35
  387. agno/api/playground.py +0 -92
  388. agno/api/schemas/app.py +0 -12
  389. agno/api/schemas/playground.py +0 -22
  390. agno/api/schemas/user.py +0 -35
  391. agno/api/schemas/workspace.py +0 -46
  392. agno/api/user.py +0 -160
  393. agno/api/workflows.py +0 -33
  394. agno/api/workspace.py +0 -175
  395. agno/app/agui/__init__.py +0 -3
  396. agno/app/agui/app.py +0 -17
  397. agno/app/agui/sync_router.py +0 -120
  398. agno/app/base.py +0 -186
  399. agno/app/discord/__init__.py +0 -3
  400. agno/app/fastapi/__init__.py +0 -3
  401. agno/app/fastapi/app.py +0 -107
  402. agno/app/fastapi/async_router.py +0 -457
  403. agno/app/fastapi/sync_router.py +0 -448
  404. agno/app/playground/app.py +0 -228
  405. agno/app/playground/async_router.py +0 -1050
  406. agno/app/playground/deploy.py +0 -249
  407. agno/app/playground/operator.py +0 -183
  408. agno/app/playground/schemas.py +0 -220
  409. agno/app/playground/serve.py +0 -55
  410. agno/app/playground/sync_router.py +0 -1042
  411. agno/app/playground/utils.py +0 -46
  412. agno/app/settings.py +0 -15
  413. agno/app/slack/__init__.py +0 -3
  414. agno/app/slack/app.py +0 -19
  415. agno/app/slack/sync_router.py +0 -92
  416. agno/app/utils.py +0 -54
  417. agno/app/whatsapp/__init__.py +0 -3
  418. agno/app/whatsapp/app.py +0 -15
  419. agno/app/whatsapp/sync_router.py +0 -197
  420. agno/cli/auth_server.py +0 -249
  421. agno/cli/config.py +0 -274
  422. agno/cli/console.py +0 -88
  423. agno/cli/credentials.py +0 -23
  424. agno/cli/entrypoint.py +0 -571
  425. agno/cli/operator.py +0 -357
  426. agno/cli/settings.py +0 -96
  427. agno/cli/ws/ws_cli.py +0 -817
  428. agno/constants.py +0 -13
  429. agno/document/__init__.py +0 -5
  430. agno/document/chunking/semantic.py +0 -45
  431. agno/document/chunking/strategy.py +0 -31
  432. agno/document/reader/__init__.py +0 -5
  433. agno/document/reader/base.py +0 -47
  434. agno/document/reader/docx_reader.py +0 -60
  435. agno/document/reader/gcs/pdf_reader.py +0 -44
  436. agno/document/reader/s3/pdf_reader.py +0 -59
  437. agno/document/reader/s3/text_reader.py +0 -63
  438. agno/document/reader/url_reader.py +0 -59
  439. agno/document/reader/youtube_reader.py +0 -58
  440. agno/embedder/__init__.py +0 -5
  441. agno/embedder/langdb.py +0 -80
  442. agno/embedder/mistral.py +0 -82
  443. agno/embedder/openai.py +0 -78
  444. agno/file/__init__.py +0 -5
  445. agno/file/file.py +0 -16
  446. agno/file/local/csv.py +0 -32
  447. agno/file/local/txt.py +0 -19
  448. agno/infra/app.py +0 -240
  449. agno/infra/base.py +0 -144
  450. agno/infra/context.py +0 -20
  451. agno/infra/db_app.py +0 -52
  452. agno/infra/resource.py +0 -205
  453. agno/infra/resources.py +0 -55
  454. agno/knowledge/agent.py +0 -698
  455. agno/knowledge/arxiv.py +0 -33
  456. agno/knowledge/combined.py +0 -36
  457. agno/knowledge/csv.py +0 -144
  458. agno/knowledge/csv_url.py +0 -124
  459. agno/knowledge/document.py +0 -223
  460. agno/knowledge/docx.py +0 -137
  461. agno/knowledge/firecrawl.py +0 -34
  462. agno/knowledge/gcs/__init__.py +0 -0
  463. agno/knowledge/gcs/base.py +0 -39
  464. agno/knowledge/gcs/pdf.py +0 -125
  465. agno/knowledge/json.py +0 -137
  466. agno/knowledge/langchain.py +0 -71
  467. agno/knowledge/light_rag.py +0 -273
  468. agno/knowledge/llamaindex.py +0 -66
  469. agno/knowledge/markdown.py +0 -154
  470. agno/knowledge/pdf.py +0 -164
  471. agno/knowledge/pdf_bytes.py +0 -42
  472. agno/knowledge/pdf_url.py +0 -148
  473. agno/knowledge/s3/__init__.py +0 -0
  474. agno/knowledge/s3/base.py +0 -64
  475. agno/knowledge/s3/pdf.py +0 -33
  476. agno/knowledge/s3/text.py +0 -34
  477. agno/knowledge/text.py +0 -141
  478. agno/knowledge/url.py +0 -46
  479. agno/knowledge/website.py +0 -179
  480. agno/knowledge/wikipedia.py +0 -32
  481. agno/knowledge/youtube.py +0 -35
  482. agno/memory/agent.py +0 -423
  483. agno/memory/classifier.py +0 -104
  484. agno/memory/db/__init__.py +0 -5
  485. agno/memory/db/base.py +0 -42
  486. agno/memory/db/mongodb.py +0 -189
  487. agno/memory/db/postgres.py +0 -203
  488. agno/memory/db/sqlite.py +0 -193
  489. agno/memory/memory.py +0 -22
  490. agno/memory/row.py +0 -36
  491. agno/memory/summarizer.py +0 -201
  492. agno/memory/summary.py +0 -19
  493. agno/memory/team.py +0 -415
  494. agno/memory/v2/__init__.py +0 -2
  495. agno/memory/v2/db/__init__.py +0 -1
  496. agno/memory/v2/db/base.py +0 -42
  497. agno/memory/v2/db/firestore.py +0 -339
  498. agno/memory/v2/db/mongodb.py +0 -196
  499. agno/memory/v2/db/postgres.py +0 -214
  500. agno/memory/v2/db/redis.py +0 -187
  501. agno/memory/v2/db/schema.py +0 -54
  502. agno/memory/v2/db/sqlite.py +0 -209
  503. agno/memory/v2/manager.py +0 -437
  504. agno/memory/v2/memory.py +0 -1097
  505. agno/memory/v2/schema.py +0 -55
  506. agno/memory/v2/summarizer.py +0 -215
  507. agno/memory/workflow.py +0 -38
  508. agno/models/ollama/tools.py +0 -430
  509. agno/models/qwen/__init__.py +0 -5
  510. agno/playground/__init__.py +0 -10
  511. agno/playground/deploy.py +0 -3
  512. agno/playground/playground.py +0 -3
  513. agno/playground/serve.py +0 -3
  514. agno/playground/settings.py +0 -3
  515. agno/reranker/__init__.py +0 -0
  516. agno/run/v2/__init__.py +0 -0
  517. agno/run/v2/workflow.py +0 -567
  518. agno/storage/__init__.py +0 -0
  519. agno/storage/agent/__init__.py +0 -0
  520. agno/storage/agent/dynamodb.py +0 -1
  521. agno/storage/agent/json.py +0 -1
  522. agno/storage/agent/mongodb.py +0 -1
  523. agno/storage/agent/postgres.py +0 -1
  524. agno/storage/agent/singlestore.py +0 -1
  525. agno/storage/agent/sqlite.py +0 -1
  526. agno/storage/agent/yaml.py +0 -1
  527. agno/storage/base.py +0 -60
  528. agno/storage/dynamodb.py +0 -673
  529. agno/storage/firestore.py +0 -297
  530. agno/storage/gcs_json.py +0 -261
  531. agno/storage/in_memory.py +0 -234
  532. agno/storage/json.py +0 -237
  533. agno/storage/mongodb.py +0 -328
  534. agno/storage/mysql.py +0 -685
  535. agno/storage/postgres.py +0 -682
  536. agno/storage/redis.py +0 -336
  537. agno/storage/session/__init__.py +0 -16
  538. agno/storage/session/agent.py +0 -64
  539. agno/storage/session/team.py +0 -63
  540. agno/storage/session/v2/__init__.py +0 -5
  541. agno/storage/session/workflow.py +0 -61
  542. agno/storage/singlestore.py +0 -606
  543. agno/storage/sqlite.py +0 -646
  544. agno/storage/workflow/__init__.py +0 -0
  545. agno/storage/workflow/mongodb.py +0 -1
  546. agno/storage/workflow/postgres.py +0 -1
  547. agno/storage/workflow/sqlite.py +0 -1
  548. agno/storage/yaml.py +0 -241
  549. agno/tools/thinking.py +0 -73
  550. agno/utils/defaults.py +0 -57
  551. agno/utils/filesystem.py +0 -39
  552. agno/utils/git.py +0 -52
  553. agno/utils/json_io.py +0 -30
  554. agno/utils/load_env.py +0 -19
  555. agno/utils/py_io.py +0 -19
  556. agno/utils/pyproject.py +0 -18
  557. agno/utils/resource_filter.py +0 -31
  558. agno/workflow/v2/__init__.py +0 -21
  559. agno/workflow/v2/types.py +0 -357
  560. agno/workflow/v2/workflow.py +0 -3312
  561. agno/workspace/__init__.py +0 -0
  562. agno/workspace/config.py +0 -325
  563. agno/workspace/enums.py +0 -6
  564. agno/workspace/helpers.py +0 -52
  565. agno/workspace/operator.py +0 -757
  566. agno/workspace/settings.py +0 -158
  567. agno-1.8.0.dist-info/METADATA +0 -979
  568. agno-1.8.0.dist-info/RECORD +0 -565
  569. agno-1.8.0.dist-info/entry_points.txt +0 -3
  570. /agno/{app → db/migrations}/__init__.py +0 -0
  571. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  572. /agno/{cli → integrations}/__init__.py +0 -0
  573. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  574. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  575. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  576. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  577. /agno/{app → os/interfaces}/slack/security.py +0 -0
  578. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  579. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  580. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  581. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
  582. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
  583. {agno-1.8.0.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