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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (589) hide show
  1. agno/agent/__init__.py +19 -27
  2. agno/agent/agent.py +3143 -4170
  3. agno/api/agent.py +11 -67
  4. agno/api/api.py +5 -46
  5. agno/api/evals.py +8 -19
  6. agno/api/os.py +17 -0
  7. agno/api/routes.py +6 -41
  8. agno/api/schemas/__init__.py +9 -0
  9. agno/api/schemas/agent.py +5 -21
  10. agno/api/schemas/evals.py +7 -16
  11. agno/api/schemas/os.py +14 -0
  12. agno/api/schemas/team.py +5 -21
  13. agno/api/schemas/utils.py +21 -0
  14. agno/api/schemas/workflows.py +11 -7
  15. agno/api/settings.py +53 -0
  16. agno/api/team.py +11 -66
  17. agno/api/workflow.py +28 -0
  18. agno/cloud/aws/base.py +214 -0
  19. agno/cloud/aws/s3/__init__.py +2 -0
  20. agno/cloud/aws/s3/api_client.py +43 -0
  21. agno/cloud/aws/s3/bucket.py +195 -0
  22. agno/cloud/aws/s3/object.py +57 -0
  23. agno/db/__init__.py +24 -0
  24. agno/db/base.py +245 -0
  25. agno/db/dynamo/__init__.py +3 -0
  26. agno/db/dynamo/dynamo.py +1743 -0
  27. agno/db/dynamo/schemas.py +278 -0
  28. agno/db/dynamo/utils.py +684 -0
  29. agno/db/firestore/__init__.py +3 -0
  30. agno/db/firestore/firestore.py +1432 -0
  31. agno/db/firestore/schemas.py +130 -0
  32. agno/db/firestore/utils.py +278 -0
  33. agno/db/gcs_json/__init__.py +3 -0
  34. agno/db/gcs_json/gcs_json_db.py +1001 -0
  35. agno/db/gcs_json/utils.py +194 -0
  36. agno/db/in_memory/__init__.py +3 -0
  37. agno/db/in_memory/in_memory_db.py +882 -0
  38. agno/db/in_memory/utils.py +172 -0
  39. agno/db/json/__init__.py +3 -0
  40. agno/db/json/json_db.py +1045 -0
  41. agno/db/json/utils.py +196 -0
  42. agno/db/migrations/v1_to_v2.py +162 -0
  43. agno/db/mongo/__init__.py +3 -0
  44. agno/db/mongo/mongo.py +1416 -0
  45. agno/db/mongo/schemas.py +77 -0
  46. agno/db/mongo/utils.py +204 -0
  47. agno/db/mysql/__init__.py +3 -0
  48. agno/db/mysql/mysql.py +1719 -0
  49. agno/db/mysql/schemas.py +124 -0
  50. agno/db/mysql/utils.py +297 -0
  51. agno/db/postgres/__init__.py +3 -0
  52. agno/db/postgres/postgres.py +1710 -0
  53. agno/db/postgres/schemas.py +124 -0
  54. agno/db/postgres/utils.py +280 -0
  55. agno/db/redis/__init__.py +3 -0
  56. agno/db/redis/redis.py +1367 -0
  57. agno/db/redis/schemas.py +109 -0
  58. agno/db/redis/utils.py +288 -0
  59. agno/db/schemas/__init__.py +3 -0
  60. agno/db/schemas/evals.py +33 -0
  61. agno/db/schemas/knowledge.py +40 -0
  62. agno/db/schemas/memory.py +46 -0
  63. agno/db/singlestore/__init__.py +3 -0
  64. agno/db/singlestore/schemas.py +116 -0
  65. agno/db/singlestore/singlestore.py +1712 -0
  66. agno/db/singlestore/utils.py +326 -0
  67. agno/db/sqlite/__init__.py +3 -0
  68. agno/db/sqlite/schemas.py +119 -0
  69. agno/db/sqlite/sqlite.py +1676 -0
  70. agno/db/sqlite/utils.py +268 -0
  71. agno/db/utils.py +88 -0
  72. agno/eval/__init__.py +14 -0
  73. agno/eval/accuracy.py +154 -48
  74. agno/eval/performance.py +88 -23
  75. agno/eval/reliability.py +73 -20
  76. agno/eval/utils.py +23 -13
  77. agno/integrations/discord/__init__.py +3 -0
  78. agno/{app → integrations}/discord/client.py +10 -10
  79. agno/knowledge/__init__.py +2 -2
  80. agno/{document → knowledge}/chunking/agentic.py +2 -2
  81. agno/{document → knowledge}/chunking/document.py +2 -2
  82. agno/{document → knowledge}/chunking/fixed.py +3 -3
  83. agno/{document → knowledge}/chunking/markdown.py +2 -2
  84. agno/{document → knowledge}/chunking/recursive.py +2 -2
  85. agno/{document → knowledge}/chunking/row.py +2 -2
  86. agno/knowledge/chunking/semantic.py +59 -0
  87. agno/knowledge/chunking/strategy.py +121 -0
  88. agno/knowledge/content.py +74 -0
  89. agno/knowledge/document/__init__.py +5 -0
  90. agno/{document → knowledge/document}/base.py +12 -2
  91. agno/knowledge/embedder/__init__.py +5 -0
  92. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  93. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  94. agno/{embedder → knowledge/embedder}/base.py +6 -0
  95. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  96. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  97. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  98. agno/{embedder → knowledge/embedder}/google.py +74 -1
  99. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  100. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  101. agno/knowledge/embedder/langdb.py +22 -0
  102. agno/knowledge/embedder/mistral.py +139 -0
  103. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  104. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  105. agno/knowledge/embedder/openai.py +223 -0
  106. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  107. agno/{embedder → knowledge/embedder}/together.py +1 -1
  108. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  109. agno/knowledge/knowledge.py +1551 -0
  110. agno/knowledge/reader/__init__.py +7 -0
  111. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  112. agno/knowledge/reader/base.py +88 -0
  113. agno/{document → knowledge}/reader/csv_reader.py +47 -65
  114. agno/knowledge/reader/docx_reader.py +83 -0
  115. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  116. agno/{document → knowledge}/reader/json_reader.py +30 -9
  117. agno/{document → knowledge}/reader/markdown_reader.py +58 -9
  118. agno/{document → knowledge}/reader/pdf_reader.py +71 -126
  119. agno/knowledge/reader/reader_factory.py +268 -0
  120. agno/knowledge/reader/s3_reader.py +101 -0
  121. agno/{document → knowledge}/reader/text_reader.py +31 -10
  122. agno/knowledge/reader/url_reader.py +128 -0
  123. agno/knowledge/reader/web_search_reader.py +366 -0
  124. agno/{document → knowledge}/reader/website_reader.py +37 -10
  125. agno/knowledge/reader/wikipedia_reader.py +59 -0
  126. agno/knowledge/reader/youtube_reader.py +78 -0
  127. agno/knowledge/remote_content/remote_content.py +88 -0
  128. agno/{reranker → knowledge/reranker}/base.py +1 -1
  129. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  130. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  131. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  132. agno/knowledge/types.py +30 -0
  133. agno/knowledge/utils.py +169 -0
  134. agno/media.py +269 -268
  135. agno/memory/__init__.py +2 -10
  136. agno/memory/manager.py +1003 -148
  137. agno/models/aimlapi/__init__.py +2 -2
  138. agno/models/aimlapi/aimlapi.py +6 -6
  139. agno/models/anthropic/claude.py +128 -72
  140. agno/models/aws/bedrock.py +107 -175
  141. agno/models/aws/claude.py +64 -18
  142. agno/models/azure/ai_foundry.py +73 -23
  143. agno/models/base.py +346 -290
  144. agno/models/cerebras/cerebras.py +84 -27
  145. agno/models/cohere/chat.py +106 -98
  146. agno/models/google/gemini.py +105 -46
  147. agno/models/groq/groq.py +97 -35
  148. agno/models/huggingface/huggingface.py +92 -27
  149. agno/models/ibm/watsonx.py +72 -13
  150. agno/models/litellm/chat.py +85 -13
  151. agno/models/message.py +46 -151
  152. agno/models/meta/llama.py +85 -49
  153. agno/models/metrics.py +120 -0
  154. agno/models/mistral/mistral.py +90 -21
  155. agno/models/ollama/__init__.py +0 -2
  156. agno/models/ollama/chat.py +85 -47
  157. agno/models/openai/chat.py +154 -37
  158. agno/models/openai/responses.py +178 -105
  159. agno/models/perplexity/perplexity.py +26 -2
  160. agno/models/portkey/portkey.py +0 -7
  161. agno/models/response.py +15 -9
  162. agno/models/utils.py +20 -0
  163. agno/models/vercel/__init__.py +2 -2
  164. agno/models/vercel/v0.py +1 -1
  165. agno/models/vllm/__init__.py +2 -2
  166. agno/models/vllm/vllm.py +3 -3
  167. agno/models/xai/xai.py +10 -10
  168. agno/os/__init__.py +3 -0
  169. agno/os/app.py +497 -0
  170. agno/os/auth.py +47 -0
  171. agno/os/config.py +103 -0
  172. agno/os/interfaces/agui/__init__.py +3 -0
  173. agno/os/interfaces/agui/agui.py +31 -0
  174. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  175. agno/{app → os/interfaces}/agui/utils.py +65 -28
  176. agno/os/interfaces/base.py +21 -0
  177. agno/os/interfaces/slack/__init__.py +3 -0
  178. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  179. agno/os/interfaces/slack/slack.py +32 -0
  180. agno/os/interfaces/whatsapp/__init__.py +3 -0
  181. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  182. agno/os/interfaces/whatsapp/whatsapp.py +29 -0
  183. agno/os/mcp.py +235 -0
  184. agno/os/router.py +1400 -0
  185. agno/os/routers/__init__.py +3 -0
  186. agno/os/routers/evals/__init__.py +3 -0
  187. agno/os/routers/evals/evals.py +393 -0
  188. agno/os/routers/evals/schemas.py +142 -0
  189. agno/os/routers/evals/utils.py +161 -0
  190. agno/os/routers/knowledge/__init__.py +3 -0
  191. agno/os/routers/knowledge/knowledge.py +850 -0
  192. agno/os/routers/knowledge/schemas.py +118 -0
  193. agno/os/routers/memory/__init__.py +3 -0
  194. agno/os/routers/memory/memory.py +410 -0
  195. agno/os/routers/memory/schemas.py +58 -0
  196. agno/os/routers/metrics/__init__.py +3 -0
  197. agno/os/routers/metrics/metrics.py +178 -0
  198. agno/os/routers/metrics/schemas.py +47 -0
  199. agno/os/routers/session/__init__.py +3 -0
  200. agno/os/routers/session/session.py +536 -0
  201. agno/os/schema.py +945 -0
  202. agno/{app/playground → os}/settings.py +7 -15
  203. agno/os/utils.py +270 -0
  204. agno/reasoning/azure_ai_foundry.py +4 -4
  205. agno/reasoning/deepseek.py +4 -4
  206. agno/reasoning/default.py +6 -11
  207. agno/reasoning/groq.py +4 -4
  208. agno/reasoning/helpers.py +4 -6
  209. agno/reasoning/ollama.py +4 -4
  210. agno/reasoning/openai.py +4 -4
  211. agno/run/agent.py +633 -0
  212. agno/run/base.py +53 -77
  213. agno/run/cancel.py +81 -0
  214. agno/run/team.py +243 -96
  215. agno/run/workflow.py +550 -12
  216. agno/session/__init__.py +10 -0
  217. agno/session/agent.py +244 -0
  218. agno/session/summary.py +225 -0
  219. agno/session/team.py +262 -0
  220. agno/{storage/session/v2 → session}/workflow.py +47 -24
  221. agno/team/__init__.py +15 -16
  222. agno/team/team.py +3260 -4824
  223. agno/tools/agentql.py +14 -5
  224. agno/tools/airflow.py +9 -4
  225. agno/tools/api.py +7 -3
  226. agno/tools/apify.py +2 -46
  227. agno/tools/arxiv.py +8 -3
  228. agno/tools/aws_lambda.py +7 -5
  229. agno/tools/aws_ses.py +7 -1
  230. agno/tools/baidusearch.py +4 -1
  231. agno/tools/bitbucket.py +4 -4
  232. agno/tools/brandfetch.py +14 -11
  233. agno/tools/bravesearch.py +4 -1
  234. agno/tools/brightdata.py +43 -23
  235. agno/tools/browserbase.py +13 -4
  236. agno/tools/calcom.py +12 -10
  237. agno/tools/calculator.py +10 -27
  238. agno/tools/cartesia.py +20 -17
  239. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  240. agno/tools/confluence.py +8 -8
  241. agno/tools/crawl4ai.py +7 -1
  242. agno/tools/csv_toolkit.py +9 -8
  243. agno/tools/dalle.py +22 -12
  244. agno/tools/daytona.py +13 -16
  245. agno/tools/decorator.py +6 -3
  246. agno/tools/desi_vocal.py +17 -8
  247. agno/tools/discord.py +11 -8
  248. agno/tools/docker.py +30 -42
  249. agno/tools/duckdb.py +34 -53
  250. agno/tools/duckduckgo.py +8 -7
  251. agno/tools/e2b.py +62 -62
  252. agno/tools/eleven_labs.py +36 -29
  253. agno/tools/email.py +4 -1
  254. agno/tools/evm.py +7 -1
  255. agno/tools/exa.py +19 -14
  256. agno/tools/fal.py +30 -30
  257. agno/tools/file.py +9 -8
  258. agno/tools/financial_datasets.py +25 -44
  259. agno/tools/firecrawl.py +17 -18
  260. agno/tools/function.py +127 -18
  261. agno/tools/giphy.py +23 -11
  262. agno/tools/github.py +48 -126
  263. agno/tools/gmail.py +45 -61
  264. agno/tools/google_bigquery.py +7 -6
  265. agno/tools/google_maps.py +11 -26
  266. agno/tools/googlesearch.py +7 -2
  267. agno/tools/googlesheets.py +21 -17
  268. agno/tools/hackernews.py +9 -5
  269. agno/tools/jina.py +5 -4
  270. agno/tools/jira.py +18 -9
  271. agno/tools/knowledge.py +31 -32
  272. agno/tools/linear.py +18 -33
  273. agno/tools/linkup.py +5 -1
  274. agno/tools/local_file_system.py +8 -5
  275. agno/tools/lumalab.py +32 -20
  276. agno/tools/mcp.py +1 -2
  277. agno/tools/mem0.py +18 -12
  278. agno/tools/memori.py +14 -10
  279. agno/tools/mlx_transcribe.py +3 -2
  280. agno/tools/models/azure_openai.py +33 -15
  281. agno/tools/models/gemini.py +59 -32
  282. agno/tools/models/groq.py +30 -23
  283. agno/tools/models/nebius.py +28 -12
  284. agno/tools/models_labs.py +40 -16
  285. agno/tools/moviepy_video.py +7 -6
  286. agno/tools/neo4j.py +10 -8
  287. agno/tools/newspaper.py +7 -2
  288. agno/tools/newspaper4k.py +8 -3
  289. agno/tools/openai.py +58 -32
  290. agno/tools/openbb.py +12 -11
  291. agno/tools/opencv.py +63 -47
  292. agno/tools/openweather.py +14 -12
  293. agno/tools/pandas.py +11 -3
  294. agno/tools/postgres.py +4 -12
  295. agno/tools/pubmed.py +4 -1
  296. agno/tools/python.py +9 -22
  297. agno/tools/reasoning.py +35 -27
  298. agno/tools/reddit.py +11 -26
  299. agno/tools/replicate.py +55 -42
  300. agno/tools/resend.py +4 -1
  301. agno/tools/scrapegraph.py +15 -14
  302. agno/tools/searxng.py +10 -23
  303. agno/tools/serpapi.py +6 -3
  304. agno/tools/serper.py +13 -4
  305. agno/tools/shell.py +9 -2
  306. agno/tools/slack.py +12 -11
  307. agno/tools/sleep.py +3 -2
  308. agno/tools/spider.py +24 -4
  309. agno/tools/sql.py +7 -6
  310. agno/tools/tavily.py +6 -4
  311. agno/tools/telegram.py +12 -4
  312. agno/tools/todoist.py +11 -31
  313. agno/tools/toolkit.py +1 -1
  314. agno/tools/trafilatura.py +22 -6
  315. agno/tools/trello.py +9 -22
  316. agno/tools/twilio.py +10 -3
  317. agno/tools/user_control_flow.py +6 -1
  318. agno/tools/valyu.py +34 -5
  319. agno/tools/visualization.py +19 -28
  320. agno/tools/webbrowser.py +4 -3
  321. agno/tools/webex.py +11 -7
  322. agno/tools/website.py +15 -46
  323. agno/tools/webtools.py +12 -4
  324. agno/tools/whatsapp.py +5 -9
  325. agno/tools/wikipedia.py +20 -13
  326. agno/tools/x.py +14 -13
  327. agno/tools/yfinance.py +13 -40
  328. agno/tools/youtube.py +26 -20
  329. agno/tools/zendesk.py +7 -2
  330. agno/tools/zep.py +10 -7
  331. agno/tools/zoom.py +10 -9
  332. agno/utils/common.py +1 -19
  333. agno/utils/events.py +100 -123
  334. agno/utils/gemini.py +1 -1
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/log.py +54 -4
  337. agno/utils/mcp.py +68 -10
  338. agno/utils/media.py +39 -0
  339. agno/utils/message.py +12 -1
  340. agno/utils/models/aws_claude.py +1 -1
  341. agno/utils/models/claude.py +6 -12
  342. agno/utils/models/cohere.py +1 -1
  343. agno/utils/models/mistral.py +8 -7
  344. agno/utils/models/schema_utils.py +3 -3
  345. agno/utils/models/watsonx.py +1 -1
  346. agno/utils/openai.py +1 -1
  347. agno/utils/pprint.py +33 -32
  348. agno/utils/print_response/agent.py +779 -0
  349. agno/utils/print_response/team.py +1669 -0
  350. agno/utils/print_response/workflow.py +1451 -0
  351. agno/utils/prompts.py +14 -14
  352. agno/utils/reasoning.py +87 -0
  353. agno/utils/response.py +42 -42
  354. agno/utils/streamlit.py +481 -0
  355. agno/utils/string.py +8 -22
  356. agno/utils/team.py +50 -0
  357. agno/utils/timer.py +2 -2
  358. agno/vectordb/base.py +33 -21
  359. agno/vectordb/cassandra/cassandra.py +287 -23
  360. agno/vectordb/chroma/chromadb.py +482 -59
  361. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  362. agno/vectordb/couchbase/couchbase.py +309 -29
  363. agno/vectordb/lancedb/lance_db.py +360 -21
  364. agno/vectordb/langchaindb/__init__.py +5 -0
  365. agno/vectordb/langchaindb/langchaindb.py +145 -0
  366. agno/vectordb/lightrag/__init__.py +5 -0
  367. agno/vectordb/lightrag/lightrag.py +374 -0
  368. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  369. agno/vectordb/milvus/milvus.py +242 -32
  370. agno/vectordb/mongodb/mongodb.py +200 -24
  371. agno/vectordb/pgvector/pgvector.py +319 -37
  372. agno/vectordb/pineconedb/pineconedb.py +221 -27
  373. agno/vectordb/qdrant/qdrant.py +334 -14
  374. agno/vectordb/singlestore/singlestore.py +286 -29
  375. agno/vectordb/surrealdb/surrealdb.py +187 -7
  376. agno/vectordb/upstashdb/upstashdb.py +342 -26
  377. agno/vectordb/weaviate/weaviate.py +227 -165
  378. agno/workflow/__init__.py +17 -13
  379. agno/workflow/{v2/condition.py → condition.py} +135 -32
  380. agno/workflow/{v2/loop.py → loop.py} +115 -28
  381. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  382. agno/workflow/{v2/router.py → router.py} +133 -32
  383. agno/workflow/{v2/step.py → step.py} +207 -49
  384. agno/workflow/{v2/steps.py → steps.py} +147 -66
  385. agno/workflow/types.py +482 -0
  386. agno/workflow/workflow.py +2410 -696
  387. agno-2.0.0.dist-info/METADATA +494 -0
  388. agno-2.0.0.dist-info/RECORD +515 -0
  389. agno-2.0.0.dist-info/licenses/LICENSE +201 -0
  390. agno/agent/metrics.py +0 -110
  391. agno/api/app.py +0 -35
  392. agno/api/playground.py +0 -92
  393. agno/api/schemas/app.py +0 -12
  394. agno/api/schemas/playground.py +0 -22
  395. agno/api/schemas/user.py +0 -35
  396. agno/api/schemas/workspace.py +0 -46
  397. agno/api/user.py +0 -160
  398. agno/api/workflows.py +0 -33
  399. agno/api/workspace.py +0 -175
  400. agno/app/agui/__init__.py +0 -3
  401. agno/app/agui/app.py +0 -17
  402. agno/app/agui/sync_router.py +0 -120
  403. agno/app/base.py +0 -186
  404. agno/app/discord/__init__.py +0 -3
  405. agno/app/fastapi/__init__.py +0 -3
  406. agno/app/fastapi/app.py +0 -107
  407. agno/app/fastapi/async_router.py +0 -457
  408. agno/app/fastapi/sync_router.py +0 -448
  409. agno/app/playground/app.py +0 -228
  410. agno/app/playground/async_router.py +0 -1053
  411. agno/app/playground/deploy.py +0 -249
  412. agno/app/playground/operator.py +0 -183
  413. agno/app/playground/schemas.py +0 -223
  414. agno/app/playground/serve.py +0 -55
  415. agno/app/playground/sync_router.py +0 -1045
  416. agno/app/playground/utils.py +0 -46
  417. agno/app/settings.py +0 -15
  418. agno/app/slack/__init__.py +0 -3
  419. agno/app/slack/app.py +0 -19
  420. agno/app/slack/sync_router.py +0 -92
  421. agno/app/utils.py +0 -54
  422. agno/app/whatsapp/__init__.py +0 -3
  423. agno/app/whatsapp/app.py +0 -15
  424. agno/app/whatsapp/sync_router.py +0 -197
  425. agno/cli/auth_server.py +0 -249
  426. agno/cli/config.py +0 -274
  427. agno/cli/console.py +0 -88
  428. agno/cli/credentials.py +0 -23
  429. agno/cli/entrypoint.py +0 -571
  430. agno/cli/operator.py +0 -357
  431. agno/cli/settings.py +0 -96
  432. agno/cli/ws/ws_cli.py +0 -817
  433. agno/constants.py +0 -13
  434. agno/document/__init__.py +0 -5
  435. agno/document/chunking/semantic.py +0 -45
  436. agno/document/chunking/strategy.py +0 -31
  437. agno/document/reader/__init__.py +0 -5
  438. agno/document/reader/base.py +0 -47
  439. agno/document/reader/docx_reader.py +0 -60
  440. agno/document/reader/gcs/pdf_reader.py +0 -44
  441. agno/document/reader/s3/pdf_reader.py +0 -59
  442. agno/document/reader/s3/text_reader.py +0 -63
  443. agno/document/reader/url_reader.py +0 -59
  444. agno/document/reader/youtube_reader.py +0 -58
  445. agno/embedder/__init__.py +0 -5
  446. agno/embedder/langdb.py +0 -80
  447. agno/embedder/mistral.py +0 -82
  448. agno/embedder/openai.py +0 -78
  449. agno/file/__init__.py +0 -5
  450. agno/file/file.py +0 -16
  451. agno/file/local/csv.py +0 -32
  452. agno/file/local/txt.py +0 -19
  453. agno/infra/app.py +0 -240
  454. agno/infra/base.py +0 -144
  455. agno/infra/context.py +0 -20
  456. agno/infra/db_app.py +0 -52
  457. agno/infra/resource.py +0 -205
  458. agno/infra/resources.py +0 -55
  459. agno/knowledge/agent.py +0 -702
  460. agno/knowledge/arxiv.py +0 -33
  461. agno/knowledge/combined.py +0 -36
  462. agno/knowledge/csv.py +0 -144
  463. agno/knowledge/csv_url.py +0 -124
  464. agno/knowledge/document.py +0 -223
  465. agno/knowledge/docx.py +0 -137
  466. agno/knowledge/firecrawl.py +0 -34
  467. agno/knowledge/gcs/__init__.py +0 -0
  468. agno/knowledge/gcs/base.py +0 -39
  469. agno/knowledge/gcs/pdf.py +0 -125
  470. agno/knowledge/json.py +0 -137
  471. agno/knowledge/langchain.py +0 -71
  472. agno/knowledge/light_rag.py +0 -273
  473. agno/knowledge/llamaindex.py +0 -66
  474. agno/knowledge/markdown.py +0 -154
  475. agno/knowledge/pdf.py +0 -164
  476. agno/knowledge/pdf_bytes.py +0 -42
  477. agno/knowledge/pdf_url.py +0 -148
  478. agno/knowledge/s3/__init__.py +0 -0
  479. agno/knowledge/s3/base.py +0 -64
  480. agno/knowledge/s3/pdf.py +0 -33
  481. agno/knowledge/s3/text.py +0 -34
  482. agno/knowledge/text.py +0 -141
  483. agno/knowledge/url.py +0 -46
  484. agno/knowledge/website.py +0 -179
  485. agno/knowledge/wikipedia.py +0 -32
  486. agno/knowledge/youtube.py +0 -35
  487. agno/memory/agent.py +0 -423
  488. agno/memory/classifier.py +0 -104
  489. agno/memory/db/__init__.py +0 -5
  490. agno/memory/db/base.py +0 -42
  491. agno/memory/db/mongodb.py +0 -189
  492. agno/memory/db/postgres.py +0 -203
  493. agno/memory/db/sqlite.py +0 -193
  494. agno/memory/memory.py +0 -22
  495. agno/memory/row.py +0 -36
  496. agno/memory/summarizer.py +0 -201
  497. agno/memory/summary.py +0 -19
  498. agno/memory/team.py +0 -415
  499. agno/memory/v2/__init__.py +0 -2
  500. agno/memory/v2/db/__init__.py +0 -1
  501. agno/memory/v2/db/base.py +0 -42
  502. agno/memory/v2/db/firestore.py +0 -339
  503. agno/memory/v2/db/mongodb.py +0 -196
  504. agno/memory/v2/db/postgres.py +0 -214
  505. agno/memory/v2/db/redis.py +0 -187
  506. agno/memory/v2/db/schema.py +0 -54
  507. agno/memory/v2/db/sqlite.py +0 -209
  508. agno/memory/v2/manager.py +0 -437
  509. agno/memory/v2/memory.py +0 -1097
  510. agno/memory/v2/schema.py +0 -55
  511. agno/memory/v2/summarizer.py +0 -215
  512. agno/memory/workflow.py +0 -38
  513. agno/models/ollama/tools.py +0 -430
  514. agno/models/qwen/__init__.py +0 -5
  515. agno/playground/__init__.py +0 -10
  516. agno/playground/deploy.py +0 -3
  517. agno/playground/playground.py +0 -3
  518. agno/playground/serve.py +0 -3
  519. agno/playground/settings.py +0 -3
  520. agno/reranker/__init__.py +0 -0
  521. agno/run/response.py +0 -467
  522. agno/run/v2/__init__.py +0 -0
  523. agno/run/v2/workflow.py +0 -567
  524. agno/storage/__init__.py +0 -0
  525. agno/storage/agent/__init__.py +0 -0
  526. agno/storage/agent/dynamodb.py +0 -1
  527. agno/storage/agent/json.py +0 -1
  528. agno/storage/agent/mongodb.py +0 -1
  529. agno/storage/agent/postgres.py +0 -1
  530. agno/storage/agent/singlestore.py +0 -1
  531. agno/storage/agent/sqlite.py +0 -1
  532. agno/storage/agent/yaml.py +0 -1
  533. agno/storage/base.py +0 -60
  534. agno/storage/dynamodb.py +0 -673
  535. agno/storage/firestore.py +0 -297
  536. agno/storage/gcs_json.py +0 -261
  537. agno/storage/in_memory.py +0 -234
  538. agno/storage/json.py +0 -237
  539. agno/storage/mongodb.py +0 -328
  540. agno/storage/mysql.py +0 -685
  541. agno/storage/postgres.py +0 -682
  542. agno/storage/redis.py +0 -336
  543. agno/storage/session/__init__.py +0 -16
  544. agno/storage/session/agent.py +0 -64
  545. agno/storage/session/team.py +0 -63
  546. agno/storage/session/v2/__init__.py +0 -5
  547. agno/storage/session/workflow.py +0 -61
  548. agno/storage/singlestore.py +0 -606
  549. agno/storage/sqlite.py +0 -646
  550. agno/storage/workflow/__init__.py +0 -0
  551. agno/storage/workflow/mongodb.py +0 -1
  552. agno/storage/workflow/postgres.py +0 -1
  553. agno/storage/workflow/sqlite.py +0 -1
  554. agno/storage/yaml.py +0 -241
  555. agno/tools/thinking.py +0 -73
  556. agno/utils/defaults.py +0 -57
  557. agno/utils/filesystem.py +0 -39
  558. agno/utils/git.py +0 -52
  559. agno/utils/json_io.py +0 -30
  560. agno/utils/load_env.py +0 -19
  561. agno/utils/py_io.py +0 -19
  562. agno/utils/pyproject.py +0 -18
  563. agno/utils/resource_filter.py +0 -31
  564. agno/workflow/v2/__init__.py +0 -21
  565. agno/workflow/v2/types.py +0 -357
  566. agno/workflow/v2/workflow.py +0 -3313
  567. agno/workspace/__init__.py +0 -0
  568. agno/workspace/config.py +0 -325
  569. agno/workspace/enums.py +0 -6
  570. agno/workspace/helpers.py +0 -52
  571. agno/workspace/operator.py +0 -757
  572. agno/workspace/settings.py +0 -158
  573. agno-1.8.2.dist-info/METADATA +0 -982
  574. agno-1.8.2.dist-info/RECORD +0 -566
  575. agno-1.8.2.dist-info/entry_points.txt +0 -3
  576. agno-1.8.2.dist-info/licenses/LICENSE +0 -375
  577. /agno/{app → db/migrations}/__init__.py +0 -0
  578. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  579. /agno/{cli → integrations}/__init__.py +0 -0
  580. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  581. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  582. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  583. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  584. /agno/{app → os/interfaces}/slack/security.py +0 -0
  585. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  586. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  587. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  588. {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
  589. {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,22 @@
1
+ from dataclasses import dataclass
2
+ from os import getenv
3
+ from typing import Optional
4
+
5
+ from agno.knowledge.embedder.openai import OpenAIEmbedder
6
+
7
+
8
+ @dataclass
9
+ class LangDBEmbedder(OpenAIEmbedder):
10
+ id: str = "text-embedding-ada-002"
11
+ dimensions: int = 1536
12
+ api_key: Optional[str] = getenv("LANGDB_API_KEY")
13
+ project_id: Optional[str] = getenv("LANGDB_PROJECT_ID")
14
+ base_url: Optional[str] = None
15
+
16
+ def __post_init__(self):
17
+ """Set the base_url based on project_id if not provided."""
18
+ if not self.project_id:
19
+ raise ValueError("LANGDB_PROJECT_ID not set in the environment")
20
+
21
+ if not self.base_url:
22
+ self.base_url = f"https://api.us-east-1.langdb.ai/{self.project_id}/v1"
@@ -0,0 +1,139 @@
1
+ from dataclasses import dataclass
2
+ from os import getenv
3
+ from typing import Any, Dict, List, Optional, Tuple
4
+
5
+ from agno.knowledge.embedder.base import Embedder
6
+ from agno.utils.log import logger
7
+
8
+ try:
9
+ from mistralai import Mistral # type: ignore
10
+ from mistralai.models.embeddingresponse import EmbeddingResponse # type: ignore
11
+ except ImportError:
12
+ logger.error("`mistralai` not installed")
13
+ raise
14
+
15
+
16
+ @dataclass
17
+ class MistralEmbedder(Embedder):
18
+ id: str = "mistral-embed"
19
+ dimensions: int = 1024
20
+ # -*- Request parameters
21
+ request_params: Optional[Dict[str, Any]] = None
22
+ # -*- Client parameters
23
+ api_key: Optional[str] = getenv("MISTRAL_API_KEY")
24
+ endpoint: Optional[str] = None
25
+ max_retries: Optional[int] = None
26
+ timeout: Optional[int] = None
27
+ client_params: Optional[Dict[str, Any]] = None
28
+ # -*- Provide the Mistral Client manually
29
+ mistral_client: Optional[Mistral] = None
30
+
31
+ @property
32
+ def client(self) -> Mistral:
33
+ if self.mistral_client:
34
+ return self.mistral_client
35
+
36
+ _client_params: Dict[str, Any] = {
37
+ "api_key": self.api_key,
38
+ "endpoint": self.endpoint,
39
+ "max_retries": self.max_retries,
40
+ "timeout": self.timeout,
41
+ }
42
+ _client_params = {k: v for k, v in _client_params.items() if v is not None}
43
+
44
+ if self.client_params:
45
+ _client_params.update(self.client_params)
46
+
47
+ self.mistral_client = Mistral(**_client_params)
48
+
49
+ return self.mistral_client
50
+
51
+ def _response(self, text: str) -> EmbeddingResponse:
52
+ _request_params: Dict[str, Any] = {
53
+ "inputs": text,
54
+ "model": self.id,
55
+ }
56
+ if self.request_params:
57
+ _request_params.update(self.request_params)
58
+ response = self.client.embeddings.create(**_request_params)
59
+ if response is None:
60
+ raise ValueError("Failed to get embedding response")
61
+ return response
62
+
63
+ def get_embedding(self, text: str) -> List[float]:
64
+ try:
65
+ response: EmbeddingResponse = self._response(text=text)
66
+ if response.data and response.data[0].embedding:
67
+ return response.data[0].embedding
68
+ return []
69
+ except Exception as e:
70
+ logger.warning(f"Error getting embedding: {e}")
71
+ return []
72
+
73
+ def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Dict[str, Any]]:
74
+ try:
75
+ response: EmbeddingResponse = self._response(text=text)
76
+ embedding: List[float] = (
77
+ response.data[0].embedding if (response.data and response.data[0].embedding) else []
78
+ )
79
+ usage: Dict[str, Any] = response.usage.model_dump() if response.usage else {}
80
+ return embedding, usage
81
+ except Exception as e:
82
+ logger.warning(f"Error getting embedding and usage: {e}")
83
+ return [], {}
84
+
85
+ async def async_get_embedding(self, text: str) -> List[float]:
86
+ """Async version of get_embedding."""
87
+ try:
88
+ # Check if the client has an async version of embeddings.create
89
+ if hasattr(self.client.embeddings, "create_async"):
90
+ response: EmbeddingResponse = await self.client.embeddings.create_async(
91
+ inputs=text, model=self.id, **self.request_params if self.request_params else {}
92
+ )
93
+ else:
94
+ # Fallback to running sync method in thread executor
95
+ import asyncio
96
+
97
+ loop = asyncio.get_running_loop()
98
+ response: EmbeddingResponse = await loop.run_in_executor( # type: ignore
99
+ None,
100
+ lambda: self.client.embeddings.create(
101
+ inputs=text, model=self.id, **self.request_params if self.request_params else {}
102
+ ),
103
+ )
104
+
105
+ if response.data and response.data[0].embedding:
106
+ return response.data[0].embedding
107
+ return []
108
+ except Exception as e:
109
+ logger.warning(f"Error getting embedding: {e}")
110
+ return []
111
+
112
+ async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Dict[str, Any]]:
113
+ """Async version of get_embedding_and_usage."""
114
+ try:
115
+ # Check if the client has an async version of embeddings.create
116
+ if hasattr(self.client.embeddings, "create_async"):
117
+ response: EmbeddingResponse = await self.client.embeddings.create_async(
118
+ inputs=text, model=self.id, **self.request_params if self.request_params else {}
119
+ )
120
+ else:
121
+ # Fallback to running sync method in thread executor
122
+ import asyncio
123
+
124
+ loop = asyncio.get_running_loop()
125
+ response: EmbeddingResponse = await loop.run_in_executor( # type: ignore
126
+ None,
127
+ lambda: self.client.embeddings.create(
128
+ inputs=text, model=self.id, **self.request_params if self.request_params else {}
129
+ ),
130
+ )
131
+
132
+ embedding: List[float] = (
133
+ response.data[0].embedding if (response.data and response.data[0].embedding) else []
134
+ )
135
+ usage: Dict[str, Any] = response.usage.model_dump() if response.usage else {}
136
+ return embedding, usage
137
+ except Exception as e:
138
+ logger.warning(f"Error getting embedding and usage: {e}")
139
+ return [], {}
@@ -2,7 +2,7 @@ from dataclasses import dataclass
2
2
  from os import getenv
