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
@@ -0,0 +1,7 @@
1
+ from agno.knowledge.reader.base import Reader
2
+ from agno.knowledge.reader.reader_factory import ReaderFactory
3
+
4
+ __all__ = [
5
+ "Reader",
6
+ "ReaderFactory",
7
+ ]
@@ -1,8 +1,11 @@
1
1
  import asyncio
2
- from typing import List
2
+ from typing import List, Optional
3
3
 
4
- from agno.document.base import Document
5
- from agno.document.reader.base import Reader
4
+ from agno.knowledge.chunking.fixed import FixedSizeChunking
5
+ from agno.knowledge.chunking.strategy import ChunkingStrategy, ChunkingStrategyType
6
+ from agno.knowledge.document.base import Document
7
+ from agno.knowledge.reader.base import Reader
8
+ from agno.knowledge.types import ContentType
6
9
 
7
10
  try:
8
11
  import arxiv # noqa: F401
@@ -11,9 +14,34 @@ except ImportError:
11
14
 
12
15
 
13
16
  class ArxivReader(Reader):
14
- max_results: int = 5 # Top articles
15
17
  sort_by: arxiv.SortCriterion = arxiv.SortCriterion.Relevance
16
18
 
19
+ @classmethod
20
+ def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
21
+ """Get the list of supported chunking strategies for Arxiv readers."""
22
+ return [
23
+ ChunkingStrategyType.FIXED_SIZE_CHUNKER,
24
+ ChunkingStrategyType.AGENTIC_CHUNKER,
25
+ ChunkingStrategyType.DOCUMENT_CHUNKER,
26
+ ChunkingStrategyType.RECURSIVE_CHUNKER,
27
+ ChunkingStrategyType.SEMANTIC_CHUNKER,
28
+ ]
29
+
30
+ @classmethod
31
+ def get_supported_content_types(self) -> List[ContentType]:
32
+ return [ContentType.TOPIC]
33
+
34
+ def __init__(
35
+ self,
36
+ chunking_strategy: Optional[ChunkingStrategy] = FixedSizeChunking(),
37
+ sort_by: arxiv.SortCriterion = arxiv.SortCriterion.Relevance,
38
+ **kwargs,
39
+ ) -> None:
40
+ super().__init__(chunking_strategy=chunking_strategy, **kwargs)
41
+
42
+ # ArxivReader-specific attributes
43
+ self.sort_by = sort_by
44
+
17
45
  def read(self, query: str) -> List[Document]:
18
46
  """
19
47
  Search a query from arXiv database
@@ -0,0 +1,88 @@
1
+ import asyncio
2
+ from dataclasses import dataclass, field
3
+ from typing import Any, List, Optional
4
+
5
+ from agno.knowledge.chunking.fixed import FixedSizeChunking
6
+ from agno.knowledge.chunking.strategy import ChunkingStrategy, ChunkingStrategyFactory, ChunkingStrategyType
7
+ from agno.knowledge.document.base import Document
8
+ from agno.knowledge.types import ContentType
9
+
10
+
11
+ @dataclass
12
+ class Reader:
13
+ """Base class for reading documents"""
14
+
15
+ chunk: bool = True
16
+ chunk_size: int = 5000
17
+ separators: List[str] = field(default_factory=lambda: ["\n", "\n\n", "\r", "\r\n", "\n\r", "\t", " ", " "])
18
+ chunking_strategy: Optional[ChunkingStrategy] = None
19
+ name: Optional[str] = None
20
+ description: Optional[str] = None
21
+ max_results: int = 5 # Maximum number of results to return (useful for search-based readers)
22
+
23
+ def __init__(
24
+ self,
25
+ chunk: bool = True,
26
+ chunk_size: int = 5000,
27
+ separators: Optional[List[str]] = None,
28
+ chunking_strategy: Optional[ChunkingStrategy] = None,
29
+ name: Optional[str] = None,
30
+ description: Optional[str] = None,
31
+ max_results: int = 5,
32
+ **kwargs,
33
+ ) -> None:
34
+ self.chunk = chunk
35
+ self.chunk_size = chunk_size
36
+ self.separators = (
37
+ separators if separators is not None else ["\n", "\n\n", "\r", "\r\n", "\n\r", "\t", " ", " "]
38
+ )
39
+ self.chunking_strategy = chunking_strategy
40
+ self.name = name
41
+ self.description = description
42
+ self.max_results = max_results
43
+
44
+ def set_chunking_strategy_from_string(self, strategy_name: str, **kwargs) -> None:
45
+ """Set the chunking strategy from a string name."""
46
+ try:
47
+ strategy_type = ChunkingStrategyType.from_string(strategy_name)
48
+ self.chunking_strategy = ChunkingStrategyFactory.create_strategy(strategy_type, **kwargs)
49
+ except ValueError as e:
50
+ raise ValueError(f"Failed to set chunking strategy: {e}")
51
+
52
+ def read(self, obj: Any, name: Optional[str] = None, password: Optional[str] = None) -> List[Document]:
53
+ raise NotImplementedError
54
+
55
+ async def async_read(self, obj: Any, name: Optional[str] = None, password: Optional[str] = None) -> List[Document]:
56
+ raise NotImplementedError
57
+
58
+ @classmethod
59
+ def get_supported_chunking_strategies(cls) -> List[ChunkingStrategyType]:
60
+ raise NotImplementedError
61
+
62
+ @classmethod
63
+ def get_supported_content_types(cls) -> List[ContentType]:
64
+ raise NotImplementedError
65
+
66
+ def chunk_document(self, document: Document) -> List[Document]:
67
+ if self.chunking_strategy is None:
68
+ self.chunking_strategy = FixedSizeChunking(chunk_size=self.chunk_size)
69
+ return self.chunking_strategy.chunk(document) # type: ignore
70
+
71
+ async def chunk_documents_async(self, documents: List[Document]) -> List[Document]:
72
+ """
73
+ Asynchronously chunk a list of documents using the instance's chunk_document method.
74
+
75
+ Args:
76
+ documents: List of documents to be chunked.
77
+
78
+ Returns:
79
+ A flattened list of chunked documents.
80
+ """
81
+
82
+ async def _chunk_document_async(doc: Document) -> List[Document]:
83
+ return await asyncio.to_thread(self.chunk_document, doc)
84
+
85
+ # Process chunking in parallel for all documents
86
+ chunked_lists = await asyncio.gather(*[_chunk_document_async(doc) for doc in documents])
87
+ # Flatten the result
88
+ return [chunk for sublist in chunked_lists for chunk in sublist]
@@ -1,28 +1,47 @@
1
1
  import asyncio
2
2
  import csv
3
3
  import io
4
- import os
5
4
  from pathlib import Path
6
5
  from typing import IO, Any, List, Optional, Union
7
- from urllib.parse import urlparse
8
6
  from uuid import uuid4
9
7
 
10
- from agno.utils.http import async_fetch_with_retry, fetch_with_retry
11
-
12
8
  try:
13
9
  import aiofiles
14
10
  except ImportError:
15
11
  raise ImportError("`aiofiles` not installed. Please install it with `pip install aiofiles`")
16
12
 
17
- from agno.document.base import Document
18
- from agno.document.reader.base import Reader
13
+ from agno.knowledge.chunking.row import RowChunking
14
+ from agno.knowledge.chunking.strategy import ChunkingStrategy, ChunkingStrategyType
15
+ from agno.knowledge.document.base import Document
16
+ from agno.knowledge.reader.base import Reader
17
+ from agno.knowledge.types import ContentType
19
18
  from agno.utils.log import logger
20
19
 
21
20
 
22
21
  class CSVReader(Reader):
23
22
  """Reader for CSV files"""
24
23
 
25
- def read(self, file: Union[Path, IO[Any]], delimiter: str = ",", quotechar: str = '"') -> List[Document]:
24
+ def __init__(self, chunking_strategy: Optional[ChunkingStrategy] = RowChunking(), **kwargs):
25
+ super().__init__(chunking_strategy=chunking_strategy, **kwargs)
26
+
27
+ @classmethod
28
+ def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
29
+ """Get the list of supported chunking strategies for CSV readers."""
30
+ return [
31
+ ChunkingStrategyType.ROW_CHUNKER,
32
+ ChunkingStrategyType.FIXED_SIZE_CHUNKER,
33
+ ChunkingStrategyType.AGENTIC_CHUNKER,
34
+ ChunkingStrategyType.DOCUMENT_CHUNKER,
35
+ ChunkingStrategyType.RECURSIVE_CHUNKER,
36
+ ]
37
+
38
+ @classmethod
39
+ def get_supported_content_types(self) -> List[ContentType]:
40
+ return [ContentType.CSV, ContentType.XLSX, ContentType.XLS]
41
+
42
+ def read(
43
+ self, file: Union[Path, IO[Any]], delimiter: str = ",", quotechar: str = '"', name: Optional[str] = None
44
+ ) -> List[Document]:
26
45
  try:
27
46
  if isinstance(file, Path):
28
47
  if not file.exists():
@@ -30,11 +49,15 @@ class CSVReader(Reader):
30
49
  logger.info(f"Reading: {file}")
31
50
  file_content = file.open(newline="", mode="r", encoding="utf-8")
32
51
  else:
33
- logger.info(f"Reading retrieved file: {file.name}")
52
+ logger.info(f"Reading retrieved file: {name or file.name}")
34
53
  file.seek(0)
35
54
  file_content = io.StringIO(file.read().decode("utf-8")) # type: ignore
36
55
 
37
- csv_name = Path(file.name).stem if isinstance(file, Path) else file.name.split(".")[0]
56
+ csv_name = name or (
57
+ Path(file.name).stem
58
+ if isinstance(file, Path)
59
+ else (getattr(file, "name", "csv_file").split(".")[0] if hasattr(file, "name") else "csv_file")
60
+ )
38
61
  csv_content = ""
39
62
  with file_content as csvfile:
40
63
  csv_reader = csv.reader(csvfile, delimiter=delimiter, quotechar=quotechar)
@@ -55,11 +78,16 @@ class CSVReader(Reader):
55
78
  return chunked_documents
56
79
  return documents
57
80
  except Exception as e:
58
- logger.error(f"Error reading: {file.name if isinstance(file, IO) else file}: {e}")
81
+ logger.error(f"Error reading: {getattr(file, 'name', str(file)) if isinstance(file, IO) else file}: {e}")
59
82
  return []
60
83
 
61
84
  async def async_read(
62
- self, file: Union[Path, IO[Any]], delimiter: str = ",", quotechar: str = '"', page_size: int = 1000
85
+ self,
86
+ file: Union[Path, IO[Any]],
87
+ delimiter: str = ",",
88
+ quotechar: str = '"',
89
+ page_size: int = 1000,
90
+ name: Optional[str] = None,
63
91
  ) -> List[Document]:
64
92
  """
