agno 1.8.1__py3-none-any.whl → 2.0.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (580) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +2778 -4123
  4. agno/api/agent.py +9 -65
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +6 -17
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -41
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +5 -21
  11. agno/api/schemas/evals.py +7 -16
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +5 -21
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +11 -7
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +9 -64
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/db/__init__.py +24 -0
  25. agno/db/base.py +245 -0
  26. agno/db/dynamo/__init__.py +3 -0
  27. agno/db/dynamo/dynamo.py +1749 -0
  28. agno/db/dynamo/schemas.py +278 -0
  29. agno/db/dynamo/utils.py +684 -0
  30. agno/db/firestore/__init__.py +3 -0
  31. agno/db/firestore/firestore.py +1438 -0
  32. agno/db/firestore/schemas.py +130 -0
  33. agno/db/firestore/utils.py +278 -0
  34. agno/db/gcs_json/__init__.py +3 -0
  35. agno/db/gcs_json/gcs_json_db.py +1001 -0
  36. agno/db/gcs_json/utils.py +194 -0
  37. agno/db/in_memory/__init__.py +3 -0
  38. agno/db/in_memory/in_memory_db.py +888 -0
  39. agno/db/in_memory/utils.py +172 -0
  40. agno/db/json/__init__.py +3 -0
  41. agno/db/json/json_db.py +1051 -0
  42. agno/db/json/utils.py +196 -0
  43. agno/db/migrations/v1_to_v2.py +162 -0
  44. agno/db/mongo/__init__.py +3 -0
  45. agno/db/mongo/mongo.py +1417 -0
  46. agno/db/mongo/schemas.py +77 -0
  47. agno/db/mongo/utils.py +204 -0
  48. agno/db/mysql/__init__.py +3 -0
  49. agno/db/mysql/mysql.py +1719 -0
  50. agno/db/mysql/schemas.py +124 -0
  51. agno/db/mysql/utils.py +298 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1720 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +281 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1371 -0
  58. agno/db/redis/schemas.py +109 -0
  59. agno/db/redis/utils.py +288 -0
  60. agno/db/schemas/__init__.py +3 -0
  61. agno/db/schemas/evals.py +33 -0
  62. agno/db/schemas/knowledge.py +40 -0
  63. agno/db/schemas/memory.py +46 -0
  64. agno/db/singlestore/__init__.py +3 -0
  65. agno/db/singlestore/schemas.py +116 -0
  66. agno/db/singlestore/singlestore.py +1722 -0
  67. agno/db/singlestore/utils.py +327 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1680 -0
  71. agno/db/sqlite/utils.py +269 -0
  72. agno/db/utils.py +88 -0
  73. agno/eval/__init__.py +14 -0
  74. agno/eval/accuracy.py +142 -43
  75. agno/eval/performance.py +88 -23
  76. agno/eval/reliability.py +73 -20
  77. agno/eval/utils.py +23 -13
  78. agno/integrations/discord/__init__.py +3 -0
  79. agno/{app → integrations}/discord/client.py +10 -10
  80. agno/knowledge/__init__.py +2 -2
  81. agno/{document → knowledge}/chunking/agentic.py +2 -2
  82. agno/{document → knowledge}/chunking/document.py +2 -2
  83. agno/{document → knowledge}/chunking/fixed.py +3 -3
  84. agno/{document → knowledge}/chunking/markdown.py +2 -2
  85. agno/{document → knowledge}/chunking/recursive.py +2 -2
  86. agno/{document → knowledge}/chunking/row.py +2 -2
  87. agno/knowledge/chunking/semantic.py +59 -0
  88. agno/knowledge/chunking/strategy.py +121 -0
  89. agno/knowledge/content.py +74 -0
  90. agno/knowledge/document/__init__.py +5 -0
  91. agno/{document → knowledge/document}/base.py +12 -2
  92. agno/knowledge/embedder/__init__.py +5 -0
  93. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  94. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  95. agno/{embedder → knowledge/embedder}/base.py +6 -0
  96. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  97. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  98. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  99. agno/{embedder → knowledge/embedder}/google.py +74 -1
  100. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  101. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  102. agno/knowledge/embedder/langdb.py +22 -0
  103. agno/knowledge/embedder/mistral.py +139 -0
  104. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  105. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  106. agno/knowledge/embedder/openai.py +223 -0
  107. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  108. agno/{embedder → knowledge/embedder}/together.py +1 -1
  109. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  110. agno/knowledge/knowledge.py +1515 -0
  111. agno/knowledge/reader/__init__.py +7 -0
  112. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  113. agno/knowledge/reader/base.py +88 -0
  114. agno/{document → knowledge}/reader/csv_reader.py +68 -15
  115. agno/knowledge/reader/docx_reader.py +83 -0
  116. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  117. agno/knowledge/reader/gcs_reader.py +67 -0
  118. agno/{document → knowledge}/reader/json_reader.py +30 -9
  119. agno/{document → knowledge}/reader/markdown_reader.py +36 -9
  120. agno/{document → knowledge}/reader/pdf_reader.py +79 -21
  121. agno/knowledge/reader/reader_factory.py +275 -0
  122. agno/knowledge/reader/s3_reader.py +171 -0
  123. agno/{document → knowledge}/reader/text_reader.py +31 -10
  124. agno/knowledge/reader/url_reader.py +84 -0
  125. agno/knowledge/reader/web_search_reader.py +389 -0
  126. agno/{document → knowledge}/reader/website_reader.py +37 -10
  127. agno/knowledge/reader/wikipedia_reader.py +59 -0
  128. agno/knowledge/reader/youtube_reader.py +78 -0
  129. agno/knowledge/remote_content/remote_content.py +88 -0
  130. agno/{reranker → knowledge/reranker}/base.py +1 -1
  131. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  132. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  133. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  134. agno/knowledge/types.py +30 -0
  135. agno/knowledge/utils.py +169 -0
  136. agno/memory/__init__.py +2 -10
  137. agno/memory/manager.py +1003 -148
  138. agno/models/aimlapi/__init__.py +2 -2
  139. agno/models/aimlapi/aimlapi.py +6 -6
  140. agno/models/anthropic/claude.py +129 -82
  141. agno/models/aws/bedrock.py +107 -175
  142. agno/models/aws/claude.py +64 -18
  143. agno/models/azure/ai_foundry.py +73 -23
  144. agno/models/base.py +347 -287
  145. agno/models/cerebras/cerebras.py +84 -27
  146. agno/models/cohere/chat.py +106 -98
  147. agno/models/google/gemini.py +100 -42
  148. agno/models/groq/groq.py +97 -35
  149. agno/models/huggingface/huggingface.py +92 -27
  150. agno/models/ibm/watsonx.py +72 -13
  151. agno/models/litellm/chat.py +85 -13
  152. agno/models/message.py +38 -144
  153. agno/models/meta/llama.py +85 -49
  154. agno/models/metrics.py +120 -0
  155. agno/models/mistral/mistral.py +90 -21
  156. agno/models/ollama/__init__.py +0 -2
  157. agno/models/ollama/chat.py +84 -46
  158. agno/models/openai/chat.py +121 -23
  159. agno/models/openai/responses.py +178 -105
  160. agno/models/perplexity/perplexity.py +26 -2
  161. agno/models/portkey/portkey.py +0 -7
  162. agno/models/response.py +14 -8
  163. agno/models/utils.py +20 -0
  164. agno/models/vercel/__init__.py +2 -2
  165. agno/models/vercel/v0.py +1 -1
  166. agno/models/vllm/__init__.py +2 -2
  167. agno/models/vllm/vllm.py +3 -3
  168. agno/models/xai/xai.py +10 -10
  169. agno/os/__init__.py +3 -0
  170. agno/os/app.py +393 -0
  171. agno/os/auth.py +47 -0
  172. agno/os/config.py +103 -0
  173. agno/os/interfaces/agui/__init__.py +3 -0
  174. agno/os/interfaces/agui/agui.py +31 -0
  175. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  176. agno/{app → os/interfaces}/agui/utils.py +65 -28
  177. agno/os/interfaces/base.py +21 -0
  178. agno/os/interfaces/slack/__init__.py +3 -0
  179. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  180. agno/os/interfaces/slack/slack.py +33 -0
  181. agno/os/interfaces/whatsapp/__init__.py +3 -0
  182. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  183. agno/os/interfaces/whatsapp/whatsapp.py +30 -0
  184. agno/os/router.py +843 -0
  185. agno/os/routers/__init__.py +3 -0
  186. agno/os/routers/evals/__init__.py +3 -0
  187. agno/os/routers/evals/evals.py +204 -0
  188. agno/os/routers/evals/schemas.py +142 -0
  189. agno/os/routers/evals/utils.py +161 -0
  190. agno/os/routers/knowledge/__init__.py +3 -0
  191. agno/os/routers/knowledge/knowledge.py +413 -0
  192. agno/os/routers/knowledge/schemas.py +118 -0
  193. agno/os/routers/memory/__init__.py +3 -0
  194. agno/os/routers/memory/memory.py +179 -0
  195. agno/os/routers/memory/schemas.py +58 -0
  196. agno/os/routers/metrics/__init__.py +3 -0
  197. agno/os/routers/metrics/metrics.py +58 -0
  198. agno/os/routers/metrics/schemas.py +47 -0
  199. agno/os/routers/session/__init__.py +3 -0
  200. agno/os/routers/session/session.py +163 -0
  201. agno/os/schema.py +892 -0
  202. agno/{app/playground → os}/settings.py +8 -15
  203. agno/os/utils.py +270 -0
  204. agno/reasoning/azure_ai_foundry.py +4 -4
  205. agno/reasoning/deepseek.py +4 -4
  206. agno/reasoning/default.py +6 -11
  207. agno/reasoning/groq.py +4 -4
  208. agno/reasoning/helpers.py +4 -6
  209. agno/reasoning/ollama.py +4 -4
  210. agno/reasoning/openai.py +4 -4
  211. agno/run/{response.py → agent.py} +144 -72
  212. agno/run/base.py +44 -58
  213. agno/run/cancel.py +83 -0
  214. agno/run/team.py +133 -77
  215. agno/run/workflow.py +537 -12
  216. agno/session/__init__.py +10 -0
  217. agno/session/agent.py +244 -0
  218. agno/session/summary.py +225 -0
  219. agno/session/team.py +262 -0
  220. agno/{storage/session/v2 → session}/workflow.py +47 -24
  221. agno/team/__init__.py +15 -16
  222. agno/team/team.py +2961 -4253
  223. agno/tools/agentql.py +14 -5
  224. agno/tools/airflow.py +9 -4
  225. agno/tools/api.py +7 -3
  226. agno/tools/apify.py +2 -46
  227. agno/tools/arxiv.py +8 -3
  228. agno/tools/aws_lambda.py +7 -5
  229. agno/tools/aws_ses.py +7 -1
  230. agno/tools/baidusearch.py +4 -1
  231. agno/tools/bitbucket.py +4 -4
  232. agno/tools/brandfetch.py +14 -11
  233. agno/tools/bravesearch.py +4 -1
  234. agno/tools/brightdata.py +42 -22
  235. agno/tools/browserbase.py +13 -4
  236. agno/tools/calcom.py +12 -10
  237. agno/tools/calculator.py +10 -27
  238. agno/tools/cartesia.py +18 -13
  239. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  240. agno/tools/confluence.py +8 -8
  241. agno/tools/crawl4ai.py +7 -1
  242. agno/tools/csv_toolkit.py +9 -8
  243. agno/tools/dalle.py +18 -11
  244. agno/tools/daytona.py +13 -16
  245. agno/tools/decorator.py +6 -3
  246. agno/tools/desi_vocal.py +16 -7
  247. agno/tools/discord.py +11 -8
  248. agno/tools/docker.py +30 -42
  249. agno/tools/duckdb.py +34 -53
  250. agno/tools/duckduckgo.py +8 -7
  251. agno/tools/e2b.py +61 -61
  252. agno/tools/eleven_labs.py +35 -28
  253. agno/tools/email.py +4 -1
  254. agno/tools/evm.py +7 -1
  255. agno/tools/exa.py +19 -14
  256. agno/tools/fal.py +29 -29
  257. agno/tools/file.py +9 -8
  258. agno/tools/financial_datasets.py +25 -44
  259. agno/tools/firecrawl.py +22 -22
  260. agno/tools/function.py +68 -17
  261. agno/tools/giphy.py +22 -10
  262. agno/tools/github.py +48 -126
  263. agno/tools/gmail.py +45 -61
  264. agno/tools/google_bigquery.py +7 -6
  265. agno/tools/google_maps.py +11 -26
  266. agno/tools/googlesearch.py +7 -2
  267. agno/tools/googlesheets.py +21 -17
  268. agno/tools/hackernews.py +9 -5
  269. agno/tools/jina.py +5 -4
  270. agno/tools/jira.py +18 -9
  271. agno/tools/knowledge.py +31 -32
  272. agno/tools/linear.py +18 -33
  273. agno/tools/linkup.py +5 -1
  274. agno/tools/local_file_system.py +8 -5
  275. agno/tools/lumalab.py +31 -19
  276. agno/tools/mem0.py +18 -12
  277. agno/tools/memori.py +14 -10
  278. agno/tools/mlx_transcribe.py +3 -2
  279. agno/tools/models/azure_openai.py +32 -14
  280. agno/tools/models/gemini.py +58 -31
  281. agno/tools/models/groq.py +29 -20
  282. agno/tools/models/nebius.py +27 -11
  283. agno/tools/models_labs.py +39 -15
  284. agno/tools/moviepy_video.py +7 -6
  285. agno/tools/neo4j.py +10 -8
  286. agno/tools/newspaper.py +7 -2
  287. agno/tools/newspaper4k.py +8 -3
  288. agno/tools/openai.py +57 -26
  289. agno/tools/openbb.py +12 -11
  290. agno/tools/opencv.py +62 -46
  291. agno/tools/openweather.py +14 -12
  292. agno/tools/pandas.py +11 -3
  293. agno/tools/postgres.py +4 -12
  294. agno/tools/pubmed.py +4 -1
  295. agno/tools/python.py +9 -22
  296. agno/tools/reasoning.py +35 -27
  297. agno/tools/reddit.py +11 -26
  298. agno/tools/replicate.py +54 -41
  299. agno/tools/resend.py +4 -1
  300. agno/tools/scrapegraph.py +15 -14
  301. agno/tools/searxng.py +10 -23
  302. agno/tools/serpapi.py +6 -3
  303. agno/tools/serper.py +13 -4
  304. agno/tools/shell.py +9 -2
  305. agno/tools/slack.py +12 -11
  306. agno/tools/sleep.py +3 -2
  307. agno/tools/spider.py +24 -4
  308. agno/tools/sql.py +7 -6
  309. agno/tools/tavily.py +6 -4
  310. agno/tools/telegram.py +12 -4
  311. agno/tools/todoist.py +11 -31
  312. agno/tools/toolkit.py +1 -1
  313. agno/tools/trafilatura.py +22 -6
  314. agno/tools/trello.py +9 -22
  315. agno/tools/twilio.py +10 -3
  316. agno/tools/user_control_flow.py +6 -1
  317. agno/tools/valyu.py +34 -5
  318. agno/tools/visualization.py +19 -28
  319. agno/tools/webbrowser.py +4 -3
  320. agno/tools/webex.py +11 -7
  321. agno/tools/website.py +15 -46
  322. agno/tools/webtools.py +12 -4
  323. agno/tools/whatsapp.py +5 -9
  324. agno/tools/wikipedia.py +20 -13
  325. agno/tools/x.py +14 -13
  326. agno/tools/yfinance.py +13 -40
  327. agno/tools/youtube.py +26 -20
  328. agno/tools/zendesk.py +7 -2
  329. agno/tools/zep.py +10 -7
  330. agno/tools/zoom.py +10 -9
  331. agno/utils/common.py +1 -19
  332. agno/utils/events.py +95 -118
  333. agno/utils/knowledge.py +29 -0
  334. agno/utils/log.py +2 -2
  335. agno/utils/mcp.py +11 -5
  336. agno/utils/media.py +39 -0
  337. agno/utils/message.py +12 -1
  338. agno/utils/models/claude.py +6 -4
  339. agno/utils/models/mistral.py +8 -7
  340. agno/utils/models/schema_utils.py +3 -3
  341. agno/utils/pprint.py +33 -32
  342. agno/utils/print_response/agent.py +779 -0
  343. agno/utils/print_response/team.py +1565 -0
  344. agno/utils/print_response/workflow.py +1451 -0
  345. agno/utils/prompts.py +14 -14
  346. agno/utils/reasoning.py +87 -0
  347. agno/utils/response.py +42 -42
  348. agno/utils/string.py +8 -22
  349. agno/utils/team.py +50 -0
  350. agno/utils/timer.py +2 -2
  351. agno/vectordb/base.py +33 -21
  352. agno/vectordb/cassandra/cassandra.py +287 -23
  353. agno/vectordb/chroma/chromadb.py +482 -59
  354. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  355. agno/vectordb/couchbase/couchbase.py +309 -29
  356. agno/vectordb/lancedb/lance_db.py +360 -21
  357. agno/vectordb/langchaindb/__init__.py +5 -0
  358. agno/vectordb/langchaindb/langchaindb.py +145 -0
  359. agno/vectordb/lightrag/__init__.py +5 -0
  360. agno/vectordb/lightrag/lightrag.py +374 -0
  361. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  362. agno/vectordb/milvus/milvus.py +242 -32
  363. agno/vectordb/mongodb/mongodb.py +200 -24
  364. agno/vectordb/pgvector/pgvector.py +319 -37
  365. agno/vectordb/pineconedb/pineconedb.py +221 -27
  366. agno/vectordb/qdrant/qdrant.py +334 -14
  367. agno/vectordb/singlestore/singlestore.py +286 -29
  368. agno/vectordb/surrealdb/surrealdb.py +187 -7
  369. agno/vectordb/upstashdb/upstashdb.py +342 -26
  370. agno/vectordb/weaviate/weaviate.py +227 -165
  371. agno/workflow/__init__.py +17 -13
  372. agno/workflow/{v2/condition.py → condition.py} +135 -32
  373. agno/workflow/{v2/loop.py → loop.py} +115 -28
  374. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  375. agno/workflow/{v2/router.py → router.py} +133 -32
  376. agno/workflow/{v2/step.py → step.py} +200 -42
  377. agno/workflow/{v2/steps.py → steps.py} +147 -66
  378. agno/workflow/types.py +482 -0
  379. agno/workflow/workflow.py +2394 -696
  380. agno-2.0.0a1.dist-info/METADATA +355 -0
  381. agno-2.0.0a1.dist-info/RECORD +514 -0
  382. agno/agent/metrics.py +0 -107
  383. agno/api/app.py +0 -35
  384. agno/api/playground.py +0 -92
  385. agno/api/schemas/app.py +0 -12
  386. agno/api/schemas/playground.py +0 -22
  387. agno/api/schemas/user.py +0 -35
  388. agno/api/schemas/workspace.py +0 -46
  389. agno/api/user.py +0 -160
  390. agno/api/workflows.py +0 -33
  391. agno/api/workspace.py +0 -175
  392. agno/app/agui/__init__.py +0 -3
  393. agno/app/agui/app.py +0 -17
  394. agno/app/agui/sync_router.py +0 -120
  395. agno/app/base.py +0 -186
  396. agno/app/discord/__init__.py +0 -3
  397. agno/app/fastapi/__init__.py +0 -3
  398. agno/app/fastapi/app.py +0 -107
  399. agno/app/fastapi/async_router.py +0 -457
  400. agno/app/fastapi/sync_router.py +0 -448
  401. agno/app/playground/app.py +0 -228
  402. agno/app/playground/async_router.py +0 -1050
  403. agno/app/playground/deploy.py +0 -249
  404. agno/app/playground/operator.py +0 -183
  405. agno/app/playground/schemas.py +0 -220
  406. agno/app/playground/serve.py +0 -55
  407. agno/app/playground/sync_router.py +0 -1042
  408. agno/app/playground/utils.py +0 -46
  409. agno/app/settings.py +0 -15
  410. agno/app/slack/__init__.py +0 -3
  411. agno/app/slack/app.py +0 -19
  412. agno/app/slack/sync_router.py +0 -92
  413. agno/app/utils.py +0 -54
  414. agno/app/whatsapp/__init__.py +0 -3
  415. agno/app/whatsapp/app.py +0 -15
  416. agno/app/whatsapp/sync_router.py +0 -197
  417. agno/cli/auth_server.py +0 -249
  418. agno/cli/config.py +0 -274
  419. agno/cli/console.py +0 -88
  420. agno/cli/credentials.py +0 -23
  421. agno/cli/entrypoint.py +0 -571
  422. agno/cli/operator.py +0 -357
  423. agno/cli/settings.py +0 -96
  424. agno/cli/ws/ws_cli.py +0 -817
  425. agno/constants.py +0 -13
  426. agno/document/__init__.py +0 -5
  427. agno/document/chunking/semantic.py +0 -45
  428. agno/document/chunking/strategy.py +0 -31
  429. agno/document/reader/__init__.py +0 -5
  430. agno/document/reader/base.py +0 -47
  431. agno/document/reader/docx_reader.py +0 -60
  432. agno/document/reader/gcs/pdf_reader.py +0 -44
  433. agno/document/reader/s3/pdf_reader.py +0 -59
  434. agno/document/reader/s3/text_reader.py +0 -63
  435. agno/document/reader/url_reader.py +0 -59
  436. agno/document/reader/youtube_reader.py +0 -58
  437. agno/embedder/__init__.py +0 -5
  438. agno/embedder/langdb.py +0 -80
  439. agno/embedder/mistral.py +0 -82
  440. agno/embedder/openai.py +0 -78
  441. agno/file/__init__.py +0 -5
  442. agno/file/file.py +0 -16
  443. agno/file/local/csv.py +0 -32
  444. agno/file/local/txt.py +0 -19
  445. agno/infra/app.py +0 -240
  446. agno/infra/base.py +0 -144
  447. agno/infra/context.py +0 -20
  448. agno/infra/db_app.py +0 -52
  449. agno/infra/resource.py +0 -205
  450. agno/infra/resources.py +0 -55
  451. agno/knowledge/agent.py +0 -702
  452. agno/knowledge/arxiv.py +0 -33
  453. agno/knowledge/combined.py +0 -36
  454. agno/knowledge/csv.py +0 -144
  455. agno/knowledge/csv_url.py +0 -124
  456. agno/knowledge/document.py +0 -223
  457. agno/knowledge/docx.py +0 -137
  458. agno/knowledge/firecrawl.py +0 -34
  459. agno/knowledge/gcs/__init__.py +0 -0
  460. agno/knowledge/gcs/base.py +0 -39
  461. agno/knowledge/gcs/pdf.py +0 -125
  462. agno/knowledge/json.py +0 -137
  463. agno/knowledge/langchain.py +0 -71
  464. agno/knowledge/light_rag.py +0 -273
  465. agno/knowledge/llamaindex.py +0 -66
  466. agno/knowledge/markdown.py +0 -154
  467. agno/knowledge/pdf.py +0 -164
  468. agno/knowledge/pdf_bytes.py +0 -42
  469. agno/knowledge/pdf_url.py +0 -148
  470. agno/knowledge/s3/__init__.py +0 -0
  471. agno/knowledge/s3/base.py +0 -64
  472. agno/knowledge/s3/pdf.py +0 -33
  473. agno/knowledge/s3/text.py +0 -34
  474. agno/knowledge/text.py +0 -141
  475. agno/knowledge/url.py +0 -46
  476. agno/knowledge/website.py +0 -179
  477. agno/knowledge/wikipedia.py +0 -32
  478. agno/knowledge/youtube.py +0 -35
  479. agno/memory/agent.py +0 -423
  480. agno/memory/classifier.py +0 -104
  481. agno/memory/db/__init__.py +0 -5
  482. agno/memory/db/base.py +0 -42
  483. agno/memory/db/mongodb.py +0 -189
  484. agno/memory/db/postgres.py +0 -203
  485. agno/memory/db/sqlite.py +0 -193
  486. agno/memory/memory.py +0 -22
  487. agno/memory/row.py +0 -36
  488. agno/memory/summarizer.py +0 -201
  489. agno/memory/summary.py +0 -19
  490. agno/memory/team.py +0 -415
  491. agno/memory/v2/__init__.py +0 -2
  492. agno/memory/v2/db/__init__.py +0 -1
  493. agno/memory/v2/db/base.py +0 -42
  494. agno/memory/v2/db/firestore.py +0 -339
  495. agno/memory/v2/db/mongodb.py +0 -196
  496. agno/memory/v2/db/postgres.py +0 -214
  497. agno/memory/v2/db/redis.py +0 -187
  498. agno/memory/v2/db/schema.py +0 -54
  499. agno/memory/v2/db/sqlite.py +0 -209
  500. agno/memory/v2/manager.py +0 -437
  501. agno/memory/v2/memory.py +0 -1097
  502. agno/memory/v2/schema.py +0 -55
  503. agno/memory/v2/summarizer.py +0 -215
  504. agno/memory/workflow.py +0 -38
  505. agno/models/ollama/tools.py +0 -430
  506. agno/models/qwen/__init__.py +0 -5
  507. agno/playground/__init__.py +0 -10
  508. agno/playground/deploy.py +0 -3
  509. agno/playground/playground.py +0 -3
  510. agno/playground/serve.py +0 -3
  511. agno/playground/settings.py +0 -3
  512. agno/reranker/__init__.py +0 -0
  513. agno/run/v2/__init__.py +0 -0
  514. agno/run/v2/workflow.py +0 -567
  515. agno/storage/__init__.py +0 -0
  516. agno/storage/agent/__init__.py +0 -0
  517. agno/storage/agent/dynamodb.py +0 -1
  518. agno/storage/agent/json.py +0 -1
  519. agno/storage/agent/mongodb.py +0 -1
  520. agno/storage/agent/postgres.py +0 -1
  521. agno/storage/agent/singlestore.py +0 -1
  522. agno/storage/agent/sqlite.py +0 -1
  523. agno/storage/agent/yaml.py +0 -1
  524. agno/storage/base.py +0 -60
  525. agno/storage/dynamodb.py +0 -673
  526. agno/storage/firestore.py +0 -297
  527. agno/storage/gcs_json.py +0 -261
  528. agno/storage/in_memory.py +0 -234
  529. agno/storage/json.py +0 -237
  530. agno/storage/mongodb.py +0 -328
  531. agno/storage/mysql.py +0 -685
  532. agno/storage/postgres.py +0 -682
  533. agno/storage/redis.py +0 -336
  534. agno/storage/session/__init__.py +0 -16
  535. agno/storage/session/agent.py +0 -64
  536. agno/storage/session/team.py +0 -63
  537. agno/storage/session/v2/__init__.py +0 -5
  538. agno/storage/session/workflow.py +0 -61
  539. agno/storage/singlestore.py +0 -606
  540. agno/storage/sqlite.py +0 -646
  541. agno/storage/workflow/__init__.py +0 -0
  542. agno/storage/workflow/mongodb.py +0 -1
  543. agno/storage/workflow/postgres.py +0 -1
  544. agno/storage/workflow/sqlite.py +0 -1
  545. agno/storage/yaml.py +0 -241
  546. agno/tools/thinking.py +0 -73
  547. agno/utils/defaults.py +0 -57
  548. agno/utils/filesystem.py +0 -39
  549. agno/utils/git.py +0 -52
  550. agno/utils/json_io.py +0 -30
  551. agno/utils/load_env.py +0 -19
  552. agno/utils/py_io.py +0 -19
  553. agno/utils/pyproject.py +0 -18
  554. agno/utils/resource_filter.py +0 -31
  555. agno/workflow/v2/__init__.py +0 -21
  556. agno/workflow/v2/types.py +0 -357
  557. agno/workflow/v2/workflow.py +0 -3312
  558. agno/workspace/__init__.py +0 -0
  559. agno/workspace/config.py +0 -325
  560. agno/workspace/enums.py +0 -6
  561. agno/workspace/helpers.py +0 -52
  562. agno/workspace/operator.py +0 -757
  563. agno/workspace/settings.py +0 -158
  564. agno-1.8.1.dist-info/METADATA +0 -982
  565. agno-1.8.1.dist-info/RECORD +0 -566
  566. agno-1.8.1.dist-info/entry_points.txt +0 -3
  567. /agno/{app → db/migrations}/__init__.py +0 -0
  568. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  569. /agno/{cli → integrations}/__init__.py +0 -0
  570. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  571. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  572. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  573. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  574. /agno/{app → os/interfaces}/slack/security.py +0 -0
  575. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  576. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  577. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  578. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
  579. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
  580. {agno-1.8.1.dist-info → agno-2.0.0a1.dist-info}/top_level.txt +0 -0