3
3
  from typing import Optional
4
4
 
5
- from agno.embedder.openai import OpenAIEmbedder
5
+ from agno.knowledge.embedder.openai import OpenAIEmbedder
6
6
 
7
7
 
8
8
  @dataclass
@@ -1,12 +1,13 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Any, Dict, List, Optional, Tuple
3
3
 
4
- from agno.embedder.base import Embedder
5
- from agno.utils.log import logger
4
+ from agno.knowledge.embedder.base import Embedder
5
+ from agno.utils.log import log_error, logger
6
6
 
7
7
  try:
8
8
  import importlib.metadata as metadata
9
9
 
10
+ from ollama import AsyncClient as AsyncOllamaClient
10
11
  from ollama import Client as OllamaClient
11
12
  from packaging import version
12
13
 
@@ -30,7 +31,7 @@ except ImportError as e:
30
31
 
31
32
  except Exception as e:
32
33
  # Catch-all for unexpected errors
33
- print(f"An unexpected error occurred: {e}")
34
+ log_error(f"An unexpected error occurred: {e}")
34
35
 
35
36
 
36
37
  @dataclass
@@ -42,6 +43,7 @@ class OllamaEmbedder(Embedder):
42
43
  options: Optional[Any] = None
43
44
  client_kwargs: Optional[Dict[str, Any]] = None
