agno 2.2.13__py3-none-any.whl → 2.4.3__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 (383) hide show
  1. agno/agent/__init__.py +6 -0
  2. agno/agent/agent.py +5252 -3145
  3. agno/agent/remote.py +525 -0
  4. agno/api/api.py +2 -0
  5. agno/client/__init__.py +3 -0
  6. agno/client/a2a/__init__.py +10 -0
  7. agno/client/a2a/client.py +554 -0
  8. agno/client/a2a/schemas.py +112 -0
  9. agno/client/a2a/utils.py +369 -0
  10. agno/client/os.py +2669 -0
  11. agno/compression/__init__.py +3 -0
  12. agno/compression/manager.py +247 -0
  13. agno/culture/manager.py +2 -2
  14. agno/db/base.py +927 -6
  15. agno/db/dynamo/dynamo.py +788 -2
  16. agno/db/dynamo/schemas.py +128 -0
  17. agno/db/dynamo/utils.py +26 -3
  18. agno/db/firestore/firestore.py +674 -50
  19. agno/db/firestore/schemas.py +41 -0
  20. agno/db/firestore/utils.py +25 -10
  21. agno/db/gcs_json/gcs_json_db.py +506 -3
  22. agno/db/gcs_json/utils.py +14 -2
  23. agno/db/in_memory/in_memory_db.py +203 -4
  24. agno/db/in_memory/utils.py +14 -2
  25. agno/db/json/json_db.py +498 -2
  26. agno/db/json/utils.py +14 -2
  27. agno/db/migrations/manager.py +199 -0
  28. agno/db/migrations/utils.py +19 -0
  29. agno/db/migrations/v1_to_v2.py +54 -16
  30. agno/db/migrations/versions/__init__.py +0 -0
  31. agno/db/migrations/versions/v2_3_0.py +977 -0
  32. agno/db/mongo/async_mongo.py +1013 -39
  33. agno/db/mongo/mongo.py +684 -4
  34. agno/db/mongo/schemas.py +48 -0
  35. agno/db/mongo/utils.py +17 -0
  36. agno/db/mysql/__init__.py +2 -1
  37. agno/db/mysql/async_mysql.py +2958 -0
  38. agno/db/mysql/mysql.py +722 -53
  39. agno/db/mysql/schemas.py +77 -11
  40. agno/db/mysql/utils.py +151 -8
  41. agno/db/postgres/async_postgres.py +1254 -137
  42. agno/db/postgres/postgres.py +2316 -93
  43. agno/db/postgres/schemas.py +153 -21
  44. agno/db/postgres/utils.py +22 -7
  45. agno/db/redis/redis.py +531 -3
  46. agno/db/redis/schemas.py +36 -0
  47. agno/db/redis/utils.py +31 -15
  48. agno/db/schemas/evals.py +1 -0
  49. agno/db/schemas/memory.py +20 -9
  50. agno/db/singlestore/schemas.py +70 -1
  51. agno/db/singlestore/singlestore.py +737 -74
  52. agno/db/singlestore/utils.py +13 -3
  53. agno/db/sqlite/async_sqlite.py +1069 -89
  54. agno/db/sqlite/schemas.py +133 -1
  55. agno/db/sqlite/sqlite.py +2203 -165
  56. agno/db/sqlite/utils.py +21 -11
  57. agno/db/surrealdb/models.py +25 -0
  58. agno/db/surrealdb/surrealdb.py +603 -1
  59. agno/db/utils.py +60 -0
  60. agno/eval/__init__.py +26 -3
  61. agno/eval/accuracy.py +25 -12
  62. agno/eval/agent_as_judge.py +871 -0
  63. agno/eval/base.py +29 -0
  64. agno/eval/performance.py +10 -4
  65. agno/eval/reliability.py +22 -13
  66. agno/eval/utils.py +2 -1
  67. agno/exceptions.py +42 -0
  68. agno/hooks/__init__.py +3 -0
  69. agno/hooks/decorator.py +164 -0
  70. agno/integrations/discord/client.py +13 -2
  71. agno/knowledge/__init__.py +4 -0
  72. agno/knowledge/chunking/code.py +90 -0
  73. agno/knowledge/chunking/document.py +65 -4
  74. agno/knowledge/chunking/fixed.py +4 -1
  75. agno/knowledge/chunking/markdown.py +102 -11
  76. agno/knowledge/chunking/recursive.py +2 -2
  77. agno/knowledge/chunking/semantic.py +130 -48
  78. agno/knowledge/chunking/strategy.py +18 -0
  79. agno/knowledge/embedder/azure_openai.py +0 -1
  80. agno/knowledge/embedder/google.py +1 -1
  81. agno/knowledge/embedder/mistral.py +1 -1
  82. agno/knowledge/embedder/nebius.py +1 -1
  83. agno/knowledge/embedder/openai.py +16 -12
  84. agno/knowledge/filesystem.py +412 -0
  85. agno/knowledge/knowledge.py +4261 -1199
  86. agno/knowledge/protocol.py +134 -0
  87. agno/knowledge/reader/arxiv_reader.py +3 -2
  88. agno/knowledge/reader/base.py +9 -7
  89. agno/knowledge/reader/csv_reader.py +91 -42
  90. agno/knowledge/reader/docx_reader.py +9 -10
  91. agno/knowledge/reader/excel_reader.py +225 -0
  92. agno/knowledge/reader/field_labeled_csv_reader.py +38 -48
  93. agno/knowledge/reader/firecrawl_reader.py +3 -2
  94. agno/knowledge/reader/json_reader.py +16 -22
  95. agno/knowledge/reader/markdown_reader.py +15 -14
  96. agno/knowledge/reader/pdf_reader.py +33 -28
  97. agno/knowledge/reader/pptx_reader.py +9 -10
  98. agno/knowledge/reader/reader_factory.py +135 -1
  99. agno/knowledge/reader/s3_reader.py +8 -16
  100. agno/knowledge/reader/tavily_reader.py +3 -3
  101. agno/knowledge/reader/text_reader.py +15 -14
  102. agno/knowledge/reader/utils/__init__.py +17 -0
  103. agno/knowledge/reader/utils/spreadsheet.py +114 -0
  104. agno/knowledge/reader/web_search_reader.py +8 -65
  105. agno/knowledge/reader/website_reader.py +16 -13
  106. agno/knowledge/reader/wikipedia_reader.py +36 -3
  107. agno/knowledge/reader/youtube_reader.py +3 -2
  108. agno/knowledge/remote_content/__init__.py +33 -0
  109. agno/knowledge/remote_content/config.py +266 -0
  110. agno/knowledge/remote_content/remote_content.py +105 -17
  111. agno/knowledge/utils.py +76 -22
  112. agno/learn/__init__.py +71 -0
  113. agno/learn/config.py +463 -0
  114. agno/learn/curate.py +185 -0
  115. agno/learn/machine.py +725 -0
  116. agno/learn/schemas.py +1114 -0
  117. agno/learn/stores/__init__.py +38 -0
  118. agno/learn/stores/decision_log.py +1156 -0
  119. agno/learn/stores/entity_memory.py +3275 -0
  120. agno/learn/stores/learned_knowledge.py +1583 -0
  121. agno/learn/stores/protocol.py +117 -0
  122. agno/learn/stores/session_context.py +1217 -0
  123. agno/learn/stores/user_memory.py +1495 -0
  124. agno/learn/stores/user_profile.py +1220 -0
  125. agno/learn/utils.py +209 -0
  126. agno/media.py +22 -6
  127. agno/memory/__init__.py +14 -1
  128. agno/memory/manager.py +223 -8
  129. agno/memory/strategies/__init__.py +15 -0
  130. agno/memory/strategies/base.py +66 -0
  131. agno/memory/strategies/summarize.py +196 -0
  132. agno/memory/strategies/types.py +37 -0
  133. agno/models/aimlapi/aimlapi.py +17 -0
  134. agno/models/anthropic/claude.py +434 -59
  135. agno/models/aws/bedrock.py +121 -20
  136. agno/models/aws/claude.py +131 -274
  137. agno/models/azure/ai_foundry.py +10 -6
  138. agno/models/azure/openai_chat.py +33 -10
  139. agno/models/base.py +1162 -561
  140. agno/models/cerebras/cerebras.py +120 -24
  141. agno/models/cerebras/cerebras_openai.py +21 -2
  142. agno/models/cohere/chat.py +65 -6
  143. agno/models/cometapi/cometapi.py +18 -1
  144. agno/models/dashscope/dashscope.py +2 -3
  145. agno/models/deepinfra/deepinfra.py +18 -1
  146. agno/models/deepseek/deepseek.py +69 -3
  147. agno/models/fireworks/fireworks.py +18 -1
  148. agno/models/google/gemini.py +959 -89
  149. agno/models/google/utils.py +22 -0
  150. agno/models/groq/groq.py +48 -18
  151. agno/models/huggingface/huggingface.py +17 -6
  152. agno/models/ibm/watsonx.py +16 -6
  153. agno/models/internlm/internlm.py +18 -1
  154. agno/models/langdb/langdb.py +13 -1
  155. agno/models/litellm/chat.py +88 -9
  156. agno/models/litellm/litellm_openai.py +18 -1
  157. agno/models/message.py +24 -5
  158. agno/models/meta/llama.py +40 -13
  159. agno/models/meta/llama_openai.py +22 -21
  160. agno/models/metrics.py +12 -0
  161. agno/models/mistral/mistral.py +8 -4
  162. agno/models/n1n/__init__.py +3 -0
  163. agno/models/n1n/n1n.py +57 -0
  164. agno/models/nebius/nebius.py +6 -7
  165. agno/models/nvidia/nvidia.py +20 -3
  166. agno/models/ollama/__init__.py +2 -0
  167. agno/models/ollama/chat.py +17 -6
  168. agno/models/ollama/responses.py +100 -0
  169. agno/models/openai/__init__.py +2 -0
  170. agno/models/openai/chat.py +117 -26
  171. agno/models/openai/open_responses.py +46 -0
  172. agno/models/openai/responses.py +110 -32
  173. agno/models/openrouter/__init__.py +2 -0
  174. agno/models/openrouter/openrouter.py +67 -2
  175. agno/models/openrouter/responses.py +146 -0
  176. agno/models/perplexity/perplexity.py +19 -1
  177. agno/models/portkey/portkey.py +7 -6
  178. agno/models/requesty/requesty.py +19 -2
  179. agno/models/response.py +20 -2
  180. agno/models/sambanova/sambanova.py +20 -3
  181. agno/models/siliconflow/siliconflow.py +19 -2
  182. agno/models/together/together.py +20 -3
  183. agno/models/vercel/v0.py +20 -3
  184. agno/models/vertexai/claude.py +124 -4
  185. agno/models/vllm/vllm.py +19 -14
  186. agno/models/xai/xai.py +19 -2
  187. agno/os/app.py +467 -137
  188. agno/os/auth.py +253 -5
  189. agno/os/config.py +22 -0
  190. agno/os/interfaces/a2a/a2a.py +7 -6
  191. agno/os/interfaces/a2a/router.py +635 -26
  192. agno/os/interfaces/a2a/utils.py +32 -33
  193. agno/os/interfaces/agui/agui.py +5 -3
  194. agno/os/interfaces/agui/router.py +26 -16
  195. agno/os/interfaces/agui/utils.py +97 -57
  196. agno/os/interfaces/base.py +7 -7
  197. agno/os/interfaces/slack/router.py +16 -7
  198. agno/os/interfaces/slack/slack.py +7 -7
  199. agno/os/interfaces/whatsapp/router.py +35 -7
  200. agno/os/interfaces/whatsapp/security.py +3 -1
  201. agno/os/interfaces/whatsapp/whatsapp.py +11 -8
  202. agno/os/managers.py +326 -0
  203. agno/os/mcp.py +652 -79
  204. agno/os/middleware/__init__.py +4 -0
  205. agno/os/middleware/jwt.py +718 -115
  206. agno/os/middleware/trailing_slash.py +27 -0
  207. agno/os/router.py +105 -1558
  208. agno/os/routers/agents/__init__.py +3 -0
  209. agno/os/routers/agents/router.py +655 -0
  210. agno/os/routers/agents/schema.py +288 -0
  211. agno/os/routers/components/__init__.py +3 -0
  212. agno/os/routers/components/components.py +475 -0
  213. agno/os/routers/database.py +155 -0
  214. agno/os/routers/evals/evals.py +111 -18
  215. agno/os/routers/evals/schemas.py +38 -5
  216. agno/os/routers/evals/utils.py +80 -11
  217. agno/os/routers/health.py +3 -3
  218. agno/os/routers/knowledge/knowledge.py +284 -35
  219. agno/os/routers/knowledge/schemas.py +14 -2
  220. agno/os/routers/memory/memory.py +274 -11
  221. agno/os/routers/memory/schemas.py +44 -3
  222. agno/os/routers/metrics/metrics.py +30 -15
  223. agno/os/routers/metrics/schemas.py +10 -6
  224. agno/os/routers/registry/__init__.py +3 -0
  225. agno/os/routers/registry/registry.py +337 -0
  226. agno/os/routers/session/session.py +143 -14
  227. agno/os/routers/teams/__init__.py +3 -0
  228. agno/os/routers/teams/router.py +550 -0
  229. agno/os/routers/teams/schema.py +280 -0
  230. agno/os/routers/traces/__init__.py +3 -0
  231. agno/os/routers/traces/schemas.py +414 -0
  232. agno/os/routers/traces/traces.py +549 -0
  233. agno/os/routers/workflows/__init__.py +3 -0
  234. agno/os/routers/workflows/router.py +757 -0
  235. agno/os/routers/workflows/schema.py +139 -0
  236. agno/os/schema.py +157 -584
  237. agno/os/scopes.py +469 -0
  238. agno/os/settings.py +3 -0
  239. agno/os/utils.py +574 -185
  240. agno/reasoning/anthropic.py +85 -1
  241. agno/reasoning/azure_ai_foundry.py +93 -1
  242. agno/reasoning/deepseek.py +102 -2
  243. agno/reasoning/default.py +6 -7
  244. agno/reasoning/gemini.py +87 -3
  245. agno/reasoning/groq.py +109 -2
  246. agno/reasoning/helpers.py +6 -7
  247. agno/reasoning/manager.py +1238 -0
  248. agno/reasoning/ollama.py +93 -1
  249. agno/reasoning/openai.py +115 -1
  250. agno/reasoning/vertexai.py +85 -1
  251. agno/registry/__init__.py +3 -0
  252. agno/registry/registry.py +68 -0
  253. agno/remote/__init__.py +3 -0
  254. agno/remote/base.py +581 -0
  255. agno/run/__init__.py +2 -4
  256. agno/run/agent.py +134 -19
  257. agno/run/base.py +49 -1
  258. agno/run/cancel.py +65 -52
  259. agno/run/cancellation_management/__init__.py +9 -0
  260. agno/run/cancellation_management/base.py +78 -0
  261. agno/run/cancellation_management/in_memory_cancellation_manager.py +100 -0
  262. agno/run/cancellation_management/redis_cancellation_manager.py +236 -0
  263. agno/run/requirement.py +181 -0
  264. agno/run/team.py +111 -19
  265. agno/run/workflow.py +2 -1
  266. agno/session/agent.py +57 -92
  267. agno/session/summary.py +1 -1
  268. agno/session/team.py +62 -115
  269. agno/session/workflow.py +353 -57
  270. agno/skills/__init__.py +17 -0
  271. agno/skills/agent_skills.py +377 -0
  272. agno/skills/errors.py +32 -0
  273. agno/skills/loaders/__init__.py +4 -0
  274. agno/skills/loaders/base.py +27 -0
  275. agno/skills/loaders/local.py +216 -0
  276. agno/skills/skill.py +65 -0
  277. agno/skills/utils.py +107 -0
  278. agno/skills/validator.py +277 -0
  279. agno/table.py +10 -0
  280. agno/team/__init__.py +5 -1
  281. agno/team/remote.py +447 -0
  282. agno/team/team.py +3769 -2202
  283. agno/tools/brandfetch.py +27 -18
  284. agno/tools/browserbase.py +225 -16
  285. agno/tools/crawl4ai.py +3 -0
  286. agno/tools/duckduckgo.py +25 -71
  287. agno/tools/exa.py +0 -21
  288. agno/tools/file.py +14 -13
  289. agno/tools/file_generation.py +12 -6
  290. agno/tools/firecrawl.py +15 -7
  291. agno/tools/function.py +94 -113
  292. agno/tools/google_bigquery.py +11 -2
  293. agno/tools/google_drive.py +4 -3
  294. agno/tools/knowledge.py +9 -4
  295. agno/tools/mcp/mcp.py +301 -18
  296. agno/tools/mcp/multi_mcp.py +269 -14
  297. agno/tools/mem0.py +11 -10
  298. agno/tools/memory.py +47 -46
  299. agno/tools/mlx_transcribe.py +10 -7
  300. agno/tools/models/nebius.py +5 -5
  301. agno/tools/models_labs.py +20 -10
  302. agno/tools/nano_banana.py +151 -0
  303. agno/tools/parallel.py +0 -7
  304. agno/tools/postgres.py +76 -36
  305. agno/tools/python.py +14 -6
  306. agno/tools/reasoning.py +30 -23
  307. agno/tools/redshift.py +406 -0
  308. agno/tools/shopify.py +1519 -0
  309. agno/tools/spotify.py +919 -0
  310. agno/tools/tavily.py +4 -1
  311. agno/tools/toolkit.py +253 -18
  312. agno/tools/websearch.py +93 -0
  313. agno/tools/website.py +1 -1
  314. agno/tools/wikipedia.py +1 -1
  315. agno/tools/workflow.py +56 -48
  316. agno/tools/yfinance.py +12 -11
  317. agno/tracing/__init__.py +12 -0
  318. agno/tracing/exporter.py +161 -0
  319. agno/tracing/schemas.py +276 -0
  320. agno/tracing/setup.py +112 -0
  321. agno/utils/agent.py +251 -10
  322. agno/utils/cryptography.py +22 -0
  323. agno/utils/dttm.py +33 -0
  324. agno/utils/events.py +264 -7
  325. agno/utils/hooks.py +111 -3
  326. agno/utils/http.py +161 -2
  327. agno/utils/mcp.py +49 -8
  328. agno/utils/media.py +22 -1
  329. agno/utils/models/ai_foundry.py +9 -2
  330. agno/utils/models/claude.py +20 -5
  331. agno/utils/models/cohere.py +9 -2
  332. agno/utils/models/llama.py +9 -2
  333. agno/utils/models/mistral.py +4 -2
  334. agno/utils/os.py +0 -0
  335. agno/utils/print_response/agent.py +99 -16
  336. agno/utils/print_response/team.py +223 -24
  337. agno/utils/print_response/workflow.py +0 -2
  338. agno/utils/prompts.py +8 -6
  339. agno/utils/remote.py +23 -0
  340. agno/utils/response.py +1 -13
  341. agno/utils/string.py +91 -2
  342. agno/utils/team.py +62 -12
  343. agno/utils/tokens.py +657 -0
  344. agno/vectordb/base.py +15 -2
  345. agno/vectordb/cassandra/cassandra.py +1 -1
  346. agno/vectordb/chroma/__init__.py +2 -1
  347. agno/vectordb/chroma/chromadb.py +468 -23
  348. agno/vectordb/clickhouse/clickhousedb.py +1 -1
  349. agno/vectordb/couchbase/couchbase.py +6 -2
  350. agno/vectordb/lancedb/lance_db.py +7 -38
  351. agno/vectordb/lightrag/lightrag.py +7 -6
  352. agno/vectordb/milvus/milvus.py +118 -84
  353. agno/vectordb/mongodb/__init__.py +2 -1
  354. agno/vectordb/mongodb/mongodb.py +14 -31
  355. agno/vectordb/pgvector/pgvector.py +120 -66
  356. agno/vectordb/pineconedb/pineconedb.py +2 -19
  357. agno/vectordb/qdrant/__init__.py +2 -1
  358. agno/vectordb/qdrant/qdrant.py +33 -56
  359. agno/vectordb/redis/__init__.py +2 -1
  360. agno/vectordb/redis/redisdb.py +19 -31
  361. agno/vectordb/singlestore/singlestore.py +17 -9
  362. agno/vectordb/surrealdb/surrealdb.py +2 -38
  363. agno/vectordb/weaviate/__init__.py +2 -1
  364. agno/vectordb/weaviate/weaviate.py +7 -3
  365. agno/workflow/__init__.py +5 -1
  366. agno/workflow/agent.py +2 -2
  367. agno/workflow/condition.py +12 -10
  368. agno/workflow/loop.py +28 -9
  369. agno/workflow/parallel.py +21 -13
  370. agno/workflow/remote.py +362 -0
  371. agno/workflow/router.py +12 -9
  372. agno/workflow/step.py +261 -36
  373. agno/workflow/steps.py +12 -8
  374. agno/workflow/types.py +40 -77
  375. agno/workflow/workflow.py +939 -213
  376. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/METADATA +134 -181
  377. agno-2.4.3.dist-info/RECORD +677 -0
  378. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/WHEEL +1 -1
  379. agno/tools/googlesearch.py +0 -98
  380. agno/tools/memori.py +0 -339
  381. agno-2.2.13.dist-info/RECORD +0 -575
  382. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/licenses/LICENSE +0 -0
  383. {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/top_level.txt +0 -0
agno/workflow/step.py CHANGED
@@ -1,15 +1,18 @@
1
1
  import inspect
2
2
  from copy import copy
3
3
  from dataclasses import dataclass
4
- from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
4
+ from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union, cast
5
5
  from uuid import uuid4
6
6
 
7
7
  from pydantic import BaseModel
8
8
  from typing_extensions import TypeGuard
9
9
 
10
10
  from agno.agent import Agent
11
+ from agno.db.base import BaseDb
11
12
  from agno.media import Audio, Image, Video
13
+ from agno.models.message import Message
12
14
  from agno.models.metrics import Metrics
15
+ from agno.registry import Registry
13
16
  from agno.run import RunContext
14
17
  from agno.run.agent import RunContentEvent, RunOutput
15
18
  from agno.run.base import BaseRunOutputEvent
@@ -21,9 +24,11 @@ from agno.run.workflow import (
21
24
  WorkflowRunOutput,
22
25
  WorkflowRunOutputEvent,
23
26
  )
27
+ from agno.session.agent import AgentSession
28
+ from agno.session.team import TeamSession
24
29
  from agno.session.workflow import WorkflowSession
25
30
  from agno.team import Team
26
- from agno.utils.log import log_debug, logger, use_agent_logger, use_team_logger, use_workflow_logger
31
+ from agno.utils.log import log_debug, log_warning, logger, use_agent_logger, use_team_logger, use_workflow_logger
27
32
  from agno.utils.merge_dict import merge_dictionaries
28
33
  from agno.workflow.types import StepInput, StepOutput, StepType
29
34
 
@@ -57,7 +62,6 @@ class Step:
57
62
 
58
63
  # Step configuration
59
64
  max_retries: int = 3
60
- timeout_seconds: Optional[int] = None
61
65
 
62
66
  skip_on_failure: bool = False
63
67
 
@@ -79,7 +83,6 @@ class Step:
79
83
  step_id: Optional[str] = None,
80
84
  description: Optional[str] = None,
81
85
  max_retries: int = 3,
82
- timeout_seconds: Optional[int] = None,
83
86
  skip_on_failure: bool = False,
84
87
  strict_input_validation: bool = False,
85
88
  add_workflow_history: Optional[bool] = None,
@@ -100,7 +103,6 @@ class Step:
100
103
  self.step_id = step_id
101
104
  self.description = description
102
105
  self.max_retries = max_retries
103
- self.timeout_seconds = timeout_seconds
104
106
  self.skip_on_failure = skip_on_failure
105
107
  self.strict_input_validation = strict_input_validation
106
108
  self.add_workflow_history = add_workflow_history
@@ -113,6 +115,121 @@ class Step:
113
115
  # Set the active executor
114
116
  self._set_active_executor()
115
117
 
118
+ def to_dict(self) -> Dict[str, Any]:
119
+ """Convert step to a dictionary representation."""
120
+ result = {
121
+ "name": self.name,
122
+ "step_id": self.step_id,
123
+ "description": self.description,
124
+ "max_retries": self.max_retries,
125
+ "skip_on_failure": self.skip_on_failure,
126
+ "strict_input_validation": self.strict_input_validation,
127
+ "add_workflow_history": self.add_workflow_history,
128
+ "num_history_runs": self.num_history_runs,
129
+ }
130
+
131
+ if self.agent is not None:
132
+ result["agent_id"] = self.agent.id
133
+ if self.team is not None:
134
+ result["team_id"] = self.team.id
135
+ # TODO: Add support for custom executors
136
+
137
+ return result
138
+
139
+ @classmethod
140
+ def from_dict(
141
+ cls,
142
+ data: Dict[str, Any],
143
+ registry: Optional[Registry] = None,
144
+ db: Optional["BaseDb"] = None,
145
+ links: Optional[List[Dict[str, Any]]] = None,
146
+ ) -> "Step":
147
+ """
148
+ Create a Step from a dictionary.
149
+
150
+ Args:
151
+ data: Dictionary containing step configuration
152
+ registry: Optional registry for rehydrating non-serializable objects
153
+ db: Optional database for loading agents/teams in steps
154
+ links: Optional links for this step version
155
+
156
+ Returns:
157
+ Step: Reconstructed step instance
158
+ """
159
+ config = data.copy()
160
+
161
+ agent = None
162
+ team = None
163
+ executor = None
164
+
165
+ # --- Handle Agent reconstruction ---
166
+ if "agent_id" in config and config["agent_id"]:
167
+ from agno.agent.agent import get_agent_by_id
168
+
169
+ agent_id = config.get("agent_id")
170
+ if db is not None and agent_id is not None:
171
+ agent = get_agent_by_id(db=db, id=agent_id, registry=registry)
172
+
173
+ # --- Handle Team reconstruction ---
174
+ # if "team_id" in config and config["team_id"] and registry:
175
+ # from agno.team.team import get_team_by_id
176
+ # team = get_team_by_id(db=db, id=config["team_id"])
177
+
178
+ # --- Handle Executor reconstruction ---
179
+ # TODO: Implement executor reconstruction
180
+ # if "executor_ref" in config and config["executor_ref"] and registry:
181
+ # executor = registry.rehydrate_function(config["executor_ref"])
182
+
183
+ return cls(
184
+ name=config.get("name"),
185
+ step_id=config.get("step_id"),
186
+ description=config.get("description"),
187
+ max_retries=config.get("max_retries", 3),
188
+ skip_on_failure=config.get("skip_on_failure", False),
189
+ strict_input_validation=config.get("strict_input_validation", False),
190
+ add_workflow_history=config.get("add_workflow_history"),
191
+ num_history_runs=config.get("num_history_runs", 3),
192
+ agent=agent,
193
+ team=team,
194
+ executor=executor,
195
+ )
196
+
197
+ def get_links(self, position: int = 0) -> List[Dict[str, Any]]:
198
+ """Get links for this step's agent/team.
199
+
200
+ Args:
201
+ position: Position of this step in the workflow.
202
+
203
+ Returns:
204
+ List of link dictionaries for the links table.
205
+ """
206
+ links = []
207
+ link_key = self.step_id or self.name
208
+
209
+ if self.agent is not None:
210
+ links.append(
211
+ {
212
+ "link_kind": "step_agent",
213
+ "link_key": link_key,
214
+ "child_component_id": self.agent.id,
215
+ "child_version": None,
216
+ "position": position,
217
+ }
218
+ )
219
+
220
+ if self.team is not None:
221
+ links.append(
222
+ {
223
+ "link_kind": "step_team",
224
+ "link_key": link_key,
225
+ "child_component_id": self.team.id,
226
+ "child_version": None,
227
+ "position": position,
228
+ }
229
+ )
230
+
231
+ return links
232
+
116
233
  @property
117
234
  def executor_name(self) -> str:
118
235
  """Get the name of the current executor"""
@@ -225,6 +342,7 @@ class Step:
225
342
  workflow_session: Optional[WorkflowSession] = None,
226
343
  add_workflow_history_to_steps: Optional[bool] = False,
227
344
  num_history_runs: int = 3,
345
+ background_tasks: Optional[Any] = None,
228
346
  ) -> StepOutput:
