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

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