agno 1.8.0__py3-none-any.whl → 2.0.0a1__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 (583) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +19 -27
  3. agno/agent/agent.py +2781 -4126
  4. agno/api/agent.py +9 -65
  5. agno/api/api.py +5 -46
  6. agno/api/evals.py +6 -17
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -41
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +5 -21
  11. agno/api/schemas/evals.py +7 -16
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +5 -21
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +11 -7
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +9 -64
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/db/__init__.py +24 -0
  25. agno/db/base.py +245 -0
  26. agno/db/dynamo/__init__.py +3 -0
  27. agno/db/dynamo/dynamo.py +1749 -0
  28. agno/db/dynamo/schemas.py +278 -0
  29. agno/db/dynamo/utils.py +684 -0
  30. agno/db/firestore/__init__.py +3 -0
  31. agno/db/firestore/firestore.py +1438 -0
  32. agno/db/firestore/schemas.py +130 -0
  33. agno/db/firestore/utils.py +278 -0
  34. agno/db/gcs_json/__init__.py +3 -0
  35. agno/db/gcs_json/gcs_json_db.py +1001 -0
  36. agno/db/gcs_json/utils.py +194 -0
  37. agno/db/in_memory/__init__.py +3 -0
  38. agno/db/in_memory/in_memory_db.py +888 -0
  39. agno/db/in_memory/utils.py +172 -0
  40. agno/db/json/__init__.py +3 -0
  41. agno/db/json/json_db.py +1051 -0
  42. agno/db/json/utils.py +196 -0
  43. agno/db/migrations/v1_to_v2.py +162 -0
  44. agno/db/mongo/__init__.py +3 -0
  45. agno/db/mongo/mongo.py +1417 -0
  46. agno/db/mongo/schemas.py +77 -0
  47. agno/db/mongo/utils.py +204 -0
  48. agno/db/mysql/__init__.py +3 -0
  49. agno/db/mysql/mysql.py +1719 -0
  50. agno/db/mysql/schemas.py +124 -0
  51. agno/db/mysql/utils.py +298 -0
  52. agno/db/postgres/__init__.py +3 -0
  53. agno/db/postgres/postgres.py +1720 -0
  54. agno/db/postgres/schemas.py +124 -0
  55. agno/db/postgres/utils.py +281 -0
  56. agno/db/redis/__init__.py +3 -0
  57. agno/db/redis/redis.py +1371 -0
  58. agno/db/redis/schemas.py +109 -0
  59. agno/db/redis/utils.py +288 -0
  60. agno/db/schemas/__init__.py +3 -0
  61. agno/db/schemas/evals.py +33 -0
  62. agno/db/schemas/knowledge.py +40 -0
  63. agno/db/schemas/memory.py +46 -0
  64. agno/db/singlestore/__init__.py +3 -0
  65. agno/db/singlestore/schemas.py +116 -0
  66. agno/db/singlestore/singlestore.py +1722 -0
  67. agno/db/singlestore/utils.py +327 -0
  68. agno/db/sqlite/__init__.py +3 -0
  69. agno/db/sqlite/schemas.py +119 -0
  70. agno/db/sqlite/sqlite.py +1680 -0
  71. agno/db/sqlite/utils.py +269 -0
  72. agno/db/utils.py +88 -0
  73. agno/eval/__init__.py +14 -0
  74. agno/eval/accuracy.py +142 -43
  75. agno/eval/performance.py +88 -23
  76. agno/eval/reliability.py +73 -20
  77. agno/eval/utils.py +23 -13
  78. agno/integrations/discord/__init__.py +3 -0
  79. agno/{app → integrations}/discord/client.py +10 -10
  80. agno/knowledge/__init__.py +2 -2
  81. agno/{document → knowledge}/chunking/agentic.py +2 -2
  82. agno/{document → knowledge}/chunking/document.py +2 -2
  83. agno/{document → knowledge}/chunking/fixed.py +3 -3
  84. agno/{document → knowledge}/chunking/markdown.py +2 -2
  85. agno/{document → knowledge}/chunking/recursive.py +2 -2
  86. agno/{document → knowledge}/chunking/row.py +2 -2
  87. agno/knowledge/chunking/semantic.py +59 -0
  88. agno/knowledge/chunking/strategy.py +121 -0
  89. agno/knowledge/content.py +74 -0
  90. agno/knowledge/document/__init__.py +5 -0
  91. agno/{document → knowledge/document}/base.py +12 -2
  92. agno/knowledge/embedder/__init__.py +5 -0
  93. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  94. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  95. agno/{embedder → knowledge/embedder}/base.py +6 -0
  96. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  97. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  98. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  99. agno/{embedder → knowledge/embedder}/google.py +74 -1
  100. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  101. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  102. agno/knowledge/embedder/langdb.py +22 -0
  103. agno/knowledge/embedder/mistral.py +139 -0
  104. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  105. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  106. agno/knowledge/embedder/openai.py +223 -0
  107. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  108. agno/{embedder → knowledge/embedder}/together.py +1 -1
  109. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  110. agno/knowledge/knowledge.py +1515 -0
  111. agno/knowledge/reader/__init__.py +7 -0
  112. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  113. agno/knowledge/reader/base.py +88 -0
  114. agno/{document → knowledge}/reader/csv_reader.py +68 -15
  115. agno/knowledge/reader/docx_reader.py +83 -0
  116. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  117. agno/knowledge/reader/gcs_reader.py +67 -0
  118. agno/{document → knowledge}/reader/json_reader.py +30 -9
  119. agno/{document → knowledge}/reader/markdown_reader.py +36 -9
  120. agno/{document → knowledge}/reader/pdf_reader.py +79 -21
  121. agno/knowledge/reader/reader_factory.py +275 -0
  122. agno/knowledge/reader/s3_reader.py +171 -0
  123. agno/{document → knowledge}/reader/text_reader.py +31 -10
  124. agno/knowledge/reader/url_reader.py +84 -0
  125. agno/knowledge/reader/web_search_reader.py +389 -0
  126. agno/{document → knowledge}/reader/website_reader.py +37 -10
  127. agno/knowledge/reader/wikipedia_reader.py +59 -0
  128. agno/knowledge/reader/youtube_reader.py +78 -0
  129. agno/knowledge/remote_content/remote_content.py +88 -0
  130. agno/{reranker → knowledge/reranker}/base.py +1 -1
  131. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  132. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  133. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  134. agno/knowledge/types.py +30 -0
  135. agno/knowledge/utils.py +169 -0
  136. agno/media.py +2 -2
  137. agno/memory/__init__.py +2 -10
  138. agno/memory/manager.py +1003 -148
  139. agno/models/aimlapi/__init__.py +2 -2
  140. agno/models/aimlapi/aimlapi.py +6 -6
  141. agno/models/anthropic/claude.py +129 -82
  142. agno/models/aws/bedrock.py +107 -175
  143. agno/models/aws/claude.py +64 -18
  144. agno/models/azure/ai_foundry.py +73 -23
  145. agno/models/base.py +347 -287
  146. agno/models/cerebras/cerebras.py +84 -27
  147. agno/models/cohere/chat.py +106 -98
  148. agno/models/dashscope/dashscope.py +14 -5
  149. agno/models/google/gemini.py +123 -53
  150. agno/models/groq/groq.py +97 -35
  151. agno/models/huggingface/huggingface.py +92 -27
  152. agno/models/ibm/watsonx.py +72 -13
  153. agno/models/litellm/chat.py +85 -13
  154. agno/models/message.py +38 -144
  155. agno/models/meta/llama.py +85 -49
  156. agno/models/metrics.py +120 -0
  157. agno/models/mistral/mistral.py +90 -21
  158. agno/models/ollama/__init__.py +0 -2
  159. agno/models/ollama/chat.py +84 -46
  160. agno/models/openai/chat.py +135 -27
  161. agno/models/openai/responses.py +233 -115
  162. agno/models/perplexity/perplexity.py +26 -2
  163. agno/models/portkey/portkey.py +0 -7
  164. agno/models/response.py +14 -8
  165. agno/models/utils.py +20 -0
  166. agno/models/vercel/__init__.py +2 -2
  167. agno/models/vercel/v0.py +1 -1
  168. agno/models/vllm/__init__.py +2 -2
  169. agno/models/vllm/vllm.py +3 -3
  170. agno/models/xai/xai.py +10 -10
  171. agno/os/__init__.py +3 -0
  172. agno/os/app.py +393 -0
  173. agno/os/auth.py +47 -0
  174. agno/os/config.py +103 -0
  175. agno/os/interfaces/agui/__init__.py +3 -0
  176. agno/os/interfaces/agui/agui.py +31 -0
  177. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  178. agno/{app → os/interfaces}/agui/utils.py +65 -28
  179. agno/os/interfaces/base.py +21 -0
  180. agno/os/interfaces/slack/__init__.py +3 -0
  181. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  182. agno/os/interfaces/slack/slack.py +33 -0
  183. agno/os/interfaces/whatsapp/__init__.py +3 -0
  184. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  185. agno/os/interfaces/whatsapp/whatsapp.py +30 -0
  186. agno/os/router.py +843 -0
  187. agno/os/routers/__init__.py +3 -0
  188. agno/os/routers/evals/__init__.py +3 -0
  189. agno/os/routers/evals/evals.py +204 -0
  190. agno/os/routers/evals/schemas.py +142 -0
  191. agno/os/routers/evals/utils.py +161 -0
  192. agno/os/routers/knowledge/__init__.py +3 -0
  193. agno/os/routers/knowledge/knowledge.py +413 -0
  194. agno/os/routers/knowledge/schemas.py +118 -0
  195. agno/os/routers/memory/__init__.py +3 -0
  196. agno/os/routers/memory/memory.py +179 -0
  197. agno/os/routers/memory/schemas.py +58 -0
  198. agno/os/routers/metrics/__init__.py +3 -0
  199. agno/os/routers/metrics/metrics.py +58 -0
  200. agno/os/routers/metrics/schemas.py +47 -0
  201. agno/os/routers/session/__init__.py +3 -0
  202. agno/os/routers/session/session.py +163 -0
  203. agno/os/schema.py +892 -0
  204. agno/{app/playground → os}/settings.py +8 -15
  205. agno/os/utils.py +270 -0
  206. agno/reasoning/azure_ai_foundry.py +4 -4
  207. agno/reasoning/deepseek.py +4 -4
  208. agno/reasoning/default.py +6 -11
  209. agno/reasoning/groq.py +4 -4
  210. agno/reasoning/helpers.py +4 -6
  211. agno/reasoning/ollama.py +4 -4
  212. agno/reasoning/openai.py +4 -4
  213. agno/run/{response.py → agent.py} +144 -72
  214. agno/run/base.py +44 -58
  215. agno/run/cancel.py +83 -0
  216. agno/run/team.py +133 -77
  217. agno/run/workflow.py +537 -12
  218. agno/session/__init__.py +10 -0
  219. agno/session/agent.py +244 -0
  220. agno/session/summary.py +225 -0
  221. agno/session/team.py +262 -0
  222. agno/{storage/session/v2 → session}/workflow.py +47 -24
  223. agno/team/__init__.py +15 -16
  224. agno/team/team.py +2967 -4243
  225. agno/tools/agentql.py +14 -5
  226. agno/tools/airflow.py +9 -4
  227. agno/tools/api.py +7 -3
  228. agno/tools/apify.py +2 -46
  229. agno/tools/arxiv.py +8 -3
  230. agno/tools/aws_lambda.py +7 -5
  231. agno/tools/aws_ses.py +7 -1
  232. agno/tools/baidusearch.py +4 -1
  233. agno/tools/bitbucket.py +4 -4
  234. agno/tools/brandfetch.py +14 -11
  235. agno/tools/bravesearch.py +4 -1
  236. agno/tools/brightdata.py +42 -22
  237. agno/tools/browserbase.py +13 -4
  238. agno/tools/calcom.py +12 -10
  239. agno/tools/calculator.py +10 -27
  240. agno/tools/cartesia.py +18 -13
  241. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  242. agno/tools/confluence.py +71 -18
  243. agno/tools/crawl4ai.py +7 -1
  244. agno/tools/csv_toolkit.py +9 -8
  245. agno/tools/dalle.py +18 -11
  246. agno/tools/daytona.py +13 -16
  247. agno/tools/decorator.py +6 -3
  248. agno/tools/desi_vocal.py +16 -7
  249. agno/tools/discord.py +11 -8
  250. agno/tools/docker.py +30 -42
  251. agno/tools/duckdb.py +34 -53
  252. agno/tools/duckduckgo.py +8 -7
  253. agno/tools/e2b.py +62 -62
  254. agno/tools/eleven_labs.py +35 -28
  255. agno/tools/email.py +4 -1
  256. agno/tools/evm.py +7 -1
  257. agno/tools/exa.py +19 -14
  258. agno/tools/fal.py +29 -29
  259. agno/tools/file.py +9 -8
  260. agno/tools/financial_datasets.py +25 -44
  261. agno/tools/firecrawl.py +22 -22
  262. agno/tools/function.py +68 -17
  263. agno/tools/giphy.py +22 -10
  264. agno/tools/github.py +48 -126
  265. agno/tools/gmail.py +46 -62
  266. agno/tools/google_bigquery.py +7 -6
  267. agno/tools/google_maps.py +11 -26
  268. agno/tools/googlesearch.py +7 -2
  269. agno/tools/googlesheets.py +21 -17
  270. agno/tools/hackernews.py +9 -5
  271. agno/tools/jina.py +5 -4
  272. agno/tools/jira.py +18 -9
  273. agno/tools/knowledge.py +31 -32
  274. agno/tools/linear.py +18 -33
  275. agno/tools/linkup.py +5 -1
  276. agno/tools/local_file_system.py +8 -5
  277. agno/tools/lumalab.py +31 -19
  278. agno/tools/mem0.py +18 -12
  279. agno/tools/memori.py +14 -10
  280. agno/tools/mlx_transcribe.py +3 -2
  281. agno/tools/models/azure_openai.py +32 -14
  282. agno/tools/models/gemini.py +58 -31
  283. agno/tools/models/groq.py +29 -20
  284. agno/tools/models/nebius.py +27 -11
  285. agno/tools/models_labs.py +39 -15
  286. agno/tools/moviepy_video.py +7 -6
  287. agno/tools/neo4j.py +134 -0
  288. agno/tools/newspaper.py +7 -2
  289. agno/tools/newspaper4k.py +8 -3
  290. agno/tools/openai.py +57 -26
  291. agno/tools/openbb.py +12 -11
  292. agno/tools/opencv.py +62 -46
  293. agno/tools/openweather.py +14 -12
  294. agno/tools/pandas.py +11 -3
  295. agno/tools/postgres.py +4 -12
  296. agno/tools/pubmed.py +4 -1
  297. agno/tools/python.py +9 -22
  298. agno/tools/reasoning.py +35 -27
  299. agno/tools/reddit.py +11 -26
  300. agno/tools/replicate.py +54 -41
  301. agno/tools/resend.py +4 -1
  302. agno/tools/scrapegraph.py +15 -14
  303. agno/tools/searxng.py +10 -23
  304. agno/tools/serpapi.py +6 -3
  305. agno/tools/serper.py +13 -4
  306. agno/tools/shell.py +9 -2
  307. agno/tools/slack.py +12 -11
  308. agno/tools/sleep.py +3 -2
  309. agno/tools/spider.py +24 -4
  310. agno/tools/sql.py +7 -6
  311. agno/tools/tavily.py +6 -4
  312. agno/tools/telegram.py +12 -4
  313. agno/tools/todoist.py +11 -31
  314. agno/tools/toolkit.py +1 -1
  315. agno/tools/trafilatura.py +22 -6
  316. agno/tools/trello.py +9 -22
  317. agno/tools/twilio.py +10 -3
  318. agno/tools/user_control_flow.py +6 -1
  319. agno/tools/valyu.py +34 -5
  320. agno/tools/visualization.py +19 -28
  321. agno/tools/webbrowser.py +4 -3
  322. agno/tools/webex.py +11 -7
  323. agno/tools/website.py +15 -46
  324. agno/tools/webtools.py +12 -4
  325. agno/tools/whatsapp.py +5 -9
  326. agno/tools/wikipedia.py +20 -13
  327. agno/tools/x.py +14 -13
  328. agno/tools/yfinance.py +13 -40
  329. agno/tools/youtube.py +26 -20
  330. agno/tools/zendesk.py +7 -2
  331. agno/tools/zep.py +10 -7
  332. agno/tools/zoom.py +10 -9
  333. agno/utils/common.py +1 -19
  334. agno/utils/events.py +95 -118
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/location.py +2 -2
  337. agno/utils/log.py +2 -2
  338. agno/utils/mcp.py +11 -5
  339. agno/utils/media.py +39 -0
  340. agno/utils/message.py +12 -1
  341. agno/utils/models/claude.py +6 -4
  342. agno/utils/models/mistral.py +8 -7
  343. agno/utils/models/schema_utils.py +3 -3
  344. agno/utils/pprint.py +33 -32
  345. agno/utils/print_response/agent.py +779 -0
  346. agno/utils/print_response/team.py +1565 -0
  347. agno/utils/print_response/workflow.py +1451 -0
  348. agno/utils/prompts.py +14 -14
  349. agno/utils/reasoning.py +87 -0
  350. agno/utils/response.py +42 -42
  351. agno/utils/string.py +8 -22
  352. agno/utils/team.py +50 -0
  353. agno/utils/timer.py +2 -2
  354. agno/vectordb/base.py +33 -21
  355. agno/vectordb/cassandra/cassandra.py +287 -23
  356. agno/vectordb/chroma/chromadb.py +482 -59
  357. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  358. agno/vectordb/couchbase/couchbase.py +309 -29
  359. agno/vectordb/lancedb/lance_db.py +360 -21
  360. agno/vectordb/langchaindb/__init__.py +5 -0
  361. agno/vectordb/langchaindb/langchaindb.py +145 -0
  362. agno/vectordb/lightrag/__init__.py +5 -0
  363. agno/vectordb/lightrag/lightrag.py +374 -0
  364. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  365. agno/vectordb/milvus/milvus.py +242 -32
  366. agno/vectordb/mongodb/mongodb.py +200 -24
  367. agno/vectordb/pgvector/pgvector.py +319 -37
  368. agno/vectordb/pineconedb/pineconedb.py +221 -27
  369. agno/vectordb/qdrant/qdrant.py +356 -14
  370. agno/vectordb/singlestore/singlestore.py +286 -29
  371. agno/vectordb/surrealdb/surrealdb.py +187 -7
  372. agno/vectordb/upstashdb/upstashdb.py +342 -26
  373. agno/vectordb/weaviate/weaviate.py +227 -165
  374. agno/workflow/__init__.py +17 -13
  375. agno/workflow/{v2/condition.py → condition.py} +135 -32
  376. agno/workflow/{v2/loop.py → loop.py} +115 -28
  377. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  378. agno/workflow/{v2/router.py → router.py} +133 -32
  379. agno/workflow/{v2/step.py → step.py} +200 -42
  380. agno/workflow/{v2/steps.py → steps.py} +147 -66
  381. agno/workflow/types.py +482 -0
  382. agno/workflow/workflow.py +2394 -696
  383. agno-2.0.0a1.dist-info/METADATA +355 -0
  384. agno-2.0.0a1.dist-info/RECORD +514 -0
  385. agno/agent/metrics.py +0 -107
  386. agno/api/app.py +0 -35
  387. agno/api/playground.py +0 -92
  388. agno/api/schemas/app.py +0 -12
  389. agno/api/schemas/playground.py +0 -22
  390. agno/api/schemas/user.py +0 -35
  391. agno/api/schemas/workspace.py +0 -46
  392. agno/api/user.py +0 -160
  393. agno/api/workflows.py +0 -33
  394. agno/api/workspace.py +0 -175
  395. agno/app/agui/__init__.py +0 -3
  396. agno/app/agui/app.py +0 -17
  397. agno/app/agui/sync_router.py +0 -120
  398. agno/app/base.py +0 -186
  399. agno/app/discord/__init__.py +0 -3
  400. agno/app/fastapi/__init__.py +0 -3
  401. agno/app/fastapi/app.py +0 -107
  402. agno/app/fastapi/async_router.py +0 -457
  403. agno/app/fastapi/sync_router.py +0 -448
  404. agno/app/playground/app.py +0 -228
  405. agno/app/playground/async_router.py +0 -1050
  406. agno/app/playground/deploy.py +0 -249
  407. agno/app/playground/operator.py +0 -183
  408. agno/app/playground/schemas.py +0 -220
  409. agno/app/playground/serve.py +0 -55
  410. agno/app/playground/sync_router.py +0 -1042
  411. agno/app/playground/utils.py +0 -46
  412. agno/app/settings.py +0 -15
  413. agno/app/slack/__init__.py +0 -3
  414. agno/app/slack/app.py +0 -19
  415. agno/app/slack/sync_router.py +0 -92
  416. agno/app/utils.py +0 -54
  417. agno/app/whatsapp/__init__.py +0 -3
  418. agno/app/whatsapp/app.py +0 -15
  419. agno/app/whatsapp/sync_router.py +0 -197
  420. agno/cli/auth_server.py +0 -249
  421. agno/cli/config.py +0 -274
  422. agno/cli/console.py +0 -88
  423. agno/cli/credentials.py +0 -23
  424. agno/cli/entrypoint.py +0 -571
  425. agno/cli/operator.py +0 -357
  426. agno/cli/settings.py +0 -96
  427. agno/cli/ws/ws_cli.py +0 -817
  428. agno/constants.py +0 -13
  429. agno/document/__init__.py +0 -5
  430. agno/document/chunking/semantic.py +0 -45
  431. agno/document/chunking/strategy.py +0 -31
  432. agno/document/reader/__init__.py +0 -5
  433. agno/document/reader/base.py +0 -47
  434. agno/document/reader/docx_reader.py +0 -60
  435. agno/document/reader/gcs/pdf_reader.py +0 -44
  436. agno/document/reader/s3/pdf_reader.py +0 -59
  437. agno/document/reader/s3/text_reader.py +0 -63
  438. agno/document/reader/url_reader.py +0 -59
  439. agno/document/reader/youtube_reader.py +0 -58
  440. agno/embedder/__init__.py +0 -5
  441. agno/embedder/langdb.py +0 -80
  442. agno/embedder/mistral.py +0 -82
  443. agno/embedder/openai.py +0 -78
  444. agno/file/__init__.py +0 -5
  445. agno/file/file.py +0 -16
  446. agno/file/local/csv.py +0 -32
  447. agno/file/local/txt.py +0 -19
  448. agno/infra/app.py +0 -240
  449. agno/infra/base.py +0 -144
  450. agno/infra/context.py +0 -20
  451. agno/infra/db_app.py +0 -52
  452. agno/infra/resource.py +0 -205
  453. agno/infra/resources.py +0 -55
  454. agno/knowledge/agent.py +0 -698
  455. agno/knowledge/arxiv.py +0 -33
  456. agno/knowledge/combined.py +0 -36
  457. agno/knowledge/csv.py +0 -144
  458. agno/knowledge/csv_url.py +0 -124
  459. agno/knowledge/document.py +0 -223
  460. agno/knowledge/docx.py +0 -137
  461. agno/knowledge/firecrawl.py +0 -34
  462. agno/knowledge/gcs/__init__.py +0 -0
  463. agno/knowledge/gcs/base.py +0 -39
  464. agno/knowledge/gcs/pdf.py +0 -125
  465. agno/knowledge/json.py +0 -137
  466. agno/knowledge/langchain.py +0 -71
  467. agno/knowledge/light_rag.py +0 -273
  468. agno/knowledge/llamaindex.py +0 -66
  469. agno/knowledge/markdown.py +0 -154
  470. agno/knowledge/pdf.py +0 -164
  471. agno/knowledge/pdf_bytes.py +0 -42
  472. agno/knowledge/pdf_url.py +0 -148
  473. agno/knowledge/s3/__init__.py +0 -0
  474. agno/knowledge/s3/base.py +0 -64
  475. agno/knowledge/s3/pdf.py +0 -33
  476. agno/knowledge/s3/text.py +0 -34
  477. agno/knowledge/text.py +0 -141
  478. agno/knowledge/url.py +0 -46
  479. agno/knowledge/website.py +0 -179
  480. agno/knowledge/wikipedia.py +0 -32
  481. agno/knowledge/youtube.py +0 -35
  482. agno/memory/agent.py +0 -423
  483. agno/memory/classifier.py +0 -104
  484. agno/memory/db/__init__.py +0 -5
  485. agno/memory/db/base.py +0 -42
  486. agno/memory/db/mongodb.py +0 -189
  487. agno/memory/db/postgres.py +0 -203
  488. agno/memory/db/sqlite.py +0 -193
  489. agno/memory/memory.py +0 -22
  490. agno/memory/row.py +0 -36
  491. agno/memory/summarizer.py +0 -201
  492. agno/memory/summary.py +0 -19
  493. agno/memory/team.py +0 -415
  494. agno/memory/v2/__init__.py +0 -2
  495. agno/memory/v2/db/__init__.py +0 -1
  496. agno/memory/v2/db/base.py +0 -42
  497. agno/memory/v2/db/firestore.py +0 -339
  498. agno/memory/v2/db/mongodb.py +0 -196
  499. agno/memory/v2/db/postgres.py +0 -214
  500. agno/memory/v2/db/redis.py +0 -187
  501. agno/memory/v2/db/schema.py +0 -54
  502. agno/memory/v2/db/sqlite.py +0 -209
  503. agno/memory/v2/manager.py +0 -437
  504. agno/memory/v2/memory.py +0 -1097
  505. agno/memory/v2/schema.py +0 -55
  506. agno/memory/v2/summarizer.py +0 -215
  507. agno/memory/workflow.py +0 -38
  508. agno/models/ollama/tools.py +0 -430
  509. agno/models/qwen/__init__.py +0 -5
  510. agno/playground/__init__.py +0 -10
  511. agno/playground/deploy.py +0 -3
  512. agno/playground/playground.py +0 -3
  513. agno/playground/serve.py +0 -3
  514. agno/playground/settings.py +0 -3
  515. agno/reranker/__init__.py +0 -0
  516. agno/run/v2/__init__.py +0 -0
  517. agno/run/v2/workflow.py +0 -567
  518. agno/storage/__init__.py +0 -0
  519. agno/storage/agent/__init__.py +0 -0
  520. agno/storage/agent/dynamodb.py +0 -1
  521. agno/storage/agent/json.py +0 -1
  522. agno/storage/agent/mongodb.py +0 -1
  523. agno/storage/agent/postgres.py +0 -1
  524. agno/storage/agent/singlestore.py +0 -1
  525. agno/storage/agent/sqlite.py +0 -1
  526. agno/storage/agent/yaml.py +0 -1
  527. agno/storage/base.py +0 -60
  528. agno/storage/dynamodb.py +0 -673
  529. agno/storage/firestore.py +0 -297
  530. agno/storage/gcs_json.py +0 -261
  531. agno/storage/in_memory.py +0 -234
  532. agno/storage/json.py +0 -237
  533. agno/storage/mongodb.py +0 -328
  534. agno/storage/mysql.py +0 -685
  535. agno/storage/postgres.py +0 -682
  536. agno/storage/redis.py +0 -336
  537. agno/storage/session/__init__.py +0 -16
  538. agno/storage/session/agent.py +0 -64
  539. agno/storage/session/team.py +0 -63
  540. agno/storage/session/v2/__init__.py +0 -5
  541. agno/storage/session/workflow.py +0 -61
  542. agno/storage/singlestore.py +0 -606
  543. agno/storage/sqlite.py +0 -646
  544. agno/storage/workflow/__init__.py +0 -0
  545. agno/storage/workflow/mongodb.py +0 -1
  546. agno/storage/workflow/postgres.py +0 -1
  547. agno/storage/workflow/sqlite.py +0 -1
  548. agno/storage/yaml.py +0 -241
  549. agno/tools/thinking.py +0 -73
  550. agno/utils/defaults.py +0 -57
  551. agno/utils/filesystem.py +0 -39
  552. agno/utils/git.py +0 -52
  553. agno/utils/json_io.py +0 -30
  554. agno/utils/load_env.py +0 -19
  555. agno/utils/py_io.py +0 -19
  556. agno/utils/pyproject.py +0 -18
  557. agno/utils/resource_filter.py +0 -31
  558. agno/workflow/v2/__init__.py +0 -21
  559. agno/workflow/v2/types.py +0 -357
  560. agno/workflow/v2/workflow.py +0 -3312
  561. agno/workspace/__init__.py +0 -0
  562. agno/workspace/config.py +0 -325
  563. agno/workspace/enums.py +0 -6
  564. agno/workspace/helpers.py +0 -52
  565. agno/workspace/operator.py +0 -757
  566. agno/workspace/settings.py +0 -158
  567. agno-1.8.0.dist-info/METADATA +0 -979
  568. agno-1.8.0.dist-info/RECORD +0 -565
  569. agno-1.8.0.dist-info/entry_points.txt +0 -3
  570. /agno/{app → db/migrations}/__init__.py +0 -0
  571. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  572. /agno/{cli → integrations}/__init__.py +0 -0
  573. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  574. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  575. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  576. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  577. /agno/{app → os/interfaces}/slack/security.py +0 -0
  578. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  579. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  580. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  581. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
  582. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
  583. {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/top_level.txt +0 -0
@@ -2,20 +2,21 @@ import asyncio
2
2
  from concurrent.futures import ThreadPoolExecutor, as_completed
3
3
  from dataclasses import dataclass
4
4
  from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
5
+ from uuid import uuid4
5
6
 
6
- from agno.run.response import RunResponseEvent
7
- from agno.run.team import TeamRunResponseEvent
8
- from agno.run.v2.workflow import (
7
+ from agno.models.metrics import Metrics
8
+ from agno.run.agent import RunOutputEvent
9
+ from agno.run.team import TeamRunOutputEvent
10
+ from agno.run.workflow import (
9
11
  ParallelExecutionCompletedEvent,
10
12
  ParallelExecutionStartedEvent,
11
- WorkflowRunResponse,
12
- WorkflowRunResponseEvent,
13
+ WorkflowRunOutput,
14
+ WorkflowRunOutputEvent,
13
15
  )
14
16
  from agno.utils.log import log_debug, logger
15
- from agno.workflow.v2.condition import Condition
16
- from agno.workflow.v2.step import Step
17
- from agno.workflow.v2.steps import Steps
18
- from agno.workflow.v2.types import StepInput, StepOutput
17
+ from agno.workflow.condition import Condition
18
+ from agno.workflow.step import Step
19
+ from agno.workflow.types import StepInput, StepOutput, StepType
19
20
 
20
21
  WorkflowSteps = List[
21
22
  Union[
@@ -55,10 +56,10 @@ class Parallel:
55
56
  """Prepare the steps for execution - mirrors workflow logic"""
56
57
  from agno.agent.agent import Agent
57
58
  from agno.team.team import Team
58
- from agno.workflow.v2.loop import Loop
59
- from agno.workflow.v2.router import Router
60
- from agno.workflow.v2.step import Step
61
- from agno.workflow.v2.steps import Steps
59
+ from agno.workflow.loop import Loop
60
+ from agno.workflow.router import Router
61
+ from agno.workflow.step import Step
62
+ from agno.workflow.steps import Steps
62
63
 
63
64
  prepared_steps: WorkflowSteps = []
64
65
  for step in self.steps:
@@ -78,23 +79,25 @@ class Parallel:
78
79
  def _aggregate_results(self, step_outputs: List[StepOutput]) -> StepOutput:
79
80
  """Aggregate multiple step outputs into a single StepOutput"""
80
81
  if not step_outputs:
81
- return StepOutput(step_name=self.name or "Parallel", content="No parallel steps executed")
82
-
83
- # To store the individual step outputs for each parallel step
84
- parallel_step_outputs = {output.step_name or f"step_{i}": output for i, output in enumerate(step_outputs)}
82
+ return StepOutput(
83
+ step_name=self.name or "Parallel",
84
+ step_id=str(uuid4()),
85
+ step_type="Parallel",
86
+ content="No parallel steps executed",
87
+ steps=[],
88
+ )
85
89
 
86
90
  if len(step_outputs) == 1:
87
- # Single result, update the step name but preserve parallel structure
91
+ # Single result, but still create a Parallel container
88
92
  single_result = step_outputs[0]
89
-
90
- # Extract metrics using the dedicated method
91
93
  aggregated_metrics = self._extract_metrics_from_response(step_outputs)
92
94
 
93
95
  return StepOutput(
94
96
  step_name=self.name or "Parallel",
95
- content=single_result.content,
96
- parallel_step_outputs=parallel_step_outputs,
97
- response=single_result.response,
97
+ step_id=str(uuid4()),
98
+ step_type=StepType.PARALLEL,
99
+ content=f"Parallel {self.name or 'execution'} completed with 1 result",
100
+ executor_name=self.name or "Parallel",
98
101
  images=single_result.images,
99
102
  videos=single_result.videos,
100
103
  audio=single_result.audio,
@@ -102,12 +105,13 @@ class Parallel:
102
105
  success=single_result.success,
103
106
  error=single_result.error,
104
107
  stop=single_result.stop,
108
+ steps=step_outputs, # This is the key addition
105
109
  )
106
110
 
107
111
  early_termination_requested = any(output.stop for output in step_outputs if hasattr(output, "stop"))
108
112
 
109
113
  # Multiple results - aggregate them
110
- aggregated_content = self._build_aggregated_content(step_outputs)
114
+ aggregated_content = f"Parallel {self.name or 'execution'} completed with {len(step_outputs)} results"
111
115
 
112
116
  # Combine all media from parallel steps
113
117
  all_images = []
@@ -127,63 +131,42 @@ class Parallel:
127
131
 
128
132
  return StepOutput(
129
133
  step_name=self.name or "Parallel",
134
+ step_id=str(uuid4()),
135
+ step_type=StepType.PARALLEL,
136
+ executor_type="parallel",
137
+ executor_name=self.name or "Parallel",
130
138
  content=aggregated_content,
131
- parallel_step_outputs=parallel_step_outputs,
132
139
  images=all_images if all_images else None,
133
140
  videos=all_videos if all_videos else None,
134
141
  audio=all_audio if all_audio else None,
135
142
  success=not has_any_failure,
136
143
  stop=early_termination_requested,
137
144
  metrics=aggregated_metrics,
145
+ steps=step_outputs,
138
146
  )
139
147
 
140
- def _extract_metrics_from_response(self, step_outputs: List[StepOutput]) -> Optional[Dict[str, Any]]:
148
+ def _extract_metrics_from_response(self, step_outputs: List[StepOutput]) -> Optional[Metrics]:
141
149
  """Extract and aggregate metrics from parallel step outputs"""
142
150
  if not step_outputs:
143
151
  return None
144
152
 
145
- parallel_step_metrics = {}
153
+ # Aggregate metrics from all parallel step outputs
154
+ total_metrics = Metrics()
146
155
 
147
156
  for result in step_outputs:
148
- step_name = result.step_name or "unknown"
149
-
150
- # Create clean step metrics for parallel steps
151
157
  if result.metrics:
152
- # If the step already has structured metrics, extract the actual metrics
153
- if isinstance(result.metrics, dict) and "metrics" in result.metrics:
154
- actual_metrics = result.metrics.get("metrics")
155
- executor_type = result.metrics.get("executor_type", "unknown")
156
- executor_name = result.metrics.get("executor_name", "unknown")
157
- else:
158
- actual_metrics = result.metrics
159
- executor_type = getattr(result, "executor_type", "unknown")
160
- executor_name = getattr(result, "executor_name", "unknown")
161
-
162
- parallel_step_metrics[step_name] = {
163
- "step_name": step_name,
164
- "executor_type": executor_type,
165
- "executor_name": executor_name,
166
- "metrics": actual_metrics,
167
- }
168
- else:
169
- # Even if no metrics, record the step execution
170
- parallel_step_metrics[step_name] = {
171
- "step_name": step_name,
172
- "executor_type": getattr(result, "executor_type", "unknown"),
173
- "executor_name": getattr(result, "executor_name", "unknown"),
174
- "metrics": None,
175
- }
176
-
177
- # Create aggregated metrics structure for parallel execution
178
- if parallel_step_metrics:
179
- return {
180
- "step_name": self.name or "Parallel",
181
- "executor_type": "parallel",
182
- "executor_name": self.name or "Parallel",
183
- "parallel_steps": parallel_step_metrics,
184
- }
158
+ total_metrics = total_metrics + result.metrics
159
+
160
+ # If no metrics were found, return None
161
+ if (
162
+ total_metrics.input_tokens == 0
163
+ and total_metrics.output_tokens == 0
164
+ and total_metrics.total_tokens == 0
165
+ and total_metrics.duration is None
166
+ ):
167
+ return None
185
168
 
186
- return None
169
+ return total_metrics
187
170
 
188
171
  def _build_aggregated_content(self, step_outputs: List[StepOutput]) -> str:
189
172
  """Build aggregated content from multiple step outputs"""
@@ -212,6 +195,9 @@ class Parallel:
212
195
  step_input: StepInput,
213
196
  session_id: Optional[str] = None,
214
197
  user_id: Optional[str] = None,
198
+ workflow_run_response: Optional[WorkflowRunOutput] = None,
199
+ store_executor_outputs: bool = True,
200
+ session_state: Optional[Dict[str, Any]] = None,
215
201
  ) -> StepOutput:
216
202
  """Execute all steps in parallel and return aggregated result"""
217
203
  # Use workflow logger for parallel orchestration
@@ -221,17 +207,27 @@ class Parallel:
221
207
 
222
208
  def execute_step_with_index(step_with_index):
223
209
  """Execute a single step and preserve its original index"""
224
- index, step = step_with_index
210
+ idx, step = step_with_index
225
211
  try:
226
- result = step.execute(step_input, session_id=session_id, user_id=user_id) # type: ignore[union-attr]
227
- return (index, result)
228
- except Exception as e:
229
- step_name = getattr(step, "name", f"step_{index}")
230
- logger.error(f"Parallel step {step_name} failed: {e}")
212
+ step_result = step.execute(
213
+ step_input,
214
+ session_id=session_id,
215
+ user_id=user_id,
216
+ workflow_run_response=workflow_run_response,
217
+ store_executor_outputs=store_executor_outputs,
218
+ session_state=session_state,
219
+ ) # type: ignore[union-attr]
220
+ return idx, step_result
221
+ except Exception as exc:
222
+ parallel_step_name = getattr(step, "name", f"step_{idx}")
223
+ logger.error(f"Parallel step {parallel_step_name} failed: {exc}")
231
224
  return (
232
- index,
225
+ idx,
233
226
  StepOutput(
234
- step_name=step_name, content=f"Step {step_name} failed: {str(e)}", success=False, error=str(e)
227
+ step_name=parallel_step_name,
228
+ content=f"Step {parallel_step_name} failed: {str(exc)}",
229
+ success=False,
230
+ error=str(exc),
235
231
  ),
236
232
  )
237
233
 
@@ -295,12 +291,17 @@ class Parallel:
295
291
  session_id: Optional[str] = None,
296
292
  user_id: Optional[str] = None,
297
293
  stream_intermediate_steps: bool = False,
298
- workflow_run_response: Optional[WorkflowRunResponse] = None,
294
+ workflow_run_response: Optional[WorkflowRunOutput] = None,
299
295
  step_index: Optional[Union[int, tuple]] = None,
300
- ) -> Iterator[Union[WorkflowRunResponseEvent, StepOutput]]:
296
+ store_executor_outputs: bool = True,
297
+ session_state: Optional[Dict[str, Any]] = None,
298
+ parent_step_id: Optional[str] = None,
299
+ ) -> Iterator[Union[WorkflowRunOutputEvent, StepOutput]]:
301
300
  """Execute all steps in parallel with streaming support"""
302
301
  log_debug(f"Parallel Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="=")
303
302
 
303
+ parallel_step_id = str(uuid4())
304
+
304
305
  self._prepare_steps()
305
306
 
306
307
  if stream_intermediate_steps and workflow_run_response:
@@ -313,19 +314,21 @@ class Parallel:
313
314
  step_name=self.name,
314
315
  step_index=step_index,
315
316
  parallel_step_count=len(self.steps),
317
+ step_id=parallel_step_id,
318
+ parent_step_id=parent_step_id,
316
319
  )
317
320
 
318
321
  def execute_step_stream_with_index(step_with_index):
319
322
  """Execute a single step with streaming and preserve its original index"""
320
- index, step = step_with_index
323
+ idx, step = step_with_index
321
324
  try:
322
- events = []
325
+ step_events = []
323
326
 
324
327
  # If step_index is None or integer (main step): create (step_index, sub_index)
325
328
  # If step_index is tuple (child step): all parallel sub-steps get same index
326
329
  if step_index is None or isinstance(step_index, int):
327
330
  # Parallel is a main step - sub-steps get sequential numbers: 1.1, 1.2, 1.3
328
- sub_step_index = (step_index if step_index is not None else 0, index)
331
+ sub_step_index = (step_index if step_index is not None else 0, idx)
329
332
  else:
330
333
  # Parallel is a child step - all sub-steps get the same parent number: 1.1, 1.1, 1.1
331
334
  sub_step_index = step_index
@@ -338,20 +341,23 @@ class Parallel:
338
341
  stream_intermediate_steps=stream_intermediate_steps,
339
342
  workflow_run_response=workflow_run_response,
340
343
  step_index=sub_step_index,
344
+ store_executor_outputs=store_executor_outputs,
345
+ session_state=session_state,
346
+ parent_step_id=parallel_step_id,
341
347
  ):
