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
@@ -1,421 +0,0 @@
1
- import json
2
- from dataclasses import asdict
3
- from io import BytesIO
4
- from typing import AsyncGenerator, List, Optional, cast
5
-
6
- from fastapi import APIRouter, File, Form, HTTPException, Query, UploadFile
7
- from fastapi.responses import JSONResponse, StreamingResponse
8
-
9
- from agno.agent.agent import Agent, RunResponse
10
- from agno.media import Audio, Image, Video
11
- from agno.playground.operator import (
12
- format_tools,
13
- get_agent_by_id,
14
- get_session_title,
15
- get_session_title_from_workflow_session,
16
- get_workflow_by_id,
17
- )
18
- from agno.playground.schemas import (
19
- AgentGetResponse,
20
- AgentModel,
21
- AgentRenameRequest,
22
- AgentSessionsResponse,
23
- WorkflowGetResponse,
24
- WorkflowRenameRequest,
25
- WorkflowRunRequest,
26
- WorkflowSessionResponse,
27
- WorkflowsGetResponse,
28
- )
29
- from agno.storage.agent.session import AgentSession
30
- from agno.storage.workflow.session import WorkflowSession
31
- from agno.utils.log import logger
32
- from agno.workflow.workflow import Workflow
33
-
34
-
35
- def get_async_playground_router(
36
- agents: Optional[List[Agent]] = None, workflows: Optional[List[Workflow]] = None
37
- ) -> APIRouter:
38
- playground_router = APIRouter(prefix="/playground", tags=["Playground"])
39
-
40
- if agents is None and workflows is None:
41
- raise ValueError("Either agents or workflows must be provided.")
42
-
43
- @playground_router.get("/status")
44
- async def playground_status():
45
- return {"playground": "available"}
46
-
47
- @playground_router.get("/agents", response_model=List[AgentGetResponse])
48
- async def get_agents():
49
- agent_list: List[AgentGetResponse] = []
50
- if agents is None:
51
- return agent_list
52
-
53
- for agent in agents:
54
- agent_tools = agent.get_tools()
55
- formatted_tools = format_tools(agent_tools)
56
-
57
- name = agent.model.name or agent.model.__class__.__name__ if agent.model else None
58
- provider = agent.model.provider or agent.model.__class__.__name__ if agent.model else ""
59
- model_id = agent.model.id if agent.model else None
60
-
61
- # Create an agent_id if its not set on the agent
62
- if agent.agent_id is None:
63
- agent.set_agent_id()
64
-
65
- if provider and model_id:
66
- provider = f"{provider} {model_id}"
67
- elif name and model_id:
68
- provider = f"{name} {model_id}"
69
- elif model_id:
70
- provider = model_id
71
- else:
72
- provider = ""
73
-
74
- agent_list.append(
75
- AgentGetResponse(
76
- agent_id=agent.agent_id,
77
- name=agent.name,
78
- model=AgentModel(
79
- name=name,
80
- model=model_id,
81
- provider=provider,
82
- ),
83
- add_context=agent.add_context,
84
- tools=formatted_tools,
85
- memory={"name": agent.memory.db.__class__.__name__} if agent.memory and agent.memory.db else None,
86
- storage={"name": agent.storage.__class__.__name__} if agent.storage else None,
87
- knowledge={"name": agent.knowledge.__class__.__name__} if agent.knowledge else None,
88
- description=agent.description,
89
- instructions=agent.instructions,
90
- )
91
- )
92
-
93
- return agent_list
94
-
95
- async def chat_response_streamer(
96
- agent: Agent,
97
- message: str,
98
- images: Optional[List[Image]] = None,
99
- audio: Optional[List[Audio]] = None,
100
- videos: Optional[List[Video]] = None,
101
- ) -> AsyncGenerator:
102
- run_response = await agent.arun(
103
- message,
104
- images=images,
105
- audio=audio,
106
- videos=videos,
107
- stream=True,
108
- stream_intermediate_steps=True,
109
- )
110
- async for run_response_chunk in run_response:
111
- run_response_chunk = cast(RunResponse, run_response_chunk)
112
- yield run_response_chunk.to_json()
113
-
114
- async def process_image(file: UploadFile) -> Image:
115
- content = file.file.read()
116
-
117
- return Image(content=content)
118
-
119
- @playground_router.post("/agents/{agent_id}/runs")
120
- async def create_agent_run(
121
- agent_id: str,
122
- message: str = Form(...),
123
- stream: bool = Form(True),
124
- monitor: bool = Form(False),
125
- session_id: Optional[str] = Form(None),
126
- user_id: Optional[str] = Form(None),
127
- files: Optional[List[UploadFile]] = File(None),
128
- image: Optional[UploadFile] = File(None),
129
- ):
130
- logger.debug(f"AgentRunRequest: {message} {session_id} {user_id} {agent_id}")
131
- agent = get_agent_by_id(agent_id, agents)
132
- if agent is None:
133
- raise HTTPException(status_code=404, detail="Agent not found")
134
-
135
- if files:
136
- if agent.knowledge is None:
137
- raise HTTPException(status_code=404, detail="KnowledgeBase not found")
138
-
139
- if session_id is not None:
140
- logger.debug(f"Continuing session: {session_id}")
141
- else:
142
- logger.debug("Creating new session")
143
-
144
- # Create a new instance of this agent
145
- new_agent_instance = agent.deep_copy(update={"session_id": session_id})
146
- if user_id is not None:
147
- new_agent_instance.user_id = user_id
148
-
149
- if monitor:
150
- new_agent_instance.monitoring = True
151
- else:
152
- new_agent_instance.monitoring = False
153
-
154
- base64_image: Optional[Image] = None
155
- if image:
156
- base64_image = await process_image(image)
157
-
158
- if files:
159
- for file in files:
160
- if file.content_type == "application/pdf":
161
- from agno.document.reader.pdf_reader import PDFReader
162
-
163
- contents = await file.read()
164
- pdf_file = BytesIO(contents)
165
- pdf_file.name = file.filename
166
- file_content = PDFReader().read(pdf_file)
167
- if agent.knowledge is not None:
168
- agent.knowledge.load_documents(file_content)
169
- elif file.content_type == "text/csv":
170
- from agno.document.reader.csv_reader import CSVReader
171
-
172
- contents = await file.read()
173
- csv_file = BytesIO(contents)
174
- csv_file.name = file.filename
175
- file_content = CSVReader().read(csv_file)
176
- if agent.knowledge is not None:
177
- agent.knowledge.load_documents(file_content)
178
- elif file.content_type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
179
- from agno.document.reader.docx_reader import DocxReader
180
-
181
- contents = await file.read()
182
- docx_file = BytesIO(contents)
183
- docx_file.name = file.filename
184
- file_content = DocxReader().read(docx_file)
185
- if agent.knowledge is not None:
186
- agent.knowledge.load_documents(file_content)
187
- elif file.content_type == "text/plain":
188
- from agno.document.reader.text_reader import TextReader
189
-
190
- contents = await file.read()
191
- text_file = BytesIO(contents)
192
- text_file.name = file.filename
193
- file_content = TextReader().read(text_file)
194
- if agent.knowledge is not None:
195
- agent.knowledge.load_documents(file_content)
196
- else:
197
- raise HTTPException(status_code=400, detail="Unsupported file type")
198
-
199
- if stream:
200
- return StreamingResponse(
201
- chat_response_streamer(new_agent_instance, message, images=[base64_image] if base64_image else None),
202
- media_type="text/event-stream",
203
- )
204
- else:
205
- run_response = cast(
206
- RunResponse,
207
- await new_agent_instance.arun(
208
- message,
209
- images=[base64_image] if base64_image else None,
210
- stream=False,
211
- ),
212
- )
213
- return run_response
214
-
215
- @playground_router.get("/agents/{agent_id}/sessions")
216
- async def get_all_agent_sessions(agent_id: str, user_id: str = Query(..., min_length=1)):
217
- logger.debug(f"AgentSessionsRequest: {agent_id} {user_id}")
218
- agent = get_agent_by_id(agent_id, agents)
219
- if agent is None:
220
- return JSONResponse(status_code=404, content="Agent not found.")
221
-
222
- if agent.storage is None:
223
- return JSONResponse(status_code=404, content="Agent does not have storage enabled.")
224
-
225
- agent_sessions: List[AgentSessionsResponse] = []
226
- all_agent_sessions: List[AgentSession] = agent.storage.get_all_sessions(user_id=user_id)
227
- for session in all_agent_sessions:
228
- title = get_session_title(session)
229
- agent_sessions.append(
230
- AgentSessionsResponse(
231
- title=title,
232
- session_id=session.session_id,
233
- session_name=session.session_data.get("session_name") if session.session_data else None,
234
- created_at=session.created_at,
235
- )
236
- )
237
- return agent_sessions
238
-
239
- @playground_router.get("/agents/{agent_id}/sessions/{session_id}")
240
- async def get_agent_session(agent_id: str, session_id: str, user_id: str = Query(..., min_length=1)):
241
- logger.debug(f"AgentSessionsRequest: {agent_id} {user_id} {session_id}")
242
- agent = get_agent_by_id(agent_id, agents)
243
- if agent is None:
244
- return JSONResponse(status_code=404, content="Agent not found.")
245
-
246
- if agent.storage is None:
247
- return JSONResponse(status_code=404, content="Agent does not have storage enabled.")
248
-
249
- agent_session: Optional[AgentSession] = agent.storage.read(session_id, user_id)
250
- if agent_session is None:
251
- return JSONResponse(status_code=404, content="Session not found.")
252
-
253
- return agent_session
254
-
255
- @playground_router.post("/agents/{agent_id}/sessions/{session_id}/rename")
256
- async def rename_agent_session(agent_id: str, session_id: str, body: AgentRenameRequest):
257
- agent = get_agent_by_id(agent_id, agents)
258
- if agent is None:
259
- return JSONResponse(status_code=404, content=f"couldn't find agent with {agent_id}")
260
-
261
- if agent.storage is None:
262
- return JSONResponse(status_code=404, content="Agent does not have storage enabled.")
263
-
264
- all_agent_sessions: List[AgentSession] = agent.storage.get_all_sessions(user_id=body.user_id)
265
- for session in all_agent_sessions:
266
- if session.session_id == session_id:
267
- agent.session_id = session_id
268
- agent.rename_session(body.name)
269
- return JSONResponse(content={"message": f"successfully renamed agent {agent.name}"})
270
-
271
- return JSONResponse(status_code=404, content="Session not found.")
272
-
273
- @playground_router.delete("/agents/{agent_id}/sessions/{session_id}")
274
- async def delete_agent_session(agent_id: str, session_id: str, user_id: str = Query(..., min_length=1)):
275
- agent = get_agent_by_id(agent_id, agents)
276
- if agent is None:
277
- return JSONResponse(status_code=404, content="Agent not found.")
278
-
279
- if agent.storage is None:
280
- return JSONResponse(status_code=404, content="Agent does not have storage enabled.")
281
-
282
- all_agent_sessions: List[AgentSession] = agent.storage.get_all_sessions(user_id=user_id)
283
- for session in all_agent_sessions:
284
- if session.session_id == session_id:
285
- agent.delete_session(session_id)
286
- return JSONResponse(content={"message": f"successfully deleted agent {agent.name}"})
287
-
288
- return JSONResponse(status_code=404, content="Session not found.")
289
-
290
- @playground_router.get("/workflows", response_model=List[WorkflowsGetResponse])
291
- async def get_workflows():
292
- if workflows is None:
293
- return []
294
-
295
- return [
296
- WorkflowsGetResponse(
297
- workflow_id=str(workflow.workflow_id),
298
- name=workflow.name,
299
- description=workflow.description,
300
- )
301
- for workflow in workflows
302
- ]
303
-
304
- @playground_router.get("/workflows/{workflow_id}", response_model=WorkflowGetResponse)
305
- async def get_workflow(workflow_id: str):
306
- workflow = get_workflow_by_id(workflow_id, workflows)
307
- if workflow is None:
308
- raise HTTPException(status_code=404, detail="Workflow not found")
309
-
310
- return WorkflowGetResponse(
311
- workflow_id=workflow.workflow_id,
312
- name=workflow.name,
313
- description=workflow.description,
314
- parameters=workflow._run_parameters or {},
315
- storage=workflow.storage.__class__.__name__ if workflow.storage else None,
316
- )
317
-
318
- @playground_router.post("/workflows/{workflow_id}/runs")
319
- async def create_workflow_run(workflow_id: str, body: WorkflowRunRequest):
320
- # Retrieve the workflow by ID
321
- workflow = get_workflow_by_id(workflow_id, workflows)
322
- if workflow is None:
323
- raise HTTPException(status_code=404, detail="Workflow not found")
324
-
325
- if body.session_id is not None:
326
- logger.debug(f"Continuing session: {body.session_id}")
327
- else:
328
- logger.debug("Creating new session")
329
-
330
- # Create a new instance of this workflow
331
- new_workflow_instance = workflow.deep_copy(update={"workflow_id": workflow_id, "session_id": body.session_id})
332
- new_workflow_instance.user_id = body.user_id
333
- new_workflow_instance.session_name = None
334
-
335
- # Return based on the response type
336
- try:
337
- if new_workflow_instance._run_return_type == "RunResponse":
338
- # Return as a normal response
339
- return new_workflow_instance.run(**body.input)
340
- else:
341
- # Return as a streaming response
342
- return StreamingResponse(
343
- (json.dumps(asdict(result)) for result in new_workflow_instance.run(**body.input)),
344
- media_type="text/event-stream",
345
- )
346
- except Exception as e:
347
- # Handle unexpected runtime errors
348
- raise HTTPException(status_code=500, detail=f"Error running workflow: {str(e)}")
349
-
350
- @playground_router.get("/workflows/{workflow_id}/sessions", response_model=List[WorkflowSessionResponse])
351
- async def get_all_workflow_sessions(workflow_id: str, user_id: str = Query(..., min_length=1)):
352
- # Retrieve the workflow by ID
353
- workflow = get_workflow_by_id(workflow_id, workflows)
354
- if not workflow:
355
- raise HTTPException(status_code=404, detail="Workflow not found")
356
-
357
- # Ensure storage is enabled for the workflow
358
- if not workflow.storage:
359
- raise HTTPException(status_code=404, detail="Workflow does not have storage enabled")
360
-
361
- # Retrieve all sessions for the given workflow and user
362
- try:
363
- all_workflow_sessions: List[WorkflowSession] = workflow.storage.get_all_sessions(
364
- user_id=user_id, workflow_id=workflow_id
365
- )
366
- except Exception as e:
367
- raise HTTPException(status_code=500, detail=f"Error retrieving sessions: {str(e)}")
368
-
369
- # Return the sessions
370
- return [
371
- WorkflowSessionResponse(
372
- title=get_session_title_from_workflow_session(session),
373
- session_id=session.session_id,
374
- session_name=session.session_data.get("session_name") if session.session_data else None,
375
- created_at=session.created_at,
376
- )
377
- for session in all_workflow_sessions
378
- ]
379
-
380
- @playground_router.get("/workflows/{workflow_id}/sessions/{session_id}")
381
- async def get_workflow_session(workflow_id: str, session_id: str, user_id: str = Query(..., min_length=1)):
382
- # Retrieve the workflow by ID
383
- workflow = get_workflow_by_id(workflow_id, workflows)
384
- if not workflow:
385
- raise HTTPException(status_code=404, detail="Workflow not found")
386
-
387
- # Ensure storage is enabled for the workflow
388
- if not workflow.storage:
389
- raise HTTPException(status_code=404, detail="Workflow does not have storage enabled")
390
-
391
- # Retrieve the specific session
392
- try:
393
- workflow_session: Optional[WorkflowSession] = workflow.storage.read(session_id, user_id)
394
- except Exception as e:
395
- raise HTTPException(status_code=500, detail=f"Error retrieving session: {str(e)}")
396
-
397
- if not workflow_session:
398
- raise HTTPException(status_code=404, detail="Session not found")
399
-
400
- # Return the session
401
- return workflow_session
402
-
403
- @playground_router.post("/workflows/{workflow_id}/sessions/{session_id}/rename")
404
- async def rename_workflow_session(workflow_id: str, session_id: str, body: WorkflowRenameRequest):
405
- workflow = get_workflow_by_id(workflow_id, workflows)
406
- if workflow is None:
407
- raise HTTPException(status_code=404, detail="Workflow not found")
408
- workflow.session_id = session_id
409
- workflow.rename_session(body.name)
410
- return JSONResponse(content={"message": f"successfully renamed workflow {workflow.name}"})
411
-
412
- @playground_router.delete("/workflows/{workflow_id}/sessions/{session_id}")
413
- async def delete_workflow_session(workflow_id: str, session_id: str):
414
- workflow = get_workflow_by_id(workflow_id, workflows)
415
- if workflow is None:
416
- raise HTTPException(status_code=404, detail="Workflow not found")
417
-
418
- workflow.delete_session(session_id)
419
- return JSONResponse(content={"message": f"successfully deleted workflow {workflow.name}"})
420
-
421
- return playground_router
agno/playground/deploy.py DELETED
@@ -1,249 +0,0 @@
1
- import tarfile
2
- from pathlib import Path
3
- from typing import List, Optional, cast
4
-
5
- from rich import box
6
- from rich.panel import Panel
7
- from rich.text import Text
8
-
9
- from agno.api.playground import deploy_playground_archive
10
- from agno.cli.settings import agno_cli_settings
11
- from agno.utils.log import logger
12
-
13
-
14
- def create_deployment_info(
15
- app: str, root: Path, elapsed_time: str = "[waiting...]", status: Optional[str] = None, error: Optional[str] = None
16
- ) -> Text:
17
- """Create a formatted text display showing deployment information.
18
-
19
- Args:
20
- app (str): The name of the application being deployed
21
- root (Path): The path to the root directory
22
- elapsed_time (str): The elapsed deployment time. Defaults to "[waiting...]"
23
- status (Optional[str]): The current deployment status. Defaults to None
24
- error (Optional[str]): The deployment error message. Defaults to None
25
-
26
- Returns:
27
- Text: A Rich Text object containing formatted deployment information
28
- """
29
- # Base info always shown
30
- elements = [
31
- ("📦 App: ", "bold"),
32
- (f"{app}\n", "cyan"),
33
- ("📂 Root: ", "bold"),
34
- (f"{root}\n", "cyan"),
35
- ("⏱️ Time: ", "bold"),
36
- (f"{elapsed_time}\n", "yellow"),
37
- ]
38
-
39
- # Add either status or error, not both
40
- if error is not None:
41
- elements.extend(
42
- [
43
- ("🚨 Error: ", "bold"),
44
- (f"{error}", "red"),
45
- ]
46
- )
47
- elif status is not None:
48
- elements.extend(
49
- [
50
- ("🚧 Status: ", "bold"),
51
- (f"{status}", "yellow"),
52
- ]
53
- )
54
-
55
- return Text.assemble(*elements)
56
-
57
-
58
- def create_info_panel(deployment_info: Text) -> Panel:
59
- """Create a formatted panel to display deployment information.
60
-
61
- Args:
62
- deployment_info (Text): The Rich Text object containing deployment information
63
-
64
- Returns:
65
- Panel: A Rich Panel object containing the formatted deployment information
66
- """
67
- return Panel(
68
- deployment_info,
69
- title="[bold green]🚀 Deploying Playground App[/bold green]",
70
- border_style="cyan",
71
- box=box.HEAVY,
72
- padding=(1, 2),
73
- )
74
-
75
-
76
- def create_error_panel(deployment_info: Text) -> Panel:
77
- """Create a formatted panel to display deployment error information.
78
-
79
- Args:
80
- deployment_info (Text): The Rich Text object containing deployment error information
81
-
82
- Returns:
83
- Panel: A Rich Panel object containing the formatted deployment error information
84
- """
85
- return Panel(
86
- deployment_info,
87
- title="[bold red]🚨 Deployment Failed[/bold red]",
88
- border_style="red",
89
- box=box.HEAVY,
90
- padding=(1, 2),
91
- )
92
-
93
-
94
- def create_tar_archive(root: Path) -> Path:
95
- """Create a gzipped tar archive of the playground files.
96
-
97
- Args:
98
- root (Path): The path to the directory to be archived
99
-
100
- Returns:
101
- Path: The path to the created tar archive
102
-
103
- Raises:
104
- Exception: If archive creation fails
105
- """
106
- tar_path = root.with_suffix(".tar.gz")
107
- try:
108
- logger.debug(f"Creating playground archive: {tar_path.name}")
109
- with tarfile.open(tar_path, "w:gz") as tar:
110
- tar.add(root, arcname=root.name)
111
- logger.debug(f"Successfully created playground archive: {tar_path.name}")
112
- return tar_path
113
- except Exception as e:
114
- logger.error(f"Failed to create playground archive: {e}")
115
- raise
116
-
117
-
118
- def deploy_archive(name: str, tar_path: Path) -> None:
119
- """Deploying the tar archive to agno-cloud.
120
-
121
- Args:
122
- name (str): The name of the playground app
123
- tar_path (Path): The path to the tar archive to be deployed
124
-
125
- Raises:
126
- Exception: If the deployment process fails
127
- """
128
- try:
129
- logger.debug(f"Deploying playground archive: {tar_path.name}")
130
- deploy_playground_archive(name=name, tar_path=tar_path)
131
- logger.debug(f"Successfully deployed playground archive: {tar_path.name}")
132
- except Exception:
133
- raise
134
-
135
-
136
- def cleanup_archive(tar_path: Path) -> None:
137
- """Delete the temporary tar archive after deployment.
138
-
139
- Args:
140
- tar_path (Path): The path to the tar archive to be deleted
141
-
142
- Raises:
143
- Exception: If the deletion process fails
144
- """
145
- try:
146
- logger.debug(f"Deleting playground archive: {tar_path.name}")
147
- tar_path.unlink()
148
- logger.debug(f"Successfully deleted playground archive: {tar_path.name}")
149
- except Exception as e:
150
- logger.error(f"Failed to delete playground archive: {e}")
151
- raise
152
-
153
-
154
- def deploy_playground_app(
155
- app: str,
156
- name: str,
157
- root: Optional[Path] = None,
158
- ) -> None:
159
- """Deploy a playground application to agno-cloud.
160
-
161
- This function:
162
- 1. Creates a tar archive of the root directory.
163
- 2. Uploades the archive to agno-cloud.
164
- 3. Cleaning up temporary files.
165
- 4. Displaying real-time progress updates.
166
-
167
- Args:
168
- app (str): The application to deploy as a string identifier.
169
- It should be the name of the module containing the Playground app from the root path.
170
- name (str): The name of the playground app.
171
- root (Optional[Path]): The root path containing the application files. Defaults to the current working directory.
172
-
173
- Raises:
174
- Exception: If any step of the deployment process fails
175
- """
176
-
177
- agno_cli_settings.gate_alpha_feature()
178
-
179
- from rich.console import Group
180
- from rich.live import Live
181
- from rich.status import Status
182
-
183
- from agno.utils.timer import Timer
184
-
185
- if app is None:
186
- raise ValueError("PlaygroundApp is required")
187
-
188
- if name is None:
189
- raise ValueError("PlaygroundApp name is required")
190
-
191
- with Live(refresh_per_second=4) as live_display:
192
- response_timer = Timer()
193
- response_timer.start()
194
- root = root or Path.cwd()
195
- root = cast(Path, root)
196
- try:
197
- deployment_info = create_deployment_info(app=app, root=root, status="Initializing...")
198
- panels: List[Panel] = [create_info_panel(deployment_info=deployment_info)]
199
-
200
- status = Status(
201
- "[bold blue]Initializing playground...[/bold blue]",
202
- spinner="aesthetic",
203
- speed=2,
204
- )
205
- panels.append(status) # type: ignore
206
- live_display.update(Group(*panels))
207
-
208
- # Step 1: Create archive
209
- status.update("[bold blue]Creating playground archive...[/bold blue]")
210
- tar_path = create_tar_archive(root=root)
211
- panels[0] = create_info_panel(
212
- create_deployment_info(
213
- app=app, root=root, elapsed_time=f"{response_timer.elapsed:.1f}s", status="Creating archive..."
214
- )
215
- )
216
- live_display.update(Group(*panels))
217
-
218
- # Step 2: Upload archive
219
- status.update("[bold blue]Uploading playground archive...[/bold blue]")
220
- deploy_archive(name=name, tar_path=tar_path)
221
- panels[0] = create_info_panel(
222
- create_deployment_info(
223
- app=app, root=root, elapsed_time=f"{response_timer.elapsed:.1f}s", status="Uploading archive..."
224
- )
225
- )
226
- live_display.update(Group(*panels))
227
-
228
- # Step 3: Cleanup
229
- status.update("[bold blue]Deleting playground archive...[/bold blue]")
230
- cleanup_archive(tar_path)
231
- panels[0] = create_info_panel(
232
- create_deployment_info(
233
- app=app, root=root, elapsed_time=f"{response_timer.elapsed:.1f}s", status="Deleting archive..."
234
- )
235
- )
236
- live_display.update(Group(*panels))
237
-
238
- # Final display update
239
- status.stop()
240
- panels.pop()
241
- live_display.update(Group(*panels))
242
- except Exception as e:
243
- status.update(f"[bold red]Deployment failed: {str(e)}[/bold red]")
244
- panels[0] = create_error_panel(
245
- create_deployment_info(app=app, root=root, elapsed_time=f"{response_timer.elapsed:.1f}s", error=str(e))
246
- )
247
- status.stop()
248
- panels.pop()
249
- live_display.update(Group(*panels))