65
93
  Read a CSV file asynchronously, processing batches of rows concurrently.
@@ -86,7 +114,11 @@ class CSVReader(Reader):
86
114
  file.seek(0)
87
115
  file_content_io = io.StringIO(file.read().decode("utf-8")) # type: ignore
88
116
 
89
- csv_name = Path(file.name).stem if isinstance(file, Path) else file.name.split(".")[0]
117
+ csv_name = name or (
118
+ Path(file.name).stem
119
+ if isinstance(file, Path)
120
+ else (getattr(file, "name", "csv_file").split(".")[0] if hasattr(file, "name") else "csv_file")
121
+ )
90
122
 
91
123
  file_content_io.seek(0)
92
124
  csv_reader = csv.reader(file_content_io, delimiter=delimiter, quotechar=quotechar)
@@ -128,57 +160,7 @@ class CSVReader(Reader):
128
160
 
129
161
  return documents
130
162
  except Exception as e:
131
- logger.error(f"Error reading async: {file.name if isinstance(file, IO) else file}: {e}")
163
+ logger.error(
164
+ f"Error reading async: {getattr(file, 'name', str(file)) if isinstance(file, IO) else file}: {e}"
165
+ )
132
166
  return []
133
-
134
-
135
- class CSVUrlReader(Reader):
136
- """Reader for CSV files"""
137
-
138
- def __init__(self, proxy: Optional[str] = None, **kwargs):
139
- super().__init__(**kwargs)
140
- self.proxy = proxy
141
-
142
- def read(self, url: str) -> List[Document]:
143
- if not url:
144
- raise ValueError("No URL provided")
145
-
146
- logger.info(f"Reading: {url}")
147
- # Retry the request up to 3 times with exponential backoff
148
- response = fetch_with_retry(url, proxy=self.proxy)
149
-
150
- parsed_url = urlparse(url)
151
- filename = os.path.basename(parsed_url.path) or "data.csv"
152
-
153
- file_obj = io.BytesIO(response.content)
154
- file_obj.name = filename
155
- documents = CSVReader().read(file=file_obj)
156
-
157
- file_obj.close()
158
-
159
- return documents
160
-
161
- async def async_read(self, url: str) -> List[Document]:
162
- if not url:
163
- raise ValueError("No URL provided")
164
-
165
- import httpx
166
-
167
- logger.info(f"Reading async: {url}")
168
-
169
- client_args = {"proxy": self.proxy} if self.proxy else {}
170
- async with httpx.AsyncClient(**client_args) as client: # type: ignore
171
- response = await async_fetch_with_retry(url, client=client)
172
-
173
- parsed_url = urlparse(url)
174
- filename = os.path.basename(parsed_url.path) or "data.csv"
175
-
176
- file_obj = io.BytesIO(response.content)
177
- file_obj.name = filename
178
-
179
- # Use the async version of CSVReader
180
- documents = await CSVReader().async_read(file=file_obj)
181
-
182
- file_obj.close()
183
-
184
- return documents
@@ -0,0 +1,83 @@
1
+ import asyncio
2
+ from pathlib import Path
3
+ from typing import IO, Any, List, Optional, Union
4
+ from uuid import uuid4
5
+
6
+ from agno.knowledge.chunking.document import DocumentChunking
7
+ from agno.knowledge.chunking.strategy import ChunkingStrategy, ChunkingStrategyType
8
+ from agno.knowledge.document.base import Document
9
+ from agno.knowledge.reader.base import Reader
10
+ from agno.knowledge.types import ContentType
11
+ from agno.utils.log import log_info, logger
12
+
13
+ try:
14
+ from docx import Document as DocxDocument # type: ignore
15
+ except ImportError:
16
+ raise ImportError("The `python-docx` package is not installed. Please install it via `pip install python-docx`.")
17
+
18
+
19
+ class DocxReader(Reader):
20
+ """Reader for Doc/Docx files"""
21
+
22
+ def __init__(self, chunking_strategy: Optional[ChunkingStrategy] = DocumentChunking(), **kwargs):
23
+ super().__init__(chunking_strategy=chunking_strategy, **kwargs)
24
+
25
+ @classmethod
26
+ def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
27
+ """Get the list of supported chunking strategies for DOCX readers."""
28
+ return [
29
+ ChunkingStrategyType.DOCUMENT_CHUNKER,
30
+ ChunkingStrategyType.FIXED_SIZE_CHUNKER,
31
+ ChunkingStrategyType.SEMANTIC_CHUNKER,
32
+ ChunkingStrategyType.AGENTIC_CHUNKER,
33
+ ChunkingStrategyType.RECURSIVE_CHUNKER,
34
+ ]
35
+
36
+ @classmethod
37
+ def get_supported_content_types(self) -> List[ContentType]:
38
+ return [ContentType.DOCX, ContentType.DOC]
39
+
40
+ def read(self, file: Union[Path, IO[Any]], name: Optional[str] = None) -> List[Document]:
41
+ """Read a docx file and return a list of documents"""
42
+ try:
43
+ if isinstance(file, Path):
44
+ if not file.exists():
45
+ raise FileNotFoundError(f"Could not find file: {file}")
46
+ log_info(f"Reading: {file}")
47
+ docx_document = DocxDocument(str(file))
48
+ doc_name = name or file.stem
49
+ else:
50
+ log_info(f"Reading uploaded file: {getattr(file, 'name', 'docx_file')}")
51
+ docx_document = DocxDocument(file)
52
+ doc_name = name or (
53
+ getattr(file, "name", "docx_file").split(".")[0] if hasattr(file, "name") else "docx_file"
54
+ )
55
+
56
+ doc_content = "\n\n".join([para.text for para in docx_document.paragraphs])
57
+
58
+ documents = [
59
+ Document(
60
+ name=doc_name,
61
+ id=str(uuid4()),
62
+ content=doc_content,
63
+ )
64
+ ]
65
+
66
+ if self.chunk:
67
+ chunked_documents = []
68
+ for document in documents:
69
+ chunked_documents.extend(self.chunk_document(document))
70
+ return chunked_documents
71
+ return documents
72
+
73
+ except Exception as e:
74
+ logger.error(f"Error reading file: {e}")
75
+ return []
76
+
77
+ async def async_read(self, file: Union[Path, IO[Any]], name: Optional[str] = None) -> List[Document]:
78
+ """Asynchronously read a docx file and return a list of documents"""
79
+ try:
80
+ return await asyncio.to_thread(self.read, file, name)
81
+ except Exception as e:
82
+ logger.error(f"Error reading file asynchronously: {e}")
83
+ return []
@@ -2,9 +2,11 @@ import asyncio
2
2
  from dataclasses import dataclass
