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/run/workflow.py ADDED
@@ -0,0 +1,708 @@
1
+ from dataclasses import asdict, dataclass, field
2
+ from enum import Enum
3
+ from time import time
4
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
5
+
6
+ from pydantic import BaseModel
7
+
8
+ from agno.media import Audio, Image, Video
9
+ from agno.run.agent import RunEvent, RunOutput, run_output_event_from_dict
10
+ from agno.run.base import BaseRunOutputEvent, RunStatus
11
+ from agno.run.team import TeamRunEvent, TeamRunOutput, team_run_output_event_from_dict
12
+ from agno.utils.media import (
13
+ reconstruct_audio_list,
14
+ reconstruct_images,
15
+ reconstruct_response_audio,
16
+ reconstruct_videos,
17
+ )
18
+
19
+ if TYPE_CHECKING:
20
+ from agno.workflow.types import StepOutput, WorkflowMetrics
21
+ else:
22
+ StepOutput = Any
23
+ WorkflowMetrics = Any
24
+
25
+
26
+ class WorkflowRunEvent(str, Enum):
27
+ """Events that can be sent by workflow execution"""
28
+
29
+ workflow_started = "WorkflowStarted"
30
+ workflow_completed = "WorkflowCompleted"
31
+ workflow_cancelled = "WorkflowCancelled"
32
+ workflow_error = "WorkflowError"
33
+
34
+ workflow_agent_started = "WorkflowAgentStarted"
35
+ workflow_agent_completed = "WorkflowAgentCompleted"
36
+
37
+ step_started = "StepStarted"
38
+ step_completed = "StepCompleted"
39
+ step_error = "StepError"
40
+
41
+ loop_execution_started = "LoopExecutionStarted"
42
+ loop_iteration_started = "LoopIterationStarted"
43
+ loop_iteration_completed = "LoopIterationCompleted"
44
+ loop_execution_completed = "LoopExecutionCompleted"
45
+
46
+ parallel_execution_started = "ParallelExecutionStarted"
47
+ parallel_execution_completed = "ParallelExecutionCompleted"
48
+
49
+ condition_execution_started = "ConditionExecutionStarted"
50
+ condition_execution_completed = "ConditionExecutionCompleted"
51
+
52
+ router_execution_started = "RouterExecutionStarted"
53
+ router_execution_completed = "RouterExecutionCompleted"
54
+
55
+ steps_execution_started = "StepsExecutionStarted"
56
+ steps_execution_completed = "StepsExecutionCompleted"
57
+
58
+ step_output = "StepOutput"
59
+
60
+ custom_event = "CustomEvent"
61
+
62
+
63
+ @dataclass
64
+ class BaseWorkflowRunOutputEvent(BaseRunOutputEvent):
65
+ """Base class for all workflow run response events"""
66
+
67
+ created_at: int = field(default_factory=lambda: int(time()))
68
+ event: str = ""
69
+
70
+ # Workflow-specific fields
71
+ workflow_id: Optional[str] = None
72
+ workflow_name: Optional[str] = None
73
+ session_id: Optional[str] = None
74
+ run_id: Optional[str] = None
75
+ step_id: Optional[str] = None
76
+ parent_step_id: Optional[str] = None
77
+
78
+ def to_dict(self) -> Dict[str, Any]:
79
+ _dict = {k: v for k, v in asdict(self).items() if v is not None}
80
+
81
+ if hasattr(self, "content") and self.content and isinstance(self.content, BaseModel):
82
+ _dict["content"] = self.content.model_dump(exclude_none=True)
83
+
84
+ # Handle StepOutput fields that contain Message objects
85
+ if hasattr(self, "step_results") and self.step_results is not None:
86
+ _dict["step_results"] = [step.to_dict() if hasattr(step, "to_dict") else step for step in self.step_results]
87
+
88
+ if hasattr(self, "step_response") and self.step_response is not None:
89
+ _dict["step_response"] = (
90
+ self.step_response.to_dict() if hasattr(self.step_response, "to_dict") else self.step_response
91
+ )
92
+
93
+ if hasattr(self, "iteration_results") and self.iteration_results is not None:
94
+ _dict["iteration_results"] = [
95
+ step.to_dict() if hasattr(step, "to_dict") else step for step in self.iteration_results
96
+ ]
97
+
98
+ if hasattr(self, "all_results") and self.all_results is not None:
99
+ _dict["all_results"] = [
100
+ [step.to_dict() if hasattr(step, "to_dict") else step for step in iteration]
101
+ for iteration in self.all_results
102
+ ]
103
+
104
+ return _dict
105
+
106
+ @property
107
+ def is_cancelled(self):
108
+ return False
109
+
110
+ @property
111
+ def is_error(self):
112
+ return False
113
+
114
+ @property
115
+ def status(self):
116
+ status = "Completed"
117
+ if self.is_error:
118
+ status = "Error"
119
+ if self.is_cancelled:
120
+ status = "Cancelled"
121
+
122
+ return status
123
+
124
+
125
+ @dataclass
126
+ class WorkflowStartedEvent(BaseWorkflowRunOutputEvent):
127
+ """Event sent when workflow execution starts"""
128
+
129
+ event: str = WorkflowRunEvent.workflow_started.value
130
+
131
+
132
+ @dataclass
133
+ class WorkflowAgentStartedEvent(BaseWorkflowRunOutputEvent):
134
+ """Event sent when workflow agent starts (before deciding to run workflow or answer directly)"""
135
+
136
+ event: str = WorkflowRunEvent.workflow_agent_started.value
137
+
138
+
139
+ @dataclass
140
+ class WorkflowAgentCompletedEvent(BaseWorkflowRunOutputEvent):
141
+ """Event sent when workflow agent completes (after running workflow or answering directly)"""
142
+
143
+ event: str = WorkflowRunEvent.workflow_agent_completed.value
144
+ content: Optional[Any] = None
145
+
146
+
147
+ @dataclass
148
+ class WorkflowCompletedEvent(BaseWorkflowRunOutputEvent):
149
+ """Event sent when workflow execution completes"""
150
+
151
+ event: str = WorkflowRunEvent.workflow_completed.value
152
+ content: Optional[Any] = None
153
+ content_type: str = "str"
154
+
155
+ # Store actual step execution results as StepOutput objects
156
+ step_results: List[StepOutput] = field(default_factory=list)
157
+ metadata: Optional[Dict[str, Any]] = None
158
+
159
+
160
+ @dataclass
161
+ class WorkflowErrorEvent(BaseWorkflowRunOutputEvent):
162
+ """Event sent when workflow execution fails"""
163
+
164
+ event: str = WorkflowRunEvent.workflow_error.value
165
+ error: Optional[str] = None
166
+
167
+ # From exceptions
168
+ error_type: Optional[str] = None
169
+ error_id: Optional[str] = None
170
+ additional_data: Optional[Dict[str, Any]] = None
171
+
172
+
173
+ @dataclass
174
+ class WorkflowCancelledEvent(BaseWorkflowRunOutputEvent):
175
+ """Event sent when workflow execution is cancelled"""
176
+
177
+ event: str = WorkflowRunEvent.workflow_cancelled.value
178
+ reason: Optional[str] = None
179
+
180
+ @property
181
+ def is_cancelled(self):
182
+ return True
183
+
184
+
185
+ @dataclass
186
+ class StepStartedEvent(BaseWorkflowRunOutputEvent):
187
+ """Event sent when step execution starts"""
188
+
189
+ event: str = WorkflowRunEvent.step_started.value
190
+ step_name: Optional[str] = None
191
+ step_index: Optional[Union[int, tuple]] = None
192
+
193
+
194
+ @dataclass
195
+ class StepCompletedEvent(BaseWorkflowRunOutputEvent):
196
+ """Event sent when step execution completes"""
197
+
198
+ event: str = WorkflowRunEvent.step_completed.value
199
+ step_name: Optional[str] = None
200
+ step_index: Optional[Union[int, tuple]] = None
201
+
202
+ content: Optional[Any] = None
203
+ content_type: str = "str"
204
+
205
+ # Media content fields
206
+ images: Optional[List[Image]] = None
207
+ videos: Optional[List[Video]] = None
208
+ audio: Optional[List[Audio]] = None
209
+ response_audio: Optional[Audio] = None
210
+
211
+ # Store actual step execution results as StepOutput objects
212
+ step_response: Optional[StepOutput] = None
213
+
214
+
215
+ @dataclass
216
+ class StepErrorEvent(BaseWorkflowRunOutputEvent):
217
+ """Event sent when step execution fails"""
218
+
219
+ event: str = WorkflowRunEvent.step_error.value
220
+ step_name: Optional[str] = None
221
+ step_index: Optional[Union[int, tuple]] = None
222
+ error: Optional[str] = None
223
+
224
+
225
+ @dataclass
226
+ class LoopExecutionStartedEvent(BaseWorkflowRunOutputEvent):
227
+ """Event sent when loop execution starts"""
228
+
229
+ event: str = WorkflowRunEvent.loop_execution_started.value
230
+ step_name: Optional[str] = None
231
+ step_index: Optional[Union[int, tuple]] = None
232
+ max_iterations: Optional[int] = None
233
+
234
+
235
+ @dataclass
236
+ class LoopIterationStartedEvent(BaseWorkflowRunOutputEvent):
237
+ """Event sent when loop iteration starts"""
238
+
239
+ event: str = WorkflowRunEvent.loop_iteration_started.value
240
+ step_name: Optional[str] = None
241
+ step_index: Optional[Union[int, tuple]] = None
242
+ iteration: int = 0
243
+ max_iterations: Optional[int] = None
244
+
245
+
246
+ @dataclass
247
+ class LoopIterationCompletedEvent(BaseWorkflowRunOutputEvent):
248
+ """Event sent when loop iteration completes"""
249
+
250
+ event: str = WorkflowRunEvent.loop_iteration_completed.value
251
+ step_name: Optional[str] = None
252
+ step_index: Optional[Union[int, tuple]] = None
253
+ iteration: int = 0
254
+ max_iterations: Optional[int] = None
255
+ iteration_results: List[StepOutput] = field(default_factory=list)
256
+ should_continue: bool = True
257
+
258
+
259
+ @dataclass
260
+ class LoopExecutionCompletedEvent(BaseWorkflowRunOutputEvent):
261
+ """Event sent when loop execution completes"""
262
+
263
+ event: str = WorkflowRunEvent.loop_execution_completed.value
264
+ step_name: Optional[str] = None
265
+ step_index: Optional[Union[int, tuple]] = None
266
+ total_iterations: int = 0
267
+ max_iterations: Optional[int] = None
268
+ all_results: List[List[StepOutput]] = field(default_factory=list)
269
+
270
+
271
+ @dataclass
272
+ class ParallelExecutionStartedEvent(BaseWorkflowRunOutputEvent):
273
+ """Event sent when parallel step execution starts"""
274
+
275
+ event: str = WorkflowRunEvent.parallel_execution_started.value
276
+ step_name: Optional[str] = None
277
+ step_index: Optional[Union[int, tuple]] = None
278
+ parallel_step_count: Optional[int] = None
279
+
280
+
281
+ @dataclass
282
+ class ParallelExecutionCompletedEvent(BaseWorkflowRunOutputEvent):
283
+ """Event sent when parallel step execution completes"""
284
+
285
+ event: str = WorkflowRunEvent.parallel_execution_completed.value
286
+ step_name: Optional[str] = None
287
+ step_index: Optional[Union[int, tuple]] = None
288
+ parallel_step_count: Optional[int] = None
289
+
290
+ # Results from all parallel steps
291
+ step_results: List[StepOutput] = field(default_factory=list)
292
+
293
+
294
+ @dataclass
295
+ class ConditionExecutionStartedEvent(BaseWorkflowRunOutputEvent):
296
+ """Event sent when condition step execution starts"""
297
+
298
+ event: str = WorkflowRunEvent.condition_execution_started.value
299
+ step_name: Optional[str] = None
300
+ step_index: Optional[Union[int, tuple]] = None
301
+ condition_result: Optional[bool] = None
302
+
303
+
304
+ @dataclass
305
+ class ConditionExecutionCompletedEvent(BaseWorkflowRunOutputEvent):
306
+ """Event sent when condition step execution completes"""
307
+
308
+ event: str = WorkflowRunEvent.condition_execution_completed.value
309
+ step_name: Optional[str] = None
310
+ step_index: Optional[Union[int, tuple]] = None
311
+ condition_result: Optional[bool] = None
312
+ executed_steps: Optional[int] = None
313
+
314
+ # Results from executed steps
315
+ step_results: List[StepOutput] = field(default_factory=list)
316
+
317
+
318
+ @dataclass
319
+ class RouterExecutionStartedEvent(BaseWorkflowRunOutputEvent):
320
+ """Event sent when router step execution starts"""
321
+
322
+ event: str = WorkflowRunEvent.router_execution_started.value
323
+ step_name: Optional[str] = None
324
+ step_index: Optional[Union[int, tuple]] = None
325
+ # Names of steps selected by router
326
+ selected_steps: List[str] = field(default_factory=list)
327
+
328
+
329
+ @dataclass
330
+ class RouterExecutionCompletedEvent(BaseWorkflowRunOutputEvent):
331
+ """Event sent when router step execution completes"""
332
+
333
+ event: str = WorkflowRunEvent.router_execution_completed.value
334
+ step_name: Optional[str] = None
335
+ step_index: Optional[Union[int, tuple]] = None
336
+ # Names of steps that were selected
337
+ selected_steps: List[str] = field(default_factory=list)
338
+ executed_steps: Optional[int] = None
339
+
340
+ # Results from executed steps
341
+ step_results: List[StepOutput] = field(default_factory=list)
342
+
343
+
344
+ @dataclass
345
+ class StepsExecutionStartedEvent(BaseWorkflowRunOutputEvent):
346
+ """Event sent when steps execution starts"""
347
+
348
+ event: str = WorkflowRunEvent.steps_execution_started.value
349
+ step_name: Optional[str] = None
350
+ step_index: Optional[Union[int, tuple]] = None
351
+ steps_count: Optional[int] = None
352
+
353
+
354
+ @dataclass
355
+ class StepsExecutionCompletedEvent(BaseWorkflowRunOutputEvent):
356
+ """Event sent when steps execution completes"""
357
+
358
+ event: str = WorkflowRunEvent.steps_execution_completed.value
359
+ step_name: Optional[str] = None
360
+ step_index: Optional[Union[int, tuple]] = None
361
+ steps_count: Optional[int] = None
362
+ executed_steps: Optional[int] = None
363
+
364
+ # Results from executed steps
365
+ step_results: List[StepOutput] = field(default_factory=list)
366
+
367
+
368
+ @dataclass
369
+ class StepOutputEvent(BaseWorkflowRunOutputEvent):
370
+ """Event sent when a step produces output - replaces direct StepOutput yielding"""
371
+
372
+ event: str = "StepOutput"
373
+ step_name: Optional[str] = None
374
+ step_index: Optional[Union[int, tuple]] = None
375
+
376
+ # Store actual step execution result as StepOutput object
377
+ step_output: Optional[StepOutput] = None
378
+
379
+ # Properties for backward compatibility
380
+ @property
381
+ def content(self) -> Optional[Union[str, Dict[str, Any], List[Any], BaseModel, Any]]:
382
+ return self.step_output.content if self.step_output else None
383
+
384
+ @property
385
+ def images(self) -> Optional[List[Image]]:
386
+ return self.step_output.images if self.step_output else None
387
+
388
+ @property
389
+ def videos(self) -> Optional[List[Video]]:
390
+ return self.step_output.videos if self.step_output else None
391
+
392
+ @property
393
+ def audio(self) -> Optional[List[Audio]]:
394
+ return self.step_output.audio if self.step_output else None
395
+
396
+ @property
397
+ def success(self) -> bool:
398
+ return self.step_output.success if self.step_output else True
399
+
400
+ @property
401
+ def error(self) -> Optional[str]:
402
+ return self.step_output.error if self.step_output else None
403
+
404
+ @property
405
+ def stop(self) -> bool:
406
+ return self.step_output.stop if self.step_output else False
407
+
408
+
409
+ @dataclass
410
+ class CustomEvent(BaseWorkflowRunOutputEvent):
411
+ """Event sent when a custom event is produced"""
412
+
413
+ event: str = WorkflowRunEvent.custom_event.value
414
+
415
+ def __init__(self, **kwargs):
416
+ # Store arbitrary attributes directly on the instance
417
+ for key, value in kwargs.items():
418
+ setattr(self, key, value)
419
+
420
+
421
+ # Union type for all workflow run response events
422
+ WorkflowRunOutputEvent = Union[
423
+ WorkflowStartedEvent,
424
+ WorkflowAgentStartedEvent,
425
+ WorkflowAgentCompletedEvent,
426
+ WorkflowCompletedEvent,
427
+ WorkflowErrorEvent,
428
+ WorkflowCancelledEvent,
429
+ StepStartedEvent,
430
+ StepCompletedEvent,
431
+ StepErrorEvent,
432
+ LoopExecutionStartedEvent,
433
+ LoopIterationStartedEvent,
434
+ LoopIterationCompletedEvent,
435
+ LoopExecutionCompletedEvent,
436
+ ParallelExecutionStartedEvent,
437
+ ParallelExecutionCompletedEvent,
438
+ ConditionExecutionStartedEvent,
439
+ ConditionExecutionCompletedEvent,
440
+ RouterExecutionStartedEvent,
441
+ RouterExecutionCompletedEvent,
442
+ StepsExecutionStartedEvent,
443
+ StepsExecutionCompletedEvent,
444
+ StepOutputEvent,
445
+ CustomEvent,
446
+ ]
447
+
448
+ # Map event string to dataclass for workflow events
449
+ WORKFLOW_RUN_EVENT_TYPE_REGISTRY = {
450
+ WorkflowRunEvent.workflow_started.value: WorkflowStartedEvent,
451
+ WorkflowRunEvent.workflow_agent_started.value: WorkflowAgentStartedEvent,
452
+ WorkflowRunEvent.workflow_agent_completed.value: WorkflowAgentCompletedEvent,
453
+ WorkflowRunEvent.workflow_completed.value: WorkflowCompletedEvent,
454
+ WorkflowRunEvent.workflow_cancelled.value: WorkflowCancelledEvent,
455
+ WorkflowRunEvent.workflow_error.value: WorkflowErrorEvent,
456
+ WorkflowRunEvent.step_started.value: StepStartedEvent,
457
+ WorkflowRunEvent.step_completed.value: StepCompletedEvent,
458
+ WorkflowRunEvent.step_error.value: StepErrorEvent,
459
+ WorkflowRunEvent.loop_execution_started.value: LoopExecutionStartedEvent,
460
+ WorkflowRunEvent.loop_iteration_started.value: LoopIterationStartedEvent,
461
+ WorkflowRunEvent.loop_iteration_completed.value: LoopIterationCompletedEvent,
462
+ WorkflowRunEvent.loop_execution_completed.value: LoopExecutionCompletedEvent,
463
+ WorkflowRunEvent.parallel_execution_started.value: ParallelExecutionStartedEvent,
464
+ WorkflowRunEvent.parallel_execution_completed.value: ParallelExecutionCompletedEvent,
465
+ WorkflowRunEvent.condition_execution_started.value: ConditionExecutionStartedEvent,
466
+ WorkflowRunEvent.condition_execution_completed.value: ConditionExecutionCompletedEvent,
467
+ WorkflowRunEvent.router_execution_started.value: RouterExecutionStartedEvent,
468
+ WorkflowRunEvent.router_execution_completed.value: RouterExecutionCompletedEvent,
469
+ WorkflowRunEvent.steps_execution_started.value: StepsExecutionStartedEvent,
470
+ WorkflowRunEvent.steps_execution_completed.value: StepsExecutionCompletedEvent,
471
+ WorkflowRunEvent.step_output.value: StepOutputEvent,
472
+ WorkflowRunEvent.custom_event.value: CustomEvent,
473
+ }
474
+
475
+
476
+ def workflow_run_output_event_from_dict(data: dict) -> BaseWorkflowRunOutputEvent:
477
+ event_type = data.get("event", "")
478
+ if event_type in {e.value for e in RunEvent}:
479
+ return run_output_event_from_dict(data) # type: ignore
480
+ elif event_type in {e.value for e in TeamRunEvent}:
481
+ return team_run_output_event_from_dict(data) # type: ignore
482
+ else:
483
+ event_class = WORKFLOW_RUN_EVENT_TYPE_REGISTRY.get(event_type)
484
+ if not event_class:
485
+ raise ValueError(f"Unknown workflow event type: {event_type}")
486
+ return event_class.from_dict(data) # type: ignore
487
+
488
+
489
+ @dataclass
490
+ class WorkflowRunOutput:
491
+ """Response returned by Workflow.run() functions - kept for backwards compatibility"""
492
+
493
+ input: Optional[Union[str, Dict[str, Any], List[Any], BaseModel]] = None
494
+ content: Optional[Union[str, Dict[str, Any], List[Any], BaseModel, Any]] = None
495
+ content_type: str = "str"
496
+
497
+ # Workflow-specific fields
498
+ workflow_id: Optional[str] = None
499
+ workflow_name: Optional[str] = None
500
+
501
+ run_id: Optional[str] = None
502
+ session_id: Optional[str] = None
503
+
504
+ # Media content fields
505
+ images: Optional[List[Image]] = None
506
+ videos: Optional[List[Video]] = None
507
+ audio: Optional[List[Audio]] = None
508
+ response_audio: Optional[Audio] = None
509
+
510
+ # Store actual step execution results as StepOutput objects
511
+ step_results: List[Union[StepOutput, List[StepOutput]]] = field(default_factory=list)
512
+
513
+ # Store agent/team responses separately with parent_run_id references
514
+ step_executor_runs: Optional[List[Union[RunOutput, TeamRunOutput]]] = None
515
+
516
+ # Workflow agent run - stores the full agent RunOutput when workflow agent is used
517
+ # The agent's parent_run_id will point to this workflow run's run_id to establish the relationship
518
+ workflow_agent_run: Optional[RunOutput] = None
519
+
520
+ # Store events from workflow execution
521
+ events: Optional[List[WorkflowRunOutputEvent]] = None
522
+
523
+ # Workflow metrics aggregated from all steps
524
+ metrics: Optional[WorkflowMetrics] = None
525
+
526
+ metadata: Optional[Dict[str, Any]] = None
527
+ created_at: int = field(default_factory=lambda: int(time()))
528
+
529
+ status: RunStatus = RunStatus.pending
530
+
531
+ @property
532
+ def is_cancelled(self):
533
+ return self.status == RunStatus.cancelled
534
+
535
+ def to_dict(self) -> Dict[str, Any]:
536
+ _dict = {
537
+ k: v
538
+ for k, v in asdict(self).items()
539
+ if v is not None
540
+ and k
541
+ not in [
542
+ "metadata",
543
+ "images",
544
+ "videos",
545
+ "audio",
546
+ "response_audio",
547
+ "step_results",
548
+ "step_executor_runs",
549
+ "events",
550
+ "metrics",
551
+ "workflow_agent_run",
552
+ ]
553
+ }
554
+
555
+ if self.status is not None:
556
+ _dict["status"] = self.status.value if isinstance(self.status, RunStatus) else self.status
557
+
558
+ if self.metadata is not None:
559
+ _dict["metadata"] = self.metadata
560
+
561
+ if self.images is not None:
562
+ _dict["images"] = [img.to_dict() for img in self.images]
563
+
564
+ if self.videos is not None:
565
+ _dict["videos"] = [vid.to_dict() for vid in self.videos]
566
+
567
+ if self.audio is not None:
568
+ _dict["audio"] = [aud.to_dict() for aud in self.audio]
569
+
570
+ if self.response_audio is not None:
571
+ _dict["response_audio"] = self.response_audio.to_dict()
572
+
573
+ if self.step_results:
574
+ flattened_responses = []
575
+ for step_response in self.step_results:
576
+ if isinstance(step_response, list):
577
+ # Handle List[StepOutput] from workflow components like Steps
578
+ flattened_responses.extend([s.to_dict() for s in step_response])
579
+ else:
580
+ # Handle single StepOutput
581
+ flattened_responses.append(step_response.to_dict())
582
+ _dict["step_results"] = flattened_responses
583
+
584
+ if self.step_executor_runs:
585
+ _dict["step_executor_runs"] = [run.to_dict() for run in self.step_executor_runs]
586
+
587
+ if self.workflow_agent_run is not None:
588
+ _dict["workflow_agent_run"] = self.workflow_agent_run.to_dict()
589
+
590
+ if self.metrics is not None:
591
+ _dict["metrics"] = self.metrics.to_dict()
592
+
593
+ if self.input is not None:
594
+ if isinstance(self.input, BaseModel):
595
+ _dict["input"] = self.input.model_dump(exclude_none=True)
596
+ else:
597
+ _dict["input"] = self.input
598
+
599
+ if self.content and isinstance(self.content, BaseModel):
600
+ _dict["content"] = self.content.model_dump(exclude_none=True, mode="json")
601
+
602
+ if self.events is not None:
603
+ _dict["events"] = [e.to_dict() for e in self.events]
604
+
605
+ return _dict
606
+
607
+ @classmethod
608
+ def from_dict(cls, data: Dict[str, Any]) -> "WorkflowRunOutput":
609
+ # Import here to avoid circular import
610
+ from agno.workflow.step import StepOutput
611
+
612
+ workflow_metrics_dict = data.pop("metrics", {})
613
+ workflow_metrics = None
614
+ if workflow_metrics_dict:
615
+ from agno.workflow.workflow import WorkflowMetrics
616
+
617
+ workflow_metrics = WorkflowMetrics.from_dict(workflow_metrics_dict)
618
+
619
+ step_results = data.pop("step_results", [])
620
+ parsed_step_results: List[Union[StepOutput, List[StepOutput]]] = []
621
+ if step_results:
622
+ for step_output_dict in step_results:
623
+ # Reconstruct StepOutput from dict
624
+ parsed_step_results.append(StepOutput.from_dict(step_output_dict))
625
+
626
+ # Parse step_executor_runs
627
+ step_executor_runs_data = data.pop("step_executor_runs", [])
628
+ step_executor_runs: List[Union[RunOutput, TeamRunOutput]] = []
629
+ if step_executor_runs_data:
630
+ step_executor_runs = []
631
+ for run_data in step_executor_runs_data:
632
+ if "team_id" in run_data or "team_name" in run_data:
633
+ step_executor_runs.append(TeamRunOutput.from_dict(run_data))
634
+ else:
635
+ step_executor_runs.append(RunOutput.from_dict(run_data))
636
+
637
+ workflow_agent_run_data = data.pop("workflow_agent_run", None)
638
+ workflow_agent_run = None
639
+ if workflow_agent_run_data:
640
+ if isinstance(workflow_agent_run_data, dict):
641
+ workflow_agent_run = RunOutput.from_dict(workflow_agent_run_data)
642
+ elif isinstance(workflow_agent_run_data, RunOutput):
643
+ workflow_agent_run = workflow_agent_run_data
644
+
645
+ metadata = data.pop("metadata", None)
646
+
647
+ images = reconstruct_images(data.pop("images", []))
648
+ videos = reconstruct_videos(data.pop("videos", []))
649
+ audio = reconstruct_audio_list(data.pop("audio", []))
650
+ response_audio = reconstruct_response_audio(data.pop("response_audio", None))
651
+
652
+ events_data = data.pop("events", [])
653
+ final_events = []
654
+ for event in events_data or []:
655
+ if "agent_id" in event:
656
+ # Agent event from agent step
657
+ from agno.run.agent import run_output_event_from_dict
658
+
659
+ event = run_output_event_from_dict(event)
660
+ elif "team_id" in event:
661
+ # Team event from team step
662
+ from agno.run.team import team_run_output_event_from_dict
663
+
664
+ event = team_run_output_event_from_dict(event)
665
+ else:
666
+ # Pure workflow event
667
+ event = workflow_run_output_event_from_dict(event)
668
+ final_events.append(event)
669
+ events = final_events
670
+
671
+ input_data = data.pop("input", None)
672
+
673
+ # Filter data to only include fields that are actually defined in the WorkflowRunOutput dataclass
674
+ from dataclasses import fields
675
+
676
+ supported_fields = {f.name for f in fields(cls)}
677
+ filtered_data = {k: v for k, v in data.items() if k in supported_fields}
678
+
679
+ return cls(
680
+ step_results=parsed_step_results,
681
+ workflow_agent_run=workflow_agent_run,
682
+ metadata=metadata,
683
+ images=images,
684
+ videos=videos,
685
+ audio=audio,
686
+ response_audio=response_audio,
687
+ events=events,
688
+ metrics=workflow_metrics,
689
+ step_executor_runs=step_executor_runs,
690
+ input=input_data,
691
+ **filtered_data,
692
+ )
693
+
694
+ def get_content_as_string(self, **kwargs) -> str:
695
+ import json
696
+
697
+ from pydantic import BaseModel
698
+
699
+ if isinstance(self.content, str):
700
+ return self.content
701
+ elif isinstance(self.content, BaseModel):
702
+ return self.content.model_dump_json(exclude_none=True, **kwargs)
703
+ else:
704
+ return json.dumps(self.content, **kwargs)
705
+
706
+ def has_completed(self) -> bool:
707
+ """Check if the workflow run is completed (either successfully or with error)"""
708
+ return self.status in [RunStatus.completed, RunStatus.error]