44
45
  ollama_client: Optional[OllamaClient] = None
46
+ async_client: Optional[AsyncOllamaClient] = None
45
47
 
46
48
  @property
47
49
  def client(self) -> OllamaClient:
@@ -58,6 +60,21 @@ class OllamaEmbedder(Embedder):
58
60
  self.ollama_client = OllamaClient(**_ollama_params)
59
61
  return self.ollama_client
60
62
 
63
+ @property
64
+ def aclient(self) -> AsyncOllamaClient:
65
+ if self.async_client:
66
+ return self.async_client
67
+
68
+ _ollama_params: Dict[str, Any] = {
69
+ "host": self.host,
70
+ "timeout": self.timeout,
71
+ }
72
+ _ollama_params = {k: v for k, v in _ollama_params.items() if v is not None}
73
+ if self.client_kwargs:
74
+ _ollama_params.update(self.client_kwargs)
75
+ self.async_client = AsyncOllamaClient(**_ollama_params)
76
+ return self.async_client
77
+
61
78
  def _response(self, text: str) -> Dict[str, Any]:
62
79
  kwargs: Dict[str, Any] = {}
63
80
  if self.options is not None:
@@ -88,3 +105,37 @@ class OllamaEmbedder(Embedder):
88
105
  embedding = self.get_embedding(text=text)