229
347
  """Execute the step with StepInput, returning final StepOutput (non-streaming)"""
230
348
  log_debug(f"Executing step: {self.name}")
@@ -272,17 +390,18 @@ class Step:
272
390
  elif isinstance(chunk.content, BaseModel):
273
391
  content = chunk.content # type: ignore[assignment]
274
392
  else:
275
- # Safeguard but should never happen
393
+ # Case when parse_response is False and the content is a dict
276
394
  content += str(chunk.content)
277
395
  elif isinstance(chunk, (RunOutput, TeamRunOutput)):
278
396
  # This is the final response from the agent/team
279
397
  content = chunk.content # type: ignore[assignment]
280
- else:
281
- # Non Agent/Team data structure that was yielded
282
- content += str(chunk)
283
398
  # If the chunk is a StepOutput, use it as the final response
284
- if isinstance(chunk, StepOutput):
399
+ elif isinstance(chunk, StepOutput):
285
400
  final_response = chunk
401
+ break
402
+ # Non Agent/Team data structure that was yielded
403
+ else:
404
+ content += str(chunk)
286
405
 
287
406
  except StopIteration as e:
288
407
  if hasattr(e, "value") and isinstance(e.value, StepOutput):
@@ -343,6 +462,10 @@ class Step:
343
462
  if isinstance(self.active_executor, Team):
