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/utils/prompts.py CHANGED
@@ -6,28 +6,28 @@ from pydantic import BaseModel
6
6
  from agno.utils.log import log_warning
7
7
 
8
8
 
9
- def get_json_output_prompt(response_model: Union[str, list, BaseModel]) -> str:
9
+ def get_json_output_prompt(output_schema: Union[str, list, BaseModel]) -> str:
10
10
  """Return the JSON output prompt for the Agent.
11
11
 
12
- This is added to the system prompt when the response_model is set and structured_outputs is False.
12
+ This is added to the system prompt when the output_schema is set and structured_outputs is False.
13
13
  """
14
14
 
15
15
  json_output_prompt = "Provide your output as a JSON containing the following fields:"
16
- if response_model is not None:
17
- if isinstance(response_model, str):
16
+ if output_schema is not None:
17
+ if isinstance(output_schema, str):
18
18
  json_output_prompt += "\n<json_fields>"
19
- json_output_prompt += f"\n{response_model}"
19
+ json_output_prompt += f"\n{output_schema}"
20
20
  json_output_prompt += "\n</json_fields>"
21
- elif isinstance(response_model, list):
21
+ elif isinstance(output_schema, list):
22
22
  json_output_prompt += "\n<json_fields>"
23
- json_output_prompt += f"\n{json.dumps(response_model)}"
23
+ json_output_prompt += f"\n{json.dumps(output_schema)}"
24
24
  json_output_prompt += "\n</json_fields>"
25
25
  elif (
26
- issubclass(type(response_model), BaseModel)
27
- or issubclass(response_model, BaseModel) # type: ignore
28
- or isinstance(response_model, BaseModel)
26
+ issubclass(type(output_schema), BaseModel)
27
+ or issubclass(output_schema, BaseModel) # type: ignore
28
+ or isinstance(output_schema, BaseModel)
29
29
  ): # type: ignore
30
- json_schema = response_model.model_json_schema()
30
+ json_schema = output_schema.model_json_schema()
31
31
  if json_schema is not None:
32
32
  response_model_properties = {}
33
33
  json_schema_properties = json_schema.get("properties")
@@ -85,7 +85,7 @@ def get_json_output_prompt(response_model: Union[str, list, BaseModel]) -> str:
85
85
  json_output_prompt += f"\n{json.dumps(response_model_properties, indent=2)}"
86
86
  json_output_prompt += "\n</json_field_properties>"
87
87
  else:
88
- log_warning(f"Could not build json schema for {response_model}")
88
+ log_warning(f"Could not build json schema for {output_schema}")
89
89
  else:
90
90
  json_output_prompt += "Provide the output as JSON."
91
91
 
@@ -95,13 +95,13 @@ def get_json_output_prompt(response_model: Union[str, list, BaseModel]) -> str:
95
95
  return json_output_prompt
96
96
 
97
97
 
98
- def get_response_model_format_prompt(response_model: Type[BaseModel]) -> str:
98
+ def get_response_model_format_prompt(output_schema: Type[BaseModel]) -> str:
99
99
  """Return the format prompt for the response model."""
100
100
 
101
101
  message = "Make sure your response is a valid string (NOT JSON) that mentions the following topics:"
102
102
 
103
103
  # Extract field names and descriptions
104
- for field_name, field_info in response_model.model_fields.items():
104
+ for field_name, field_info in output_schema.model_fields.items():
105
105
  description = field_info.description or ""
106
106
  if description:
107
107
  message += f"\n- {field_name}: {description}"