3
3
  from typing import Dict, List, Literal, Optional
4
4
 
5
- from agno.document.base import Document
6
- from agno.document.chunking.strategy import ChunkingStrategy
7
- from agno.document.reader.base import Reader
5
+ from agno.knowledge.chunking.semantic import SemanticChunking
6
+ from agno.knowledge.chunking.strategy import ChunkingStrategy, ChunkingStrategyType
7
+ from agno.knowledge.document.base import Document
8
+ from agno.knowledge.reader.base import Reader
9
+ from agno.knowledge.types import ContentType
8
10
  from agno.utils.log import log_debug, logger
9
11
 
10
12
  try:
@@ -26,17 +28,36 @@ class FirecrawlReader(Reader):
26
28
  mode: Literal["scrape", "crawl"] = "scrape",
27
29
  chunk: bool = True,
28
30
  chunk_size: int = 5000,
29
- chunking_strategy: Optional[ChunkingStrategy] = None,
31
+ chunking_strategy: Optional[ChunkingStrategy] = SemanticChunking(),
32
+ name: Optional[str] = None,
33
+ description: Optional[str] = None,
30
34
  ) -> None:
31
35
  # Initialise base Reader (handles chunk_size / strategy)
32
- super().__init__(chunk=chunk, chunk_size=chunk_size, chunking_strategy=chunking_strategy)
36
+ super().__init__(
37
+ chunk=chunk, chunk_size=chunk_size, chunking_strategy=chunking_strategy, name=name, description=description
38
+ )
33
39
 
