agno 2.2.13__py3-none-any.whl → 2.4.3__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 (383) hide show
  1. agno/agent/__init__.py +6 -0
  2. agno/agent/agent.py +5252 -3145
  3. agno/agent/remote.py +525 -0
  4. agno/api/api.py +2 -0
  5. agno/client/__init__.py +3 -0
  6. agno/client/a2a/__init__.py +10 -0
  7. agno/client/a2a/client.py +554 -0
  8. agno/client/a2a/schemas.py +112 -0
  9. agno/client/a2a/utils.py +369 -0
  10. agno/client/os.py +2669 -0
  11. agno/compression/__init__.py +3 -0
  12. agno/compression/manager.py +247 -0
  13. agno/culture/manager.py +2 -2
  14. agno/db/base.py +927 -6
  15. agno/db/dynamo/dynamo.py +788 -2
  16. agno/db/dynamo/schemas.py +128 -0
  17. agno/db/dynamo/utils.py +26 -3
  18. agno/db/firestore/firestore.py +674 -50
  19. agno/db/firestore/schemas.py +41 -0
  20. agno/db/firestore/utils.py +25 -10
  21. agno/db/gcs_json/gcs_json_db.py +506 -3
  22. agno/db/gcs_json/utils.py +14 -2
  23. agno/db/in_memory/in_memory_db.py +203 -4
  24. agno/db/in_memory/utils.py +14 -2
  25. agno/db/json/json_db.py +498 -2
  26. agno/db/json/utils.py +14 -2
  27. agno/db/migrations/manager.py +199 -0
  28. agno/db/migrations/utils.py +19 -0
  29. agno/db/migrations/v1_to_v2.py +54 -16
  30. agno/db/migrations/versions/__init__.py +0 -0
  31. agno/db/migrations/versions/v2_3_0.py +977 -0
  32. agno/db/mongo/async_mongo.py +1013 -39
  33. agno/db/mongo/mongo.py +684 -4
  34. agno/db/mongo/schemas.py +48 -0
  35. agno/db/mongo/utils.py +17 -0
  36. agno/db/mysql/__init__.py +2 -1
  37. agno/db/mysql/async_mysql.py +2958 -0
  38. agno/db/mysql/mysql.py +722 -53
  39. agno/db/mysql/schemas.py +77 -11
  40. agno/db/mysql/utils.py +151 -8
  41. agno/db/postgres/async_postgres.py +1254 -137
  42. agno/db/postgres/postgres.py +2316 -93
  43. agno/db/postgres/schemas.py +153 -21
  44. agno/db/postgres/utils.py +22 -7
  45. agno/db/redis/redis.py +531 -3
  46. agno/db/redis/schemas.py +36 -0
  47. agno/db/redis/utils.py +31 -15
  48. agno/db/schemas/evals.py +1 -0
  49. agno/db/schemas/memory.py +20 -9
  50. agno/db/singlestore/schemas.py +70 -1
  51. agno/db/singlestore/singlestore.py +737 -74
  52. agno/db/singlestore/utils.py +13 -3
  53. agno/db/sqlite/async_sqlite.py +1069 -89
  54. agno/db/sqlite/schemas.py +133 -1
  55. agno/db/sqlite/sqlite.py +2203 -165
  56. agno/db/sqlite/utils.py +21 -11
  57. agno/db/surrealdb/models.py +25 -0
  58. agno/db/surrealdb/surrealdb.py +603 -1
  59. agno/db/utils.py +60 -0
  60. agno/eval/__init__.py +26 -3
  61. agno/eval/accuracy.py +25 -12
  62. agno/eval/agent_as_judge.py +871 -0
  63. agno/eval/base.py +29 -0
  64. agno/eval/performance.py +10 -4
  65. agno/eval/reliability.py +22 -13
  66. agno/eval/utils.py +2 -1
  67. agno/exceptions.py +42 -0
  68. agno/hooks/__init__.py +3 -0
  69. agno/hooks/decorator.py +164 -0
  70. agno/integrations/discord/client.py +13 -2
  71. agno/knowledge/__init__.py +4 -0
  72. agno/knowledge/chunking/code.py +90 -0
  73. agno/knowledge/chunking/document.py +65 -4
  74. agno/knowledge/chunking/fixed.py +4 -1
  75. agno/knowledge/chunking/markdown.py +102 -11
  76. agno/knowledge/chunking/recursive.py +2 -2
  77. agno/knowledge/chunking/semantic.py +130 -48
  78. agno/knowledge/chunking/strategy.py +18 -0
  79. agno/knowledge/embedder/azure_openai.py +0 -1
  80. agno/knowledge/embedder/google.py +1 -1
  81. agno/knowledge/embedder/mistral.py +1 -1
  82. agno/knowledge/embedder/nebius.py +1 -1
  83. agno/knowledge/embedder/openai.py +16 -12
  84. agno/knowledge/filesystem.py +412 -0
  85. agno/knowledge/knowledge.py +4261 -1199
  86. agno/knowledge/protocol.py +134 -0
  87. agno/knowledge/reader/arxiv_reader.py +3 -2
  88. agno/knowledge/reader/base.py +9 -7
  89. agno/knowledge/reader/csv_reader.py +91 -42
  90. agno/knowledge/reader/docx_reader.py +9 -10
  91. agno/knowledge/reader/excel_reader.py +225 -0
  92. agno/knowledge/reader/field_labeled_csv_reader.py +38 -48
  93. agno/knowledge/reader/firecrawl_reader.py +3 -2
  94. agno/knowledge/reader/json_reader.py +16 -22
  95. agno/knowledge/reader/markdown_reader.py +15 -14
  96. agno/knowledge/reader/pdf_reader.py +33 -28
  97. agno/knowledge/reader/pptx_reader.py +9 -10
  98. agno/knowledge/reader/reader_factory.py +135 -1
  99. agno/knowledge/reader/s3_reader.py +8 -16
  100. agno/knowledge/reader/tavily_reader.py +3 -3
  101. agno/knowledge/reader/text_reader.py +15 -14
  102. agno/knowledge/reader/utils/__init__.py +17 -0
  103. agno/knowledge/reader/utils/spreadsheet.py +114 -0
  104. agno/knowledge/reader/web_search_reader.py +8 -65
  105. agno/knowledge/reader/website_reader.py +16 -13
  106. agno/knowledge/reader/wikipedia_reader.py +36 -3
  107. agno/knowledge/reader/youtube_reader.py +3 -2
  108. agno/knowledge/remote_content/__init__.py +33 -0
  109. agno/knowledge/remote_content/config.py +266 -0
  110. agno/knowledge/remote_content/remote_content.py +105 -17
  111. agno/knowledge/utils.py +76 -22
  112. agno/learn/__init__.py +71 -0
  113. agno/learn/config.py +463 -0
  114. agno/learn/curate.py +185 -0
  115. agno/learn/machine.py +725 -0
  116. agno/learn/schemas.py +1114 -0
  117. agno/learn/stores/__init__.py +38 -0
  118. agno/learn/stores/decision_log.py +1156 -0
  119. agno/learn/stores/entity_memory.py +3275 -0
  120. agno/learn/stores/learned_knowledge.py +1583 -0
  121. agno/learn/stores/protocol.py +117 -0
  122. agno/learn/stores/session_context.py +1217 -0
  123. agno/learn/stores/user_memory.py +1495 -0
  124. agno/learn/stores/user_profile.py +1220 -0
  125. agno/learn/utils.py +209 -0
  126. agno/media.py +22 -6
  127. agno/memory/__init__.py +14 -1
  128. agno/memory/manager.py +223 -8
  129. agno/memory/strategies/__init__.py +15 -0
  130. agno/memory/strategies/base.py +66 -0
  131. agno/memory/strategies/summarize.py +196 -0
  132. agno/memory/strategies/types.py +37 -0
  133. agno/models/aimlapi/aimlapi.py +17 -0
  134. agno/models/anthropic/claude.py +434 -59
  135. agno/models/aws/bedrock.py +121 -20
  136. agno/models/aws/claude.py +131 -274
  137. agno/models/azure/ai_foundry.py +10 -6
  138. agno/models/azure/openai_chat.py +33 -10
  139. agno/models/base.py +1162 -561
  140. agno/models/cerebras/cerebras.py +120 -24
  141. agno/models/cerebras/cerebras_openai.py +21 -2
  142. agno/models/cohere/chat.py +65 -6
  143. agno/models/cometapi/cometapi.py +18 -1
  144. agno/models/dashscope/dashscope.py +2 -3
  145. agno/models/deepinfra/deepinfra.py +18 -1
  146. agno/models/deepseek/deepseek.py +69 -3
  147. agno/models/fireworks/fireworks.py +18 -1
  148. agno/models/google/gemini.py +959 -89
  149. agno/models/google/utils.py +22 -0
  150. agno/models/groq/groq.py +48 -18
  151. agno/models/huggingface/huggingface.py +17 -6
  152. agno/models/ibm/watsonx.py +16 -6
  153. agno/models/internlm/internlm.py +18 -1
  154. agno/models/langdb/langdb.py +13 -1
  155. agno/models/litellm/chat.py +88 -9
  156. agno/models/litellm/litellm_openai.py +18 -1
  157. agno/models/message.py +24 -5
  158. agno/models/meta/llama.py +40 -13
  159. agno/models/meta/llama_openai.py +22 -21
  160. agno/models/metrics.py +12 -0
  161. agno/models/mistral/mistral.py +8 -4
  162. agno/models/n1n/__init__.py +3 -0
  163. agno/models/n1n/n1n.py +57 -0
  164. agno/models/nebius/nebius.py +6 -7
  165. agno/models/nvidia/nvidia.py +20 -3
  166. agno/models/ollama/__init__.py +2 -0
  167. agno/models/ollama/chat.py +17 -6
  168. agno/models/ollama/responses.py +100 -0
  169. agno/models/openai/__init__.py +2 -0
  170. agno/models/openai/chat.py +117 -26
  171. agno/models/openai/open_responses.py +46 -0
  172. agno/models/openai/responses.py +110 -32
  173. agno/models/openrouter/__init__.py +2 -0
  174. agno/models/openrouter/openrouter.py +67 -2
  175. agno/models/openrouter/responses.py +146 -0
  176. agno/models/perplexity/perplexity.py +19 -1
  177. agno/models/portkey/portkey.py +7 -6
  178. agno/models/requesty/requesty.py +19 -2
  179. agno/models/response.py +20 -2
  180. agno/models/sambanova/sambanova.py +20 -3
  181. agno/models/siliconflow/siliconflow.py +19 -2
  182. agno/models/together/together.py +20 -3
  183. agno/models/vercel/v0.py +20 -3
  184. agno/models/vertexai/claude.py +124 -4
  185. agno/models/vllm/vllm.py +19 -14
  186. agno/models/xai/xai.py +19 -2
  187. agno/os/app.py +467 -137
  188. agno/os/auth.py +253 -5
  189. agno/os/config.py +22 -0
  190. agno/os/interfaces/a2a/a2a.py +7 -6
  191. agno/os/interfaces/a2a/router.py +635 -26
  192. agno/os/interfaces/a2a/utils.py +32 -33
  193. agno/os/interfaces/agui/agui.py +5 -3
  194. agno/os/interfaces/agui/router.py +26 -16
  195. agno/os/interfaces/agui/utils.py +97 -57
  196. agno/os/interfaces/base.py +7 -7
  197. agno/os/interfaces/slack/router.py +16 -7
  198. agno/os/interfaces/slack/slack.py +7 -7
  199. agno/os/interfaces/whatsapp/router.py +35 -7
  200. agno/os/interfaces/whatsapp/security.py +3 -1
  201. agno/os/interfaces/whatsapp/whatsapp.py +11 -8
  202. agno/os/managers.py +326 -0
  203. agno/os/mcp.py +652 -79
  204. agno/os/middleware/__init__.py +4 -0
  205. agno/os/middleware/jwt.py +718 -115
  206. agno/os/middleware/trailing_slash.py +27 -0
  207. agno/os/router.py +105 -1558
  208. agno/os/routers/agents/__init__.py +3 -0
  209. agno/os/routers/agents/router.py +655 -0
  210. agno/os/routers/agents/schema.py +288 -0
  211. agno/os/routers/components/__init__.py +3 -0
  212. agno/os/routers/components/components.py +475 -0
  213. agno/os/routers/database.py +155 -0
  214. agno/os/routers/evals/evals.py +111 -18
  215. agno/os/routers/evals/schemas.py +38 -5
  216. agno/os/routers/evals/utils.py +80 -11
  217. agno/os/routers/health.py +3 -3
  218. agno/os/routers/knowledge/knowledge.py +284 -35
  219. agno/os/routers/knowledge/schemas.py +14 -2
  220. agno/os/routers/memory/memory.py +274 -11
  221. agno/os/routers/memory/schemas.py +44 -3
  222. agno/os/routers/metrics/metrics.py +30 -15
  223. agno/os/routers/metrics/schemas.py +10 -6
  224. agno/os/routers/registry/__init__.py +3 -0
  225. agno/os/routers/registry/registry.py +337 -0
  226. agno/os/routers/session/session.py +143 -14
  227. agno/os/routers/teams/__init__.py +3 -0
  228. agno/os/routers/teams/router.py +550 -0
  229. agno/os/routers/teams/schema.py +280 -0
  230. agno/os/routers/traces/__init__.py +3 -0
  231. agno/os/routers/traces/schemas.py +414 -0
  232. agno/os/routers/traces/traces.py +549 -0
  233. agno/os/routers/workflows/__init__.py +3 -0
  234. agno/os/routers/workflows/router.py +757 -0
  235. agno/os/routers/workflows/schema.py +139 -0
  236. agno/os/schema.py +157 -584
  237. agno/os/scopes.py +469 -0
  238. agno/os/settings.py +3 -0
  239. agno/os/utils.py +574 -185
  240. agno/reasoning/anthropic.py +85 -1
  241. agno/reasoning/azure_ai_foundry.py +93 -1
  242. agno/reasoning/deepseek.py +102 -2
  243. agno/reasoning/default.py +6 -7
  244. agno/reasoning/gemini.py +87 -3
  245. agno/reasoning/groq.py +109 -2
  246. agno/reasoning/helpers.py +6 -7
  247. agno/reasoning/manager.py +1238 -0
  248. agno/reasoning/ollama.py +93 -1
  249. agno/reasoning/openai.py +115 -1
  250. agno/reasoning/vertexai.py +85 -1
  251. agno/registry/__init__.py +3 -0
  252. agno/registry/registry.py +68 -0
  253. agno/remote/__init__.py +3 -0
  254. agno/remote/base.py +581 -0
  255. agno/run/__init__.py +2 -4
  256. agno/run/agent.py +134 -19
  257. agno/run/base.py +49 -1
  258. agno/run/cancel.py +65 -52
  259. agno/run/cancellation_management/__init__.py +9 -0
  260. agno/run/cancellation_management/base.py +78 -0
  261. agno/run/cancellation_management/in_memory_cancellation_manager.py +100 -0
  262. agno/run/cancellation_management/redis_cancellation_manager.py +236 -0
  263. agno/run/requirement.py +181 -0
  264. agno/run/team.py +111 -19
  265. agno/run/workflow.py +2 -1
  266. agno/session/agent.py +57 -92
  267. agno/session/summary.py +1 -1
  268. agno/session/team.py +62 -115
  269. agno/session/workflow.py +353 -57
  270. agno/skills/__init__.py +17 -0
  271. agno/skills/agent_skills.py +377 -0
  272. agno/skills/errors.py +32 -0
  273. agno/skills/loaders/__init__.py +4 -0
  274. agno/skills/loaders/base.py +27 -0
  275. agno/skills/loaders/local.py +216 -0
  276. agno/skills/skill.py +65 -0
  277. agno/skills/utils.py +107 -0
  278. agno/skills/validator.py +277 -0
  279. agno/table.py +10 -0
  280. agno/team/__init__.py +5 -1
  281. agno/team/remote.py +447 -0
  282. agno/team/team.py +3769 -2202
  283. agno/tools/brandfetch.py +27 -18
  284. agno/tools/browserbase.py +225 -16
  285. agno/tools/crawl4ai.py +3 -0
  286. agno/tools/duckduckgo.py +25 -71
  287. agno/tools/exa.py +0 -21
  288. agno/tools/file.py +14 -13
  289. agno/tools/file_generation.py +12 -6
  290. agno/tools/firecrawl.py +15 -7
  291. agno/tools/function.py +94 -113
  292. agno/tools/google_bigquery.py +11 -2
  293. agno/tools/google_drive.py +4 -3
  294. agno/tools/knowledge.py +9 -4
  295. agno/tools/mcp/mcp.py +301 -18
  296. agno/tools/mcp/multi_mcp.py +269 -14
  297. agno/tools/mem0.py +11 -10
  298. agno/tools/memory.py +47 -46
  299. agno/tools/mlx_transcribe.py +10 -7
  300. agno/tools/models/nebius.py +5 -5
  301. agno/tools/models_labs.py +20 -10
  302. agno/tools/nano_banana.py +151 -0
  303. agno/tools/parallel.py +0 -7
  304. agno/tools/postgres.py +76 -36
  305. agno/tools/python.py +14 -6
  306. agno/tools/reasoning.py +30 -23
  307. agno/tools/redshift.py +406 -0
  308. agno/tools/shopify.py +1519 -0
  309. agno/tools/spotify.py +919 -0
  310. agno/tools/tavily.py +4 -1
  311. agno/tools/toolkit.py +253 -18
  312. agno/tools/websearch.py +93 -0
  313. agno/tools/website.py +1 -1
  314. agno/tools/wikipedia.py +1 -1
  315. agno/tools/workflow.py +56 -48
  316. agno/tools/yfinance.py +12 -11
  317. agno/tracing/__init__.py +12 -0
  318. agno/tracing/exporter.py +161 -0
  319. agno/tracing/schemas.py +276 -0
  320. agno/tracing/setup.py +112 -0
  321. agno/utils/agent.py +251 -10
  322. agno/utils/cryptography.py +22 -0
  323. agno/utils/dttm.py +33 -0
  324. agno/utils/events.py +264 -7
  325. agno/utils/hooks.py +111 -3
  326. agno/utils/http.py +161 -2
  327. agno/utils/mcp.py +49 -8
  328. agno/utils/media.py +22 -1
  329. agno/utils/models/ai_foundry.py +9 -2
  330. agno/utils/models/claude.py +20 -5
  331. agno/utils/models/cohere.py +9 -2
  332. agno/utils/models/llama.py +9 -2
  333. agno/utils/models/mistral.py +4 -2
  334. agno/utils/os.py +0 -0
  335. agno/utils/print_response/agent.py +99 -16
  336. agno/utils/print_response/team.py +223 -24
  337. agno/utils/print_response/workflow.py +0 -2
  338. agno/utils/prompts.py +8 -6
  339. agno/utils/remote.py +23 -0
  340. agno/utils/response.py +1 -13
  341. agno/utils/string.py +91 -2
  342. agno/utils/team.py +62 -12
  343. agno/utils/tokens.py +657 -0
  344. agno/vectordb/base.py +15 -2
  345. agno/vectordb/cassandra/cassandra.py +1 -1
  346. agno/vectordb/chroma/__init__.py +2 -1
  347. agno/vectordb/chroma/chromadb.py +468 -23
  348. agno/vectordb/clickhouse/clickhousedb.py +1 -1
  349. agno/vectordb/couchbase/couchbase.py +6 -2
  350. agno/vectordb/lancedb/lance_db.py +7 -38
  351. agno/vectordb/lightrag/lightrag.py +7 -6
  352. agno/vectordb/milvus/milvus.py +118 -84
  353. agno/vectordb/mongodb/__init__.py +2 -1
  354. agno/vectordb/mongodb/mongodb.py +14 -31
  355. agno/vectordb/pgvector/pgvector.py +120 -66
  356. agno/vectordb/pineconedb/pineconedb.py +2 -19
  357. agno/vectordb/qdrant/__init__.py +2 -1
  358. agno/vectordb/qdrant/qdrant.py +33 -56
  359. agno/vectordb/redis/__init__.py +2 -1
  360. agno/vectordb/redis/redisdb.py +19 -31
  361. agno/vectordb/singlestore/singlestore.py +17 -9
  362. agno/vectordb/surrealdb/surrealdb.py +2 -38
  363. agno/vectordb/weaviate/__init__.py +2 -1
  364. agno/vectordb/weaviate/weaviate.py +7 -3
  365. agno/workflow/__init__.py +5 -1
  366. agno/workflow/agent.py +2 -2
  367. agno/workflow/condition.py +12 -10
  368. agno/workflow/loop.py +28 -9
  369. agno/workflow/parallel.py +21 -13
  370. agno/workflow/remote.py +362 -0
  371. agno/workflow/router.py +12 -9
  372. agno/workflow/step.py +261 -36
  373. agno/workflow/steps.py +12 -8
  374. agno/workflow/types.py +40 -77
  375. agno/workflow/workflow.py +939 -213
  376. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/METADATA +134 -181
  377. agno-2.4.3.dist-info/RECORD +677 -0
  378. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/WHEEL +1 -1
  379. agno/tools/googlesearch.py +0 -98
  380. agno/tools/memori.py +0 -339
  381. agno-2.2.13.dist-info/RECORD +0 -575
  382. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/licenses/LICENSE +0 -0
  383. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/top_level.txt +0 -0