@@ -0,0 +1,87 @@
1
+ from typing import TYPE_CHECKING, List, Union
2
+
3
+ from agno.models.message import Message
4
+ from agno.models.metrics import Metrics
5
+ from agno.reasoning.step import ReasoningStep
6
+
7
+ if TYPE_CHECKING:
8
+ from agno.run.agent import RunOutput
9
+ from agno.team.team import TeamRunOutput
10
+
11
+
12
+ def append_to_reasoning_content(run_response: Union["RunOutput", "TeamRunOutput"], content: str) -> None:
13
+ """Helper to append content to the reasoning_content field."""
14
+ if not hasattr(run_response, "reasoning_content") or not run_response.reasoning_content: # type: ignore
15
+ run_response.reasoning_content = content # type: ignore
16
+ else:
17
+ run_response.reasoning_content += content # type: ignore
18
+
19
+
20
+ def add_reasoning_step_to_metadata(
21
+ run_response: Union["RunOutput", "TeamRunOutput"], reasoning_step: ReasoningStep
22
+ ) -> None:
23
+ if run_response.reasoning_steps is None:
24
+ run_response.reasoning_steps = []
25
+
26
+ run_response.reasoning_steps.append(reasoning_step)
27
+
28
+
29
+ def add_reasoning_metrics_to_metadata(
30
+ run_response: Union["RunOutput", "TeamRunOutput"], reasoning_time_taken: float
31
+ ) -> None:
32
+ try:
33
+ # Initialize reasoning_messages if it doesn't exist
34
+ if run_response.reasoning_messages is None:
35
+ run_response.reasoning_messages = []
36
+
37
+ metrics_message = Message(
38
+ role="assistant",
39
+ content=run_response.reasoning_content,
40
+ metrics=Metrics(duration=reasoning_time_taken),
41
+ )
42
+
43
+ # Add the metrics message to the reasoning_messages
44
+ run_response.reasoning_messages.append(metrics_message)
45
+
46
+ except Exception as e:
47
+ # Log the error but don't crash
48
+ from agno.utils.log import log_error
49
+
50
+ log_error(f"Failed to add reasoning metrics to metadata: {str(e)}")
51
+
52
+
53
+ def update_run_output_with_reasoning(
54
+ run_response: Union["RunOutput", "TeamRunOutput"],
55
+ reasoning_steps: List[ReasoningStep],
56
+ reasoning_agent_messages: List[Message],
57
+ ) -> None:
58
+ # Update reasoning_steps
59
+ if run_response.reasoning_steps is None:
60
+ run_response.reasoning_steps = reasoning_steps
61
+ else:
62
+ run_response.reasoning_steps.extend(reasoning_steps)
63
+
64
+ # Update reasoning_messages
65
+ if run_response.reasoning_messages is None:
66
+ run_response.reasoning_messages = reasoning_agent_messages
67
+ else:
68
+ run_response.reasoning_messages.extend(reasoning_agent_messages)
69
+
70
+ # Create and store reasoning_content
71
+ reasoning_content = ""
72
+ for step in reasoning_steps:
73
+ if step.title:
74
+ reasoning_content += f"## {step.title}\n"
75
+ if step.reasoning:
76
+ reasoning_content += f"{step.reasoning}\n"
77
+ if step.action:
78
+ reasoning_content += f"Action: {step.action}\n"
79
+ if step.result:
80
+ reasoning_content += f"Result: {step.result}\n"
81
+ reasoning_content += "\n"
82
+
83
+ # Add to existing reasoning_content or set it
84
+ if not run_response.reasoning_content:
85
+ run_response.reasoning_content = reasoning_content
86
+ else:
87
+ run_response.reasoning_content += reasoning_content
agno/utils/response.py CHANGED
@@ -1,12 +1,10 @@
1
1
  from typing import AsyncIterator, Iterator, List, Set, Union
2
2
 
3
3
  from agno.exceptions import RunCancelledException
4
- from agno.models.message import Message
5
4
  from agno.models.response import ToolExecution
6
5
  from agno.reasoning.step import ReasoningStep
7
- from agno.run.base import RunResponseExtraData
8
- from agno.run.response import RunResponse, RunResponseEvent, RunResponsePausedEvent
9
- from agno.run.team import TeamRunResponse, TeamRunResponseEvent
6
+ from agno.run.agent import RunOutput, RunOutputEvent, RunPausedEvent
7
+ from agno.run.team import TeamRunOutput, TeamRunOutputEvent
10
8
 
11
9
 
12
10
  def create_panel(content, title, border_style="blue"):
@@ -18,6 +16,29 @@ def create_panel(content, title, border_style="blue"):
18
16
  )
19
17
 
20
18
 
19
+ def build_reasoning_step_panel(
20
+ step_idx: int, step: ReasoningStep, show_full_reasoning: bool = False, color: str = "green"
21
+ ):
22
+ from rich.text import Text
23
+
24
+ # Build step content
25
+ step_content = Text.assemble()
26
+ if step.title is not None:
27
+ step_content.append(f"{step.title}\n", "bold")
28
+ if step.action is not None:
29
+ step_content.append(Text.from_markup(f"[bold]Action:[/bold] {step.action}\n", style="dim"))
30
+ if step.result is not None:
31
+ step_content.append(Text.from_markup(step.result, style="dim"))
32
+
33
+ if show_full_reasoning:
34
+ # Add detailed reasoning information if available
35
+ if step.reasoning is not None:
36
+ step_content.append(Text.from_markup(f"\n[bold]Reasoning:[/bold] {step.reasoning}", style="dim"))
37
+ if step.confidence is not None:
38
+ step_content.append(Text.from_markup(f"\n[bold]Confidence:[/bold] {step.confidence}", style="dim"))
39
+ return create_panel(content=step_content, title=f"Reasoning step {step_idx}", border_style=color)
40
+
41
+
21
42
  def escape_markdown_tags(content: str, tags: Set[str]) -> str:
