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