34
40
  # Firecrawl-specific attributes
35
41
  self.api_key = api_key
36
42
  self.params = params
37
43
  self.mode = mode
38
44
 
39
- def scrape(self, url: str) -> List[Document]:
45
+ @classmethod
46
+ def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
47
+ """Get the list of supported chunking strategies for Firecrawl readers."""
48
+ return [
49
+ ChunkingStrategyType.SEMANTIC_CHUNKER,
50
+ ChunkingStrategyType.FIXED_SIZE_CHUNKER,
51
+ ChunkingStrategyType.AGENTIC_CHUNKER,
52
+ ChunkingStrategyType.DOCUMENT_CHUNKER,
53
+ ChunkingStrategyType.RECURSIVE_CHUNKER,
54
+ ]
55
+
56
+ @classmethod
57
+ def get_supported_content_types(self) -> List[ContentType]:
58
+ return [ContentType.URL]
59
+
60
+ def scrape(self, url: str, name: Optional[str] = None) -> List[Document]:
40
61
  """
41
62
  Scrapes a website and returns a list of documents.
42
63
 
@@ -71,12 +92,12 @@ class FirecrawlReader(Reader):
71
92
 
72
93
  documents = []
73
94
  if self.chunk and content: # Only chunk if there's content
74
- documents.extend(self.chunk_document(Document(name=url, id=url, content=content)))
95
+ documents.extend(self.chunk_document(Document(name=name or url, id=url, content=content)))
75
96
  else:
76
- documents.append(Document(name=url, id=url, content=content))
97
+ documents.append(Document(name=name or url, id=url, content=content))
77
98
  return documents
78
99
 
79
- async def async_scrape(self, url: str) -> List[Document]:
100
+ async def async_scrape(self, url: str, name: Optional[str] = None) -> List[Document]:
80
101
  """