22
43
  """Escape special tags in markdown content."""
23
44
  escaped_content = content
@@ -29,32 +50,11 @@ def escape_markdown_tags(content: str, tags: Set[str]) -> str:
29
50
  return escaped_content
30
51
 
31
52
 
32
- def check_if_run_cancelled(run_response: Union[RunResponse, RunResponseEvent, TeamRunResponse, TeamRunResponseEvent]):
33
- if run_response.is_cancelled:
53
+ def check_if_run_cancelled(run_output: Union[RunOutput, RunOutputEvent, TeamRunOutput, TeamRunOutputEvent]):
54
+ if run_output.is_cancelled:
34
55
  raise RunCancelledException()
35
56
 
36
57
 
37
- def update_run_response_with_reasoning(
38
- run_response: Union[RunResponse, TeamRunResponse],
39
- reasoning_steps: List[ReasoningStep],
40
- reasoning_agent_messages: List[Message],
41
- ) -> None:
42
- if run_response.extra_data is None:
43
- run_response.extra_data = RunResponseExtraData()
44
-
45
- # Update reasoning_steps
46
- if run_response.extra_data.reasoning_steps is None:
47
- run_response.extra_data.reasoning_steps = reasoning_steps
48
- else:
49
- run_response.extra_data.reasoning_steps.extend(reasoning_steps)
50
-
51
- # Update reasoning_messages
52
- if run_response.extra_data.reasoning_messages is None:
53
- run_response.extra_data.reasoning_messages = reasoning_agent_messages
54
- else:
55
- run_response.extra_data.reasoning_messages.extend(reasoning_agent_messages)
56
-
57
-
58
58
  def format_tool_calls(tool_calls: List[ToolExecution]) -> List[str]:
59
59
  """Format tool calls for display in a readable format.
60
60
 
@@ -70,39 +70,39 @@ def format_tool_calls(tool_calls: List[ToolExecution]) -> List[str]:
70
70
  if tool_call.tool_name is not None:
71
71
  tool_name = tool_call.tool_name
72
72
  args_str = ""
73
- if tool_call.tool_args is not None:
73
+ if tool_call.tool_args is not None and tool_call.tool_args: # Check if args exist and are non-empty
74
74
  args_str = ", ".join(f"{k}={v}" for k, v in tool_call.tool_args.items())
75
75
  formatted_tool_calls.append(f"{tool_name}({args_str})")
76
76
 
77
77
  return formatted_tool_calls
78
78
 
79
79
 
80
- def create_paused_run_response_panel(run_response: Union[RunResponsePausedEvent, RunResponse]):
80
+ def create_paused_run_output_panel(run_output: Union[RunPausedEvent, RunOutput]):
81
81
  from rich.text import Text
82
82
 
83
83
  tool_calls_content = Text("Run is paused. ")
84
- if run_response.tools is not None:
85
- if any(tc.requires_confirmation for tc in run_response.tools):
84
+ if run_output.tools is not None:
85
+ if any(tc.requires_confirmation for tc in run_output.tools):
86
86
  tool_calls_content.append("The following tool calls require confirmation:\n")
87
- for tool_call in run_response.tools:
87
+ for tool_call in run_output.tools:
88
88
  if tool_call.requires_confirmation:
89
89
  args_str = ""
90
90
  for arg, value in tool_call.tool_args.items() if tool_call.tool_args else {}:
91
91
  args_str += f"{arg}={value}, "
92
92
  args_str = args_str.rstrip(", ")
93
93
  tool_calls_content.append(f"• {tool_call.tool_name}({args_str})\n")
94
- if any(tc.requires_user_input for tc in run_response.tools):
94
+ if any(tc.requires_user_input for tc in run_output.tools):
95
95
  tool_calls_content.append("The following tool calls require user input:\n")
96
- for tool_call in run_response.tools:
96
+ for tool_call in run_output.tools:
97
97
  if tool_call.requires_user_input:
98
98
  args_str = ""
99
99
  for arg, value in tool_call.tool_args.items() if tool_call.tool_args else {}:
100
100
  args_str += f"{arg}={value}, "
101
101
  args_str = args_str.rstrip(", ")
102
102
  tool_calls_content.append(f"• {tool_call.tool_name}({args_str})\n")
103
- if any(tc.external_execution_required for tc in run_response.tools):
103
+ if any(tc.external_execution_required for tc in run_output.tools):
104
104
  tool_calls_content.append("The following tool calls require external execution:\n")
105
- for tool_call in run_response.tools:
105
+ for tool_call in run_output.tools:
106
106
  if tool_call.external_execution_required:
107
107
  args_str = ""
108
108
  for arg, value in tool_call.tool_args.items() if tool_call.tool_args else {}:
@@ -119,9 +119,9 @@ def create_paused_run_response_panel(run_response: Union[RunResponsePausedEvent,
119
119
  return response_panel
120
120
 
121
121
 
122
- def get_paused_content(run_response: RunResponse) -> str:
122
+ def get_paused_content(run_output: RunOutput) -> str:
123
123
  paused_content = ""
124
- for tool in run_response.tools or []:
124
+ for tool in run_output.tools or []:
125
125
  # Initialize flags for each tool
126
126
  confirmation_required = False
127
127
  user_input_required = False
@@ -152,12 +152,12 @@ def get_paused_content(run_response: RunResponse) -> str:
152
152
 
153
153
 
154
154
  def generator_wrapper(
155
- event: Union[RunResponseEvent, TeamRunResponseEvent],
156
- ) -> Iterator[Union[RunResponseEvent, TeamRunResponseEvent]]:
155
+ event: Union[RunOutputEvent, TeamRunOutputEvent],
156
+ ) -> Iterator[Union[RunOutputEvent, TeamRunOutputEvent]]:
157
157
  yield event
158
158
 
159
159
 
160
160
  async def async_generator_wrapper(
161
- event: Union[RunResponseEvent, TeamRunResponseEvent],
162
- ) -> AsyncIterator[Union[RunResponseEvent, TeamRunResponseEvent]]:
161
+ event: Union[RunOutputEvent, TeamRunOutputEvent],
162
+ ) -> AsyncIterator[Union[RunOutputEvent, TeamRunOutputEvent]]:
163
163
  yield event
agno/utils/string.py CHANGED
@@ -27,20 +27,6 @@ def is_valid_uuid(uuid_str: str) -> bool:
27
27
  return False
28
28
 
29
29
 
30
- def safe_content_hash(content: str) -> str:
31
- """
32
- Return an MD5 hash of the input string, replacing null bytes and invalid surrogates for safe hashing.
33
- """
34
- cleaned_content = content.replace("\x00", "\ufffd")
35
- try:
36
- content_hash = hashlib.md5(cleaned_content.encode("utf-8")).hexdigest()
37
- except UnicodeEncodeError:
38
- cleaned_content = "".join("\ufffd" if "\ud800" <= c <= "\udfff" else c for c in cleaned_content)
39
- content_hash = hashlib.md5(cleaned_content.encode("utf-8")).hexdigest()
40
-
41
- return content_hash
42
-
43
-
44
30
  def url_safe_string(input_string):
45
31
  # Replace spaces with dashes
46
32
  safe_string = input_string.replace(" ", "-")
@@ -130,13 +116,13 @@ def _clean_json_content(content: str) -> str:
130
116
  return content
131
117
 
132
118
 
133
- def _parse_individual_json(content: str, response_model: Type[BaseModel]) -> Optional[BaseModel]:
119
+ def _parse_individual_json(content: str, output_schema: Type[BaseModel]) -> Optional[BaseModel]:
134
120
  """Parse individual JSON objects from content and merge them based on response model fields."""
135
121
  candidate_jsons = _extract_json_objects(content)
136
122
  merged_data: dict = {}
137
123
 
138
124
  # Get the expected fields from the response model
139
- model_fields = response_model.model_fields if hasattr(response_model, "model_fields") else {}
125
+ model_fields = output_schema.model_fields if hasattr(output_schema, "model_fields") else {}
140
126
 
141
127
  for candidate in candidate_jsons:
142
128
  try:
@@ -161,13 +147,13 @@ def _parse_individual_json(content: str, response_model: Type[BaseModel]) -> Opt
161
147
  return None
162
148
 
163
149
  try:
164
- return response_model.model_validate(merged_data)
150
+ return output_schema.model_validate(merged_data)
165
151
  except ValidationError as e:
166
152
  logger.warning("Validation failed on merged data: %s", e)
167
153
  return None
168
154
 
169
155
 
170
- def parse_response_model_str(content: str, response_model: Type[BaseModel]) -> Optional[BaseModel]:
156
+ def parse_response_model_str(content: str, output_schema: Type[BaseModel]) -> Optional[BaseModel]:
171
157
  structured_output = None
172
158
 
173
159
  # Clean content first to simplify all parsing attempts
@@ -175,12 +161,12 @@ def parse_response_model_str(content: str, response_model: Type[BaseModel]) -> O
175
161
 
176
162
  try:
177
163
  # First attempt: direct JSON validation on cleaned content
178
- structured_output = response_model.model_validate_json(cleaned_content)
164
+ structured_output = output_schema.model_validate_json(cleaned_content)
179
165
  except (ValidationError, json.JSONDecodeError):
180
166
  try:
181
167
  # Second attempt: Parse as Python dict
182
168
  data = json.loads(cleaned_content)
183
- structured_output = response_model.model_validate(data)
169
+ structured_output = output_schema.model_validate(data)
184
170
  except (ValidationError, json.JSONDecodeError) as e:
185
171
  logger.warning(f"Failed to parse cleaned JSON: {e}")
186
172
 
@@ -191,13 +177,13 @@ def parse_response_model_str(content: str, response_model: Type[BaseModel]) -> O
191
177
  # Single JSON object - try to parse it directly
192
178
  try:
193
179
  data = json.loads(candidate_jsons[0])
194
- structured_output = response_model.model_validate(data)
180
+ structured_output = output_schema.model_validate(data)
195
181
  except (ValidationError, json.JSONDecodeError):
196
182
  pass
197
183
 
198
184
  if structured_output is None:
199
185
  # Final attempt: Handle concatenated JSON objects with field merging
200
- structured_output = _parse_individual_json(cleaned_content, response_model)
186
+ structured_output = _parse_individual_json(cleaned_content, output_schema)
201
187
  if structured_output is None:
202
188
  logger.warning("All parsing attempts failed.")
203
189
 
agno/utils/team.py ADDED
@@ -0,0 +1,50 @@
1
+ from typing import TYPE_CHECKING, Optional, Union
2
+
3
+ from agno.agent import Agent
4
+ from agno.utils.string import is_valid_uuid, url_safe_string
5
+
6
+ if TYPE_CHECKING:
7
+ from agno.team.team import Team
8
+
9
+
10
+ def format_member_agent_task(
11
+ task_description: str,
12
+ expected_output: Optional[str] = None,
13
+ team_member_interactions_str: Optional[str] = None,
14
+ ) -> str:
15
+ member_agent_task = "You are a member of a team of agents. Your goal is to complete the following task:"
16
+ member_agent_task += f"\n\n<task>\n{task_description}\n</task>"
17
+
18
+ if expected_output is not None:
19
+ member_agent_task += f"\n\n<expected_output>\n{expected_output}\n</expected_output>"
20
+
21
+ if team_member_interactions_str:
22
+ member_agent_task += f"\n\n{team_member_interactions_str}"
23
+
24
+ return member_agent_task
25
+
26
+
27
+ def get_member_id(member: Union[Agent, "Team"]) -> str:
28
+ """
29
+ Get the ID of a member
30
+
31
+ If the member has an agent_id or team_id, use that if it is not a valid UUID.
32
+ Then if the member has a name, convert that to a URL safe string.
33
+ Then if the member has the default UUID ID, use that.
34
+ Otherwise, return None.
35
+ """
36
+ from agno.team.team import Team
37
+
38
+ if isinstance(member, Agent) and member.id is not None and (not is_valid_uuid(member.id)):
39
+ url_safe_member_id = url_safe_string(member.id)
40
+ elif isinstance(member, Team) and member.id is not None and (not is_valid_uuid(member.id)):
41
+ url_safe_member_id = url_safe_string(member.id)
42
+ elif member.name is not None:
43
+ url_safe_member_id = url_safe_string(member.name)
44
+ elif isinstance(member, Agent) and member.id is not None:
45
+ url_safe_member_id = member.id
46
+ elif isinstance(member, Team) and member.id is not None:
47
+ url_safe_member_id = member.id
48
+ else:
49
+ url_safe_member_id = None
50
+ return url_safe_member_id
agno/utils/timer.py CHANGED
@@ -24,11 +24,11 @@ class Timer:
24
24
  self.elapsed_time = self.end_time - self.start_time
25
25
  return self.end_time
26
26
 
27
- def __enter__(self):
27
+ def __enter__(self) -> "Timer":
28
28
  self.start_time = perf_counter()
29
29
  return self
30
30
 
31
- def __exit__(self, *args):
31
+ def __exit__(self, *args) -> None:
32
32
  self.end_time = perf_counter()
33
33
  if self.start_time is not None:
34
34
  self.elapsed_time = self.end_time - self.start_time
agno/vectordb/base.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from abc import ABC, abstractmethod
2
2
  from typing import Any, Dict, List, Optional
3
3
 
4
- from agno.document import Document
4
+ from agno.knowledge.document import Document
5
5
 
6
6
 
7
7
  class VectorDb(ABC):
@@ -16,41 +16,42 @@ class VectorDb(ABC):
16
16
  raise NotImplementedError
17
17
 
18
18
  @abstractmethod
19
- def doc_exists(self, document: Document) -> bool:
19
+ def name_exists(self, name: str) -> bool:
20
20
  raise NotImplementedError
21
21
 
22
22
  @abstractmethod
23
- async def async_doc_exists(self, document: Document) -> bool:
23
+ def async_name_exists(self, name: str) -> bool:
24
24
  raise NotImplementedError
25
25
 
26
26
  @abstractmethod
27
- def name_exists(self, name: str) -> bool:
27
+ def id_exists(self, id: str) -> bool:
28
28
  raise NotImplementedError
29
29
 
30
30
  @abstractmethod
31
- def async_name_exists(self, name: str) -> bool:
32
- raise NotImplementedError
33
-
34
- def id_exists(self, id: str) -> bool:
31
+ def content_hash_exists(self, content_hash: str) -> bool:
35
32
  raise NotImplementedError
36
33
 
37
34
  @abstractmethod
38
- def insert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
35
+ def insert(self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
39
36
  raise NotImplementedError
40
37
 
41
38
  @abstractmethod
42
- async def async_insert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
39
+ async def async_insert(
40
+ self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None
41
+ ) -> None:
43
42
  raise NotImplementedError
44
43
 
45
44
  def upsert_available(self) -> bool:
46
45
  return False
47
46
 
48
47
  @abstractmethod
49
- def upsert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
48
+ def upsert(self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
50
49
  raise NotImplementedError
51
50
 
52
51
  @abstractmethod
53
- async def async_upsert(self, documents: List[Document], filters: Optional[Dict[str, Any]] = None) -> None:
52
+ async def async_upsert(
53
+ self, content_hash: str, documents: List[Document], filters: Optional[Dict[str, Any]] = None
54
+ ) -> None:
54
55
  raise NotImplementedError
55
56
 
56
57
  @abstractmethod
@@ -63,15 +64,6 @@ class VectorDb(ABC):
63
64
  ) -> List[Document]:
64
65
  raise NotImplementedError
65
66
 
66
- def vector_search(self, query: str, limit: int = 5) -> List[Document]:
67
- raise NotImplementedError
68
-
69
- def keyword_search(self, query: str, limit: int = 5) -> List[Document]:
70
- raise NotImplementedError
71
-
72
- def hybrid_search(self, query: str, limit: int = 5) -> List[Document]:
73
- raise NotImplementedError
74
-
75
67
  @abstractmethod
76
68
  def drop(self) -> None:
77
69
  raise NotImplementedError
@@ -94,3 +86,23 @@ class VectorDb(ABC):
94
86
  @abstractmethod
95
87
  def delete(self) -> bool:
96
88
  raise NotImplementedError
89
+
90
+ @abstractmethod
91
+ def delete_by_id(self, id: str) -> bool:
92
+ raise NotImplementedError
93
+
94
+ @abstractmethod
95
+ def delete_by_name(self, name: str) -> bool:
96
+ raise NotImplementedError
97
+
98
+ @abstractmethod
99
+ def delete_by_metadata(self, metadata: Dict[str, Any]) -> bool:
100
+ raise NotImplementedError
101
+
102
+ @abstractmethod
103
+ def update_metadata(self, content_id: str, metadata: Dict[str, Any]) -> None:
104
+ raise NotImplementedError
105
+
106
+ @abstractmethod
107
+ def delete_by_content_id(self, content_id: str) -> bool:
108
+ raise NotImplementedError