agno 1.8.1__py3-none-any.whl → 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (590) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +3143 -4170
  4. agno/api/agent.py +11 -67
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +8 -19
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -41
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +5 -21
  11. agno/api/schemas/evals.py +7 -16
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +5 -21
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +11 -7
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +11 -66
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/db/__init__.py +24 -0
  25. agno/db/base.py +245 -0
  26. agno/db/dynamo/__init__.py +3 -0
  27. agno/db/dynamo/dynamo.py +1743 -0
  28. agno/db/dynamo/schemas.py +278 -0
  29. agno/db/dynamo/utils.py +684 -0
  30. agno/db/firestore/__init__.py +3 -0
  31. agno/db/firestore/firestore.py +1432 -0
  32. agno/db/firestore/schemas.py +130 -0
  33. agno/db/firestore/utils.py +278 -0
  34. agno/db/gcs_json/__init__.py +3 -0
  35. agno/db/gcs_json/gcs_json_db.py +1001 -0
  36. agno/db/gcs_json/utils.py +194 -0
  37. agno/db/in_memory/__init__.py +3 -0
  38. agno/db/in_memory/in_memory_db.py +882 -0
  39. agno/db/in_memory/utils.py +172 -0
  40. agno/db/json/__init__.py +3 -0
  41. agno/db/json/json_db.py +1045 -0
  42. agno/db/json/utils.py +196 -0
  43. agno/db/migrations/v1_to_v2.py +162 -0
  44. agno/db/mongo/__init__.py +3 -0
  45. agno/db/mongo/mongo.py +1416 -0
  46. agno/db/mongo/schemas.py +77 -0
  47. agno/db/mongo/utils.py +204 -0
  48. agno/db/mysql/__init__.py +3 -0
  49. agno/db/mysql/mysql.py +1719 -0
  50. agno/db/mysql/schemas.py +124 -0
  51. agno/db/mysql/utils.py +297 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1710 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +280 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1367 -0
  58. agno/db/redis/schemas.py +109 -0
  59. agno/db/redis/utils.py +288 -0
  60. agno/db/schemas/__init__.py +3 -0
  61. agno/db/schemas/evals.py +33 -0
  62. agno/db/schemas/knowledge.py +40 -0
  63. agno/db/schemas/memory.py +46 -0
  64. agno/db/singlestore/__init__.py +3 -0
  65. agno/db/singlestore/schemas.py +116 -0
  66. agno/db/singlestore/singlestore.py +1712 -0
  67. agno/db/singlestore/utils.py +326 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1676 -0
  71. agno/db/sqlite/utils.py +268 -0
  72. agno/db/utils.py +88 -0
  73. agno/eval/__init__.py +14 -0
  74. agno/eval/accuracy.py +154 -48
  75. agno/eval/performance.py +88 -23
  76. agno/eval/reliability.py +73 -20
  77. agno/eval/utils.py +23 -13
  78. agno/integrations/discord/__init__.py +3 -0
  79. agno/{app → integrations}/discord/client.py +15 -11
  80. agno/knowledge/__init__.py +2 -2
  81. agno/{document → knowledge}/chunking/agentic.py +2 -2
  82. agno/{document → knowledge}/chunking/document.py +2 -2
  83. agno/{document → knowledge}/chunking/fixed.py +3 -3
  84. agno/{document → knowledge}/chunking/markdown.py +2 -2
  85. agno/{document → knowledge}/chunking/recursive.py +2 -2
  86. agno/{document → knowledge}/chunking/row.py +2 -2
  87. agno/knowledge/chunking/semantic.py +59 -0
  88. agno/knowledge/chunking/strategy.py +121 -0
  89. agno/knowledge/content.py +74 -0
  90. agno/knowledge/document/__init__.py +5 -0
  91. agno/{document → knowledge/document}/base.py +12 -2
  92. agno/knowledge/embedder/__init__.py +5 -0
  93. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  94. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  95. agno/{embedder → knowledge/embedder}/base.py +6 -0
  96. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  97. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  98. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  99. agno/{embedder → knowledge/embedder}/google.py +74 -1
  100. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  101. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  102. agno/knowledge/embedder/langdb.py +22 -0
  103. agno/knowledge/embedder/mistral.py +139 -0
  104. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  105. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  106. agno/knowledge/embedder/openai.py +223 -0
  107. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  108. agno/{embedder → knowledge/embedder}/together.py +1 -1
  109. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  110. agno/knowledge/knowledge.py +1551 -0
  111. agno/knowledge/reader/__init__.py +7 -0
  112. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  113. agno/knowledge/reader/base.py +88 -0
  114. agno/{document → knowledge}/reader/csv_reader.py +47 -65
  115. agno/knowledge/reader/docx_reader.py +83 -0
  116. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  117. agno/{document → knowledge}/reader/json_reader.py +30 -9
  118. agno/{document → knowledge}/reader/markdown_reader.py +58 -9
  119. agno/{document → knowledge}/reader/pdf_reader.py +71 -126
  120. agno/knowledge/reader/reader_factory.py +268 -0
  121. agno/knowledge/reader/s3_reader.py +101 -0
  122. agno/{document → knowledge}/reader/text_reader.py +31 -10
  123. agno/knowledge/reader/url_reader.py +128 -0
  124. agno/knowledge/reader/web_search_reader.py +366 -0
  125. agno/{document → knowledge}/reader/website_reader.py +37 -10
  126. agno/knowledge/reader/wikipedia_reader.py +59 -0
  127. agno/knowledge/reader/youtube_reader.py +78 -0
  128. agno/knowledge/remote_content/remote_content.py +88 -0
  129. agno/{reranker → knowledge/reranker}/base.py +1 -1
  130. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  131. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  132. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  133. agno/knowledge/types.py +30 -0
  134. agno/knowledge/utils.py +169 -0
  135. agno/media.py +269 -268
  136. agno/memory/__init__.py +2 -10
  137. agno/memory/manager.py +1003 -148
  138. agno/models/aimlapi/__init__.py +2 -2
  139. agno/models/aimlapi/aimlapi.py +6 -6
  140. agno/models/anthropic/claude.py +131 -131
  141. agno/models/aws/bedrock.py +110 -182
  142. agno/models/aws/claude.py +64 -18
  143. agno/models/azure/ai_foundry.py +73 -23
  144. agno/models/base.py +346 -290
  145. agno/models/cerebras/cerebras.py +84 -27
  146. agno/models/cohere/chat.py +106 -98
  147. agno/models/google/gemini.py +105 -46
  148. agno/models/groq/groq.py +97 -35
  149. agno/models/huggingface/huggingface.py +92 -27
  150. agno/models/ibm/watsonx.py +72 -13
  151. agno/models/litellm/chat.py +85 -13
  152. agno/models/message.py +46 -151
  153. agno/models/meta/llama.py +85 -49
  154. agno/models/metrics.py +120 -0
  155. agno/models/mistral/mistral.py +90 -21
  156. agno/models/ollama/__init__.py +0 -2
  157. agno/models/ollama/chat.py +85 -47
  158. agno/models/openai/chat.py +154 -37
  159. agno/models/openai/responses.py +178 -105
  160. agno/models/perplexity/perplexity.py +26 -2
  161. agno/models/portkey/portkey.py +0 -7
  162. agno/models/response.py +15 -9
  163. agno/models/utils.py +20 -0
  164. agno/models/vercel/__init__.py +2 -2
  165. agno/models/vercel/v0.py +1 -1
  166. agno/models/vllm/__init__.py +2 -2
  167. agno/models/vllm/vllm.py +3 -3
  168. agno/models/xai/xai.py +10 -10
  169. agno/os/__init__.py +3 -0
  170. agno/os/app.py +497 -0
  171. agno/os/auth.py +47 -0
  172. agno/os/config.py +103 -0
  173. agno/os/interfaces/agui/__init__.py +3 -0
  174. agno/os/interfaces/agui/agui.py +31 -0
  175. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  176. agno/{app → os/interfaces}/agui/utils.py +77 -33
  177. agno/os/interfaces/base.py +21 -0
  178. agno/os/interfaces/slack/__init__.py +3 -0
  179. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  180. agno/os/interfaces/slack/slack.py +32 -0
  181. agno/os/interfaces/whatsapp/__init__.py +3 -0
  182. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  183. agno/os/interfaces/whatsapp/whatsapp.py +29 -0
  184. agno/os/mcp.py +235 -0
  185. agno/os/router.py +1400 -0
  186. agno/os/routers/__init__.py +3 -0
  187. agno/os/routers/evals/__init__.py +3 -0
  188. agno/os/routers/evals/evals.py +393 -0
  189. agno/os/routers/evals/schemas.py +142 -0
  190. agno/os/routers/evals/utils.py +161 -0
  191. agno/os/routers/knowledge/__init__.py +3 -0
  192. agno/os/routers/knowledge/knowledge.py +850 -0
  193. agno/os/routers/knowledge/schemas.py +118 -0
  194. agno/os/routers/memory/__init__.py +3 -0
  195. agno/os/routers/memory/memory.py +410 -0
  196. agno/os/routers/memory/schemas.py +58 -0
  197. agno/os/routers/metrics/__init__.py +3 -0
  198. agno/os/routers/metrics/metrics.py +178 -0
  199. agno/os/routers/metrics/schemas.py +47 -0
  200. agno/os/routers/session/__init__.py +3 -0
  201. agno/os/routers/session/session.py +536 -0
  202. agno/os/schema.py +945 -0
  203. agno/{app/playground → os}/settings.py +7 -15
  204. agno/os/utils.py +270 -0
  205. agno/reasoning/azure_ai_foundry.py +4 -4
  206. agno/reasoning/deepseek.py +4 -4
  207. agno/reasoning/default.py +6 -11
  208. agno/reasoning/groq.py +4 -4
  209. agno/reasoning/helpers.py +4 -6
  210. agno/reasoning/ollama.py +4 -4
  211. agno/reasoning/openai.py +4 -4
  212. agno/run/agent.py +633 -0
  213. agno/run/base.py +53 -77
  214. agno/run/cancel.py +81 -0
  215. agno/run/team.py +243 -96
  216. agno/run/workflow.py +550 -12
  217. agno/session/__init__.py +10 -0
  218. agno/session/agent.py +244 -0
  219. agno/session/summary.py +225 -0
  220. agno/session/team.py +262 -0
  221. agno/{storage/session/v2 → session}/workflow.py +47 -24
  222. agno/team/__init__.py +15 -16
  223. agno/team/team.py +3260 -4824
  224. agno/tools/agentql.py +14 -5
  225. agno/tools/airflow.py +9 -4
  226. agno/tools/api.py +7 -3
  227. agno/tools/apify.py +2 -46
  228. agno/tools/arxiv.py +8 -3
  229. agno/tools/aws_lambda.py +7 -5
  230. agno/tools/aws_ses.py +7 -1
  231. agno/tools/baidusearch.py +4 -1
  232. agno/tools/bitbucket.py +4 -4
  233. agno/tools/brandfetch.py +14 -11
  234. agno/tools/bravesearch.py +4 -1
  235. agno/tools/brightdata.py +43 -23
  236. agno/tools/browserbase.py +13 -4
  237. agno/tools/calcom.py +12 -10
  238. agno/tools/calculator.py +10 -27
  239. agno/tools/cartesia.py +20 -17
  240. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  241. agno/tools/confluence.py +8 -8
  242. agno/tools/crawl4ai.py +7 -1
  243. agno/tools/csv_toolkit.py +9 -8
  244. agno/tools/dalle.py +22 -12
  245. agno/tools/daytona.py +13 -16
  246. agno/tools/decorator.py +6 -3
  247. agno/tools/desi_vocal.py +17 -8
  248. agno/tools/discord.py +11 -8
  249. agno/tools/docker.py +30 -42
  250. agno/tools/duckdb.py +34 -53
  251. agno/tools/duckduckgo.py +8 -7
  252. agno/tools/e2b.py +62 -62
  253. agno/tools/eleven_labs.py +36 -29
  254. agno/tools/email.py +4 -1
  255. agno/tools/evm.py +7 -1
  256. agno/tools/exa.py +19 -14
  257. agno/tools/fal.py +30 -30
  258. agno/tools/file.py +9 -8
  259. agno/tools/financial_datasets.py +25 -44
  260. agno/tools/firecrawl.py +22 -22
  261. agno/tools/function.py +127 -18
  262. agno/tools/giphy.py +23 -11
  263. agno/tools/github.py +48 -126
  264. agno/tools/gmail.py +45 -61
  265. agno/tools/google_bigquery.py +7 -6
  266. agno/tools/google_maps.py +11 -26
  267. agno/tools/googlesearch.py +7 -2
  268. agno/tools/googlesheets.py +21 -17
  269. agno/tools/hackernews.py +9 -5
  270. agno/tools/jina.py +5 -4
  271. agno/tools/jira.py +18 -9
  272. agno/tools/knowledge.py +31 -32
  273. agno/tools/linear.py +19 -34
  274. agno/tools/linkup.py +5 -1
  275. agno/tools/local_file_system.py +8 -5
  276. agno/tools/lumalab.py +32 -20
  277. agno/tools/mcp.py +1 -2
  278. agno/tools/mem0.py +18 -12
  279. agno/tools/memori.py +14 -10
  280. agno/tools/mlx_transcribe.py +3 -2
  281. agno/tools/models/azure_openai.py +33 -15
  282. agno/tools/models/gemini.py +59 -32
  283. agno/tools/models/groq.py +30 -23
  284. agno/tools/models/nebius.py +28 -12
  285. agno/tools/models_labs.py +40 -16
  286. agno/tools/moviepy_video.py +7 -6
  287. agno/tools/neo4j.py +10 -8
  288. agno/tools/newspaper.py +7 -2
  289. agno/tools/newspaper4k.py +8 -3
  290. agno/tools/openai.py +58 -32
  291. agno/tools/openbb.py +12 -11
  292. agno/tools/opencv.py +63 -47
  293. agno/tools/openweather.py +14 -12
  294. agno/tools/pandas.py +11 -3
  295. agno/tools/postgres.py +4 -12
  296. agno/tools/pubmed.py +4 -1
  297. agno/tools/python.py +9 -22
  298. agno/tools/reasoning.py +35 -27
  299. agno/tools/reddit.py +11 -26
  300. agno/tools/replicate.py +55 -42
  301. agno/tools/resend.py +4 -1
  302. agno/tools/scrapegraph.py +15 -14
  303. agno/tools/searxng.py +10 -23
  304. agno/tools/serpapi.py +6 -3
  305. agno/tools/serper.py +13 -4
  306. agno/tools/shell.py +9 -2
  307. agno/tools/slack.py +12 -11
  308. agno/tools/sleep.py +3 -2
  309. agno/tools/spider.py +24 -4
  310. agno/tools/sql.py +7 -6
  311. agno/tools/tavily.py +6 -4
  312. agno/tools/telegram.py +12 -4
  313. agno/tools/todoist.py +11 -31
  314. agno/tools/toolkit.py +1 -1
  315. agno/tools/trafilatura.py +22 -6
  316. agno/tools/trello.py +9 -22
  317. agno/tools/twilio.py +10 -3
  318. agno/tools/user_control_flow.py +6 -1
  319. agno/tools/valyu.py +34 -5
  320. agno/tools/visualization.py +19 -28
  321. agno/tools/webbrowser.py +4 -3
  322. agno/tools/webex.py +11 -7
  323. agno/tools/website.py +15 -46
  324. agno/tools/webtools.py +12 -4
  325. agno/tools/whatsapp.py +5 -9
  326. agno/tools/wikipedia.py +20 -13
  327. agno/tools/x.py +14 -13
  328. agno/tools/yfinance.py +13 -40
  329. agno/tools/youtube.py +26 -20
  330. agno/tools/zendesk.py +7 -2
  331. agno/tools/zep.py +10 -7
  332. agno/tools/zoom.py +10 -9
  333. agno/utils/common.py +1 -19
  334. agno/utils/events.py +100 -123
  335. agno/utils/gemini.py +32 -2
  336. agno/utils/knowledge.py +29 -0
  337. agno/utils/log.py +54 -4
  338. agno/utils/mcp.py +68 -10
  339. agno/utils/media.py +39 -0
  340. agno/utils/message.py +12 -1
  341. agno/utils/models/aws_claude.py +1 -1
  342. agno/utils/models/claude.py +47 -4
  343. agno/utils/models/cohere.py +1 -1
  344. agno/utils/models/mistral.py +8 -7
  345. agno/utils/models/schema_utils.py +3 -3
  346. agno/utils/models/watsonx.py +1 -1
  347. agno/utils/openai.py +1 -1
  348. agno/utils/pprint.py +33 -32
  349. agno/utils/print_response/agent.py +779 -0
  350. agno/utils/print_response/team.py +1669 -0
  351. agno/utils/print_response/workflow.py +1451 -0
  352. agno/utils/prompts.py +14 -14
  353. agno/utils/reasoning.py +87 -0
  354. agno/utils/response.py +42 -42
  355. agno/utils/streamlit.py +481 -0
  356. agno/utils/string.py +8 -22
  357. agno/utils/team.py +50 -0
  358. agno/utils/timer.py +2 -2
  359. agno/vectordb/base.py +33 -21
  360. agno/vectordb/cassandra/cassandra.py +287 -23
  361. agno/vectordb/chroma/chromadb.py +482 -59
  362. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  363. agno/vectordb/couchbase/couchbase.py +309 -29
  364. agno/vectordb/lancedb/lance_db.py +360 -21
  365. agno/vectordb/langchaindb/__init__.py +5 -0
  366. agno/vectordb/langchaindb/langchaindb.py +145 -0
  367. agno/vectordb/lightrag/__init__.py +5 -0
  368. agno/vectordb/lightrag/lightrag.py +374 -0
  369. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  370. agno/vectordb/milvus/milvus.py +242 -32
  371. agno/vectordb/mongodb/mongodb.py +200 -24
  372. agno/vectordb/pgvector/pgvector.py +319 -37
  373. agno/vectordb/pineconedb/pineconedb.py +221 -27
  374. agno/vectordb/qdrant/qdrant.py +334 -14
  375. agno/vectordb/singlestore/singlestore.py +286 -29
  376. agno/vectordb/surrealdb/surrealdb.py +187 -7
  377. agno/vectordb/upstashdb/upstashdb.py +342 -26
  378. agno/vectordb/weaviate/weaviate.py +227 -165
  379. agno/workflow/__init__.py +17 -13
  380. agno/workflow/{v2/condition.py → condition.py} +135 -32
  381. agno/workflow/{v2/loop.py → loop.py} +115 -28
  382. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  383. agno/workflow/{v2/router.py → router.py} +133 -32
  384. agno/workflow/{v2/step.py → step.py} +207 -49
  385. agno/workflow/{v2/steps.py → steps.py} +147 -66
  386. agno/workflow/types.py +482 -0
  387. agno/workflow/workflow.py +2410 -696
  388. agno-2.0.0.dist-info/METADATA +494 -0
  389. agno-2.0.0.dist-info/RECORD +515 -0
  390. agno-2.0.0.dist-info/licenses/LICENSE +201 -0
  391. agno/agent/metrics.py +0 -107
  392. agno/api/app.py +0 -35
  393. agno/api/playground.py +0 -92
  394. agno/api/schemas/app.py +0 -12
  395. agno/api/schemas/playground.py +0 -22
  396. agno/api/schemas/user.py +0 -35
  397. agno/api/schemas/workspace.py +0 -46
  398. agno/api/user.py +0 -160
  399. agno/api/workflows.py +0 -33
  400. agno/api/workspace.py +0 -175
  401. agno/app/agui/__init__.py +0 -3
  402. agno/app/agui/app.py +0 -17
  403. agno/app/agui/sync_router.py +0 -120
  404. agno/app/base.py +0 -186
  405. agno/app/discord/__init__.py +0 -3
  406. agno/app/fastapi/__init__.py +0 -3
  407. agno/app/fastapi/app.py +0 -107
  408. agno/app/fastapi/async_router.py +0 -457
  409. agno/app/fastapi/sync_router.py +0 -448
  410. agno/app/playground/app.py +0 -228
  411. agno/app/playground/async_router.py +0 -1050
  412. agno/app/playground/deploy.py +0 -249
  413. agno/app/playground/operator.py +0 -183
  414. agno/app/playground/schemas.py +0 -220
  415. agno/app/playground/serve.py +0 -55
  416. agno/app/playground/sync_router.py +0 -1042
  417. agno/app/playground/utils.py +0 -46
  418. agno/app/settings.py +0 -15
  419. agno/app/slack/__init__.py +0 -3
  420. agno/app/slack/app.py +0 -19
  421. agno/app/slack/sync_router.py +0 -92
  422. agno/app/utils.py +0 -54
  423. agno/app/whatsapp/__init__.py +0 -3
  424. agno/app/whatsapp/app.py +0 -15
  425. agno/app/whatsapp/sync_router.py +0 -197
  426. agno/cli/auth_server.py +0 -249
  427. agno/cli/config.py +0 -274
  428. agno/cli/console.py +0 -88
  429. agno/cli/credentials.py +0 -23
  430. agno/cli/entrypoint.py +0 -571
  431. agno/cli/operator.py +0 -357
  432. agno/cli/settings.py +0 -96
  433. agno/cli/ws/ws_cli.py +0 -817
  434. agno/constants.py +0 -13
  435. agno/document/__init__.py +0 -5
  436. agno/document/chunking/semantic.py +0 -45
  437. agno/document/chunking/strategy.py +0 -31
  438. agno/document/reader/__init__.py +0 -5
  439. agno/document/reader/base.py +0 -47
  440. agno/document/reader/docx_reader.py +0 -60
  441. agno/document/reader/gcs/pdf_reader.py +0 -44
  442. agno/document/reader/s3/pdf_reader.py +0 -59
  443. agno/document/reader/s3/text_reader.py +0 -63
  444. agno/document/reader/url_reader.py +0 -59
  445. agno/document/reader/youtube_reader.py +0 -58
  446. agno/embedder/__init__.py +0 -5
  447. agno/embedder/langdb.py +0 -80
  448. agno/embedder/mistral.py +0 -82
  449. agno/embedder/openai.py +0 -78
  450. agno/file/__init__.py +0 -5
  451. agno/file/file.py +0 -16
  452. agno/file/local/csv.py +0 -32
  453. agno/file/local/txt.py +0 -19
  454. agno/infra/app.py +0 -240
  455. agno/infra/base.py +0 -144
  456. agno/infra/context.py +0 -20
  457. agno/infra/db_app.py +0 -52
  458. agno/infra/resource.py +0 -205
  459. agno/infra/resources.py +0 -55
  460. agno/knowledge/agent.py +0 -702
  461. agno/knowledge/arxiv.py +0 -33
  462. agno/knowledge/combined.py +0 -36
  463. agno/knowledge/csv.py +0 -144
  464. agno/knowledge/csv_url.py +0 -124
  465. agno/knowledge/document.py +0 -223
  466. agno/knowledge/docx.py +0 -137
  467. agno/knowledge/firecrawl.py +0 -34
  468. agno/knowledge/gcs/__init__.py +0 -0
  469. agno/knowledge/gcs/base.py +0 -39
  470. agno/knowledge/gcs/pdf.py +0 -125
  471. agno/knowledge/json.py +0 -137
  472. agno/knowledge/langchain.py +0 -71
  473. agno/knowledge/light_rag.py +0 -273
  474. agno/knowledge/llamaindex.py +0 -66
  475. agno/knowledge/markdown.py +0 -154
  476. agno/knowledge/pdf.py +0 -164
  477. agno/knowledge/pdf_bytes.py +0 -42
  478. agno/knowledge/pdf_url.py +0 -148
  479. agno/knowledge/s3/__init__.py +0 -0
  480. agno/knowledge/s3/base.py +0 -64
  481. agno/knowledge/s3/pdf.py +0 -33
  482. agno/knowledge/s3/text.py +0 -34
  483. agno/knowledge/text.py +0 -141
  484. agno/knowledge/url.py +0 -46
  485. agno/knowledge/website.py +0 -179
  486. agno/knowledge/wikipedia.py +0 -32
  487. agno/knowledge/youtube.py +0 -35
  488. agno/memory/agent.py +0 -423
  489. agno/memory/classifier.py +0 -104
  490. agno/memory/db/__init__.py +0 -5
  491. agno/memory/db/base.py +0 -42
  492. agno/memory/db/mongodb.py +0 -189
  493. agno/memory/db/postgres.py +0 -203
  494. agno/memory/db/sqlite.py +0 -193
  495. agno/memory/memory.py +0 -22
  496. agno/memory/row.py +0 -36
  497. agno/memory/summarizer.py +0 -201
  498. agno/memory/summary.py +0 -19
  499. agno/memory/team.py +0 -415
  500. agno/memory/v2/__init__.py +0 -2
  501. agno/memory/v2/db/__init__.py +0 -1
  502. agno/memory/v2/db/base.py +0 -42
  503. agno/memory/v2/db/firestore.py +0 -339
  504. agno/memory/v2/db/mongodb.py +0 -196
  505. agno/memory/v2/db/postgres.py +0 -214
  506. agno/memory/v2/db/redis.py +0 -187
  507. agno/memory/v2/db/schema.py +0 -54
  508. agno/memory/v2/db/sqlite.py +0 -209
  509. agno/memory/v2/manager.py +0 -437
  510. agno/memory/v2/memory.py +0 -1097
  511. agno/memory/v2/schema.py +0 -55
  512. agno/memory/v2/summarizer.py +0 -215
  513. agno/memory/workflow.py +0 -38
  514. agno/models/ollama/tools.py +0 -430
  515. agno/models/qwen/__init__.py +0 -5
  516. agno/playground/__init__.py +0 -10
  517. agno/playground/deploy.py +0 -3
  518. agno/playground/playground.py +0 -3
  519. agno/playground/serve.py +0 -3
  520. agno/playground/settings.py +0 -3
  521. agno/reranker/__init__.py +0 -0
  522. agno/run/response.py +0 -467
  523. agno/run/v2/__init__.py +0 -0
  524. agno/run/v2/workflow.py +0 -567
  525. agno/storage/__init__.py +0 -0
  526. agno/storage/agent/__init__.py +0 -0
  527. agno/storage/agent/dynamodb.py +0 -1
  528. agno/storage/agent/json.py +0 -1
  529. agno/storage/agent/mongodb.py +0 -1
  530. agno/storage/agent/postgres.py +0 -1
  531. agno/storage/agent/singlestore.py +0 -1
  532. agno/storage/agent/sqlite.py +0 -1
  533. agno/storage/agent/yaml.py +0 -1
  534. agno/storage/base.py +0 -60
  535. agno/storage/dynamodb.py +0 -673
  536. agno/storage/firestore.py +0 -297
  537. agno/storage/gcs_json.py +0 -261
  538. agno/storage/in_memory.py +0 -234
  539. agno/storage/json.py +0 -237
  540. agno/storage/mongodb.py +0 -328
  541. agno/storage/mysql.py +0 -685
  542. agno/storage/postgres.py +0 -682
  543. agno/storage/redis.py +0 -336
  544. agno/storage/session/__init__.py +0 -16
  545. agno/storage/session/agent.py +0 -64
  546. agno/storage/session/team.py +0 -63
  547. agno/storage/session/v2/__init__.py +0 -5
  548. agno/storage/session/workflow.py +0 -61
  549. agno/storage/singlestore.py +0 -606
  550. agno/storage/sqlite.py +0 -646
  551. agno/storage/workflow/__init__.py +0 -0
  552. agno/storage/workflow/mongodb.py +0 -1
  553. agno/storage/workflow/postgres.py +0 -1
  554. agno/storage/workflow/sqlite.py +0 -1
  555. agno/storage/yaml.py +0 -241
  556. agno/tools/thinking.py +0 -73
  557. agno/utils/defaults.py +0 -57
  558. agno/utils/filesystem.py +0 -39
  559. agno/utils/git.py +0 -52
  560. agno/utils/json_io.py +0 -30
  561. agno/utils/load_env.py +0 -19
  562. agno/utils/py_io.py +0 -19
  563. agno/utils/pyproject.py +0 -18
  564. agno/utils/resource_filter.py +0 -31
  565. agno/workflow/v2/__init__.py +0 -21
  566. agno/workflow/v2/types.py +0 -357
  567. agno/workflow/v2/workflow.py +0 -3312
  568. agno/workspace/__init__.py +0 -0
  569. agno/workspace/config.py +0 -325
  570. agno/workspace/enums.py +0 -6
  571. agno/workspace/helpers.py +0 -52
  572. agno/workspace/operator.py +0 -757
  573. agno/workspace/settings.py +0 -158
  574. agno-1.8.1.dist-info/METADATA +0 -982
  575. agno-1.8.1.dist-info/RECORD +0 -566
  576. agno-1.8.1.dist-info/entry_points.txt +0 -3
  577. agno-1.8.1.dist-info/licenses/LICENSE +0 -375
  578. /agno/{app → db/migrations}/__init__.py +0 -0
  579. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  580. /agno/{cli → integrations}/__init__.py +0 -0
  581. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  582. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  583. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  584. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  585. /agno/{app → os/interfaces}/slack/security.py +0 -0
  586. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  587. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  588. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  589. {agno-1.8.1.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
  590. {agno-1.8.1.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
agno/eval/reliability.py CHANGED
@@ -1,15 +1,17 @@
1
1
  from dataclasses import asdict, dataclass, field
2
2
  from os import getenv
3
- from typing import TYPE_CHECKING, List, Optional
3
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional
4
4
  from uuid import uuid4
5
5
 
6
+ from agno.db.base import BaseDb
7
+
6
8
  if TYPE_CHECKING:
7
9
  from rich.console import Console
8
10
 
9
- from agno.agent import RunResponse
10
- from agno.api.schemas.evals import EvalType
11
- from agno.eval.utils import async_log_eval_run, log_eval_run, store_result_in_file
12
- from agno.run.team import TeamRunResponse
11
+ from agno.agent import RunOutput
12
+ from agno.db.schemas.evals import EvalType
13
+ from agno.eval.utils import async_log_eval, log_eval_run, store_result_in_file
14
+ from agno.run.team import TeamRunOutput
13
15
  from agno.utils.log import logger
14
16
 
15
17
 
@@ -46,9 +48,9 @@ class ReliabilityEval:
46
48
  eval_id: str = field(default_factory=lambda: str(uuid4()))
47
49
 
48
50
  # Agent response
49
- agent_response: Optional[RunResponse] = None
51
+ agent_response: Optional[RunOutput] = None
50
52
  # Team response
51
- team_response: Optional[TeamRunResponse] = None
53
+ team_response: Optional[TeamRunOutput] = None
52
54
  # Expected tool calls
53
55
  expected_tool_calls: Optional[List[str]] = None
54
56
  # Result of the evaluation
@@ -60,8 +62,13 @@ class ReliabilityEval:
60
62
  file_path_to_save_results: Optional[str] = None
61
63
  # Enable debug logs
62
64
  debug_mode: bool = getenv("AGNO_DEBUG", "false").lower() == "true"
63
- # Log the results to the Agno platform. On by default.
64
- monitoring: bool = getenv("AGNO_MONITOR", "true").lower() == "true"
65
+ # The database to store Evaluation results
66
+ db: Optional[BaseDb] = None
67
+
68
+ # Telemetry settings
69
+ # telemetry=True logs minimal telemetry for analytics
70
+ # This helps us improve our Evals and provide better support
71
+ telemetry: bool = True
65
72
 
66
73
  def run(self, *, print_results: bool = False) -> Optional[ReliabilityResult]:
67
74
  if self.agent_response is None and self.team_response is None:
@@ -100,15 +107,18 @@ class ReliabilityEval:
100
107
 
101
108
  failed_tool_calls = []
102
109
  passed_tool_calls = []
103
- for tool_call in actual_tool_calls: # type: ignore
104
- tool_name = tool_call.get("function", {}).get("name")
105
- if not tool_name:
106
- continue
107
- else:
108
- if tool_name not in self.expected_tool_calls: # type: ignore
109
- failed_tool_calls.append(tool_call.get("function", {}).get("name"))
110
+ if not actual_tool_calls:
111
+ failed_tool_calls = self.expected_tool_calls or []
112
+ else:
113
+ for tool_call in actual_tool_calls: # type: ignore
114
+ tool_name = tool_call.get("function", {}).get("name")
115
+ if not tool_name:
116
+ continue
110
117
  else:
111
- passed_tool_calls.append(tool_call.get("function", {}).get("name"))
118
+ if tool_name not in self.expected_tool_calls: # type: ignore
119
+ failed_tool_calls.append(tool_call.get("function", {}).get("name"))
120
+ else:
121
+ passed_tool_calls.append(tool_call.get("function", {}).get("name"))
112
122
 
113
123
  self.result = ReliabilityResult(
114
124
  eval_status="PASSED" if len(failed_tool_calls) == 0 else "FAILED",
@@ -130,7 +140,7 @@ class ReliabilityEval:
130
140
  self.result.print_eval(console)
131
141
 
132
142
  # Log results to the Agno platform if requested
133
- if self.monitoring:
143
+ if self.db:
134
144
  if self.agent_response is not None:
135
145
  agent_id = self.agent_response.agent_id
136
146
  team_id = None
@@ -142,7 +152,12 @@ class ReliabilityEval:
142
152
  model_id = self.team_response.model
143
153
  model_provider = self.team_response.model_provider
144
154
 
155
+ eval_input = {
156
+ "expected_tool_calls": self.expected_tool_calls,
157
+ }
158
+
145
159
  log_eval_run(
160
+ db=self.db,
146
161
  run_id=self.eval_id, # type: ignore
147
162
  run_data=asdict(self.result),
148
163
  eval_type=EvalType.RELIABILITY,
@@ -151,6 +166,18 @@ class ReliabilityEval:
151
166
  team_id=team_id,
152
167
  model_id=model_id,
153
168
  model_provider=model_provider,
169
+ eval_input=eval_input,
170
+ )
171
+
172
+ if self.telemetry:
173
+ from agno.api.evals import EvalRunCreate, create_eval_run_telemetry
174
+
175
+ create_eval_run_telemetry(
176
+ eval_run=EvalRunCreate(
177
+ run_id=self.eval_id,
178
+ eval_type=EvalType.RELIABILITY,
179
+ data=self._get_telemetry_data(),
180
+ ),
154
181
  )
155
182
 
156
183
  logger.debug(f"*********** Evaluation End: {self.eval_id} ***********")
@@ -223,7 +250,7 @@ class ReliabilityEval:
223
250
  self.result.print_eval(console)
224
251
 
225
252
  # Log results to the Agno platform if requested
226
- if self.monitoring:
253
+ if self.db:
227
254
  if self.agent_response is not None:
228
255
  agent_id = self.agent_response.agent_id
229
256
  team_id = None
@@ -235,7 +262,12 @@ class ReliabilityEval:
235
262
  model_id = self.team_response.model
236
263
  model_provider = self.team_response.model_provider
237
264
 
238
- await async_log_eval_run(
265
+ eval_input = {
266
+ "expected_tool_calls": self.expected_tool_calls,
267
+ }
268
+
269
+ await async_log_eval(
270
+ db=self.db,
239
271
  run_id=self.eval_id, # type: ignore
240
272
  run_data=asdict(self.result),
241
273
  eval_type=EvalType.RELIABILITY,
@@ -244,7 +276,28 @@ class ReliabilityEval:
244
276
  team_id=team_id,
245
277
  model_id=model_id,
246
278
  model_provider=model_provider,
279
+ eval_input=eval_input,
280
+ )
281
+
282
+ if self.telemetry:
283
+ from agno.api.evals import EvalRunCreate, async_create_eval_run_telemetry
284
+
285
+ await async_create_eval_run_telemetry(
286
+ eval_run=EvalRunCreate(
287
+ run_id=self.eval_id,
288
+ eval_type=EvalType.RELIABILITY,
289
+ data=self._get_telemetry_data(),
290
+ ),
247
291
  )
248
292
 
249
293
  logger.debug(f"*********** Evaluation End: {self.eval_id} ***********")
250
294
  return self.result
295
+
296
+ def _get_telemetry_data(self) -> Dict[str, Any]:
297
+ """Get the telemetry data for the evaluation"""
298
+ return {
299
+ "team_id": self.team_response.team_id if self.team_response else None,
300
+ "agent_id": self.agent_response.agent_id if self.agent_response else None,
301
+ "model_id": self.agent_response.model if self.agent_response else None,
302
+ "model_provider": self.agent_response.model_provider if self.agent_response else None,
303
+ }
agno/eval/utils.py CHANGED
@@ -2,8 +2,8 @@ from dataclasses import asdict
2
2
  from pathlib import Path
3
3
  from typing import TYPE_CHECKING, Optional, Union
4
4
 
5
- from agno.api.evals import async_create_eval_run, create_eval_run
6
- from agno.api.schemas.evals import EvalRunCreate, EvalType
5
+ from agno.db.base import BaseDb
6
+ from agno.db.schemas.evals import EvalRunRecord, EvalType
7
7
  from agno.utils.log import log_debug, logger
8
8
 
9
9
  if TYPE_CHECKING:
@@ -13,61 +13,71 @@ if TYPE_CHECKING:
13
13
 
14
14
 
15
15
  def log_eval_run(
16
+ db: BaseDb,
16
17
  run_id: str,
17
18
  run_data: dict,
18
19
  eval_type: EvalType,
20
+ eval_input: dict,
19
21
  agent_id: Optional[str] = None,
20
22
  model_id: Optional[str] = None,
21
23
  model_provider: Optional[str] = None,
22
24
  name: Optional[str] = None,
23
- evaluated_entity_name: Optional[str] = None,
25
+ evaluated_component_name: Optional[str] = None,
24
26
  team_id: Optional[str] = None,
27
+ workflow_id: Optional[str] = None,
25
28
  ) -> None:
26
29
  """Call the API to create an evaluation run."""
27
30
 
28
31
  try:
29
- create_eval_run(
30
- eval_run=EvalRunCreate(
32
+ db.create_eval_run(
33
+ EvalRunRecord(
31
34
  run_id=run_id,
32
35
  eval_type=eval_type,
33
36
  eval_data=run_data,
37
+ eval_input=eval_input,
34
38
  agent_id=agent_id,
35
39
  model_id=model_id,
36
40
  model_provider=model_provider,
37
41
  name=name,
38
- evaluated_entity_name=evaluated_entity_name,
42
+ evaluated_component_name=evaluated_component_name,
39
43
  team_id=team_id,
44
+ workflow_id=workflow_id,
40
45
  )
41
46
  )
42
47
  except Exception as e:
43
48
  log_debug(f"Could not create agent event: {e}")
44
49
 
45
50
 
46
- async def async_log_eval_run(
51
+ async def async_log_eval(
52
+ db: BaseDb,
47
53
  run_id: str,
48
54
  run_data: dict,
49
55
  eval_type: EvalType,
56
+ eval_input: dict,
50
57
  agent_id: Optional[str] = None,
51
58
  model_id: Optional[str] = None,
52
59
  model_provider: Optional[str] = None,
53
60
  name: Optional[str] = None,
54
- evaluated_entity_name: Optional[str] = None,
61
+ evaluated_component_name: Optional[str] = None,
55
62
  team_id: Optional[str] = None,
63
+ workflow_id: Optional[str] = None,
56
64
  ) -> None:
57
- """Asycn call to the API to create an evaluation run."""
65
+ """Call the API to create an evaluation run."""
58
66
 
59
67
  try:
60
- await async_create_eval_run(
61
- eval_run=EvalRunCreate(
68
+ db.create_eval_run(
69
+ EvalRunRecord(
62
70
  run_id=run_id,
63
71
  eval_type=eval_type,
64
72
  eval_data=run_data,
73
+ eval_input=eval_input,
65
74
  agent_id=agent_id,
66
75
  model_id=model_id,
67
76
  model_provider=model_provider,
68
- team_id=team_id,
69
77
  name=name,
70
- evaluated_entity_name=evaluated_entity_name,
78
+ evaluated_component_name=evaluated_component_name,
79
+ team_id=team_id,
80
+ workflow_id=workflow_id,
71
81
  )
72
82
  )
73
83
  except Exception as e:
@@ -0,0 +1,3 @@
1
+ from agno.integrations.discord.client import DiscordClient
2
+
3
+ __all__ = ["DiscordClient"]
@@ -4,10 +4,11 @@ from typing import Optional, Union
4
4
 
5
5
  import requests
6
6
 
7
- from agno.agent.agent import Agent, RunResponse
7
+ from agno.agent.agent import Agent, RunOutput
8
8
  from agno.media import Audio, File, Image, Video
9
- from agno.team.team import Team, TeamRunResponse
9
+ from agno.team.team import Team, TeamRunOutput
10
10
  from agno.utils.log import log_info, log_warning
11
+ from agno.utils.message import get_text_from_message
11
12
 
12
13
  try:
13
14
  import discord
@@ -115,8 +116,8 @@ class DiscordClient:
115
116
  """)
116
117
  if self.agent:
117
118
  self.agent.additional_context = additional_context
118
- agent_response: RunResponse = await self.agent.arun(
119
- message_text,
119
+ agent_response: RunOutput = await self.agent.arun(
120
+ input=message_text,
120
121
  user_id=message_user_id,
121
122
  session_id=str(thread.id),
122
123
  images=[Image(url=message_image)] if message_image else None,
@@ -127,8 +128,8 @@ class DiscordClient:
127
128
  await self._handle_response_in_thread(agent_response, thread)
128
129
  elif self.team:
129
130
  self.team.additional_context = additional_context
130
- team_response: TeamRunResponse = await self.team.arun(
131
- message_text,
131
+ team_response: TeamRunOutput = await self.team.arun(
132
+ input=message_text,
132
133
  user_id=message_user_id,
133
134
  session_id=str(thread.id),
134
135
  images=[Image(url=message_image)] if message_image else None,
@@ -139,8 +140,8 @@ class DiscordClient:
139
140
  await self._handle_response_in_thread(team_response, thread)
140
141
 
141
142
  async def handle_hitl(
142
- self, run_response: RunResponse, thread: Union[discord.Thread, discord.TextChannel]
143
- ) -> RunResponse:
143
+ self, run_response: RunOutput, thread: Union[discord.Thread, discord.TextChannel]
144
+ ) -> RunOutput:
144
145
  """Handles optional Human-In-The-Loop interaction."""
145
146
  if run_response.is_paused:
146
147
  for tool in run_response.tools_requiring_confirmation:
@@ -157,9 +158,9 @@ class DiscordClient:
157
158
  return run_response
158
159
 
159
160
  async def _handle_response_in_thread(
160
- self, response: Union[RunResponse, TeamRunResponse], thread: Union[discord.TextChannel, discord.Thread]
161
+ self, response: Union[RunOutput, TeamRunOutput], thread: Union[discord.TextChannel, discord.Thread]
161
162
  ):
162
- if isinstance(response, RunResponse):
163
+ if isinstance(response, RunOutput):
163
164
  response = await self.handle_hitl(response, thread)
164
165
 
165
166
  if response.reasoning_content:
@@ -167,7 +168,10 @@ class DiscordClient:
167
168
  thread=thread, message=f"Reasoning: \n{response.reasoning_content}", italics=True
168
169
  )
169
170
 
170
- await self._send_discord_messages(thread=thread, message=str(response.content))
171
+ # Handle structured outputs properly
172
+ content_message = get_text_from_message(response.content) if response.content is not None else ""
173
+
174
+ await self._send_discord_messages(thread=thread, message=content_message)
171
175
 
172
176
  async def _send_discord_messages(self, thread: discord.channel, message: str, italics: bool = False): # type: ignore
173
177
  if len(message) < 1500:
@@ -1,5 +1,5 @@
1
- from agno.knowledge.agent import AgentKnowledge
1
+ from agno.knowledge.knowledge import Knowledge
2
2
 
3
3
  __all__ = [
4
- "AgentKnowledge",
4
+ "Knowledge",
5
5
  ]
@@ -1,7 +1,7 @@
1
1
  from typing import List, Optional
2
2
 
3
- from agno.document.base import Document
4
- from agno.document.chunking.strategy import ChunkingStrategy
3
+ from agno.knowledge.chunking.strategy import ChunkingStrategy
4
+ from agno.knowledge.document.base import Document
5
5
  from agno.models.base import Model
6
6
  from agno.models.defaults import DEFAULT_OPENAI_MODEL_ID
7
7
  from agno.models.message import Message
@@ -1,7 +1,7 @@
1
1
  from typing import List
2
2
 
3
- from agno.document.base import Document
4
- from agno.document.chunking.strategy import ChunkingStrategy
3
+ from agno.knowledge.chunking.strategy import ChunkingStrategy
4
+ from agno.knowledge.document.base import Document
5
5
 
6
6
 
7
7
  class DocumentChunking(ChunkingStrategy):
@@ -1,13 +1,13 @@
1
1
  from typing import List
2
2
 
3
- from agno.document.base import Document
4
- from agno.document.chunking.strategy import ChunkingStrategy
3
+ from agno.knowledge.chunking.strategy import ChunkingStrategy
4
+ from agno.knowledge.document.base import Document
5
5
 
6
6
 
7
7
  class FixedSizeChunking(ChunkingStrategy):
8
8
  """Chunking strategy that splits text into fixed-size chunks with optional overlap"""
9
9
 
10
- def __init__(self, chunk_size: int = 5000, overlap: int = 0):
10
+ def __init__(self, chunk_size: int = 100, overlap: int = 0):
11
11
  # overlap must be less than chunk size
12
12
  if overlap >= chunk_size:
13
13
  raise ValueError(f"Invalid parameters: overlap ({overlap}) must be less than chunk size ({chunk_size}).")
@@ -8,8 +8,8 @@ try:
8
8
  except ImportError:
9
9
  raise ImportError("`unstructured` not installed. Please install it using `pip install unstructured markdown`")
10
10
 
11
- from agno.document.base import Document
12
- from agno.document.chunking.strategy import ChunkingStrategy
11
+ from agno.knowledge.chunking.strategy import ChunkingStrategy
12
+ from agno.knowledge.document.base import Document
13
13
 
14
14
 
15
15
  class MarkdownChunking(ChunkingStrategy):
@@ -1,8 +1,8 @@
1
1
  import warnings
2
2
  from typing import List
3
3
 
4
- from agno.document.base import Document
5
- from agno.document.chunking.strategy import ChunkingStrategy
4
+ from agno.knowledge.chunking.strategy import ChunkingStrategy
5
+ from agno.knowledge.document.base import Document
6
6
 
7
7
 
8
8
  class RecursiveChunking(ChunkingStrategy):
@@ -1,7 +1,7 @@
1
1
  from typing import List
2
2
 
3
- from agno.document.base import Document
4
- from agno.document.chunking.strategy import ChunkingStrategy
3
+ from agno.knowledge.chunking.strategy import ChunkingStrategy
4
+ from agno.knowledge.document.base import Document
5
5
 
6
6
 
7
7
  class RowChunking(ChunkingStrategy):
@@ -0,0 +1,59 @@
1
+ from typing import List, Optional
2
+
3
+ from agno.knowledge.chunking.strategy import ChunkingStrategy
4
+ from agno.knowledge.document.base import Document
5
+ from agno.knowledge.embedder.base import Embedder
6
+ from agno.knowledge.embedder.openai import OpenAIEmbedder
7
+
8
+
9
+ class SemanticChunking(ChunkingStrategy):
10
+ """Chunking strategy that splits text into semantic chunks using chonkie"""
11
+
12
+ def __init__(self, embedder: Optional[Embedder] = None, chunk_size: int = 5000, similarity_threshold: float = 0.5):
13
+ self.embedder = embedder or OpenAIEmbedder(id="text-embedding-3-small") # type: ignore
14
+ self.chunk_size = chunk_size
15
+ self.similarity_threshold = similarity_threshold
16
+ self.chunker = None # Will be initialized lazily when needed
17
+
18
+ def _initialize_chunker(self):
19
+ """Lazily initialize the chunker with chonkie dependency."""
20
+ if self.chunker is None:
21
+ try:
22
+ from chonkie import SemanticChunker
23
+ except ImportError:
24
+ raise ImportError(
25
+ "`chonkie` is required for semantic chunking. "
26
+ "Please install it using `pip install chonkie` to use SemanticChunking."
27
+ )
28
+
29
+ self.chunker = SemanticChunker(
30
+ embedding_model=self.embedder.id, # type: ignore
31
+ chunk_size=self.chunk_size,
32
+ threshold=self.similarity_threshold,
33
+ )
34
+
35
+ def chunk(self, document: Document) -> List[Document]:
36
+ """Split document into semantic chunks using chonkie"""
37
+ if not document.content:
38
+ return [document]
39
+
40
+ # Ensure chunker is initialized (will raise ImportError if chonkie is missing)
41
+ self._initialize_chunker()
42
+
43
+ # Use chonkie to split into semantic chunks
44
+ if self.chunker is None:
45
+ raise RuntimeError("Chunker failed to initialize")
46
+
47
+ chunks = self.chunker.chunk(self.clean_text(document.content))
48
+
49
+ # Convert chunks to Documents
50
+ chunked_documents: List[Document] = []
51
+ for i, chunk in enumerate(chunks, 1):
52
+ meta_data = document.meta_data.copy()
53
+ meta_data["chunk"] = i
54
+ chunk_id = f"{document.id}_{i}" if document.id else None
55
+ meta_data["chunk_size"] = len(chunk.text)
56
+
57
+ chunked_documents.append(Document(id=chunk_id, name=document.name, meta_data=meta_data, content=chunk.text))
58
+
59
+ return chunked_documents
@@ -0,0 +1,121 @@
1
+ from abc import ABC, abstractmethod
2
+ from enum import Enum
3
+ from typing import List
4
+
5
+ from agno.knowledge.document.base import Document
6
+
7
+
8
+ class ChunkingStrategy(ABC):
9
+ """Base class for chunking strategies"""
10
+
11
+ @abstractmethod
12
+ def chunk(self, document: Document) -> List[Document]:
13
+ raise NotImplementedError
14
+
15
+ def clean_text(self, text: str) -> str:
16
+ """Clean the text by replacing multiple newlines with a single newline"""
17
+ import re
18
+
19
+ # Replace multiple newlines with a single newline
20
+ cleaned_text = re.sub(r"\n+", "\n", text)
21
+ # Replace multiple spaces with a single space
22
+ cleaned_text = re.sub(r"\s+", " ", cleaned_text)
23
+ # Replace multiple tabs with a single tab
24
+ cleaned_text = re.sub(r"\t+", "\t", cleaned_text)
25
+ # Replace multiple carriage returns with a single carriage return
26
+ cleaned_text = re.sub(r"\r+", "\r", cleaned_text)
27
+ # Replace multiple form feeds with a single form feed
28
+ cleaned_text = re.sub(r"\f+", "\f", cleaned_text)
29
+ # Replace multiple vertical tabs with a single vertical tab
30
+ cleaned_text = re.sub(r"\v+", "\v", cleaned_text)
31
+
32
+ return cleaned_text
33
+
34
+
35
+ class ChunkingStrategyType(str, Enum):
36
+ """Enumeration of available chunking strategies."""
37
+
38
+ AGENTIC_CHUNKER = "AgenticChunker"
39
+ DOCUMENT_CHUNKER = "DocumentChunker"
40
+ RECURSIVE_CHUNKER = "RecursiveChunker"
41
+ SEMANTIC_CHUNKER = "SemanticChunker"
42
+ FIXED_SIZE_CHUNKER = "FixedSizeChunker"
43
+ ROW_CHUNKER = "RowChunker"
44
+ MARKDOWN_CHUNKER = "MarkdownChunker"
45
+
46
+ @classmethod
47
+ def from_string(cls, strategy_name: str) -> "ChunkingStrategyType":
48
+ """Convert a string to a ChunkingStrategyType."""
49
+ strategy_name_clean = strategy_name.strip()
50
+
51
+ # Try exact enum value match first
52
+ for enum_member in cls:
53
+ if enum_member.value == strategy_name_clean:
54
+ return enum_member
55
+
56
+ raise ValueError(f"Unsupported chunking strategy: {strategy_name}. Valid options: {[e.value for e in cls]}")
57
+
58
+
59
+ class ChunkingStrategyFactory:
60
+ """Factory for creating chunking strategy instances."""
61
+
62
+ @classmethod
63
+ def create_strategy(cls, strategy_type: ChunkingStrategyType, **kwargs) -> ChunkingStrategy:
64
+ """Create an instance of the chunking strategy with the given parameters."""
65
+ strategy_map = {
66
+ ChunkingStrategyType.AGENTIC_CHUNKER: cls._create_agentic_chunking,
67
+ ChunkingStrategyType.DOCUMENT_CHUNKER: cls._create_document_chunking,
68
+ ChunkingStrategyType.RECURSIVE_CHUNKER: cls._create_recursive_chunking,
69
+ ChunkingStrategyType.SEMANTIC_CHUNKER: cls._create_semantic_chunking,
70
+ ChunkingStrategyType.FIXED_SIZE_CHUNKER: cls._create_fixed_chunking,
71
+ ChunkingStrategyType.ROW_CHUNKER: cls._create_row_chunking,
72
+ ChunkingStrategyType.MARKDOWN_CHUNKER: cls._create_markdown_chunking,
73
+ }
74
+ return strategy_map[strategy_type](**kwargs)
75
+
76
+ @classmethod
77
+ def _create_agentic_chunking(cls, **kwargs) -> ChunkingStrategy:
78
+ from agno.knowledge.chunking.agentic import AgenticChunking
79
+
80
+ # Map chunk_size to max_chunk_size for AgenticChunking
81
+ if "chunk_size" in kwargs and "max_chunk_size" not in kwargs:
82
+ kwargs["max_chunk_size"] = kwargs.pop("chunk_size")
83
+ return AgenticChunking(**kwargs)
84
+
85
+ @classmethod
86
+ def _create_document_chunking(cls, **kwargs) -> ChunkingStrategy:
87
+ from agno.knowledge.chunking.document import DocumentChunking
88
+
89
+ return DocumentChunking(**kwargs)
90
+
91
+ @classmethod
92
+ def _create_recursive_chunking(cls, **kwargs) -> ChunkingStrategy:
93
+ from agno.knowledge.chunking.recursive import RecursiveChunking
94
+
95
+ return RecursiveChunking(**kwargs)
96
+
97
+ @classmethod
98
+ def _create_semantic_chunking(cls, **kwargs) -> ChunkingStrategy:
99
+ from agno.knowledge.chunking.semantic import SemanticChunking
100
+
101
+ return SemanticChunking(**kwargs)
102
+
103
+ @classmethod
104
+ def _create_fixed_chunking(cls, **kwargs) -> ChunkingStrategy:
105
+ from agno.knowledge.chunking.fixed import FixedSizeChunking
106
+
107
+ return FixedSizeChunking(**kwargs)
108
+
109
+ @classmethod
110
+ def _create_row_chunking(cls, **kwargs) -> ChunkingStrategy:
111
+ from agno.knowledge.chunking.row import RowChunking
112
+
113
+ # Remove chunk_size if present since RowChunking doesn't use it
114
+ kwargs.pop("chunk_size", None)
115
+ return RowChunking(**kwargs)
116
+
117
+ @classmethod
118
+ def _create_markdown_chunking(cls, **kwargs) -> ChunkingStrategy:
119
+ from agno.knowledge.chunking.markdown import MarkdownChunking
120
+
121
+ return MarkdownChunking(**kwargs)