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