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

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