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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (723) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +44 -5
  3. agno/agent/agent.py +10531 -2975
  4. agno/api/agent.py +14 -53
  5. agno/api/api.py +7 -46
  6. agno/api/evals.py +22 -0
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -25
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +6 -9
  11. agno/api/schemas/evals.py +16 -0
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +10 -10
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +16 -0
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +22 -26
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/compression/__init__.py +3 -0
  25. agno/compression/manager.py +247 -0
  26. agno/culture/__init__.py +3 -0
  27. agno/culture/manager.py +956 -0
  28. agno/db/__init__.py +24 -0
  29. agno/db/async_postgres/__init__.py +3 -0
  30. agno/db/base.py +946 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2781 -0
  33. agno/db/dynamo/schemas.py +442 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +2379 -0
  37. agno/db/firestore/schemas.py +181 -0
  38. agno/db/firestore/utils.py +376 -0
  39. agno/db/gcs_json/__init__.py +3 -0
  40. agno/db/gcs_json/gcs_json_db.py +1791 -0
  41. agno/db/gcs_json/utils.py +228 -0
  42. agno/db/in_memory/__init__.py +3 -0
  43. agno/db/in_memory/in_memory_db.py +1312 -0
  44. agno/db/in_memory/utils.py +230 -0
  45. agno/db/json/__init__.py +3 -0
  46. agno/db/json/json_db.py +1777 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/manager.py +199 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/migrations/versions/v2_3_0.py +938 -0
  51. agno/db/mongo/__init__.py +17 -0
  52. agno/db/mongo/async_mongo.py +2760 -0
  53. agno/db/mongo/mongo.py +2597 -0
  54. agno/db/mongo/schemas.py +119 -0
  55. agno/db/mongo/utils.py +276 -0
  56. agno/db/mysql/__init__.py +4 -0
  57. agno/db/mysql/async_mysql.py +2912 -0
  58. agno/db/mysql/mysql.py +2923 -0
  59. agno/db/mysql/schemas.py +186 -0
  60. agno/db/mysql/utils.py +488 -0
  61. agno/db/postgres/__init__.py +4 -0
  62. agno/db/postgres/async_postgres.py +2579 -0
  63. agno/db/postgres/postgres.py +2870 -0
  64. agno/db/postgres/schemas.py +187 -0
  65. agno/db/postgres/utils.py +442 -0
  66. agno/db/redis/__init__.py +3 -0
  67. agno/db/redis/redis.py +2141 -0
  68. agno/db/redis/schemas.py +159 -0
  69. agno/db/redis/utils.py +346 -0
  70. agno/db/schemas/__init__.py +4 -0
  71. agno/db/schemas/culture.py +120 -0
  72. agno/db/schemas/evals.py +34 -0
  73. agno/db/schemas/knowledge.py +40 -0
  74. agno/db/schemas/memory.py +61 -0
  75. agno/db/singlestore/__init__.py +3 -0
  76. agno/db/singlestore/schemas.py +179 -0
  77. agno/db/singlestore/singlestore.py +2877 -0
  78. agno/db/singlestore/utils.py +384 -0
  79. agno/db/sqlite/__init__.py +4 -0
  80. agno/db/sqlite/async_sqlite.py +2911 -0
  81. agno/db/sqlite/schemas.py +181 -0
  82. agno/db/sqlite/sqlite.py +2908 -0
  83. agno/db/sqlite/utils.py +429 -0
  84. agno/db/surrealdb/__init__.py +3 -0
  85. agno/db/surrealdb/metrics.py +292 -0
  86. agno/db/surrealdb/models.py +334 -0
  87. agno/db/surrealdb/queries.py +71 -0
  88. agno/db/surrealdb/surrealdb.py +1908 -0
  89. agno/db/surrealdb/utils.py +147 -0
  90. agno/db/utils.py +118 -0
  91. agno/eval/__init__.py +24 -0
  92. agno/eval/accuracy.py +666 -276
  93. agno/eval/agent_as_judge.py +861 -0
  94. agno/eval/base.py +29 -0
  95. agno/eval/performance.py +779 -0
  96. agno/eval/reliability.py +241 -62
  97. agno/eval/utils.py +120 -0
  98. agno/exceptions.py +143 -1
  99. agno/filters.py +354 -0
  100. agno/guardrails/__init__.py +6 -0
  101. agno/guardrails/base.py +19 -0
  102. agno/guardrails/openai.py +144 -0
  103. agno/guardrails/pii.py +94 -0
  104. agno/guardrails/prompt_injection.py +52 -0
  105. agno/hooks/__init__.py +3 -0
  106. agno/hooks/decorator.py +164 -0
  107. agno/integrations/discord/__init__.py +3 -0
  108. agno/integrations/discord/client.py +203 -0
  109. agno/knowledge/__init__.py +5 -1
  110. agno/{document → knowledge}/chunking/agentic.py +22 -14
  111. agno/{document → knowledge}/chunking/document.py +2 -2
  112. agno/{document → knowledge}/chunking/fixed.py +7 -6
  113. agno/knowledge/chunking/markdown.py +151 -0
  114. agno/{document → knowledge}/chunking/recursive.py +15 -3
  115. agno/knowledge/chunking/row.py +39 -0
  116. agno/knowledge/chunking/semantic.py +91 -0
  117. agno/knowledge/chunking/strategy.py +165 -0
  118. agno/knowledge/content.py +74 -0
  119. agno/knowledge/document/__init__.py +5 -0
  120. agno/{document → knowledge/document}/base.py +12 -2
  121. agno/knowledge/embedder/__init__.py +5 -0
  122. agno/knowledge/embedder/aws_bedrock.py +343 -0
  123. agno/knowledge/embedder/azure_openai.py +210 -0
  124. agno/{embedder → knowledge/embedder}/base.py +8 -0
  125. agno/knowledge/embedder/cohere.py +323 -0
  126. agno/knowledge/embedder/fastembed.py +62 -0
  127. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  128. agno/knowledge/embedder/google.py +258 -0
  129. agno/knowledge/embedder/huggingface.py +94 -0
  130. agno/knowledge/embedder/jina.py +182 -0
  131. agno/knowledge/embedder/langdb.py +22 -0
  132. agno/knowledge/embedder/mistral.py +206 -0
  133. agno/knowledge/embedder/nebius.py +13 -0
  134. agno/knowledge/embedder/ollama.py +154 -0
  135. agno/knowledge/embedder/openai.py +195 -0
  136. agno/knowledge/embedder/sentence_transformer.py +63 -0
  137. agno/{embedder → knowledge/embedder}/together.py +1 -1
  138. agno/knowledge/embedder/vllm.py +262 -0
  139. agno/knowledge/embedder/voyageai.py +165 -0
  140. agno/knowledge/knowledge.py +3006 -0
  141. agno/knowledge/reader/__init__.py +7 -0
  142. agno/knowledge/reader/arxiv_reader.py +81 -0
  143. agno/knowledge/reader/base.py +95 -0
  144. agno/knowledge/reader/csv_reader.py +164 -0
  145. agno/knowledge/reader/docx_reader.py +82 -0
  146. agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
  147. agno/knowledge/reader/firecrawl_reader.py +201 -0
  148. agno/knowledge/reader/json_reader.py +88 -0
  149. agno/knowledge/reader/markdown_reader.py +137 -0
  150. agno/knowledge/reader/pdf_reader.py +431 -0
  151. agno/knowledge/reader/pptx_reader.py +101 -0
  152. agno/knowledge/reader/reader_factory.py +313 -0
  153. agno/knowledge/reader/s3_reader.py +89 -0
  154. agno/knowledge/reader/tavily_reader.py +193 -0
  155. agno/knowledge/reader/text_reader.py +127 -0
  156. agno/knowledge/reader/web_search_reader.py +325 -0
  157. agno/knowledge/reader/website_reader.py +455 -0
  158. agno/knowledge/reader/wikipedia_reader.py +91 -0
  159. agno/knowledge/reader/youtube_reader.py +78 -0
  160. agno/knowledge/remote_content/remote_content.py +88 -0
  161. agno/knowledge/reranker/__init__.py +3 -0
  162. agno/{reranker → knowledge/reranker}/base.py +1 -1
  163. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  164. agno/knowledge/reranker/infinity.py +195 -0
  165. agno/knowledge/reranker/sentence_transformer.py +54 -0
  166. agno/knowledge/types.py +39 -0
  167. agno/knowledge/utils.py +234 -0
  168. agno/media.py +439 -95
  169. agno/memory/__init__.py +16 -3
  170. agno/memory/manager.py +1474 -123
  171. agno/memory/strategies/__init__.py +15 -0
  172. agno/memory/strategies/base.py +66 -0
  173. agno/memory/strategies/summarize.py +196 -0
  174. agno/memory/strategies/types.py +37 -0
  175. agno/models/aimlapi/__init__.py +5 -0
  176. agno/models/aimlapi/aimlapi.py +62 -0
  177. agno/models/anthropic/__init__.py +4 -0
  178. agno/models/anthropic/claude.py +960 -496
  179. agno/models/aws/__init__.py +15 -0
  180. agno/models/aws/bedrock.py +686 -451
  181. agno/models/aws/claude.py +190 -183
  182. agno/models/azure/__init__.py +18 -1
  183. agno/models/azure/ai_foundry.py +489 -0
  184. agno/models/azure/openai_chat.py +89 -40
  185. agno/models/base.py +2477 -550
  186. agno/models/cerebras/__init__.py +12 -0
  187. agno/models/cerebras/cerebras.py +565 -0
  188. agno/models/cerebras/cerebras_openai.py +131 -0
  189. agno/models/cohere/__init__.py +4 -0
  190. agno/models/cohere/chat.py +306 -492
  191. agno/models/cometapi/__init__.py +5 -0
  192. agno/models/cometapi/cometapi.py +74 -0
  193. agno/models/dashscope/__init__.py +5 -0
  194. agno/models/dashscope/dashscope.py +90 -0
  195. agno/models/deepinfra/__init__.py +5 -0
  196. agno/models/deepinfra/deepinfra.py +45 -0
  197. agno/models/deepseek/__init__.py +4 -0
  198. agno/models/deepseek/deepseek.py +110 -9
  199. agno/models/fireworks/__init__.py +4 -0
  200. agno/models/fireworks/fireworks.py +19 -22
  201. agno/models/google/__init__.py +3 -7
  202. agno/models/google/gemini.py +1717 -662
  203. agno/models/google/utils.py +22 -0
  204. agno/models/groq/__init__.py +4 -0
  205. agno/models/groq/groq.py +391 -666
  206. agno/models/huggingface/__init__.py +4 -0
  207. agno/models/huggingface/huggingface.py +266 -538
  208. agno/models/ibm/__init__.py +5 -0
  209. agno/models/ibm/watsonx.py +432 -0
  210. agno/models/internlm/__init__.py +3 -0
  211. agno/models/internlm/internlm.py +20 -3
  212. agno/models/langdb/__init__.py +1 -0
  213. agno/models/langdb/langdb.py +60 -0
  214. agno/models/litellm/__init__.py +14 -0
  215. agno/models/litellm/chat.py +503 -0
  216. agno/models/litellm/litellm_openai.py +42 -0
  217. agno/models/llama_cpp/__init__.py +5 -0
  218. agno/models/llama_cpp/llama_cpp.py +22 -0
  219. agno/models/lmstudio/__init__.py +5 -0
  220. agno/models/lmstudio/lmstudio.py +25 -0
  221. agno/models/message.py +361 -39
  222. agno/models/meta/__init__.py +12 -0
  223. agno/models/meta/llama.py +502 -0
  224. agno/models/meta/llama_openai.py +79 -0
  225. agno/models/metrics.py +120 -0
  226. agno/models/mistral/__init__.py +4 -0
  227. agno/models/mistral/mistral.py +293 -393
  228. agno/models/nebius/__init__.py +3 -0
  229. agno/models/nebius/nebius.py +53 -0
  230. agno/models/nexus/__init__.py +3 -0
  231. agno/models/nexus/nexus.py +22 -0
  232. agno/models/nvidia/__init__.py +4 -0
  233. agno/models/nvidia/nvidia.py +22 -3
  234. agno/models/ollama/__init__.py +4 -2
  235. agno/models/ollama/chat.py +257 -492
  236. agno/models/openai/__init__.py +7 -0
  237. agno/models/openai/chat.py +725 -770
  238. agno/models/openai/like.py +16 -2
  239. agno/models/openai/responses.py +1121 -0
  240. agno/models/openrouter/__init__.py +4 -0
  241. agno/models/openrouter/openrouter.py +62 -5
  242. agno/models/perplexity/__init__.py +5 -0
  243. agno/models/perplexity/perplexity.py +203 -0
  244. agno/models/portkey/__init__.py +3 -0
  245. agno/models/portkey/portkey.py +82 -0
  246. agno/models/requesty/__init__.py +5 -0
  247. agno/models/requesty/requesty.py +69 -0
  248. agno/models/response.py +177 -7
  249. agno/models/sambanova/__init__.py +4 -0
  250. agno/models/sambanova/sambanova.py +23 -4
  251. agno/models/siliconflow/__init__.py +5 -0
  252. agno/models/siliconflow/siliconflow.py +42 -0
  253. agno/models/together/__init__.py +4 -0
  254. agno/models/together/together.py +21 -164
  255. agno/models/utils.py +266 -0
  256. agno/models/vercel/__init__.py +3 -0
  257. agno/models/vercel/v0.py +43 -0
  258. agno/models/vertexai/__init__.py +0 -1
  259. agno/models/vertexai/claude.py +190 -0
  260. agno/models/vllm/__init__.py +3 -0
  261. agno/models/vllm/vllm.py +83 -0
  262. agno/models/xai/__init__.py +2 -0
  263. agno/models/xai/xai.py +111 -7
  264. agno/os/__init__.py +3 -0
  265. agno/os/app.py +1027 -0
  266. agno/os/auth.py +244 -0
  267. agno/os/config.py +126 -0
  268. agno/os/interfaces/__init__.py +1 -0
  269. agno/os/interfaces/a2a/__init__.py +3 -0
  270. agno/os/interfaces/a2a/a2a.py +42 -0
  271. agno/os/interfaces/a2a/router.py +249 -0
  272. agno/os/interfaces/a2a/utils.py +924 -0
  273. agno/os/interfaces/agui/__init__.py +3 -0
  274. agno/os/interfaces/agui/agui.py +47 -0
  275. agno/os/interfaces/agui/router.py +147 -0
  276. agno/os/interfaces/agui/utils.py +574 -0
  277. agno/os/interfaces/base.py +25 -0
  278. agno/os/interfaces/slack/__init__.py +3 -0
  279. agno/os/interfaces/slack/router.py +148 -0
  280. agno/os/interfaces/slack/security.py +30 -0
  281. agno/os/interfaces/slack/slack.py +47 -0
  282. agno/os/interfaces/whatsapp/__init__.py +3 -0
  283. agno/os/interfaces/whatsapp/router.py +210 -0
  284. agno/os/interfaces/whatsapp/security.py +55 -0
  285. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  286. agno/os/mcp.py +293 -0
  287. agno/os/middleware/__init__.py +9 -0
  288. agno/os/middleware/jwt.py +797 -0
  289. agno/os/router.py +258 -0
  290. agno/os/routers/__init__.py +3 -0
  291. agno/os/routers/agents/__init__.py +3 -0
  292. agno/os/routers/agents/router.py +599 -0
  293. agno/os/routers/agents/schema.py +261 -0
  294. agno/os/routers/evals/__init__.py +3 -0
  295. agno/os/routers/evals/evals.py +450 -0
  296. agno/os/routers/evals/schemas.py +174 -0
  297. agno/os/routers/evals/utils.py +231 -0
  298. agno/os/routers/health.py +31 -0
  299. agno/os/routers/home.py +52 -0
  300. agno/os/routers/knowledge/__init__.py +3 -0
  301. agno/os/routers/knowledge/knowledge.py +1008 -0
  302. agno/os/routers/knowledge/schemas.py +178 -0
  303. agno/os/routers/memory/__init__.py +3 -0
  304. agno/os/routers/memory/memory.py +661 -0
  305. agno/os/routers/memory/schemas.py +88 -0
  306. agno/os/routers/metrics/__init__.py +3 -0
  307. agno/os/routers/metrics/metrics.py +190 -0
  308. agno/os/routers/metrics/schemas.py +47 -0
  309. agno/os/routers/session/__init__.py +3 -0
  310. agno/os/routers/session/session.py +997 -0
  311. agno/os/routers/teams/__init__.py +3 -0
  312. agno/os/routers/teams/router.py +512 -0
  313. agno/os/routers/teams/schema.py +257 -0
  314. agno/os/routers/traces/__init__.py +3 -0
  315. agno/os/routers/traces/schemas.py +414 -0
  316. agno/os/routers/traces/traces.py +499 -0
  317. agno/os/routers/workflows/__init__.py +3 -0
  318. agno/os/routers/workflows/router.py +624 -0
  319. agno/os/routers/workflows/schema.py +75 -0
  320. agno/os/schema.py +534 -0
  321. agno/os/scopes.py +469 -0
  322. agno/{playground → os}/settings.py +7 -15
  323. agno/os/utils.py +973 -0
  324. agno/reasoning/anthropic.py +80 -0
  325. agno/reasoning/azure_ai_foundry.py +67 -0
  326. agno/reasoning/deepseek.py +63 -0
  327. agno/reasoning/default.py +97 -0
  328. agno/reasoning/gemini.py +73 -0
  329. agno/reasoning/groq.py +71 -0
  330. agno/reasoning/helpers.py +24 -1
  331. agno/reasoning/ollama.py +67 -0
  332. agno/reasoning/openai.py +86 -0
  333. agno/reasoning/step.py +2 -1
  334. agno/reasoning/vertexai.py +76 -0
  335. agno/run/__init__.py +6 -0
  336. agno/run/agent.py +822 -0
  337. agno/run/base.py +247 -0
  338. agno/run/cancel.py +81 -0
  339. agno/run/requirement.py +181 -0
  340. agno/run/team.py +767 -0
  341. agno/run/workflow.py +708 -0
  342. agno/session/__init__.py +10 -0
  343. agno/session/agent.py +260 -0
  344. agno/session/summary.py +265 -0
  345. agno/session/team.py +342 -0
  346. agno/session/workflow.py +501 -0
  347. agno/table.py +10 -0
  348. agno/team/__init__.py +37 -0
  349. agno/team/team.py +9536 -0
  350. agno/tools/__init__.py +7 -0
  351. agno/tools/agentql.py +120 -0
  352. agno/tools/airflow.py +22 -12
  353. agno/tools/api.py +122 -0
  354. agno/tools/apify.py +276 -83
  355. agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
  356. agno/tools/aws_lambda.py +28 -7
  357. agno/tools/aws_ses.py +66 -0
  358. agno/tools/baidusearch.py +11 -4
  359. agno/tools/bitbucket.py +292 -0
  360. agno/tools/brandfetch.py +213 -0
  361. agno/tools/bravesearch.py +106 -0
  362. agno/tools/brightdata.py +367 -0
  363. agno/tools/browserbase.py +209 -0
  364. agno/tools/calcom.py +32 -23
  365. agno/tools/calculator.py +24 -37
  366. agno/tools/cartesia.py +187 -0
  367. agno/tools/{clickup_tool.py → clickup.py} +17 -28
  368. agno/tools/confluence.py +91 -26
  369. agno/tools/crawl4ai.py +139 -43
  370. agno/tools/csv_toolkit.py +28 -22
  371. agno/tools/dalle.py +36 -22
  372. agno/tools/daytona.py +475 -0
  373. agno/tools/decorator.py +169 -14
  374. agno/tools/desi_vocal.py +23 -11
  375. agno/tools/discord.py +32 -29
  376. agno/tools/docker.py +716 -0
  377. agno/tools/duckdb.py +76 -81
  378. agno/tools/duckduckgo.py +43 -40
  379. agno/tools/e2b.py +703 -0
  380. agno/tools/eleven_labs.py +65 -54
  381. agno/tools/email.py +13 -5
  382. agno/tools/evm.py +129 -0
  383. agno/tools/exa.py +324 -42
  384. agno/tools/fal.py +39 -35
  385. agno/tools/file.py +196 -30
  386. agno/tools/file_generation.py +356 -0
  387. agno/tools/financial_datasets.py +288 -0
  388. agno/tools/firecrawl.py +108 -33
  389. agno/tools/function.py +960 -122
  390. agno/tools/giphy.py +34 -12
  391. agno/tools/github.py +1294 -97
  392. agno/tools/gmail.py +922 -0
  393. agno/tools/google_bigquery.py +117 -0
  394. agno/tools/google_drive.py +271 -0
  395. agno/tools/google_maps.py +253 -0
  396. agno/tools/googlecalendar.py +607 -107
  397. agno/tools/googlesheets.py +377 -0
  398. agno/tools/hackernews.py +20 -12
  399. agno/tools/jina.py +24 -14
  400. agno/tools/jira.py +48 -19
  401. agno/tools/knowledge.py +218 -0
  402. agno/tools/linear.py +82 -43
  403. agno/tools/linkup.py +58 -0
  404. agno/tools/local_file_system.py +15 -7
  405. agno/tools/lumalab.py +41 -26
  406. agno/tools/mcp/__init__.py +10 -0
  407. agno/tools/mcp/mcp.py +331 -0
  408. agno/tools/mcp/multi_mcp.py +347 -0
  409. agno/tools/mcp/params.py +24 -0
  410. agno/tools/mcp_toolbox.py +284 -0
  411. agno/tools/mem0.py +193 -0
  412. agno/tools/memory.py +419 -0
  413. agno/tools/mlx_transcribe.py +11 -9
  414. agno/tools/models/azure_openai.py +190 -0
  415. agno/tools/models/gemini.py +203 -0
  416. agno/tools/models/groq.py +158 -0
  417. agno/tools/models/morph.py +186 -0
  418. agno/tools/models/nebius.py +124 -0
  419. agno/tools/models_labs.py +163 -82
  420. agno/tools/moviepy_video.py +18 -13
  421. agno/tools/nano_banana.py +151 -0
  422. agno/tools/neo4j.py +134 -0
  423. agno/tools/newspaper.py +15 -4
  424. agno/tools/newspaper4k.py +19 -6
  425. agno/tools/notion.py +204 -0
  426. agno/tools/openai.py +181 -17
  427. agno/tools/openbb.py +27 -20
  428. agno/tools/opencv.py +321 -0
  429. agno/tools/openweather.py +233 -0
  430. agno/tools/oxylabs.py +385 -0
  431. agno/tools/pandas.py +25 -15
  432. agno/tools/parallel.py +314 -0
  433. agno/tools/postgres.py +238 -185
  434. agno/tools/pubmed.py +125 -13
  435. agno/tools/python.py +48 -35
  436. agno/tools/reasoning.py +283 -0
  437. agno/tools/reddit.py +207 -29
  438. agno/tools/redshift.py +406 -0
  439. agno/tools/replicate.py +69 -26
  440. agno/tools/resend.py +11 -6
  441. agno/tools/scrapegraph.py +179 -19
  442. agno/tools/searxng.py +23 -31
  443. agno/tools/serpapi.py +15 -10
  444. agno/tools/serper.py +255 -0
  445. agno/tools/shell.py +23 -12
  446. agno/tools/shopify.py +1519 -0
  447. agno/tools/slack.py +56 -14
  448. agno/tools/sleep.py +8 -6
  449. agno/tools/spider.py +35 -11
  450. agno/tools/spotify.py +919 -0
  451. agno/tools/sql.py +34 -19
  452. agno/tools/tavily.py +158 -8
  453. agno/tools/telegram.py +18 -8
  454. agno/tools/todoist.py +218 -0
  455. agno/tools/toolkit.py +134 -9
  456. agno/tools/trafilatura.py +388 -0
  457. agno/tools/trello.py +25 -28
  458. agno/tools/twilio.py +18 -9
  459. agno/tools/user_control_flow.py +78 -0
  460. agno/tools/valyu.py +228 -0
  461. agno/tools/visualization.py +467 -0
  462. agno/tools/webbrowser.py +28 -0
  463. agno/tools/webex.py +76 -0
  464. agno/tools/website.py +23 -19
  465. agno/tools/webtools.py +45 -0
  466. agno/tools/whatsapp.py +286 -0
  467. agno/tools/wikipedia.py +28 -19
  468. agno/tools/workflow.py +285 -0
  469. agno/tools/{twitter.py → x.py} +142 -46
  470. agno/tools/yfinance.py +41 -39
  471. agno/tools/youtube.py +34 -17
  472. agno/tools/zendesk.py +15 -5
  473. agno/tools/zep.py +454 -0
  474. agno/tools/zoom.py +86 -37
  475. agno/tracing/__init__.py +12 -0
  476. agno/tracing/exporter.py +157 -0
  477. agno/tracing/schemas.py +276 -0
  478. agno/tracing/setup.py +111 -0
  479. agno/utils/agent.py +938 -0
  480. agno/utils/audio.py +37 -1
  481. agno/utils/certs.py +27 -0
  482. agno/utils/code_execution.py +11 -0
  483. agno/utils/common.py +103 -20
  484. agno/utils/cryptography.py +22 -0
  485. agno/utils/dttm.py +33 -0
  486. agno/utils/events.py +700 -0
  487. agno/utils/functions.py +107 -37
  488. agno/utils/gemini.py +426 -0
  489. agno/utils/hooks.py +171 -0
  490. agno/utils/http.py +185 -0
  491. agno/utils/json_schema.py +159 -37
  492. agno/utils/knowledge.py +36 -0
  493. agno/utils/location.py +19 -0
  494. agno/utils/log.py +221 -8
  495. agno/utils/mcp.py +214 -0
  496. agno/utils/media.py +335 -14
  497. agno/utils/merge_dict.py +22 -1
  498. agno/utils/message.py +77 -2
  499. agno/utils/models/ai_foundry.py +50 -0
  500. agno/utils/models/claude.py +373 -0
  501. agno/utils/models/cohere.py +94 -0
  502. agno/utils/models/llama.py +85 -0
  503. agno/utils/models/mistral.py +100 -0
  504. agno/utils/models/openai_responses.py +140 -0
  505. agno/utils/models/schema_utils.py +153 -0
  506. agno/utils/models/watsonx.py +41 -0
  507. agno/utils/openai.py +257 -0
  508. agno/utils/pickle.py +1 -1
  509. agno/utils/pprint.py +124 -8
  510. agno/utils/print_response/agent.py +930 -0
  511. agno/utils/print_response/team.py +1914 -0
  512. agno/utils/print_response/workflow.py +1668 -0
  513. agno/utils/prompts.py +111 -0
  514. agno/utils/reasoning.py +108 -0
  515. agno/utils/response.py +163 -0
  516. agno/utils/serialize.py +32 -0
  517. agno/utils/shell.py +4 -4
  518. agno/utils/streamlit.py +487 -0
  519. agno/utils/string.py +204 -51
  520. agno/utils/team.py +139 -0
  521. agno/utils/timer.py +9 -2
  522. agno/utils/tokens.py +657 -0
  523. agno/utils/tools.py +19 -1
  524. agno/utils/whatsapp.py +305 -0
  525. agno/utils/yaml_io.py +3 -3
  526. agno/vectordb/__init__.py +2 -0
  527. agno/vectordb/base.py +87 -9
  528. agno/vectordb/cassandra/__init__.py +5 -1
  529. agno/vectordb/cassandra/cassandra.py +383 -27
  530. agno/vectordb/chroma/__init__.py +4 -0
  531. agno/vectordb/chroma/chromadb.py +748 -83
  532. agno/vectordb/clickhouse/__init__.py +7 -1
  533. agno/vectordb/clickhouse/clickhousedb.py +554 -53
  534. agno/vectordb/couchbase/__init__.py +3 -0
  535. agno/vectordb/couchbase/couchbase.py +1446 -0
  536. agno/vectordb/lancedb/__init__.py +5 -0
  537. agno/vectordb/lancedb/lance_db.py +730 -98
  538. agno/vectordb/langchaindb/__init__.py +5 -0
  539. agno/vectordb/langchaindb/langchaindb.py +163 -0
  540. agno/vectordb/lightrag/__init__.py +5 -0
  541. agno/vectordb/lightrag/lightrag.py +388 -0
  542. agno/vectordb/llamaindex/__init__.py +3 -0
  543. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  544. agno/vectordb/milvus/__init__.py +3 -0
  545. agno/vectordb/milvus/milvus.py +966 -78
  546. agno/vectordb/mongodb/__init__.py +9 -1
  547. agno/vectordb/mongodb/mongodb.py +1175 -172
  548. agno/vectordb/pgvector/__init__.py +8 -0
  549. agno/vectordb/pgvector/pgvector.py +599 -115
  550. agno/vectordb/pineconedb/__init__.py +5 -1
  551. agno/vectordb/pineconedb/pineconedb.py +406 -43
  552. agno/vectordb/qdrant/__init__.py +4 -0
  553. agno/vectordb/qdrant/qdrant.py +914 -61
  554. agno/vectordb/redis/__init__.py +9 -0
  555. agno/vectordb/redis/redisdb.py +682 -0
  556. agno/vectordb/singlestore/__init__.py +8 -1
  557. agno/vectordb/singlestore/singlestore.py +771 -0
  558. agno/vectordb/surrealdb/__init__.py +3 -0
  559. agno/vectordb/surrealdb/surrealdb.py +663 -0
  560. agno/vectordb/upstashdb/__init__.py +5 -0
  561. agno/vectordb/upstashdb/upstashdb.py +718 -0
  562. agno/vectordb/weaviate/__init__.py +8 -0
  563. agno/vectordb/weaviate/index.py +15 -0
  564. agno/vectordb/weaviate/weaviate.py +1009 -0
  565. agno/workflow/__init__.py +23 -1
  566. agno/workflow/agent.py +299 -0
  567. agno/workflow/condition.py +759 -0
  568. agno/workflow/loop.py +756 -0
  569. agno/workflow/parallel.py +853 -0
  570. agno/workflow/router.py +723 -0
  571. agno/workflow/step.py +1564 -0
  572. agno/workflow/steps.py +613 -0
  573. agno/workflow/types.py +556 -0
  574. agno/workflow/workflow.py +4327 -514
  575. agno-2.3.13.dist-info/METADATA +639 -0
  576. agno-2.3.13.dist-info/RECORD +613 -0
  577. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
  578. agno-2.3.13.dist-info/licenses/LICENSE +201 -0
  579. agno/api/playground.py +0 -91
  580. agno/api/schemas/playground.py +0 -22
  581. agno/api/schemas/user.py +0 -22
  582. agno/api/schemas/workspace.py +0 -46
  583. agno/api/user.py +0 -160
  584. agno/api/workspace.py +0 -151
  585. agno/cli/auth_server.py +0 -118
  586. agno/cli/config.py +0 -275
  587. agno/cli/console.py +0 -88
  588. agno/cli/credentials.py +0 -23
  589. agno/cli/entrypoint.py +0 -571
  590. agno/cli/operator.py +0 -355
  591. agno/cli/settings.py +0 -85
  592. agno/cli/ws/ws_cli.py +0 -817
  593. agno/constants.py +0 -13
  594. agno/document/__init__.py +0 -1
  595. agno/document/chunking/semantic.py +0 -47
  596. agno/document/chunking/strategy.py +0 -31
  597. agno/document/reader/__init__.py +0 -1
  598. agno/document/reader/arxiv_reader.py +0 -41
  599. agno/document/reader/base.py +0 -22
  600. agno/document/reader/csv_reader.py +0 -84
  601. agno/document/reader/docx_reader.py +0 -46
  602. agno/document/reader/firecrawl_reader.py +0 -99
  603. agno/document/reader/json_reader.py +0 -43
  604. agno/document/reader/pdf_reader.py +0 -219
  605. agno/document/reader/s3/pdf_reader.py +0 -46
  606. agno/document/reader/s3/text_reader.py +0 -51
  607. agno/document/reader/text_reader.py +0 -41
  608. agno/document/reader/website_reader.py +0 -175
  609. agno/document/reader/youtube_reader.py +0 -50
  610. agno/embedder/__init__.py +0 -1
  611. agno/embedder/azure_openai.py +0 -86
  612. agno/embedder/cohere.py +0 -72
  613. agno/embedder/fastembed.py +0 -37
  614. agno/embedder/google.py +0 -73
  615. agno/embedder/huggingface.py +0 -54
  616. agno/embedder/mistral.py +0 -80
  617. agno/embedder/ollama.py +0 -57
  618. agno/embedder/openai.py +0 -74
  619. agno/embedder/sentence_transformer.py +0 -38
  620. agno/embedder/voyageai.py +0 -64
  621. agno/eval/perf.py +0 -201
  622. agno/file/__init__.py +0 -1
  623. agno/file/file.py +0 -16
  624. agno/file/local/csv.py +0 -32
  625. agno/file/local/txt.py +0 -19
  626. agno/infra/app.py +0 -240
  627. agno/infra/base.py +0 -144
  628. agno/infra/context.py +0 -20
  629. agno/infra/db_app.py +0 -52
  630. agno/infra/resource.py +0 -205
  631. agno/infra/resources.py +0 -55
  632. agno/knowledge/agent.py +0 -230
  633. agno/knowledge/arxiv.py +0 -22
  634. agno/knowledge/combined.py +0 -22
  635. agno/knowledge/csv.py +0 -28
  636. agno/knowledge/csv_url.py +0 -19
  637. agno/knowledge/document.py +0 -20
  638. agno/knowledge/docx.py +0 -30
  639. agno/knowledge/json.py +0 -28
  640. agno/knowledge/langchain.py +0 -71
  641. agno/knowledge/llamaindex.py +0 -66
  642. agno/knowledge/pdf.py +0 -28
  643. agno/knowledge/pdf_url.py +0 -26
  644. agno/knowledge/s3/base.py +0 -60
  645. agno/knowledge/s3/pdf.py +0 -21
  646. agno/knowledge/s3/text.py +0 -23
  647. agno/knowledge/text.py +0 -30
  648. agno/knowledge/website.py +0 -88
  649. agno/knowledge/wikipedia.py +0 -31
  650. agno/knowledge/youtube.py +0 -22
  651. agno/memory/agent.py +0 -392
  652. agno/memory/classifier.py +0 -104
  653. agno/memory/db/__init__.py +0 -1
  654. agno/memory/db/base.py +0 -42
  655. agno/memory/db/mongodb.py +0 -189
  656. agno/memory/db/postgres.py +0 -203
  657. agno/memory/db/sqlite.py +0 -193
  658. agno/memory/memory.py +0 -15
  659. agno/memory/row.py +0 -36
  660. agno/memory/summarizer.py +0 -192
  661. agno/memory/summary.py +0 -19
  662. agno/memory/workflow.py +0 -38
  663. agno/models/google/gemini_openai.py +0 -26
  664. agno/models/ollama/hermes.py +0 -221
  665. agno/models/ollama/tools.py +0 -362
  666. agno/models/vertexai/gemini.py +0 -595
  667. agno/playground/__init__.py +0 -3
  668. agno/playground/async_router.py +0 -421
  669. agno/playground/deploy.py +0 -249
  670. agno/playground/operator.py +0 -92
  671. agno/playground/playground.py +0 -91
  672. agno/playground/schemas.py +0 -76
  673. agno/playground/serve.py +0 -55
  674. agno/playground/sync_router.py +0 -405
  675. agno/reasoning/agent.py +0 -68
  676. agno/run/response.py +0 -112
  677. agno/storage/agent/__init__.py +0 -0
  678. agno/storage/agent/base.py +0 -38
  679. agno/storage/agent/dynamodb.py +0 -350
  680. agno/storage/agent/json.py +0 -92
  681. agno/storage/agent/mongodb.py +0 -228
  682. agno/storage/agent/postgres.py +0 -367
  683. agno/storage/agent/session.py +0 -79
  684. agno/storage/agent/singlestore.py +0 -303
  685. agno/storage/agent/sqlite.py +0 -357
  686. agno/storage/agent/yaml.py +0 -93
  687. agno/storage/workflow/__init__.py +0 -0
  688. agno/storage/workflow/base.py +0 -40
  689. agno/storage/workflow/mongodb.py +0 -233
  690. agno/storage/workflow/postgres.py +0 -366
  691. agno/storage/workflow/session.py +0 -60
  692. agno/storage/workflow/sqlite.py +0 -359
  693. agno/tools/googlesearch.py +0 -88
  694. agno/utils/defaults.py +0 -57
  695. agno/utils/filesystem.py +0 -39
  696. agno/utils/git.py +0 -52
  697. agno/utils/json_io.py +0 -30
  698. agno/utils/load_env.py +0 -19
  699. agno/utils/py_io.py +0 -19
  700. agno/utils/pyproject.py +0 -18
  701. agno/utils/resource_filter.py +0 -31
  702. agno/vectordb/singlestore/s2vectordb.py +0 -390
  703. agno/vectordb/singlestore/s2vectordb2.py +0 -355
  704. agno/workspace/__init__.py +0 -0
  705. agno/workspace/config.py +0 -325
  706. agno/workspace/enums.py +0 -6
  707. agno/workspace/helpers.py +0 -48
  708. agno/workspace/operator.py +0 -758
  709. agno/workspace/settings.py +0 -63
  710. agno-0.1.2.dist-info/LICENSE +0 -375
  711. agno-0.1.2.dist-info/METADATA +0 -502
  712. agno-0.1.2.dist-info/RECORD +0 -352
  713. agno-0.1.2.dist-info/entry_points.txt +0 -3
  714. /agno/{cli → db/migrations}/__init__.py +0 -0
  715. /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
  716. /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
  717. /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
  718. /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
  719. /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
  720. /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
  721. /agno/{reranker → utils/models}/__init__.py +0 -0
  722. /agno/{storage → utils/print_response}/__init__.py +0 -0
  723. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,94 @@
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 log_error, log_warning
7
+
8
+ try:
9
+ from huggingface_hub import AsyncInferenceClient, InferenceClient
10
+ except ImportError:
11
+ log_error("`huggingface-hub` not installed, please run `pip install huggingface-hub`")
12
+ raise
13
+
14
+
15
+ @dataclass
16
+ class HuggingfaceCustomEmbedder(Embedder):
17
+ """Huggingface Custom Embedder"""
18
+
19
+ id: str = "intfloat/multilingual-e5-large"
20
+ api_key: Optional[str] = getenv("HUGGINGFACE_API_KEY")
21
+ client_params: Optional[Dict[str, Any]] = None
22
+ huggingface_client: Optional[InferenceClient] = None
23
+ async_client: Optional[AsyncInferenceClient] = None
24
+
25
+ def __post_init__(self):
26
+ if self.enable_batch:
27
+ log_warning("HuggingfaceEmbedder does not support batch embeddings, setting enable_batch to False")
28
+ self.enable_batch = False
29
+
30
+ @property
31
+ def client(self) -> InferenceClient:
32
+ if self.huggingface_client:
33
+ return self.huggingface_client
34
+ _client_params: Dict[str, Any] = {}
35
+ if self.api_key:
36
+ _client_params["api_key"] = self.api_key
37
+ if self.client_params:
38
+ _client_params.update(self.client_params)
39
+ self.huggingface_client = InferenceClient(**_client_params)
40
+ return self.huggingface_client
41
+
42
+ @property
43
+ def aclient(self) -> AsyncInferenceClient:
44
+ if self.async_client:
45
+ return self.async_client
46
+ _client_params: Dict[str, Any] = {}
47
+ if self.api_key:
48
+ _client_params["api_key"] = self.api_key
49
+ if self.client_params:
50
+ _client_params.update(self.client_params)
51
+ self.async_client = AsyncInferenceClient(**_client_params)
52
+ return self.async_client
53
+
54
+ def _response(self, text: str):
55
+ return self.client.feature_extraction(text=text, model=self.id)
56
+
57
+ def get_embedding(self, text: str) -> List[float]:
58
+ response = self._response(text=text)
59
+ try:
60
+ # If already a list, return directly
61
+ if isinstance(response, list):
62
+ return response
63
+ # If numpy array, convert to list
64
+ elif hasattr(response, "tolist"):
65
+ return response.tolist()
66
+ else:
67
+ return list(response)
68
+ except Exception as e:
69
+ log_warning(f"Failed to process embeddings: {e}")
70
+ return []
71
+
72
+ def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
73
+ return self.get_embedding(text=text), None
74
+
75
+ async def async_get_embedding(self, text: str) -> List[float]:
76
+ """Async version of get_embedding using AsyncInferenceClient."""
77
+ response = await self.aclient.feature_extraction(text=text, model=self.id)
78
+ try:
79
+ # If already a list, return directly
80
+ if isinstance(response, list):
81
+ return response
82
+ # If numpy array, convert to list
83
+ elif hasattr(response, "tolist"):
84
+ return response.tolist()
85
+ else:
86
+ return list(response)
87
+ except Exception as e:
88
+ log_warning(f"Failed to process embeddings: {e}")
89
+ return []
90
+
91
+ async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
92
+ """Async version of get_embedding_and_usage."""
93
+ embedding = await self.async_get_embedding(text=text)
94
+ return embedding, None
@@ -0,0 +1,182 @@
1
+ from dataclasses import dataclass
2
+ from os import getenv
3
+ from typing import Any, Dict, List, Optional, Tuple
4
+
5
+ from typing_extensions import Literal
6
+
7
+ from agno.knowledge.embedder.base import Embedder
8
+ from agno.utils.log import logger
9
+
10
+ try:
11
+ import requests
12
+ except ImportError:
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")
19
+
20
+
21
+ @dataclass
22
+ class JinaEmbedder(Embedder):
23
+ id: str = "jina-embeddings-v3"
24
+ dimensions: int = 1024
25
+ embedding_type: Literal["float", "base64", "int8"] = "float"
26
+ late_chunking: bool = False
27
+ user: Optional[str] = None
28
+ api_key: Optional[str] = getenv("JINA_API_KEY")
29
+ base_url: str = "https://api.jina.ai/v1/embeddings"
30
+ headers: Optional[Dict[str, str]] = None
31
+ request_params: Optional[Dict[str, Any]] = None
32
+ timeout: Optional[float] = None
33
+
34
+ def _get_headers(self) -> Dict[str, str]:
35
+ if not self.api_key:
36
+ raise ValueError(
37
+ "API key is required for Jina embedder. Set JINA_API_KEY environment variable or pass api_key parameter."
38
+ )
39
+
40
+ headers = {"Content-Type": "application/json", "Authorization": f"Bearer {self.api_key}"}
41
+ if self.headers:
42
+ headers.update(self.headers)
43
+ return headers
44
+
45
+ def _response(self, text: str) -> Dict[str, Any]:
46
+ data = {
47
+ "model": self.id,
48
+ "late_chunking": self.late_chunking,
49
+ "dimensions": self.dimensions,
50
+ "embedding_type": self.embedding_type,
51
+ "input": [text], # Jina API expects a list
52
+ }
53
+ if self.user is not None:
54
+ data["user"] = self.user
55
+ if self.request_params:
56
+ data.update(self.request_params)
57
+
58
+ response = requests.post(self.base_url, headers=self._get_headers(), json=data, timeout=self.timeout)
59
+ response.raise_for_status()
60
+ return response.json()
61
+
62
+ def get_embedding(self, text: str) -> List[float]:
63
+ try:
64
+ result = self._response(text)
65
+ return result["data"][0]["embedding"]
66
+ except Exception as e:
67
+ logger.warning(f"Failed to get embedding: {e}")
68
+ return []
69
+
70
+ def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
71
+ try:
72
+ result = self._response(text)
73
+ embedding = result["data"][0]["embedding"]
74
+ usage = result.get("usage")
75
+ return embedding, usage
76
+ except Exception as e:
77
+ logger.warning(f"Failed to get embedding and usage: {e}")
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
120
+
121
+ async def _async_batch_response(self, texts: List[str]) -> Dict[str, Any]:
122
+ """Async batch version of _response using aiohttp."""
123
+ data = {
124
+ "model": self.id,
125
+ "late_chunking": self.late_chunking,
126
+ "dimensions": self.dimensions,
127
+ "embedding_type": self.embedding_type,
128
+ "input": texts, # Jina API expects a list of texts for batch processing
129
+ }
130
+ if self.user is not None:
131
+ data["user"] = self.user
132
+ if self.request_params:
133
+ data.update(self.request_params)
134
+
135
+ timeout = aiohttp.ClientTimeout(total=self.timeout) if self.timeout else None
136
+
137
+ async with aiohttp.ClientSession(timeout=timeout) as session:
138
+ async with session.post(self.base_url, headers=self._get_headers(), json=data) as response:
139
+ response.raise_for_status()
140
+ return await response.json()
141
+
142
+ async def async_get_embeddings_batch_and_usage(
143
+ self, texts: List[str]
144
+ ) -> Tuple[List[List[float]], List[Optional[Dict]]]:
145
+ """
146
+ Get embeddings and usage for multiple texts in batches.
147
+
148
+ Args:
149
+ texts: List of text strings to embed
150
+
151
+ Returns:
152
+ Tuple of (List of embedding vectors, List of usage dictionaries)
153
+ """
154
+ all_embeddings = []
155
+ all_usage = []
156
+ logger.info(f"Getting embeddings and usage for {len(texts)} texts in batches of {self.batch_size}")
157
+
158
+ for i in range(0, len(texts), self.batch_size):
159
+ batch_texts = texts[i : i + self.batch_size]
160
+
161
+ try:
162
+ result = await self._async_batch_response(batch_texts)
163
+ batch_embeddings = [data["embedding"] for data in result["data"]]
164
+ all_embeddings.extend(batch_embeddings)
165
+
166
+ # For each embedding in the batch, add the same usage information
167
+ usage_dict = result.get("usage")
168
+ all_usage.extend([usage_dict] * len(batch_embeddings))
169
+ except Exception as e:
170
+ logger.warning(f"Error in async batch embedding: {e}")
171
+ # Fallback to individual calls for this batch
172
+ for text in batch_texts:
173
+ try:
174
+ embedding, usage = await self.async_get_embedding_and_usage(text)
175
+ all_embeddings.append(embedding)
176
+ all_usage.append(usage)
177
+ except Exception as e2:
178
+ logger.warning(f"Error in individual async embedding fallback: {e2}")
179
+ all_embeddings.append([])
180
+ all_usage.append(None)
181
+
182
+ return all_embeddings, all_usage
@@ -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,206 @@
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 log_error, log_info, log_warning
7
+
8
+ try:
9
+ from mistralai import Mistral # type: ignore
10
+ from mistralai.models.embeddingresponse import EmbeddingResponse # type: ignore
11
+ except ImportError:
12
+ log_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], # Mistral API expects a list
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
+ log_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
+ log_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
+ log_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
+ log_warning(f"Error getting embedding and usage: {e}")
139
+ return [], {}
140
+
141
+ async def async_get_embeddings_batch_and_usage(
142
+ self, texts: List[str]
143
+ ) -> Tuple[List[List[float]], List[Optional[Dict[str, Any]]]]:
144
+ """
145
+ Get embeddings and usage for multiple texts in batches.
146
+
147
+ Args:
148
+ texts: List of text strings to embed
149
+
150
+ Returns:
151
+ Tuple of (List of embedding vectors, List of usage dictionaries)
152
+ """
153
+ all_embeddings = []
154
+ all_usage = []
155
+ log_info(f"Getting embeddings and usage for {len(texts)} texts in batches of {self.batch_size}")
156
+
157
+ for i in range(0, len(texts), self.batch_size):
158
+ batch_texts = texts[i : i + self.batch_size]
159
+
160
+ _request_params: Dict[str, Any] = {
161
+ "inputs": batch_texts, # Mistral API expects a list for batch processing
162
+ "model": self.id,
163
+ }
164
+ if self.request_params:
165
+ _request_params.update(self.request_params)
166
+
167
+ try:
168
+ # Check if the client has an async version of embeddings.create
169
+ if hasattr(self.client.embeddings, "create_async"):
170
+ response: EmbeddingResponse = await self.client.embeddings.create_async(**_request_params)
171
+ else:
172
+ # Fallback to running sync method in thread executor
173
+ import asyncio
174
+
175
+ loop = asyncio.get_running_loop()
176
+ response: EmbeddingResponse = await loop.run_in_executor( # type: ignore
177
+ None, lambda: self.client.embeddings.create(**_request_params)
178
+ )
179
+
180
+ # Extract embeddings from batch response
181
+ if response.data:
182
+ batch_embeddings = [data.embedding for data in response.data if data.embedding]
183
+ all_embeddings.extend(batch_embeddings)
184
+ else:
185
+ # If no embeddings, add empty lists for each text in batch
186
+ all_embeddings.extend([[] for _ in batch_texts])
187
+
188
+ # Extract usage information
189
+ usage_dict = response.usage.model_dump() if response.usage else None
190
+ # Add same usage info for each embedding in the batch
191
+ all_usage.extend([usage_dict] * len(batch_texts))
192
+
193
+ except Exception as e:
194
+ log_warning(f"Error in async batch embedding: {e}")
195
+ # Fallback to individual calls for this batch
196
+ for text in batch_texts:
197
+ try:
198
+ embedding, usage = await self.async_get_embedding_and_usage(text)
199
+ all_embeddings.append(embedding)
200
+ all_usage.append(usage)
201
+ except Exception as e2:
202
+ log_warning(f"Error in individual async embedding fallback: {e2}")
203
+ all_embeddings.append([])
204
+ all_usage.append(None)
205
+
206
+ return all_embeddings, all_usage
@@ -0,0 +1,13 @@
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 NebiusEmbedder(OpenAIEmbedder):
10
+ id: str = "BAAI/bge-en-icl"
11
+ dimensions: int = 1024
12
+ api_key: Optional[str] = getenv("NEBIUS_API_KEY")
13
+ base_url: str = "https://api.tokenfactory.nebius.com/v1/"
@@ -0,0 +1,154 @@
1
+ from dataclasses import dataclass
2
+ from typing import Any, Dict, List, Optional, Tuple
3
+
4
+ from agno.knowledge.embedder.base import Embedder
5
+ from agno.utils.log import log_error, logger
6
+
7
+ try:
8
+ import importlib.metadata as metadata
9
+
10
+ from ollama import AsyncClient as AsyncOllamaClient
11
+ from ollama import Client as OllamaClient
12
+ from packaging import version
13
+
14
+ # Get installed Ollama version
15
+ ollama_version = metadata.version("ollama")
16
+
17
+ # Check version compatibility (requires v0.3.x or higher)
18
+ parsed_version = version.parse(ollama_version)
19
+ if parsed_version.major == 0 and parsed_version.minor < 3:
20
+ import warnings
21
+
22
+ warnings.warn("Only Ollama v0.3.x and above are supported", UserWarning)
23
+ raise RuntimeError("Incompatible Ollama version detected")
24
+
25
+ except ImportError as e:
26
+ # Handle different import error scenarios
27
+ if "ollama" in str(e):
28
+ raise ImportError("Ollama not installed. Install with `pip install ollama`") from e
29
+ else:
30
+ raise ImportError("Missing dependencies. Install with `pip install packaging importlib-metadata`") from e
31
+
32
+ except Exception as e:
33
+ # Catch-all for unexpected errors
34
+ log_error(f"An unexpected error occurred: {e}")
35
+
36
+
37
+ @dataclass
38
+ class OllamaEmbedder(Embedder):
39
+ id: str = "openhermes"
40
+ dimensions: int = 4096
41
+ host: Optional[str] = None
42
+ timeout: Optional[Any] = None
43
+ options: Optional[Any] = None
44
+ client_kwargs: Optional[Dict[str, Any]] = None
45
+ ollama_client: Optional[OllamaClient] = None
46
+ async_client: Optional[AsyncOllamaClient] = None
47
+
48
+ def __post_init__(self):
49
+ if self.enable_batch:
50
+ logger.warning("OllamaEmbedder does not support batch embeddings, setting enable_batch to False")
51
+ self.enable_batch = False
52
+
53
+ @property
54
+ def client(self) -> OllamaClient:
55
+ if self.ollama_client:
56
+ return self.ollama_client
57
+
58
+ _ollama_params: Dict[str, Any] = {
59
+ "host": self.host,
60
+ "timeout": self.timeout,
61
+ }
62
+ _ollama_params = {k: v for k, v in _ollama_params.items() if v is not None}
63
+ if self.client_kwargs:
64
+ _ollama_params.update(self.client_kwargs)
65
+ self.ollama_client = OllamaClient(**_ollama_params)
66
+ return self.ollama_client
67
+
68
+ @property
69
+ def aclient(self) -> AsyncOllamaClient:
70
+ if self.async_client:
71
+ return self.async_client
72
+
73
+ _ollama_params: Dict[str, Any] = {
74
+ "host": self.host,
75
+ "timeout": self.timeout,
76
+ }
77
+ _ollama_params = {k: v for k, v in _ollama_params.items() if v is not None}
78
+ if self.client_kwargs:
79
+ _ollama_params.update(self.client_kwargs)
80
+ self.async_client = AsyncOllamaClient(**_ollama_params)
81
+ return self.async_client
82
+
83
+ def _response(self, text: str) -> Dict[str, Any]:
84
+ kwargs: Dict[str, Any] = {}
85
+ if self.options is not None:
86
+ kwargs["options"] = self.options
87
+
88
+ # Add dimensions parameter for models that support it
89
+ if self.dimensions is not None:
90
+ kwargs["dimensions"] = self.dimensions
91
+
92
+ response = self.client.embed(input=text, model=self.id, **kwargs)
93
+ if response and "embeddings" in response:
94
+ embeddings = response["embeddings"]
95
+ if isinstance(embeddings, list) and len(embeddings) > 0 and isinstance(embeddings[0], list):
96
+ return {"embeddings": embeddings[0]} # Use the first element
97
+ elif isinstance(embeddings, list) and all(isinstance(x, (int, float)) for x in embeddings):
98
+ return {"embeddings": embeddings} # Return as-is if already flat
99
+ return {"embeddings": []} # Return an empty list if no valid embedding is found
100
+
101
+ def get_embedding(self, text: str) -> List[float]:
102
+ try:
103
+ response = self._response(text=text)
104
+ embedding = response.get("embeddings", [])
105
+ if len(embedding) != self.dimensions:
106
+ logger.warning(f"Expected embedding dimension {self.dimensions}, but got {len(embedding)}")
107
+ return []
108
+ return embedding
109
+ except Exception as e:
110
+ logger.warning(e)
111
+ return []
112
+
113
+ def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
114
+ embedding = self.get_embedding(text=text)
115
+ usage = None
116
+ return embedding, usage
117
+
118
+ async def _async_response(self, text: str) -> Dict[str, Any]:
119
+ """Async version of _response using AsyncOllamaClient."""
120
+ kwargs: Dict[str, Any] = {}
121
+ if self.options is not None:
122
+ kwargs["options"] = self.options
123
+
124
+ # Add dimensions parameter for models that support it
125
+ if self.dimensions is not None:
126
+ kwargs["dimensions"] = self.dimensions
127
+
128
+ response = await self.aclient.embed(input=text, model=self.id, **kwargs)
129
+ if response and "embeddings" in response:
130
+ embeddings = response["embeddings"]
131
+ if isinstance(embeddings, list) and len(embeddings) > 0 and isinstance(embeddings[0], list):
132
+ return {"embeddings": embeddings[0]} # Use the first element
133
+ elif isinstance(embeddings, list) and all(isinstance(x, (int, float)) for x in embeddings):
134
+ return {"embeddings": embeddings} # Return as-is if already flat
135
+ return {"embeddings": []} # Return an empty list if no valid embedding is found
136
+
137
+ async def async_get_embedding(self, text: str) -> List[float]:
138
+ """Async version of get_embedding."""
139
+ try:
140
+ response = await self._async_response(text=text)
141
+ embedding = response.get("embeddings", [])
142
+ if len(embedding) != self.dimensions:
143
+ logger.warning(f"Expected embedding dimension {self.dimensions}, but got {len(embedding)}")
144
+ return []
145
+ return embedding
146
+ except Exception as e:
147
+ logger.warning(f"Error getting embedding: {e}")
148
+ return []
149
+
150
+ async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
151
+ """Async version of get_embedding_and_usage."""
152
+ embedding = await self.async_get_embedding(text=text)
153
+ usage = None
154
+ return embedding, usage