81
102
  Asynchronously scrapes a website and returns a list of documents.
82
103
 
@@ -89,9 +110,9 @@ class FirecrawlReader(Reader):
89
110
  log_debug(f"Async scraping: {url}")
90
111
 
91
112
  # Use asyncio.to_thread to run the synchronous scrape in a thread
92
- return await asyncio.to_thread(self.scrape, url)
113
+ return await asyncio.to_thread(self.scrape, url, name)
93
114
 
94
- def crawl(self, url: str) -> List[Document]:
115
+ def crawl(self, url: str, name: Optional[str] = None) -> List[Document]:
95
116
  """
96
117
  Crawls a website and returns a list of documents.
97
118
 
@@ -124,13 +145,13 @@ class FirecrawlReader(Reader):
124
145
 
125
146
  if content: # Only create document if content exists
126
147
  if self.chunk:
127
- documents.extend(self.chunk_document(Document(name=url, id=url, content=content)))
148
+ documents.extend(self.chunk_document(Document(name=name or url, id=url, content=content)))
128
149
  else:
129
- documents.append(Document(name=url, id=url, content=content))
150
+ documents.append(Document(name=name or url, id=url, content=content))
130
151
 
131
152
  return documents
132
153
 
133
- async def async_crawl(self, url: str) -> List[Document]:
154
+ async def async_crawl(self, url: str, name: Optional[str] = None) -> List[Document]:
134
155
  """
135
156
  Asynchronously crawls a website and returns a list of documents.
136
157
 
@@ -143,9 +164,9 @@ class FirecrawlReader(Reader):
143
164
  log_debug(f"Async crawling: {url}")
144
165
 
145
166
  # Use asyncio.to_thread to run the synchronous crawl in a thread
146
- return await asyncio.to_thread(self.crawl, url)
167
+ return await asyncio.to_thread(self.crawl, url, name)
147
168
 
148
- def read(self, url: str) -> List[Document]:
169
+ def read(self, url: str, name: Optional[str] = None) -> List[Document]:
149
170
  """
150
171
  Reads from a URL based on the mode setting.
151
172
 
@@ -156,13 +177,13 @@ class FirecrawlReader(Reader):
156
177
  A list of documents
157
178
  """
158
179
  if self.mode == "scrape":
159
- return self.scrape(url)
180
+ return self.scrape(url, name)
160
181
  elif self.mode == "crawl":
161
- return self.crawl(url)
182
+ return self.crawl(url, name)
162
183
  else:
163
184
  raise NotImplementedError(f"Mode {self.mode} not implemented")
164
185
 
165
- async def async_read(self, url: str) -> List[Document]:
186
+ async def async_read(self, url: str, name: Optional[str] = None) -> List[Document]:
166
187
  """
167
188
  Asynchronously reads from a URL based on the mode setting.
168
189
 
@@ -173,8 +194,8 @@ class FirecrawlReader(Reader):
173
194
  A list of documents
174
195
  """
