agno 0.1.2__py3-none-any.whl → 2.3.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (723) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +44 -5
  3. agno/agent/agent.py +10531 -2975
  4. agno/api/agent.py +14 -53
  5. agno/api/api.py +7 -46
  6. agno/api/evals.py +22 -0
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -25
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +6 -9
  11. agno/api/schemas/evals.py +16 -0
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +10 -10
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +16 -0
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +22 -26
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/compression/__init__.py +3 -0
  25. agno/compression/manager.py +247 -0
  26. agno/culture/__init__.py +3 -0
  27. agno/culture/manager.py +956 -0
  28. agno/db/__init__.py +24 -0
  29. agno/db/async_postgres/__init__.py +3 -0
  30. agno/db/base.py +946 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2781 -0
  33. agno/db/dynamo/schemas.py +442 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +2379 -0
  37. agno/db/firestore/schemas.py +181 -0
  38. agno/db/firestore/utils.py +376 -0
  39. agno/db/gcs_json/__init__.py +3 -0
  40. agno/db/gcs_json/gcs_json_db.py +1791 -0
  41. agno/db/gcs_json/utils.py +228 -0
  42. agno/db/in_memory/__init__.py +3 -0
  43. agno/db/in_memory/in_memory_db.py +1312 -0
  44. agno/db/in_memory/utils.py +230 -0
  45. agno/db/json/__init__.py +3 -0
  46. agno/db/json/json_db.py +1777 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/manager.py +199 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/migrations/versions/v2_3_0.py +938 -0
  51. agno/db/mongo/__init__.py +17 -0
  52. agno/db/mongo/async_mongo.py +2760 -0
  53. agno/db/mongo/mongo.py +2597 -0
  54. agno/db/mongo/schemas.py +119 -0
  55. agno/db/mongo/utils.py +276 -0
  56. agno/db/mysql/__init__.py +4 -0
  57. agno/db/mysql/async_mysql.py +2912 -0
  58. agno/db/mysql/mysql.py +2923 -0
  59. agno/db/mysql/schemas.py +186 -0
  60. agno/db/mysql/utils.py +488 -0
  61. agno/db/postgres/__init__.py +4 -0
  62. agno/db/postgres/async_postgres.py +2579 -0
  63. agno/db/postgres/postgres.py +2870 -0
  64. agno/db/postgres/schemas.py +187 -0
  65. agno/db/postgres/utils.py +442 -0
  66. agno/db/redis/__init__.py +3 -0
  67. agno/db/redis/redis.py +2141 -0
  68. agno/db/redis/schemas.py +159 -0
  69. agno/db/redis/utils.py +346 -0
  70. agno/db/schemas/__init__.py +4 -0
  71. agno/db/schemas/culture.py +120 -0
  72. agno/db/schemas/evals.py +34 -0
  73. agno/db/schemas/knowledge.py +40 -0
  74. agno/db/schemas/memory.py +61 -0
  75. agno/db/singlestore/__init__.py +3 -0
  76. agno/db/singlestore/schemas.py +179 -0
  77. agno/db/singlestore/singlestore.py +2877 -0
  78. agno/db/singlestore/utils.py +384 -0
  79. agno/db/sqlite/__init__.py +4 -0
  80. agno/db/sqlite/async_sqlite.py +2911 -0
  81. agno/db/sqlite/schemas.py +181 -0
  82. agno/db/sqlite/sqlite.py +2908 -0
  83. agno/db/sqlite/utils.py +429 -0
  84. agno/db/surrealdb/__init__.py +3 -0
  85. agno/db/surrealdb/metrics.py +292 -0
  86. agno/db/surrealdb/models.py +334 -0
  87. agno/db/surrealdb/queries.py +71 -0
  88. agno/db/surrealdb/surrealdb.py +1908 -0
  89. agno/db/surrealdb/utils.py +147 -0
  90. agno/db/utils.py +118 -0
  91. agno/eval/__init__.py +24 -0
  92. agno/eval/accuracy.py +666 -276
  93. agno/eval/agent_as_judge.py +861 -0
  94. agno/eval/base.py +29 -0
  95. agno/eval/performance.py +779 -0
  96. agno/eval/reliability.py +241 -62
  97. agno/eval/utils.py +120 -0
  98. agno/exceptions.py +143 -1
  99. agno/filters.py +354 -0
  100. agno/guardrails/__init__.py +6 -0
  101. agno/guardrails/base.py +19 -0
  102. agno/guardrails/openai.py +144 -0
  103. agno/guardrails/pii.py +94 -0
  104. agno/guardrails/prompt_injection.py +52 -0
  105. agno/hooks/__init__.py +3 -0
  106. agno/hooks/decorator.py +164 -0
  107. agno/integrations/discord/__init__.py +3 -0
  108. agno/integrations/discord/client.py +203 -0
  109. agno/knowledge/__init__.py +5 -1
  110. agno/{document → knowledge}/chunking/agentic.py +22 -14
  111. agno/{document → knowledge}/chunking/document.py +2 -2
  112. agno/{document → knowledge}/chunking/fixed.py +7 -6
  113. agno/knowledge/chunking/markdown.py +151 -0
  114. agno/{document → knowledge}/chunking/recursive.py +15 -3
  115. agno/knowledge/chunking/row.py +39 -0
  116. agno/knowledge/chunking/semantic.py +91 -0
  117. agno/knowledge/chunking/strategy.py +165 -0
  118. agno/knowledge/content.py +74 -0
  119. agno/knowledge/document/__init__.py +5 -0
  120. agno/{document → knowledge/document}/base.py +12 -2
  121. agno/knowledge/embedder/__init__.py +5 -0
  122. agno/knowledge/embedder/aws_bedrock.py +343 -0
  123. agno/knowledge/embedder/azure_openai.py +210 -0
  124. agno/{embedder → knowledge/embedder}/base.py +8 -0
  125. agno/knowledge/embedder/cohere.py +323 -0
  126. agno/knowledge/embedder/fastembed.py +62 -0
  127. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  128. agno/knowledge/embedder/google.py +258 -0
  129. agno/knowledge/embedder/huggingface.py +94 -0
  130. agno/knowledge/embedder/jina.py +182 -0
  131. agno/knowledge/embedder/langdb.py +22 -0
  132. agno/knowledge/embedder/mistral.py +206 -0
  133. agno/knowledge/embedder/nebius.py +13 -0
  134. agno/knowledge/embedder/ollama.py +154 -0
  135. agno/knowledge/embedder/openai.py +195 -0
  136. agno/knowledge/embedder/sentence_transformer.py +63 -0
  137. agno/{embedder → knowledge/embedder}/together.py +1 -1
  138. agno/knowledge/embedder/vllm.py +262 -0
  139. agno/knowledge/embedder/voyageai.py +165 -0
  140. agno/knowledge/knowledge.py +3006 -0
  141. agno/knowledge/reader/__init__.py +7 -0
  142. agno/knowledge/reader/arxiv_reader.py +81 -0
  143. agno/knowledge/reader/base.py +95 -0
  144. agno/knowledge/reader/csv_reader.py +164 -0
  145. agno/knowledge/reader/docx_reader.py +82 -0
  146. agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
  147. agno/knowledge/reader/firecrawl_reader.py +201 -0
  148. agno/knowledge/reader/json_reader.py +88 -0
  149. agno/knowledge/reader/markdown_reader.py +137 -0
  150. agno/knowledge/reader/pdf_reader.py +431 -0
  151. agno/knowledge/reader/pptx_reader.py +101 -0
  152. agno/knowledge/reader/reader_factory.py +313 -0
  153. agno/knowledge/reader/s3_reader.py +89 -0
  154. agno/knowledge/reader/tavily_reader.py +193 -0
  155. agno/knowledge/reader/text_reader.py +127 -0
  156. agno/knowledge/reader/web_search_reader.py +325 -0
  157. agno/knowledge/reader/website_reader.py +455 -0
  158. agno/knowledge/reader/wikipedia_reader.py +91 -0
  159. agno/knowledge/reader/youtube_reader.py +78 -0
  160. agno/knowledge/remote_content/remote_content.py +88 -0
  161. agno/knowledge/reranker/__init__.py +3 -0
  162. agno/{reranker → knowledge/reranker}/base.py +1 -1
  163. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  164. agno/knowledge/reranker/infinity.py +195 -0
  165. agno/knowledge/reranker/sentence_transformer.py +54 -0
  166. agno/knowledge/types.py +39 -0
  167. agno/knowledge/utils.py +234 -0
  168. agno/media.py +439 -95
  169. agno/memory/__init__.py +16 -3
  170. agno/memory/manager.py +1474 -123
  171. agno/memory/strategies/__init__.py +15 -0
  172. agno/memory/strategies/base.py +66 -0
  173. agno/memory/strategies/summarize.py +196 -0
  174. agno/memory/strategies/types.py +37 -0
  175. agno/models/aimlapi/__init__.py +5 -0
  176. agno/models/aimlapi/aimlapi.py +62 -0
  177. agno/models/anthropic/__init__.py +4 -0
  178. agno/models/anthropic/claude.py +960 -496
  179. agno/models/aws/__init__.py +15 -0
  180. agno/models/aws/bedrock.py +686 -451
  181. agno/models/aws/claude.py +190 -183
  182. agno/models/azure/__init__.py +18 -1
  183. agno/models/azure/ai_foundry.py +489 -0
  184. agno/models/azure/openai_chat.py +89 -40
  185. agno/models/base.py +2477 -550
  186. agno/models/cerebras/__init__.py +12 -0
  187. agno/models/cerebras/cerebras.py +565 -0
  188. agno/models/cerebras/cerebras_openai.py +131 -0
  189. agno/models/cohere/__init__.py +4 -0
  190. agno/models/cohere/chat.py +306 -492
  191. agno/models/cometapi/__init__.py +5 -0
  192. agno/models/cometapi/cometapi.py +74 -0
  193. agno/models/dashscope/__init__.py +5 -0
  194. agno/models/dashscope/dashscope.py +90 -0
  195. agno/models/deepinfra/__init__.py +5 -0
  196. agno/models/deepinfra/deepinfra.py +45 -0
  197. agno/models/deepseek/__init__.py +4 -0
  198. agno/models/deepseek/deepseek.py +110 -9
  199. agno/models/fireworks/__init__.py +4 -0
  200. agno/models/fireworks/fireworks.py +19 -22
  201. agno/models/google/__init__.py +3 -7
  202. agno/models/google/gemini.py +1717 -662
  203. agno/models/google/utils.py +22 -0
  204. agno/models/groq/__init__.py +4 -0
  205. agno/models/groq/groq.py +391 -666
  206. agno/models/huggingface/__init__.py +4 -0
  207. agno/models/huggingface/huggingface.py +266 -538
  208. agno/models/ibm/__init__.py +5 -0
  209. agno/models/ibm/watsonx.py +432 -0
  210. agno/models/internlm/__init__.py +3 -0
  211. agno/models/internlm/internlm.py +20 -3
  212. agno/models/langdb/__init__.py +1 -0
  213. agno/models/langdb/langdb.py +60 -0
  214. agno/models/litellm/__init__.py +14 -0
  215. agno/models/litellm/chat.py +503 -0
  216. agno/models/litellm/litellm_openai.py +42 -0
  217. agno/models/llama_cpp/__init__.py +5 -0
  218. agno/models/llama_cpp/llama_cpp.py +22 -0
  219. agno/models/lmstudio/__init__.py +5 -0
  220. agno/models/lmstudio/lmstudio.py +25 -0
  221. agno/models/message.py +361 -39
  222. agno/models/meta/__init__.py +12 -0
  223. agno/models/meta/llama.py +502 -0
  224. agno/models/meta/llama_openai.py +79 -0
  225. agno/models/metrics.py +120 -0
  226. agno/models/mistral/__init__.py +4 -0
  227. agno/models/mistral/mistral.py +293 -393
  228. agno/models/nebius/__init__.py +3 -0
  229. agno/models/nebius/nebius.py +53 -0
  230. agno/models/nexus/__init__.py +3 -0
  231. agno/models/nexus/nexus.py +22 -0
  232. agno/models/nvidia/__init__.py +4 -0
  233. agno/models/nvidia/nvidia.py +22 -3
  234. agno/models/ollama/__init__.py +4 -2
  235. agno/models/ollama/chat.py +257 -492
  236. agno/models/openai/__init__.py +7 -0
  237. agno/models/openai/chat.py +725 -770
  238. agno/models/openai/like.py +16 -2
  239. agno/models/openai/responses.py +1121 -0
  240. agno/models/openrouter/__init__.py +4 -0
  241. agno/models/openrouter/openrouter.py +62 -5
  242. agno/models/perplexity/__init__.py +5 -0
  243. agno/models/perplexity/perplexity.py +203 -0
  244. agno/models/portkey/__init__.py +3 -0
  245. agno/models/portkey/portkey.py +82 -0
  246. agno/models/requesty/__init__.py +5 -0
  247. agno/models/requesty/requesty.py +69 -0
  248. agno/models/response.py +177 -7
  249. agno/models/sambanova/__init__.py +4 -0
  250. agno/models/sambanova/sambanova.py +23 -4
  251. agno/models/siliconflow/__init__.py +5 -0
  252. agno/models/siliconflow/siliconflow.py +42 -0
  253. agno/models/together/__init__.py +4 -0
  254. agno/models/together/together.py +21 -164
  255. agno/models/utils.py +266 -0
  256. agno/models/vercel/__init__.py +3 -0
  257. agno/models/vercel/v0.py +43 -0
  258. agno/models/vertexai/__init__.py +0 -1
  259. agno/models/vertexai/claude.py +190 -0
  260. agno/models/vllm/__init__.py +3 -0
  261. agno/models/vllm/vllm.py +83 -0
  262. agno/models/xai/__init__.py +2 -0
  263. agno/models/xai/xai.py +111 -7
  264. agno/os/__init__.py +3 -0
  265. agno/os/app.py +1027 -0
  266. agno/os/auth.py +244 -0
  267. agno/os/config.py +126 -0
  268. agno/os/interfaces/__init__.py +1 -0
  269. agno/os/interfaces/a2a/__init__.py +3 -0
  270. agno/os/interfaces/a2a/a2a.py +42 -0
  271. agno/os/interfaces/a2a/router.py +249 -0
  272. agno/os/interfaces/a2a/utils.py +924 -0
  273. agno/os/interfaces/agui/__init__.py +3 -0
  274. agno/os/interfaces/agui/agui.py +47 -0
  275. agno/os/interfaces/agui/router.py +147 -0
  276. agno/os/interfaces/agui/utils.py +574 -0
  277. agno/os/interfaces/base.py +25 -0
  278. agno/os/interfaces/slack/__init__.py +3 -0
  279. agno/os/interfaces/slack/router.py +148 -0
  280. agno/os/interfaces/slack/security.py +30 -0
  281. agno/os/interfaces/slack/slack.py +47 -0
  282. agno/os/interfaces/whatsapp/__init__.py +3 -0
  283. agno/os/interfaces/whatsapp/router.py +210 -0
  284. agno/os/interfaces/whatsapp/security.py +55 -0
  285. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  286. agno/os/mcp.py +293 -0
  287. agno/os/middleware/__init__.py +9 -0
  288. agno/os/middleware/jwt.py +797 -0
  289. agno/os/router.py +258 -0
  290. agno/os/routers/__init__.py +3 -0
  291. agno/os/routers/agents/__init__.py +3 -0
  292. agno/os/routers/agents/router.py +599 -0
  293. agno/os/routers/agents/schema.py +261 -0
  294. agno/os/routers/evals/__init__.py +3 -0
  295. agno/os/routers/evals/evals.py +450 -0
  296. agno/os/routers/evals/schemas.py +174 -0
  297. agno/os/routers/evals/utils.py +231 -0
  298. agno/os/routers/health.py +31 -0
  299. agno/os/routers/home.py +52 -0
  300. agno/os/routers/knowledge/__init__.py +3 -0
  301. agno/os/routers/knowledge/knowledge.py +1008 -0
  302. agno/os/routers/knowledge/schemas.py +178 -0
  303. agno/os/routers/memory/__init__.py +3 -0
  304. agno/os/routers/memory/memory.py +661 -0
  305. agno/os/routers/memory/schemas.py +88 -0
  306. agno/os/routers/metrics/__init__.py +3 -0
  307. agno/os/routers/metrics/metrics.py +190 -0
  308. agno/os/routers/metrics/schemas.py +47 -0
  309. agno/os/routers/session/__init__.py +3 -0
  310. agno/os/routers/session/session.py +997 -0
  311. agno/os/routers/teams/__init__.py +3 -0
  312. agno/os/routers/teams/router.py +512 -0
  313. agno/os/routers/teams/schema.py +257 -0
  314. agno/os/routers/traces/__init__.py +3 -0
  315. agno/os/routers/traces/schemas.py +414 -0
  316. agno/os/routers/traces/traces.py +499 -0
  317. agno/os/routers/workflows/__init__.py +3 -0
  318. agno/os/routers/workflows/router.py +624 -0
  319. agno/os/routers/workflows/schema.py +75 -0
  320. agno/os/schema.py +534 -0
  321. agno/os/scopes.py +469 -0
  322. agno/{playground → os}/settings.py +7 -15
  323. agno/os/utils.py +973 -0
  324. agno/reasoning/anthropic.py +80 -0
  325. agno/reasoning/azure_ai_foundry.py +67 -0
  326. agno/reasoning/deepseek.py +63 -0
  327. agno/reasoning/default.py +97 -0
  328. agno/reasoning/gemini.py +73 -0
  329. agno/reasoning/groq.py +71 -0
  330. agno/reasoning/helpers.py +24 -1
  331. agno/reasoning/ollama.py +67 -0
  332. agno/reasoning/openai.py +86 -0
  333. agno/reasoning/step.py +2 -1
  334. agno/reasoning/vertexai.py +76 -0
  335. agno/run/__init__.py +6 -0
  336. agno/run/agent.py +822 -0
  337. agno/run/base.py +247 -0
  338. agno/run/cancel.py +81 -0
  339. agno/run/requirement.py +181 -0
  340. agno/run/team.py +767 -0
  341. agno/run/workflow.py +708 -0
  342. agno/session/__init__.py +10 -0
  343. agno/session/agent.py +260 -0
  344. agno/session/summary.py +265 -0
  345. agno/session/team.py +342 -0
  346. agno/session/workflow.py +501 -0
  347. agno/table.py +10 -0
  348. agno/team/__init__.py +37 -0
  349. agno/team/team.py +9536 -0
  350. agno/tools/__init__.py +7 -0
  351. agno/tools/agentql.py +120 -0
  352. agno/tools/airflow.py +22 -12
  353. agno/tools/api.py +122 -0
  354. agno/tools/apify.py +276 -83
  355. agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
  356. agno/tools/aws_lambda.py +28 -7
  357. agno/tools/aws_ses.py +66 -0
  358. agno/tools/baidusearch.py +11 -4
  359. agno/tools/bitbucket.py +292 -0
  360. agno/tools/brandfetch.py +213 -0
  361. agno/tools/bravesearch.py +106 -0
  362. agno/tools/brightdata.py +367 -0
  363. agno/tools/browserbase.py +209 -0
  364. agno/tools/calcom.py +32 -23
  365. agno/tools/calculator.py +24 -37
  366. agno/tools/cartesia.py +187 -0
  367. agno/tools/{clickup_tool.py → clickup.py} +17 -28
  368. agno/tools/confluence.py +91 -26
  369. agno/tools/crawl4ai.py +139 -43
  370. agno/tools/csv_toolkit.py +28 -22
  371. agno/tools/dalle.py +36 -22
  372. agno/tools/daytona.py +475 -0
  373. agno/tools/decorator.py +169 -14
  374. agno/tools/desi_vocal.py +23 -11
  375. agno/tools/discord.py +32 -29
  376. agno/tools/docker.py +716 -0
  377. agno/tools/duckdb.py +76 -81
  378. agno/tools/duckduckgo.py +43 -40
  379. agno/tools/e2b.py +703 -0
  380. agno/tools/eleven_labs.py +65 -54
  381. agno/tools/email.py +13 -5
  382. agno/tools/evm.py +129 -0
  383. agno/tools/exa.py +324 -42
  384. agno/tools/fal.py +39 -35
  385. agno/tools/file.py +196 -30
  386. agno/tools/file_generation.py +356 -0
  387. agno/tools/financial_datasets.py +288 -0
  388. agno/tools/firecrawl.py +108 -33
  389. agno/tools/function.py +960 -122
  390. agno/tools/giphy.py +34 -12
  391. agno/tools/github.py +1294 -97
  392. agno/tools/gmail.py +922 -0
  393. agno/tools/google_bigquery.py +117 -0
  394. agno/tools/google_drive.py +271 -0
  395. agno/tools/google_maps.py +253 -0
  396. agno/tools/googlecalendar.py +607 -107
  397. agno/tools/googlesheets.py +377 -0
  398. agno/tools/hackernews.py +20 -12
  399. agno/tools/jina.py +24 -14
  400. agno/tools/jira.py +48 -19
  401. agno/tools/knowledge.py +218 -0
  402. agno/tools/linear.py +82 -43
  403. agno/tools/linkup.py +58 -0
  404. agno/tools/local_file_system.py +15 -7
  405. agno/tools/lumalab.py +41 -26
  406. agno/tools/mcp/__init__.py +10 -0
  407. agno/tools/mcp/mcp.py +331 -0
  408. agno/tools/mcp/multi_mcp.py +347 -0
  409. agno/tools/mcp/params.py +24 -0
  410. agno/tools/mcp_toolbox.py +284 -0
  411. agno/tools/mem0.py +193 -0
  412. agno/tools/memory.py +419 -0
  413. agno/tools/mlx_transcribe.py +11 -9
  414. agno/tools/models/azure_openai.py +190 -0
  415. agno/tools/models/gemini.py +203 -0
  416. agno/tools/models/groq.py +158 -0
  417. agno/tools/models/morph.py +186 -0
  418. agno/tools/models/nebius.py +124 -0
  419. agno/tools/models_labs.py +163 -82
  420. agno/tools/moviepy_video.py +18 -13
  421. agno/tools/nano_banana.py +151 -0
  422. agno/tools/neo4j.py +134 -0
  423. agno/tools/newspaper.py +15 -4
  424. agno/tools/newspaper4k.py +19 -6
  425. agno/tools/notion.py +204 -0
  426. agno/tools/openai.py +181 -17
  427. agno/tools/openbb.py +27 -20
  428. agno/tools/opencv.py +321 -0
  429. agno/tools/openweather.py +233 -0
  430. agno/tools/oxylabs.py +385 -0
  431. agno/tools/pandas.py +25 -15
  432. agno/tools/parallel.py +314 -0
  433. agno/tools/postgres.py +238 -185
  434. agno/tools/pubmed.py +125 -13
  435. agno/tools/python.py +48 -35
  436. agno/tools/reasoning.py +283 -0
  437. agno/tools/reddit.py +207 -29
  438. agno/tools/redshift.py +406 -0
  439. agno/tools/replicate.py +69 -26
  440. agno/tools/resend.py +11 -6
  441. agno/tools/scrapegraph.py +179 -19
  442. agno/tools/searxng.py +23 -31
  443. agno/tools/serpapi.py +15 -10
  444. agno/tools/serper.py +255 -0
  445. agno/tools/shell.py +23 -12
  446. agno/tools/shopify.py +1519 -0
  447. agno/tools/slack.py +56 -14
  448. agno/tools/sleep.py +8 -6
  449. agno/tools/spider.py +35 -11
  450. agno/tools/spotify.py +919 -0
  451. agno/tools/sql.py +34 -19
  452. agno/tools/tavily.py +158 -8
  453. agno/tools/telegram.py +18 -8
  454. agno/tools/todoist.py +218 -0
  455. agno/tools/toolkit.py +134 -9
  456. agno/tools/trafilatura.py +388 -0
  457. agno/tools/trello.py +25 -28
  458. agno/tools/twilio.py +18 -9
  459. agno/tools/user_control_flow.py +78 -0
  460. agno/tools/valyu.py +228 -0
  461. agno/tools/visualization.py +467 -0
  462. agno/tools/webbrowser.py +28 -0
  463. agno/tools/webex.py +76 -0
  464. agno/tools/website.py +23 -19
  465. agno/tools/webtools.py +45 -0
  466. agno/tools/whatsapp.py +286 -0
  467. agno/tools/wikipedia.py +28 -19
  468. agno/tools/workflow.py +285 -0
  469. agno/tools/{twitter.py → x.py} +142 -46
  470. agno/tools/yfinance.py +41 -39
  471. agno/tools/youtube.py +34 -17
  472. agno/tools/zendesk.py +15 -5
  473. agno/tools/zep.py +454 -0
  474. agno/tools/zoom.py +86 -37
  475. agno/tracing/__init__.py +12 -0
  476. agno/tracing/exporter.py +157 -0
  477. agno/tracing/schemas.py +276 -0
  478. agno/tracing/setup.py +111 -0
  479. agno/utils/agent.py +938 -0
  480. agno/utils/audio.py +37 -1
  481. agno/utils/certs.py +27 -0
  482. agno/utils/code_execution.py +11 -0
  483. agno/utils/common.py +103 -20
  484. agno/utils/cryptography.py +22 -0
  485. agno/utils/dttm.py +33 -0
  486. agno/utils/events.py +700 -0
  487. agno/utils/functions.py +107 -37
  488. agno/utils/gemini.py +426 -0
  489. agno/utils/hooks.py +171 -0
  490. agno/utils/http.py +185 -0
  491. agno/utils/json_schema.py +159 -37
  492. agno/utils/knowledge.py +36 -0
  493. agno/utils/location.py +19 -0
  494. agno/utils/log.py +221 -8
  495. agno/utils/mcp.py +214 -0
  496. agno/utils/media.py +335 -14
  497. agno/utils/merge_dict.py +22 -1
  498. agno/utils/message.py +77 -2
  499. agno/utils/models/ai_foundry.py +50 -0
  500. agno/utils/models/claude.py +373 -0
  501. agno/utils/models/cohere.py +94 -0
  502. agno/utils/models/llama.py +85 -0
  503. agno/utils/models/mistral.py +100 -0
  504. agno/utils/models/openai_responses.py +140 -0
  505. agno/utils/models/schema_utils.py +153 -0
  506. agno/utils/models/watsonx.py +41 -0
  507. agno/utils/openai.py +257 -0
  508. agno/utils/pickle.py +1 -1
  509. agno/utils/pprint.py +124 -8
  510. agno/utils/print_response/agent.py +930 -0
  511. agno/utils/print_response/team.py +1914 -0
  512. agno/utils/print_response/workflow.py +1668 -0
  513. agno/utils/prompts.py +111 -0
  514. agno/utils/reasoning.py +108 -0
  515. agno/utils/response.py +163 -0
  516. agno/utils/serialize.py +32 -0
  517. agno/utils/shell.py +4 -4
  518. agno/utils/streamlit.py +487 -0
  519. agno/utils/string.py +204 -51
  520. agno/utils/team.py +139 -0
  521. agno/utils/timer.py +9 -2
  522. agno/utils/tokens.py +657 -0
  523. agno/utils/tools.py +19 -1
  524. agno/utils/whatsapp.py +305 -0
  525. agno/utils/yaml_io.py +3 -3
  526. agno/vectordb/__init__.py +2 -0
  527. agno/vectordb/base.py +87 -9
  528. agno/vectordb/cassandra/__init__.py +5 -1
  529. agno/vectordb/cassandra/cassandra.py +383 -27
  530. agno/vectordb/chroma/__init__.py +4 -0
  531. agno/vectordb/chroma/chromadb.py +748 -83
  532. agno/vectordb/clickhouse/__init__.py +7 -1
  533. agno/vectordb/clickhouse/clickhousedb.py +554 -53
  534. agno/vectordb/couchbase/__init__.py +3 -0
  535. agno/vectordb/couchbase/couchbase.py +1446 -0
  536. agno/vectordb/lancedb/__init__.py +5 -0
  537. agno/vectordb/lancedb/lance_db.py +730 -98
  538. agno/vectordb/langchaindb/__init__.py +5 -0
  539. agno/vectordb/langchaindb/langchaindb.py +163 -0
  540. agno/vectordb/lightrag/__init__.py +5 -0
  541. agno/vectordb/lightrag/lightrag.py +388 -0
  542. agno/vectordb/llamaindex/__init__.py +3 -0
  543. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  544. agno/vectordb/milvus/__init__.py +3 -0
  545. agno/vectordb/milvus/milvus.py +966 -78
  546. agno/vectordb/mongodb/__init__.py +9 -1
  547. agno/vectordb/mongodb/mongodb.py +1175 -172
  548. agno/vectordb/pgvector/__init__.py +8 -0
  549. agno/vectordb/pgvector/pgvector.py +599 -115
  550. agno/vectordb/pineconedb/__init__.py +5 -1
  551. agno/vectordb/pineconedb/pineconedb.py +406 -43
  552. agno/vectordb/qdrant/__init__.py +4 -0
  553. agno/vectordb/qdrant/qdrant.py +914 -61
  554. agno/vectordb/redis/__init__.py +9 -0
  555. agno/vectordb/redis/redisdb.py +682 -0
  556. agno/vectordb/singlestore/__init__.py +8 -1
  557. agno/vectordb/singlestore/singlestore.py +771 -0
  558. agno/vectordb/surrealdb/__init__.py +3 -0
  559. agno/vectordb/surrealdb/surrealdb.py +663 -0
  560. agno/vectordb/upstashdb/__init__.py +5 -0
  561. agno/vectordb/upstashdb/upstashdb.py +718 -0
  562. agno/vectordb/weaviate/__init__.py +8 -0
  563. agno/vectordb/weaviate/index.py +15 -0
  564. agno/vectordb/weaviate/weaviate.py +1009 -0
  565. agno/workflow/__init__.py +23 -1
  566. agno/workflow/agent.py +299 -0
  567. agno/workflow/condition.py +759 -0
  568. agno/workflow/loop.py +756 -0
  569. agno/workflow/parallel.py +853 -0
  570. agno/workflow/router.py +723 -0
  571. agno/workflow/step.py +1564 -0
  572. agno/workflow/steps.py +613 -0
  573. agno/workflow/types.py +556 -0
  574. agno/workflow/workflow.py +4327 -514
  575. agno-2.3.13.dist-info/METADATA +639 -0
  576. agno-2.3.13.dist-info/RECORD +613 -0
  577. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
  578. agno-2.3.13.dist-info/licenses/LICENSE +201 -0
  579. agno/api/playground.py +0 -91
  580. agno/api/schemas/playground.py +0 -22
  581. agno/api/schemas/user.py +0 -22
  582. agno/api/schemas/workspace.py +0 -46
  583. agno/api/user.py +0 -160
  584. agno/api/workspace.py +0 -151
  585. agno/cli/auth_server.py +0 -118
  586. agno/cli/config.py +0 -275
  587. agno/cli/console.py +0 -88
  588. agno/cli/credentials.py +0 -23
  589. agno/cli/entrypoint.py +0 -571
  590. agno/cli/operator.py +0 -355
  591. agno/cli/settings.py +0 -85
  592. agno/cli/ws/ws_cli.py +0 -817
  593. agno/constants.py +0 -13
  594. agno/document/__init__.py +0 -1
  595. agno/document/chunking/semantic.py +0 -47
  596. agno/document/chunking/strategy.py +0 -31
  597. agno/document/reader/__init__.py +0 -1
  598. agno/document/reader/arxiv_reader.py +0 -41
  599. agno/document/reader/base.py +0 -22
  600. agno/document/reader/csv_reader.py +0 -84
  601. agno/document/reader/docx_reader.py +0 -46
  602. agno/document/reader/firecrawl_reader.py +0 -99
  603. agno/document/reader/json_reader.py +0 -43
  604. agno/document/reader/pdf_reader.py +0 -219
  605. agno/document/reader/s3/pdf_reader.py +0 -46
  606. agno/document/reader/s3/text_reader.py +0 -51
  607. agno/document/reader/text_reader.py +0 -41
  608. agno/document/reader/website_reader.py +0 -175
  609. agno/document/reader/youtube_reader.py +0 -50
  610. agno/embedder/__init__.py +0 -1
  611. agno/embedder/azure_openai.py +0 -86
  612. agno/embedder/cohere.py +0 -72
  613. agno/embedder/fastembed.py +0 -37
  614. agno/embedder/google.py +0 -73
  615. agno/embedder/huggingface.py +0 -54
  616. agno/embedder/mistral.py +0 -80
  617. agno/embedder/ollama.py +0 -57
  618. agno/embedder/openai.py +0 -74
  619. agno/embedder/sentence_transformer.py +0 -38
  620. agno/embedder/voyageai.py +0 -64
  621. agno/eval/perf.py +0 -201
  622. agno/file/__init__.py +0 -1
  623. agno/file/file.py +0 -16
  624. agno/file/local/csv.py +0 -32
  625. agno/file/local/txt.py +0 -19
  626. agno/infra/app.py +0 -240
  627. agno/infra/base.py +0 -144
  628. agno/infra/context.py +0 -20
  629. agno/infra/db_app.py +0 -52
  630. agno/infra/resource.py +0 -205
  631. agno/infra/resources.py +0 -55
  632. agno/knowledge/agent.py +0 -230
  633. agno/knowledge/arxiv.py +0 -22
  634. agno/knowledge/combined.py +0 -22
  635. agno/knowledge/csv.py +0 -28
  636. agno/knowledge/csv_url.py +0 -19
  637. agno/knowledge/document.py +0 -20
  638. agno/knowledge/docx.py +0 -30
  639. agno/knowledge/json.py +0 -28
  640. agno/knowledge/langchain.py +0 -71
  641. agno/knowledge/llamaindex.py +0 -66
  642. agno/knowledge/pdf.py +0 -28
  643. agno/knowledge/pdf_url.py +0 -26
  644. agno/knowledge/s3/base.py +0 -60
  645. agno/knowledge/s3/pdf.py +0 -21
  646. agno/knowledge/s3/text.py +0 -23
  647. agno/knowledge/text.py +0 -30
  648. agno/knowledge/website.py +0 -88
  649. agno/knowledge/wikipedia.py +0 -31
  650. agno/knowledge/youtube.py +0 -22
  651. agno/memory/agent.py +0 -392
  652. agno/memory/classifier.py +0 -104
  653. agno/memory/db/__init__.py +0 -1
  654. agno/memory/db/base.py +0 -42
  655. agno/memory/db/mongodb.py +0 -189
  656. agno/memory/db/postgres.py +0 -203
  657. agno/memory/db/sqlite.py +0 -193
  658. agno/memory/memory.py +0 -15
  659. agno/memory/row.py +0 -36
  660. agno/memory/summarizer.py +0 -192
  661. agno/memory/summary.py +0 -19
  662. agno/memory/workflow.py +0 -38
  663. agno/models/google/gemini_openai.py +0 -26
  664. agno/models/ollama/hermes.py +0 -221
  665. agno/models/ollama/tools.py +0 -362
  666. agno/models/vertexai/gemini.py +0 -595
  667. agno/playground/__init__.py +0 -3
  668. agno/playground/async_router.py +0 -421
  669. agno/playground/deploy.py +0 -249
  670. agno/playground/operator.py +0 -92
  671. agno/playground/playground.py +0 -91
  672. agno/playground/schemas.py +0 -76
  673. agno/playground/serve.py +0 -55
  674. agno/playground/sync_router.py +0 -405
  675. agno/reasoning/agent.py +0 -68
  676. agno/run/response.py +0 -112
  677. agno/storage/agent/__init__.py +0 -0
  678. agno/storage/agent/base.py +0 -38
  679. agno/storage/agent/dynamodb.py +0 -350
  680. agno/storage/agent/json.py +0 -92
  681. agno/storage/agent/mongodb.py +0 -228
  682. agno/storage/agent/postgres.py +0 -367
  683. agno/storage/agent/session.py +0 -79
  684. agno/storage/agent/singlestore.py +0 -303
  685. agno/storage/agent/sqlite.py +0 -357
  686. agno/storage/agent/yaml.py +0 -93
  687. agno/storage/workflow/__init__.py +0 -0
  688. agno/storage/workflow/base.py +0 -40
  689. agno/storage/workflow/mongodb.py +0 -233
  690. agno/storage/workflow/postgres.py +0 -366
  691. agno/storage/workflow/session.py +0 -60
  692. agno/storage/workflow/sqlite.py +0 -359
  693. agno/tools/googlesearch.py +0 -88
  694. agno/utils/defaults.py +0 -57
  695. agno/utils/filesystem.py +0 -39
  696. agno/utils/git.py +0 -52
  697. agno/utils/json_io.py +0 -30
  698. agno/utils/load_env.py +0 -19
  699. agno/utils/py_io.py +0 -19
  700. agno/utils/pyproject.py +0 -18
  701. agno/utils/resource_filter.py +0 -31
  702. agno/vectordb/singlestore/s2vectordb.py +0 -390
  703. agno/vectordb/singlestore/s2vectordb2.py +0 -355
  704. agno/workspace/__init__.py +0 -0
  705. agno/workspace/config.py +0 -325
  706. agno/workspace/enums.py +0 -6
  707. agno/workspace/helpers.py +0 -48
  708. agno/workspace/operator.py +0 -758
  709. agno/workspace/settings.py +0 -63
  710. agno-0.1.2.dist-info/LICENSE +0 -375
  711. agno-0.1.2.dist-info/METADATA +0 -502
  712. agno-0.1.2.dist-info/RECORD +0 -352
  713. agno-0.1.2.dist-info/entry_points.txt +0 -3
  714. /agno/{cli → db/migrations}/__init__.py +0 -0
  715. /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
  716. /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
  717. /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
  718. /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
  719. /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
  720. /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
  721. /agno/{reranker → utils/models}/__init__.py +0 -0
  722. /agno/{storage → utils/print_response}/__init__.py +0 -0
  723. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,313 @@
