agno 1.8.1__py3-none-any.whl → 2.0.0rc1__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 (583) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +3181 -4169
  4. agno/api/agent.py +11 -67
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +8 -19
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -41
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +5 -21
  11. agno/api/schemas/evals.py +7 -16
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +5 -21
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +11 -7
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +11 -66
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/db/__init__.py +24 -0
  25. agno/db/base.py +245 -0
  26. agno/db/dynamo/__init__.py +3 -0
  27. agno/db/dynamo/dynamo.py +1743 -0
  28. agno/db/dynamo/schemas.py +278 -0
  29. agno/db/dynamo/utils.py +684 -0
  30. agno/db/firestore/__init__.py +3 -0
  31. agno/db/firestore/firestore.py +1432 -0
  32. agno/db/firestore/schemas.py +130 -0
  33. agno/db/firestore/utils.py +278 -0
  34. agno/db/gcs_json/__init__.py +3 -0
  35. agno/db/gcs_json/gcs_json_db.py +1001 -0
  36. agno/db/gcs_json/utils.py +194 -0
  37. agno/db/in_memory/__init__.py +3 -0
  38. agno/db/in_memory/in_memory_db.py +882 -0
  39. agno/db/in_memory/utils.py +172 -0
  40. agno/db/json/__init__.py +3 -0
  41. agno/db/json/json_db.py +1045 -0
  42. agno/db/json/utils.py +196 -0
  43. agno/db/migrations/v1_to_v2.py +162 -0
  44. agno/db/mongo/__init__.py +3 -0
  45. agno/db/mongo/mongo.py +1411 -0
  46. agno/db/mongo/schemas.py +77 -0
  47. agno/db/mongo/utils.py +204 -0
  48. agno/db/mysql/__init__.py +3 -0
  49. agno/db/mysql/mysql.py +1719 -0
  50. agno/db/mysql/schemas.py +124 -0
  51. agno/db/mysql/utils.py +297 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1710 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +280 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1367 -0
  58. agno/db/redis/schemas.py +109 -0
  59. agno/db/redis/utils.py +288 -0
  60. agno/db/schemas/__init__.py +3 -0
  61. agno/db/schemas/evals.py +33 -0
  62. agno/db/schemas/knowledge.py +40 -0
  63. agno/db/schemas/memory.py +46 -0
  64. agno/db/singlestore/__init__.py +3 -0
  65. agno/db/singlestore/schemas.py +116 -0
  66. agno/db/singlestore/singlestore.py +1712 -0
  67. agno/db/singlestore/utils.py +326 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1676 -0
  71. agno/db/sqlite/utils.py +268 -0
  72. agno/db/utils.py +88 -0
  73. agno/eval/__init__.py +14 -0
  74. agno/eval/accuracy.py +142 -43
  75. agno/eval/performance.py +88 -23
  76. agno/eval/reliability.py +73 -20
  77. agno/eval/utils.py +23 -13
  78. agno/integrations/discord/__init__.py +3 -0
  79. agno/{app → integrations}/discord/client.py +15 -11
  80. agno/knowledge/__init__.py +2 -2
  81. agno/{document → knowledge}/chunking/agentic.py +2 -2
  82. agno/{document → knowledge}/chunking/document.py +2 -2
  83. agno/{document → knowledge}/chunking/fixed.py +3 -3
  84. agno/{document → knowledge}/chunking/markdown.py +2 -2
  85. agno/{document → knowledge}/chunking/recursive.py +2 -2
  86. agno/{document → knowledge}/chunking/row.py +2 -2
  87. agno/knowledge/chunking/semantic.py +59 -0
  88. agno/knowledge/chunking/strategy.py +121 -0
  89. agno/knowledge/content.py +74 -0
  90. agno/knowledge/document/__init__.py +5 -0
  91. agno/{document → knowledge/document}/base.py +12 -2
  92. agno/knowledge/embedder/__init__.py +5 -0
  93. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  94. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  95. agno/{embedder → knowledge/embedder}/base.py +6 -0
  96. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  97. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  98. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  99. agno/{embedder → knowledge/embedder}/google.py +74 -1
  100. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  101. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  102. agno/knowledge/embedder/langdb.py +22 -0
  103. agno/knowledge/embedder/mistral.py +139 -0
  104. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  105. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  106. agno/knowledge/embedder/openai.py +223 -0
  107. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  108. agno/{embedder → knowledge/embedder}/together.py +1 -1
  109. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  110. agno/knowledge/knowledge.py +1515 -0
  111. agno/knowledge/reader/__init__.py +7 -0
  112. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  113. agno/knowledge/reader/base.py +88 -0
  114. agno/{document → knowledge}/reader/csv_reader.py +68 -15
  115. agno/knowledge/reader/docx_reader.py +83 -0
  116. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  117. agno/knowledge/reader/gcs_reader.py +67 -0
  118. agno/{document → knowledge}/reader/json_reader.py +30 -9
  119. agno/{document → knowledge}/reader/markdown_reader.py +36 -9
  120. agno/{document → knowledge}/reader/pdf_reader.py +79 -21
  121. agno/knowledge/reader/reader_factory.py +275 -0
  122. agno/knowledge/reader/s3_reader.py +171 -0
  123. agno/{document → knowledge}/reader/text_reader.py +31 -10
  124. agno/knowledge/reader/url_reader.py +84 -0
  125. agno/knowledge/reader/web_search_reader.py +389 -0
  126. agno/{document → knowledge}/reader/website_reader.py +37 -10
  127. agno/knowledge/reader/wikipedia_reader.py +59 -0
  128. agno/knowledge/reader/youtube_reader.py +78 -0
  129. agno/knowledge/remote_content/remote_content.py +88 -0
  130. agno/{reranker → knowledge/reranker}/base.py +1 -1
  131. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  132. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  133. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  134. agno/knowledge/types.py +30 -0
  135. agno/knowledge/utils.py +169 -0
  136. agno/memory/__init__.py +2 -10
  137. agno/memory/manager.py +1003 -148
  138. agno/models/aimlapi/__init__.py +2 -2
  139. agno/models/aimlapi/aimlapi.py +6 -6
  140. agno/models/anthropic/claude.py +131 -131
  141. agno/models/aws/bedrock.py +107 -175
  142. agno/models/aws/claude.py +64 -18
  143. agno/models/azure/ai_foundry.py +73 -23
  144. agno/models/base.py +347 -287
  145. agno/models/cerebras/cerebras.py +84 -27
  146. agno/models/cohere/chat.py +106 -98
  147. agno/models/google/gemini.py +100 -42
  148. agno/models/groq/groq.py +97 -35
  149. agno/models/huggingface/huggingface.py +92 -27
  150. agno/models/ibm/watsonx.py +72 -13
  151. agno/models/litellm/chat.py +85 -13
  152. agno/models/message.py +45 -150
  153. agno/models/meta/llama.py +85 -49
  154. agno/models/metrics.py +120 -0
  155. agno/models/mistral/mistral.py +90 -21
  156. agno/models/ollama/__init__.py +0 -2
  157. agno/models/ollama/chat.py +84 -46
  158. agno/models/openai/chat.py +121 -23
  159. agno/models/openai/responses.py +178 -105
  160. agno/models/perplexity/perplexity.py +26 -2
  161. agno/models/portkey/portkey.py +0 -7
  162. agno/models/response.py +14 -8
  163. agno/models/utils.py +20 -0
  164. agno/models/vercel/__init__.py +2 -2
  165. agno/models/vercel/v0.py +1 -1
  166. agno/models/vllm/__init__.py +2 -2
  167. agno/models/vllm/vllm.py +3 -3
  168. agno/models/xai/xai.py +10 -10
  169. agno/os/__init__.py +3 -0
  170. agno/os/app.py +489 -0
  171. agno/os/auth.py +47 -0
  172. agno/os/config.py +103 -0
  173. agno/os/interfaces/agui/__init__.py +3 -0
  174. agno/os/interfaces/agui/agui.py +31 -0
  175. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  176. agno/{app → os/interfaces}/agui/utils.py +77 -33
  177. agno/os/interfaces/base.py +21 -0
  178. agno/os/interfaces/slack/__init__.py +3 -0
  179. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  180. agno/os/interfaces/slack/slack.py +32 -0
  181. agno/os/interfaces/whatsapp/__init__.py +3 -0
  182. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  183. agno/os/interfaces/whatsapp/whatsapp.py +29 -0
  184. agno/os/mcp.py +255 -0
  185. agno/os/router.py +869 -0
  186. agno/os/routers/__init__.py +3 -0
  187. agno/os/routers/evals/__init__.py +3 -0
  188. agno/os/routers/evals/evals.py +208 -0
  189. agno/os/routers/evals/schemas.py +142 -0
  190. agno/os/routers/evals/utils.py +161 -0
  191. agno/os/routers/knowledge/__init__.py +3 -0
  192. agno/os/routers/knowledge/knowledge.py +436 -0
  193. agno/os/routers/knowledge/schemas.py +118 -0
  194. agno/os/routers/memory/__init__.py +3 -0
  195. agno/os/routers/memory/memory.py +188 -0
  196. agno/os/routers/memory/schemas.py +58 -0
  197. agno/os/routers/metrics/__init__.py +3 -0
  198. agno/os/routers/metrics/metrics.py +60 -0
  199. agno/os/routers/metrics/schemas.py +47 -0
  200. agno/os/routers/session/__init__.py +3 -0
  201. agno/os/routers/session/session.py +168 -0
  202. agno/os/schema.py +892 -0
  203. agno/{app/playground → os}/settings.py +7 -15
  204. agno/os/utils.py +270 -0
  205. agno/reasoning/azure_ai_foundry.py +4 -4
  206. agno/reasoning/deepseek.py +4 -4
  207. agno/reasoning/default.py +6 -11
  208. agno/reasoning/groq.py +4 -4
  209. agno/reasoning/helpers.py +4 -6
  210. agno/reasoning/ollama.py +4 -4
  211. agno/reasoning/openai.py +4 -4
  212. agno/run/{response.py → agent.py} +231 -74
  213. agno/run/base.py +44 -58
  214. agno/run/cancel.py +81 -0
  215. agno/run/team.py +133 -77
  216. agno/run/workflow.py +537 -12
  217. agno/session/__init__.py +10 -0
  218. agno/session/agent.py +244 -0
  219. agno/session/summary.py +225 -0
  220. agno/session/team.py +262 -0
  221. agno/{storage/session/v2 → session}/workflow.py +47 -24
  222. agno/team/__init__.py +15 -16
  223. agno/team/team.py +2960 -4252
  224. agno/tools/agentql.py +14 -5
  225. agno/tools/airflow.py +9 -4
  226. agno/tools/api.py +7 -3
  227. agno/tools/apify.py +2 -46
  228. agno/tools/arxiv.py +8 -3
  229. agno/tools/aws_lambda.py +7 -5
  230. agno/tools/aws_ses.py +7 -1
  231. agno/tools/baidusearch.py +4 -1
  232. agno/tools/bitbucket.py +4 -4
  233. agno/tools/brandfetch.py +14 -11
  234. agno/tools/bravesearch.py +4 -1
  235. agno/tools/brightdata.py +42 -22
  236. agno/tools/browserbase.py +13 -4
  237. agno/tools/calcom.py +12 -10
  238. agno/tools/calculator.py +10 -27
  239. agno/tools/cartesia.py +18 -13
  240. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  241. agno/tools/confluence.py +8 -8
  242. agno/tools/crawl4ai.py +7 -1
  243. agno/tools/csv_toolkit.py +9 -8
  244. agno/tools/dalle.py +18 -11
  245. agno/tools/daytona.py +13 -16
  246. agno/tools/decorator.py +6 -3
  247. agno/tools/desi_vocal.py +16 -7
  248. agno/tools/discord.py +11 -8
  249. agno/tools/docker.py +30 -42
  250. agno/tools/duckdb.py +34 -53
  251. agno/tools/duckduckgo.py +8 -7
  252. agno/tools/e2b.py +61 -61
  253. agno/tools/eleven_labs.py +35 -28
  254. agno/tools/email.py +4 -1
  255. agno/tools/evm.py +7 -1
  256. agno/tools/exa.py +19 -14
  257. agno/tools/fal.py +29 -29
  258. agno/tools/file.py +9 -8
  259. agno/tools/financial_datasets.py +25 -44
  260. agno/tools/firecrawl.py +22 -22
  261. agno/tools/function.py +127 -18
  262. agno/tools/giphy.py +22 -10
  263. agno/tools/github.py +48 -126
  264. agno/tools/gmail.py +45 -61
  265. agno/tools/google_bigquery.py +7 -6
  266. agno/tools/google_maps.py +11 -26
  267. agno/tools/googlesearch.py +7 -2
  268. agno/tools/googlesheets.py +21 -17
  269. agno/tools/hackernews.py +9 -5
  270. agno/tools/jina.py +5 -4
  271. agno/tools/jira.py +18 -9
  272. agno/tools/knowledge.py +31 -32
  273. agno/tools/linear.py +19 -34
  274. agno/tools/linkup.py +5 -1
  275. agno/tools/local_file_system.py +8 -5
  276. agno/tools/lumalab.py +31 -19
  277. agno/tools/mem0.py +18 -12
  278. agno/tools/memori.py +14 -10
  279. agno/tools/mlx_transcribe.py +3 -2
  280. agno/tools/models/azure_openai.py +32 -14
  281. agno/tools/models/gemini.py +58 -31
  282. agno/tools/models/groq.py +29 -20
  283. agno/tools/models/nebius.py +27 -11
  284. agno/tools/models_labs.py +39 -15
  285. agno/tools/moviepy_video.py +7 -6
  286. agno/tools/neo4j.py +10 -8
  287. agno/tools/newspaper.py +7 -2
  288. agno/tools/newspaper4k.py +8 -3
  289. agno/tools/openai.py +57 -26
  290. agno/tools/openbb.py +12 -11
  291. agno/tools/opencv.py +62 -46
  292. agno/tools/openweather.py +14 -12
  293. agno/tools/pandas.py +11 -3
  294. agno/tools/postgres.py +4 -12
  295. agno/tools/pubmed.py +4 -1
  296. agno/tools/python.py +9 -22
  297. agno/tools/reasoning.py +35 -27
  298. agno/tools/reddit.py +11 -26
  299. agno/tools/replicate.py +54 -41
  300. agno/tools/resend.py +4 -1
  301. agno/tools/scrapegraph.py +15 -14
  302. agno/tools/searxng.py +10 -23
  303. agno/tools/serpapi.py +6 -3
  304. agno/tools/serper.py +13 -4
  305. agno/tools/shell.py +9 -2
  306. agno/tools/slack.py +12 -11
  307. agno/tools/sleep.py +3 -2
  308. agno/tools/spider.py +24 -4
  309. agno/tools/sql.py +7 -6
  310. agno/tools/tavily.py +6 -4
  311. agno/tools/telegram.py +12 -4
  312. agno/tools/todoist.py +11 -31
  313. agno/tools/toolkit.py +1 -1
  314. agno/tools/trafilatura.py +22 -6
  315. agno/tools/trello.py +9 -22
  316. agno/tools/twilio.py +10 -3
  317. agno/tools/user_control_flow.py +6 -1
  318. agno/tools/valyu.py +34 -5
  319. agno/tools/visualization.py +19 -28
  320. agno/tools/webbrowser.py +4 -3
  321. agno/tools/webex.py +11 -7
  322. agno/tools/website.py +15 -46
  323. agno/tools/webtools.py +12 -4
  324. agno/tools/whatsapp.py +5 -9
  325. agno/tools/wikipedia.py +20 -13
  326. agno/tools/x.py +14 -13
  327. agno/tools/yfinance.py +13 -40
  328. agno/tools/youtube.py +26 -20
  329. agno/tools/zendesk.py +7 -2
  330. agno/tools/zep.py +10 -7
  331. agno/tools/zoom.py +10 -9
  332. agno/utils/common.py +1 -19
  333. agno/utils/events.py +95 -118
  334. agno/utils/gemini.py +31 -1
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/log.py +2 -2
  337. agno/utils/mcp.py +11 -5
  338. agno/utils/media.py +39 -0
  339. agno/utils/message.py +12 -1
  340. agno/utils/models/claude.py +55 -4
  341. agno/utils/models/mistral.py +8 -7
  342. agno/utils/models/schema_utils.py +3 -3
  343. agno/utils/pprint.py +33 -32
  344. agno/utils/print_response/agent.py +779 -0
  345. agno/utils/print_response/team.py +1565 -0
  346. agno/utils/print_response/workflow.py +1451 -0
  347. agno/utils/prompts.py +14 -14
  348. agno/utils/reasoning.py +87 -0
  349. agno/utils/response.py +42 -42
  350. agno/utils/streamlit.py +454 -0
  351. agno/utils/string.py +8 -22
  352. agno/utils/team.py +50 -0
  353. agno/utils/timer.py +2 -2
  354. agno/vectordb/base.py +33 -21
  355. agno/vectordb/cassandra/cassandra.py +287 -23
  356. agno/vectordb/chroma/chromadb.py +482 -59
  357. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  358. agno/vectordb/couchbase/couchbase.py +309 -29
  359. agno/vectordb/lancedb/lance_db.py +360 -21
  360. agno/vectordb/langchaindb/__init__.py +5 -0
  361. agno/vectordb/langchaindb/langchaindb.py +145 -0
  362. agno/vectordb/lightrag/__init__.py +5 -0
  363. agno/vectordb/lightrag/lightrag.py +374 -0
  364. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  365. agno/vectordb/milvus/milvus.py +242 -32
  366. agno/vectordb/mongodb/mongodb.py +200 -24
  367. agno/vectordb/pgvector/pgvector.py +319 -37
  368. agno/vectordb/pineconedb/pineconedb.py +221 -27
  369. agno/vectordb/qdrant/qdrant.py +334 -14
  370. agno/vectordb/singlestore/singlestore.py +286 -29
  371. agno/vectordb/surrealdb/surrealdb.py +187 -7
  372. agno/vectordb/upstashdb/upstashdb.py +342 -26
  373. agno/vectordb/weaviate/weaviate.py +227 -165
  374. agno/workflow/__init__.py +17 -13
  375. agno/workflow/{v2/condition.py → condition.py} +135 -32
  376. agno/workflow/{v2/loop.py → loop.py} +115 -28
  377. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  378. agno/workflow/{v2/router.py → router.py} +133 -32
  379. agno/workflow/{v2/step.py → step.py} +200 -42
  380. agno/workflow/{v2/steps.py → steps.py} +147 -66
  381. agno/workflow/types.py +482 -0
  382. agno/workflow/workflow.py +2401 -696
  383. agno-2.0.0rc1.dist-info/METADATA +355 -0
  384. agno-2.0.0rc1.dist-info/RECORD +516 -0
  385. agno/agent/metrics.py +0 -107
  386. agno/api/app.py +0 -35
  387. agno/api/playground.py +0 -92
  388. agno/api/schemas/app.py +0 -12
  389. agno/api/schemas/playground.py +0 -22
  390. agno/api/schemas/user.py +0 -35
  391. agno/api/schemas/workspace.py +0 -46
  392. agno/api/user.py +0 -160
  393. agno/api/workflows.py +0 -33
  394. agno/api/workspace.py +0 -175
  395. agno/app/agui/__init__.py +0 -3
  396. agno/app/agui/app.py +0 -17
  397. agno/app/agui/sync_router.py +0 -120
  398. agno/app/base.py +0 -186
  399. agno/app/discord/__init__.py +0 -3
  400. agno/app/fastapi/__init__.py +0 -3
  401. agno/app/fastapi/app.py +0 -107
  402. agno/app/fastapi/async_router.py +0 -457
  403. agno/app/fastapi/sync_router.py +0 -448
  404. agno/app/playground/app.py +0 -228
  405. agno/app/playground/async_router.py +0 -1050
  406. agno/app/playground/deploy.py +0 -249
  407. agno/app/playground/operator.py +0 -183
  408. agno/app/playground/schemas.py +0 -220
  409. agno/app/playground/serve.py +0 -55
  410. agno/app/playground/sync_router.py +0 -1042
  411. agno/app/playground/utils.py +0 -46
  412. agno/app/settings.py +0 -15
  413. agno/app/slack/__init__.py +0 -3
  414. agno/app/slack/app.py +0 -19
  415. agno/app/slack/sync_router.py +0 -92
  416. agno/app/utils.py +0 -54
  417. agno/app/whatsapp/__init__.py +0 -3
  418. agno/app/whatsapp/app.py +0 -15
  419. agno/app/whatsapp/sync_router.py +0 -197
  420. agno/cli/auth_server.py +0 -249
  421. agno/cli/config.py +0 -274
  422. agno/cli/console.py +0 -88
  423. agno/cli/credentials.py +0 -23
  424. agno/cli/entrypoint.py +0 -571
  425. agno/cli/operator.py +0 -357
  426. agno/cli/settings.py +0 -96
  427. agno/cli/ws/ws_cli.py +0 -817
  428. agno/constants.py +0 -13
  429. agno/document/__init__.py +0 -5
  430. agno/document/chunking/semantic.py +0 -45
  431. agno/document/chunking/strategy.py +0 -31
  432. agno/document/reader/__init__.py +0 -5
  433. agno/document/reader/base.py +0 -47
  434. agno/document/reader/docx_reader.py +0 -60
  435. agno/document/reader/gcs/pdf_reader.py +0 -44
  436. agno/document/reader/s3/pdf_reader.py +0 -59
  437. agno/document/reader/s3/text_reader.py +0 -63
  438. agno/document/reader/url_reader.py +0 -59
  439. agno/document/reader/youtube_reader.py +0 -58
  440. agno/embedder/__init__.py +0 -5
  441. agno/embedder/langdb.py +0 -80
  442. agno/embedder/mistral.py +0 -82
  443. agno/embedder/openai.py +0 -78
  444. agno/file/__init__.py +0 -5
  445. agno/file/file.py +0 -16
  446. agno/file/local/csv.py +0 -32
  447. agno/file/local/txt.py +0 -19
  448. agno/infra/app.py +0 -240
  449. agno/infra/base.py +0 -144
  450. agno/infra/context.py +0 -20
  451. agno/infra/db_app.py +0 -52
  452. agno/infra/resource.py +0 -205
  453. agno/infra/resources.py +0 -55
  454. agno/knowledge/agent.py +0 -702
  455. agno/knowledge/arxiv.py +0 -33
  456. agno/knowledge/combined.py +0 -36
  457. agno/knowledge/csv.py +0 -144
  458. agno/knowledge/csv_url.py +0 -124
  459. agno/knowledge/document.py +0 -223
  460. agno/knowledge/docx.py +0 -137
  461. agno/knowledge/firecrawl.py +0 -34
  462. agno/knowledge/gcs/__init__.py +0 -0
  463. agno/knowledge/gcs/base.py +0 -39
  464. agno/knowledge/gcs/pdf.py +0 -125
  465. agno/knowledge/json.py +0 -137
  466. agno/knowledge/langchain.py +0 -71
  467. agno/knowledge/light_rag.py +0 -273
  468. agno/knowledge/llamaindex.py +0 -66
  469. agno/knowledge/markdown.py +0 -154
  470. agno/knowledge/pdf.py +0 -164
  471. agno/knowledge/pdf_bytes.py +0 -42
  472. agno/knowledge/pdf_url.py +0 -148
  473. agno/knowledge/s3/__init__.py +0 -0
  474. agno/knowledge/s3/base.py +0 -64
  475. agno/knowledge/s3/pdf.py +0 -33
  476. agno/knowledge/s3/text.py +0 -34
  477. agno/knowledge/text.py +0 -141
  478. agno/knowledge/url.py +0 -46
  479. agno/knowledge/website.py +0 -179
  480. agno/knowledge/wikipedia.py +0 -32
  481. agno/knowledge/youtube.py +0 -35
  482. agno/memory/agent.py +0 -423
  483. agno/memory/classifier.py +0 -104
  484. agno/memory/db/__init__.py +0 -5
  485. agno/memory/db/base.py +0 -42
  486. agno/memory/db/mongodb.py +0 -189
  487. agno/memory/db/postgres.py +0 -203
  488. agno/memory/db/sqlite.py +0 -193
  489. agno/memory/memory.py +0 -22
  490. agno/memory/row.py +0 -36
  491. agno/memory/summarizer.py +0 -201
  492. agno/memory/summary.py +0 -19
  493. agno/memory/team.py +0 -415
  494. agno/memory/v2/__init__.py +0 -2
  495. agno/memory/v2/db/__init__.py +0 -1
  496. agno/memory/v2/db/base.py +0 -42
  497. agno/memory/v2/db/firestore.py +0 -339
  498. agno/memory/v2/db/mongodb.py +0 -196
  499. agno/memory/v2/db/postgres.py +0 -214
  500. agno/memory/v2/db/redis.py +0 -187
  501. agno/memory/v2/db/schema.py +0 -54
  502. agno/memory/v2/db/sqlite.py +0 -209
  503. agno/memory/v2/manager.py +0 -437
  504. agno/memory/v2/memory.py +0 -1097
  505. agno/memory/v2/schema.py +0 -55
  506. agno/memory/v2/summarizer.py +0 -215
  507. agno/memory/workflow.py +0 -38
  508. agno/models/ollama/tools.py +0 -430
  509. agno/models/qwen/__init__.py +0 -5
  510. agno/playground/__init__.py +0 -10
  511. agno/playground/deploy.py +0 -3
  512. agno/playground/playground.py +0 -3
  513. agno/playground/serve.py +0 -3
  514. agno/playground/settings.py +0 -3
  515. agno/reranker/__init__.py +0 -0
  516. agno/run/v2/__init__.py +0 -0
  517. agno/run/v2/workflow.py +0 -567
  518. agno/storage/__init__.py +0 -0
  519. agno/storage/agent/__init__.py +0 -0
  520. agno/storage/agent/dynamodb.py +0 -1
  521. agno/storage/agent/json.py +0 -1
  522. agno/storage/agent/mongodb.py +0 -1
  523. agno/storage/agent/postgres.py +0 -1
  524. agno/storage/agent/singlestore.py +0 -1
  525. agno/storage/agent/sqlite.py +0 -1
  526. agno/storage/agent/yaml.py +0 -1
  527. agno/storage/base.py +0 -60
  528. agno/storage/dynamodb.py +0 -673
  529. agno/storage/firestore.py +0 -297
  530. agno/storage/gcs_json.py +0 -261
  531. agno/storage/in_memory.py +0 -234
  532. agno/storage/json.py +0 -237
  533. agno/storage/mongodb.py +0 -328
  534. agno/storage/mysql.py +0 -685
  535. agno/storage/postgres.py +0 -682
  536. agno/storage/redis.py +0 -336
  537. agno/storage/session/__init__.py +0 -16
  538. agno/storage/session/agent.py +0 -64
  539. agno/storage/session/team.py +0 -63
  540. agno/storage/session/v2/__init__.py +0 -5
  541. agno/storage/session/workflow.py +0 -61
  542. agno/storage/singlestore.py +0 -606
  543. agno/storage/sqlite.py +0 -646
  544. agno/storage/workflow/__init__.py +0 -0
  545. agno/storage/workflow/mongodb.py +0 -1
  546. agno/storage/workflow/postgres.py +0 -1
  547. agno/storage/workflow/sqlite.py +0 -1
  548. agno/storage/yaml.py +0 -241
  549. agno/tools/thinking.py +0 -73
  550. agno/utils/defaults.py +0 -57
  551. agno/utils/filesystem.py +0 -39
  552. agno/utils/git.py +0 -52
  553. agno/utils/json_io.py +0 -30
  554. agno/utils/load_env.py +0 -19
  555. agno/utils/py_io.py +0 -19
  556. agno/utils/pyproject.py +0 -18
  557. agno/utils/resource_filter.py +0 -31
  558. agno/workflow/v2/__init__.py +0 -21
  559. agno/workflow/v2/types.py +0 -357
  560. agno/workflow/v2/workflow.py +0 -3312
  561. agno/workspace/__init__.py +0 -0
  562. agno/workspace/config.py +0 -325
  563. agno/workspace/enums.py +0 -6
  564. agno/workspace/helpers.py +0 -52
  565. agno/workspace/operator.py +0 -757
  566. agno/workspace/settings.py +0 -158
  567. agno-1.8.1.dist-info/METADATA +0 -982
  568. agno-1.8.1.dist-info/RECORD +0 -566
  569. agno-1.8.1.dist-info/entry_points.txt +0 -3
  570. /agno/{app → db/migrations}/__init__.py +0 -0
  571. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  572. /agno/{cli → integrations}/__init__.py +0 -0
  573. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  574. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  575. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  576. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  577. /agno/{app → os/interfaces}/slack/security.py +0 -0
  578. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  579. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  580. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  581. {agno-1.8.1.dist-info → agno-2.0.0rc1.dist-info}/WHEEL +0 -0
  582. {agno-1.8.1.dist-info → agno-2.0.0rc1.dist-info}/licenses/LICENSE +0 -0
  583. {agno-1.8.1.dist-info → agno-2.0.0rc1.dist-info}/top_level.txt +0 -0