89
106
  usage = None
90
107
  return embedding, usage
108
+
109
+ async def _async_response(self, text: str) -> Dict[str, Any]:
110
+ """Async version of _response using AsyncOllamaClient."""
111
+ kwargs: Dict[str, Any] = {}
112
+ if self.options is not None:
113
+ kwargs["options"] = self.options
114
+
115
+ response = await self.aclient.embed(input=text, model=self.id, **kwargs)
116
+ if response and "embeddings" in response:
117
+ embeddings = response["embeddings"]
118
+ if isinstance(embeddings, list) and len(embeddings) > 0 and isinstance(embeddings[0], list):
119
+ return {"embeddings": embeddings[0]} # Use the first element
120
+ elif isinstance(embeddings, list) and all(isinstance(x, (int, float)) for x in embeddings):
121
+ return {"embeddings": embeddings} # Return as-is if already flat
122
+ return {"embeddings": []} # Return an empty list if no valid embedding is found
123
+
124
+ async def async_get_embedding(self, text: str) -> List[float]:
125
+ """Async version of get_embedding."""
126
+ try:
127
+ response = await self._async_response(text=text)
128
+ embedding = response.get("embeddings", [])
129
+ if len(embedding) != self.dimensions:
130
+ logger.warning(f"Expected embedding dimension {self.dimensions}, but got {len(embedding)}")
131
+ return []
132
+ return embedding
133
+ except Exception as e:
134
+ logger.warning(f"Error getting embedding: {e}")
135
+ return []
136
+
137
+ async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
138
+ """Async version of get_embedding_and_usage."""
139
+ embedding = await self.async_get_embedding(text=text)
140
+ usage = None
141
+ return embedding, usage
@@ -0,0 +1,223 @@
1
+ from dataclasses import dataclass
2
+ from typing import Any, Dict, List, Optional, Tuple
3
+
4
+ from typing_extensions import Literal
5
+
6
+ from agno.knowledge.embedder.base import Embedder
7
+ from agno.utils.log import logger
8
+
9
+ try:
10
+ from openai import AsyncOpenAI
11
+ from openai import OpenAI as OpenAIClient
12
+ from openai.types.create_embedding_response import CreateEmbeddingResponse
13
+ except ImportError:
14
+ raise ImportError("`openai` not installed")
15
+
16
+
17
+ @dataclass
18
+ class OpenAIEmbedder(Embedder):
19
+ id: str = "text-embedding-3-small"
20
+ dimensions: Optional[int] = None
21
+ encoding_format: Literal["float", "base64"] = "float"
22
+ user: Optional[str] = None
23
+ api_key: Optional[str] = None
24
+ organization: Optional[str] = None
25
+ base_url: Optional[str] = None
26
+ request_params: Optional[Dict[str, Any]] = None
27
+ client_params: Optional[Dict[str, Any]] = None
28
+ openai_client: Optional[OpenAIClient] = None
29
+ async_client: Optional[AsyncOpenAI] = None
30
+
31
+ def __post_init__(self):
32
+ if self.dimensions is None:
33
+ self.dimensions = 3072 if self.id == "text-embedding-3-large" else 1536
34
+
35
+ @property
36
+ def client(self) -> OpenAIClient:
37
+ if self.openai_client:
38
+ return self.openai_client
39
+
40
+ _client_params: Dict[str, Any] = {
41
+ "api_key": self.api_key,
42
+ "organization": self.organization,
43
+ "base_url": self.base_url,
44
+ }
45
+ _client_params = {k: v for k, v in _client_params.items() if v is not None}
46
+ if self.client_params:
47
+ _client_params.update(self.client_params)
48
+ self.openai_client = OpenAIClient(**_client_params)
49
+ return self.openai_client
50
+
51
+ @property
52
+ def aclient(self) -> AsyncOpenAI:
53
+ if self.async_client:
54
+ return self.async_client
55
+ params = {
56
+ "api_key": self.api_key,
57
+ "organization": self.organization,
58
+ "base_url": self.base_url,
59
+ }
60
+ filtered_params: Dict[str, Any] = {k: v for k, v in params.items() if v is not None}
61
+ if self.client_params:
62
+ filtered_params.update(self.client_params)
63
+ self.async_client = AsyncOpenAI(**filtered_params)
64
+ return self.async_client
65
+
66
+ def response(self, text: str) -> CreateEmbeddingResponse:
67
+ _request_params: Dict[str, Any] = {
68
+ "input": text,
69
+ "model": self.id,
70
+ "encoding_format": self.encoding_format,
71
+ }
72
+ if self.user is not None:
73
+ _request_params["user"] = self.user
74
+ if self.id.startswith("text-embedding-3"):
75
+ _request_params["dimensions"] = self.dimensions
76
+ if self.request_params:
77
+ _request_params.update(self.request_params)
78
+ return self.client.embeddings.create(**_request_params)
79
+
80
+ def get_embedding(self, text: str) -> List[float]:
81
+ response: CreateEmbeddingResponse = self.response(text=text)
82
+ try:
83
+ return response.data[0].embedding
84
+ except Exception as e:
85
+ logger.warning(e)
86
+ return []
87
+
88
+ def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
89
+ response: CreateEmbeddingResponse = self.response(text=text)
90
+
91
+ embedding = response.data[0].embedding
92
+ usage = response.usage
93
+ if usage:
94
+ return embedding, usage.model_dump()
95
+ return embedding, None
96
+
97
+ async def async_get_embedding(self, text: str) -> List[float]:
98
+ req: Dict[str, Any] = {
99
+ "input": text,
100
+ "model": self.id,
101
+ "encoding_format": self.encoding_format,
102
+ }
103
+ if self.user is not None:
104
+ req["user"] = self.user
105
+ if self.id.startswith("text-embedding-3"):
106
+ req["dimensions"] = self.dimensions
107
+ if self.request_params:
108
+ req.update(self.request_params)
109
+
110
+ try:
111
+ response: CreateEmbeddingResponse = await self.aclient.embeddings.create(**req)
112
+ return response.data[0].embedding
113
+ except Exception as e:
114
+ logger.warning(e)
115
+ return []
116
+
117
+ async def async_get_embedding_and_usage(self, text: str):
118
+ req: Dict[str, Any] = {
119
+ "input": text,
120
+ "model": self.id,
121
+ "encoding_format": self.encoding_format,
122
+ }
123
+ if self.user is not None:
124
+ req["user"] = self.user
125
+ if self.id.startswith("text-embedding-3"):
126
+ req["dimensions"] = self.dimensions
127
+ if self.request_params:
128
+ req.update(self.request_params)
129
+
130
+ response = await self.aclient.embeddings.create(**req)
131
+ embedding = response.data[0].embedding
132
+ usage = response.usage
133
+ return embedding, usage.model_dump() if usage else None
134
+
135
+ def get_embeddings_batch(self, texts: List[str], batch_size: int = 100) -> List[List[float]]:
136
+ """
137
+ Get embeddings for multiple texts in batches.
138
+
139
+ Args:
140
+ texts: List of text strings to embed
141
+ batch_size: Number of texts to process in each API call (max ~2048)
142
+
143
+ Returns:
144
+ List of embedding vectors
145
+ """
146
+ all_embeddings = []
147
+
148
+ for i in range(0, len(texts), batch_size):
149
+ batch_texts = texts[i : i + batch_size]
150
+
151
+ req: Dict[str, Any] = {
152
+ "input": batch_texts,
153
+ "model": self.id,
154
+ "encoding_format": self.encoding_format,
155
+ }
156
+ if self.user is not None:
157
+ req["user"] = self.user
158
+ if self.id.startswith("text-embedding-3"):
159
+ req["dimensions"] = self.dimensions
160
+ if self.request_params:
161
+ req.update(self.request_params)
162
+
163
+ try:
164
+ response: CreateEmbeddingResponse = self.client.embeddings.create(**req)
165
+ batch_embeddings = [data.embedding for data in response.data]
166
+ all_embeddings.extend(batch_embeddings)
167
+ except Exception as e:
168
+ logger.warning(f"Error in batch embedding: {e}")
169
+ # Fallback to individual calls for this batch
170
+ for text in batch_texts:
171
+ try:
172
+ embedding = self.get_embedding(text)
173
+ all_embeddings.append(embedding)
174
+ except Exception as e2:
175
+ logger.warning(f"Error in individual embedding fallback: {e2}")
176
+ all_embeddings.append([])
177
+
178
+ return all_embeddings
179
+
180
+ async def async_get_embeddings_batch(self, texts: List[str], batch_size: int = 100) -> List[List[float]]:
181
+ """
182
+ Get embeddings for multiple texts in batches (async version).
183
+
184
+ Args:
185
+ texts: List of text strings to embed
186
+ batch_size: Number of texts to process in each API call (max ~2048)
187
+
188
+ Returns:
189
+ List of embedding vectors
190
+ """
191
+ all_embeddings = []
192
+
193
+ for i in range(0, len(texts), batch_size):
194
+ batch_texts = texts[i : i + batch_size]
195
+
196
+ req: Dict[str, Any] = {
197
+ "input": batch_texts,
198
+ "model": self.id,
199
+ "encoding_format": self.encoding_format,
200
+ }
201
+ if self.user is not None:
202
+ req["user"] = self.user
203
+ if self.id.startswith("text-embedding-3"):
204
+ req["dimensions"] = self.dimensions
205
+ if self.request_params:
206
+ req.update(self.request_params)
207
+
208
+ try:
209
+ response: CreateEmbeddingResponse = await self.aclient.embeddings.create(**req)
210
+ batch_embeddings = [data.embedding for data in response.data]
211
+ all_embeddings.extend(batch_embeddings)
212
+ except Exception as e:
213
+ logger.warning(f"Error in async batch embedding: {e}")
214
+ # Fallback to individual async calls for this batch
215
+ for text in batch_texts:
216
+ try:
217
+ embedding = await self.async_get_embedding(text)
218
+ all_embeddings.append(embedding)
219
+ except Exception as e2:
220
+ logger.warning(f"Error in individual async embedding fallback: {e2}")
221
+ all_embeddings.append([])
222
+
223
+ return all_embeddings
@@ -1,7 +1,7 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Dict, List, Optional, Tuple, Union
3
3
 