agno/memory/classifier.py DELETED
@@ -1,104 +0,0 @@
1
- from typing import Any, List, Optional, cast
2
-
3
- from pydantic import BaseModel
4
-
5
- from agno.memory.memory import Memory
6
- from agno.models.base import Model
7
- from agno.models.message import Message
8
- from agno.utils.log import log_debug, logger
9
-
10
-
11
- class MemoryClassifier(BaseModel):
12
- model: Optional[Model] = None
13
-
14
- # Provide the system prompt for the classifier as a string
15
- system_prompt: Optional[str] = None
16
- # Existing Memories
17
- existing_memories: Optional[List[Memory]] = None
18
-
19
- def update_model(self) -> None:
20
- if self.model is None:
21
- try:
22
- from agno.models.openai import OpenAIChat
23
- except ModuleNotFoundError as e:
24
- logger.exception(e)
25
- logger.error(
26
- "Agno uses `openai` as the default model provider. Please provide a `model` or install `openai`."
27
- )
28
- exit(1)
29
- self.model = OpenAIChat(id="gpt-4o")
30
-
31
- def get_system_message(self) -> Message:
32
- # -*- Return a system message for classification
33
- system_prompt_lines = [
34
- "Your task is to identify if the user's message contains information that is worth remembering for future conversations.",
35
- "This includes details that could personalize ongoing interactions with the user, such as:\n"
36
- " - Personal facts: name, age, occupation, location, interests, preferences, etc.\n"
37
- " - Significant life events or experiences shared by the user\n"
38
- " - Important context about the user's current situation, challenges or goals\n"
39
- " - What the user likes or dislikes, their opinions, beliefs, values, etc.\n"
40
- " - Any other details that provide valuable insights into the user's personality, perspective or needs",
41
- "Your task is to decide whether the user input contains any of the above information worth remembering.",
42
- "If the user input contains any information worth remembering for future conversations, respond with 'yes'.",
43
- "If the input does not contain any important details worth saving, respond with 'no' to disregard it.",
44
- "You will also be provided with a list of existing memories to help you decide if the input is new or already known.",
45
- "If the memory already exists that matches the input, respond with 'no' to keep it as is.",
46
- "If a memory exists that needs to be updated or deleted, respond with 'yes' to update/delete it.",
47
- "You must only respond with 'yes' or 'no'. Nothing else will be considered as a valid response.",
48
- ]
49
- if self.existing_memories and len(self.existing_memories) > 0:
50
- system_prompt_lines.extend(
51
- [
52
- "\nExisting memories:",
53
- "<existing_memories>\n"
54
- + "\n".join([f" - {m.memory}" for m in self.existing_memories])
55
- + "\n</existing_memories>",
56
- ]
57
- )
58
- return Message(role="system", content="\n".join(system_prompt_lines))
59
-
60
- def run(
61
- self,
62
- message: Optional[str] = None,
63
- **kwargs: Any,
64
- ) -> Optional[str]:
65
- log_debug("*********** MemoryClassifier Start ***********")
66
-
67
- # Update the Model (set defaults, add logit etc.)
68
- self.update_model()
69
-
70
- # Prepare the List of messages to send to the Model
71
- messages_for_model: List[Message] = [self.get_system_message()]
72
- # Add the user prompt message
73
- user_prompt_message = Message(role="user", content=message, **kwargs) if message else None
74
- if user_prompt_message is not None:
75
- messages_for_model += [user_prompt_message]
76
-
77
- # Generate a response from the Model (includes running function calls)
78
- self.model = cast(Model, self.model)
79
- response = self.model.response(messages=messages_for_model)
80
- log_debug("*********** MemoryClassifier End ***********")
81
- return response.content
82
-
83
- async def arun(
84
- self,
85
- message: Optional[str] = None,
86
- **kwargs: Any,
87
- ) -> Optional[str]:
88
- log_debug("*********** Async MemoryClassifier Start ***********")
89
-
90
- # Update the Model (set defaults, add logit etc.)
91
- self.update_model()
92
-
93
- # Prepare the List of messages to send to the Model
94
- messages_for_model: List[Message] = [self.get_system_message()]
95
- # Add the user prompt message
96
- user_prompt_message = Message(role="user", content=message, **kwargs) if message else None
97
- if user_prompt_message is not None:
98
- messages_for_model += [user_prompt_message]
99
-
100
- # Generate a response from the Model (includes running function calls)
101
- self.model = cast(Model, self.model)
102
- response = await self.model.aresponse(messages=messages_for_model)
103
- log_debug("*********** Async MemoryClassifier End ***********")
104
- return response.content
@@ -1,5 +0,0 @@
1
- from agno.memory.db.base import MemoryDb
2
-
3
- __all__ = [
4
- "MemoryDb",
5
- ]
agno/memory/db/base.py DELETED
@@ -1,42 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from typing import List, Optional
3
-
4
- from agno.memory.row import MemoryRow
5
-
6
-
7
- class MemoryDb(ABC):
8
- """Base class for the Memory Database."""
9
-
10
- @abstractmethod
11
- def create(self) -> None:
12
- raise NotImplementedError
13
-
14
- @abstractmethod
15
- def memory_exists(self, memory: MemoryRow) -> bool:
16
- raise NotImplementedError
17
-
18
- @abstractmethod
19
- def read_memories(
20
- self, user_id: Optional[str] = None, limit: Optional[int] = None, sort: Optional[str] = None
21
- ) -> List[MemoryRow]:
22
- raise NotImplementedError
23
-
24
- @abstractmethod
25
- def upsert_memory(self, memory: MemoryRow) -> Optional[MemoryRow]:
26
- raise NotImplementedError
27
-
28
- @abstractmethod
29
- def delete_memory(self, id: str) -> None:
30
- raise NotImplementedError
31
-
32
- @abstractmethod
33
- def drop_table(self) -> None:
34
- raise NotImplementedError
35
-
36
- @abstractmethod
37
- def table_exists(self) -> bool:
38
- raise NotImplementedError
39
-
40
- @abstractmethod
41
- def clear(self) -> bool:
42
- raise NotImplementedError
agno/memory/db/mongodb.py DELETED
@@ -1,189 +0,0 @@
1
- from datetime import datetime, timezone
2
- from typing import List, Optional
3
-
4
- try:
5
- from pymongo import MongoClient
6
- from pymongo.collection import Collection
7
- from pymongo.database import Database
8
- from pymongo.errors import PyMongoError
9
- except ImportError:
10
- raise ImportError("`pymongo` not installed. Please install it with `pip install pymongo`")
11
-
12
- from agno.memory.db.base import MemoryDb
13
- from agno.memory.row import MemoryRow
14
- from agno.utils.log import log_debug, logger
15
-
16
-
17
- class MongoMemoryDb(MemoryDb):
18
- def __init__(
19
- self,
20
- collection_name: str = "memory",
21
- db_url: Optional[str] = None,
22
- db_name: str = "agno",
23
- client: Optional[MongoClient] = None,
24
- ):
25
- """
26
- This class provides a memory store backed by a MongoDB collection.
27
-
28
- Args:
29
- collection_name: The name of the collection to store memories
30
- db_url: MongoDB connection URL
31
- db_name: Name of the database
32
- client: Optional existing MongoDB client
33
- """
34
- self._client: Optional[MongoClient] = client
35
- if self._client is None and db_url is not None:
36
- self._client = MongoClient(db_url)
37
-
38
- if self._client is None:
39
- raise ValueError("Must provide either db_url or client")
40
-
41
- self.collection_name: str = collection_name
42
- self.db_name: str = db_name
43
- self.db: Database = self._client[self.db_name]
44
- self.collection: Collection = self.db[self.collection_name]
45
-
46
- def create(self) -> None:
47
- """Create indexes for the collection"""
48
- try:
49
- # Create indexes
50
- self.collection.create_index("id", unique=True)
51
- self.collection.create_index("user_id")
52
- self.collection.create_index("created_at")
53
- except PyMongoError as e:
54
- logger.error(f"Error creating indexes for collection '{self.collection_name}': {e}")
55
- raise
56
-
57
- def memory_exists(self, memory: MemoryRow) -> bool:
58
- """Check if a memory exists
59
- Args:
60
- memory: MemoryRow to check
61
- Returns:
62
- bool: True if the memory exists, False otherwise
63
- """
64
- try:
65
- result = self.collection.find_one({"id": memory.id})
66
- return result is not None
67
- except PyMongoError as e:
68
- logger.error(f"Error checking memory existence: {e}")
69
- return False
70
-
71
- def read_memories(
72
- self, user_id: Optional[str] = None, limit: Optional[int] = None, sort: Optional[str] = None
73
- ) -> List[MemoryRow]:
74
- """Read memories from the collection
75
- Args:
76
- user_id: ID of the user to read
77
- limit: Maximum number of memories to read
78
- sort: Sort order ("asc" or "desc")
79
- Returns:
80
- List[MemoryRow]: List of memories
81
- """
82
- memories: List[MemoryRow] = []
83
- try:
84
- # Build query
85
- query = {}
86
- if user_id is not None:
87
- query["user_id"] = user_id
88
-
89
- # Build sort order
90
- sort_order = -1 if sort != "asc" else 1
91
- cursor = self.collection.find(query).sort("created_at", sort_order)
92
-
93
- if limit is not None:
94
- cursor = cursor.limit(limit)
95
-
96
- for doc in cursor:
97
- # Remove MongoDB _id before converting to MemoryRow
98
- doc.pop("_id", None)
99
- memories.append(MemoryRow(user_id=doc["user_id"], memory=doc["memory"]))
100
- except PyMongoError as e:
101
- logger.error(f"Error reading memories: {e}")
102
- return memories
103
-
104
- def upsert_memory(self, memory: MemoryRow, create_and_retry: bool = True) -> None:
105
- """Upsert a memory into the collection
106
- Args:
107
- memory: MemoryRow to upsert
108
- create_and_retry: Whether to create a new memory if the id already exists
109
- Returns:
110
- None
111
- """
112
- try:
113
- now = datetime.now(timezone.utc)
114
- timestamp = int(now.timestamp())
115
-
116
- # Add version field for optimistic locking
117
- memory_dict = memory.model_dump()
118
- if "_version" not in memory_dict:
119
- memory_dict["_version"] = 1
120
- else:
121
- memory_dict["_version"] += 1
122
-
123
- update_data = {
124
- "user_id": memory.user_id,
125
- "memory": memory.memory,
126
- "updated_at": timestamp,
127
- "_version": memory_dict["_version"],
128
- }
129
-
130
- # For new documents, set created_at
131
- query = {"id": memory.id}
132
- doc = self.collection.find_one(query)
133
- if not doc:
134
- update_data["created_at"] = timestamp
135
-
136
- result = self.collection.update_one(query, {"$set": update_data}, upsert=True)
137
-
138
- if not result.acknowledged:
139
- logger.error("Memory upsert not acknowledged")
140
-
141
- except PyMongoError as e:
142
- logger.error(f"Error upserting memory: {e}")
143
- raise
144
-
145
- def delete_memory(self, id: str) -> None:
146
- """Delete a memory from the collection
147
- Args:
148
- id: ID of the memory to delete
149
- Returns:
150
- None
151
- """
152
- try:
153
- result = self.collection.delete_one({"id": id})
154
- if result.deleted_count == 0:
155
- log_debug(f"No memory found with id: {id}")
156
- else:
157
- log_debug(f"Successfully deleted memory with id: {id}")
158
- except PyMongoError as e:
159
- logger.error(f"Error deleting memory: {e}")
160
- raise
161
-
162
- def drop_table(self) -> None:
163
- """Drop the collection
164
- Returns:
165
- None
166
- """
167
- try:
168
- self.collection.drop()
169
- except PyMongoError as e:
170
- logger.error(f"Error dropping collection: {e}")
171
-
172
- def table_exists(self) -> bool:
173
- """Check if the collection exists
174
- Returns:
175
- bool: True if the collection exists, False otherwise
176
- """
177
- return self.collection_name in self.db.list_collection_names()
178
-
179
- def clear(self) -> bool:
180
- """Clear the collection
181
- Returns:
182
- bool: True if the collection was cleared, False otherwise
183
- """
184
- try:
185
- result = self.collection.delete_many({})
186
- return result.acknowledged
187
- except PyMongoError as e:
188
- logger.error(f"Error clearing collection: {e}")
189
- return False
@@ -1,203 +0,0 @@
1
- from typing import List, Optional
2
-
3
- try:
4
- from sqlalchemy.dialects import postgresql
5
- from sqlalchemy.engine import Engine, create_engine
6
- from sqlalchemy.inspection import inspect
7
- from sqlalchemy.orm import scoped_session, sessionmaker
8
- from sqlalchemy.schema import Column, MetaData, Table
9
- from sqlalchemy.sql.expression import delete, select, text
10
- from sqlalchemy.types import DateTime, String
11
- except ImportError:
12
- raise ImportError("`sqlalchemy` not installed. Please install using `pip install sqlalchemy 'psycopg[binary]'`")
13
-
14
- from agno.memory.db.base import MemoryDb
15
- from agno.memory.row import MemoryRow
16
- from agno.utils.log import log_debug, logger
17
-
18
-
19
- class PgMemoryDb(MemoryDb):
20
- def __init__(
21
- self,
22
- table_name: str,
23
- schema: Optional[str] = "ai",
24
- db_url: Optional[str] = None,
25
- db_engine: Optional[Engine] = None,
26
- ):
27
- """
28
- This class provides a memory store backed by a postgres table.
29
-
30
- The following order is used to determine the database connection:
31
- 1. Use the db_engine if provided
32
- 2. Use the db_url to create the engine
33
-
34
- Args:
35
- table_name (str): The name of the table to store memory rows.
36
- schema (Optional[str]): The schema to store the table in. Defaults to "ai".
37
- db_url (Optional[str]): The database URL to connect to. Defaults to None.
38
- db_engine (Optional[Engine]): The database engine to use. Defaults to None.
39
- """
40
- _engine: Optional[Engine] = db_engine
41
- if _engine is None and db_url is not None:
42
- _engine = create_engine(db_url)
43
-
44
- if _engine is None:
45
- raise ValueError("Must provide either db_url or db_engine")
46
-
47
- self.table_name: str = table_name
48
- self.schema: Optional[str] = schema
49
- self.db_url: Optional[str] = db_url
50
- self.db_engine: Engine = _engine
51
- self.inspector = inspect(self.db_engine)
52
- self.metadata: MetaData = MetaData(schema=self.schema)
53
- self.Session: scoped_session = scoped_session(sessionmaker(bind=self.db_engine))
54
- self.table: Table = self.get_table()
55
-
56
- def get_table(self) -> Table:
57
- return Table(
58
- self.table_name,
59
- self.metadata,
60
- Column("id", String, primary_key=True),
61
- Column("user_id", String),
62
- Column("memory", postgresql.JSONB, server_default=text("'{}'::jsonb")),
63
- Column("created_at", DateTime(timezone=True), server_default=text("now()")),
64
- Column("updated_at", DateTime(timezone=True), onupdate=text("now()")),
65
- extend_existing=True,
66
- )
67
-
68
- def create(self) -> None:
69
- if not self.table_exists():
70
- try:
71
- with self.Session() as sess, sess.begin():
72
- if self.schema is not None:
73
- log_debug(f"Creating schema: {self.schema}")
74
- sess.execute(text(f"CREATE SCHEMA IF NOT EXISTS {self.schema};"))
75
- log_debug(f"Creating table: {self.table_name}")
76
- self.table.create(self.db_engine, checkfirst=True)
77
- except Exception as e:
78
- logger.error(f"Error creating table '{self.table.fullname}': {e}")
79
- raise
80
-
81
- def memory_exists(self, memory: MemoryRow) -> bool:
82
- columns = [self.table.c.id]
83
- with self.Session() as sess, sess.begin():
84
- stmt = select(*columns).where(self.table.c.id == memory.id)
85
- result = sess.execute(stmt).first()
86
- return result is not None
87
-
88
- def read_memories(
89
- self, user_id: Optional[str] = None, limit: Optional[int] = None, sort: Optional[str] = None
90
- ) -> List[MemoryRow]:
91
- memories: List[MemoryRow] = []
92
- try:
93
- with self.Session() as sess, sess.begin():
94
- stmt = select(self.table)
95
- if user_id is not None:
96
- stmt = stmt.where(self.table.c.user_id == user_id)
97
- if limit is not None:
98
- stmt = stmt.limit(limit)
99
-
100
- if sort == "asc":
101
- stmt = stmt.order_by(self.table.c.created_at.asc())
102
- else:
103
- stmt = stmt.order_by(self.table.c.created_at.desc())
104
-
105
- rows = sess.execute(stmt).fetchall()
106
- for row in rows:
107
- if row is not None:
108
- memories.append(MemoryRow.model_validate(row))
109
- except Exception as e:
110
- log_debug(f"Exception reading from table: {e}")
111
- log_debug(f"Table does not exist: {self.table.name}")
112
- log_debug("Creating table for future transactions")
113
- self.create()
114
- return memories
115
-
116
- def upsert_memory(self, memory: MemoryRow, create_and_retry: bool = True) -> None:
117
- """Create a new memory if it does not exist, otherwise update the existing memory"""
118
-
119
- try:
120
- with self.Session() as sess, sess.begin():
121
- # Create an insert statement
122
- stmt = postgresql.insert(self.table).values(
123
- id=memory.id,
124
- user_id=memory.user_id,
125
- memory=memory.memory,
126
- )
127
-
128
- # Define the upsert if the memory already exists
129
- # See: https://docs.sqlalchemy.org/en/20/dialects/postgresql.html#postgresql-insert-on-conflict
130
- stmt = stmt.on_conflict_do_update(
131
- index_elements=["id"],
132
- set_=dict(
133
- user_id=stmt.excluded.user_id,
134
- memory=stmt.excluded.memory,
135
- ),
136
- )
137
-
138
- sess.execute(stmt)
139
- except Exception as e:
140
- log_debug(f"Exception upserting into table: {e}")
141
- log_debug(f"Table does not exist: {self.table.name}")
142
- log_debug("Creating table for future transactions")
143
- self.create()
144
- if create_and_retry:
145
- return self.upsert_memory(memory, create_and_retry=False)
146
- return None
147
-
148
- def delete_memory(self, id: str) -> None:
149
- with self.Session() as sess, sess.begin():
150
- stmt = delete(self.table).where(self.table.c.id == id)
151
- sess.execute(stmt)
152
-
153
- def drop_table(self) -> None:
154
- if self.table_exists():
155
- log_debug(f"Deleting table: {self.table_name}")
156
- self.table.drop(self.db_engine)
157
-
158
- def table_exists(self) -> bool:
159
- log_debug(f"Checking if table exists: {self.table.name}")
160
- try:
161
- return inspect(self.db_engine).has_table(self.table.name, schema=self.schema)
162
- except Exception as e:
163
- logger.error(e)
164
- return False
165
-
166
- def clear(self) -> bool:
167
- with self.Session() as sess, sess.begin():
168
- stmt = delete(self.table)
169
- sess.execute(stmt)
170
- return True
171
-
172
- def __deepcopy__(self, memo):
173
- """
174
- Create a deep copy of the PgMemoryDb instance, handling unpickleable attributes.
175
-
176
- Args:
177
- memo (dict): A dictionary of objects already copied during the current copying pass.
178
-
179
- Returns:
180
- PgMemoryDb: A deep-copied instance of PgMemoryDb.
181
- """
182
- from copy import deepcopy
183
-
184
- # Create a new instance without calling __init__
185
- cls = self.__class__
186
- copied_obj = cls.__new__(cls)
187
- memo[id(self)] = copied_obj
188
-
189
- # Deep copy attributes
190
- for k, v in self.__dict__.items():
191
- if k in {"metadata", "table"}:
192
- continue
193
- # Reuse db_engine and Session without copying
194
- elif k in {"db_engine", "Session"}:
195
- setattr(copied_obj, k, v)
196
- else:
197
- setattr(copied_obj, k, deepcopy(v, memo))
198
-
199
- # Recreate metadata and table for the copied instance
200
- copied_obj.metadata = MetaData(schema=copied_obj.schema)
201
- copied_obj.table = copied_obj.get_table()
202
-
203
- return copied_obj