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

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