4
- from agno.embedder.base import Embedder
4
+ from agno.knowledge.embedder.base import Embedder
5
5
  from agno.utils.log import logger
6
6
 
7
7
  try:
@@ -42,3 +42,18 @@ class SentenceTransformerEmbedder(Embedder):
42
42
 
43
43
  def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
44
44
  return self.get_embedding(text=text), None
45
+
46
+ async def async_get_embedding(self, text: Union[str, List[str]]) -> List[float]:
47
+ """Async version using thread executor for CPU-bound operations."""
48
+ import asyncio
49
+
50
+ loop = asyncio.get_event_loop()
51
+ # Run the CPU-bound operation in a thread executor
52
+ return await loop.run_in_executor(None, self.get_embedding, text)
53
+
54
+ async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
55
+ """Async version using thread executor for CPU-bound operations."""
56
+ import asyncio
57
+
58
+ loop = asyncio.get_event_loop()
59
+ return await loop.run_in_executor(None, self.get_embedding_and_usage, text)
@@ -2,7 +2,7 @@ from dataclasses import dataclass
2
2
  from os import getenv
3
3
  from typing import Optional
4
4
 
5
- from agno.embedder.openai import OpenAIEmbedder
5
+ from agno.knowledge.embedder.openai import OpenAIEmbedder
6
6
 
