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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (723) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +44 -5
  3. agno/agent/agent.py +10531 -2975
  4. agno/api/agent.py +14 -53
  5. agno/api/api.py +7 -46
  6. agno/api/evals.py +22 -0
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -25
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +6 -9
  11. agno/api/schemas/evals.py +16 -0
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +10 -10
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +16 -0
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +22 -26
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/compression/__init__.py +3 -0
  25. agno/compression/manager.py +247 -0
  26. agno/culture/__init__.py +3 -0
  27. agno/culture/manager.py +956 -0
  28. agno/db/__init__.py +24 -0
  29. agno/db/async_postgres/__init__.py +3 -0
  30. agno/db/base.py +946 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2781 -0
  33. agno/db/dynamo/schemas.py +442 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +2379 -0
  37. agno/db/firestore/schemas.py +181 -0
  38. agno/db/firestore/utils.py +376 -0
  39. agno/db/gcs_json/__init__.py +3 -0
  40. agno/db/gcs_json/gcs_json_db.py +1791 -0
  41. agno/db/gcs_json/utils.py +228 -0
  42. agno/db/in_memory/__init__.py +3 -0
  43. agno/db/in_memory/in_memory_db.py +1312 -0
  44. agno/db/in_memory/utils.py +230 -0
  45. agno/db/json/__init__.py +3 -0
  46. agno/db/json/json_db.py +1777 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/manager.py +199 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/migrations/versions/v2_3_0.py +938 -0
  51. agno/db/mongo/__init__.py +17 -0
  52. agno/db/mongo/async_mongo.py +2760 -0
  53. agno/db/mongo/mongo.py +2597 -0
  54. agno/db/mongo/schemas.py +119 -0
  55. agno/db/mongo/utils.py +276 -0
  56. agno/db/mysql/__init__.py +4 -0
  57. agno/db/mysql/async_mysql.py +2912 -0
  58. agno/db/mysql/mysql.py +2923 -0
  59. agno/db/mysql/schemas.py +186 -0
  60. agno/db/mysql/utils.py +488 -0
  61. agno/db/postgres/__init__.py +4 -0
  62. agno/db/postgres/async_postgres.py +2579 -0
  63. agno/db/postgres/postgres.py +2870 -0
  64. agno/db/postgres/schemas.py +187 -0
  65. agno/db/postgres/utils.py +442 -0
  66. agno/db/redis/__init__.py +3 -0
  67. agno/db/redis/redis.py +2141 -0
  68. agno/db/redis/schemas.py +159 -0
  69. agno/db/redis/utils.py +346 -0
  70. agno/db/schemas/__init__.py +4 -0
  71. agno/db/schemas/culture.py +120 -0
  72. agno/db/schemas/evals.py +34 -0
  73. agno/db/schemas/knowledge.py +40 -0
  74. agno/db/schemas/memory.py +61 -0
  75. agno/db/singlestore/__init__.py +3 -0
  76. agno/db/singlestore/schemas.py +179 -0
  77. agno/db/singlestore/singlestore.py +2877 -0
  78. agno/db/singlestore/utils.py +384 -0
  79. agno/db/sqlite/__init__.py +4 -0
  80. agno/db/sqlite/async_sqlite.py +2911 -0
  81. agno/db/sqlite/schemas.py +181 -0
  82. agno/db/sqlite/sqlite.py +2908 -0
  83. agno/db/sqlite/utils.py +429 -0
  84. agno/db/surrealdb/__init__.py +3 -0
  85. agno/db/surrealdb/metrics.py +292 -0
  86. agno/db/surrealdb/models.py +334 -0
  87. agno/db/surrealdb/queries.py +71 -0
  88. agno/db/surrealdb/surrealdb.py +1908 -0
  89. agno/db/surrealdb/utils.py +147 -0
  90. agno/db/utils.py +118 -0
  91. agno/eval/__init__.py +24 -0
  92. agno/eval/accuracy.py +666 -276
  93. agno/eval/agent_as_judge.py +861 -0
  94. agno/eval/base.py +29 -0
  95. agno/eval/performance.py +779 -0
  96. agno/eval/reliability.py +241 -62
  97. agno/eval/utils.py +120 -0
  98. agno/exceptions.py +143 -1
  99. agno/filters.py +354 -0
  100. agno/guardrails/__init__.py +6 -0
  101. agno/guardrails/base.py +19 -0
  102. agno/guardrails/openai.py +144 -0
  103. agno/guardrails/pii.py +94 -0
  104. agno/guardrails/prompt_injection.py +52 -0
  105. agno/hooks/__init__.py +3 -0
  106. agno/hooks/decorator.py +164 -0
  107. agno/integrations/discord/__init__.py +3 -0
  108. agno/integrations/discord/client.py +203 -0
  109. agno/knowledge/__init__.py +5 -1
  110. agno/{document → knowledge}/chunking/agentic.py +22 -14
  111. agno/{document → knowledge}/chunking/document.py +2 -2
  112. agno/{document → knowledge}/chunking/fixed.py +7 -6
  113. agno/knowledge/chunking/markdown.py +151 -0
  114. agno/{document → knowledge}/chunking/recursive.py +15 -3
  115. agno/knowledge/chunking/row.py +39 -0
  116. agno/knowledge/chunking/semantic.py +91 -0
  117. agno/knowledge/chunking/strategy.py +165 -0
  118. agno/knowledge/content.py +74 -0
  119. agno/knowledge/document/__init__.py +5 -0
  120. agno/{document → knowledge/document}/base.py +12 -2
  121. agno/knowledge/embedder/__init__.py +5 -0
  122. agno/knowledge/embedder/aws_bedrock.py +343 -0
  123. agno/knowledge/embedder/azure_openai.py +210 -0
  124. agno/{embedder → knowledge/embedder}/base.py +8 -0
  125. agno/knowledge/embedder/cohere.py +323 -0
  126. agno/knowledge/embedder/fastembed.py +62 -0
  127. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  128. agno/knowledge/embedder/google.py +258 -0
  129. agno/knowledge/embedder/huggingface.py +94 -0
  130. agno/knowledge/embedder/jina.py +182 -0
  131. agno/knowledge/embedder/langdb.py +22 -0
  132. agno/knowledge/embedder/mistral.py +206 -0
  133. agno/knowledge/embedder/nebius.py +13 -0
  134. agno/knowledge/embedder/ollama.py +154 -0
  135. agno/knowledge/embedder/openai.py +195 -0
  136. agno/knowledge/embedder/sentence_transformer.py +63 -0
  137. agno/{embedder → knowledge/embedder}/together.py +1 -1
  138. agno/knowledge/embedder/vllm.py +262 -0
  139. agno/knowledge/embedder/voyageai.py +165 -0
  140. agno/knowledge/knowledge.py +3006 -0
  141. agno/knowledge/reader/__init__.py +7 -0
  142. agno/knowledge/reader/arxiv_reader.py +81 -0
  143. agno/knowledge/reader/base.py +95 -0
  144. agno/knowledge/reader/csv_reader.py +164 -0
  145. agno/knowledge/reader/docx_reader.py +82 -0
  146. agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
  147. agno/knowledge/reader/firecrawl_reader.py +201 -0
  148. agno/knowledge/reader/json_reader.py +88 -0
  149. agno/knowledge/reader/markdown_reader.py +137 -0
  150. agno/knowledge/reader/pdf_reader.py +431 -0
  151. agno/knowledge/reader/pptx_reader.py +101 -0
  152. agno/knowledge/reader/reader_factory.py +313 -0
  153. agno/knowledge/reader/s3_reader.py +89 -0
  154. agno/knowledge/reader/tavily_reader.py +193 -0
  155. agno/knowledge/reader/text_reader.py +127 -0
  156. agno/knowledge/reader/web_search_reader.py +325 -0
  157. agno/knowledge/reader/website_reader.py +455 -0
  158. agno/knowledge/reader/wikipedia_reader.py +91 -0
  159. agno/knowledge/reader/youtube_reader.py +78 -0
  160. agno/knowledge/remote_content/remote_content.py +88 -0
  161. agno/knowledge/reranker/__init__.py +3 -0
  162. agno/{reranker → knowledge/reranker}/base.py +1 -1
  163. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  164. agno/knowledge/reranker/infinity.py +195 -0
  165. agno/knowledge/reranker/sentence_transformer.py +54 -0
  166. agno/knowledge/types.py +39 -0
  167. agno/knowledge/utils.py +234 -0
  168. agno/media.py +439 -95
  169. agno/memory/__init__.py +16 -3
  170. agno/memory/manager.py +1474 -123
  171. agno/memory/strategies/__init__.py +15 -0
  172. agno/memory/strategies/base.py +66 -0
  173. agno/memory/strategies/summarize.py +196 -0
  174. agno/memory/strategies/types.py +37 -0
  175. agno/models/aimlapi/__init__.py +5 -0
  176. agno/models/aimlapi/aimlapi.py +62 -0
  177. agno/models/anthropic/__init__.py +4 -0
  178. agno/models/anthropic/claude.py +960 -496
  179. agno/models/aws/__init__.py +15 -0
  180. agno/models/aws/bedrock.py +686 -451
  181. agno/models/aws/claude.py +190 -183
  182. agno/models/azure/__init__.py +18 -1
  183. agno/models/azure/ai_foundry.py +489 -0
  184. agno/models/azure/openai_chat.py +89 -40
  185. agno/models/base.py +2477 -550
  186. agno/models/cerebras/__init__.py +12 -0
  187. agno/models/cerebras/cerebras.py +565 -0
  188. agno/models/cerebras/cerebras_openai.py +131 -0
  189. agno/models/cohere/__init__.py +4 -0
  190. agno/models/cohere/chat.py +306 -492
  191. agno/models/cometapi/__init__.py +5 -0
  192. agno/models/cometapi/cometapi.py +74 -0
  193. agno/models/dashscope/__init__.py +5 -0
  194. agno/models/dashscope/dashscope.py +90 -0
  195. agno/models/deepinfra/__init__.py +5 -0
  196. agno/models/deepinfra/deepinfra.py +45 -0
  197. agno/models/deepseek/__init__.py +4 -0
  198. agno/models/deepseek/deepseek.py +110 -9
  199. agno/models/fireworks/__init__.py +4 -0
  200. agno/models/fireworks/fireworks.py +19 -22
  201. agno/models/google/__init__.py +3 -7
  202. agno/models/google/gemini.py +1717 -662
  203. agno/models/google/utils.py +22 -0
  204. agno/models/groq/__init__.py +4 -0
  205. agno/models/groq/groq.py +391 -666
  206. agno/models/huggingface/__init__.py +4 -0
  207. agno/models/huggingface/huggingface.py +266 -538
  208. agno/models/ibm/__init__.py +5 -0
  209. agno/models/ibm/watsonx.py +432 -0
  210. agno/models/internlm/__init__.py +3 -0
  211. agno/models/internlm/internlm.py +20 -3
  212. agno/models/langdb/__init__.py +1 -0
  213. agno/models/langdb/langdb.py +60 -0
  214. agno/models/litellm/__init__.py +14 -0
  215. agno/models/litellm/chat.py +503 -0
  216. agno/models/litellm/litellm_openai.py +42 -0
  217. agno/models/llama_cpp/__init__.py +5 -0
  218. agno/models/llama_cpp/llama_cpp.py +22 -0
  219. agno/models/lmstudio/__init__.py +5 -0
  220. agno/models/lmstudio/lmstudio.py +25 -0
  221. agno/models/message.py +361 -39
  222. agno/models/meta/__init__.py +12 -0
  223. agno/models/meta/llama.py +502 -0
  224. agno/models/meta/llama_openai.py +79 -0
  225. agno/models/metrics.py +120 -0
  226. agno/models/mistral/__init__.py +4 -0
  227. agno/models/mistral/mistral.py +293 -393
  228. agno/models/nebius/__init__.py +3 -0
  229. agno/models/nebius/nebius.py +53 -0
  230. agno/models/nexus/__init__.py +3 -0
  231. agno/models/nexus/nexus.py +22 -0
  232. agno/models/nvidia/__init__.py +4 -0
  233. agno/models/nvidia/nvidia.py +22 -3
  234. agno/models/ollama/__init__.py +4 -2
  235. agno/models/ollama/chat.py +257 -492
  236. agno/models/openai/__init__.py +7 -0
  237. agno/models/openai/chat.py +725 -770
  238. agno/models/openai/like.py +16 -2
  239. agno/models/openai/responses.py +1121 -0
  240. agno/models/openrouter/__init__.py +4 -0
  241. agno/models/openrouter/openrouter.py +62 -5
  242. agno/models/perplexity/__init__.py +5 -0
  243. agno/models/perplexity/perplexity.py +203 -0
  244. agno/models/portkey/__init__.py +3 -0
  245. agno/models/portkey/portkey.py +82 -0
  246. agno/models/requesty/__init__.py +5 -0
  247. agno/models/requesty/requesty.py +69 -0
  248. agno/models/response.py +177 -7
  249. agno/models/sambanova/__init__.py +4 -0
  250. agno/models/sambanova/sambanova.py +23 -4
  251. agno/models/siliconflow/__init__.py +5 -0
  252. agno/models/siliconflow/siliconflow.py +42 -0
  253. agno/models/together/__init__.py +4 -0
  254. agno/models/together/together.py +21 -164
  255. agno/models/utils.py +266 -0
  256. agno/models/vercel/__init__.py +3 -0
  257. agno/models/vercel/v0.py +43 -0
  258. agno/models/vertexai/__init__.py +0 -1
  259. agno/models/vertexai/claude.py +190 -0
  260. agno/models/vllm/__init__.py +3 -0
  261. agno/models/vllm/vllm.py +83 -0
  262. agno/models/xai/__init__.py +2 -0
  263. agno/models/xai/xai.py +111 -7
  264. agno/os/__init__.py +3 -0
  265. agno/os/app.py +1027 -0
  266. agno/os/auth.py +244 -0
  267. agno/os/config.py +126 -0
  268. agno/os/interfaces/__init__.py +1 -0
  269. agno/os/interfaces/a2a/__init__.py +3 -0
  270. agno/os/interfaces/a2a/a2a.py +42 -0
  271. agno/os/interfaces/a2a/router.py +249 -0
  272. agno/os/interfaces/a2a/utils.py +924 -0
  273. agno/os/interfaces/agui/__init__.py +3 -0
  274. agno/os/interfaces/agui/agui.py +47 -0
  275. agno/os/interfaces/agui/router.py +147 -0
  276. agno/os/interfaces/agui/utils.py +574 -0
  277. agno/os/interfaces/base.py +25 -0
  278. agno/os/interfaces/slack/__init__.py +3 -0
  279. agno/os/interfaces/slack/router.py +148 -0
  280. agno/os/interfaces/slack/security.py +30 -0
  281. agno/os/interfaces/slack/slack.py +47 -0
  282. agno/os/interfaces/whatsapp/__init__.py +3 -0
  283. agno/os/interfaces/whatsapp/router.py +210 -0
  284. agno/os/interfaces/whatsapp/security.py +55 -0
  285. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  286. agno/os/mcp.py +293 -0
  287. agno/os/middleware/__init__.py +9 -0
  288. agno/os/middleware/jwt.py +797 -0
  289. agno/os/router.py +258 -0
  290. agno/os/routers/__init__.py +3 -0
  291. agno/os/routers/agents/__init__.py +3 -0
  292. agno/os/routers/agents/router.py +599 -0
  293. agno/os/routers/agents/schema.py +261 -0
  294. agno/os/routers/evals/__init__.py +3 -0
  295. agno/os/routers/evals/evals.py +450 -0
  296. agno/os/routers/evals/schemas.py +174 -0
  297. agno/os/routers/evals/utils.py +231 -0
  298. agno/os/routers/health.py +31 -0
  299. agno/os/routers/home.py +52 -0
  300. agno/os/routers/knowledge/__init__.py +3 -0
  301. agno/os/routers/knowledge/knowledge.py +1008 -0
  302. agno/os/routers/knowledge/schemas.py +178 -0
  303. agno/os/routers/memory/__init__.py +3 -0
  304. agno/os/routers/memory/memory.py +661 -0
  305. agno/os/routers/memory/schemas.py +88 -0
  306. agno/os/routers/metrics/__init__.py +3 -0
  307. agno/os/routers/metrics/metrics.py +190 -0
  308. agno/os/routers/metrics/schemas.py +47 -0
  309. agno/os/routers/session/__init__.py +3 -0
  310. agno/os/routers/session/session.py +997 -0
  311. agno/os/routers/teams/__init__.py +3 -0
  312. agno/os/routers/teams/router.py +512 -0
  313. agno/os/routers/teams/schema.py +257 -0
  314. agno/os/routers/traces/__init__.py +3 -0
  315. agno/os/routers/traces/schemas.py +414 -0
  316. agno/os/routers/traces/traces.py +499 -0
  317. agno/os/routers/workflows/__init__.py +3 -0
  318. agno/os/routers/workflows/router.py +624 -0
  319. agno/os/routers/workflows/schema.py +75 -0
  320. agno/os/schema.py +534 -0
  321. agno/os/scopes.py +469 -0
  322. agno/{playground → os}/settings.py +7 -15
  323. agno/os/utils.py +973 -0
  324. agno/reasoning/anthropic.py +80 -0
  325. agno/reasoning/azure_ai_foundry.py +67 -0
  326. agno/reasoning/deepseek.py +63 -0
  327. agno/reasoning/default.py +97 -0
  328. agno/reasoning/gemini.py +73 -0
  329. agno/reasoning/groq.py +71 -0
  330. agno/reasoning/helpers.py +24 -1
  331. agno/reasoning/ollama.py +67 -0
  332. agno/reasoning/openai.py +86 -0
  333. agno/reasoning/step.py +2 -1
  334. agno/reasoning/vertexai.py +76 -0
  335. agno/run/__init__.py +6 -0
  336. agno/run/agent.py +822 -0
  337. agno/run/base.py +247 -0
  338. agno/run/cancel.py +81 -0
  339. agno/run/requirement.py +181 -0
  340. agno/run/team.py +767 -0
  341. agno/run/workflow.py +708 -0
  342. agno/session/__init__.py +10 -0
  343. agno/session/agent.py +260 -0
  344. agno/session/summary.py +265 -0
  345. agno/session/team.py +342 -0
  346. agno/session/workflow.py +501 -0
  347. agno/table.py +10 -0
  348. agno/team/__init__.py +37 -0
  349. agno/team/team.py +9536 -0
  350. agno/tools/__init__.py +7 -0
  351. agno/tools/agentql.py +120 -0
  352. agno/tools/airflow.py +22 -12
  353. agno/tools/api.py +122 -0
  354. agno/tools/apify.py +276 -83
  355. agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
  356. agno/tools/aws_lambda.py +28 -7
  357. agno/tools/aws_ses.py +66 -0
  358. agno/tools/baidusearch.py +11 -4
  359. agno/tools/bitbucket.py +292 -0
  360. agno/tools/brandfetch.py +213 -0
  361. agno/tools/bravesearch.py +106 -0
  362. agno/tools/brightdata.py +367 -0
  363. agno/tools/browserbase.py +209 -0
  364. agno/tools/calcom.py +32 -23
  365. agno/tools/calculator.py +24 -37
  366. agno/tools/cartesia.py +187 -0
  367. agno/tools/{clickup_tool.py → clickup.py} +17 -28
  368. agno/tools/confluence.py +91 -26
  369. agno/tools/crawl4ai.py +139 -43
  370. agno/tools/csv_toolkit.py +28 -22
  371. agno/tools/dalle.py +36 -22
  372. agno/tools/daytona.py +475 -0
  373. agno/tools/decorator.py +169 -14
  374. agno/tools/desi_vocal.py +23 -11
  375. agno/tools/discord.py +32 -29
  376. agno/tools/docker.py +716 -0
  377. agno/tools/duckdb.py +76 -81
  378. agno/tools/duckduckgo.py +43 -40
  379. agno/tools/e2b.py +703 -0
  380. agno/tools/eleven_labs.py +65 -54
  381. agno/tools/email.py +13 -5
  382. agno/tools/evm.py +129 -0
  383. agno/tools/exa.py +324 -42
  384. agno/tools/fal.py +39 -35
  385. agno/tools/file.py +196 -30
  386. agno/tools/file_generation.py +356 -0
  387. agno/tools/financial_datasets.py +288 -0
  388. agno/tools/firecrawl.py +108 -33
  389. agno/tools/function.py +960 -122
  390. agno/tools/giphy.py +34 -12
  391. agno/tools/github.py +1294 -97
  392. agno/tools/gmail.py +922 -0
  393. agno/tools/google_bigquery.py +117 -0
  394. agno/tools/google_drive.py +271 -0
  395. agno/tools/google_maps.py +253 -0
  396. agno/tools/googlecalendar.py +607 -107
  397. agno/tools/googlesheets.py +377 -0
  398. agno/tools/hackernews.py +20 -12
  399. agno/tools/jina.py +24 -14
  400. agno/tools/jira.py +48 -19
  401. agno/tools/knowledge.py +218 -0
  402. agno/tools/linear.py +82 -43
  403. agno/tools/linkup.py +58 -0
  404. agno/tools/local_file_system.py +15 -7
  405. agno/tools/lumalab.py +41 -26
  406. agno/tools/mcp/__init__.py +10 -0
  407. agno/tools/mcp/mcp.py +331 -0
  408. agno/tools/mcp/multi_mcp.py +347 -0
  409. agno/tools/mcp/params.py +24 -0
  410. agno/tools/mcp_toolbox.py +284 -0
  411. agno/tools/mem0.py +193 -0
  412. agno/tools/memory.py +419 -0
  413. agno/tools/mlx_transcribe.py +11 -9
  414. agno/tools/models/azure_openai.py +190 -0
  415. agno/tools/models/gemini.py +203 -0
  416. agno/tools/models/groq.py +158 -0
  417. agno/tools/models/morph.py +186 -0
  418. agno/tools/models/nebius.py +124 -0
  419. agno/tools/models_labs.py +163 -82
  420. agno/tools/moviepy_video.py +18 -13
  421. agno/tools/nano_banana.py +151 -0
  422. agno/tools/neo4j.py +134 -0
  423. agno/tools/newspaper.py +15 -4
  424. agno/tools/newspaper4k.py +19 -6
  425. agno/tools/notion.py +204 -0
  426. agno/tools/openai.py +181 -17
  427. agno/tools/openbb.py +27 -20
  428. agno/tools/opencv.py +321 -0
  429. agno/tools/openweather.py +233 -0
  430. agno/tools/oxylabs.py +385 -0
  431. agno/tools/pandas.py +25 -15
  432. agno/tools/parallel.py +314 -0
  433. agno/tools/postgres.py +238 -185
  434. agno/tools/pubmed.py +125 -13
  435. agno/tools/python.py +48 -35
  436. agno/tools/reasoning.py +283 -0
  437. agno/tools/reddit.py +207 -29
  438. agno/tools/redshift.py +406 -0
  439. agno/tools/replicate.py +69 -26
  440. agno/tools/resend.py +11 -6
  441. agno/tools/scrapegraph.py +179 -19
  442. agno/tools/searxng.py +23 -31
  443. agno/tools/serpapi.py +15 -10
  444. agno/tools/serper.py +255 -0
  445. agno/tools/shell.py +23 -12
  446. agno/tools/shopify.py +1519 -0
  447. agno/tools/slack.py +56 -14
  448. agno/tools/sleep.py +8 -6
  449. agno/tools/spider.py +35 -11
  450. agno/tools/spotify.py +919 -0
  451. agno/tools/sql.py +34 -19
  452. agno/tools/tavily.py +158 -8
  453. agno/tools/telegram.py +18 -8
  454. agno/tools/todoist.py +218 -0
  455. agno/tools/toolkit.py +134 -9
  456. agno/tools/trafilatura.py +388 -0
  457. agno/tools/trello.py +25 -28
  458. agno/tools/twilio.py +18 -9
  459. agno/tools/user_control_flow.py +78 -0
  460. agno/tools/valyu.py +228 -0
  461. agno/tools/visualization.py +467 -0
  462. agno/tools/webbrowser.py +28 -0
  463. agno/tools/webex.py +76 -0
  464. agno/tools/website.py +23 -19
  465. agno/tools/webtools.py +45 -0
  466. agno/tools/whatsapp.py +286 -0
  467. agno/tools/wikipedia.py +28 -19
  468. agno/tools/workflow.py +285 -0
  469. agno/tools/{twitter.py → x.py} +142 -46
  470. agno/tools/yfinance.py +41 -39
  471. agno/tools/youtube.py +34 -17
  472. agno/tools/zendesk.py +15 -5
  473. agno/tools/zep.py +454 -0
  474. agno/tools/zoom.py +86 -37
  475. agno/tracing/__init__.py +12 -0
  476. agno/tracing/exporter.py +157 -0
  477. agno/tracing/schemas.py +276 -0
  478. agno/tracing/setup.py +111 -0
  479. agno/utils/agent.py +938 -0
  480. agno/utils/audio.py +37 -1
  481. agno/utils/certs.py +27 -0
  482. agno/utils/code_execution.py +11 -0
  483. agno/utils/common.py +103 -20
  484. agno/utils/cryptography.py +22 -0
  485. agno/utils/dttm.py +33 -0
  486. agno/utils/events.py +700 -0
  487. agno/utils/functions.py +107 -37
  488. agno/utils/gemini.py +426 -0
  489. agno/utils/hooks.py +171 -0
  490. agno/utils/http.py +185 -0
  491. agno/utils/json_schema.py +159 -37
  492. agno/utils/knowledge.py +36 -0
  493. agno/utils/location.py +19 -0
  494. agno/utils/log.py +221 -8
  495. agno/utils/mcp.py +214 -0
  496. agno/utils/media.py +335 -14
  497. agno/utils/merge_dict.py +22 -1
  498. agno/utils/message.py +77 -2
  499. agno/utils/models/ai_foundry.py +50 -0
  500. agno/utils/models/claude.py +373 -0
  501. agno/utils/models/cohere.py +94 -0
  502. agno/utils/models/llama.py +85 -0
  503. agno/utils/models/mistral.py +100 -0
  504. agno/utils/models/openai_responses.py +140 -0
  505. agno/utils/models/schema_utils.py +153 -0
  506. agno/utils/models/watsonx.py +41 -0
  507. agno/utils/openai.py +257 -0
  508. agno/utils/pickle.py +1 -1
  509. agno/utils/pprint.py +124 -8
  510. agno/utils/print_response/agent.py +930 -0
  511. agno/utils/print_response/team.py +1914 -0
  512. agno/utils/print_response/workflow.py +1668 -0
  513. agno/utils/prompts.py +111 -0
  514. agno/utils/reasoning.py +108 -0
  515. agno/utils/response.py +163 -0
  516. agno/utils/serialize.py +32 -0
  517. agno/utils/shell.py +4 -4
  518. agno/utils/streamlit.py +487 -0
  519. agno/utils/string.py +204 -51
  520. agno/utils/team.py +139 -0
  521. agno/utils/timer.py +9 -2
  522. agno/utils/tokens.py +657 -0
  523. agno/utils/tools.py +19 -1
  524. agno/utils/whatsapp.py +305 -0
  525. agno/utils/yaml_io.py +3 -3
  526. agno/vectordb/__init__.py +2 -0
  527. agno/vectordb/base.py +87 -9
  528. agno/vectordb/cassandra/__init__.py +5 -1
  529. agno/vectordb/cassandra/cassandra.py +383 -27
  530. agno/vectordb/chroma/__init__.py +4 -0
  531. agno/vectordb/chroma/chromadb.py +748 -83
  532. agno/vectordb/clickhouse/__init__.py +7 -1
  533. agno/vectordb/clickhouse/clickhousedb.py +554 -53
  534. agno/vectordb/couchbase/__init__.py +3 -0
  535. agno/vectordb/couchbase/couchbase.py +1446 -0
  536. agno/vectordb/lancedb/__init__.py +5 -0
  537. agno/vectordb/lancedb/lance_db.py +730 -98
  538. agno/vectordb/langchaindb/__init__.py +5 -0
  539. agno/vectordb/langchaindb/langchaindb.py +163 -0
  540. agno/vectordb/lightrag/__init__.py +5 -0
  541. agno/vectordb/lightrag/lightrag.py +388 -0
  542. agno/vectordb/llamaindex/__init__.py +3 -0
  543. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  544. agno/vectordb/milvus/__init__.py +3 -0
  545. agno/vectordb/milvus/milvus.py +966 -78
  546. agno/vectordb/mongodb/__init__.py +9 -1
  547. agno/vectordb/mongodb/mongodb.py +1175 -172
  548. agno/vectordb/pgvector/__init__.py +8 -0
  549. agno/vectordb/pgvector/pgvector.py +599 -115
  550. agno/vectordb/pineconedb/__init__.py +5 -1
  551. agno/vectordb/pineconedb/pineconedb.py +406 -43
  552. agno/vectordb/qdrant/__init__.py +4 -0
  553. agno/vectordb/qdrant/qdrant.py +914 -61
  554. agno/vectordb/redis/__init__.py +9 -0
  555. agno/vectordb/redis/redisdb.py +682 -0
  556. agno/vectordb/singlestore/__init__.py +8 -1
  557. agno/vectordb/singlestore/singlestore.py +771 -0
  558. agno/vectordb/surrealdb/__init__.py +3 -0
  559. agno/vectordb/surrealdb/surrealdb.py +663 -0
  560. agno/vectordb/upstashdb/__init__.py +5 -0
  561. agno/vectordb/upstashdb/upstashdb.py +718 -0
  562. agno/vectordb/weaviate/__init__.py +8 -0
  563. agno/vectordb/weaviate/index.py +15 -0
  564. agno/vectordb/weaviate/weaviate.py +1009 -0
  565. agno/workflow/__init__.py +23 -1
  566. agno/workflow/agent.py +299 -0
  567. agno/workflow/condition.py +759 -0
  568. agno/workflow/loop.py +756 -0
  569. agno/workflow/parallel.py +853 -0
  570. agno/workflow/router.py +723 -0
  571. agno/workflow/step.py +1564 -0
  572. agno/workflow/steps.py +613 -0
  573. agno/workflow/types.py +556 -0
  574. agno/workflow/workflow.py +4327 -514
  575. agno-2.3.13.dist-info/METADATA +639 -0
  576. agno-2.3.13.dist-info/RECORD +613 -0
  577. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
  578. agno-2.3.13.dist-info/licenses/LICENSE +201 -0
  579. agno/api/playground.py +0 -91
  580. agno/api/schemas/playground.py +0 -22
  581. agno/api/schemas/user.py +0 -22
  582. agno/api/schemas/workspace.py +0 -46
  583. agno/api/user.py +0 -160
  584. agno/api/workspace.py +0 -151
  585. agno/cli/auth_server.py +0 -118
  586. agno/cli/config.py +0 -275
  587. agno/cli/console.py +0 -88
  588. agno/cli/credentials.py +0 -23
  589. agno/cli/entrypoint.py +0 -571
  590. agno/cli/operator.py +0 -355
  591. agno/cli/settings.py +0 -85
  592. agno/cli/ws/ws_cli.py +0 -817
  593. agno/constants.py +0 -13
  594. agno/document/__init__.py +0 -1
  595. agno/document/chunking/semantic.py +0 -47
  596. agno/document/chunking/strategy.py +0 -31
  597. agno/document/reader/__init__.py +0 -1
  598. agno/document/reader/arxiv_reader.py +0 -41
  599. agno/document/reader/base.py +0 -22
  600. agno/document/reader/csv_reader.py +0 -84
  601. agno/document/reader/docx_reader.py +0 -46
  602. agno/document/reader/firecrawl_reader.py +0 -99
  603. agno/document/reader/json_reader.py +0 -43
  604. agno/document/reader/pdf_reader.py +0 -219
  605. agno/document/reader/s3/pdf_reader.py +0 -46
  606. agno/document/reader/s3/text_reader.py +0 -51
  607. agno/document/reader/text_reader.py +0 -41
  608. agno/document/reader/website_reader.py +0 -175
  609. agno/document/reader/youtube_reader.py +0 -50
  610. agno/embedder/__init__.py +0 -1
  611. agno/embedder/azure_openai.py +0 -86
  612. agno/embedder/cohere.py +0 -72
  613. agno/embedder/fastembed.py +0 -37
  614. agno/embedder/google.py +0 -73
  615. agno/embedder/huggingface.py +0 -54
  616. agno/embedder/mistral.py +0 -80
  617. agno/embedder/ollama.py +0 -57
  618. agno/embedder/openai.py +0 -74
  619. agno/embedder/sentence_transformer.py +0 -38
  620. agno/embedder/voyageai.py +0 -64
  621. agno/eval/perf.py +0 -201
  622. agno/file/__init__.py +0 -1
  623. agno/file/file.py +0 -16
  624. agno/file/local/csv.py +0 -32
  625. agno/file/local/txt.py +0 -19
  626. agno/infra/app.py +0 -240
  627. agno/infra/base.py +0 -144
  628. agno/infra/context.py +0 -20
  629. agno/infra/db_app.py +0 -52
  630. agno/infra/resource.py +0 -205
  631. agno/infra/resources.py +0 -55
  632. agno/knowledge/agent.py +0 -230
  633. agno/knowledge/arxiv.py +0 -22
  634. agno/knowledge/combined.py +0 -22
  635. agno/knowledge/csv.py +0 -28
  636. agno/knowledge/csv_url.py +0 -19
  637. agno/knowledge/document.py +0 -20
  638. agno/knowledge/docx.py +0 -30
  639. agno/knowledge/json.py +0 -28
  640. agno/knowledge/langchain.py +0 -71
  641. agno/knowledge/llamaindex.py +0 -66
  642. agno/knowledge/pdf.py +0 -28
  643. agno/knowledge/pdf_url.py +0 -26
  644. agno/knowledge/s3/base.py +0 -60
  645. agno/knowledge/s3/pdf.py +0 -21
  646. agno/knowledge/s3/text.py +0 -23
  647. agno/knowledge/text.py +0 -30
  648. agno/knowledge/website.py +0 -88
  649. agno/knowledge/wikipedia.py +0 -31
  650. agno/knowledge/youtube.py +0 -22
  651. agno/memory/agent.py +0 -392
  652. agno/memory/classifier.py +0 -104
  653. agno/memory/db/__init__.py +0 -1
  654. agno/memory/db/base.py +0 -42
  655. agno/memory/db/mongodb.py +0 -189
  656. agno/memory/db/postgres.py +0 -203
  657. agno/memory/db/sqlite.py +0 -193
  658. agno/memory/memory.py +0 -15
  659. agno/memory/row.py +0 -36
  660. agno/memory/summarizer.py +0 -192
  661. agno/memory/summary.py +0 -19
  662. agno/memory/workflow.py +0 -38
  663. agno/models/google/gemini_openai.py +0 -26
  664. agno/models/ollama/hermes.py +0 -221
  665. agno/models/ollama/tools.py +0 -362
  666. agno/models/vertexai/gemini.py +0 -595
  667. agno/playground/__init__.py +0 -3
  668. agno/playground/async_router.py +0 -421
  669. agno/playground/deploy.py +0 -249
  670. agno/playground/operator.py +0 -92
  671. agno/playground/playground.py +0 -91
  672. agno/playground/schemas.py +0 -76
  673. agno/playground/serve.py +0 -55
  674. agno/playground/sync_router.py +0 -405
  675. agno/reasoning/agent.py +0 -68
  676. agno/run/response.py +0 -112
  677. agno/storage/agent/__init__.py +0 -0
  678. agno/storage/agent/base.py +0 -38
  679. agno/storage/agent/dynamodb.py +0 -350
  680. agno/storage/agent/json.py +0 -92
  681. agno/storage/agent/mongodb.py +0 -228
  682. agno/storage/agent/postgres.py +0 -367
  683. agno/storage/agent/session.py +0 -79
  684. agno/storage/agent/singlestore.py +0 -303
  685. agno/storage/agent/sqlite.py +0 -357
  686. agno/storage/agent/yaml.py +0 -93
  687. agno/storage/workflow/__init__.py +0 -0
  688. agno/storage/workflow/base.py +0 -40
  689. agno/storage/workflow/mongodb.py +0 -233
  690. agno/storage/workflow/postgres.py +0 -366
  691. agno/storage/workflow/session.py +0 -60
  692. agno/storage/workflow/sqlite.py +0 -359
  693. agno/tools/googlesearch.py +0 -88
  694. agno/utils/defaults.py +0 -57
  695. agno/utils/filesystem.py +0 -39
  696. agno/utils/git.py +0 -52
  697. agno/utils/json_io.py +0 -30
  698. agno/utils/load_env.py +0 -19
  699. agno/utils/py_io.py +0 -19
  700. agno/utils/pyproject.py +0 -18
  701. agno/utils/resource_filter.py +0 -31
  702. agno/vectordb/singlestore/s2vectordb.py +0 -390
  703. agno/vectordb/singlestore/s2vectordb2.py +0 -355
  704. agno/workspace/__init__.py +0 -0
  705. agno/workspace/config.py +0 -325
  706. agno/workspace/enums.py +0 -6
  707. agno/workspace/helpers.py +0 -48
  708. agno/workspace/operator.py +0 -758
  709. agno/workspace/settings.py +0 -63
  710. agno-0.1.2.dist-info/LICENSE +0 -375
  711. agno-0.1.2.dist-info/METADATA +0 -502
  712. agno-0.1.2.dist-info/RECORD +0 -352
  713. agno-0.1.2.dist-info/entry_points.txt +0 -3
  714. /agno/{cli → db/migrations}/__init__.py +0 -0
  715. /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
  716. /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
  717. /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
  718. /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
  719. /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
  720. /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
  721. /agno/{reranker → utils/models}/__init__.py +0 -0
  722. /agno/{storage → utils/print_response}/__init__.py +0 -0
  723. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