175
196
  if self.mode == "scrape":
176
- return await self.async_scrape(url)
197
+ return await self.async_scrape(url, name)
177
198
  elif self.mode == "crawl":
178
- return await self.async_crawl(url)
199
+ return await self.async_crawl(url, name)
179
200
  else:
180
201
  raise NotImplementedError(f"Mode {self.mode} not implemented")
@@ -2,11 +2,14 @@ import asyncio
2
2
  import json
3
3
  from io import BytesIO
4
4
  from pathlib import Path
5
- from typing import IO, Any, List, Union
5
+ from typing import IO, Any, List, Optional, Union
6
6
  from uuid import uuid4
7
7
 
8
- from agno.document.base import Document
9
- from agno.document.reader.base import Reader
8
+ from agno.knowledge.chunking.fixed import FixedSizeChunking
9
+ from agno.knowledge.chunking.strategy import ChunkingStrategy, ChunkingStrategyType
10
+ from agno.knowledge.document.base import Document
11
+ from agno.knowledge.reader.base import Reader
12
+ from agno.knowledge.types import ContentType
10
13
  from agno.utils.log import log_info
11
14
 
12
15
 
@@ -15,18 +18,36 @@ class JSONReader(Reader):
15
18
 
16
19
  chunk: bool = False
17
20
 
18
- def read(self, path: Union[Path, IO[Any]]) -> List[Document]:
21
+ def __init__(self, chunking_strategy: Optional[ChunkingStrategy] = FixedSizeChunking(), **kwargs):
22
+ super().__init__(chunking_strategy=chunking_strategy, **kwargs)
23
+
24
+ @classmethod
25
+ def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
26
+ """Get the list of supported chunking strategies for JSON readers."""
27
+ return [
28
+ ChunkingStrategyType.FIXED_SIZE_CHUNKER,
29
+ ChunkingStrategyType.AGENTIC_CHUNKER,
30
+ ChunkingStrategyType.DOCUMENT_CHUNKER,
31
+ ChunkingStrategyType.RECURSIVE_CHUNKER,
32
+ ChunkingStrategyType.SEMANTIC_CHUNKER,
33
+ ]
34
+
35
+ @classmethod
36
+ def get_supported_content_types(self) -> List[ContentType]:
37
+ return [ContentType.JSON]
38
+
39
+ def read(self, path: Union[Path, IO[Any]], name: Optional[str] = None) -> List[Document]:
19
40
  try:
20
41
  if isinstance(path, Path):
21
42
  if not path.exists():
22
43
  raise FileNotFoundError(f"Could not find file: {path}")
23
44
  log_info(f"Reading: {path}")
24
- json_name = path.name.split(".")[0]
45
+ json_name = name or path.name.split(".")[0]
25
46
  json_contents = json.loads(path.read_text("utf-8"))
26
47
 
27
48
  elif isinstance(path, BytesIO):
28
- log_info(f"Reading uploaded file: {path.name}")
29
- json_name = path.name.split(".")[0]
49
+ json_name = name or path.name.split(".")[0]
50
+ log_info(f"Reading uploaded file: {json_name}")
30
51
  path.seek(0)
31
52
  json_contents = json.load(path)
32
53
 
@@ -54,7 +75,7 @@ class JSONReader(Reader):
54
75
  except Exception:
55
76
  raise
56
77
 
57
- async def async_read(self, path: Union[Path, IO[Any]]) -> List[Document]:
78
+ async def async_read(self, path: Union[Path, IO[Any]], name: Optional[str] = None) -> List[Document]:
58
79
  """Asynchronously read JSON files.
59
80
 
60
81
  Args:
@@ -63,4 +84,4 @@ class JSONReader(Reader):
63
84
  Returns:
64
85
  List[Document]: List of documents from the JSON file
65
86
  """
66
- return await asyncio.to_thread(self.read, path)
87
+ return await asyncio.to_thread(self.read, path, name)