342
- events.append(event)
343
- return (index, events)
344
- except Exception as e:
345
- step_name = getattr(step, "name", f"step_{index}")
346
- logger.error(f"Parallel step {step_name} streaming failed: {e}")
348
+ step_events.append(event)
349
+ return idx, step_events
350
+ except Exception as exc:
351
+ parallel_step_name = getattr(step, "name", f"step_{idx}")
352
+ logger.error(f"Parallel step {parallel_step_name} streaming failed: {exc}")
347
353
  return (
348
- index,
354
+ idx,
349
355
  [
350
356
  StepOutput(
351
- step_name=step_name,
352
- content=f"Step {step_name} failed: {str(e)}",
357
+ step_name=parallel_step_name,
358
+ content=f"Step {parallel_step_name} failed: {str(exc)}",
353
359
  success=False,
354
- error=str(e),
360
+ error=str(exc),
355
361
  )
356
362
  ],
357
363
  )
@@ -431,6 +437,8 @@ class Parallel:
431
437
  step_index=step_index,
432
438
  parallel_step_count=len(self.steps),
433
439
  step_results=[aggregated_result], # Now single aggregated result
440
+ step_id=parallel_step_id,
441
+ parent_step_id=parent_step_id,
434
442
  )
435
443
 
436
444
  async def aexecute(
@@ -438,6 +446,9 @@ class Parallel:
438
446
  step_input: StepInput,
439
447
  session_id: Optional[str] = None,
440
448
  user_id: Optional[str] = None,
449
+ workflow_run_response: Optional[WorkflowRunOutput] = None,
450
+ store_executor_outputs: bool = True,
451
+ session_state: Optional[Dict[str, Any]] = None,
441
452
  ) -> StepOutput:
442
453
  """Execute all steps in parallel using asyncio and return aggregated result"""
443
454
  # Use workflow logger for async parallel orchestration
@@ -447,20 +458,27 @@ class Parallel:
447
458
 
448
459
  async def execute_step_async_with_index(step_with_index):
449
460
  """Execute a single step asynchronously and preserve its original index"""
450
- index, step = step_with_index
461
+ idx, step = step_with_index
451
462
  try:
452
- result = await step.aexecute(step_input, session_id=session_id, user_id=user_id) # type: ignore[union-attr]
453
- return (index, result)
454
- except Exception as e:
455
- step_name = getattr(step, "name", f"step_{index}")
456
- logger.error(f"Parallel step {step_name} failed: {e}")
463
+ inner_step_result = await step.aexecute(
464
+ step_input,
465
+ session_id=session_id,
466
+ user_id=user_id,
467
+ workflow_run_response=workflow_run_response,
468
+ store_executor_outputs=store_executor_outputs,
469
+ session_state=session_state,
470
+ ) # type: ignore[union-attr]
471
+ return idx, inner_step_result
472
+ except Exception as exc:
473
+ parallel_step_name = getattr(step, "name", f"step_{idx}")
474
+ logger.error(f"Parallel step {parallel_step_name} failed: {exc}")
457
475
  return (
458
- index,
476
+ idx,
459
477
  StepOutput(
460
- step_name=step_name,
461
- content=f"Step {step_name} failed: {str(e)}",
478
+ step_name=parallel_step_name,
479
+ content=f"Step {parallel_step_name} failed: {str(exc)}",
462
480
  success=False,
463
- error=str(e),
481
+ error=str(exc),
464
482
  ),
465
483
  )
