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

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