344
463
  kwargs["store_member_responses"] = True
345
464
 
465
+ # Forward background_tasks if provided
466
+ if background_tasks is not None:
467
+ kwargs["background_tasks"] = background_tasks
468
+
346
469
  num_history_runs = self.num_history_runs if self.num_history_runs else num_history_runs
347
470
 
348
471
  use_history = (
@@ -454,7 +577,6 @@ class Step:
454
577
  session_id: Optional[str] = None,
455
578
  user_id: Optional[str] = None,
456
579
  stream_events: bool = False,
457
- stream_intermediate_steps: bool = False,
458
580
  stream_executor_events: bool = True,
459
581
  workflow_run_response: Optional["WorkflowRunOutput"] = None,
460
582
  run_context: Optional[RunContext] = None,
@@ -465,6 +587,7 @@ class Step:
465
587
  workflow_session: Optional["WorkflowSession"] = None,
466
588
  add_workflow_history_to_steps: Optional[bool] = False,
467
589
  num_history_runs: int = 3,
590
+ background_tasks: Optional[Any] = None,
468
591
  ) -> Iterator[Union[WorkflowRunOutputEvent, StepOutput]]:
469
592
  """Execute the step with event-driven streaming support"""
470
593
 
@@ -481,9 +604,6 @@ class Step:
481
604
  else:
482
605
  session_state_copy = copy(session_state) if session_state is not None else {}
483
606
 
484
- # Considering both stream_events and stream_intermediate_steps (deprecated)
485
- stream_events = stream_events or stream_intermediate_steps
486
-
487
607
  # Emit StepStartedEvent
488
608
  if stream_events and workflow_run_response:
489
609
  yield StepStartedEvent(
@@ -537,11 +657,11 @@ class Step:
537
657
  yield enriched_event # type: ignore[misc]
538
658
  elif isinstance(event, (RunOutput, TeamRunOutput)):
539
659
  content = event.content # type: ignore[assignment]
540
- else:
541
- content += str(event)
542
- if isinstance(event, StepOutput):
660
+ elif isinstance(event, StepOutput):
543
661
  final_response = event
544
662
  break
663
+ else:
664
+ content += str(event)
545
665
 
546
666
  # Merge session_state changes back
547
667
  if run_context is None and session_state is not None:
@@ -598,6 +718,10 @@ class Step:
598
718
  if isinstance(self.active_executor, Team):
599
719
  kwargs["store_member_responses"] = True
600
720
 
721
+ # Forward background_tasks if provided
722
+ if background_tasks is not None:
723
+ kwargs["background_tasks"] = background_tasks
724
+
601
725
  num_history_runs = self.num_history_runs if self.num_history_runs else num_history_runs
602
726
 
603
727
  use_history = (
@@ -623,7 +747,7 @@ class Step:
623
747
  session_state=session_state_copy, # Send a copy to the executor
624
748
  stream=True,
625
749
  stream_events=stream_events,
626
- yield_run_response=True,
750
+ yield_run_output=True,
627
751
  run_context=run_context,
628
752
  **kwargs,
629
753
  )
@@ -632,7 +756,7 @@ class Step:
632
756
  for event in response_stream:
633
757
  if isinstance(event, RunOutput) or isinstance(event, TeamRunOutput):
634
758
  active_executor_run_response = event
635
- break
759
+ continue
636
760
  # Only yield executor events if stream_executor_events is True
637
761
  if stream_executor_events:
638
762
  enriched_event = self._enrich_event_with_context(
@@ -709,6 +833,7 @@ class Step:
709
833
  workflow_session: Optional["WorkflowSession"] = None,
710
834
  add_workflow_history_to_steps: Optional[bool] = False,
711
835
  num_history_runs: int = 3,
836
+ background_tasks: Optional[Any] = None,
712
837
  ) -> StepOutput:
713
838
  """Execute the step with StepInput, returning final StepOutput (non-streaming)"""
714
839
  logger.info(f"Executing async step (non-streaming): {self.name}")
@@ -758,10 +883,12 @@ class Step:
758
883
  content = str(chunk.content)
759
884
  elif isinstance(chunk, (RunOutput, TeamRunOutput)):
760
885
  content = chunk.content # type: ignore[assignment]
886
+ elif isinstance(chunk, StepOutput):
887
+ final_response = chunk
888
+ break
761
889
  else:
762
890
  content += str(chunk)
763
- if isinstance(chunk, StepOutput):
764
- final_response = chunk
891
+
765
892
  else:
766
893
  if _is_async_generator_function(self.active_executor):
767
894
  iterator = await self._acall_custom_function(
@@ -784,10 +911,11 @@ class Step:
784
911
  content = str(chunk.content)
785
912
  elif isinstance(chunk, (RunOutput, TeamRunOutput)):
786
913
  content = chunk.content # type: ignore[assignment]
914
+ elif isinstance(chunk, StepOutput):
915
+ final_response = chunk
916
+ break
787
917
  else:
788
918
  content += str(chunk)
789
- if isinstance(chunk, StepOutput):
790
- final_response = chunk
791
919
 
792
920
  except StopIteration as e:
793
921
  if hasattr(e, "value") and isinstance(e.value, StepOutput):
@@ -856,6 +984,10 @@ class Step:
856
984
  if isinstance(self.active_executor, Team):
857
985
  kwargs["store_member_responses"] = True
858
986
 
987
+ # Forward background_tasks if provided
988
+ if background_tasks is not None:
989
+ kwargs["background_tasks"] = background_tasks
990
+
859
991
  num_history_runs = self.num_history_runs if self.num_history_runs else num_history_runs
860
992
 
861
993
  use_history = (
@@ -920,7 +1052,6 @@ class Step:
920
1052
  session_id: Optional[str] = None,
921
1053
  user_id: Optional[str] = None,
922
1054
  stream_events: bool = False,
923
- stream_intermediate_steps: bool = False,
924
1055
  stream_executor_events: bool = True,
925
1056
  workflow_run_response: Optional["WorkflowRunOutput"] = None,
926
1057
  run_context: Optional[RunContext] = None,
@@ -931,6 +1062,7 @@ class Step:
931
1062
  workflow_session: Optional["WorkflowSession"] = None,
932
1063
  add_workflow_history_to_steps: Optional[bool] = False,
933
1064
  num_history_runs: int = 3,
1065
+ background_tasks: Optional[Any] = None,
934
1066
  ) -> AsyncIterator[Union[WorkflowRunOutputEvent, StepOutput]]:
935
1067
  """Execute the step with event-driven streaming support"""
936
1068
 
@@ -947,9 +1079,6 @@ class Step:
947
1079
  else:
948
1080
  session_state_copy = copy(session_state) if session_state is not None else {}
949
1081
 
950
- # Considering both stream_events and stream_intermediate_steps (deprecated)
951
- stream_events = stream_events or stream_intermediate_steps
952
-
953
1082
  if stream_events and workflow_run_response:
954
1083
  # Emit StepStartedEvent
955
1084
  yield StepStartedEvent(
@@ -1003,11 +1132,11 @@ class Step:
1003
1132
  yield enriched_event # type: ignore[misc]
1004
1133
  elif isinstance(event, (RunOutput, TeamRunOutput)):
1005
1134
  content = event.content # type: ignore[assignment]
1006
- else:
1007
- content += str(event)
1008
- if isinstance(event, StepOutput):
1135
+ elif isinstance(event, StepOutput):
1009
1136
  final_response = event
1010
1137
  break
1138
+ else:
1139
+ content += str(event)
1011
1140
  if not final_response:
1012
1141
  final_response = StepOutput(content=content)
1013
1142
  elif _is_async_callable(self.active_executor):
@@ -1054,11 +1183,14 @@ class Step:
1054
1183
  yield enriched_event # type: ignore[misc]
1055
1184
  elif isinstance(event, (RunOutput, TeamRunOutput)):
1056
1185
  content = event.content # type: ignore[assignment]
1057
- else:
1058
- content += str(event)
1059
- if isinstance(event, StepOutput):
1186
+ elif isinstance(event, StepOutput):
1060
1187
  final_response = event
1061
1188
  break
1189
+ else:
1190
+ if isinstance(content, str):
1191
+ content += str(event)
1192
+ else:
1193
+ content = str(event)
1062
1194
  if not final_response:
1063
1195
  final_response = StepOutput(content=content)
1064
1196
  else:
@@ -1105,6 +1237,10 @@ class Step:
1105
1237
  if isinstance(self.active_executor, Team):
1106
1238
  kwargs["store_member_responses"] = True
1107
1239
 
1240
+ # Forward background_tasks if provided
1241
+ if background_tasks is not None:
1242
+ kwargs["background_tasks"] = background_tasks
1243
+
1108
1244
  num_history_runs = self.num_history_runs if self.num_history_runs else num_history_runs
1109
1245
 
1110
1246
  use_history = (
@@ -1131,7 +1267,7 @@ class Step:
1131
1267
  stream=True,
1132
1268
  stream_events=stream_events,
1133
1269
  run_context=run_context,
1134
- yield_run_response=True,
1270
+ yield_run_output=True,
1135
1271
  **kwargs,
1136
1272
  )
1137
1273
 
@@ -1202,6 +1338,83 @@ class Step:
1202
1338
 
1203
1339
  return
1204
1340
 
1341
+ def get_chat_history(self, session_id: str, last_n_runs: Optional[int] = None) -> List[Message]:
1342
+ """Return the step's Agent or Team chat history for the given session.
1343
+
1344
+ Args:
1345
+ session_id: The session ID to get the chat history for. If not provided, the current cached session ID is used.
1346
+ last_n_runs: Number of recent runs to include. If None, all runs will be considered.
1347
+
1348
+ Returns:
1349
+ List[Message]: The step's Agent or Team chat history for the given session.
1350
+ """
1351
+ session: Union[AgentSession, TeamSession, WorkflowSession, None] = None
1352
+
1353
+ if self.agent:
1354
+ session = self.agent.get_session(session_id=session_id)
1355
+ if not session:
1356
+ log_warning("Session not found")
1357
+ return []
1358
+
1359
+ if not isinstance(session, WorkflowSession):
1360
+ raise ValueError("The provided session is not a WorkflowSession")
1361
+
1362
+ session = cast(WorkflowSession, session)
1363
+ return session.get_messages(last_n_runs=last_n_runs, agent_id=self.agent.id)
1364
+
1365
+ elif self.team:
1366
+ session = self.team.get_session(session_id=session_id)
1367
+ if not session:
1368
+ log_warning("Session not found")
1369
+ return []
1370
+
1371
+ if not isinstance(session, WorkflowSession):
1372
+ raise ValueError("The provided session is not a WorkflowSession")
1373
+
1374
+ session = cast(WorkflowSession, session)
1375
+ return session.get_messages(last_n_runs=last_n_runs, team_id=self.team.id)
1376
+
1377
+ return []
1378
+
1379
+ async def aget_chat_history(
1380
+ self, session_id: Optional[str] = None, last_n_runs: Optional[int] = None
1381
+ ) -> List[Message]:
1382
+ """Return the step's Agent or Team chat history for the given session.
1383
+
1384
+ Args:
1385
+ session_id: The session ID to get the chat history for. If not provided, the current cached session ID is used.
1386
+ last_n_runs: Number of recent runs to include. If None, all runs will be considered.
1387
+
1388
+ Returns:
1389
+ List[Message]: The step's Agent or Team chat history for the given session.
1390
+ """
1391
+ session: Union[AgentSession, TeamSession, WorkflowSession, None] = None
1392
+
1393
+ if self.agent:
1394
+ session = await self.agent.aget_session(session_id=session_id)
1395
+ if not session:
1396
+ log_warning("Session not found")
1397
+ return []
1398
+
1399
+ if not isinstance(session, WorkflowSession):
1400
+ raise ValueError("The provided session is not a WorkflowSession")
1401
+
1402
+ session = cast(WorkflowSession, session)
1403
+ return session.get_messages(last_n_runs=last_n_runs, agent_id=self.agent.id)
1404
+
1405
+ elif self.team:
1406
+ session = await self.team.aget_session(session_id=session_id)
1407
+ if not session:
1408
+ log_warning("Session not found")
1409
+ return []
1410
+
1411
+ if not isinstance(session, WorkflowSession):
1412
+ raise ValueError("The provided session is not a WorkflowSession")
1413
+
1414
+ return session.get_messages(last_n_runs=last_n_runs, team_id=self.team.id)
1415
+
1416
+ return []
1417
+
1205
1418
  def _store_executor_response(
1206
1419
  self, workflow_run_response: "WorkflowRunOutput", executor_run_response: Union[RunOutput, TeamRunOutput]
1207
1420
  ) -> None:
@@ -1243,10 +1456,22 @@ class Step:
1243
1456
 
1244
1457
  For container steps (Steps, Router, Loop, etc.), this will recursively find the content from the
1245
1458
  last actual step rather than using the generic container message.
1459
+
1460
+ For Parallel steps, aggregates content from ALL inner steps (not just the last one).
1246
1461
  """
1247
- # If this step has nested steps (like Steps, Condition, Router, Loop, etc.)
1462
+ # If this step has nested steps (like Steps, Condition, Router, Loop, Parallel, etc.)
1248
1463
  if hasattr(step_output, "steps") and step_output.steps and len(step_output.steps) > 0:
1249
- # Recursively get content from the last nested step
1464
+ # For Parallel steps, aggregate content from ALL inner steps
1465
+ if step_output.step_type == StepType.PARALLEL:
1466
+ aggregated_parts = []
1467
+ for i, inner_step in enumerate(step_output.steps):
1468
+ inner_content = self._get_deepest_content_from_step_output(inner_step)
1469
+ if inner_content:
1470
+ step_name = inner_step.step_name or f"Step {i + 1}"
1471
+ aggregated_parts.append(f"=== {step_name} ===\n{inner_content}")
1472
+ return "\n\n".join(aggregated_parts) if aggregated_parts else step_output.content # type: ignore
1473
+
1474
+ # For other nested step types, recursively get content from the last nested step
1250
1475
  return self._get_deepest_content_from_step_output(step_output.steps[-1])
1251
1476
 
1252
1477
  # For regular steps, return their content
agno/workflow/steps.py CHANGED
@@ -125,6 +125,7 @@ class Steps:
125
125
  workflow_session: Optional[WorkflowSession] = None,
126
126
  add_workflow_history_to_steps: Optional[bool] = False,
127
127
  num_history_runs: int = 3,
128
+ background_tasks: Optional[Any] = None,
128
129
  ) -> StepOutput:
129
130
  """Execute all steps in sequence and return the final result"""
130
131
  log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
@@ -158,6 +159,7 @@ class Steps:
158
159
  workflow_session=workflow_session,
159
160
  add_workflow_history_to_steps=add_workflow_history_to_steps,
160
161
  num_history_runs=num_history_runs,
162
+ background_tasks=background_tasks,
161
163
  )
162
164
 
163
165
  # Handle both single StepOutput and List[StepOutput] (from Loop/Condition/Router steps)
@@ -191,6 +193,7 @@ class Steps:
191
193
  step_type=StepType.STEPS,
192
194
  content=f"Steps {self.name} completed with {len(all_results)} results",
193
195
  success=all(result.success for result in all_results) if all_results else True,
196
+ stop=any(result.stop for result in all_results) if all_results else False,
194
197
  steps=all_results,
195
198
  )
196
199
 
@@ -212,7 +215,6 @@ class Steps:
212
215
  session_id: Optional[str] = None,
213
216
  user_id: Optional[str] = None,
214
217
  stream_events: bool = False,
215
- stream_intermediate_steps: bool = False,
216
218
  stream_executor_events: bool = True,
217
219
  step_index: Optional[Union[int, tuple]] = None,
218
220
  store_executor_outputs: bool = True,
@@ -220,6 +222,7 @@ class Steps:
220
222
  workflow_session: Optional[WorkflowSession] = None,
221
223
  add_workflow_history_to_steps: Optional[bool] = False,
222
224
  num_history_runs: int = 3,
225
+ background_tasks: Optional[Any] = None,
223
226
  ) -> Iterator[Union[WorkflowRunOutputEvent, TeamRunOutputEvent, RunOutputEvent, StepOutput]]:
224
227
  """Execute all steps in sequence with streaming support"""
225
228
  log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
@@ -228,9 +231,6 @@ class Steps:
228
231
 
229
232
  self._prepare_steps()
230
233
 
231
- # Considering both stream_events and stream_intermediate_steps (deprecated)
232
- stream_events = stream_events or stream_intermediate_steps
233
-
234
234
  if stream_events:
235
235
  # Yield steps execution started event
236
236
  yield StepsExecutionStartedEvent(
@@ -284,6 +284,7 @@ class Steps:
284
284
  workflow_session=workflow_session,
285
285
  add_workflow_history_to_steps=add_workflow_history_to_steps,
286
286
  num_history_runs=num_history_runs,
287
+ background_tasks=background_tasks,
287
288
  ):
288
289
  if isinstance(event, StepOutput):
289
290
  step_outputs_for_step.append(event)
@@ -340,6 +341,7 @@ class Steps:
340
341
  step_type=StepType.STEPS,
341
342
  content=f"Steps {self.name} completed with {len(all_results)} results",
342
343
  success=all(result.success for result in all_results) if all_results else True,
344
+ stop=any(result.stop for result in all_results) if all_results else False,
343
345
  steps=all_results,
344
346
  )
345
347
 
@@ -365,6 +367,7 @@ class Steps:
365
367
  workflow_session: Optional[WorkflowSession] = None,
366
368
  add_workflow_history_to_steps: Optional[bool] = False,
367
369
  num_history_runs: int = 3,
370
+ background_tasks: Optional[Any] = None,
368
371
  ) -> StepOutput:
369
372
  """Execute all steps in sequence asynchronously and return the final result"""
370
373
  log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
@@ -398,6 +401,7 @@ class Steps:
398
401
  workflow_session=workflow_session,
399
402
  add_workflow_history_to_steps=add_workflow_history_to_steps,
400
403
  num_history_runs=num_history_runs,
404
+ background_tasks=background_tasks,
401
405
  )
402
406
 
403
407
  # Handle both single StepOutput and List[StepOutput] (from Loop/Condition/Router steps)
@@ -430,6 +434,7 @@ class Steps:
430
434
  step_type=StepType.STEPS,
431
435
  content=f"Steps {self.name} completed with {len(all_results)} results",
432
436
  success=all(result.success for result in all_results) if all_results else True,
437
+ stop=any(result.stop for result in all_results) if all_results else False,
433
438
  steps=all_results,
434
439
  )
435
440
 
@@ -451,7 +456,6 @@ class Steps:
451
456
  session_id: Optional[str] = None,
452
457
  user_id: Optional[str] = None,
453
458
  stream_events: bool = False,
454
- stream_intermediate_steps: bool = False,
455
459
  stream_executor_events: bool = True,
456
460
  step_index: Optional[Union[int, tuple]] = None,
457
461
  store_executor_outputs: bool = True,
@@ -459,6 +463,7 @@ class Steps:
459
463
  workflow_session: Optional[WorkflowSession] = None,
460
464
  add_workflow_history_to_steps: Optional[bool] = False,
461
465
  num_history_runs: int = 3,
466
+ background_tasks: Optional[Any] = None,
462
467
  ) -> AsyncIterator[Union[WorkflowRunOutputEvent, TeamRunOutputEvent, RunOutputEvent, StepOutput]]:
463
468
  """Execute all steps in sequence with async streaming support"""
464
469
  log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
@@ -467,9 +472,6 @@ class Steps:
467
472
 
468
473
  self._prepare_steps()
469
474
 
470
- # Considering both stream_events and stream_intermediate_steps (deprecated)
471
- stream_events = stream_events or stream_intermediate_steps
472
-
473
475
  if stream_events:
474
476
  # Yield steps execution started event
475
477
  yield StepsExecutionStartedEvent(
@@ -523,6 +525,7 @@ class Steps:
523
525
  workflow_session=workflow_session,
524
526
  add_workflow_history_to_steps=add_workflow_history_to_steps,
525
527
  num_history_runs=num_history_runs,
528
+ background_tasks=background_tasks,
526
529
  ):
527
530
  if isinstance(event, StepOutput):
528
531
  step_outputs_for_step.append(event)
@@ -578,6 +581,7 @@ class Steps:
578
581
  step_type=StepType.STEPS,
579
582
  content=f"Steps {self.name} completed with {len(all_results)} results",
580
583
  success=all(result.success for result in all_results) if all_results else True,
584
+ stop=any(result.stop for result in all_results) if all_results else False,
581
585
  steps=all_results,
582
586
  )
583
587