7
7
 
8
8
  @dataclass
@@ -1,10 +1,11 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Any, Dict, List, Optional, Tuple
3
3
 
4
- from agno.embedder.base import Embedder
4
+ from agno.knowledge.embedder.base import Embedder
5
5
  from agno.utils.log import logger
6
6
 
7
7
  try:
8
+ from voyageai import AsyncClient as AsyncVoyageClient
8
9
  from voyageai import Client as VoyageClient
9
10
  from voyageai.object import EmbeddingsObject
10
11
  except ImportError:
@@ -22,6 +23,7 @@ class VoyageAIEmbedder(Embedder):
22
23
  timeout: Optional[float] = None
23
24
  client_params: Optional[Dict[str, Any]] = None
24
25
  voyage_client: Optional[VoyageClient] = None
26
+ async_client: Optional[AsyncVoyageClient] = None
25
27
 
26
28
  @property
27
29
  def client(self) -> VoyageClient:
@@ -39,6 +41,22 @@ class VoyageAIEmbedder(Embedder):
39
41
  self.voyage_client = VoyageClient(**_client_params)
40
42
  return self.voyage_client
41
43
 
44
+ @property
45
+ def aclient(self) -> AsyncVoyageClient:
46
+ if self.async_client:
47
+ return self.async_client
48
+
49
+ _client_params = {
50
+ "api_key": self.api_key,
51
+ "max_retries": self.max_retries,
52
+ "timeout": self.timeout,
53
+ }
54
+ _client_params = {k: v for k, v in _client_params.items() if v is not None}
55
+ if self.client_params:
56
+ _client_params.update(self.client_params)
57
+ self.async_client = AsyncVoyageClient(**_client_params)
58
+ return self.async_client
59
+
42
60
  def _response(self, text: str) -> EmbeddingsObject:
