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,109 @@
1
+ """Table schemas and related utils used by the RedisDb class"""
2
+
3
+ from typing import Any
4
+
5
+ SESSION_SCHEMA = {
6
+ "session_id": {"type": "string", "primary_key": True},
7
+ "session_type": {"type": "string"},
8
+ "agent_id": {"type": "string"},
9
+ "team_id": {"type": "string"},
10
+ "workflow_id": {"type": "string"},
11
+ "user_id": {"type": "string"},
12
+ "session_data": {"type": "json"},
13
+ "agent_data": {"type": "json"},
14
+ "team_data": {"type": "json"},
15
+ "workflow_data": {"type": "json"},
16
+ "metadata": {"type": "json"},
17
+ "runs": {"type": "json"},
18
+ "summary": {"type": "json"},
19
+ "created_at": {"type": "integer"},
20
+ "updated_at": {"type": "integer"},
21
+ }
22
+
23
+ USER_MEMORY_SCHEMA = {
24
+ "memory_id": {"type": "string", "primary_key": True},
25
+ "memory": {"type": "json"},
26
+ "agent_id": {"type": "string"},
27
+ "team_id": {"type": "string"},
28
+ "user_id": {"type": "string"},
29
+ "topics": {"type": "json"},
30
+ "updated_at": {"type": "integer"},
31
+ }
32
+
33
+ METRICS_SCHEMA = {
34
+ "id": {"type": "string", "primary_key": True},
35
+ "agent_runs_count": {"type": "integer", "default": 0},
36
+ "team_runs_count": {"type": "integer", "default": 0},
37
+ "workflow_runs_count": {"type": "integer", "default": 0},
38
+ "agent_sessions_count": {"type": "integer", "default": 0},
39
+ "team_sessions_count": {"type": "integer", "default": 0},
40
+ "workflow_sessions_count": {"type": "integer", "default": 0},
41
+ "users_count": {"type": "integer", "default": 0},
42
+ "token_metrics": {"type": "json", "default": {}},
43
+ "model_metrics": {"type": "json", "default": {}},
44
+ "date": {"type": "date"},
45
+ "aggregation_period": {"type": "string"},
46
+ "created_at": {"type": "integer"},
47
+ "updated_at": {"type": "integer"},
48
+ "completed": {"type": "boolean", "default": False},
49
+ }
50
+
51
+ EVAL_SCHEMA = {
52
+ "run_id": {"type": "string", "primary_key": True},
53
+ "eval_type": {"type": "string"},
54
+ "eval_data": {"type": "json"},
55
+ "eval_input": {"type": "json"},
56
+ "name": {"type": "string"},
57
+ "agent_id": {"type": "string"},
58
+ "team_id": {"type": "string"},
59
+ "workflow_id": {"type": "string"},
60
+ "model_id": {"type": "string"},
61
+ "model_provider": {"type": "string"},
62
+ "evaluated_component_name": {"type": "string"},
63
+ "created_at": {"type": "integer"},
64
+ "updated_at": {"type": "integer"},
65
+ }
66
+
67
+ KNOWLEDGE_SCHEMA = {
68
+ "id": {"type": "string", "primary_key": True},
69
+ "name": {"type": "string"},
70
+ "description": {"type": "string"},
71
+ "metadata": {"type": "json"},
72
+ "type": {"type": "string"},
73
+ "size": {"type": "integer"},
74
+ "linked_to": {"type": "string"},
75
+ "access_count": {"type": "integer"},
76
+ "created_at": {"type": "integer"},
77
+ "updated_at": {"type": "integer"},
78
+ "status": {"type": "string"},
79
+ "status_message": {"type": "string"},
80
+ "external_id": {"type": "string"},
81
+ }
82
+
83
+
84
+ def get_table_schema_definition(table_type: str) -> dict[str, Any]:
85
+ """
86
+ Get the expected schema definition for the given table.
87
+
88
+ For Redis, we don't need actual schemas since it's a key-value store,
89
+ but we maintain this for compatibility with the base interface.
90
+
91
+ Args:
92
+ table_type (str): The type of table to get the schema for.
93
+
94
+ Returns:
95
+ Dict[str, Any]: Dictionary containing schema information for the table
96
+ """
97
+ schemas = {
98
+ "sessions": SESSION_SCHEMA,
99
+ "memories": USER_MEMORY_SCHEMA,
100
+ "metrics": METRICS_SCHEMA,
101
+ "evals": EVAL_SCHEMA,
102
+ "knowledge": KNOWLEDGE_SCHEMA,
103
+ }
104
+
105
+ schema = schemas.get(table_type, {})
106
+ if not schema:
107
+ raise ValueError(f"Unknown table type: {table_type}")
108
+
109
+ return schema
agno/db/redis/utils.py ADDED
@@ -0,0 +1,288 @@
1
+ """Utility functions for the Redis database class."""
2
+
3
+ import json
4
+ import time
5
+ from datetime import date, datetime, timedelta, timezone
6
+ from typing import Any, Dict, List, Optional
7
+ from uuid import UUID
8
+
9
+ from agno.utils.log import log_warning
10
+
11
+ try:
12
+ from redis import Redis
13
+ except ImportError:
14
+ raise ImportError("`redis` not installed. Please install it using `pip install redis`")
15
+
16
+
17
+ # -- Serialization and deserialization --
18
+
19
+
20
+ class CustomEncoder(json.JSONEncoder):
21
+ """Custom encoder to handle non JSON serializable types."""
22
+
23
+ def default(self, obj):
24
+ if isinstance(obj, UUID):
25
+ return str(obj)
26
+ elif isinstance(obj, (date, datetime)):
27
+ return obj.isoformat()
28
+
29
+ return super().default(obj)
30
+
31
+
32
+ def serialize_data(data: dict) -> str:
33
+ return json.dumps(data, ensure_ascii=False, cls=CustomEncoder)
34
+
35
+
36
+ def deserialize_data(data: str) -> dict:
37
+ return json.loads(data)
38
+
39
+
40
+ # -- Redis utils --
41
+
42
+
43
+ def generate_redis_key(prefix: str, table_type: str, key_id: str) -> str:
44
+ """Generate Redis key with proper namespacing."""
45
+ return f"{prefix}:{table_type}:{key_id}"
46
+
47
+
48
+ def generate_index_key(prefix: str, table_type: str, index_field: str, index_value: str) -> str:
49
+ """Generate Redis key for index entries."""
50
+ return f"{prefix}:{table_type}:index:{index_field}:{index_value}"
51
+
52
+
53
+ def get_all_keys_for_table(redis_client: Redis, prefix: str, table_type: str) -> List[str]:
54
+ """Get all relevant keys for the given table type.
55
+
56
+ Args:
57
+ redis_client (Redis): The Redis client.
58
+ prefix (str): The prefix for the keys.
59
+ table_type (str): The table type.
60
+
61
+ Returns:
62
+ List[str]: A list of all relevant keys for the given table type.
63
+ """
64
+ pattern = f"{prefix}:{table_type}:*"
65
+ all_keys = redis_client.scan_iter(match=pattern)
66
+ relevant_keys = []
67
+
68
+ for key in all_keys:
69
+ if ":index:" in key: # Skip index keys
70
+ continue
71
+ relevant_keys.append(key)
72
+
73
+ return relevant_keys
74
+
75
+
76
+ # -- DB util methods --
77
+
78
+
79
+ def apply_sorting(
80
+ records: List[Dict[str, Any]], sort_by: Optional[str] = None, sort_order: Optional[str] = None
81
+ ) -> List[Dict[str, Any]]:
82
+ if sort_by is None:
83
+ return records
84
+
85
+ def get_sort_key(record):
86
+ value = record.get(sort_by, 0)
87
+ if value is None:
88
+ return 0 if isinstance(records[0].get(sort_by, 0), (int, float)) else ""
89
+ return value
90
+
91
+ try:
92
+ is_reverse = sort_order == "desc"
93
+ return sorted(records, key=get_sort_key, reverse=is_reverse)
94
+
95
+ except Exception as e:
96
+ log_warning(f"Error sorting Redisrecords: {e}")
97
+ return records
98
+
99
+
100
+ def apply_pagination(
101
+ records: List[Dict[str, Any]], limit: Optional[int] = None, page: Optional[int] = None
102
+ ) -> List[Dict[str, Any]]:
103
+ if limit is None:
104
+ return records
105
+
106
+ if page is not None and page > 0:
107
+ start_idx = (page - 1) * limit
108
+ end_idx = start_idx + limit
109
+ return records[start_idx:end_idx]
110
+
111
+ return records[:limit]
112
+
113
+
114
+ def apply_filters(records: List[Dict[str, Any]], conditions: Dict[str, Any]) -> List[Dict[str, Any]]:
115
+ if not conditions:
116
+ return records
117
+
118
+ filtered_records = []
119
+ for record in records:
120
+ match = True
121
+ for key, value in conditions.items():
122
+ if key not in record or record[key] != value:
123
+ match = False
124
+ break
125
+ if match:
126
+ filtered_records.append(record)
127
+
128
+ return filtered_records
129
+
130
+
131
+ def create_index_entries(
132
+ redis_client: Redis,
133
+ prefix: str,
134
+ table_type: str,
135
+ record_id: str,
136
+ record_data: Dict[str, Any],
137
+ index_fields: List[str],
138
+ ) -> None:
139
+ for field in index_fields:
140
+ if field in record_data and record_data[field] is not None:
141
+ index_key = generate_index_key(prefix, table_type, field, str(record_data[field]))
142
+ redis_client.sadd(index_key, record_id)
143
+
144
+
145
+ def remove_index_entries(
146
+ redis_client: Redis,
147
+ prefix: str,
148
+ table_type: str,
149
+ record_id: str,
150
+ record_data: Dict[str, Any],
151
+ index_fields: List[str],
152
+ ) -> None:
153
+ for field in index_fields:
154
+ if field in record_data and record_data[field] is not None:
155
+ index_key = generate_index_key(prefix, table_type, field, str(record_data[field]))
156
+ redis_client.srem(index_key, record_id)
157
+
158
+
159
+ # -- Metrics utils --
160
+
161
+
162
+ def calculate_date_metrics(date_to_process: date, sessions_data: dict) -> dict:
163
+ """Calculate metrics for the given date.
164
+
165
+ Args:
166
+ date_to_process (date): The date to calculate metrics for.
167
+ sessions_data (dict): The sessions data.
168
+
169
+ Returns:
170
+ dict: A dictionary with the calculated metrics.
171
+ """
172
+ metrics = {
173
+ "users_count": 0,
174
+ "agent_sessions_count": 0,
175
+ "team_sessions_count": 0,
176
+ "workflow_sessions_count": 0,
177
+ "agent_runs_count": 0,
178
+ "team_runs_count": 0,
179
+ "workflow_runs_count": 0,
180
+ }
181
+ token_metrics = {
182
+ "input_tokens": 0,
183
+ "output_tokens": 0,
184
+ "total_tokens": 0,
185
+ "audio_total_tokens": 0,
186
+ "audio_input_tokens": 0,
187
+ "audio_output_tokens": 0,
188
+ "cache_read_tokens": 0,
189
+ "cache_write_tokens": 0,
190
+ "reasoning_tokens": 0,
191
+ }
192
+ model_counts: Dict[str, int] = {}
193
+
194
+ session_types = [
195
+ ("agent", "agent_sessions_count", "agent_runs_count"),
196
+ ("team", "team_sessions_count", "team_runs_count"),
197
+ ("workflow", "workflow_sessions_count", "workflow_runs_count"),
198
+ ]
199
+ all_user_ids = set()
200
+
201
+ for session_type, sessions_count_key, runs_count_key in session_types:
202
+ sessions = sessions_data.get(session_type, [])
203
+ metrics[sessions_count_key] = len(sessions)
204
+
205
+ for session in sessions:
206
+ if session.get("user_id"):
207
+ all_user_ids.add(session["user_id"])
208
+ metrics[runs_count_key] += len(session.get("runs", []))
209
+ if runs := session.get("runs", []):
210
+ for run in runs:
211
+ if model_id := run.get("model"):
212
+ model_provider = run.get("model_provider", "")
213
+ model_counts[f"{model_id}:{model_provider}"] = (
214
+ model_counts.get(f"{model_id}:{model_provider}", 0) + 1
215
+ )
216
+
217
+ session_metrics = session.get("session_data", {}).get("session_metrics", {})
218
+ for field in token_metrics:
219
+ token_metrics[field] += session_metrics.get(field, 0)
220
+
221
+ model_metrics = []
222
+ for model, count in model_counts.items():
223
+ model_id, model_provider = model.split(":")
224
+ model_metrics.append({"model_id": model_id, "model_provider": model_provider, "count": count})
225
+
226
+ metrics["users_count"] = len(all_user_ids)
227
+ current_time = int(time.time())
228
+
229
+ # Create a deterministic ID based on date and aggregation period. This simplifies avoiding duplicates
230
+ metric_id = f"{date_to_process.isoformat()}_daily"
231
+
232
+ return {
233
+ "id": metric_id,
234
+ "date": date_to_process,
235
+ "completed": date_to_process < datetime.now(timezone.utc).date(),
236
+ "token_metrics": token_metrics,
237
+ "model_metrics": model_metrics,
238
+ "created_at": current_time,
239
+ "updated_at": current_time,
240
+ "aggregation_period": "daily",
241
+ **metrics,
242
+ }
243
+
244
+
245
+ def fetch_all_sessions_data(
246
+ sessions: List[Dict[str, Any]], dates_to_process: list[date], start_timestamp: int
247
+ ) -> Optional[dict]:
248
+ """Return all session data for the given dates, for all session types.
249
+
250
+ Args:
251
+ sessions (List[Dict[str, Any]]): The sessions data.
252
+ dates_to_process (list[date]): The dates to process.
253
+ start_timestamp (int): The start timestamp.
254
+
255
+ Returns:
256
+ Optional[dict]: A dictionary with the session data for the given dates, for all session types.
257
+ """
258
+ if not dates_to_process:
259
+ return None
260
+
261
+ all_sessions_data: Dict[str, Dict[str, List[Dict[str, Any]]]] = {
262
+ date_to_process.isoformat(): {"agent": [], "team": [], "workflow": []} for date_to_process in dates_to_process
263
+ }
264
+
265
+ for session in sessions:
266
+ session_date = (
267
+ datetime.fromtimestamp(session.get("created_at", start_timestamp), tz=timezone.utc).date().isoformat()
268
+ )
269
+ if session_date in all_sessions_data:
270
+ all_sessions_data[session_date][session["session_type"]].append(session)
271
+
272
+ return all_sessions_data
273
+
274
+
275
+ def get_dates_to_calculate_metrics_for(starting_date: date) -> list[date]:
276
+ """Return the list of dates to calculate metrics for.
277
+
278
+ Args:
279
+ starting_date (date): The starting date.
280
+
281
+ Returns:
282
+ list[date]: The list of dates to calculate metrics for.
283
+ """
284
+ today = datetime.now(timezone.utc).date()
285
+ days_diff = (today - starting_date).days + 1
286
+ if days_diff <= 0:
287
+ return []
288
+ return [starting_date + timedelta(days=x) for x in range(days_diff)]
@@ -0,0 +1,3 @@
1
+ from agno.db.schemas.memory import UserMemory
2
+
3
+ __all__ = ["UserMemory"]
@@ -0,0 +1,33 @@
1
+ from enum import Enum
2
+ from typing import Any, Dict, Optional
3
+
4
+ from pydantic import BaseModel
5
+
6
+
7
+ class EvalType(str, Enum):
8
+ ACCURACY = "accuracy"
9
+ PERFORMANCE = "performance"
10
+ RELIABILITY = "reliability"
11
+
12
+
13
+ class EvalFilterType(str, Enum):
14
+ AGENT = "agent"
15
+ TEAM = "team"
16
+ WORKFLOW = "workflow"
17
+
18
+
19
+ class EvalRunRecord(BaseModel):
20
+ """Evaluation run results stored in the database"""
21
+
22
+ agent_id: Optional[str] = None
23
+ model_id: Optional[str] = None
24
+ model_provider: Optional[str] = None
25
+ team_id: Optional[str] = None
26
+ workflow_id: Optional[str] = None
27
+ name: Optional[str] = None
28
+ evaluated_component_name: Optional[str] = None
29
+
30
+ run_id: str
31
+ eval_type: EvalType
32
+ eval_data: Dict[str, Any]
33
+ eval_input: Optional[Dict[str, Any]] = None
@@ -0,0 +1,40 @@
1
+ from datetime import datetime
2
+ from typing import Any, Dict, Optional
3
+
4
+ from pydantic import BaseModel, ConfigDict, model_validator
5
+
6
+
7
+ class KnowledgeRow(BaseModel):
8
+ """Knowledge Row that is stored in the database"""
9
+
10
+ # id for this knowledge, auto-generated if not provided
11
+ id: Optional[str] = None
12
+ name: str
13
+ description: str
14
+ metadata: Optional[Dict[str, Any]] = None
15
+ type: Optional[str] = None
16
+ size: Optional[int] = None
17
+ linked_to: Optional[str] = None
18
+ access_count: Optional[int] = None
19
+ status: Optional[str] = None
20
+ status_message: Optional[str] = None
21
+ created_at: Optional[int] = None
22
+ updated_at: Optional[int] = None
23
+ external_id: Optional[str] = None
24
+
25
+ model_config = ConfigDict(from_attributes=True, arbitrary_types_allowed=True)
26
+
27
+ @model_validator(mode="after")
28
+ def generate_id(self) -> "KnowledgeRow":
29
+ if self.id is None:
30
+ from uuid import uuid4
31
+
32
+ self.id = str(uuid4())
33
+ return self
34
+
35
+ def to_dict(self) -> Dict[str, Any]:
36
+ _dict = self.model_dump(exclude={"updated_at"})
37
+
38
+ _dict["updated_at"] = datetime.fromtimestamp(self.updated_at).isoformat() if self.updated_at else None
39
+
40
+ return _dict
@@ -0,0 +1,46 @@
1
+ from dataclasses import dataclass
2
+ from datetime import datetime, timezone
3
+ from typing import Any, Dict, List, Optional
4
+
5
+
6
+ @dataclass
7
+ class UserMemory:
8
+ """Model for User Memories"""
9
+
10
+ memory: str
11
+ memory_id: Optional[str] = None
12
+ topics: Optional[List[str]] = None
13
+ user_id: Optional[str] = None
14
+ input: Optional[str] = None
15
+ updated_at: Optional[datetime] = None
16
+ feedback: Optional[str] = None
17
+
18
+ agent_id: Optional[str] = None
19
+ team_id: Optional[str] = None
20
+
21
+ def to_dict(self) -> Dict[str, Any]:
22
+ _dict = {
23
+ "memory_id": self.memory_id,
24
+ "memory": self.memory,
25
+ "topics": self.topics,
26
+ "updated_at": self.updated_at.isoformat() if self.updated_at else None,
27
+ "input": self.input,
28
+ "user_id": self.user_id,
29
+ "agent_id": self.agent_id,
30
+ "team_id": self.team_id,
31
+ "feedback": self.feedback,
32
+ }
33
+ return {k: v for k, v in _dict.items() if v is not None}
34
+
35
+ @classmethod
36
+ def from_dict(cls, data: Dict[str, Any]) -> "UserMemory":
37
+ data = dict(data)
38
+
39
+ # Convert updated_at to datetime
40
+ if updated_at := data.get("updated_at"):
41
+ if isinstance(updated_at, (int, float)):
42
+ data["updated_at"] = datetime.fromtimestamp(updated_at, tz=timezone.utc)
43
+ else:
44
+ data["updated_at"] = datetime.fromisoformat(updated_at)
45
+
46
+ return cls(**data)
@@ -0,0 +1,3 @@
1
+ from agno.db.singlestore.singlestore import SingleStoreDb
2
+
3
+ __all__ = ["SingleStoreDb"]
@@ -0,0 +1,116 @@
1
+ """Table schemas and related utils used by the SingleStoreDb class"""
2
+
3
+ from typing import Any
4
+
5
+ try:
6
+ from sqlalchemy.types import JSON, BigInteger, Boolean, Date, String, Text
7
+ except ImportError:
8
+ raise ImportError("`sqlalchemy` not installed. Please install it using `pip install sqlalchemy`")
9
+
10
+ SESSION_TABLE_SCHEMA = {
11
+ "session_id": {"type": lambda: String(128), "nullable": False},
12
+ "session_type": {"type": lambda: String(20), "nullable": False, "index": True},
13
+ "agent_id": {"type": lambda: String(128), "nullable": True},
14
+ "team_id": {"type": lambda: String(128), "nullable": True},
15
+ "workflow_id": {"type": lambda: String(128), "nullable": True},
16
+ "user_id": {"type": lambda: String(128), "nullable": True},
17
+ "session_data": {"type": JSON, "nullable": True},
18
+ "agent_data": {"type": JSON, "nullable": True},
19
+ "team_data": {"type": JSON, "nullable": True},
20
+ "workflow_data": {"type": JSON, "nullable": True},
21
+ "metadata": {"type": JSON, "nullable": True},
22
+ "runs": {"type": JSON, "nullable": True},
23
+ "summary": {"type": JSON, "nullable": True},
24
+ "created_at": {"type": BigInteger, "nullable": False, "index": True},
25
+ "updated_at": {"type": BigInteger, "nullable": True},
26
+ "_unique_constraints": [
27
+ {
28
+ "name": "uq_session_id",
29
+ "columns": ["session_id"],
30
+ },
31
+ ],
32
+ }
33
+
34
+ USER_MEMORY_TABLE_SCHEMA = {
35
+ "memory_id": {"type": lambda: String(128), "primary_key": True, "nullable": False},
36
+ "memory": {"type": JSON, "nullable": False},
37
+ "input": {"type": Text, "nullable": True},
38
+ "agent_id": {"type": lambda: String(128), "nullable": True},
39
+ "team_id": {"type": lambda: String(128), "nullable": True},
40
+ "user_id": {"type": lambda: String(128), "nullable": True, "index": True},
41
+ "topics": {"type": JSON, "nullable": True},
42
+ "updated_at": {"type": BigInteger, "nullable": True, "index": True},
43
+ }
44
+
45
+ EVAL_TABLE_SCHEMA = {
46
+ "run_id": {"type": lambda: String(128), "primary_key": True, "nullable": False},
47
+ "eval_type": {"type": lambda: String(50), "nullable": False},
48
+ "eval_data": {"type": JSON, "nullable": False},
49
+ "eval_input": {"type": JSON, "nullable": False},
50
+ "name": {"type": lambda: String(255), "nullable": True},
51
+ "agent_id": {"type": lambda: String(128), "nullable": True},
52
+ "team_id": {"type": lambda: String(128), "nullable": True},
53
+ "workflow_id": {"type": lambda: String(128), "nullable": True},
54
+ "model_id": {"type": lambda: String(128), "nullable": True},
55
+ "model_provider": {"type": lambda: String(50), "nullable": True},
56
+ "evaluated_component_name": {"type": lambda: String(255), "nullable": True},
57
+ "created_at": {"type": BigInteger, "nullable": False, "index": True},
58
+ "updated_at": {"type": BigInteger, "nullable": True},
59
+ }
60
+
61
+ KNOWLEDGE_TABLE_SCHEMA = {
62
+ "id": {"type": lambda: String(128), "primary_key": True, "nullable": False},
63
+ "name": {"type": lambda: String(255), "nullable": False},
64
+ "description": {"type": Text, "nullable": False},
65
+ "metadata": {"type": JSON, "nullable": True},
66
+ "type": {"type": lambda: String(50), "nullable": True},
67
+ "size": {"type": BigInteger, "nullable": True},
68
+ "linked_to": {"type": lambda: String(128), "nullable": True},
69
+ "access_count": {"type": BigInteger, "nullable": True},
70
+ "status": {"type": lambda: String(50), "nullable": True},
71
+ "status_message": {"type": Text, "nullable": True},
72
+ "created_at": {"type": BigInteger, "nullable": True},
73
+ "updated_at": {"type": BigInteger, "nullable": True},
74
+ "external_id": {"type": lambda: String(128), "nullable": True},
75
+ }
76
+
77
+ METRICS_TABLE_SCHEMA = {
78
+ "id": {"type": lambda: String(128), "primary_key": True, "nullable": False},
79
+ "agent_runs_count": {"type": BigInteger, "nullable": False, "default": 0},
80
+ "team_runs_count": {"type": BigInteger, "nullable": False, "default": 0},
81
+ "workflow_runs_count": {"type": BigInteger, "nullable": False, "default": 0},
82
+ "agent_sessions_count": {"type": BigInteger, "nullable": False, "default": 0},
83
+ "team_sessions_count": {"type": BigInteger, "nullable": False, "default": 0},
84
+ "workflow_sessions_count": {"type": BigInteger, "nullable": False, "default": 0},
85
+ "users_count": {"type": BigInteger, "nullable": False, "default": 0},
86
+ "token_metrics": {"type": JSON, "nullable": False, "default": {}},
87
+ "model_metrics": {"type": JSON, "nullable": False, "default": {}},
88
+ "date": {"type": Date, "nullable": False, "index": True},
89
+ "aggregation_period": {"type": lambda: String(20), "nullable": False, "index": True},
90
+ "created_at": {"type": BigInteger, "nullable": False},
91
+ "updated_at": {"type": BigInteger, "nullable": True},
92
+ "completed": {"type": Boolean, "nullable": False, "default": False},
93
+ }
94
+
95
+
96
+ def get_table_schema_definition(table_type: str) -> dict[str, Any]:
97
+ """
98
+ Get the expected schema definition for the given table.
99
+ Args:
100
+ table_type (str): The type of table to get the schema for.
101
+ Returns:
102
+ Dict[str, Any]: Dictionary containing column definitions for the table
103
+ """
104
+ schemas = {
105
+ "sessions": SESSION_TABLE_SCHEMA,
106
+ "evals": EVAL_TABLE_SCHEMA,
107
+ "metrics": METRICS_TABLE_SCHEMA,
108
+ "memories": USER_MEMORY_TABLE_SCHEMA,
109
+ "knowledge_contents": KNOWLEDGE_TABLE_SCHEMA,
110
+ }
111
+ schema = schemas.get(table_type, {})
112
+
113
+ if not schema:
114
+ raise ValueError(f"Unknown table type: {table_type}")
115
+
116
+ return schema # type: ignore[return-value]