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,502 @@
1
+ from collections.abc import AsyncIterator
2
+ from dataclasses import dataclass
3
+ from os import getenv
4
+ from typing import Any, Dict, Iterator, List, Optional, Type, Union
5
+
6
+ import httpx
7
+ from pydantic import BaseModel
8
+
9
+ from agno.exceptions import ModelProviderError
10
+ from agno.models.base import Model
11
+ from agno.models.message import Message
12
+ from agno.models.metrics import Metrics
13
+ from agno.models.response import ModelResponse
14
+ from agno.run.agent import RunOutput
15
+ from agno.utils.http import get_default_async_client, get_default_sync_client
16
+ from agno.utils.log import log_debug, log_error, log_warning
17
+ from agno.utils.models.llama import format_message
18
+
19
+ try:
20
+ from llama_api_client import AsyncLlamaAPIClient, LlamaAPIClient
21
+ from llama_api_client.types.create_chat_completion_response import CreateChatCompletionResponse, Metric
22
+ from llama_api_client.types.create_chat_completion_response_stream_chunk import (
23
+ CreateChatCompletionResponseStreamChunk,
24
+ EventDeltaTextDelta,
25
+ EventDeltaToolCallDelta,
26
+ EventDeltaToolCallDeltaFunction,
27
+ EventMetric,
28
+ )
29
+ from llama_api_client.types.message_text_content_item import MessageTextContentItem
30
+ except ImportError:
31
+ raise ImportError("`llama-api-client` not installed. Please install using `pip install llama-api-client`")
32
+
33
+
34
+ @dataclass
35
+ class Llama(Model):
36
+ """
37
+ A class for interacting with Llama models using the Llama API using the Llama SDK.
38
+ """
39
+
40
+ id: str = "Llama-4-Maverick-17B-128E-Instruct-FP8"
41
+ name: str = "Llama"
42
+ provider: str = "Llama"
43
+
44
+ supports_native_structured_outputs: bool = False
45
+ supports_json_schema_outputs: bool = True
46
+
47
+ # Request parameters
48
+ max_completion_tokens: Optional[int] = None
49
+ repetition_penalty: Optional[float] = None
50
+ temperature: Optional[float] = None
51
+ top_p: Optional[float] = None
52
+ top_k: Optional[int] = None
53
+ extra_headers: Optional[Any] = None
54
+ extra_query: Optional[Any] = None
55
+ extra_body: Optional[Any] = None
56
+ request_params: Optional[Dict[str, Any]] = None
57
+
58
+ # Client parameters
59
+ api_key: Optional[str] = None
60
+ base_url: Optional[Union[str, httpx.URL]] = None
61
+ timeout: Optional[float] = None
62
+ max_retries: Optional[int] = None
63
+ default_headers: Optional[Any] = None
64
+ default_query: Optional[Any] = None
65
+ http_client: Optional[Union[httpx.Client, httpx.AsyncClient]] = None
66
+ client_params: Optional[Dict[str, Any]] = None
67
+
68
+ # OpenAI clients
69
+ client: Optional[LlamaAPIClient] = None
70
+ async_client: Optional[AsyncLlamaAPIClient] = None
71
+
72
+ def _get_client_params(self) -> Dict[str, Any]:
73
+ # Fetch API key from env if not already set
74
+ if not self.api_key:
75
+ self.api_key = getenv("LLAMA_API_KEY")
76
+ if not self.api_key:
77
+ log_error("LLAMA_API_KEY not set. Please set the LLAMA_API_KEY environment variable.")
78
+
79
+ # Define base client params
80
+ base_params = {
81
+ "api_key": self.api_key,
82
+ "base_url": self.base_url,
83
+ "timeout": self.timeout,
84
+ "max_retries": self.max_retries,
85
+ "default_headers": self.default_headers,
86
+ "default_query": self.default_query,
87
+ }
88
+
89
+ # Create client_params dict with non-None values
90
+ client_params = {k: v for k, v in base_params.items() if v is not None}
91
+
92
+ # Add additional client params if provided
93
+ if self.client_params:
94
+ client_params.update(self.client_params)
95
+ return client_params
96
+
97
+ def get_client(self) -> LlamaAPIClient:
98
+ """
99
+ Returns a Llama client.
100
+
101
+ Returns:
102
+ LlamaAPIClient: An instance of the Llama client.
103
+ """
104
+ if self.client and not self.client.is_closed():
105
+ return self.client
106
+
107
+ client_params: Dict[str, Any] = self._get_client_params()
108
+ if self.http_client:
109
+ if isinstance(self.http_client, httpx.Client):
110
+ client_params["http_client"] = self.http_client
111
+ else:
112
+ log_warning("http_client is not an instance of httpx.Client. Using default global httpx.Client.")
113
+ # Use global sync client when user http_client is invalid
114
+ client_params["http_client"] = get_default_sync_client()
115
+ else:
116
+ # Use global sync client when no custom http_client is provided
117
+ client_params["http_client"] = get_default_sync_client()
118
+ self.client = LlamaAPIClient(**client_params)
119
+ return self.client
120
+
121
+ def get_async_client(self) -> AsyncLlamaAPIClient:
122
+ """
123
+ Returns an asynchronous Llama client.
124
+
125
+ Returns:
126
+ AsyncLlamaAPIClient: An instance of the asynchronous Llama client.
127
+ """
128
+ if self.async_client and not self.async_client.is_closed():
129
+ return self.async_client
130
+
131
+ client_params: Dict[str, Any] = self._get_client_params()
132
+ if self.http_client:
133
+ if isinstance(self.http_client, httpx.AsyncClient):
134
+ client_params["http_client"] = self.http_client
135
+ else:
136
+ log_warning(
137
+ "http_client is not an instance of httpx.AsyncClient. Using default global httpx.AsyncClient."
138
+ )
139
+ # Use global async client when user http_client is invalid
140
+ client_params["http_client"] = get_default_async_client()
141
+ else:
142
+ # Use global async client when no custom http_client is provided
143
+ client_params["http_client"] = get_default_async_client()
144
+
145
+ # Create and cache the client
146
+ self.async_client = AsyncLlamaAPIClient(**client_params)
147
+ return self.async_client
148
+
149
+ def get_request_params(
150
+ self,
151
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
152
+ tools: Optional[List[Dict[str, Any]]] = None,
153
+ ) -> Dict[str, Any]:
154
+ """
155
+ Returns keyword arguments for API requests.
156
+ """
157
+ # Define base request parameters
158
+ base_params = {
159
+ "max_completion_tokens": self.max_completion_tokens,
160
+ "repetition_penalty": self.repetition_penalty,
161
+ "temperature": self.temperature,
162
+ "top_p": self.top_p,
163
+ "top_k": self.top_k,
164
+ "extra_headers": self.extra_headers,
165
+ "extra_query": self.extra_query,
166
+ "extra_body": self.extra_body,
167
+ "request_params": self.request_params,
168
+ }
169
+
170
+ # Filter out None values
171
+ request_params = {k: v for k, v in base_params.items() if v is not None}
172
+
173
+ # Add tools
174
+ if tools is not None and len(tools) > 0:
175
+ request_params["tools"] = tools
176
+
177
+ if response_format is not None:
178
+ request_params["response_format"] = response_format
179
+
180
+ # Add additional request params if provided
181
+ if self.request_params:
182
+ request_params.update(self.request_params)
183
+
184
+ if request_params:
185
+ log_debug(f"Calling {self.provider} with request parameters: {request_params}", log_level=2)
186
+ return request_params
187
+
188
+ def to_dict(self) -> Dict[str, Any]:
189
+ """
190
+ Convert the model to a dictionary.
191
+
192
+ Returns:
193
+ Dict[str, Any]: The dictionary representation of the model.
194
+ """
195
+ model_dict = super().to_dict()
196
+ model_dict.update(
197
+ {
198
+ "max_completion_tokens": self.max_completion_tokens,
199
+ "repetition_penalty": self.repetition_penalty,
200
+ "temperature": self.temperature,
201
+ "top_p": self.top_p,
202
+ "top_k": self.top_k,
203
+ "extra_headers": self.extra_headers,
204
+ "extra_query": self.extra_query,
205
+ "extra_body": self.extra_body,
206
+ "request_params": self.request_params,
207
+ }
208
+ )
209
+ cleaned_dict = {k: v for k, v in model_dict.items() if v is not None}
210
+ return cleaned_dict
211
+
212
+ def invoke(
213
+ self,
214
+ messages: List[Message],
215
+ assistant_message: Message,
216
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
217
+ tools: Optional[List[Dict[str, Any]]] = None,
218
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
219
+ run_response: Optional[RunOutput] = None,
220
+ compress_tool_results: bool = False,
221
+ ) -> ModelResponse:
222
+ """
223
+ Send a chat completion request to the Llama API.
224
+ """
225
+ assistant_message.metrics.start_timer()
226
+
227
+ provider_response = self.get_client().chat.completions.create(
228
+ model=self.id,
229
+ messages=[
230
+ format_message(m, tool_calls=bool(tools), compress_tool_results=compress_tool_results) # type: ignore
231
+ for m in messages
232
+ ],
233
+ **self.get_request_params(tools=tools, response_format=response_format),
234
+ )
235
+
236
+ assistant_message.metrics.stop_timer()
237
+
238
+ model_response = self._parse_provider_response(provider_response, response_format=response_format)
239
+ return model_response
240
+
241
+ async def ainvoke(
242
+ self,
243
+ messages: List[Message],
244
+ assistant_message: Message,
245
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
246
+ tools: Optional[List[Dict[str, Any]]] = None,
247
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
248
+ run_response: Optional[RunOutput] = None,
249
+ compress_tool_results: bool = False,
250
+ ) -> ModelResponse:
251
+ """
252
+ Sends an asynchronous chat completion request to the Llama API.
253
+ """
254
+ if run_response and run_response.metrics:
255
+ run_response.metrics.set_time_to_first_token()
256
+
257
+ assistant_message.metrics.start_timer()
258
+
259
+ provider_response = await self.get_async_client().chat.completions.create(
260
+ model=self.id,
261
+ messages=[
262
+ format_message(m, tool_calls=bool(tools), compress_tool_results=compress_tool_results) # type: ignore
263
+ for m in messages
264
+ ],
265
+ **self.get_request_params(tools=tools, response_format=response_format),
266
+ )
267
+
268
+ assistant_message.metrics.stop_timer()
269
+
270
+ model_response = self._parse_provider_response(provider_response, response_format=response_format)
271
+ return model_response
272
+
273
+ def invoke_stream(
274
+ self,
275
+ messages: List[Message],
276
+ assistant_message: Message,
277
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
278
+ tools: Optional[List[Dict[str, Any]]] = None,
279
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
280
+ run_response: Optional[RunOutput] = None,
281
+ compress_tool_results: bool = False,
282
+ ) -> Iterator[ModelResponse]:
283
+ """
284
+ Send a streaming chat completion request to the Llama API.
285
+ """
286
+ if run_response and run_response.metrics:
287
+ run_response.metrics.set_time_to_first_token()
288
+
289
+ try:
290
+ assistant_message.metrics.start_timer()
291
+
292
+ for chunk in self.get_client().chat.completions.create(
293
+ model=self.id,
294
+ messages=[
295
+ format_message(m, tool_calls=bool(tools), compress_tool_results=compress_tool_results) # type: ignore
296
+ for m in messages
297
+ ],
298
+ stream=True,
299
+ **self.get_request_params(tools=tools, response_format=response_format),
300
+ ):
301
+ yield self._parse_provider_response_delta(chunk) # type: ignore
302
+
303
+ assistant_message.metrics.stop_timer()
304
+
305
+ except Exception as e:
306
+ log_error(f"Error from Llama API: {e}")
307
+ raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
308
+
309
+ async def ainvoke_stream(
310
+ self,
311
+ messages: List[Message],
312
+ assistant_message: Message,
313
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
314
+ tools: Optional[List[Dict[str, Any]]] = None,
315
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
316
+ run_response: Optional[RunOutput] = None,
317
+ compress_tool_results: bool = False,
318
+ ) -> AsyncIterator[ModelResponse]:
319
+ """
320
+ Sends an asynchronous streaming chat completion request to the Llama API.
321
+ """
322
+ if run_response and run_response.metrics:
323
+ run_response.metrics.set_time_to_first_token()
324
+
325
+ assistant_message.metrics.start_timer()
326
+
327
+ try:
328
+ async for chunk in await self.get_async_client().chat.completions.create(
329
+ model=self.id,
330
+ messages=[
331
+ format_message(m, tool_calls=bool(tools), compress_tool_results=compress_tool_results) # type: ignore
332
+ for m in messages
333
+ ],
334
+ stream=True,
335
+ **self.get_request_params(tools=tools, response_format=response_format),
336
+ ):
337
+ yield self._parse_provider_response_delta(chunk) # type: ignore
338
+
339
+ assistant_message.metrics.stop_timer()
340
+
341
+ except Exception as e:
342
+ log_error(f"Error from Llama API: {e}")
343
+ raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
344
+
345
+ def parse_tool_calls(self, tool_calls_data: List[EventDeltaToolCallDeltaFunction]) -> List[Dict[str, Any]]:
346
+ """
347
+ Parse the tool calls from the Llama API.
348
+
349
+ Args:
350
+ tool_calls_data (List[Tuple[str, Any]]): The tool calls data.
351
+
352
+ Returns:
353
+ List[Dict[str, Any]]: The parsed tool calls.
354
+ """
355
+ tool_calls: List[Dict[str, Any]] = []
356
+
357
+ _tool_call_id: Optional[str] = None
358
+ _function_name_parts: List[str] = []
359
+ _function_arguments_parts: List[str] = []
360
+
361
+ def _create_tool_call():
362
+ nonlocal _tool_call_id
363
+ if _tool_call_id and (_function_name_parts or _function_arguments_parts):
364
+ tool_calls.append(
365
+ {
366
+ "id": _tool_call_id,
367
+ "type": "function",
368
+ "function": {
369
+ "name": "".join(_function_name_parts),
370
+ "arguments": "".join(_function_arguments_parts),
371
+ },
372
+ }
373
+ )
374
+ _tool_call_id = None
375
+ _function_name_parts.clear()
376
+ _function_arguments_parts.clear()
377
+
378
+ for _field, _value in tool_calls_data:
379
+ if _field == "function" and isinstance(_value, EventDeltaToolCallDeltaFunction):
380
+ if _value.name and (_tool_call_id or _function_name_parts or _function_arguments_parts):
381
+ _create_tool_call()
382
+ if _value.name:
383
+ _function_name_parts.append(_value.name)
384
+ if _value.arguments:
385
+ _function_arguments_parts.append(_value.arguments)
386
+
387
+ elif _field == "id":
388
+ if _value and _tool_call_id:
389
+ _create_tool_call()
390
+ if _value:
391
+ _tool_call_id = _value # type: ignore
392
+
393
+ _create_tool_call()
394
+
395
+ return tool_calls
396
+
397
+ def _parse_provider_response(self, response: CreateChatCompletionResponse, **kwargs) -> ModelResponse:
398
+ """
399
+ Parse the Llama response into a ModelResponse.
400
+
401
+ Args:
402
+ response: Response from invoke() method
403
+
404
+ Returns:
405
+ ModelResponse: Parsed response data
406
+ """
407
+ model_response = ModelResponse()
408
+
409
+ # Get response message
410
+ response_message = response.completion_message
411
+
412
+ # Add role
413
+ if response_message.role is not None:
414
+ model_response.role = response_message.role
415
+
416
+ # Add content
417
+ if response_message.content is not None:
418
+ if isinstance(response_message.content, MessageTextContentItem):
419
+ model_response.content = response_message.content.text
420
+ else:
421
+ model_response.content = response_message.content
422
+
423
+ # Add tool calls
424
+ if response_message.tool_calls is not None and len(response_message.tool_calls) > 0:
425
+ try:
426
+ for tool_call in response_message.tool_calls:
427
+ tool_name = tool_call.function.name
428
+ tool_input = tool_call.function.arguments
429
+
430
+ function_def = {"name": tool_name}
431
+ if tool_input:
432
+ function_def["arguments"] = tool_input
433
+
434
+ model_response.tool_calls.append(
435
+ {
436
+ "id": tool_call.id,
437
+ "type": "function",
438
+ "function": function_def,
439
+ }
440
+ )
441
+
442
+ except Exception as e:
443
+ log_warning(f"Error processing tool calls: {e}")
444
+
445
+ # Add metrics from the metrics list
446
+ if hasattr(response, "metrics") and response.metrics is not None:
447
+ model_response.response_usage = self._get_metrics(response.metrics)
448
+
449
+ return model_response
450
+
451
+ def _parse_provider_response_delta(
452
+ self, response: CreateChatCompletionResponseStreamChunk, **kwargs
453
+ ) -> ModelResponse:
454
+ """
455
+ Parse the Llama streaming response into a ModelResponse.
456
+
457
+ Args:
458
+ response_delta: Raw response chunk from the Llama API
459
+
460
+ Returns:
461
+ ModelResponse: Parsed response data
462
+ """
463
+ model_response = ModelResponse()
464
+
465
+ if response is not None:
466
+ delta = response.event
467
+
468
+ # Capture metrics event
469
+ if delta.event_type == "metrics" and delta.metrics is not None:
470
+ model_response.response_usage = self._get_metrics(delta.metrics)
471
+
472
+ if isinstance(delta.delta, EventDeltaTextDelta):
473
+ model_response.content = delta.delta.text
474
+
475
+ # Add tool calls
476
+ if isinstance(delta.delta, EventDeltaToolCallDelta):
477
+ model_response.tool_calls = delta.delta # type: ignore
478
+
479
+ return model_response
480
+
481
+ def _get_metrics(self, response_usage: Union[List[Metric], List[EventMetric]]) -> Metrics:
482
+ """
483
+ Parse the given Llama usage into an Agno Metrics object.
484
+
485
+ Args:
486
+ response_usage: Usage data from Llama
487
+
488
+ Returns:
489
+ Metrics: Parsed metrics data
490
+ """
491
+ metrics = Metrics()
492
+
493
+ for metric in response_usage:
494
+ metrics_field = metric.metric
495
+ if metrics_field == "num_prompt_tokens":
496
+ metrics.input_tokens = int(metric.value)
497
+ elif metrics_field == "num_completion_tokens":
498
+ metrics.output_tokens = int(metric.value)
499
+
500
+ metrics.total_tokens = metrics.input_tokens + metrics.output_tokens
501
+
502
+ return metrics
@@ -0,0 +1,79 @@
1
+ from dataclasses import dataclass
2
+ from os import getenv
3
+ from typing import Any, Dict, Optional
4
+
5
+ try:
6
+ from openai import AsyncOpenAI as AsyncOpenAIClient
7
+ except ImportError:
8
+ raise ImportError("`openai` not installed. Please install using `pip install openai`")
9
+
10
+ from agno.exceptions import ModelAuthenticationError
11
+ from agno.models.meta.llama import Message
12
+ from agno.models.openai.like import OpenAILike
13
+ from agno.utils.models.llama import format_message
14
+
15
+
16
+ @dataclass
17
+ class LlamaOpenAI(OpenAILike):
18
+ """
19
+ Class for interacting with the Llama API via OpenAI-like interface.
20
+
21
+ Attributes:
22
+ id (str): The ID of the language model.
23
+ name (str): The name of the API.
24
+ provider (str): The provider of the API.
25
+ api_key (Optional[str]): The API key for the xAI API.
26
+ base_url (Optional[str]): The base URL for the xAI API.
27
+ """
28
+
29
+ id: str = "Llama-4-Maverick-17B-128E-Instruct-FP8"
30
+ name: str = "LlamaOpenAI"
31
+ provider: str = "LlamaOpenAI"
32
+
33
+ api_key: Optional[str] = None
34
+ base_url: Optional[str] = "https://api.llama.com/compat/v1/"
35
+
36
+ # Request parameters
37
+ max_completion_tokens: Optional[int] = None
38
+ repetition_penalty: Optional[float] = None
39
+ temperature: Optional[float] = None
40
+ top_p: Optional[float] = None
41
+ top_k: Optional[int] = None
42
+ extra_headers: Optional[Any] = None
43
+ extra_query: Optional[Any] = None
44
+ extra_body: Optional[Any] = None
45
+ request_params: Optional[Dict[str, Any]] = None
46
+
47
+ supports_native_structured_outputs: bool = False
48
+ supports_json_schema_outputs: bool = True
49
+
50
+ # Cached async client
51
+ openai_async_client: Optional[AsyncOpenAIClient] = None
52
+
53
+ def _get_client_params(self) -> Dict[str, Any]:
54
+ """
55
+ Returns client parameters for API requests, checking for LLAMA_API_KEY.
56
+
57
+ Returns:
58
+ Dict[str, Any]: A dictionary of client parameters for API requests.
59
+ """
60
+ if not self.api_key:
61
+ self.api_key = getenv("LLAMA_API_KEY")
62
+ if not self.api_key:
63
+ raise ModelAuthenticationError(
64
+ message="LLAMA_API_KEY not set. Please set the LLAMA_API_KEY environment variable.",
65
+ model_name=self.name,
66
+ )
67
+ return super()._get_client_params()
68
+
69
+ def _format_message(self, message: Message) -> Dict[str, Any]:
70
+ """
71
+ Format a message into the format expected by Llama API.
72
+
73
+ Args:
74
+ message (Message): The message to format.
75
+
76
+ Returns:
77
+ Dict[str, Any]: The formatted message.
78
+ """
79
+ return format_message(message, openai_like=True)
agno/models/metrics.py ADDED
@@ -0,0 +1,120 @@
1
+ from dataclasses import asdict, dataclass
2
+ from typing import Any, Dict, Optional
3
+
4
+ from agno.utils.timer import Timer
5
+
6
+
7
+ @dataclass
8
+ class Metrics:
9
+ """All relevant metrics for a session, run or message."""
10
+
11
+ # Main token consumption values
12
+ input_tokens: int = 0
13
+ output_tokens: int = 0
14
+ total_tokens: int = 0
15
+
16
+ # Audio token usage
17
+ audio_input_tokens: int = 0
18
+ audio_output_tokens: int = 0
19
+ audio_total_tokens: int = 0
20
+
21
+ # Cache token usage
22
+ cache_read_tokens: int = 0
23
+ cache_write_tokens: int = 0
24
+
25
+ # Tokens employed in reasoning
26
+ reasoning_tokens: int = 0
27
+
28
+ # Time metrics
29
+ # Internal timer utility for tracking execution time
30
+ timer: Optional[Timer] = None
31
+ # Time from run start to first token generation, in seconds
32
+ time_to_first_token: Optional[float] = None
33
+ # Total run time, in seconds
34
+ duration: Optional[float] = None
35
+
36
+ # Provider-specific metrics
37
+ provider_metrics: Optional[dict] = None
38
+
39
+ # Any additional metrics
40
+ additional_metrics: Optional[dict] = None
41
+
42
+ def to_dict(self) -> Dict[str, Any]:
43
+ metrics_dict = asdict(self)
44
+ # Remove the timer util if present
45
+ metrics_dict.pop("timer", None)
46
+ metrics_dict = {
47
+ k: v
48
+ for k, v in metrics_dict.items()
49
+ if v is not None and (not isinstance(v, (int, float)) or v != 0) and (not isinstance(v, dict) or len(v) > 0)
50
+ }
51
+ return metrics_dict
52
+
53
+ def __add__(self, other: "Metrics") -> "Metrics":
54
+ # Create new instance of the same type as self
55
+ result_class = type(self)
56
+ result = result_class(
57
+ input_tokens=self.input_tokens + other.input_tokens,
58
+ output_tokens=self.output_tokens + other.output_tokens,
59
+ total_tokens=self.total_tokens + other.total_tokens,
60
+ audio_total_tokens=self.audio_total_tokens + other.audio_total_tokens,
61
+ audio_input_tokens=self.audio_input_tokens + other.audio_input_tokens,
62
+ audio_output_tokens=self.audio_output_tokens + other.audio_output_tokens,
63
+ cache_read_tokens=self.cache_read_tokens + other.cache_read_tokens,
64
+ cache_write_tokens=self.cache_write_tokens + other.cache_write_tokens,
65
+ reasoning_tokens=self.reasoning_tokens + other.reasoning_tokens,
66
+ )
67
+
68
+ # Handle provider_metrics
69
+ if self.provider_metrics or other.provider_metrics:
70
+ result.provider_metrics = {}
71
+ if self.provider_metrics:
72
+ result.provider_metrics.update(self.provider_metrics)
73
+ if other.provider_metrics:
74
+ result.provider_metrics.update(other.provider_metrics)
75
+
76
+ # Handle additional metrics
77
+ if self.additional_metrics or other.additional_metrics:
78
+ result.additional_metrics = {}
79
+ if self.additional_metrics:
80
+ result.additional_metrics.update(self.additional_metrics)
81
+ if other.additional_metrics:
82
+ result.additional_metrics.update(other.additional_metrics)
83
+
84
+ # Sum durations if both exist
85
+ if self.duration is not None and other.duration is not None:
86
+ result.duration = self.duration + other.duration
87
+ elif self.duration is not None:
88
+ result.duration = self.duration
89
+ elif other.duration is not None:
90
+ result.duration = other.duration
91
+
92
+ # Sum time to first token if both exist
93
+ if self.time_to_first_token is not None and other.time_to_first_token is not None:
94
+ result.time_to_first_token = self.time_to_first_token + other.time_to_first_token
95
+ elif self.time_to_first_token is not None:
96
+ result.time_to_first_token = self.time_to_first_token
97
+ elif other.time_to_first_token is not None:
98
+ result.time_to_first_token = other.time_to_first_token
99
+
100
+ return result
101
+
102
+ def __radd__(self, other: "Metrics") -> "Metrics":
103
+ if other == 0: # Handle sum() starting value
104
+ return self
105
+ return self + other
106
+
107
+ def start_timer(self):
108
+ if self.timer is None:
109
+ self.timer = Timer()
110
+ self.timer.start()
111
+
112
+ def stop_timer(self, set_duration: bool = True):
113
+ if self.timer is not None:
114
+ self.timer.stop()
115
+ if set_duration:
116
+ self.duration = self.timer.elapsed
117
+
118
+ def set_time_to_first_token(self):
119
+ if self.timer is not None:
120
+ self.time_to_first_token = self.timer.elapsed