agno 0.1.2__py3-none-any.whl → 2.3.13__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 (723) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +44 -5
  3. agno/agent/agent.py +10531 -2975
  4. agno/api/agent.py +14 -53
  5. agno/api/api.py +7 -46
  6. agno/api/evals.py +22 -0
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -25
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +6 -9
  11. agno/api/schemas/evals.py +16 -0
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +10 -10
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +16 -0
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +22 -26
  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/compression/__init__.py +3 -0
  25. agno/compression/manager.py +247 -0
  26. agno/culture/__init__.py +3 -0
  27. agno/culture/manager.py +956 -0
  28. agno/db/__init__.py +24 -0
  29. agno/db/async_postgres/__init__.py +3 -0
  30. agno/db/base.py +946 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2781 -0
  33. agno/db/dynamo/schemas.py +442 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +2379 -0
  37. agno/db/firestore/schemas.py +181 -0
  38. agno/db/firestore/utils.py +376 -0
  39. agno/db/gcs_json/__init__.py +3 -0
  40. agno/db/gcs_json/gcs_json_db.py +1791 -0
  41. agno/db/gcs_json/utils.py +228 -0
  42. agno/db/in_memory/__init__.py +3 -0
  43. agno/db/in_memory/in_memory_db.py +1312 -0
  44. agno/db/in_memory/utils.py +230 -0
  45. agno/db/json/__init__.py +3 -0
  46. agno/db/json/json_db.py +1777 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/manager.py +199 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/migrations/versions/v2_3_0.py +938 -0
  51. agno/db/mongo/__init__.py +17 -0
  52. agno/db/mongo/async_mongo.py +2760 -0
  53. agno/db/mongo/mongo.py +2597 -0
  54. agno/db/mongo/schemas.py +119 -0
  55. agno/db/mongo/utils.py +276 -0
  56. agno/db/mysql/__init__.py +4 -0
  57. agno/db/mysql/async_mysql.py +2912 -0
  58. agno/db/mysql/mysql.py +2923 -0
  59. agno/db/mysql/schemas.py +186 -0
  60. agno/db/mysql/utils.py +488 -0
  61. agno/db/postgres/__init__.py +4 -0
  62. agno/db/postgres/async_postgres.py +2579 -0
  63. agno/db/postgres/postgres.py +2870 -0
  64. agno/db/postgres/schemas.py +187 -0
  65. agno/db/postgres/utils.py +442 -0
  66. agno/db/redis/__init__.py +3 -0
  67. agno/db/redis/redis.py +2141 -0
  68. agno/db/redis/schemas.py +159 -0
  69. agno/db/redis/utils.py +346 -0
  70. agno/db/schemas/__init__.py +4 -0
  71. agno/db/schemas/culture.py +120 -0
  72. agno/db/schemas/evals.py +34 -0
  73. agno/db/schemas/knowledge.py +40 -0
  74. agno/db/schemas/memory.py +61 -0
  75. agno/db/singlestore/__init__.py +3 -0
  76. agno/db/singlestore/schemas.py +179 -0
  77. agno/db/singlestore/singlestore.py +2877 -0
  78. agno/db/singlestore/utils.py +384 -0
  79. agno/db/sqlite/__init__.py +4 -0
  80. agno/db/sqlite/async_sqlite.py +2911 -0
  81. agno/db/sqlite/schemas.py +181 -0
  82. agno/db/sqlite/sqlite.py +2908 -0
  83. agno/db/sqlite/utils.py +429 -0
  84. agno/db/surrealdb/__init__.py +3 -0
  85. agno/db/surrealdb/metrics.py +292 -0
  86. agno/db/surrealdb/models.py +334 -0
  87. agno/db/surrealdb/queries.py +71 -0
  88. agno/db/surrealdb/surrealdb.py +1908 -0
  89. agno/db/surrealdb/utils.py +147 -0
  90. agno/db/utils.py +118 -0
  91. agno/eval/__init__.py +24 -0
  92. agno/eval/accuracy.py +666 -276
  93. agno/eval/agent_as_judge.py +861 -0
  94. agno/eval/base.py +29 -0
  95. agno/eval/performance.py +779 -0
  96. agno/eval/reliability.py +241 -62
  97. agno/eval/utils.py +120 -0
  98. agno/exceptions.py +143 -1
  99. agno/filters.py +354 -0
  100. agno/guardrails/__init__.py +6 -0
  101. agno/guardrails/base.py +19 -0
  102. agno/guardrails/openai.py +144 -0
  103. agno/guardrails/pii.py +94 -0
  104. agno/guardrails/prompt_injection.py +52 -0
  105. agno/hooks/__init__.py +3 -0
  106. agno/hooks/decorator.py +164 -0
  107. agno/integrations/discord/__init__.py +3 -0
  108. agno/integrations/discord/client.py +203 -0
  109. agno/knowledge/__init__.py +5 -1
  110. agno/{document → knowledge}/chunking/agentic.py +22 -14
  111. agno/{document → knowledge}/chunking/document.py +2 -2
  112. agno/{document → knowledge}/chunking/fixed.py +7 -6
  113. agno/knowledge/chunking/markdown.py +151 -0
  114. agno/{document → knowledge}/chunking/recursive.py +15 -3
  115. agno/knowledge/chunking/row.py +39 -0
  116. agno/knowledge/chunking/semantic.py +91 -0
  117. agno/knowledge/chunking/strategy.py +165 -0
  118. agno/knowledge/content.py +74 -0
  119. agno/knowledge/document/__init__.py +5 -0
  120. agno/{document → knowledge/document}/base.py +12 -2
  121. agno/knowledge/embedder/__init__.py +5 -0
  122. agno/knowledge/embedder/aws_bedrock.py +343 -0
  123. agno/knowledge/embedder/azure_openai.py +210 -0
  124. agno/{embedder → knowledge/embedder}/base.py +8 -0
  125. agno/knowledge/embedder/cohere.py +323 -0
  126. agno/knowledge/embedder/fastembed.py +62 -0
  127. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  128. agno/knowledge/embedder/google.py +258 -0
  129. agno/knowledge/embedder/huggingface.py +94 -0
  130. agno/knowledge/embedder/jina.py +182 -0
  131. agno/knowledge/embedder/langdb.py +22 -0
  132. agno/knowledge/embedder/mistral.py +206 -0
  133. agno/knowledge/embedder/nebius.py +13 -0
  134. agno/knowledge/embedder/ollama.py +154 -0
  135. agno/knowledge/embedder/openai.py +195 -0
  136. agno/knowledge/embedder/sentence_transformer.py +63 -0
  137. agno/{embedder → knowledge/embedder}/together.py +1 -1
  138. agno/knowledge/embedder/vllm.py +262 -0
  139. agno/knowledge/embedder/voyageai.py +165 -0
  140. agno/knowledge/knowledge.py +3006 -0
  141. agno/knowledge/reader/__init__.py +7 -0
  142. agno/knowledge/reader/arxiv_reader.py +81 -0
  143. agno/knowledge/reader/base.py +95 -0
  144. agno/knowledge/reader/csv_reader.py +164 -0
  145. agno/knowledge/reader/docx_reader.py +82 -0
  146. agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
  147. agno/knowledge/reader/firecrawl_reader.py +201 -0
  148. agno/knowledge/reader/json_reader.py +88 -0
  149. agno/knowledge/reader/markdown_reader.py +137 -0
  150. agno/knowledge/reader/pdf_reader.py +431 -0
  151. agno/knowledge/reader/pptx_reader.py +101 -0
  152. agno/knowledge/reader/reader_factory.py +313 -0
  153. agno/knowledge/reader/s3_reader.py +89 -0
  154. agno/knowledge/reader/tavily_reader.py +193 -0
  155. agno/knowledge/reader/text_reader.py +127 -0
  156. agno/knowledge/reader/web_search_reader.py +325 -0
  157. agno/knowledge/reader/website_reader.py +455 -0
  158. agno/knowledge/reader/wikipedia_reader.py +91 -0
  159. agno/knowledge/reader/youtube_reader.py +78 -0
  160. agno/knowledge/remote_content/remote_content.py +88 -0
  161. agno/knowledge/reranker/__init__.py +3 -0
  162. agno/{reranker → knowledge/reranker}/base.py +1 -1
  163. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  164. agno/knowledge/reranker/infinity.py +195 -0
  165. agno/knowledge/reranker/sentence_transformer.py +54 -0
  166. agno/knowledge/types.py +39 -0
  167. agno/knowledge/utils.py +234 -0
  168. agno/media.py +439 -95
  169. agno/memory/__init__.py +16 -3
  170. agno/memory/manager.py +1474 -123
  171. agno/memory/strategies/__init__.py +15 -0
  172. agno/memory/strategies/base.py +66 -0
  173. agno/memory/strategies/summarize.py +196 -0
  174. agno/memory/strategies/types.py +37 -0
  175. agno/models/aimlapi/__init__.py +5 -0
  176. agno/models/aimlapi/aimlapi.py +62 -0
  177. agno/models/anthropic/__init__.py +4 -0
  178. agno/models/anthropic/claude.py +960 -496
  179. agno/models/aws/__init__.py +15 -0
  180. agno/models/aws/bedrock.py +686 -451
  181. agno/models/aws/claude.py +190 -183
  182. agno/models/azure/__init__.py +18 -1
  183. agno/models/azure/ai_foundry.py +489 -0
  184. agno/models/azure/openai_chat.py +89 -40
  185. agno/models/base.py +2477 -550
  186. agno/models/cerebras/__init__.py +12 -0
  187. agno/models/cerebras/cerebras.py +565 -0
  188. agno/models/cerebras/cerebras_openai.py +131 -0
  189. agno/models/cohere/__init__.py +4 -0
  190. agno/models/cohere/chat.py +306 -492
  191. agno/models/cometapi/__init__.py +5 -0
  192. agno/models/cometapi/cometapi.py +74 -0
  193. agno/models/dashscope/__init__.py +5 -0
  194. agno/models/dashscope/dashscope.py +90 -0
  195. agno/models/deepinfra/__init__.py +5 -0
  196. agno/models/deepinfra/deepinfra.py +45 -0
  197. agno/models/deepseek/__init__.py +4 -0
  198. agno/models/deepseek/deepseek.py +110 -9
  199. agno/models/fireworks/__init__.py +4 -0
  200. agno/models/fireworks/fireworks.py +19 -22
  201. agno/models/google/__init__.py +3 -7
  202. agno/models/google/gemini.py +1717 -662
  203. agno/models/google/utils.py +22 -0
  204. agno/models/groq/__init__.py +4 -0
  205. agno/models/groq/groq.py +391 -666
  206. agno/models/huggingface/__init__.py +4 -0
  207. agno/models/huggingface/huggingface.py +266 -538
  208. agno/models/ibm/__init__.py +5 -0
  209. agno/models/ibm/watsonx.py +432 -0
  210. agno/models/internlm/__init__.py +3 -0
  211. agno/models/internlm/internlm.py +20 -3
  212. agno/models/langdb/__init__.py +1 -0
  213. agno/models/langdb/langdb.py +60 -0
  214. agno/models/litellm/__init__.py +14 -0
  215. agno/models/litellm/chat.py +503 -0
  216. agno/models/litellm/litellm_openai.py +42 -0
  217. agno/models/llama_cpp/__init__.py +5 -0
  218. agno/models/llama_cpp/llama_cpp.py +22 -0
  219. agno/models/lmstudio/__init__.py +5 -0
  220. agno/models/lmstudio/lmstudio.py +25 -0
  221. agno/models/message.py +361 -39
  222. agno/models/meta/__init__.py +12 -0
  223. agno/models/meta/llama.py +502 -0
  224. agno/models/meta/llama_openai.py +79 -0
  225. agno/models/metrics.py +120 -0
  226. agno/models/mistral/__init__.py +4 -0
  227. agno/models/mistral/mistral.py +293 -393
  228. agno/models/nebius/__init__.py +3 -0
  229. agno/models/nebius/nebius.py +53 -0
  230. agno/models/nexus/__init__.py +3 -0
  231. agno/models/nexus/nexus.py +22 -0
  232. agno/models/nvidia/__init__.py +4 -0
  233. agno/models/nvidia/nvidia.py +22 -3
  234. agno/models/ollama/__init__.py +4 -2
  235. agno/models/ollama/chat.py +257 -492
  236. agno/models/openai/__init__.py +7 -0
  237. agno/models/openai/chat.py +725 -770
  238. agno/models/openai/like.py +16 -2
  239. agno/models/openai/responses.py +1121 -0
  240. agno/models/openrouter/__init__.py +4 -0
  241. agno/models/openrouter/openrouter.py +62 -5
  242. agno/models/perplexity/__init__.py +5 -0
  243. agno/models/perplexity/perplexity.py +203 -0
  244. agno/models/portkey/__init__.py +3 -0
  245. agno/models/portkey/portkey.py +82 -0
  246. agno/models/requesty/__init__.py +5 -0
  247. agno/models/requesty/requesty.py +69 -0
  248. agno/models/response.py +177 -7
  249. agno/models/sambanova/__init__.py +4 -0
  250. agno/models/sambanova/sambanova.py +23 -4
  251. agno/models/siliconflow/__init__.py +5 -0
  252. agno/models/siliconflow/siliconflow.py +42 -0
  253. agno/models/together/__init__.py +4 -0
  254. agno/models/together/together.py +21 -164
  255. agno/models/utils.py +266 -0
  256. agno/models/vercel/__init__.py +3 -0
  257. agno/models/vercel/v0.py +43 -0
  258. agno/models/vertexai/__init__.py +0 -1
  259. agno/models/vertexai/claude.py +190 -0
  260. agno/models/vllm/__init__.py +3 -0
  261. agno/models/vllm/vllm.py +83 -0
  262. agno/models/xai/__init__.py +2 -0
  263. agno/models/xai/xai.py +111 -7
  264. agno/os/__init__.py +3 -0
  265. agno/os/app.py +1027 -0
  266. agno/os/auth.py +244 -0
  267. agno/os/config.py +126 -0
  268. agno/os/interfaces/__init__.py +1 -0
  269. agno/os/interfaces/a2a/__init__.py +3 -0
  270. agno/os/interfaces/a2a/a2a.py +42 -0
  271. agno/os/interfaces/a2a/router.py +249 -0
  272. agno/os/interfaces/a2a/utils.py +924 -0
  273. agno/os/interfaces/agui/__init__.py +3 -0
  274. agno/os/interfaces/agui/agui.py +47 -0
  275. agno/os/interfaces/agui/router.py +147 -0
  276. agno/os/interfaces/agui/utils.py +574 -0
  277. agno/os/interfaces/base.py +25 -0
  278. agno/os/interfaces/slack/__init__.py +3 -0
  279. agno/os/interfaces/slack/router.py +148 -0
  280. agno/os/interfaces/slack/security.py +30 -0
  281. agno/os/interfaces/slack/slack.py +47 -0
  282. agno/os/interfaces/whatsapp/__init__.py +3 -0
  283. agno/os/interfaces/whatsapp/router.py +210 -0
  284. agno/os/interfaces/whatsapp/security.py +55 -0
  285. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  286. agno/os/mcp.py +293 -0
  287. agno/os/middleware/__init__.py +9 -0
  288. agno/os/middleware/jwt.py +797 -0
  289. agno/os/router.py +258 -0
  290. agno/os/routers/__init__.py +3 -0
  291. agno/os/routers/agents/__init__.py +3 -0
  292. agno/os/routers/agents/router.py +599 -0
  293. agno/os/routers/agents/schema.py +261 -0
  294. agno/os/routers/evals/__init__.py +3 -0
  295. agno/os/routers/evals/evals.py +450 -0
  296. agno/os/routers/evals/schemas.py +174 -0
  297. agno/os/routers/evals/utils.py +231 -0
  298. agno/os/routers/health.py +31 -0
  299. agno/os/routers/home.py +52 -0
  300. agno/os/routers/knowledge/__init__.py +3 -0
  301. agno/os/routers/knowledge/knowledge.py +1008 -0
  302. agno/os/routers/knowledge/schemas.py +178 -0
  303. agno/os/routers/memory/__init__.py +3 -0
  304. agno/os/routers/memory/memory.py +661 -0
  305. agno/os/routers/memory/schemas.py +88 -0
  306. agno/os/routers/metrics/__init__.py +3 -0
  307. agno/os/routers/metrics/metrics.py +190 -0
  308. agno/os/routers/metrics/schemas.py +47 -0
  309. agno/os/routers/session/__init__.py +3 -0
  310. agno/os/routers/session/session.py +997 -0
  311. agno/os/routers/teams/__init__.py +3 -0
  312. agno/os/routers/teams/router.py +512 -0
  313. agno/os/routers/teams/schema.py +257 -0
  314. agno/os/routers/traces/__init__.py +3 -0
  315. agno/os/routers/traces/schemas.py +414 -0
  316. agno/os/routers/traces/traces.py +499 -0
  317. agno/os/routers/workflows/__init__.py +3 -0
  318. agno/os/routers/workflows/router.py +624 -0
  319. agno/os/routers/workflows/schema.py +75 -0
  320. agno/os/schema.py +534 -0
  321. agno/os/scopes.py +469 -0
  322. agno/{playground → os}/settings.py +7 -15
  323. agno/os/utils.py +973 -0
  324. agno/reasoning/anthropic.py +80 -0
  325. agno/reasoning/azure_ai_foundry.py +67 -0
  326. agno/reasoning/deepseek.py +63 -0
  327. agno/reasoning/default.py +97 -0
  328. agno/reasoning/gemini.py +73 -0
  329. agno/reasoning/groq.py +71 -0
  330. agno/reasoning/helpers.py +24 -1
  331. agno/reasoning/ollama.py +67 -0
  332. agno/reasoning/openai.py +86 -0
  333. agno/reasoning/step.py +2 -1
  334. agno/reasoning/vertexai.py +76 -0
  335. agno/run/__init__.py +6 -0
  336. agno/run/agent.py +822 -0
  337. agno/run/base.py +247 -0
  338. agno/run/cancel.py +81 -0
  339. agno/run/requirement.py +181 -0
  340. agno/run/team.py +767 -0
  341. agno/run/workflow.py +708 -0
  342. agno/session/__init__.py +10 -0
  343. agno/session/agent.py +260 -0
  344. agno/session/summary.py +265 -0
  345. agno/session/team.py +342 -0
  346. agno/session/workflow.py +501 -0
  347. agno/table.py +10 -0
  348. agno/team/__init__.py +37 -0
  349. agno/team/team.py +9536 -0
  350. agno/tools/__init__.py +7 -0
  351. agno/tools/agentql.py +120 -0
  352. agno/tools/airflow.py +22 -12
  353. agno/tools/api.py +122 -0
  354. agno/tools/apify.py +276 -83
  355. agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
  356. agno/tools/aws_lambda.py +28 -7
  357. agno/tools/aws_ses.py +66 -0
  358. agno/tools/baidusearch.py +11 -4
  359. agno/tools/bitbucket.py +292 -0
  360. agno/tools/brandfetch.py +213 -0
  361. agno/tools/bravesearch.py +106 -0
  362. agno/tools/brightdata.py +367 -0
  363. agno/tools/browserbase.py +209 -0
  364. agno/tools/calcom.py +32 -23
  365. agno/tools/calculator.py +24 -37
  366. agno/tools/cartesia.py +187 -0
  367. agno/tools/{clickup_tool.py → clickup.py} +17 -28
  368. agno/tools/confluence.py +91 -26
  369. agno/tools/crawl4ai.py +139 -43
  370. agno/tools/csv_toolkit.py +28 -22
  371. agno/tools/dalle.py +36 -22
  372. agno/tools/daytona.py +475 -0
  373. agno/tools/decorator.py +169 -14
  374. agno/tools/desi_vocal.py +23 -11
  375. agno/tools/discord.py +32 -29
  376. agno/tools/docker.py +716 -0
  377. agno/tools/duckdb.py +76 -81
  378. agno/tools/duckduckgo.py +43 -40
  379. agno/tools/e2b.py +703 -0
  380. agno/tools/eleven_labs.py +65 -54
  381. agno/tools/email.py +13 -5
  382. agno/tools/evm.py +129 -0
  383. agno/tools/exa.py +324 -42
  384. agno/tools/fal.py +39 -35
  385. agno/tools/file.py +196 -30
  386. agno/tools/file_generation.py +356 -0
  387. agno/tools/financial_datasets.py +288 -0
  388. agno/tools/firecrawl.py +108 -33
  389. agno/tools/function.py +960 -122
  390. agno/tools/giphy.py +34 -12
  391. agno/tools/github.py +1294 -97
  392. agno/tools/gmail.py +922 -0
  393. agno/tools/google_bigquery.py +117 -0
  394. agno/tools/google_drive.py +271 -0
  395. agno/tools/google_maps.py +253 -0
  396. agno/tools/googlecalendar.py +607 -107
  397. agno/tools/googlesheets.py +377 -0
  398. agno/tools/hackernews.py +20 -12
  399. agno/tools/jina.py +24 -14
  400. agno/tools/jira.py +48 -19
  401. agno/tools/knowledge.py +218 -0
  402. agno/tools/linear.py +82 -43
  403. agno/tools/linkup.py +58 -0
  404. agno/tools/local_file_system.py +15 -7
  405. agno/tools/lumalab.py +41 -26
  406. agno/tools/mcp/__init__.py +10 -0
  407. agno/tools/mcp/mcp.py +331 -0
  408. agno/tools/mcp/multi_mcp.py +347 -0
  409. agno/tools/mcp/params.py +24 -0
  410. agno/tools/mcp_toolbox.py +284 -0
  411. agno/tools/mem0.py +193 -0
  412. agno/tools/memory.py +419 -0
  413. agno/tools/mlx_transcribe.py +11 -9
  414. agno/tools/models/azure_openai.py +190 -0
  415. agno/tools/models/gemini.py +203 -0
  416. agno/tools/models/groq.py +158 -0
  417. agno/tools/models/morph.py +186 -0
  418. agno/tools/models/nebius.py +124 -0
  419. agno/tools/models_labs.py +163 -82
  420. agno/tools/moviepy_video.py +18 -13
  421. agno/tools/nano_banana.py +151 -0
  422. agno/tools/neo4j.py +134 -0
  423. agno/tools/newspaper.py +15 -4
  424. agno/tools/newspaper4k.py +19 -6
  425. agno/tools/notion.py +204 -0
  426. agno/tools/openai.py +181 -17
  427. agno/tools/openbb.py +27 -20
  428. agno/tools/opencv.py +321 -0
  429. agno/tools/openweather.py +233 -0
  430. agno/tools/oxylabs.py +385 -0
  431. agno/tools/pandas.py +25 -15
  432. agno/tools/parallel.py +314 -0
  433. agno/tools/postgres.py +238 -185
  434. agno/tools/pubmed.py +125 -13
  435. agno/tools/python.py +48 -35
  436. agno/tools/reasoning.py +283 -0
  437. agno/tools/reddit.py +207 -29
  438. agno/tools/redshift.py +406 -0
  439. agno/tools/replicate.py +69 -26
  440. agno/tools/resend.py +11 -6
  441. agno/tools/scrapegraph.py +179 -19
  442. agno/tools/searxng.py +23 -31
  443. agno/tools/serpapi.py +15 -10
  444. agno/tools/serper.py +255 -0
  445. agno/tools/shell.py +23 -12
  446. agno/tools/shopify.py +1519 -0
  447. agno/tools/slack.py +56 -14
  448. agno/tools/sleep.py +8 -6
  449. agno/tools/spider.py +35 -11
  450. agno/tools/spotify.py +919 -0
  451. agno/tools/sql.py +34 -19
  452. agno/tools/tavily.py +158 -8
  453. agno/tools/telegram.py +18 -8
  454. agno/tools/todoist.py +218 -0
  455. agno/tools/toolkit.py +134 -9
  456. agno/tools/trafilatura.py +388 -0
  457. agno/tools/trello.py +25 -28
  458. agno/tools/twilio.py +18 -9
  459. agno/tools/user_control_flow.py +78 -0
  460. agno/tools/valyu.py +228 -0
  461. agno/tools/visualization.py +467 -0
  462. agno/tools/webbrowser.py +28 -0
  463. agno/tools/webex.py +76 -0
  464. agno/tools/website.py +23 -19
  465. agno/tools/webtools.py +45 -0
  466. agno/tools/whatsapp.py +286 -0
  467. agno/tools/wikipedia.py +28 -19
  468. agno/tools/workflow.py +285 -0
  469. agno/tools/{twitter.py → x.py} +142 -46
  470. agno/tools/yfinance.py +41 -39
  471. agno/tools/youtube.py +34 -17
  472. agno/tools/zendesk.py +15 -5
  473. agno/tools/zep.py +454 -0
  474. agno/tools/zoom.py +86 -37
  475. agno/tracing/__init__.py +12 -0
  476. agno/tracing/exporter.py +157 -0
  477. agno/tracing/schemas.py +276 -0
  478. agno/tracing/setup.py +111 -0
  479. agno/utils/agent.py +938 -0
  480. agno/utils/audio.py +37 -1
  481. agno/utils/certs.py +27 -0
  482. agno/utils/code_execution.py +11 -0
  483. agno/utils/common.py +103 -20
  484. agno/utils/cryptography.py +22 -0
  485. agno/utils/dttm.py +33 -0
  486. agno/utils/events.py +700 -0
  487. agno/utils/functions.py +107 -37
  488. agno/utils/gemini.py +426 -0
  489. agno/utils/hooks.py +171 -0
  490. agno/utils/http.py +185 -0
  491. agno/utils/json_schema.py +159 -37
  492. agno/utils/knowledge.py +36 -0
  493. agno/utils/location.py +19 -0
  494. agno/utils/log.py +221 -8
  495. agno/utils/mcp.py +214 -0
  496. agno/utils/media.py +335 -14
  497. agno/utils/merge_dict.py +22 -1
  498. agno/utils/message.py +77 -2
  499. agno/utils/models/ai_foundry.py +50 -0
  500. agno/utils/models/claude.py +373 -0
  501. agno/utils/models/cohere.py +94 -0
  502. agno/utils/models/llama.py +85 -0
  503. agno/utils/models/mistral.py +100 -0
  504. agno/utils/models/openai_responses.py +140 -0
  505. agno/utils/models/schema_utils.py +153 -0
  506. agno/utils/models/watsonx.py +41 -0
  507. agno/utils/openai.py +257 -0
  508. agno/utils/pickle.py +1 -1
  509. agno/utils/pprint.py +124 -8
  510. agno/utils/print_response/agent.py +930 -0
  511. agno/utils/print_response/team.py +1914 -0
  512. agno/utils/print_response/workflow.py +1668 -0
  513. agno/utils/prompts.py +111 -0
  514. agno/utils/reasoning.py +108 -0
  515. agno/utils/response.py +163 -0
  516. agno/utils/serialize.py +32 -0
  517. agno/utils/shell.py +4 -4
  518. agno/utils/streamlit.py +487 -0
  519. agno/utils/string.py +204 -51
  520. agno/utils/team.py +139 -0
  521. agno/utils/timer.py +9 -2
  522. agno/utils/tokens.py +657 -0
  523. agno/utils/tools.py +19 -1
  524. agno/utils/whatsapp.py +305 -0
  525. agno/utils/yaml_io.py +3 -3
  526. agno/vectordb/__init__.py +2 -0
  527. agno/vectordb/base.py +87 -9
  528. agno/vectordb/cassandra/__init__.py +5 -1
  529. agno/vectordb/cassandra/cassandra.py +383 -27
  530. agno/vectordb/chroma/__init__.py +4 -0
  531. agno/vectordb/chroma/chromadb.py +748 -83
  532. agno/vectordb/clickhouse/__init__.py +7 -1
  533. agno/vectordb/clickhouse/clickhousedb.py +554 -53
  534. agno/vectordb/couchbase/__init__.py +3 -0
  535. agno/vectordb/couchbase/couchbase.py +1446 -0
  536. agno/vectordb/lancedb/__init__.py +5 -0
  537. agno/vectordb/lancedb/lance_db.py +730 -98
  538. agno/vectordb/langchaindb/__init__.py +5 -0
  539. agno/vectordb/langchaindb/langchaindb.py +163 -0
  540. agno/vectordb/lightrag/__init__.py +5 -0
  541. agno/vectordb/lightrag/lightrag.py +388 -0
  542. agno/vectordb/llamaindex/__init__.py +3 -0
  543. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  544. agno/vectordb/milvus/__init__.py +3 -0
  545. agno/vectordb/milvus/milvus.py +966 -78
  546. agno/vectordb/mongodb/__init__.py +9 -1
  547. agno/vectordb/mongodb/mongodb.py +1175 -172
  548. agno/vectordb/pgvector/__init__.py +8 -0
  549. agno/vectordb/pgvector/pgvector.py +599 -115
  550. agno/vectordb/pineconedb/__init__.py +5 -1
  551. agno/vectordb/pineconedb/pineconedb.py +406 -43
  552. agno/vectordb/qdrant/__init__.py +4 -0
  553. agno/vectordb/qdrant/qdrant.py +914 -61
  554. agno/vectordb/redis/__init__.py +9 -0
  555. agno/vectordb/redis/redisdb.py +682 -0
  556. agno/vectordb/singlestore/__init__.py +8 -1
  557. agno/vectordb/singlestore/singlestore.py +771 -0
  558. agno/vectordb/surrealdb/__init__.py +3 -0
  559. agno/vectordb/surrealdb/surrealdb.py +663 -0
  560. agno/vectordb/upstashdb/__init__.py +5 -0
  561. agno/vectordb/upstashdb/upstashdb.py +718 -0
  562. agno/vectordb/weaviate/__init__.py +8 -0
  563. agno/vectordb/weaviate/index.py +15 -0
  564. agno/vectordb/weaviate/weaviate.py +1009 -0
  565. agno/workflow/__init__.py +23 -1
  566. agno/workflow/agent.py +299 -0
  567. agno/workflow/condition.py +759 -0
  568. agno/workflow/loop.py +756 -0
  569. agno/workflow/parallel.py +853 -0
  570. agno/workflow/router.py +723 -0
  571. agno/workflow/step.py +1564 -0
  572. agno/workflow/steps.py +613 -0
  573. agno/workflow/types.py +556 -0
  574. agno/workflow/workflow.py +4327 -514
  575. agno-2.3.13.dist-info/METADATA +639 -0
  576. agno-2.3.13.dist-info/RECORD +613 -0
  577. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
  578. agno-2.3.13.dist-info/licenses/LICENSE +201 -0
  579. agno/api/playground.py +0 -91
  580. agno/api/schemas/playground.py +0 -22
  581. agno/api/schemas/user.py +0 -22
  582. agno/api/schemas/workspace.py +0 -46
  583. agno/api/user.py +0 -160
  584. agno/api/workspace.py +0 -151
  585. agno/cli/auth_server.py +0 -118
  586. agno/cli/config.py +0 -275
  587. agno/cli/console.py +0 -88
  588. agno/cli/credentials.py +0 -23
  589. agno/cli/entrypoint.py +0 -571
  590. agno/cli/operator.py +0 -355
  591. agno/cli/settings.py +0 -85
  592. agno/cli/ws/ws_cli.py +0 -817
  593. agno/constants.py +0 -13
  594. agno/document/__init__.py +0 -1
  595. agno/document/chunking/semantic.py +0 -47
  596. agno/document/chunking/strategy.py +0 -31
  597. agno/document/reader/__init__.py +0 -1
  598. agno/document/reader/arxiv_reader.py +0 -41
  599. agno/document/reader/base.py +0 -22
  600. agno/document/reader/csv_reader.py +0 -84
  601. agno/document/reader/docx_reader.py +0 -46
  602. agno/document/reader/firecrawl_reader.py +0 -99
  603. agno/document/reader/json_reader.py +0 -43
  604. agno/document/reader/pdf_reader.py +0 -219
  605. agno/document/reader/s3/pdf_reader.py +0 -46
  606. agno/document/reader/s3/text_reader.py +0 -51
  607. agno/document/reader/text_reader.py +0 -41
  608. agno/document/reader/website_reader.py +0 -175
  609. agno/document/reader/youtube_reader.py +0 -50
  610. agno/embedder/__init__.py +0 -1
  611. agno/embedder/azure_openai.py +0 -86
  612. agno/embedder/cohere.py +0 -72
  613. agno/embedder/fastembed.py +0 -37
  614. agno/embedder/google.py +0 -73
  615. agno/embedder/huggingface.py +0 -54
  616. agno/embedder/mistral.py +0 -80
  617. agno/embedder/ollama.py +0 -57
  618. agno/embedder/openai.py +0 -74
  619. agno/embedder/sentence_transformer.py +0 -38
  620. agno/embedder/voyageai.py +0 -64
  621. agno/eval/perf.py +0 -201
  622. agno/file/__init__.py +0 -1
  623. agno/file/file.py +0 -16
  624. agno/file/local/csv.py +0 -32
  625. agno/file/local/txt.py +0 -19
  626. agno/infra/app.py +0 -240
  627. agno/infra/base.py +0 -144
  628. agno/infra/context.py +0 -20
  629. agno/infra/db_app.py +0 -52
  630. agno/infra/resource.py +0 -205
  631. agno/infra/resources.py +0 -55
  632. agno/knowledge/agent.py +0 -230
  633. agno/knowledge/arxiv.py +0 -22
  634. agno/knowledge/combined.py +0 -22
  635. agno/knowledge/csv.py +0 -28
  636. agno/knowledge/csv_url.py +0 -19
  637. agno/knowledge/document.py +0 -20
  638. agno/knowledge/docx.py +0 -30
  639. agno/knowledge/json.py +0 -28
  640. agno/knowledge/langchain.py +0 -71
  641. agno/knowledge/llamaindex.py +0 -66
  642. agno/knowledge/pdf.py +0 -28
  643. agno/knowledge/pdf_url.py +0 -26
  644. agno/knowledge/s3/base.py +0 -60
  645. agno/knowledge/s3/pdf.py +0 -21
  646. agno/knowledge/s3/text.py +0 -23
  647. agno/knowledge/text.py +0 -30
  648. agno/knowledge/website.py +0 -88
  649. agno/knowledge/wikipedia.py +0 -31
  650. agno/knowledge/youtube.py +0 -22
  651. agno/memory/agent.py +0 -392
  652. agno/memory/classifier.py +0 -104
  653. agno/memory/db/__init__.py +0 -1
  654. agno/memory/db/base.py +0 -42
  655. agno/memory/db/mongodb.py +0 -189
  656. agno/memory/db/postgres.py +0 -203
  657. agno/memory/db/sqlite.py +0 -193
  658. agno/memory/memory.py +0 -15
  659. agno/memory/row.py +0 -36
  660. agno/memory/summarizer.py +0 -192
  661. agno/memory/summary.py +0 -19
  662. agno/memory/workflow.py +0 -38
  663. agno/models/google/gemini_openai.py +0 -26
  664. agno/models/ollama/hermes.py +0 -221
  665. agno/models/ollama/tools.py +0 -362
  666. agno/models/vertexai/gemini.py +0 -595
  667. agno/playground/__init__.py +0 -3
  668. agno/playground/async_router.py +0 -421
  669. agno/playground/deploy.py +0 -249
  670. agno/playground/operator.py +0 -92
  671. agno/playground/playground.py +0 -91
  672. agno/playground/schemas.py +0 -76
  673. agno/playground/serve.py +0 -55
  674. agno/playground/sync_router.py +0 -405
  675. agno/reasoning/agent.py +0 -68
  676. agno/run/response.py +0 -112
  677. agno/storage/agent/__init__.py +0 -0
  678. agno/storage/agent/base.py +0 -38
  679. agno/storage/agent/dynamodb.py +0 -350
  680. agno/storage/agent/json.py +0 -92
  681. agno/storage/agent/mongodb.py +0 -228
  682. agno/storage/agent/postgres.py +0 -367
  683. agno/storage/agent/session.py +0 -79
  684. agno/storage/agent/singlestore.py +0 -303
  685. agno/storage/agent/sqlite.py +0 -357
  686. agno/storage/agent/yaml.py +0 -93
  687. agno/storage/workflow/__init__.py +0 -0
  688. agno/storage/workflow/base.py +0 -40
  689. agno/storage/workflow/mongodb.py +0 -233
  690. agno/storage/workflow/postgres.py +0 -366
  691. agno/storage/workflow/session.py +0 -60
  692. agno/storage/workflow/sqlite.py +0 -359
  693. agno/tools/googlesearch.py +0 -88
  694. agno/utils/defaults.py +0 -57
  695. agno/utils/filesystem.py +0 -39
  696. agno/utils/git.py +0 -52
  697. agno/utils/json_io.py +0 -30
  698. agno/utils/load_env.py +0 -19
  699. agno/utils/py_io.py +0 -19
  700. agno/utils/pyproject.py +0 -18
  701. agno/utils/resource_filter.py +0 -31
  702. agno/vectordb/singlestore/s2vectordb.py +0 -390
  703. agno/vectordb/singlestore/s2vectordb2.py +0 -355
  704. agno/workspace/__init__.py +0 -0
  705. agno/workspace/config.py +0 -325
  706. agno/workspace/enums.py +0 -6
  707. agno/workspace/helpers.py +0 -48
  708. agno/workspace/operator.py +0 -758
  709. agno/workspace/settings.py +0 -63
  710. agno-0.1.2.dist-info/LICENSE +0 -375
  711. agno-0.1.2.dist-info/METADATA +0 -502
  712. agno-0.1.2.dist-info/RECORD +0 -352
  713. agno-0.1.2.dist-info/entry_points.txt +0 -3
  714. /agno/{cli → db/migrations}/__init__.py +0 -0
  715. /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
  716. /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
  717. /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
  718. /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
  719. /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
  720. /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
  721. /agno/{reranker → utils/models}/__init__.py +0 -0
  722. /agno/{storage → utils/print_response}/__init__.py +0 -0
  723. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