agno/api/workspace.py DELETED
@@ -1,151 +0,0 @@
1
- from typing import Dict, List, Optional, Union
2
-
3
- from httpx import Response
4
-
5
- from agno.api.api import api, invalid_response
6
- from agno.api.routes import ApiRoutes
7
- from agno.api.schemas.team import TeamIdentifier
8
- from agno.api.schemas.user import UserSchema
9
- from agno.api.schemas.workspace import (
10
- WorkspaceCreate,
11
- WorkspaceEvent,
12
- WorkspaceSchema,
13
- WorkspaceUpdate,
14
- )
15
- from agno.cli.settings import agno_cli_settings
16
- from agno.utils.log import logger
17
-
18
-
19
- def create_workspace_for_user(
20
- user: UserSchema, workspace: WorkspaceCreate, team: Optional[TeamIdentifier] = None
21
- ) -> Optional[WorkspaceSchema]:
22
- logger.debug("--**-- Creating workspace")
23
- with api.AuthenticatedClient() as api_client:
24
- try:
25
- payload = {
26
- "user": user.model_dump(include={"id_user", "email"}),
27
- "workspace": workspace.model_dump(exclude_none=True),
28
- }
29
- if team is not None:
30
- payload["team"] = team.model_dump(exclude_none=True)
31
-
32
- r: Response = api_client.post(
33
- ApiRoutes.WORKSPACE_CREATE,
34
- json=payload,
35
- timeout=2.0,
36
- )
37
- if invalid_response(r):
38
- try:
39
- error_msg = r.json().get("detail", "Permission denied")
40
- except Exception:
41
- error_msg = f"Could not create workspace: {r.text}"
42
- logger.error(error_msg)
43
- return None
44
-
45
- response_json: Union[Dict, List] = r.json()
46
- if response_json is None:
47
- return None
48
-
49
- created_workspace: WorkspaceSchema = WorkspaceSchema.model_validate(response_json)
50
- if created_workspace is not None:
51
- return created_workspace
52
- except Exception as e:
53
- logger.debug(f"Could not create workspace: {e}")
54
- return None
55
-
56
-
57
- def update_workspace_for_user(user: UserSchema, workspace: WorkspaceUpdate) -> Optional[WorkspaceSchema]:
58
- logger.debug("--**-- Updating workspace for user")
59
- with api.AuthenticatedClient() as api_client:
60
- try:
61
- payload = {
62
- "user": user.model_dump(include={"id_user", "email"}),
63
- "workspace": workspace.model_dump(exclude_none=True),
64
- }
65
-
66
- r: Response = api_client.post(
67
- ApiRoutes.WORKSPACE_UPDATE,
68
- json=payload,
69
- )
70
- if invalid_response(r):
71
- try:
72
- error_msg = r.json().get("detail", "Could not update workspace")
73
- except Exception:
74
- error_msg = f"Could not update workspace: {r.text}"
75
- logger.error(error_msg)
76
- return None
77
-
78
- response_json: Union[Dict, List] = r.json()
79
- if response_json is None:
80
- return None
81
-
82
- updated_workspace: WorkspaceSchema = WorkspaceSchema.model_validate(response_json)
83
- if updated_workspace is not None:
84
- return updated_workspace
85
- except Exception as e:
86
- logger.debug(f"Could not update workspace: {e}")
87
- return None
88
-
89
-
90
- def update_workspace_for_team(
91
- user: UserSchema, workspace: WorkspaceUpdate, team: TeamIdentifier
92
- ) -> Optional[WorkspaceSchema]:
93
- logger.debug("--**-- Updating workspace for team")
94
- with api.AuthenticatedClient() as api_client:
95
- try:
96
- payload = {
97
- "user": user.model_dump(include={"id_user", "email"}),
98
- "team_workspace": workspace.model_dump(exclude_none=True).update({"id_team": team.id_team}),
99
- }
100
-
101
- r: Response = api_client.post(
102
- ApiRoutes.WORKSPACE_UPDATE,
103
- json=payload,
104
- )
105
- if invalid_response(r):
106
- try:
107
- error_msg = r.json().get("detail", "Could not update workspace")
108
- except Exception:
109
- error_msg = f"Could not update workspace: {r.text}"
110
- logger.error(error_msg)
111
- return None
112
-
113
- response_json: Union[Dict, List] = r.json()
114
- if response_json is None:
115
- return None
116
-
117
- updated_workspace: WorkspaceSchema = WorkspaceSchema.model_validate(response_json)
118
- if updated_workspace is not None:
119
- return updated_workspace
120
- except Exception as e:
121
- logger.debug(f"Could not update workspace: {e}")
122
- return None
123
-
124
-
125
- def log_workspace_event(user: UserSchema, workspace_event: WorkspaceEvent) -> bool:
126
- if not agno_cli_settings.api_enabled:
127
- return False
128
-
129
- logger.debug("--**-- Log workspace event")
130
- with api.AuthenticatedClient() as api_client:
131
- try:
132
- r: Response = api_client.post(
133
- ApiRoutes.WORKSPACE_EVENT_CREATE,
134
- json={
135
- "user": user.model_dump(include={"id_user", "email"}),
136
- "event": workspace_event.model_dump(exclude_none=True),
137
- },
138
- )
139
- if invalid_response(r):
140
- return False
141
-
142
- response_json: Union[Dict, List] = r.json()
143
- if response_json is None:
144
- return False
145
-
146
- if isinstance(response_json, dict) and response_json.get("status") == "success":
147
- return True
148
- return False
149
- except Exception as e:
150
- logger.debug(f"Could not log workspace event: {e}")
151
- return False
agno/cli/auth_server.py DELETED
@@ -1,118 +0,0 @@
1
- from http.server import BaseHTTPRequestHandler, HTTPServer
2
- from typing import Optional
3
-
4
- from agno.cli.settings import agno_cli_settings
5
-
6
-
7
- class CliAuthRequestHandler(BaseHTTPRequestHandler):
8
- """Request Handler to accept the CLI auth token after the web based auth flow.
9
- References:
10
- https://medium.com/@hasinthaindrajee/browser-sso-for-cli-applications-b0be743fa656
11
- https://gist.github.com/mdonkers/63e115cc0c79b4f6b8b3a6b797e485c7
12
-
13
- TODO:
14
- * Fix the header and limit to only localhost or agno.com
15
- """
16
-
17
- def _set_response(self):
18
- self.send_response(204)
19
- self.send_header("Access-Control-Allow-Origin", "*")
20
- self.send_header("Access-Control-Allow-Headers", "*")
21
- self.send_header("Access-Control-Allow-Methods", "POST")
22
- self.end_headers()
23
-
24
- # def do_GET(self):
25
- # logger.info("GET request,\nPath: %s\nHeaders:\n%s\n", str(self.path), str(self.headers))
26
- # self._set_response()
27
- # self.wfile.write("GET request for {}".format(self.path).encode('utf-8'))
28
-
29
- def do_OPTIONS(self):
30
- # logger.debug(
31
- # "OPTIONS request,\nPath: %s\nHeaders:\n%s\n",
32
- # str(self.path),
33
- # str(self.headers),
34
- # )
35
- self._set_response()
36
- # self.wfile.write("OPTIONS request for {}".format(self.path).encode('utf-8'))
37
-
38
- def do_POST(self):
39
- content_length = int(self.headers["Content-Length"]) # <--- Gets the size of data
40
- post_data = self.rfile.read(content_length) # <--- Gets the data itself
41
- decoded_post_data = post_data.decode("utf-8")
42
- # logger.debug(
43
- # "POST request,\nPath: {}\nHeaders:\n{}\n\nBody:\n{}\n".format(
44
- # str(self.path), str(self.headers), decoded_post_data
45
- # )
46
- # )
47
- # logger.debug("Data: {}".format(decoded_post_data))
48
- # logger.info("type: {}".format(type(post_data)))
49
- agno_cli_settings.tmp_token_path.parent.mkdir(parents=True, exist_ok=True)
50
- agno_cli_settings.tmp_token_path.touch(exist_ok=True)
51
- agno_cli_settings.tmp_token_path.write_text(decoded_post_data)
52
- # TODO: Add checks before shutting down the server
53
- self.server.running = False # type: ignore
54
- self._set_response()
55
-
56
- def log_message(self, format, *args):
57
- pass
58
-
59
-
60
- class CliAuthServer:
61
- """
62
- Source: https://stackoverflow.com/a/38196725/10953921
63
- """
64
-
65
- def __init__(self, port: int = 9191):
66
- import threading
67
-
68
- self._server = HTTPServer(("", port), CliAuthRequestHandler)
69
- self._thread = threading.Thread(target=self.run)
70
- self._thread.daemon = True
71
- self._server.running = False # type: ignore
72
-
73
- def run(self):
74
- self._server.running = True # type: ignore
75
- while self._server.running: # type: ignore
76
- self._server.handle_request()
77
-
78
- def start(self):
79
- self._thread.start()
80
-
81
- def shut_down(self):
82
- self._thread.close() # type: ignore
83
-
84
-
85
- def check_port(port: int):
86
- import socket
87
-
88
- with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
89
- try:
90
- return s.connect_ex(("localhost", port)) == 0
91
- except Exception as e:
92
- print(f"Error occurred: {e}")
93
- return False
94
-
95
-
96
- def get_port_for_auth_server():
97
- starting_port = 9191
98
- for port in range(starting_port, starting_port + 100):
99
- if not check_port(port):
100
- return port
101
-
102
-
103
- def get_auth_token_from_web_flow(port: int) -> Optional[str]:
104
- """
105
- GET request: curl http://localhost:9191
106
- POST request: curl -d "foo=bar&bin=baz" http://localhost:9191
107
- """
108
- import json
109
-
110
- server = CliAuthServer(port)
111
- server.run()
112
-
113
- if agno_cli_settings.tmp_token_path.exists() and agno_cli_settings.tmp_token_path.is_file():
114
- auth_token_str = agno_cli_settings.tmp_token_path.read_text()
115
- auth_token_json = json.loads(auth_token_str)
116
- agno_cli_settings.tmp_token_path.unlink()
117
- return auth_token_json.get("AuthToken", None)
118
- return None
agno/cli/config.py DELETED
@@ -1,275 +0,0 @@
1
- from collections import OrderedDict
2
- from pathlib import Path
3
- from typing import Dict, List, Optional
4
-
5
- from agno.api.schemas.team import TeamSchema
6
- from agno.api.schemas.user import UserSchema
7
- from agno.api.schemas.workspace import WorkspaceSchema
8
- from agno.cli.console import print_heading, print_info
9
- from agno.cli.settings import agno_cli_settings
10
- from agno.utils.json_io import read_json_file, write_json_file
11
- from agno.utils.log import logger
12
- from agno.workspace.config import WorkspaceConfig
13
-
14
-
15
- class AgnoCliConfig:
16
- """The AgnoCliConfig class manages user data for the agno cli"""
17
-
18
- def __init__(
19
- self,
20
- user: Optional[UserSchema] = None,
21
- active_ws_dir: Optional[str] = None,
22
- ws_config_map: Optional[Dict[str, WorkspaceConfig]] = None,
23
- ) -> None:
24
- # Current user, populated after authenticating with the api
25
- # To add a user, use the user setter
26
- self._user: Optional[UserSchema] = user
27
-
28
- # Active ws dir - used as the default for `ag` commands
29
- # To add an active workspace, use the active_ws_dir setter
30
- self._active_ws_dir: Optional[str] = active_ws_dir
31
-
32
- # Mapping from ws_root_path to ws_config
33
- self.ws_config_map: Dict[str, WorkspaceConfig] = ws_config_map or OrderedDict()
34
-
35
- ######################################################
36
- ## User functions
37
- ######################################################
38
-
39
- @property
40
- def user(self) -> Optional[UserSchema]:
41
- return self._user
42
-
43
- @user.setter
44
- def user(self, user: Optional[UserSchema]) -> None:
45
- """Sets the user"""
46
- if user is not None:
47
- logger.debug(f"Setting user to: {user.email}")
48
- clear_user_cache = (
49
- self._user is not None # previous user is not None
50
- and self._user.email != "anon" # previous user is not anon
51
- and (user.email != self._user.email or user.id_user != self._user.id_user) # new user is different
52
- )
53
- self._user = user
54
- if clear_user_cache:
55
- self.clear_user_cache()
56
- self.save_config()
57
-
58
- def clear_user_cache(self) -> None:
59
- """Clears the user cache"""
60
- logger.debug("Clearing user cache")
61
- self.ws_config_map.clear()
62
- self._active_ws_dir = None
63
- agno_cli_settings.ai_conversations_path.unlink(missing_ok=True)
64
- logger.info("Workspaces cleared, please setup again using `ag ws setup`")
65
-
66
- ######################################################
67
- ## Workspace functions
68
- ######################################################
69
-
70
- @property
71
- def active_ws_dir(self) -> Optional[str]:
72
- return self._active_ws_dir
73
-
74
- def set_active_ws_dir(self, ws_root_path: Optional[Path]) -> None:
75
- if ws_root_path is not None:
76
- logger.debug(f"Setting active workspace to: {str(ws_root_path)}")
77
- self._active_ws_dir = str(ws_root_path)
78
- self.save_config()
79
-
80
- @property
81
- def available_ws(self) -> List[WorkspaceConfig]:
82
- return list(self.ws_config_map.values())
83
-
84
- def _add_or_update_ws_config(
85
- self,
86
- ws_root_path: Path,
87
- ws_schema: Optional[WorkspaceSchema] = None,
88
- ws_team: Optional[TeamSchema] = None,
89
- ws_api_key: Optional[str] = None,
90
- ) -> Optional[WorkspaceConfig]:
91
- """The main function to create, update or refresh a WorkspaceConfig.
92
-
93
- This function does not call self.save_config(). Remember to save_config() after calling this function.
94
- """
95
-
96
- # Validate ws_root_path
97
- if ws_root_path is None or not isinstance(ws_root_path, Path):
98
- raise ValueError(f"Invalid ws_root: {ws_root_path}")
99
- ws_root_str = str(ws_root_path)
100
-
101
- ######################################################
102
- # Create new ws_config if one does not exist
103
- ######################################################
104
- if ws_root_str not in self.ws_config_map:
105
- logger.debug(f"Creating workspace at: {ws_root_str}")
106
- new_workspace_config = WorkspaceConfig(
107
- ws_root_path=ws_root_path,
108
- ws_schema=ws_schema,
109
- ws_team=ws_team,
110
- ws_api_key=ws_api_key,
111
- )
112
- self.ws_config_map[ws_root_str] = new_workspace_config
113
- logger.debug(f"Workspace created at: {ws_root_str}")
114
-
115
- # Return the new_workspace_config
116
- return new_workspace_config
117
-
118
- ######################################################
119
- # Update ws_config
120
- ######################################################
121
- logger.debug(f"Updating workspace at: {ws_root_str}")
122
- # By this point there should be a WorkspaceConfig object for this ws_name
123
- existing_ws_config: Optional[WorkspaceConfig] = self.ws_config_map.get(ws_root_str, None)
124
- if existing_ws_config is None:
125
- logger.error(f"Could not find workspace at: {ws_root_str}, please run `ag ws setup`")
126
- return None
127
-
128
- # Update the ws_schema if it's not None and different from the existing one
129
- if ws_schema is not None and existing_ws_config.ws_schema != ws_schema:
130
- existing_ws_config.ws_schema = ws_schema
131
-
132
- # Update the ws_team if it's not None and different from the existing one
133
- if ws_team is not None and existing_ws_config.ws_team != ws_team:
134
- existing_ws_config.ws_team = ws_team
135
-
136
- # Update the ws_api_key if it's not None and different from the existing one
137
- if ws_api_key is not None and existing_ws_config.ws_api_key != ws_api_key:
138
- existing_ws_config.ws_api_key = ws_api_key
139
-
140
- # Swap the existing ws_config with the updated one
141
- self.ws_config_map[ws_root_str] = existing_ws_config
142
-
143
- # Return the updated_ws_config
144
- return existing_ws_config
145
-
146
- def add_new_ws_to_config(
147
- self, ws_root_path: Path, ws_team: Optional[TeamSchema] = None
148
- ) -> Optional[WorkspaceConfig]:
149
- """Adds a newly created workspace to the AgnoCliConfig"""
150
-
151
- ws_config = self._add_or_update_ws_config(ws_root_path=ws_root_path, ws_team=ws_team)
152
- self.save_config()
153
- return ws_config
154
-
155
- def create_or_update_ws_config(
156
- self,
157
- ws_root_path: Path,
158
- ws_schema: Optional[WorkspaceSchema] = None,
159
- ws_team: Optional[TeamSchema] = None,
160
- set_as_active: bool = True,
161
- ) -> Optional[WorkspaceConfig]:
162
- """Creates or updates a WorkspaceConfig and returns the WorkspaceConfig"""
163
-
164
- ws_config = self._add_or_update_ws_config(
165
- ws_root_path=ws_root_path,
166
- ws_schema=ws_schema,
167
- ws_team=ws_team,
168
- )
169
- if set_as_active:
170
- self._active_ws_dir = str(ws_root_path)
171
- self.save_config()
172
- return ws_config
173
-
174
- def delete_ws(self, ws_root_path: Path) -> None:
175
- """Handles Deleting a workspace from the AgnoCliConfig and api"""
176
-
177
- ws_root_str = str(ws_root_path)
178
- print_heading(f"Deleting record for workspace: {ws_root_str}")
179
-
180
- ws_config: Optional[WorkspaceConfig] = self.ws_config_map.pop(ws_root_str, None)
181
- if ws_config is None:
182
- logger.warning(f"No record of workspace at {ws_root_str}")
183
- return
184
-
185
- # Check if we're deleting the active workspace, if yes, unset the active ws
186
- if self._active_ws_dir is not None and self._active_ws_dir == ws_root_str:
187
- print_info(f"Removing {ws_root_str} as the active workspace")
188
- self._active_ws_dir = None
189
- self.save_config()
190
- print_info("Workspace record deleted")
191
- print_info("Note: this does not delete any data locally or from agno.com, please delete them manually\n")
192
-
193
- def get_ws_config_by_dir_name(self, ws_dir_name: str) -> Optional[WorkspaceConfig]:
194
- ws_root_str: Optional[str] = None
195
- for k, v in self.ws_config_map.items():
196
- if v.ws_root_path.stem == ws_dir_name:
197
- ws_root_str = k
198
- break
199
-
200
- if ws_root_str is None or ws_root_str not in self.ws_config_map:
201
- return None
202
-
203
- return self.ws_config_map[ws_root_str]
204
-
205
- def get_ws_config_by_path(self, ws_root_path: Path) -> Optional[WorkspaceConfig]:
206
- return self.ws_config_map[str(ws_root_path)] if str(ws_root_path) in self.ws_config_map else None
207
-
208
- def get_active_ws_config(self) -> Optional[WorkspaceConfig]:
209
- if self.active_ws_dir is not None and self.active_ws_dir in self.ws_config_map:
210
- return self.ws_config_map[self.active_ws_dir]
211
- return None
212
-
213
- ######################################################
214
- ## Save AgnoCliConfig
215
- ######################################################
216
-
217
- def save_config(self):
218
- config_data = {
219
- "user": self.user.model_dump() if self.user else None,
220
- "active_ws_dir": self.active_ws_dir,
221
- "ws_config_map": {k: v.to_dict() for k, v in self.ws_config_map.items()},
222
- }
223
- write_json_file(file_path=agno_cli_settings.config_file_path, data=config_data)
224
-
225
- @classmethod
226
- def from_saved_config(cls) -> Optional["AgnoCliConfig"]:
227
- try:
228
- config_data = read_json_file(file_path=agno_cli_settings.config_file_path)
229
- if config_data is None or not isinstance(config_data, dict):
230
- logger.debug("No config found")
231
- return None
232
-
233
- user_dict = config_data.get("user")
234
- user_schema = UserSchema.model_validate(user_dict) if user_dict else None
235
- active_ws_dir = config_data.get("active_ws_dir")
236
-
237
- # Create a new config
238
- new_config = cls(user_schema, active_ws_dir)
239
-
240
- # Add all the workspaces
241
- for k, v in config_data.get("ws_config_map", {}).items():
242
- _ws_config = WorkspaceConfig.model_validate(v)
243
- if _ws_config is not None:
244
- new_config.ws_config_map[k] = _ws_config
245
- return new_config
246
- except Exception as e:
247
- logger.warning(e)
248
- logger.warning("Please setup the workspace using `ag ws setup`")
249
- return None
250
-
251
- ######################################################
252
- ## Print AgnoCliConfig
253
- ######################################################
254
-
255
- def print_to_cli(self, show_all: bool = False):
256
- if self.user:
257
- print_heading(f"User: {self.user.email}\n")
258
- if self.active_ws_dir:
259
- print_heading(f"Active workspace directory: {self.active_ws_dir}\n")
260
- else:
261
- print_info("No active workspace found.")
262
- print_info(
263
- "Please create a workspace using `ag ws create` or setup an existing workspace using `ag ws setup`"
264
- )
265
-
266
- if show_all and len(self.ws_config_map) > 0:
267
- print_heading("Available workspaces:\n")
268
- c = 1
269
- for k, v in self.ws_config_map.items():
270
- print_info(f" {c}. Path: {k}")
271
- if v.ws_schema and v.ws_schema.ws_name:
272
- print_info(f" Name: {v.ws_schema.ws_name}")
273
- if v.ws_team and v.ws_team.name:
274
- print_info(f" Team: {v.ws_team.name}")
275
- c += 1
agno/cli/console.py DELETED
@@ -1,88 +0,0 @@
1
- from rich.console import Console
2
- from rich.style import Style
3
-
4
- from agno.utils.log import logger
5
-
6
- console = Console()
7
-
8
- ######################################################
9
- ## Styles
10
- # Standard Colors: https://rich.readthedocs.io/en/stable/appendix/colors.html#appendix-colors
11
- ######################################################
12
-
13
- heading_style = Style(
14
- color="green",
15
- bold=True,
16
- underline=True,
17
- )
18
- subheading_style = Style(
19
- color="chartreuse3",
20
- bold=True,
21
- )
22
- success_style = Style(color="chartreuse3")
23
- fail_style = Style(color="red")
24
- error_style = Style(color="red")
25
- info_style = Style()
26
- warn_style = Style(color="magenta")
27
-
28
-
29
- ######################################################
30
- ## Print functions
31
- ######################################################
32
-
33
-
34
- def print_heading(msg: str) -> None:
35
- console.print(msg, style=heading_style)
36
-
37
-
38
- def print_subheading(msg: str) -> None:
39
- console.print(msg, style=subheading_style)
40
-
41
-
42
- def print_info(msg: str) -> None:
43
- console.print(msg, style=info_style)
44
-
45
-
46
- def log_config_not_available_msg() -> None:
47
- logger.error("Agno config not found, please run `ag init` and try again")
48
-
49
-
50
- def log_active_workspace_not_available() -> None:
51
- logger.error("Could not find an active workspace. You can:")
52
- logger.error("- Run `ag ws setup` to setup a workspace at the current path")
53
- logger.error("- Run `ag ws create` to create a new workspace")
54
-
55
-
56
- def print_available_workspaces(avl_ws_list) -> None:
57
- avl_ws_names = [w.ws_root_path.stem for w in avl_ws_list] if avl_ws_list else []
58
- print_info("Available Workspaces:\n - {}".format("\n - ".join(avl_ws_names)))
59
-
60
-
61
- def confirm_yes_no(question, default: str = "yes") -> bool:
62
- """Ask a yes/no question via raw_input().
63
-
64
- "question" is a string that is presented to the user.
65
- "default" is the presumed answer if the user just hits <Enter>.
66
- It must be "yes" (the default), "no" or None (meaning
67
- an answer is required of the user).
68
-
69
- The "answer" return value is True for "yes" or False for "no".
70
- """
71
- inp_to_result_map = {"yes": True, "y": True, "ye": True, "no": False, "n": False}
72
- if default is None:
73
- prompt = " [y/n]: "
74
- elif default == "yes":
75
- prompt = " [Y/n]: "
76
- elif default == "no":
77
- prompt = " [y/N]: "
78
- else:
79
- raise ValueError(f"Invalid default answer: {default}")
80
-
81
- choice = console.input(prompt=(question + prompt)).lower()
82
- if default is not None and choice == "":
83
- return inp_to_result_map[default]
84
- elif choice in inp_to_result_map:
85
- return inp_to_result_map[choice]
86
- else:
87
- logger.error(f"{choice} invalid")
88
- return False
agno/cli/credentials.py DELETED
@@ -1,23 +0,0 @@
1
- from typing import Dict, Optional
2
-
3
- from agno.cli.settings import agno_cli_settings
4
- from agno.utils.json_io import read_json_file, write_json_file
5
-
6
-
7
- def save_auth_token(auth_token: str):
8
- # logger.debug(f"Storing {auth_token} to {str(agno_cli_settings.credentials_path)}")
9
- _data = {"token": auth_token}
10
- write_json_file(agno_cli_settings.credentials_path, _data)
11
-
12
-
13
- def read_auth_token() -> Optional[str]:
14
- # logger.debug(f"Reading token from {str(agno_cli_settings.credentials_path)}")
15
- _data: Dict = read_json_file(agno_cli_settings.credentials_path) # type: ignore
16
- if _data is None:
17
- return None
18
-
19
- try:
20
- return _data.get("token")
21
- except Exception:
22
- pass
23
- return None