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/knowledge/website.py DELETED
@@ -1,179 +0,0 @@
1
- import asyncio
2
- from typing import Any, AsyncIterator, Dict, Iterator, List, Optional
3
-
4
- from pydantic import model_validator
5
-
6
- from agno.document import Document
7
- from agno.document.chunking.fixed import FixedSizeChunking
8
- from agno.document.reader.website_reader import WebsiteReader
9
- from agno.knowledge.agent import AgentKnowledge
10
- from agno.utils.log import log_debug, log_info, logger
11
-
12
-
13
- class WebsiteKnowledgeBase(AgentKnowledge):
14
- urls: List[str] = []
15
- reader: Optional[WebsiteReader] = None
16
-
17
- # WebsiteReader parameters
18
- max_depth: int = 3
19
- max_links: int = 10
20
-
21
- @model_validator(mode="after")
22
- def set_reader(self) -> "WebsiteKnowledgeBase":
23
- if self.reader is None:
24
- self.reader = WebsiteReader(
25
- max_depth=self.max_depth,
26
- max_links=self.max_links,
27
- chunking_strategy=self.chunking_strategy or FixedSizeChunking(),
28
- )
29
- return self
30
-
31
- @property
32
- def document_lists(self) -> Iterator[List[Document]]:
33
- """Iterate over urls and yield lists of documents.
34
- Each object yielded by the iterator is a list of documents.
35
-
36
- Returns:
37
- Iterator[List[Document]]: Iterator yielding list of documents
38
- """
39
- if self.reader is not None:
40
- for _url in self.urls:
41
- yield self.reader.read(url=_url)
42
-
43
- @property
44
- async def async_document_lists(self) -> AsyncIterator[List[Document]]:
45
- """Asynchronously iterate over urls and yield lists of documents.
46
- Each object yielded by the iterator is a list of documents.
47
-
48
- Returns:
49
- AsyncIterator[List[Document]]: AsyncIterator yielding list of documents
50
- """
51
- if self.reader is not None:
52
- for _url in self.urls:
53
- yield await self.reader.async_read(url=_url)
54
-
55
- def load(
56
- self,
57
- recreate: bool = False,
58
- upsert: bool = True,
59
- skip_existing: bool = True,
60
- filters: Optional[Dict[str, Any]] = None,
61
- ) -> None:
62
- """Load the website contents to the vector db"""
63
-
64
- if self.vector_db is None:
65
- logger.warning("No vector db provided")
66
- return
67
-
68
- if self.reader is None:
69
- logger.warning("No reader provided")
70
- return
71
-
72
- if recreate:
73
- log_debug("Dropping collection")
74
- self.vector_db.drop()
75
-
76
- log_debug("Creating collection")
77
- self.vector_db.create()
78
-
79
- log_info("Loading knowledge base")
80
-
81
- # Given that the crawler needs to parse the URL before existence can be checked
82
- # We check if the website url exists in the vector db if recreate is False
83
- urls_to_read = self.urls.copy()
84
- if not recreate:
85
- for url in urls_to_read:
86
- log_debug(f"Checking if {url} exists in the vector db")
87
- if self.vector_db.name_exists(name=url):
88
- log_debug(f"Skipping {url} as it exists in the vector db")
89
- urls_to_read.remove(url)
90
-
91
- num_documents = 0
92
- for url in urls_to_read:
93
- if document_list := self.reader.read(url=url):
94
- # Filter out documents which already exist in the vector db
95
- if not recreate:
96
- document_list = [document for document in document_list if not self.vector_db.doc_exists(document)]
97
- if not document_list:
98
- continue
99
- if upsert and self.vector_db.upsert_available():
100
- self.vector_db.upsert(documents=document_list, filters=filters)
101
- else:
102
- self.vector_db.insert(documents=document_list, filters=filters)
103
- num_documents += len(document_list)
104
- log_info(f"Loaded {num_documents} documents to knowledge base")
105
-
106
- if self.optimize_on is not None and num_documents > self.optimize_on:
107
- log_debug("Optimizing Vector DB")
108
- self.vector_db.optimize()
109
-
110
- async def async_load(
111
- self,
112
- recreate: bool = False,
113
- upsert: bool = True,
114
- skip_existing: bool = True,
115
- filters: Optional[Dict[str, Any]] = None,
116
- ) -> None:
117
- """Asynchronously load the website contents to the vector db"""
118
-
119
- if self.vector_db is None:
120
- logger.warning("No vector db provided")
121
- return
122
-
123
- if self.reader is None:
124
- logger.warning("No reader provided")
125
- return
126
-
127
- vector_db = self.vector_db
128
- reader = self.reader
129
-
130
- if recreate:
131
- log_debug("Dropping collection asynchronously")
132
- await vector_db.async_drop()
133
-
134
- log_debug("Creating collection asynchronously")
135
- await vector_db.async_create()
136
-
137
- log_info("Loading knowledge base asynchronously")
138
- num_documents = 0
139
-
140
- urls_to_read = self.urls.copy()
141
- if not recreate:
142
- for url in urls_to_read[:]:
143
- log_debug(f"Checking if {url} exists in the vector db")
144
- name_exists = vector_db.async_name_exists(name=url)
145
- if name_exists:
146
- log_debug(f"Skipping {url} as it exists in the vector db")
147
- urls_to_read.remove(url)
148
-
149
- async def process_url(url: str) -> List[Document]:
150
- try:
151
- document_list = await reader.async_read(url=url)
152
-
153
- if not recreate:
154
- filtered_documents = []
155
- for document in document_list:
156
- if not await vector_db.async_doc_exists(document):
157
- filtered_documents.append(document)
158
- document_list = filtered_documents
159
-
160
- return document_list
161
- except Exception as e:
162
- logger.error(f"Error processing URL {url}: {e}")
163
- return []
164
-
165
- url_tasks = [process_url(url) for url in urls_to_read]
166
- all_document_lists = await asyncio.gather(*url_tasks)
167
-
168
- for document_list in all_document_lists:
169
- if document_list:
170
- if upsert and vector_db.upsert_available():
171
- await vector_db.async_upsert(documents=document_list, filters=filters)
172
- else:
173
- await vector_db.async_insert(documents=document_list, filters=filters)
174
- num_documents += len(document_list)
175
- log_info(f"Loaded {num_documents} documents to knowledge base asynchronously")
176
-
177
- if self.optimize_on is not None and num_documents > self.optimize_on:
178
- log_debug("Optimizing Vector DB")
179
- vector_db.optimize()
@@ -1,32 +0,0 @@
1
- from typing import Iterator, List
2
-
3
- from agno.document import Document
4
- from agno.knowledge.agent import AgentKnowledge
5
-
6
- try:
7
- import wikipedia # noqa: F401
8
- except ImportError:
9
- raise ImportError("The `wikipedia` package is not installed. Please install it via `pip install wikipedia`.")
10
-
11
-
12
- class WikipediaKnowledgeBase(AgentKnowledge):
13
- topics: List[str] = []
14
- auto_suggest: bool = True
15
-
16
- @property
17
- def document_lists(self) -> Iterator[List[Document]]:
18
- """Iterate over urls and yield lists of documents.
19
- Each object yielded by the iterator is a list of documents.
20
-
21
- Returns:
22
- Iterator[List[Document]]: Iterator yielding list of documents
23
- """
24
-
25
- for topic in self.topics:
26
- yield [
27
- Document(
28
- name=topic,
29
- meta_data={"topic": topic},
30
- content=wikipedia.summary(topic, auto_suggest=self.auto_suggest),
31
- )
32
- ]
agno/knowledge/youtube.py DELETED
@@ -1,35 +0,0 @@
1
- import asyncio
2
- from typing import AsyncIterator, Iterator, List
3
-
4
- from agno.document import Document
5
- from agno.document.reader.youtube_reader import YouTubeReader
6
- from agno.knowledge.agent import AgentKnowledge
7
-
8
-
9
- class YouTubeKnowledgeBase(AgentKnowledge):
10
- urls: List[str] = []
11
- reader: YouTubeReader = YouTubeReader()
12
-
13
- @property
14
- def document_lists(self) -> Iterator[List[Document]]:
15
- """Iterate over YouTube URLs and yield lists of documents.
16
- Each object yielded by the iterator is a list of documents.
17
-
18
- Returns:
19
- Iterator[List[Document]]: Iterator yielding list of documents
20
- """
21
- for url in self.urls:
22
- yield self.reader.read(video_url=url)
23
-
24
- @property
25
- async def async_document_lists(self) -> AsyncIterator[List[Document]]:
26
- """Asynchronously iterate over YouTube URLs and yield lists of documents.
27
- Each object yielded by the iterator is a list of documents.
28
-
29
- Returns:
30
- AsyncIterator[List[Document]]: Async iterator yielding list of documents
31
- """
32
- tasks = [self.reader.async_read(video_url=url) for url in self.urls]
33
- results = await asyncio.gather(*tasks)
34
- for documents in results:
35
- yield documents
agno/memory/agent.py DELETED
@@ -1,423 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import Any, Dict, List, Optional, Tuple
4
-
5
- from pydantic import BaseModel, ConfigDict
6
-
7
- from agno.memory.classifier import MemoryClassifier
8
- from agno.memory.db import MemoryDb
9
- from agno.memory.manager import MemoryManager
10
- from agno.memory.memory import Memory, MemoryRetrieval
11
- from agno.memory.summarizer import MemorySummarizer
12
- from agno.memory.summary import SessionSummary
13
- from agno.models.message import Message
14
- from agno.run.response import RunResponse
15
- from agno.utils.log import log_debug, log_info, logger
16
-
17
-
18
- class AgentRun(BaseModel):
19
- message: Optional[Message] = None
20
- messages: Optional[List[Message]] = None
21
- response: Optional[RunResponse] = None
22
-
23
- model_config = ConfigDict(arbitrary_types_allowed=True)
24
-
25
- def to_dict(self) -> Dict[str, Any]:
26
- response = {
27
- "message": self.message.to_dict() if self.message else None,
28
- "messages": [message.to_dict() for message in self.messages] if self.messages else None,
29
- "response": self.response.to_dict() if self.response else None,
30
- }
31
- return {k: v for k, v in response.items() if v is not None}
32
-
33
-
34
- class AgentMemory(BaseModel):
35
- # Runs between the user and agent
36
- runs: List[AgentRun] = []
37
- # List of messages sent to the model
38
- messages: List[Message] = []
39
- update_system_message_on_change: bool = False
40
-
41
- # Summary of the session
42
- summary: Optional[SessionSummary] = None
43
- # Create and store session summaries
44
- create_session_summary: bool = False
45
- # Update session summaries after each run
46
- update_session_summary_after_run: bool = True
47
- # Summarizer to generate session summaries
48
- summarizer: Optional[MemorySummarizer] = None
49
-
50
- # Create and store personalized memories for this user
51
- create_user_memories: bool = False
52
- # Update memories for the user after each run
53
- update_user_memories_after_run: bool = True
54
-
55
- # MemoryDb to store personalized memories
56
- db: Optional[MemoryDb] = None
57
- # User ID for the personalized memories
58
- user_id: Optional[str] = None
59
- retrieval: MemoryRetrieval = MemoryRetrieval.last_n
60
- memories: Optional[List[Memory]] = None
61
- num_memories: Optional[int] = None
62
- classifier: Optional[MemoryClassifier] = None
63
- manager: Optional[MemoryManager] = None
64
-
65
- # True when memory is being updated
66
- updating_memory: bool = False
67
-
68
- version: int = 1
69
-
70
- model_config = ConfigDict(arbitrary_types_allowed=True)
71
-
72
- def to_dict(self) -> Dict[str, Any]:
73
- _memory_dict = self.model_dump(
74
- exclude_none=True,
75
- include={
76
- "update_system_message_on_change",
77
- "create_session_summary",
78
- "update_session_summary_after_run",
79
- "create_user_memories",
80
- "update_user_memories_after_run",
81
- "user_id",
82
- "num_memories",
83
- },
84
- )
85
- # Add summary if it exists
86
- if self.summary is not None:
87
- _memory_dict["summary"] = self.summary.to_dict()
88
- # Add memories if they exist
89
- if self.memories is not None:
90
- _memory_dict["memories"] = [memory.to_dict() for memory in self.memories]
91
- # Add messages if they exist
92
- if self.messages is not None:
93
- _memory_dict["messages"] = [message.to_dict() for message in self.messages]
94
- # Add runs if they exist
95
- if self.runs is not None:
96
- _memory_dict["runs"] = [run.to_dict() for run in self.runs]
97
- return _memory_dict
98
-
99
- def add_run(self, agent_run: AgentRun) -> None:
100
- """Adds an AgentRun to the runs list."""
101
- # Initialize runs list if it doesn't exist
102
- if self.runs is None:
103
- self.runs = []
104
-
105
- # Process run if it has a valid response with run_id
106
- if agent_run.response and agent_run.response.run_id:
107
- run_id = agent_run.response.run_id
108
-
109
- # Check for existing run with same ID
110
- for i, run in enumerate(self.runs):
111
- if run.response and run.response.run_id == run_id:
112
- # Replace existing run
113
- self.runs[i] = agent_run
114
- log_debug(f"Replaced existing AgentRun with run_id {run_id} in memory")
115
- return
116
-
117
- # Add new run if not found
118
- self.runs.append(agent_run)
119
- log_debug("Added AgentRun to AgentMemory")
120
-
121
- def add_system_message(self, message: Message, system_message_role: str = "system") -> None:
122
- """Add the system messages to the messages list"""
123
- # If this is the first run in the session, add the system message to the messages list
124
- if len(self.messages) == 0:
125
- if message is not None:
126
- self.messages.append(message)
127
- # If there are messages in the memory, check if the system message is already in the memory
128
- # If it is not, add the system message to the messages list
129
- # If it is, update the system message if content has changed and update_system_message_on_change is True
130
- else:
131
- system_message_index = next((i for i, m in enumerate(self.messages) if m.role == system_message_role), None)
132
- # Update the system message in memory if content has changed
133
- if system_message_index is not None:
134
- if (
135
- self.messages[system_message_index].content != message.content
136
- and self.update_system_message_on_change
137
- ):
138
- log_info("Updating system message in memory with new content")
139
- self.messages[system_message_index] = message
140
- else:
141
- # Add the system message to the messages list
142
- self.messages.insert(0, message)
143
-
144
- def add_messages(self, messages: List[Message]) -> None:
145
- """Add a list of messages to the messages list."""
146
- self.messages.extend(messages)
147
- log_debug(f"Added {len(messages)} Messages to AgentMemory")
148
-
149
- def get_messages(self) -> List[Dict[str, Any]]:
150
- """Returns the messages list as a list of dictionaries."""
151
- return [message.model_dump() for message in self.messages]
152
-
153
- def get_messages_from_last_n_runs(
154
- self, last_n: Optional[int] = None, skip_role: Optional[str] = None
155
- ) -> List[Message]:
156
- """Returns the messages from the last_n runs, excluding previously tagged history messages.
157
-
158
- Args:
159
- last_n: The number of runs to return from the end of the conversation.
160
- skip_role: Skip messages with this role.
161
-
162
- Returns:
163
- A list of Messages from the specified runs, excluding history messages.
164
- """
165
- if not self.runs:
166
- return []
167
-
168
- runs_to_process = self.runs if last_n is None else self.runs[-last_n:]
169
- messages_from_history = []
170
-
171
- for run in runs_to_process:
172
- if not (run.response and run.response.messages):
173
- continue
174
-
175
- for message in run.response.messages:
176
- # Skip messages with specified role
177
- if skip_role and message.role == skip_role:
178
- continue
179
- # Skip messages that were tagged as history in previous runs
180
- if hasattr(message, "from_history") and message.from_history:
181
- continue
182
-
183
- messages_from_history.append(message)
184
-
185
- log_debug(f"Getting messages from previous runs: {len(messages_from_history)}")
186
- return messages_from_history
187
-
188
- def get_message_pairs(
189
- self, user_role: str = "user", assistant_role: Optional[List[str]] = None
190
- ) -> List[Tuple[Message, Message]]:
191
- """Returns a list of tuples of (user message, assistant response)."""
192
-
193
- if assistant_role is None:
194
- assistant_role = ["assistant", "model", "CHATBOT"]
195
-
196
- runs_as_message_pairs: List[Tuple[Message, Message]] = []
197
- for run in self.runs:
198
- if run.response and run.response.messages:
199
- user_messages_from_run = None
200
- assistant_messages_from_run = None
201
-
202
- # Start from the beginning to look for the user message
203
- for message in run.response.messages:
204
- if hasattr(message, "from_history") and message.from_history:
205
- continue
206
- if message.role == user_role:
207
- user_messages_from_run = message
208
- break
209
-
210
- # Start from the end to look for the assistant response
211
- for message in run.response.messages[::-1]:
212
- if hasattr(message, "from_history") and message.from_history:
213
- continue
214
- if message.role in assistant_role:
215
- assistant_messages_from_run = message
216
- break
217
-
218
- if user_messages_from_run and assistant_messages_from_run:
219
- runs_as_message_pairs.append((user_messages_from_run, assistant_messages_from_run))
220
- return runs_as_message_pairs
221
-
222
- def get_tool_calls(self, num_calls: Optional[int] = None) -> List[Dict[str, Any]]:
223
- """Returns a list of tool calls from the messages"""
224
-
225
- tool_calls = []
226
- for message in self.messages[::-1]:
227
- if message.tool_calls:
228
- for tool_call in message.tool_calls:
229
- tool_calls.append(tool_call)
230
- if num_calls and len(tool_calls) >= num_calls:
231
- return tool_calls
232
- return tool_calls
233
-
234
- def load_user_memories(self) -> None:
235
- """Load memories from memory db for this user."""
236
-
237
- if self.db is None:
238
- return
239
-
240
- try:
241
- if self.retrieval in (MemoryRetrieval.last_n, MemoryRetrieval.first_n):
242
- memory_rows = self.db.read_memories(
243
- user_id=self.user_id,
244
- limit=self.num_memories,
245
- sort="asc" if self.retrieval == MemoryRetrieval.first_n else "desc",
246
- )
247
- else:
248
- raise NotImplementedError("Semantic retrieval not yet supported.")
249
- except Exception as e:
250
- log_debug(f"Error reading memory: {e}")
251
- return
252
-
253
- # Clear the existing memories
254
- self.memories = []
255
-
256
- # No memories to load
257
- if memory_rows is None or len(memory_rows) == 0:
258
- return
259
-
260
- for row in memory_rows:
261
- try:
262
- self.memories.append(Memory.model_validate(row.memory))
263
- except Exception as e:
264
- logger.warning(f"Error loading memory: {e}")
265
- continue
266
-
267
- def should_update_memory(self, input: str) -> bool:
268
- """Determines if a message should be added to the memory db."""
269
- from agno.memory.classifier import MemoryClassifier
270
-
271
- if self.classifier is None:
272
- self.classifier = MemoryClassifier()
273
-
274
- self.classifier.existing_memories = self.memories
275
- classifier_response = self.classifier.run(input)
276
- if classifier_response and classifier_response.lower() == "yes":
277
- return True
278
- return False
279
-
280
- async def ashould_update_memory(self, input: str) -> bool:
281
- """Determines if a message should be added to the memory db."""
282
- from agno.memory.classifier import MemoryClassifier
283
-
284
- if self.classifier is None:
285
- self.classifier = MemoryClassifier()
286
-
287
- self.classifier.existing_memories = self.memories
288
- classifier_response = await self.classifier.arun(input)
289
- if classifier_response and classifier_response.lower() == "yes":
290
- return True
291
- return False
292
-
293
- def update_memory(self, input: str, force: bool = False) -> Optional[str]:
294
- """Creates a memory from a message and adds it to the memory db.
295
-
296
- Args:
297
- input: The input message to create a memory from.
298
- force: If True, the memory will be created even if the classifier returns False.
299
-
300
- Returns:
301
- The response from the memory manager.
302
- """
303
- from agno.memory.manager import MemoryManager
304
-
305
- if input is None or not isinstance(input, str):
306
- return "Invalid message content"
307
-
308
- if self.db is None:
309
- logger.warning("MemoryDb not provided.")
310
- return "Please provide a db to store memories"
311
-
312
- self.updating_memory = True
313
-
314
- # Check if this user message should be added to long term memory
315
- should_update_memory = force or self.should_update_memory(input=input)
316
- log_debug(f"Update memory: {should_update_memory}")
317
-
318
- if not should_update_memory:
319
- log_debug("Memory update not required")
320
- return "Memory update not required"
321
-
322
- if self.manager is None:
323
- self.manager = MemoryManager(user_id=self.user_id, db=self.db)
324
-
325
- else:
326
- self.manager.db = self.db
327
- self.manager.user_id = self.user_id
328
-
329
- response = self.manager.run(input)
330
- self.load_user_memories()
331
- self.updating_memory = False
332
- return response
333
-
334
- async def aupdate_memory(self, input: str, force: bool = False) -> Optional[str]:
335
- """Creates a memory from a message and adds it to the memory db.
336
-
337
- Args:
338
- input: The input message to create a memory from.
339
- force: If True, the memory will be created even if the classifier returns False.
340
-
341
- Returns:
342
- The response from the memory manager.
343
- """
344
- if input is None or not isinstance(input, str):
345
- return "Invalid message content"
346
-
347
- if self.db is None:
348
- logger.warning("MemoryDb not provided.")
349
- return "Please provide a db to store memories"
350
-
351
- self.updating_memory = True
352
-
353
- # Check if this user message should be added to long term memory
354
- should_update_memory = force or await self.ashould_update_memory(input=input)
355
- log_debug(f"Async update memory: {should_update_memory}")
356
-
357
- if not should_update_memory:
358
- log_debug("Memory update not required")
359
- return "Memory update not required"
360
-
361
- if self.manager is None:
362
- self.manager = MemoryManager(user_id=self.user_id, db=self.db)
363
-
364
- else:
365
- self.manager.db = self.db
366
- self.manager.user_id = self.user_id
367
-
368
- response = await self.manager.arun(input)
369
- self.load_user_memories()
370
- self.updating_memory = False
371
- return response
372
-
373
- def update_summary(self) -> Optional[SessionSummary]:
374
- """Creates a summary of the session"""
375
- from agno.memory.summarizer import MemorySummarizer
376
-
377
- self.updating_memory = True
378
-
379
- if self.summarizer is None:
380
- self.summarizer = MemorySummarizer()
381
-
382
- self.summary = self.summarizer.run(self.get_message_pairs())
383
- self.updating_memory = False
384
- return self.summary
385
-
386
- async def aupdate_summary(self) -> Optional[SessionSummary]:
387
- """Creates a summary of the session"""
388
- from agno.memory.summarizer import MemorySummarizer
389
-
390
- self.updating_memory = True
391
-
392
- if self.summarizer is None:
393
- self.summarizer = MemorySummarizer()
394
-
395
- self.summary = await self.summarizer.arun(self.get_message_pairs())
396
- self.updating_memory = False
397
- return self.summary
398
-
399
- def clear(self) -> None:
400
- """Clear the AgentMemory"""
401
-
402
- self.runs = []
403
- self.messages = []
404
- self.summary = None
405
- self.memories = None
406
-
407
- def __deepcopy__(self, memo):
408
- from copy import deepcopy
409
-
410
- # Create a new instance without calling __init__
411
- cls = self.__class__
412
- copied_obj = cls.__new__(cls)
413
- memo[id(self)] = copied_obj
414
-
415
- # Deep copy attributes
416
- for k, v in self.__dict__.items():
417
- # Reuse db
418
- if k in {"db", "classifier", "manager", "summarizer"}:
419
- setattr(copied_obj, k, v)
420
- else:
421
- setattr(copied_obj, k, deepcopy(v, memo))
422
-
423
- return copied_obj