@@ -4,7 +4,7 @@ from typing import Any
4
4
 
5
5
  try:
6
6
  from sqlalchemy.dialects.postgresql import JSONB
7
- from sqlalchemy.types import JSON, BigInteger, Boolean, Date, String
7
+ from sqlalchemy.types import BigInteger, Boolean, Date, Integer, String, Text
8
8
  except ImportError:
9
9
  raise ImportError("`sqlalchemy` not installed. Please install it using `pip install sqlalchemy`")
10
10
 
@@ -15,13 +15,13 @@ SESSION_TABLE_SCHEMA = {
15
15
  "team_id": {"type": String, "nullable": True},
16
16
  "workflow_id": {"type": String, "nullable": True},
17
17
  "user_id": {"type": String, "nullable": True},
18
- "session_data": {"type": JSON, "nullable": True},
19
- "agent_data": {"type": JSON, "nullable": True},
20
- "team_data": {"type": JSON, "nullable": True},
21
- "workflow_data": {"type": JSON, "nullable": True},
22
- "metadata": {"type": JSON, "nullable": True},
23
- "runs": {"type": JSON, "nullable": True},
24
- "summary": {"type": JSON, "nullable": True},
18
+ "session_data": {"type": JSONB, "nullable": True},
19
+ "agent_data": {"type": JSONB, "nullable": True},
20
+ "team_data": {"type": JSONB, "nullable": True},
21
+ "workflow_data": {"type": JSONB, "nullable": True},
22
+ "metadata": {"type": JSONB, "nullable": True},
23
+ "runs": {"type": JSONB, "nullable": True},
24
+ "summary": {"type": JSONB, "nullable": True},
25
25
  "created_at": {"type": BigInteger, "nullable": False, "index": True},
26
26
  "updated_at": {"type": BigInteger, "nullable": True},
27
27
  "_unique_constraints": [
@@ -34,20 +34,22 @@ SESSION_TABLE_SCHEMA = {
34
34
 
35
35
  MEMORY_TABLE_SCHEMA = {
36
36
  "memory_id": {"type": String, "primary_key": True, "nullable": False},
37
- "memory": {"type": JSON, "nullable": False},
38
- "input": {"type": String, "nullable": True},
37
+ "memory": {"type": JSONB, "nullable": False},
38
+ "feedback": {"type": Text, "nullable": True},
39
+ "input": {"type": Text, "nullable": True},
39
40
  "agent_id": {"type": String, "nullable": True},
40
41
  "team_id": {"type": String, "nullable": True},
41
42
  "user_id": {"type": String, "nullable": True, "index": True},
42
- "topics": {"type": JSON, "nullable": True},
43
+ "topics": {"type": JSONB, "nullable": True},
44
+ "created_at": {"type": BigInteger, "nullable": False, "index": True},
43
45
  "updated_at": {"type": BigInteger, "nullable": True, "index": True},
44
46
  }
45
47
 
46
48
  EVAL_TABLE_SCHEMA = {
47
49
  "run_id": {"type": String, "primary_key": True, "nullable": False},
48
50
  "eval_type": {"type": String, "nullable": False},
49
- "eval_data": {"type": JSON, "nullable": False},
50
- "eval_input": {"type": JSON, "nullable": False},
51
+ "eval_data": {"type": JSONB, "nullable": False},
52
+ "eval_input": {"type": JSONB, "nullable": False},
51
53
  "name": {"type": String, "nullable": True},
52
54
  "agent_id": {"type": String, "nullable": True},
53
55
  "team_id": {"type": String, "nullable": True},
@@ -62,14 +64,14 @@ EVAL_TABLE_SCHEMA = {
62
64
  KNOWLEDGE_TABLE_SCHEMA = {
63
65
  "id": {"type": String, "primary_key": True, "nullable": False},
64
66
  "name": {"type": String, "nullable": False},
65
- "description": {"type": String, "nullable": False},
66
- "metadata": {"type": JSON, "nullable": True},
67
+ "description": {"type": Text, "nullable": False},
68
+ "metadata": {"type": JSONB, "nullable": True},
67
69
  "type": {"type": String, "nullable": True},
68
70
  "size": {"type": BigInteger, "nullable": True},
69
71
  "linked_to": {"type": String, "nullable": True},
70
72
  "access_count": {"type": BigInteger, "nullable": True},
71
73
  "status": {"type": String, "nullable": True},
72
- "status_message": {"type": String, "nullable": True},
74
+ "status_message": {"type": Text, "nullable": True},
73
75
  "created_at": {"type": BigInteger, "nullable": True},
74
76
  "updated_at": {"type": BigInteger, "nullable": True},
75
77
  "external_id": {"type": String, "nullable": True},
@@ -84,8 +86,8 @@ METRICS_TABLE_SCHEMA = {
84
86
  "team_sessions_count": {"type": BigInteger, "nullable": False, "default": 0},
85
87
  "workflow_sessions_count": {"type": BigInteger, "nullable": False, "default": 0},
86
88
  "users_count": {"type": BigInteger, "nullable": False, "default": 0},
87
- "token_metrics": {"type": JSON, "nullable": False, "default": {}},
88
- "model_metrics": {"type": JSON, "nullable": False, "default": {}},
89
+ "token_metrics": {"type": JSONB, "nullable": False, "default": {}},
90
+ "model_metrics": {"type": JSONB, "nullable": False, "default": {}},
89
91
  "date": {"type": Date, "nullable": False, "index": True},
90
92
  "aggregation_period": {"type": String, "nullable": False},
91
93
  "created_at": {"type": BigInteger, "nullable": False},
@@ -102,27 +104,151 @@ METRICS_TABLE_SCHEMA = {
102
104
  CULTURAL_KNOWLEDGE_TABLE_SCHEMA = {
103
105
  "id": {"type": String, "primary_key": True, "nullable": False},
104
106
  "name": {"type": String, "nullable": False, "index": True},
105
- "summary": {"type": String, "nullable": True},
107
+ "summary": {"type": Text, "nullable": True},
106
108
  "content": {"type": JSONB, "nullable": True},
107
109
  "metadata": {"type": JSONB, "nullable": True},
108
- "input": {"type": String, "nullable": True},
110
+ "input": {"type": Text, "nullable": True},
109
111
  "created_at": {"type": BigInteger, "nullable": True},
110
112
  "updated_at": {"type": BigInteger, "nullable": True},
111
113
  "agent_id": {"type": String, "nullable": True},
112
114
  "team_id": {"type": String, "nullable": True},
113
115
  }
114
116
 
117
+ VERSIONS_TABLE_SCHEMA = {
118
+ "table_name": {"type": String, "nullable": False, "primary_key": True},
119
+ "version": {"type": String, "nullable": False},
120
+ "created_at": {"type": String, "nullable": False, "index": True},
121
+ "updated_at": {"type": String, "nullable": True},
122
+ }
123
+
124
+ TRACE_TABLE_SCHEMA = {
125
+ "trace_id": {"type": String, "primary_key": True, "nullable": False},
126
+ "name": {"type": String, "nullable": False},
127
+ "status": {"type": String, "nullable": False, "index": True},
128
+ "start_time": {"type": String, "nullable": False, "index": True}, # ISO 8601 datetime string
129
+ "end_time": {"type": String, "nullable": False}, # ISO 8601 datetime string
130
+ "duration_ms": {"type": BigInteger, "nullable": False},
131
+ "run_id": {"type": String, "nullable": True, "index": True},
132
+ "session_id": {"type": String, "nullable": True, "index": True},
133
+ "user_id": {"type": String, "nullable": True, "index": True},
134
+ "agent_id": {"type": String, "nullable": True, "index": True},
135
+ "team_id": {"type": String, "nullable": True, "index": True},
136
+ "workflow_id": {"type": String, "nullable": True, "index": True},
137
+ "created_at": {"type": String, "nullable": False, "index": True}, # ISO 8601 datetime string
138
+ }
139
+
140
+
141
+ def _get_span_table_schema(traces_table_name: str = "agno_traces", db_schema: str = "agno") -> dict[str, Any]:
142
+ """Get the span table schema with the correct foreign key reference.
143
+
144
+ Args:
145
+ traces_table_name: The name of the traces table to reference in the foreign key.
146
+ db_schema: The database schema name.
147
+
148
+ Returns:
149
+ The span table schema dictionary.
150
+ """
151
+ return {
152
+ "span_id": {"type": String, "primary_key": True, "nullable": False},
153
+ "trace_id": {
154
+ "type": String,
155
+ "nullable": False,
156
+ "index": True,
157
+ "foreign_key": f"{db_schema}.{traces_table_name}.trace_id",
158
+ },
159
+ "parent_span_id": {"type": String, "nullable": True, "index": True},
160
+ "name": {"type": String, "nullable": False},
161
+ "span_kind": {"type": String, "nullable": False},
162
+ "status_code": {"type": String, "nullable": False},
163
+ "status_message": {"type": Text, "nullable": True},
164
+ "start_time": {"type": String, "nullable": False, "index": True}, # ISO 8601 datetime string
165
+ "end_time": {"type": String, "nullable": False}, # ISO 8601 datetime string
166
+ "duration_ms": {"type": BigInteger, "nullable": False},
167
+ "attributes": {"type": JSONB, "nullable": True},
168
+ "created_at": {"type": String, "nullable": False, "index": True}, # ISO 8601 datetime string
169
+ }
170
+
171
+
172
+ COMPONENT_TABLE_SCHEMA = {
173
+ "component_id": {"type": String, "primary_key": True},
174
+ "component_type": {"type": String, "nullable": False, "index": True}, # agent|team|workflow
175
+ "name": {"type": String, "nullable": True, "index": True},
176
+ "description": {"type": Text, "nullable": True},
177
+ "current_version": {"type": Integer, "nullable": True, "index": True},
178
+ "metadata": {"type": JSONB, "nullable": True},
179
+ "created_at": {"type": BigInteger, "nullable": False, "index": True},
180
+ "updated_at": {"type": BigInteger, "nullable": True},
181
+ "deleted_at": {"type": BigInteger, "nullable": True},
182
+ }
183
+
184
+ COMPONENT_CONFIGS_TABLE_SCHEMA = {
185
+ "component_id": {"type": String, "primary_key": True, "foreign_key": "components.component_id"},
186
+ "version": {"type": Integer, "primary_key": True},
187
+ "label": {"type": String, "nullable": True}, # stable|v1.2.0|pre-refactor
188
+ "stage": {"type": String, "nullable": False, "default": "draft", "index": True}, # draft|published
189
+ "config": {"type": JSONB, "nullable": False},
190
+ "notes": {"type": Text, "nullable": True},
191
+ "created_at": {"type": BigInteger, "nullable": False, "index": True},
192
+ "updated_at": {"type": BigInteger, "nullable": True},
193
+ "deleted_at": {"type": BigInteger, "nullable": True},
194
+ }
195
+
196
+ COMPONENT_LINKS_TABLE_SCHEMA = {
197
+ "parent_component_id": {"type": String, "nullable": False},
198
+ "parent_version": {"type": Integer, "nullable": False},
199
+ "link_kind": {"type": String, "nullable": False, "index": True},
200
+ "link_key": {"type": String, "nullable": False},
201
+ "child_component_id": {"type": String, "nullable": False, "foreign_key": "components.component_id"},
202
+ "child_version": {"type": Integer, "nullable": True},
203
+ "position": {"type": Integer, "nullable": False},
204
+ "meta": {"type": JSONB, "nullable": True},
205
+ "created_at": {"type": BigInteger, "nullable": True, "index": True},
206
+ "updated_at": {"type": BigInteger, "nullable": True},
207
+ "__primary_key__": ["parent_component_id", "parent_version", "link_kind", "link_key"],
208
+ "__foreign_keys__": [
209
+ {
210
+ "columns": ["parent_component_id", "parent_version"],
211
+ "ref_table": "component_configs",
212
+ "ref_columns": ["component_id", "version"],
213
+ }
214
+ ],
215
+ }
216
+ LEARNINGS_TABLE_SCHEMA = {
217
+ "learning_id": {"type": String, "primary_key": True, "nullable": False},
218
+ "learning_type": {"type": String, "nullable": False, "index": True},
219
+ "namespace": {"type": String, "nullable": True, "index": True},
220
+ "user_id": {"type": String, "nullable": True, "index": True},
221
+ "agent_id": {"type": String, "nullable": True, "index": True},
222
+ "team_id": {"type": String, "nullable": True, "index": True},
223
+ "workflow_id": {"type": String, "nullable": True, "index": True},
224
+ "session_id": {"type": String, "nullable": True, "index": True},
225
+ "entity_id": {"type": String, "nullable": True, "index": True},
226
+ "entity_type": {"type": String, "nullable": True, "index": True},
227
+ "content": {"type": JSONB, "nullable": False},
228
+ "metadata": {"type": JSONB, "nullable": True},
229
+ "created_at": {"type": BigInteger, "nullable": False, "index": True},
230
+ "updated_at": {"type": BigInteger, "nullable": True},
231
+ }
232
+
115
233
 
116
- def get_table_schema_definition(table_type: str) -> dict[str, Any]:
234
+ def get_table_schema_definition(
235
+ table_type: str, traces_table_name: str = "agno_traces", db_schema: str = "agno"
236
+ ) -> dict[str, Any]:
117
237
  """
118
238
  Get the expected schema definition for the given table.
119
239
 
120
240
  Args:
121
241
  table_type (str): The type of table to get the schema for.
242
+ traces_table_name (str): The name of the traces table (used for spans foreign key).
243
+ db_schema (str): The database schema name (used for spans foreign key).
122
244
 
123
245
  Returns:
124
246
  Dict[str, Any]: Dictionary containing column definitions for the table
125
247
  """
248
+ # Handle spans table specially to resolve the foreign key reference
249
+ if table_type == "spans":
250
+ return _get_span_table_schema(traces_table_name, db_schema)
251
+
126
252
  schemas = {
127
253
  "sessions": SESSION_TABLE_SCHEMA,
128
254
  "evals": EVAL_TABLE_SCHEMA,
@@ -130,6 +256,12 @@ def get_table_schema_definition(table_type: str) -> dict[str, Any]:
130
256
  "memories": MEMORY_TABLE_SCHEMA,
131
257
  "knowledge": KNOWLEDGE_TABLE_SCHEMA,
132
258
  "culture": CULTURAL_KNOWLEDGE_TABLE_SCHEMA,
259
+ "versions": VERSIONS_TABLE_SCHEMA,
260
+ "traces": TRACE_TABLE_SCHEMA,
261
+ "components": COMPONENT_TABLE_SCHEMA,
262
+ "component_configs": COMPONENT_CONFIGS_TABLE_SCHEMA,
263
+ "component_links": COMPONENT_LINKS_TABLE_SCHEMA,
264
+ "learnings": LEARNINGS_TABLE_SCHEMA,
133
265
  }
134
266
 
135
267
  schema = schemas.get(table_type, {})
agno/db/postgres/utils.py CHANGED
@@ -13,8 +13,9 @@ from agno.db.schemas.culture import CulturalKnowledge
13
13
  from agno.utils.log import log_debug, log_error, log_warning
14
14
 
15
15
  try:
16
- from sqlalchemy import Table
16
+ from sqlalchemy import Table, func
17
17
  from sqlalchemy.dialects import postgresql
18
+ from sqlalchemy.exc import NoSuchTableError
18
19
  from sqlalchemy.inspection import inspect
19
20
  from sqlalchemy.orm import Session
20
21
  from sqlalchemy.sql.expression import text
@@ -34,6 +35,11 @@ def apply_sorting(stmt, table: Table, sort_by: Optional[str] = None, sort_order:
34
35
 
35
36
  Returns:
36
37
  The modified statement with sorting applied
38
+
39
+ Note:
40
+ For 'updated_at' sorting, uses COALESCE(updated_at, created_at) to fall back
41
+ to created_at when updated_at is NULL. This ensures pre-2.0 records (which may
42
+ have NULL updated_at) are sorted correctly by their creation time.
37
43
  """
38
44
  if sort_by is None:
39
45
  return stmt
@@ -42,8 +48,13 @@ def apply_sorting(stmt, table: Table, sort_by: Optional[str] = None, sort_order:
42
48
  log_debug(f"Invalid sort field: '{sort_by}'. Will not apply any sorting.")
43
49
  return stmt
44
50
 
45
- # Apply the given sorting
46
- sort_column = getattr(table.c, sort_by)
51
+ # For updated_at, use COALESCE to fall back to created_at if updated_at is NULL
52
+ # This handles pre-2.0 records that may have NULL updated_at values
53
+ if sort_by == "updated_at" and hasattr(table.c, "created_at"):
54
+ sort_column = func.coalesce(table.c.updated_at, table.c.created_at)
55
+ else:
56
+ sort_column = getattr(table.c, sort_by)
57
+
47
58
  if sort_order and sort_order == "asc":
48
59
  return stmt.order_by(sort_column.asc())
49
60
  else:
@@ -173,6 +184,9 @@ async def ais_valid_table(db_engine: AsyncEngine, table_name: str, table_type: s
173
184
  return False
174
185
 
175
186
  return True
187
+ except NoSuchTableError:
188
+ log_error(f"Table {db_schema}.{table_name} does not exist")
189
+ return False
176
190
  except Exception as e:
177
191
  log_error(f"Error validating table schema for {db_schema}.{table_name}: {e}")
178
192
  return False
@@ -298,16 +312,17 @@ def calculate_date_metrics(date_to_process: date, sessions_data: dict) -> dict:
298
312
  for session in sessions:
299
313
  if session.get("user_id"):
300
314
  all_user_ids.add(session["user_id"])
301
- metrics[runs_count_key] += len(session.get("runs", []))
302
- if runs := session.get("runs", []):
315
+ runs = session.get("runs", []) or []
316
+ metrics[runs_count_key] += len(runs)
317
+ if runs:
303
318
  for run in runs:
304
319
  if model_id := run.get("model"):
305
320
  model_provider = run.get("model_provider", "")
306
321
  model_counts[f"{model_id}:{model_provider}"] = (
307
322
  model_counts.get(f"{model_id}:{model_provider}", 0) + 1
308
323
  )
309
-
310
- session_metrics = session.get("session_data", {}).get("session_metrics", {})
324
+ session_data = session.get("session_data", {}) or {}
325
+ session_metrics = session_data.get("session_metrics", {}) or {}
311
326
  for field in token_metrics:
312
327
  token_metrics[field] += session_metrics.get(field, 0)
313
328