466
484
 
@@ -522,12 +540,17 @@ class Parallel:
522
540
  session_id: Optional[str] = None,
523
541
  user_id: Optional[str] = None,
524
542
  stream_intermediate_steps: bool = False,
525
- workflow_run_response: Optional[WorkflowRunResponse] = None,
543
+ workflow_run_response: Optional[WorkflowRunOutput] = None,
526
544
  step_index: Optional[Union[int, tuple]] = None,
527
- ) -> AsyncIterator[Union[WorkflowRunResponseEvent, TeamRunResponseEvent, RunResponseEvent, StepOutput]]:
545
+ store_executor_outputs: bool = True,
546
+ session_state: Optional[Dict[str, Any]] = None,
547
+ parent_step_id: Optional[str] = None,
548
+ ) -> AsyncIterator[Union[WorkflowRunOutputEvent, TeamRunOutputEvent, RunOutputEvent, StepOutput]]:
528
549
  """Execute all steps in parallel with async streaming support"""
529
550
  log_debug(f"Parallel Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="=")
530
551
 
552
+ parallel_step_id = str(uuid4())
553
+
531
554
  self._prepare_steps()
532
555
 
533
556
  if stream_intermediate_steps and workflow_run_response:
@@ -540,19 +563,21 @@ class Parallel:
540
563
  step_name=self.name,
541
564
  step_index=step_index,
542
565
  parallel_step_count=len(self.steps),
566
+ step_id=parallel_step_id,
567
+ parent_step_id=parent_step_id,
543
568
  )