agno/models/xai/xai.py CHANGED
@@ -65,7 +65,7 @@ class xAI(OpenAILike):
65
65
 
66
66
  return request_params
67
67
 
68
- def parse_provider_response(
68
+ def _parse_provider_response(
69
69
  self,
70
70
  response: ChatCompletion,
71
71
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
@@ -73,21 +73,21 @@ class xAI(OpenAILike):
73
73
  """
74
74
  Parse the xAI response into a ModelResponse.
75
75
  """
76
- model_response = super().parse_provider_response(response, response_format)
76
+ model_response = super()._parse_provider_response(response, response_format)
77
77
 
78
- if hasattr(response, "citations") and response.citations:
78
+ if hasattr(response, "citations") and response.citations: # type: ignore
79
79
  citations = Citations()
80
80
  url_citations = []
81
- for citation_url in response.citations:
81
+ for citation_url in response.citations: # type: ignore
82
82
  url_citations.append(UrlCitation(url=str(citation_url)))
83
83
 
84
84
  citations.urls = url_citations
85
- citations.raw = response.citations
85
+ citations.raw = response.citations # type: ignore
86
86
  model_response.citations = citations
87
87
 
88
88
  return model_response
89
89
 
90
- def parse_provider_response_delta(self, response_delta: ChatCompletionChunk) -> ModelResponse:
90
+ def _parse_provider_response_delta(self, response_delta: ChatCompletionChunk) -> ModelResponse:
91
91
  """
92
92
  Parse the xAI streaming response.
93
93
 
@@ -97,16 +97,16 @@ class xAI(OpenAILike):
97
97
  Returns:
98
98
  ModelResponse: Parsed response data
99
99
  """
100
- model_response = super().parse_provider_response_delta(response_delta)
100
+ model_response = super()._parse_provider_response_delta(response_delta)
101
101
 
102
- if hasattr(response_delta, "citations") and response_delta.citations:
102
+ if hasattr(response_delta, "citations") and response_delta.citations: # type: ignore
103
103
  citations = Citations()
104
104
  url_citations = []
105
- for citation_url in response_delta.citations:
105
+ for citation_url in response_delta.citations: # type: ignore
106
106
  url_citations.append(UrlCitation(url=str(citation_url)))
107
107
 
108
108
  citations.urls = url_citations
109
- citations.raw = response_delta.citations
109
+ citations.raw = response_delta.citations # type: ignore
110
110
  model_response.citations = citations
111
111
 
112
112
  return model_response
agno/os/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from agno.os.app import AgentOS
2
+
3
+ __all__ = ["AgentOS"]
agno/os/app.py ADDED
@@ -0,0 +1,489 @@
1
+ from contextlib import asynccontextmanager
2
+ from functools import partial
3
+ from os import getenv
4
+ from typing import Any, Dict, List, Optional, Union
5
+ from uuid import uuid4
6
+
7
+ from fastapi import FastAPI, HTTPException
8
+ from fastapi.responses import JSONResponse
9
+ from rich import box
10
+ from rich.panel import Panel
11
+ from starlette.middleware.cors import CORSMiddleware
12
+ from starlette.requests import Request
13
+
14
+ from agno.agent.agent import Agent
15
+ from agno.os.config import (
16
+ AgentOSConfig,
17
+ DatabaseConfig,
18
+ EvalsConfig,
19
+ EvalsDomainConfig,
20
+ KnowledgeConfig,
21
+ KnowledgeDomainConfig,
22
+ MemoryConfig,
23
+ MemoryDomainConfig,
24
+ MetricsConfig,
25
+ MetricsDomainConfig,
26
+ SessionConfig,
27
+ SessionDomainConfig,
28
+ )
29
+ from agno.os.interfaces.base import BaseInterface
30
+ from agno.os.router import get_base_router
31
+ from agno.os.routers.evals import get_eval_router
32
+ from agno.os.routers.knowledge import get_knowledge_router
33
+ from agno.os.routers.memory import get_memory_router
34
+ from agno.os.routers.metrics import get_metrics_router
35
+ from agno.os.routers.session import get_session_router
36
+ from agno.os.settings import AgnoAPISettings
37
+ from agno.os.utils import generate_id
38
+ from agno.team.team import Team
39
+ from agno.tools.mcp import MCPTools, MultiMCPTools
40
+ from agno.workflow.workflow import Workflow
41
+
42
+
43
+ @asynccontextmanager
44
+ async def mcp_lifespan(app, mcp_tools: List[Union[MCPTools, MultiMCPTools]]):
45
+ """Manage MCP connection lifecycle inside a FastAPI app"""
46
+ # Startup logic: connect to all contextual MCP servers
47
+ for tool in mcp_tools:
48
+ await tool.connect()
49
+
50
+ yield
51
+
52
+ # Shutdown logic: Close all contextual MCP connections
53
+ for tool in mcp_tools:
54
+ await tool.close()
55
+
56
+
57
+ class AgentOS:
58
+ def __init__(
59
+ self,
60
+ os_id: Optional[str] = None,
61
+ name: Optional[str] = None,
62
+ description: Optional[str] = None,
63
+ version: Optional[str] = None,
64
+ agents: Optional[List[Agent]] = None,
65
+ teams: Optional[List[Team]] = None,
66
+ workflows: Optional[List[Workflow]] = None,
67
+ interfaces: Optional[List[BaseInterface]] = None,
68
+ config: Optional[Union[str, AgentOSConfig]] = None,
69
+ settings: Optional[AgnoAPISettings] = None,
70
+ fastapi_app: Optional[FastAPI] = None,
71
+ lifespan: Optional[Any] = None,
72
+ enable_mcp: bool = False,
73
+ telemetry: bool = True,
74
+ ):
75
+ if not agents and not workflows and not teams:
76
+ raise ValueError("Either agents, teams or workflows must be provided.")
77
+
78
+ self.config = self._load_yaml_config(config) if isinstance(config, str) else config
79
+
80
+ self.agents: Optional[List[Agent]] = agents
81
+ self.workflows: Optional[List[Workflow]] = workflows
82
+ self.teams: Optional[List[Team]] = teams
83
+ self.interfaces = interfaces or []
84
+
85
+ self.settings: AgnoAPISettings = settings or AgnoAPISettings()
86
+ self.fastapi_app: Optional[FastAPI] = fastapi_app
87
+
88
+ self.interfaces = interfaces or []
89
+
90
+ self.os_id: Optional[str] = os_id
91
+ self.name = name
92
+ self.version = version
93
+ self.description = description
94
+
95
+ self.telemetry = telemetry
96
+
97
+ self.enable_mcp = enable_mcp
98
+ self.lifespan = lifespan
99
+
100
+ # List of all MCP tools used inside the AgentOS
101
+ self.mcp_tools: List[Union[MCPTools, MultiMCPTools]] = []
102
+
103
+ if self.agents:
104
+ for agent in self.agents:
105
+ # Track all MCP tools to later handle their connection
106
+ if agent.tools:
107
+ for tool in agent.tools:
108
+ if isinstance(tool, MCPTools) or isinstance(tool, MultiMCPTools):
109
+ self.mcp_tools.append(tool)
110
+
111
+ agent.initialize_agent()
112
+
113
+ # Required for the built-in routes to work
114
+ agent.store_events = True
115
+
116
+ if self.teams:
117
+ for team in self.teams:
118
+ # Track all MCP tools to later handle their connection
119
+ if team.tools:
120
+ for tool in team.tools:
121
+ if isinstance(tool, MCPTools) or isinstance(tool, MultiMCPTools):
122
+ self.mcp_tools.append(tool)
123
+
124
+ team.initialize_team()
125
+
126
+ # Required for the built-in routes to work
127
+ team.store_events = True
128
+
129
+ for member in team.members:
130
+ if isinstance(member, Agent):
131
+ member.team_id = None
132
+ member.initialize_agent()
133
+ elif isinstance(member, Team):
134
+ member.initialize_team()
135
+
136
+ if self.workflows:
137
+ for workflow in self.workflows:
138
+ # TODO: track MCP tools in workflow members
139
+ if not workflow.id:
140
+ workflow.id = generate_id(workflow.name)
141
+
142
+ if self.telemetry:
143
+ from agno.api.os import OSLaunch, log_os_telemetry
144
+
145
+ log_os_telemetry(launch=OSLaunch(os_id=self.os_id, data=self._get_telemetry_data()))
146
+
147
+ def _make_app(self, lifespan: Optional[Any] = None) -> FastAPI:
148
+ # Adjust the FastAPI app lifespan to handle MCP connections if relevant
149
+ app_lifespan = lifespan
150
+ if self.mcp_tools is not None:
151
+ mcp_tools_lifespan = partial(mcp_lifespan, mcp_tools=self.mcp_tools)
152
+ # If there is already a lifespan, combine it with the MCP lifespan
153
+ if lifespan is not None:
154
+ # Combine both lifespans
155
+ @asynccontextmanager
156
+ async def combined_lifespan(app: FastAPI):
157
+ # Run both lifespans
158
+ async with lifespan(app): # type: ignore
159
+ async with mcp_tools_lifespan(app): # type: ignore
160
+ yield
161
+
162
+ app_lifespan = combined_lifespan # type: ignore
163
+ else:
164
+ app_lifespan = mcp_tools_lifespan
165
+
166
+ return FastAPI(
167
+ title=self.name or "Agno AgentOS",
168
+ version=self.version or "1.0.0",
169
+ description=self.description or "An agent operating system.",
170
+ docs_url="/docs" if self.settings.docs_enabled else None,
171
+ redoc_url="/redoc" if self.settings.docs_enabled else None,
172
+ openapi_url="/openapi.json" if self.settings.docs_enabled else None,
173
+ lifespan=app_lifespan,
174
+ )
175
+
176
+ def get_app(self) -> FastAPI:
177
+ if not self.fastapi_app:
178
+ if self.enable_mcp:
179
+ from contextlib import asynccontextmanager
180
+
181
+ from agno.os.mcp import get_mcp_server
182
+
183
+ self.mcp_app = get_mcp_server(self)
184
+
185
+ final_lifespan = self.mcp_app.lifespan
186
+ if self.lifespan is not None:
187
+ # Combine both lifespans
188
+ @asynccontextmanager
189
+ async def combined_lifespan(app: FastAPI):
190
+ # Run both lifespans
191
+ async with self.lifespan(app): # type: ignore
192
+ async with self.mcp_app.lifespan(app): # type: ignore
193
+ yield
194
+
195
+ final_lifespan = combined_lifespan # type: ignore
196
+
197
+ self.fastapi_app = self._make_app(lifespan=final_lifespan)
198
+ else:
199
+ self.fastapi_app = self._make_app(lifespan=self.lifespan)
200
+
201
+ # Add routes
202
+ self.fastapi_app.include_router(get_base_router(self, settings=self.settings))
203
+
204
+ for interface in self.interfaces:
205
+ interface_router = interface.get_router()
206
+ self.fastapi_app.include_router(interface_router)
207
+
208
+ self._auto_discover_databases()
209
+ self._auto_discover_knowledge_instances()
210
+ self._setup_routers()
211
+
212
+ # Mount MCP if needed
213
+ if self.enable_mcp and self.mcp_app:
214
+ self.fastapi_app.mount("/", self.mcp_app)
215
+
216
+ # Add middleware
217
+ @self.fastapi_app.exception_handler(HTTPException)
218
+ async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
219
+ return JSONResponse(
220
+ status_code=exc.status_code,
221
+ content={"detail": str(exc.detail)},
222
+ )
223
+
224
+ async def general_exception_handler(request: Request, call_next):
225
+ try:
226
+ return await call_next(request)
227
+ except Exception as e:
228
+ return JSONResponse(
229
+ status_code=e.status_code if hasattr(e, "status_code") else 500, # type: ignore
230
+ content={"detail": str(e)},
231
+ )
232
+
233
+ self.fastapi_app.middleware("http")(general_exception_handler)
234
+
235
+ self.fastapi_app.add_middleware(
236
+ CORSMiddleware,
237
+ allow_origins=self.settings.cors_origin_list, # type: ignore
238
+ allow_credentials=True,
239
+ allow_methods=["*"],
240
+ allow_headers=["*"],
241
+ expose_headers=["*"],
242
+ )
243
+
244
+ return self.fastapi_app
245
+
246
+ def get_routes(self) -> List[Any]:
247
+ """Retrieve all routes from the FastAPI app.
248
+
249
+ Returns:
250
+ List[Any]: List of routes included in the FastAPI app.
251
+ """
252
+ app = self.get_app()
253
+
254
+ return app.routes
255
+
256
+ def _get_telemetry_data(self) -> Dict[str, Any]:
257
+ """Get the telemetry data for the OS"""
258
+ return {
259
+ "agents": [agent.id for agent in self.agents] if self.agents else None,
260
+ "teams": [team.id for team in self.teams] if self.teams else None,
261
+ "workflows": [workflow.id for workflow in self.workflows] if self.workflows else None,
262
+ "interfaces": [interface.type for interface in self.interfaces] if self.interfaces else None,
263
+ }
264
+
265
+ def _load_yaml_config(self, config_file_path: str) -> AgentOSConfig:
266
+ """Load a YAML config file and return the configuration as an AgentOSConfig instance."""
267
+ from pathlib import Path
268
+
269
+ import yaml
270
+
271
+ # Validate that the path points to a YAML file
272
+ path = Path(config_file_path)
273
+ if path.suffix.lower() not in [".yaml", ".yml"]:
274
+ raise ValueError(f"Config file must have a .yaml or .yml extension, got: {config_file_path}")
275
+
276
+ # Load the YAML file
277
+ with open(config_file_path, "r") as f:
278
+ return AgentOSConfig.model_validate(yaml.safe_load(f))
279
+
280
+ def _auto_discover_databases(self) -> None:
281
+ """Auto-discover the databases used by all contextual agents, teams and workflows."""
282
+ dbs = {}
283
+
284
+ for agent in self.agents or []:
285
+ if agent.db:
286
+ dbs[agent.db.id] = agent.db
287
+ if agent.knowledge and agent.knowledge.contents_db:
288
+ dbs[agent.knowledge.contents_db.id] = agent.knowledge.contents_db
289
+
290
+ for team in self.teams or []:
291
+ if team.db:
292
+ dbs[team.db.id] = team.db
293
+ if team.knowledge and team.knowledge.contents_db:
294
+ dbs[team.knowledge.contents_db.id] = team.knowledge.contents_db
295
+
296
+ for workflow in self.workflows or []:
297
+ if workflow.db:
298
+ dbs[workflow.db.id] = workflow.db
299
+
300
+ for interface in self.interfaces or []:
301
+ if interface.agent and interface.agent.db:
302
+ dbs[interface.agent.db.id] = interface.agent.db
303
+ elif interface.team and interface.team.db:
304
+ dbs[interface.team.db.id] = interface.team.db
305
+
306
+ self.dbs = dbs
307
+
308
+ def _auto_discover_knowledge_instances(self) -> None:
309
+ """Auto-discover the knowledge instances used by all contextual agents, teams and workflows."""
310
+ knowledge_instances = []
311
+ for agent in self.agents or []:
312
+ if agent.knowledge:
313
+ knowledge_instances.append(agent.knowledge)
314
+
315
+ for team in self.teams or []:
316
+ if team.knowledge:
317
+ knowledge_instances.append(team.knowledge)
318
+
319
+ self.knowledge_instances = knowledge_instances
320
+
321
+ def _get_session_config(self) -> SessionConfig:
322
+ session_config = self.config.session if self.config and self.config.session else SessionConfig()
323
+
324
+ if session_config.dbs is None:
325
+ session_config.dbs = []
326
+
327
+ multiple_dbs: bool = len(self.dbs.keys()) > 1
328
+ dbs_with_specific_config = [db.db_id for db in session_config.dbs]
329
+
330
+ for db_id in self.dbs.keys():
331
+ if db_id not in dbs_with_specific_config:
332
+ session_config.dbs.append(
333
+ DatabaseConfig(
334
+ db_id=db_id,
335
+ domain_config=SessionDomainConfig(
336
+ display_name="Sessions" if not multiple_dbs else "Sessions in database '" + db_id + "'"
337
+ ),
338
+ )
339
+ )
340
+
341
+ return session_config
342
+
343
+ def _get_memory_config(self) -> MemoryConfig:
344
+ memory_config = self.config.memory if self.config and self.config.memory else MemoryConfig()
345
+
346
+ if memory_config.dbs is None:
347
+ memory_config.dbs = []
348
+
349
+ multiple_dbs: bool = len(self.dbs.keys()) > 1
350
+ dbs_with_specific_config = [db.db_id for db in memory_config.dbs]
351
+
352
+ for db_id in self.dbs.keys():
353
+ if db_id not in dbs_with_specific_config:
354
+ memory_config.dbs.append(
355
+ DatabaseConfig(
356
+ db_id=db_id,
357
+ domain_config=MemoryDomainConfig(
358
+ display_name="Memory" if not multiple_dbs else "Memory in database '" + db_id + "'"
359
+ ),
360
+ )
361
+ )
362
+
363
+ return memory_config
364
+
365
+ def _get_knowledge_config(self) -> KnowledgeConfig:
366
+ knowledge_config = self.config.knowledge if self.config and self.config.knowledge else KnowledgeConfig()
367
+
368
+ if knowledge_config.dbs is None:
369
+ knowledge_config.dbs = []
370
+
371
+ multiple_dbs: bool = len(self.dbs.keys()) > 1
372
+ dbs_with_specific_config = [db.db_id for db in knowledge_config.dbs]
373
+
374
+ for db_id in self.dbs.keys():
375
+ if db_id not in dbs_with_specific_config:
376
+ knowledge_config.dbs.append(
377
+ DatabaseConfig(
378
+ db_id=db_id,
379
+ domain_config=KnowledgeDomainConfig(
380
+ display_name="Knowledge" if not multiple_dbs else "Knowledge in database " + db_id
381
+ ),
382
+ )
383
+ )
384
+
385
+ return knowledge_config
386
+
387
+ def _get_metrics_config(self) -> MetricsConfig:
388
+ metrics_config = self.config.metrics if self.config and self.config.metrics else MetricsConfig()
389
+
390
+ if metrics_config.dbs is None:
391
+ metrics_config.dbs = []
392
+
393
+ multiple_dbs: bool = len(self.dbs.keys()) > 1
394
+ dbs_with_specific_config = [db.db_id for db in metrics_config.dbs]
395
+
396
+ for db_id in self.dbs.keys():
397
+ if db_id not in dbs_with_specific_config:
398
+ metrics_config.dbs.append(
399
+ DatabaseConfig(
400
+ db_id=db_id,
401
+ domain_config=MetricsDomainConfig(
402
+ display_name="Metrics" if not multiple_dbs else "Metrics in database '" + db_id + "'"
403
+ ),
404
+ )
405
+ )
406
+
407
+ return metrics_config
408
+
409
+ def _get_evals_config(self) -> EvalsConfig:
410
+ evals_config = self.config.evals if self.config and self.config.evals else EvalsConfig()
411
+
412
+ if evals_config.dbs is None:
413
+ evals_config.dbs = []
414
+
415
+ multiple_dbs: bool = len(self.dbs.keys()) > 1
416
+ dbs_with_specific_config = [db.db_id for db in evals_config.dbs]
417
+
418
+ for db_id in self.dbs.keys():
419
+ if db_id not in dbs_with_specific_config:
420
+ evals_config.dbs.append(
421
+ DatabaseConfig(
422
+ db_id=db_id,
423
+ domain_config=EvalsDomainConfig(
424
+ display_name="Evals" if not multiple_dbs else "Evals in database '" + db_id + "'"
425
+ ),
426
+ )
427
+ )
428
+
429
+ return evals_config
430
+
431
+ def _setup_routers(self) -> None:
432
+ """Add all routers to the FastAPI app."""
433
+ if not self.dbs or not self.fastapi_app:
434
+ return
435
+
436
+ routers = [
437
+ get_session_router(dbs=self.dbs),
438
+ get_memory_router(dbs=self.dbs),
439
+ get_eval_router(dbs=self.dbs, agents=self.agents, teams=self.teams),
440
+ get_metrics_router(dbs=self.dbs),
441
+ get_knowledge_router(knowledge_instances=self.knowledge_instances),
442
+ ]
443
+
444
+ for router in routers:
445
+ self.fastapi_app.include_router(router)
446
+
447
+ def set_os_id(self) -> str:
448
+ # If os_id is already set, keep it instead of overriding with UUID
449
+ if self.os_id is None:
450
+ self.os_id = str(uuid4())
451
+
452
+ return self.os_id
453
+
454
+ def serve(
455
+ self,
456
+ app: Union[str, FastAPI],
457
+ *,
458
+ host: str = "localhost",
459
+ port: int = 7777,
460
+ reload: bool = False,
461
+ **kwargs,
462
+ ):
463
+ import uvicorn
464
+
465
+ if getenv("AGNO_API_RUNTIME", "").lower() == "stg":
466
+ public_endpoint = "https://os-stg.agno.com/"
467
+ else:
468
+ public_endpoint = "https://os.agno.com/"
469
+
470
+ # Create a terminal panel to announce OS initialization and provide useful info
471
+ from rich.align import Align
472
+ from rich.console import Console, Group
473
+
474
+ aligned_endpoint = Align.center(f"[bold cyan]{public_endpoint}[/bold cyan]")
475
+ connection_endpoint = f"\n\n[bold dark_orange]Running on:[/bold dark_orange] http://{host}:{port}"
476
+
477
+ console = Console()
478
+ console.print(
479
+ Panel(
480
+ Group(aligned_endpoint, connection_endpoint),
481
+ title="AgentOS",
482
+ expand=False,
483
+ border_style="dark_orange",
484
+ box=box.DOUBLE_EDGE,
485
+ padding=(2, 2),
486
+ )
487
+ )
488
+
489
+ uvicorn.run(app=app, host=host, port=port, reload=reload, **kwargs)
agno/os/auth.py ADDED
@@ -0,0 +1,47 @@
1
+ from typing import Optional
2
+
3
+ from fastapi import Header, HTTPException
4
+ from fastapi.security import HTTPBearer
5
+
6
+ from agno.os.settings import AgnoAPISettings
7
+
8
+ # Create a global HTTPBearer instance
9
+ security = HTTPBearer(auto_error=False)
10
+
11
+
12
+ def get_authentication_dependency(settings: AgnoAPISettings):
13
+ """
14
+ Create an authentication dependency function for FastAPI routes.
15
+
16
+ Args:
17
+ settings: The API settings containing the security key
18
+
19
+ Returns:
20
+ A dependency function that can be used with FastAPI's Depends()
21
+ """
22
+
23
+ def auth_dependency(authorization: Optional[str] = Header(None)) -> bool:
24
+ # If no security key is set, skip authentication entirely
25
+ if not settings or not settings.os_security_key:
26
+ return True
27
+
28
+ # If security is enabled but no authorization header provided, fail
29
+ if not authorization:
30
+ raise HTTPException(status_code=401, detail="Authorization header required")
31
+
32
+ # Check if the authorization header starts with "Bearer "
33
+ if not authorization.startswith("Bearer "):
34
+ raise HTTPException(
35
+ status_code=401, detail="Invalid authorization header format. Expected 'Bearer <token>'"
36
+ )
37
+
38
+ # Extract the token from the authorization header
39
+ token = authorization[7:] # Remove "Bearer " prefix
40
+
41
+ # Verify the token
42
+ if token != settings.os_security_key:
43
+ raise HTTPException(status_code=401, detail="Invalid authentication token")
44
+
45
+ return True
46
+
47
+ return auth_dependency
agno/os/config.py ADDED
@@ -0,0 +1,103 @@
1
+ """Schemas related to the AgentOS configuration"""
2
+
3
+ from typing import Generic, List, Optional, TypeVar
4
+
5
+ from pydantic import BaseModel, field_validator
6
+
7
+
8
+ class EvalsDomainConfig(BaseModel):
9
+ """Configuration for the Evals domain of the AgentOS"""
10
+
11
+ display_name: Optional[str] = None
12
+ available_models: Optional[List[str]] = None
13
+
14
+
15
+ class SessionDomainConfig(BaseModel):
16
+ """Configuration for the Session domain of the AgentOS"""
17
+
18
+ display_name: Optional[str] = None
19
+
20
+
21
+ class KnowledgeDomainConfig(BaseModel):
22
+ """Configuration for the Knowledge domain of the AgentOS"""
23
+
24
+ display_name: Optional[str] = None
25
+
26
+
27
+ class MetricsDomainConfig(BaseModel):
28
+ """Configuration for the Metrics domain of the AgentOS"""
29
+
30
+ display_name: Optional[str] = None
31
+
32
+
33
+ class MemoryDomainConfig(BaseModel):
34
+ """Configuration for the Memory domain of the AgentOS"""
35
+
36
+ display_name: Optional[str] = None
37
+
38
+
39
+ DomainConfigType = TypeVar("DomainConfigType")
40
+
41
+
42
+ class DatabaseConfig(BaseModel, Generic[DomainConfigType]):
43
+ """Configuration for a domain when used with the contextual database"""
44
+
45
+ db_id: str
46
+ domain_config: Optional[DomainConfigType] = None
47
+
48
+
49
+ class EvalsConfig(EvalsDomainConfig):
50
+ """Configuration for the Evals domain of the AgentOS"""
51
+
52
+ dbs: Optional[List[DatabaseConfig[EvalsDomainConfig]]] = None
53
+
54
+
55
+ class SessionConfig(SessionDomainConfig):
56
+ """Configuration for the Session domain of the AgentOS"""
57
+
58
+ dbs: Optional[List[DatabaseConfig[SessionDomainConfig]]] = None
59
+
60
+
61
+ class MemoryConfig(MemoryDomainConfig):
62
+ """Configuration for the Memory domain of the AgentOS"""
63
+
64
+ dbs: Optional[List[DatabaseConfig[MemoryDomainConfig]]] = None
65
+
66
+
67
+ class KnowledgeConfig(KnowledgeDomainConfig):
68
+ """Configuration for the Knowledge domain of the AgentOS"""
69
+
70
+ dbs: Optional[List[DatabaseConfig[KnowledgeDomainConfig]]] = None
71
+
72
+
73
+ class MetricsConfig(MetricsDomainConfig):
74
+ """Configuration for the Metrics domain of the AgentOS"""
75
+
76
+ dbs: Optional[List[DatabaseConfig[MetricsDomainConfig]]] = None
77
+
78
+
79
+ class ChatConfig(BaseModel):
80
+ """Configuration for the Chat page of the AgentOS"""
81
+
82
+ quick_prompts: dict[str, list[str]]
83
+
84
+ # Limit the number of quick prompts to 3 (per agent/team/workflow)
85
+ @field_validator("quick_prompts")
86
+ @classmethod
87
+ def limit_lists(cls, v):
88
+ for key, lst in v.items():
89
+ if len(lst) > 3:
90
+ raise ValueError(f"Too many quick prompts for '{key}', maximum allowed is 3")
91
+ return v
92
+
93
+
94
+ class AgentOSConfig(BaseModel):
95
+ """General configuration for an AgentOS instance"""
96
+
97
+ available_models: Optional[List[str]] = None
98
+ chat: Optional[ChatConfig] = None
99
+ evals: Optional[EvalsConfig] = None
100
+ knowledge: Optional[KnowledgeConfig] = None
101
+ memory: Optional[MemoryConfig] = None
102
+ session: Optional[SessionConfig] = None
103
+ metrics: Optional[MetricsConfig] = None