43
61
  _request_params: Dict[str, Any] = {
44
62
  "texts": [text],
@@ -62,3 +80,33 @@ class VoyageAIEmbedder(Embedder):
62
80
  embedding = response.embeddings[0]
63
81
  usage = {"total_tokens": response.total_tokens}
64
82
  return embedding, usage
83
+
84
+ async def _async_response(self, text: str) -> EmbeddingsObject:
85
+ """Async version of _response using AsyncVoyageClient."""
86
+ _request_params: Dict[str, Any] = {
87
+ "texts": [text],
88
+ "model": self.id,
89
+ }
90
+ if self.request_params:
91
+ _request_params.update(self.request_params)
92
+ return await self.aclient.embed(**_request_params)
93
+
94
+ async def async_get_embedding(self, text: str) -> List[float]:
95
+ """Async version of get_embedding."""
96
+ try:
97
+ response: EmbeddingsObject = await self._async_response(text=text)
98
+ return response.embeddings[0]
99
+ except Exception as e:
100
+ logger.warning(f"Error getting embedding: {e}")
101
+ return []
102
+
103
+ async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
104
+ """Async version of get_embedding_and_usage."""
105
+ try:
106
+ response: EmbeddingsObject = await self._async_response(text=text)
107
+ embedding = response.embeddings[0]
108
+ usage = {"total_tokens": response.total_tokens}
109
+ return embedding, usage
110
+ except Exception as e:
111
+ logger.warning(f"Error getting embedding and usage: {e}")
112
+ return [], None