544
569
 
545
570
  async def execute_step_stream_async_with_index(step_with_index):
546
571
  """Execute a single step with async streaming and preserve its original index"""
547
- index, step = step_with_index
572
+ idx, step = step_with_index
548
573
  try:
549
- events = []
574
+ step_events = []
550
575
 
551
576
  # If step_index is None or integer (main step): create (step_index, sub_index)
552
577
  # If step_index is tuple (child step): all parallel sub-steps get same index
553
578
  if step_index is None or isinstance(step_index, int):
554
579
  # Parallel is a main step - sub-steps get sequential numbers: 1.1, 1.2, 1.3
555
- sub_step_index = (step_index if step_index is not None else 0, index)
580
+ sub_step_index = (step_index if step_index is not None else 0, idx)
556
581
  else:
557
582
  # Parallel is a child step - all sub-steps get the same parent number: 1.1, 1.1, 1.1
558
583
  sub_step_index = step_index
@@ -565,18 +590,21 @@ class Parallel:
565
590
  stream_intermediate_steps=stream_intermediate_steps,
566
591
  workflow_run_response=workflow_run_response,
567
592
  step_index=sub_step_index,
593
+ store_executor_outputs=store_executor_outputs,
594
+ session_state=session_state,
595
+ parent_step_id=parallel_step_id,
568
596
  ): # type: ignore[union-attr]
569
- events.append(event)
570
- return (index, events)
597
+ step_events.append(event)
598
+ return idx, step_events
571
599
  except Exception as e:
572
- step_name = getattr(step, "name", f"step_{index}")
573
- logger.error(f"Parallel step {step_name} async streaming failed: {e}")
600
+ parallel_step_name = getattr(step, "name", f"step_{idx}")
601
+ logger.error(f"Parallel step {parallel_step_name} async streaming failed: {e}")
574
602
  return (
575
- index,
603
+ idx,
576
604
  [
577
605
  StepOutput(
578
- step_name=step_name,
579
- content=f"Step {step_name} failed: {str(e)}",
606
+ step_name=parallel_step_name,
607
+ content=f"Step {parallel_step_name} failed: {str(e)}",
580
608
  success=False,
581
609
  error=str(e),
582
610
  )
@@ -656,4 +684,6 @@ class Parallel:
656
684
  step_index=step_index,
657
685
  parallel_step_count=len(self.steps),
658
686
  step_results=[aggregated_result], # Now single aggregated result
687
+ step_id=parallel_step_id,
688
+ parent_step_id=parent_step_id,
659
689
  )