agno/tools/mem0.py ADDED
@@ -0,0 +1,193 @@
1
+ import json
2
+ from os import getenv
3
+ from typing import Any, Dict, List, Optional, Union
4
+
5
+ from agno.tools import Toolkit
6
+ from agno.utils.log import log_debug, log_error, log_warning
7
+
8
+ try:
9
+ from mem0.client.main import MemoryClient
10
+ from mem0.memory.main import Memory
11
+ except ImportError:
12
+ raise ImportError("`mem0ai` package not found. Please install it with `pip install mem0ai`")
13
+
14
+
15
+ class Mem0Tools(Toolkit):
16
+ def __init__(
17
+ self,
18
+ config: Optional[Dict[str, Any]] = None,
19
+ api_key: Optional[str] = None,
20
+ user_id: Optional[str] = None,
21
+ org_id: Optional[str] = None,
22
+ project_id: Optional[str] = None,
23
+ infer: bool = True,
24
+ enable_add_memory: bool = True,
25
+ enable_search_memory: bool = True,
26
+ enable_get_all_memories: bool = True,
27
+ enable_delete_all_memories: bool = True,
28
+ all: bool = False,
29
+ **kwargs,
30
+ ):
31
+ tools: List[Any] = []
32
+ if enable_add_memory or all:
33
+ tools.append(self.add_memory)
34
+ if enable_search_memory or all:
35
+ tools.append(self.search_memory)
36
+ if enable_get_all_memories or all:
37
+ tools.append(self.get_all_memories)
38
+ if enable_delete_all_memories or all:
39
+ tools.append(self.delete_all_memories)
40
+
41
+ super().__init__(name="mem0_tools", tools=tools, **kwargs)
42
+ self.api_key = api_key or getenv("MEM0_API_KEY")
43
+ self.user_id = user_id
44
+ self.org_id = org_id or getenv("MEM0_ORG_ID")
45
+ self.project_id = project_id or getenv("MEM0_PROJECT_ID")
46
+ self.client: Union[Memory, MemoryClient]
47
+ self.infer = infer
48
+
49
+ try:
50
+ if self.api_key:
51
+ log_debug("Using Mem0 Platform API key.")
52
+ client_kwargs = {"api_key": self.api_key}
53
+ if self.org_id:
54
+ client_kwargs["org_id"] = self.org_id
55
+ if self.project_id:
56
+ client_kwargs["project_id"] = self.project_id
57
+ self.client = MemoryClient(**client_kwargs)
58
+ elif config is not None:
59
+ log_debug("Using Mem0 with config.")
60
+ self.client = Memory.from_config(config)
61
+ else:
62
+ log_debug("Initializing Mem0 with default settings.")
63
+ self.client = Memory()
64
+ except Exception as e:
65
+ log_error(f"Failed to initialize Mem0 client: {e}")
66
+ raise ConnectionError("Failed to initialize Mem0 client. Ensure API keys/config are set.") from e
67
+
68
+ def _get_user_id(
69
+ self,
70
+ method_name: str,
71
+ session_state: Dict[str, Any],
72
+ ) -> str:
73
+ """Resolve the user ID"""
74
+ resolved_user_id = self.user_id
75
+ if not resolved_user_id:
76
+ try:
77
+ resolved_user_id = session_state.get("current_user_id")
78
+ except Exception:
79
+ pass
80
+ if not resolved_user_id:
81
+ error_msg = f"Error in {method_name}: A user_id must be provided in the method call."
82
+ log_error(error_msg)
83
+ return error_msg
84
+ return resolved_user_id
85
+
86
+ def add_memory(
87
+ self,
88
+ session_state,
89
+ content: Union[str, Dict[str, str]],
90
+ ) -> str:
91
+ """Add facts to the user's memory.
92
+ Args:
93
+ content(Union[str, Dict[str, str]]): The facts that should be stored.
94
+ Example:
95
+ content = "I live in NYC"
96
+ content = {"Name": "John", "Age": 30, "Location": "New York"}
97
+ Returns:
98
+ str: JSON-encoded Mem0 response or an error message.
99
+ """
100
+
101
+ resolved_user_id = self._get_user_id("add_memory", session_state=session_state)
102
+ if isinstance(resolved_user_id, str) and resolved_user_id.startswith("Error in add_memory:"):
103
+ return resolved_user_id
104
+ try:
105
+ if isinstance(content, dict):
106
+ log_debug("Wrapping dict message into content string")
107
+ content = json.dumps(content)
108
+ elif not isinstance(content, str):
109
+ content = str(content)
110
+ messages_list = [{"role": "user", "content": content}]
111
+
112
+ result = self.client.add(
113
+ messages_list,
114
+ user_id=resolved_user_id,
115
+ infer=self.infer,
116
+ )
117
+ return json.dumps(result)
118
+ except Exception as e:
119
+ log_error(f"Error adding memory: {e}")
120
+ return f"Error adding memory: {e}"
121
+
122
+ def search_memory(
123
+ self,
124
+ session_state: Dict[str, Any],
125
+ query: str,
126
+ ) -> str:
127
+ """Semantic search for *query* across the user's stored memories."""
128
+
129
+ resolved_user_id = self._get_user_id("search_memory", session_state=session_state)
130
+ if isinstance(resolved_user_id, str) and resolved_user_id.startswith("Error in search_memory:"):
131
+ return resolved_user_id
132
+ try:
133
+ results = self.client.search(
134
+ query=query,
135
+ user_id=resolved_user_id,
136
+ )
137
+
138
+ if isinstance(results, dict) and "results" in results:
139
+ search_results_list = results.get("results", [])
140
+ elif isinstance(results, list):
141
+ search_results_list = results
142
+ else:
143
+ log_warning(f"Unexpected return type from mem0.search: {type(results)}. Returning empty list.")
144
+ search_results_list = []
145
+
146
+ return json.dumps(search_results_list)
147
+ except ValueError as ve:
148
+ log_error(str(ve))
149
+ return str(ve)
150
+ except Exception as e:
151
+ log_error(f"Error searching memory: {e}")
152
+ return f"Error searching memory: {e}"
153
+
154
+ def get_all_memories(self, session_state: Dict[str, Any]) -> str:
155
+ """Return **all** memories for the current user as a JSON string."""
156
+
157
+ resolved_user_id = self._get_user_id("get_all_memories", session_state=session_state)
158
+ if isinstance(resolved_user_id, str) and resolved_user_id.startswith("Error in get_all_memories:"):
159
+ return resolved_user_id
160
+ try:
161
+ results = self.client.get_all(
162
+ user_id=resolved_user_id,
163
+ )
164
+
165
+ if isinstance(results, dict) and "results" in results:
166
+ memories_list = results.get("results", [])
167
+ elif isinstance(results, list):
168
+ memories_list = results
169
+ else:
170
+ log_warning(f"Unexpected return type from mem0.get_all: {type(results)}. Returning empty list.")
171
+ memories_list = []
172
+ return json.dumps(memories_list)
173
+ except ValueError as ve:
174
+ log_error(str(ve))
175
+ return str(ve)
176
+ except Exception as e:
177
+ log_error(f"Error getting all memories: {e}")
178
+ return f"Error getting all memories: {e}"
179
+
180
+ def delete_all_memories(self, session_state: Dict[str, Any]) -> str:
181
+ """Delete *all* memories associated with the current user"""
182
+
183
+ resolved_user_id = self._get_user_id("delete_all_memories", session_state=session_state)
184
+ if isinstance(resolved_user_id, str) and resolved_user_id.startswith("Error in delete_all_memories:"):
185
+ error_msg = resolved_user_id
186
+ log_error(error_msg)
187
+ return f"Error deleting all memories: {error_msg}"
188
+ try:
189
+ self.client.delete_all(user_id=resolved_user_id)
190
+ return f"Successfully deleted all memories for user_id: {resolved_user_id}."
191
+ except Exception as e:
192
+ log_error(f"Error deleting all memories: {e}")
193
+ return f"Error deleting all memories: {e}"
agno/tools/memory.py ADDED
@@ -0,0 +1,419 @@
1
+ import json
2
+ from textwrap import dedent
3
+ from typing import Any, Dict, List, Optional
4
+ from uuid import uuid4
5
+
6
+ from agno.db.base import BaseDb
7
+ from agno.db.schemas import UserMemory
8
+ from agno.tools import Toolkit
9
+ from agno.utils.log import log_debug, log_error
10
+
11
+
12
+ class MemoryTools(Toolkit):
13
+ def __init__(
14
+ self,
15
+ db: BaseDb,
16
+ enable_get_memories: bool = True,
17
+ enable_add_memory: bool = True,
18
+ enable_update_memory: bool = True,
19
+ enable_delete_memory: bool = True,
20
+ enable_analyze: bool = True,
21
+ enable_think: bool = True,
22
+ instructions: Optional[str] = None,
23
+ add_instructions: bool = True,
24
+ add_few_shot: bool = True,
25
+ few_shot_examples: Optional[str] = None,
26
+ all: bool = False,
27
+ **kwargs,
28
+ ):
29
+ # Add instructions for using this toolkit
30
+ if instructions is None:
31
+ self.instructions = self.DEFAULT_INSTRUCTIONS
32
+ if add_few_shot:
33
+ if few_shot_examples is not None:
34
+ self.instructions += "\n" + few_shot_examples
35
+ else:
36
+ self.instructions += "\n" + self.FEW_SHOT_EXAMPLES
37
+ else:
38
+ self.instructions = instructions
39
+
40
+ # The database to use for memory operations
41
+ self.db: BaseDb = db
42
+
43
+ tools: List[Any] = []
44
+ if enable_think or all:
45
+ tools.append(self.think)
46
+ if enable_get_memories or all:
47
+ tools.append(self.get_memories)
48
+ if enable_add_memory or all:
49
+ tools.append(self.add_memory)
50
+ if enable_update_memory or all:
51
+ tools.append(self.update_memory)
52
+ if enable_delete_memory or all:
53
+ tools.append(self.delete_memory)
54
+ if enable_analyze or all:
55
+ tools.append(self.analyze)
56
+
57
+ super().__init__(
58
+ name="memory_tools",
59
+ instructions=self.instructions,
60
+ add_instructions=add_instructions,
61
+ tools=tools,
62
+ **kwargs,
63
+ )
64
+
65
+ def think(self, session_state: Dict[str, Any], thought: str) -> str:
66
+ """Use this tool as a scratchpad to reason about memory operations, refine your approach, brainstorm memory content, or revise your plan.
67
+
68
+ Call `Think` whenever you need to figure out what to do next, analyze the user's requirements, plan memory operations, or decide on execution strategy.
69
+ You should use this tool as frequently as needed.
70
+
71
+ Args:
72
+ thought: Your thought process and reasoning about memory operations.
73
+ """
74
+ try:
75
+ log_debug(f"Memory Thought: {thought}")
76
+
77
+ # Add the thought to the session state
78
+ if session_state is None:
79
+ session_state = {}
80
+ if "memory_thoughts" not in session_state:
81
+ session_state["memory_thoughts"] = []
82
+ session_state["memory_thoughts"].append(thought)
83
+
84
+ # Return the full log of thoughts and the new thought
85
+ thoughts = "\n".join([f"- {t}" for t in session_state["memory_thoughts"]])
86
+ formatted_thoughts = dedent(
87
+ f"""Memory Thoughts:
88
+ {thoughts}
89
+ """
90
+ ).strip()
91
+ return formatted_thoughts
92
+ except Exception as e:
93
+ log_error(f"Error recording memory thought: {e}")
94
+ return f"Error recording memory thought: {e}"
95
+
96
+ def get_memories(self, session_state: Dict[str, Any]) -> str:
97
+ """
98
+ Use this tool to get a list of memories for the current user from the database.
99
+ """
100
+ try:
101
+ # Get user info from session state
102
+ user_id = session_state.get("current_user_id") if session_state else None
103
+
104
+ memories = self.db.get_user_memories(user_id=user_id)
105
+
106
+ # Store the result in session state for analysis
107
+ if session_state is None:
108
+ session_state = {}
109
+ if "memory_operations" not in session_state:
110
+ session_state["memory_operations"] = []
111
+
112
+ operation_result = {
113
+ "operation": "get_memories",
114
+ "success": True,
115
+ "memories": [memory.to_dict() for memory in memories], # type: ignore
116
+ "error": None,
117
+ }
118
+ session_state["memory_operations"].append(operation_result)
119
+
120
+ return json.dumps([memory.to_dict() for memory in memories], indent=2) # type: ignore
121
+ except Exception as e:
122
+ log_error(f"Error getting memories: {e}")
123
+ return json.dumps({"error": str(e)}, indent=2)
124
+
125
+ def add_memory(
126
+ self,
127
+ session_state: Dict[str, Any],
128
+ memory: str,
129
+ topics: Optional[List[str]] = None,
130
+ ) -> str:
131
+ """Use this tool to add a new memory to the database.
132
+
133
+ Args:
134
+ memory: The memory content to store
135
+ topics: Optional list of topics associated with this memory
136
+
137
+ Returns:
138
+ str: JSON string containing the created memory information
139
+ """
140
+ try:
141
+ log_debug(f"Adding memory: {memory}")
142
+
143
+ # Get user and agent info from session state
144
+ user_id = session_state.get("current_user_id") if session_state else None
145
+
146
+ # Create UserMemory object
147
+ user_memory = UserMemory(
148
+ memory_id=str(uuid4()),
149
+ memory=memory,
150
+ topics=topics,
151
+ user_id=user_id,
152
+ )
153
+
154
+ # Add to database
155
+ created_memory = self.db.upsert_user_memory(user_memory)
156
+
157
+ # Store the result in session state for analysis
158
+ if session_state is None:
159
+ session_state = {}
160
+ if "memory_operations" not in session_state:
161
+ session_state["memory_operations"] = []
162
+
163
+ memory_dict = created_memory.to_dict() if created_memory else None # type: ignore
164
+
165
+ operation_result = {
166
+ "operation": "add_memory",
167
+ "success": created_memory is not None,
168
+ "memory": memory_dict,
169
+ "error": None,
170
+ }
171
+ session_state["memory_operations"].append(operation_result)
172
+
173
+ if created_memory:
174
+ return json.dumps({"success": True, "operation": "add_memory", "memory": memory_dict}, indent=2)
175
+ else:
176
+ return json.dumps(
177
+ {"success": False, "operation": "add_memory", "error": "Failed to create memory"}, indent=2
178
+ )
179
+
180
+ except Exception as e:
181
+ log_error(f"Error adding memory: {e}")
182
+ return json.dumps({"success": False, "operation": "add_memory", "error": str(e)}, indent=2)
183
+
184
+ def update_memory(
185
+ self,
186
+ session_state: Dict[str, Any],
187
+ memory_id: str,
188
+ memory: Optional[str] = None,
189
+ topics: Optional[List[str]] = None,
190
+ ) -> str:
191
+ """Use this tool to update an existing memory in the database.
192
+
193
+ Args:
194
+ memory_id: The ID of the memory to update
195
+ memory: Updated memory content (if provided)
196
+ topics: Updated list of topics (if provided)
197
+
198
+ Returns:
199
+ str: JSON string containing the updated memory information
200
+ """
201
+ try:
202
+ log_debug(f"Updating memory: {memory_id}")
203
+
204
+ # First get the existing memory
205
+ existing_memory = self.db.get_user_memory(memory_id)
206
+ if not existing_memory:
207
+ return json.dumps(
208
+ {"success": False, "operation": "update_memory", "error": f"Memory with ID {memory_id} not found"},
209
+ indent=2,
210
+ )
211
+
212
+ # Update fields if provided
213
+ updated_memory = UserMemory(
214
+ memory=memory if memory is not None else existing_memory.memory, # type: ignore
215
+ memory_id=memory_id,
216
+ topics=topics if topics is not None else existing_memory.topics, # type: ignore
217
+ user_id=existing_memory.user_id, # type: ignore
218
+ )
219
+
220
+ # Update in database
221
+ updated_result = self.db.upsert_user_memory(updated_memory)
222
+
223
+ # Store the result in session state for analysis
224
+ if session_state is None:
225
+ session_state = {}
226
+ if "memory_operations" not in session_state:
227
+ session_state["memory_operations"] = []
228
+
229
+ memory_dict = updated_result.to_dict() if updated_result else None # type: ignore
230
+
231
+ operation_result = {
232
+ "operation": "update_memory",
233
+ "success": updated_result is not None,
234
+ "memory": memory_dict,
235
+ "error": None,
236
+ }
237
+ session_state["memory_operations"].append(operation_result)
238
+
239
+ if updated_result:
240
+ return json.dumps({"success": True, "operation": "update_memory", "memory": memory_dict}, indent=2)
241
+ else:
242
+ return json.dumps(
243
+ {"success": False, "operation": "update_memory", "error": "Failed to update memory"}, indent=2
244
+ )
245
+
246
+ except Exception as e:
247
+ log_error(f"Error updating memory: {e}")
248
+ return json.dumps({"success": False, "operation": "update_memory", "error": str(e)}, indent=2)
249
+
250
+ def delete_memory(
251
+ self,
252
+ session_state: Dict[str, Any],
253
+ memory_id: str,
254
+ ) -> str:
255
+ """Use this tool to delete a memory from the database.
256
+
257
+ Args:
258
+ memory_id: The ID of the memory to delete
259
+
260
+ Returns:
261
+ str: JSON string containing the deletion result
262
+ """
263
+ try:
264
+ log_debug(f"Deleting memory: {memory_id}")
265
+
266
+ # Check if memory exists before deletion
267
+ existing_memory = self.db.get_user_memory(memory_id)
268
+ if not existing_memory:
269
+ return json.dumps(
270
+ {"success": False, "operation": "delete_memory", "error": f"Memory with ID {memory_id} not found"},
271
+ indent=2,
272
+ )
273
+
274
+ # Delete from database
275
+ self.db.delete_user_memory(memory_id)
276
+
277
+ # Store the result in session state for analysis
278
+ if session_state is None:
279
+ session_state = {}
280
+ if "memory_operations" not in session_state:
281
+ session_state["memory_operations"] = []
282
+
283
+ memory_dict = existing_memory.to_dict() if existing_memory else None # type: ignore
284
+
285
+ operation_result = {
286
+ "operation": "delete_memory",
287
+ "success": True,
288
+ "memory_id": memory_id,
289
+ "deleted_memory": memory_dict,
290
+ "error": None,
291
+ }
292
+ session_state["memory_operations"].append(operation_result)
293
+
294
+ return json.dumps(
295
+ {
296
+ "success": True,
297
+ "operation": "delete_memory",
298
+ "memory_id": memory_id,
299
+ "deleted_memory": memory_dict,
300
+ },
301
+ indent=2,
302
+ )
303
+
304
+ except Exception as e:
305
+ log_error(f"Error deleting memory: {e}")
306
+ return json.dumps({"success": False, "operation": "delete_memory", "error": str(e)}, indent=2)
307
+
308
+ def analyze(self, session_state: Dict[str, Any], analysis: str) -> str:
309
+ """Use this tool to evaluate whether the memory operations results are correct and sufficient.
310
+ If not, go back to "Think" or use memory operations with refined parameters.
311
+
312
+ Args:
313
+ analysis: Your analysis of the memory operations results.
314
+ """
315
+ try:
316
+ log_debug(f"Memory Analysis: {analysis}")
317
+
318
+ # Add the analysis to the session state
319
+ if session_state is None:
320
+ session_state = {}
321
+ if "memory_analysis" not in session_state:
322
+ session_state["memory_analysis"] = []
323
+ session_state["memory_analysis"].append(analysis)
324
+
325
+ # Return the full log of analysis and the new analysis
326
+ analysis_log = "\n".join([f"- {a}" for a in session_state["memory_analysis"]])
327
+ formatted_analysis = dedent(
328
+ f"""Memory Analysis:
329
+ {analysis_log}
330
+ """
331
+ ).strip()
332
+ return formatted_analysis
333
+ except Exception as e:
334
+ log_error(f"Error recording memory analysis: {e}")
335
+ return f"Error recording memory analysis: {e}"
336
+
337
+ DEFAULT_INSTRUCTIONS = dedent("""\
338
+ You have access to the Think, Add Memory, Update Memory, Delete Memory, and Analyze tools that will help you manage user memories and analyze their operations. Use these tools as frequently as needed to successfully complete memory management tasks.
339
+
340
+ ## How to use the Think, Memory Operations, and Analyze tools:
341
+
342
+ 1. **Think**
343
+ - Purpose: A scratchpad for planning memory operations, brainstorming memory content, and refining your approach. You never reveal your "Think" content to the user.
344
+ - Usage: Call `think` whenever you need to figure out what memory operations to perform, analyze requirements, or decide on strategy.
345
+
346
+ 2. **Get Memories**
347
+ - Purpose: Retrieves a list of memories from the database for the current user.
348
+ - Usage: Call `get_memories` when you need to retrieve memories for the current user.
349
+
350
+ 3. **Add Memory**
351
+ - Purpose: Creates new memories in the database with specified content and metadata.
352
+ - Usage: Call `add_memory` with memory content and optional topics when you need to store new information.
353
+
354
+ 4. **Update Memory**
355
+ - Purpose: Modifies existing memories in the database by memory ID.
356
+ - Usage: Call `update_memory` with a memory ID and the fields you want to change. Only specify the fields that need updating.
357
+
358
+ 5. **Delete Memory**
359
+ - Purpose: Removes memories from the database by memory ID.
360
+ - Usage: Call `delete_memory` with a memory ID when a memory is no longer needed or requested to be removed.
361
+
362
+ 6. **Analyze**
363
+ - Purpose: Evaluate whether the memory operations results are correct and sufficient. If not, go back to "Think" or use memory operations with refined parameters.
364
+ - Usage: Call `analyze` after performing memory operations to verify:
365
+ - Success: Did the operation complete successfully?
366
+ - Accuracy: Is the memory content correct and well-formed?
367
+ - Completeness: Are all required fields populated appropriately?
368
+ - Errors: Were there any failures or unexpected behaviors?
369
+
370
+ **Important Guidelines**:
371
+ - Do not include your internal chain-of-thought in direct user responses.
372
+ - Use "Think" to reason internally. These notes are never exposed to the user.
373
+ - When you provide a final answer to the user, be clear, concise, and based on the memory operation results.
374
+ - If memory operations fail or produce unexpected results, acknowledge limitations and explain what went wrong.
375
+ - Always verify memory IDs exist before attempting updates or deletions.
376
+ - Use descriptive topics and clear memory content to make memories easily searchable and understandable.\
377
+ """)
378
+
379
+ FEW_SHOT_EXAMPLES = dedent("""\
380
+ You can refer to the examples below as guidance for how to use each tool.
381
+
382
+ ### Examples
383
+
384
+ #### Example 1: Adding User Preferences
385
+
386
+ User: I prefer vegetarian recipes and I'm allergic to nuts.
387
+ Think: I should store the user's dietary preferences. I should create a memory with this information and use relevant topics for easy retrieval.
388
+ Add Memory: memory="User prefers vegetarian recipes and is allergic to nuts", topics=["dietary_preferences", "allergies", "food"]
389
+ Analyze: Successfully created memory with dietary preferences. The topics are well-chosen for future retrieval. This should help with future food-related requests.
390
+
391
+ Final Answer: Noted. I've stored your dietary preferences. I'll remember that you prefer vegetarian recipes and have a nut allergy for future reference.
392
+
393
+ #### Example 2: Updating Existing Information
394
+
395
+ User: Actually, update my dietary info - I'm now eating fish too, so I'm pescatarian.
396
+ Think: The user wants to update their previous dietary preference from vegetarian to pescatarian. I need to find their existing dietary memory and update it.
397
+ Update Memory: memory_id="previous_memory_id", memory="User follows pescatarian diet (vegetarian + fish) and is allergic to nuts", topics=["dietary_preferences", "allergies", "food", "pescatarian"]
398
+ Analyze: Successfully updated the dietary preference memory. The content now accurately reflects pescatarian diet and maintains the nut allergy information.
399
+
400
+ Final Answer: I've updated your dietary preferences to reflect that you follow a pescatarian diet (vegetarian plus fish) while maintaining your nut allergy information.
401
+
402
+ #### Example 3: Removing Outdated Information
403
+
404
+ User: Please forget about my old work schedule - it's completely changed.
405
+ Think: The user wants me to delete their old work schedule memory since it's no longer relevant. I should find and remove that memory.
406
+ Delete Memory: memory_id="work_schedule_memory_id"
407
+ Analyze: Successfully deleted the outdated work schedule memory. The old information won't interfere with future scheduling requests.
408
+
409
+ Final Answer: I've removed your old work schedule information. Feel free to share your new schedule when you're ready, and I'll store the updated information.
410
+
411
+ #### Example 4: Retrieving Memories
412
+
413
+ User: What have you remembered about me?
414
+ Think: The user wants to retrieve memories about themselves. I should use the get_memories tool to retrieve the memories.
415
+ Get Memories:
416
+ Analyze: Successfully retrieved the memories about the user. The memories are relevant to the user's preferences and activities.
417
+
418
+ Final Answer: I've retrieved the memories about you. You like to hike in the mountains on weekends and travel to new places and experience different cultures. You are planning to travel to Africa in December.\
419
+ """)
@@ -20,7 +20,7 @@ from pathlib import Path
20
20
  from typing import Any, Dict, List, Optional, Tuple, Union