1
+ import os
2
+ from typing import Any, Callable, Dict, List, Optional
3
+
4
+ from agno.knowledge.reader.base import Reader
5
+
6
+
7
+ class ReaderFactory:
8
+ """Factory for creating and managing document readers with lazy loading."""
9
+
10
+ # Cache for instantiated readers
11
+ _reader_cache: Dict[str, Reader] = {}
12
+
13
+ @classmethod
14
+ def _get_pdf_reader(cls, **kwargs) -> Reader:
15
+ """Get PDF reader instance."""
16
+ from agno.knowledge.reader.pdf_reader import PDFReader
17
+
18
+ config: Dict[str, Any] = {
19
+ "name": "PDF Reader",
20
+ "description": "Processes PDF documents with OCR support for images and text extraction",
21
+ }
22
+ config.update(kwargs)
23
+ return PDFReader(**config)
24
+
25
+ @classmethod
26
+ def _get_csv_reader(cls, **kwargs) -> Reader:
27
+ """Get CSV reader instance."""
28
+ from agno.knowledge.reader.csv_reader import CSVReader
29
+
30
+ config: Dict[str, Any] = {
31
+ "name": "CSV Reader",
32
+ "description": "Parses CSV, XLSX, and XLS files with custom delimiter support",
33
+ }
34
+ config.update(kwargs)
35
+ return CSVReader(**config)
36
+
37
+ @classmethod
38
+ def _get_field_labeled_csv_reader(cls, **kwargs) -> Reader:
39
+ """Get Field Labeled CSV reader instance."""
40
+ from agno.knowledge.reader.field_labeled_csv_reader import FieldLabeledCSVReader
41
+
42
+ config: Dict[str, Any] = {
43
+ "name": "Field Labeled CSV Reader",
44
+ "description": "Converts CSV rows to field-labeled text format for enhanced readability and context",
45
+ }
46
+ config.update(kwargs)
47
+ return FieldLabeledCSVReader(**config)
48
+
49
+ @classmethod
50
+ def _get_docx_reader(cls, **kwargs) -> Reader:
51
+ """Get Docx reader instance."""
52
+ from agno.knowledge.reader.docx_reader import DocxReader
53
+
54
+ config: Dict[str, Any] = {
55
+ "name": "Docx Reader",
56
+ "description": "Extracts text content from Microsoft Word documents (.docx and .doc formats)",
57
+ }
58
+ config.update(kwargs)
59
+ return DocxReader(**config)
60
+
61
+ @classmethod
62
+ def _get_pptx_reader(cls, **kwargs) -> Reader:
63
+ """Get PPTX reader instance."""
64
+ from agno.knowledge.reader.pptx_reader import PPTXReader
65
+
66
+ config: Dict[str, Any] = {
67
+ "name": "PPTX Reader",
68
+ "description": "Extracts text content from Microsoft PowerPoint presentations (.pptx format)",
69
+ }
70
+ config.update(kwargs)
71
+ return PPTXReader(**config)
72
+
73
+ @classmethod
74
+ def _get_json_reader(cls, **kwargs) -> Reader:
75
+ """Get JSON reader instance."""
76
+ from agno.knowledge.reader.json_reader import JSONReader
77
+
78
+ config: Dict[str, Any] = {
79
+ "name": "JSON Reader",
80
+ "description": "Processes JSON data structures and API responses with nested object handling",
81
+ }
82
+ config.update(kwargs)
83
+ return JSONReader(**config)
84
+
85
+ @classmethod
86
+ def _get_markdown_reader(cls, **kwargs) -> Reader:
87
+ """Get Markdown reader instance."""
88
+ from agno.knowledge.reader.markdown_reader import MarkdownReader
89
+
90
+ config: Dict[str, Any] = {
91
+ "name": "Markdown Reader",
92
+ "description": "Processes Markdown documentation with header-aware chunking and formatting preservation",
93
+ }
94
+ config.update(kwargs)
95
+ return MarkdownReader(**config)
96
+
97
+ @classmethod
98
+ def _get_text_reader(cls, **kwargs) -> Reader:
99
+ """Get Text reader instance."""
100
+ from agno.knowledge.reader.text_reader import TextReader
101
+
102
+ config: Dict[str, Any] = {
103
+ "name": "Text Reader",
104
+ "description": "Handles plain text files with customizable chunking strategies and encoding detection",
105
+ }
106
+ config.update(kwargs)
107
+ return TextReader(**config)
108
+
109
+ @classmethod
110
+ def _get_website_reader(cls, **kwargs) -> Reader:
111
+ """Get Website reader instance."""
112
+ from agno.knowledge.reader.website_reader import WebsiteReader
113
+
114
+ config: Dict[str, Any] = {
115
+ "name": "Website Reader",
116
+ "description": "Scrapes and extracts content from web pages with HTML parsing and text cleaning",
117
+ }
118
+ config.update(kwargs)
119
+ return WebsiteReader(**config)
120
+
121
+ @classmethod
122
+ def _get_firecrawl_reader(cls, **kwargs) -> Reader:
123
+ """Get Firecrawl reader instance."""
124
+ from agno.knowledge.reader.firecrawl_reader import FirecrawlReader
125
+
126
+ config: Dict[str, Any] = {
127
+ "api_key": kwargs.get("api_key") or os.getenv("FIRECRAWL_API_KEY"),
128
+ "mode": "crawl",
129
+ "name": "Firecrawl Reader",
130
+ "description": "Advanced web scraping and crawling with JavaScript rendering and structured data extraction",
131
+ }
132
+ config.update(kwargs)
133
+ return FirecrawlReader(**config)
134
+
135
+ @classmethod
136
+ def _get_tavily_reader(cls, **kwargs) -> Reader:
137
+ """Get Tavily reader instance."""
138
+ from agno.knowledge.reader.tavily_reader import TavilyReader
139
+
140
+ config: Dict[str, Any] = {
141
+ "api_key": kwargs.get("api_key") or os.getenv("TAVILY_API_KEY"),
142
+ "extract_format": "markdown",
143
+ "extract_depth": "basic",
144
+ "name": "Tavily Reader",
145
+ "description": "Extracts content from URLs using Tavily's Extract API with markdown or text output",
146
+ }
147
+ config.update(kwargs)
148
+ return TavilyReader(**config)
149
+
150
+ @classmethod
151
+ def _get_youtube_reader(cls, **kwargs) -> Reader:
152
+ """Get YouTube reader instance."""
153
+ from agno.knowledge.reader.youtube_reader import YouTubeReader
154
+
155
+ config: Dict[str, Any] = {
156
+ "name": "YouTube Reader",
157
+ "description": "Extracts transcripts and metadata from YouTube videos and playlists",
158
+ }
159
+ config.update(kwargs)
160
+ return YouTubeReader(**config)
161
+
162
+ @classmethod
163
+ def _get_arxiv_reader(cls, **kwargs) -> Reader:
164
+ """Get Arxiv reader instance."""
165
+ from agno.knowledge.reader.arxiv_reader import ArxivReader
166
+
167
+ config: Dict[str, Any] = {
168
+ "name": "Arxiv Reader",
169
+ "description": "Downloads and processes academic papers from ArXiv with PDF parsing and metadata extraction",
170
+ }
171
+ config.update(kwargs)
172
+ return ArxivReader(**config)
173
+
174
+ @classmethod
175
+ def _get_wikipedia_reader(cls, **kwargs) -> Reader:
176
+ """Get Wikipedia reader instance."""
177
+ from agno.knowledge.reader.wikipedia_reader import WikipediaReader
178
+
179
+ config: Dict[str, Any] = {
180
+ "name": "Wikipedia Reader",
181
+ "description": "Fetches and processes Wikipedia articles with section-aware chunking and link resolution",
182
+ }
183
+ config.update(kwargs)
184
+ return WikipediaReader(**config)
185
+
186
+ @classmethod
187
+ def _get_web_search_reader(cls, **kwargs) -> Reader:
188
+ """Get Web Search reader instance."""
189
+ from agno.knowledge.reader.web_search_reader import WebSearchReader
190
+
191
+ config: Dict[str, Any] = {
192
+ "name": "Web Search Reader",
193
+ "description": "Executes web searches and processes results with relevance ranking and content extraction",
194
+ }
195
+ config.update(kwargs)
196
+ return WebSearchReader(**config)
197
+
198
+ @classmethod
199
+ def _get_reader_method(cls, reader_key: str) -> Callable[[], Reader]:
200
+ """Get the appropriate reader method for the given key."""
201
+ method_name = f"_get_{reader_key}_reader"
202
+ if not hasattr(cls, method_name):
203
+ raise ValueError(f"Unknown reader: {reader_key}")
204
+ return getattr(cls, method_name)
205
+
206
+ @classmethod
207
+ def create_reader(cls, reader_key: str, **kwargs) -> Reader:
208
+ """Create a reader instance with the given key and optional overrides."""
209
+ if reader_key in cls._reader_cache:
210
+ return cls._reader_cache[reader_key]
211
+
212
+ # Get the reader method and create the instance
213
+ reader_method = cls._get_reader_method(reader_key)
214
+ reader = reader_method(**kwargs)
215
+
216
+ # Cache the reader
217
+ cls._reader_cache[reader_key] = reader
218
+
219
+ return reader
220
+
221
+ @classmethod
222
+ def get_reader_for_extension(cls, extension: str) -> Reader:
223
+ """Get the appropriate reader for a file extension."""
224
+ extension = extension.lower()
225
+
226
+ if extension in [".pdf", "application/pdf"]:
227
+ return cls.create_reader("pdf")
228
+ elif extension in [".csv", "text/csv"]:
229
+ return cls.create_reader("csv")
230
+ elif extension in [".docx", ".doc", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"]:
231
+ return cls.create_reader("docx")
232
+ elif extension == ".pptx":
233
+ return cls.create_reader("pptx")
234
+ elif extension == ".json":
235
+ return cls.create_reader("json")
236
+ elif extension in [".md", ".markdown"]:
237
+ return cls.create_reader("markdown")
238
+ elif extension in [".txt", ".text"]:
239
+ return cls.create_reader("text")
240
+ else:
241
+ # Default to text reader for unknown extensions
242
+ return cls.create_reader("text")
243
+
244
+ @classmethod
245
+ def get_reader_for_url(cls, url: str) -> Reader:
246
+ """Get the appropriate reader for a URL."""
247
+ url_lower = url.lower()
248
+
249
+ # Check for YouTube URLs
250
+ if any(domain in url_lower for domain in ["youtube.com", "youtu.be"]):
251
+ return cls.create_reader("youtube")
252
+
253
+ # Default to website reader
254
+ return cls.create_reader("website")
255
+
256
+ @classmethod
257
+ def get_all_reader_keys(cls) -> List[str]:
258
+ """Get all available reader keys in priority order."""
259
+ # Extract reader keys from method names
260
+
261
+ PREFIX = "_get_"
262
+ SUFFIX = "_reader"
263
+
264
+ reader_keys = []
265
+ for attr_name in dir(cls):
266
+ if attr_name.startswith(PREFIX) and attr_name.endswith(SUFFIX):
267
+ reader_key = attr_name[len(PREFIX) : -len(SUFFIX)] # Remove "_get_" prefix and "_reader" suffix
268
+ reader_keys.append(reader_key)
269
+
270
+ # Define priority order for URL readers
271
+ url_reader_priority = [
272
+ "website",
273
+ "firecrawl",
274
+ "tavily",
275
+ "youtube",
276
+ ]
277
+
278
+ # Sort with URL readers in priority order, others alphabetically
279
+ def sort_key(reader_key):
280
+ if reader_key in url_reader_priority:
281
+ return (0, url_reader_priority.index(reader_key))
282
+ else:
283
+ return (1, reader_key)
284
+
285
+ reader_keys.sort(key=sort_key)
286
+ return reader_keys
287
+
288
+ @classmethod
289
+ def create_all_readers(cls) -> Dict[str, Reader]:
290
+ """Create all readers and return them as a dictionary."""
291
+ readers = {}
292
+ for reader_key in cls.get_all_reader_keys():
293
+ readers[reader_key] = cls.create_reader(reader_key)
294
+ return readers
295
+
296
+ @classmethod
297
+ def clear_cache(cls):
298
+ """Clear the reader cache."""
299
+ cls._reader_cache.clear()
300
+
301
+ @classmethod
302
+ def register_reader(
303
+ cls,
304
+ key: str,
305
+ reader_method,
306
+ name: str,
307
+ description: str,
308
+ extensions: Optional[List[str]] = None,
309
+ ):
310
+ """Register a new reader type."""
311
+ # Add the reader method to the class
312
+ method_name = f"_get_{key}_reader"
313
+ setattr(cls, method_name, classmethod(reader_method))
@@ -0,0 +1,89 @@
1
+ import asyncio
2
+ from io import BytesIO
3
+ from pathlib import Path
4
+ from typing import List, Optional
5
+
6
+ from agno.knowledge.chunking.fixed import FixedSizeChunking
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.reader.pdf_reader import PDFReader
11
+ from agno.knowledge.reader.text_reader import TextReader
12
+ from agno.knowledge.types import ContentType
13
+ from agno.utils.log import log_debug, log_error
14
+
15
+ try:
16
+ from agno.aws.resource.s3.object import S3Object # type: ignore
17
+ except (ModuleNotFoundError, ImportError):
18
+ raise ImportError("`agno-aws` not installed. Please install using `pip install agno-aws`")
19
+
20
+ try:
21
+ import textract # noqa: F401
22
+ except ImportError:
23
+ raise ImportError("`textract` not installed. Please install it via `pip install textract`.")
24
+
25
+ try:
26
+ from pypdf import PdfReader as DocumentReader # noqa: F401
27
+ except ImportError:
28
+ raise ImportError("`pypdf` not installed. Please install it via `pip install pypdf`.")
29
+
30
+
31
+ class S3Reader(Reader):
32
+ """Reader for S3 files"""
33
+
34
+ def __init__(self, chunking_strategy: Optional[ChunkingStrategy] = FixedSizeChunking(), **kwargs):
35
+ super().__init__(chunking_strategy=chunking_strategy, **kwargs)
36
+
37
+ @classmethod
38
+ def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
39
+ """Get the list of supported chunking strategies for S3 readers."""
40
+ return [
41
+ ChunkingStrategyType.FIXED_SIZE_CHUNKER,
42
+ ChunkingStrategyType.AGENTIC_CHUNKER,
43
+ ChunkingStrategyType.DOCUMENT_CHUNKER,
44
+ ChunkingStrategyType.RECURSIVE_CHUNKER,
45
+ ChunkingStrategyType.SEMANTIC_CHUNKER,
46
+ ]
47
+
48
+ @classmethod
49
+ def get_supported_content_types(self) -> List[ContentType]:
50
+ return [ContentType.FILE, ContentType.URL, ContentType.TEXT]
51
+
52
+ def read(self, name: Optional[str], s3_object: S3Object) -> List[Document]:
53
+ try:
54
+ log_debug(f"Reading S3 file: {s3_object.uri}")
55
+
56
+ # Read PDF files
57
+ if s3_object.uri.endswith(".pdf"):
58
+ object_resource = s3_object.get_resource()
59
+ object_body = object_resource.get()["Body"]
60
+ doc_name = (
61
+ s3_object.name.split("/")[-1].split(".")[0].replace("/", "_").replace(" ", "_")
62
+ if name is None
63
+ else name
64
+ )
65
+ return PDFReader().read(pdf=BytesIO(object_body.read()), name=doc_name)
66
+
67
+ # Read text files
68
+ else:
69
+ doc_name = (
70
+ s3_object.name.split("/")[-1].split(".")[0].replace("/", "_").replace(" ", "_")
71
+ if name is None
72
+ else name
73
+ )
74
+ obj_name = s3_object.name.split("/")[-1]
75
+ temporary_file = Path("storage").joinpath(obj_name)
76
+ s3_object.download(temporary_file)
77
+ documents = TextReader().read(file=temporary_file, name=doc_name)
78
+
79
+ temporary_file.unlink()
80
+ return documents
81
+
82
+ except Exception as e:
83
+ log_error(f"Error reading: {s3_object.uri}: {e}")
84
+
85
+ return []
86
+
87
+ async def async_read(self, name: Optional[str], s3_object: S3Object) -> List[Document]:
88
+ """Asynchronously read S3 files by running the synchronous read operation in a thread."""
89
+ return await asyncio.to_thread(self.read, name, s3_object)
@@ -0,0 +1,193 @@
1
+ import asyncio
2
+ from dataclasses import dataclass
3
+ from typing import Dict, List, Literal, Optional
4
+
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
10
+ from agno.utils.log import log_debug, logger
11
+
12
+ try:
13
+ from tavily import TavilyClient # type: ignore[attr-defined]
14
+ except ImportError:
15
+ raise ImportError(
16
+ "The `tavily-python` package is not installed. Please install it via `pip install tavily-python`."
17
+ )
18
+
19
+
20
+ @dataclass
21
+ class TavilyReader(Reader):
22
+ api_key: Optional[str] = None
23
+ params: Optional[Dict] = None
24
+ extract_format: Literal["markdown", "text"] = "markdown"
25
+ extract_depth: Literal["basic", "advanced"] = "basic"
26
+
27
+ def __init__(
28
+ self,
29
+ api_key: Optional[str] = None,
30
+ params: Optional[Dict] = None,
31
+ extract_format: Literal["markdown", "text"] = "markdown",
32
+ extract_depth: Literal["basic", "advanced"] = "basic",
33
+ chunk: bool = True,
34
+ chunk_size: int = 5000,
35
+ chunking_strategy: Optional[ChunkingStrategy] = SemanticChunking(),
36
+ name: Optional[str] = None,
37
+ description: Optional[str] = None,
38
+ ) -> None:
39
+ """
40
+ Initialize TavilyReader for extracting content from URLs using Tavily's Extract API.
41
+
42
+ Args:
43
+ api_key: Tavily API key (or use TAVILY_API_KEY env var)
44
+ params: Additional parameters to pass to the extract API
45
+ extract_format: Output format - "markdown" or "text"
46
+ extract_depth: Extraction depth - "basic" (1 credit/5 URLs) or "advanced" (2 credits/5 URLs)
47
+ chunk: Whether to chunk the extracted content
48
+ chunk_size: Size of chunks when chunking is enabled
49
+ chunking_strategy: Strategy to use for chunking
50
+ name: Name of the reader
51
+ description: Description of the reader
52
+ """
53
+ # Initialize base Reader (handles chunk_size / strategy)
54
+ super().__init__(
55
+ chunk=chunk, chunk_size=chunk_size, chunking_strategy=chunking_strategy, name=name, description=description
56
+ )
57
+
58
+ # Tavily-specific attributes
59
+ self.api_key = api_key
60
+ self.params = params or {}
61
+ self.extract_format = extract_format
62
+ self.extract_depth = extract_depth
63
+
64
+ @classmethod
65
+ def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
66
+ """Get the list of supported chunking strategies for Tavily readers."""
67
+ return [
68
+ ChunkingStrategyType.SEMANTIC_CHUNKER,
69
+ ChunkingStrategyType.FIXED_SIZE_CHUNKER,
70
+ ChunkingStrategyType.AGENTIC_CHUNKER,
71
+ ChunkingStrategyType.DOCUMENT_CHUNKER,
72
+ ChunkingStrategyType.RECURSIVE_CHUNKER,
73
+ ]
74
+
75
+ @classmethod
76
+ def get_supported_content_types(self) -> List[ContentType]:
77
+ return [ContentType.URL]
78
+
79
+ def _extract(self, url: str, name: Optional[str] = None) -> List[Document]:
80
+ """
81
+ Internal method to extract content from a URL using Tavily's Extract API.
82
+
83
+ Args:
84
+ url: The URL to extract content from
85
+ name: Optional name for the document (defaults to URL)
86
+
87
+ Returns:
88
+ A list of documents containing the extracted content
89
+ """
90
+ log_debug(f"Extracting content from: {url}")
91
+
92
+ client = TavilyClient(api_key=self.api_key)
93
+
94
+ # Prepare extract parameters
95
+ extract_params = {
96
+ "urls": [url],
97
+ "depth": self.extract_depth,
98
+ }
99
+
100
+ # Add optional params if provided
101
+ if self.params:
102
+ extract_params.update(self.params)
103
+
104
+ try:
105
+ # Call Tavily Extract API
106
+ response = client.extract(**extract_params)
107
+
108
+ # Extract content from response
109
+ if not response or "results" not in response:
110
+ logger.warning(f"No results received for URL: {url}")
111
+ return [Document(name=name or url, id=url, content="")]
112
+
113
+ results = response.get("results", [])
114
+ if not results:
115
+ logger.warning(f"Empty results for URL: {url}")
116
+ return [Document(name=name or url, id=url, content="")]
117
+
118
+ # Get the first result (since we're extracting a single URL)
119
+ result = results[0]
120
+
121
+ # Check if extraction failed
122
+ if "failed_reason" in result:
123
+ logger.warning(f"Extraction failed for {url}: {result['failed_reason']}")
124
+ return [Document(name=name or url, id=url, content="")]
125
+
126
+ # Get raw content
127
+ content = result.get("raw_content", "")
128
+
129
+ if content is None:
130
+ content = ""
131
+ logger.warning(f"No content received for URL: {url}")
132
+
133
+ # Debug logging
134
+ log_debug(f"Received content type: {type(content)}")
135
+ log_debug(f"Content length: {len(content) if content else 0}")
136
+
137
+ # Create documents
138
+ documents = []
139
+ if self.chunk and content:
140
+ documents.extend(self.chunk_document(Document(name=name or url, id=url, content=content)))
141
+ else:
142
+ documents.append(Document(name=name or url, id=url, content=content))
143
+ return documents
144
+
145
+ except Exception as e:
146
+ logger.error(f"Error extracting content from {url}: {e}")
147
+ return [Document(name=name or url, id=url, content="")]
148
+
149
+ async def _async_extract(self, url: str, name: Optional[str] = None) -> List[Document]:
150
+ """
151
+ Internal async method to extract content from a URL.
152
+
153
+ Args:
154
+ url: The URL to extract content from
155
+ name: Optional name for the document
156
+
157
+ Returns:
158
+ A list of documents containing the extracted content
159
+ """
160
+ log_debug(f"Async extracting content from: {url}")
161
+
162
+ # Use asyncio.to_thread to run the synchronous extract in a thread
163
+ return await asyncio.to_thread(self._extract, url, name)
164
+
165
+ def read(self, url: str, name: Optional[str] = None) -> List[Document]:
166
+ """
167
+ Reads content from a URL using Tavily Extract API.
168
+
169
+ This is the public API method that users should call.
170
+
171
+ Args:
172
+ url: The URL to extract content from
173
+ name: Optional name for the document
174
+
175
+ Returns:
176
+ A list of documents containing the extracted content
177
+ """
178
+ return self._extract(url, name)
179
+
180
+ async def async_read(self, url: str, name: Optional[str] = None) -> List[Document]:
181
+ """
182
+ Asynchronously reads content from a URL using Tavily Extract API.
183
+
184
+ This is the public API method that users should call for async operations.
185
+
186
+ Args:
187
+ url: The URL to extract content from
188
+ name: Optional name for the document
189
+
190
+ Returns:
191
+ A list of documents containing the extracted content
192
+ """
193
+ return await self._async_extract(url, name)