21
21
 
22
22
  from agno.tools import Toolkit
23
- from agno.utils.log import logger
23
+ from agno.utils.log import log_info, logger
24
24
 
25
25
  try:
26
26
  import mlx_whisper
@@ -32,7 +32,7 @@ class MLXTranscribeTools(Toolkit):
32
32
  def __init__(
33
33
  self,
34
34
  base_dir: Optional[Path] = None,
35
- read_files_in_base_dir: bool = True,
35
+ enable_read_files_in_base_dir: bool = True,
36
36
  path_or_hf_repo: str = "mlx-community/whisper-large-v3-turbo",
37
37
  verbose: Optional[bool] = None,
38
38
  temperature: Optional[Union[float, Tuple[float, ...]]] = None,
@@ -47,9 +47,9 @@ class MLXTranscribeTools(Toolkit):
47
47
  clip_timestamps: Optional[Union[str, List[float]]] = None,
48
48
  hallucination_silence_threshold: Optional[float] = None,
49
49
  decode_options: Optional[dict] = None,
50
+ all: bool = False,
51
+ **kwargs,
50
52
  ):
51
- super().__init__(name="mlx_transcribe")
52
-
53
53
  self.base_dir: Path = base_dir or Path.cwd()
54
54
  self.path_or_hf_repo: str = path_or_hf_repo
55
55
  self.verbose: Optional[bool] = verbose
@@ -66,9 +66,11 @@ class MLXTranscribeTools(Toolkit):
66
66
  self.hallucination_silence_threshold: Optional[float] = hallucination_silence_threshold
67
67
  self.decode_options: Optional[dict] = decode_options
68
68
 
69
- self.register(self.transcribe)
70
- if read_files_in_base_dir:
71
- self.register(self.read_files)
69
+ tools: List[Any] = [self.transcribe]
70
+ if enable_read_files_in_base_dir or all:
71
+ tools.append(self.read_files)
72
+
73
+ super().__init__(name="mlx_transcribe", tools=tools, **kwargs)
72
74
 
73
75
  def transcribe(self, file_name: str) -> str:
74
76
  """
@@ -85,7 +87,7 @@ class MLXTranscribeTools(Toolkit):
85
87
  if audio_file_path is None:
86
88
  return "No audio file path provided"
87
89
 
88
- logger.info(f"Transcribing audio file {audio_file_path}")
90
+ log_info(f"Transcribing audio file {audio_file_path}")
89
91
  transcription_kwargs: Dict[str, Any] = {
90
92
  "path_or_hf_repo": self.path_or_hf_repo,
91
93
  }
@@ -130,7 +132,7 @@ class MLXTranscribeTools(Toolkit):
130
132
  str: A JSON string containing the list of files in the base directory.
131
133
  """
132
134
  try:
133
- logger.info(f"Reading files in : {self.base_dir}")
135
+ log_info(f"Reading files in : {self.base_dir}")
134
136
  return json.dumps([str(file_name) for file_name in self.base_dir.iterdir()], indent=4)
135
137
  except Exception as e:
136
138
  logger.error(f"Error reading files: {e}")