agno 1.8.2__py3-none-any.whl → 2.0.0__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 (589) hide show
  1. agno/agent/__init__.py +19 -27
  2. agno/agent/agent.py +3143 -4170
  3. agno/api/agent.py +11 -67
  4. agno/api/api.py +5 -46
  5. agno/api/evals.py +8 -19
  6. agno/api/os.py +17 -0
  7. agno/api/routes.py +6 -41
  8. agno/api/schemas/__init__.py +9 -0
  9. agno/api/schemas/agent.py +5 -21
  10. agno/api/schemas/evals.py +7 -16
  11. agno/api/schemas/os.py +14 -0
  12. agno/api/schemas/team.py +5 -21
  13. agno/api/schemas/utils.py +21 -0
  14. agno/api/schemas/workflows.py +11 -7
  15. agno/api/settings.py +53 -0
  16. agno/api/team.py +11 -66
  17. agno/api/workflow.py +28 -0
  18. agno/cloud/aws/base.py +214 -0
  19. agno/cloud/aws/s3/__init__.py +2 -0
  20. agno/cloud/aws/s3/api_client.py +43 -0
  21. agno/cloud/aws/s3/bucket.py +195 -0
  22. agno/cloud/aws/s3/object.py +57 -0
  23. agno/db/__init__.py +24 -0
  24. agno/db/base.py +245 -0
  25. agno/db/dynamo/__init__.py +3 -0
  26. agno/db/dynamo/dynamo.py +1743 -0
  27. agno/db/dynamo/schemas.py +278 -0
  28. agno/db/dynamo/utils.py +684 -0
  29. agno/db/firestore/__init__.py +3 -0
  30. agno/db/firestore/firestore.py +1432 -0
  31. agno/db/firestore/schemas.py +130 -0
  32. agno/db/firestore/utils.py +278 -0
  33. agno/db/gcs_json/__init__.py +3 -0
  34. agno/db/gcs_json/gcs_json_db.py +1001 -0
  35. agno/db/gcs_json/utils.py +194 -0
  36. agno/db/in_memory/__init__.py +3 -0
  37. agno/db/in_memory/in_memory_db.py +882 -0
  38. agno/db/in_memory/utils.py +172 -0
  39. agno/db/json/__init__.py +3 -0
  40. agno/db/json/json_db.py +1045 -0
  41. agno/db/json/utils.py +196 -0
  42. agno/db/migrations/v1_to_v2.py +162 -0
  43. agno/db/mongo/__init__.py +3 -0
  44. agno/db/mongo/mongo.py +1416 -0
  45. agno/db/mongo/schemas.py +77 -0
  46. agno/db/mongo/utils.py +204 -0
  47. agno/db/mysql/__init__.py +3 -0
  48. agno/db/mysql/mysql.py +1719 -0
  49. agno/db/mysql/schemas.py +124 -0
  50. agno/db/mysql/utils.py +297 -0
  51. agno/db/postgres/__init__.py +3 -0
  52. agno/db/postgres/postgres.py +1710 -0
  53. agno/db/postgres/schemas.py +124 -0
  54. agno/db/postgres/utils.py +280 -0
  55. agno/db/redis/__init__.py +3 -0
  56. agno/db/redis/redis.py +1367 -0
  57. agno/db/redis/schemas.py +109 -0
  58. agno/db/redis/utils.py +288 -0
  59. agno/db/schemas/__init__.py +3 -0
  60. agno/db/schemas/evals.py +33 -0
  61. agno/db/schemas/knowledge.py +40 -0
  62. agno/db/schemas/memory.py +46 -0
  63. agno/db/singlestore/__init__.py +3 -0
  64. agno/db/singlestore/schemas.py +116 -0
  65. agno/db/singlestore/singlestore.py +1712 -0
  66. agno/db/singlestore/utils.py +326 -0
  67. agno/db/sqlite/__init__.py +3 -0
  68. agno/db/sqlite/schemas.py +119 -0
  69. agno/db/sqlite/sqlite.py +1676 -0
  70. agno/db/sqlite/utils.py +268 -0
  71. agno/db/utils.py +88 -0
  72. agno/eval/__init__.py +14 -0
  73. agno/eval/accuracy.py +154 -48
  74. agno/eval/performance.py +88 -23
  75. agno/eval/reliability.py +73 -20
  76. agno/eval/utils.py +23 -13
  77. agno/integrations/discord/__init__.py +3 -0
  78. agno/{app → integrations}/discord/client.py +10 -10
  79. agno/knowledge/__init__.py +2 -2
  80. agno/{document → knowledge}/chunking/agentic.py +2 -2
  81. agno/{document → knowledge}/chunking/document.py +2 -2
  82. agno/{document → knowledge}/chunking/fixed.py +3 -3
  83. agno/{document → knowledge}/chunking/markdown.py +2 -2
  84. agno/{document → knowledge}/chunking/recursive.py +2 -2
  85. agno/{document → knowledge}/chunking/row.py +2 -2
  86. agno/knowledge/chunking/semantic.py +59 -0
  87. agno/knowledge/chunking/strategy.py +121 -0
  88. agno/knowledge/content.py +74 -0
  89. agno/knowledge/document/__init__.py +5 -0
  90. agno/{document → knowledge/document}/base.py +12 -2
  91. agno/knowledge/embedder/__init__.py +5 -0
  92. agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
  93. agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
  94. agno/{embedder → knowledge/embedder}/base.py +6 -0
  95. agno/{embedder → knowledge/embedder}/cohere.py +72 -1
  96. agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
  97. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  98. agno/{embedder → knowledge/embedder}/google.py +74 -1
  99. agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
  100. agno/{embedder → knowledge/embedder}/jina.py +48 -2
  101. agno/knowledge/embedder/langdb.py +22 -0
  102. agno/knowledge/embedder/mistral.py +139 -0
  103. agno/{embedder → knowledge/embedder}/nebius.py +1 -1
  104. agno/{embedder → knowledge/embedder}/ollama.py +54 -3
  105. agno/knowledge/embedder/openai.py +223 -0
  106. agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
  107. agno/{embedder → knowledge/embedder}/together.py +1 -1
  108. agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
  109. agno/knowledge/knowledge.py +1551 -0
  110. agno/knowledge/reader/__init__.py +7 -0
  111. agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
  112. agno/knowledge/reader/base.py +88 -0
  113. agno/{document → knowledge}/reader/csv_reader.py +47 -65
  114. agno/knowledge/reader/docx_reader.py +83 -0
  115. agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
  116. agno/{document → knowledge}/reader/json_reader.py +30 -9
  117. agno/{document → knowledge}/reader/markdown_reader.py +58 -9
  118. agno/{document → knowledge}/reader/pdf_reader.py +71 -126
  119. agno/knowledge/reader/reader_factory.py +268 -0
  120. agno/knowledge/reader/s3_reader.py +101 -0
  121. agno/{document → knowledge}/reader/text_reader.py +31 -10
  122. agno/knowledge/reader/url_reader.py +128 -0
  123. agno/knowledge/reader/web_search_reader.py +366 -0
  124. agno/{document → knowledge}/reader/website_reader.py +37 -10
  125. agno/knowledge/reader/wikipedia_reader.py +59 -0
  126. agno/knowledge/reader/youtube_reader.py +78 -0
  127. agno/knowledge/remote_content/remote_content.py +88 -0
  128. agno/{reranker → knowledge/reranker}/base.py +1 -1
  129. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  130. agno/{reranker → knowledge/reranker}/infinity.py +2 -2
  131. agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
  132. agno/knowledge/types.py +30 -0
  133. agno/knowledge/utils.py +169 -0
  134. agno/media.py +269 -268
  135. agno/memory/__init__.py +2 -10
  136. agno/memory/manager.py +1003 -148
  137. agno/models/aimlapi/__init__.py +2 -2
  138. agno/models/aimlapi/aimlapi.py +6 -6
  139. agno/models/anthropic/claude.py +128 -72
  140. agno/models/aws/bedrock.py +107 -175
  141. agno/models/aws/claude.py +64 -18
  142. agno/models/azure/ai_foundry.py +73 -23
  143. agno/models/base.py +346 -290
  144. agno/models/cerebras/cerebras.py +84 -27
  145. agno/models/cohere/chat.py +106 -98
  146. agno/models/google/gemini.py +105 -46
  147. agno/models/groq/groq.py +97 -35
  148. agno/models/huggingface/huggingface.py +92 -27
  149. agno/models/ibm/watsonx.py +72 -13
  150. agno/models/litellm/chat.py +85 -13
  151. agno/models/message.py +46 -151
  152. agno/models/meta/llama.py +85 -49
  153. agno/models/metrics.py +120 -0
  154. agno/models/mistral/mistral.py +90 -21
  155. agno/models/ollama/__init__.py +0 -2
  156. agno/models/ollama/chat.py +85 -47
  157. agno/models/openai/chat.py +154 -37
  158. agno/models/openai/responses.py +178 -105
  159. agno/models/perplexity/perplexity.py +26 -2
  160. agno/models/portkey/portkey.py +0 -7
  161. agno/models/response.py +15 -9
  162. agno/models/utils.py +20 -0
  163. agno/models/vercel/__init__.py +2 -2
  164. agno/models/vercel/v0.py +1 -1
  165. agno/models/vllm/__init__.py +2 -2
  166. agno/models/vllm/vllm.py +3 -3
  167. agno/models/xai/xai.py +10 -10
  168. agno/os/__init__.py +3 -0
  169. agno/os/app.py +497 -0
  170. agno/os/auth.py +47 -0
  171. agno/os/config.py +103 -0
  172. agno/os/interfaces/agui/__init__.py +3 -0
  173. agno/os/interfaces/agui/agui.py +31 -0
  174. agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
  175. agno/{app → os/interfaces}/agui/utils.py +65 -28
  176. agno/os/interfaces/base.py +21 -0
  177. agno/os/interfaces/slack/__init__.py +3 -0
  178. agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
  179. agno/os/interfaces/slack/slack.py +32 -0
  180. agno/os/interfaces/whatsapp/__init__.py +3 -0
  181. agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
  182. agno/os/interfaces/whatsapp/whatsapp.py +29 -0
  183. agno/os/mcp.py +235 -0
  184. agno/os/router.py +1400 -0
  185. agno/os/routers/__init__.py +3 -0
  186. agno/os/routers/evals/__init__.py +3 -0
  187. agno/os/routers/evals/evals.py +393 -0
  188. agno/os/routers/evals/schemas.py +142 -0
  189. agno/os/routers/evals/utils.py +161 -0
  190. agno/os/routers/knowledge/__init__.py +3 -0
  191. agno/os/routers/knowledge/knowledge.py +850 -0
  192. agno/os/routers/knowledge/schemas.py +118 -0
  193. agno/os/routers/memory/__init__.py +3 -0
  194. agno/os/routers/memory/memory.py +410 -0
  195. agno/os/routers/memory/schemas.py +58 -0
  196. agno/os/routers/metrics/__init__.py +3 -0
  197. agno/os/routers/metrics/metrics.py +178 -0
  198. agno/os/routers/metrics/schemas.py +47 -0
  199. agno/os/routers/session/__init__.py +3 -0
  200. agno/os/routers/session/session.py +536 -0
  201. agno/os/schema.py +945 -0
  202. agno/{app/playground → os}/settings.py +7 -15
  203. agno/os/utils.py +270 -0
  204. agno/reasoning/azure_ai_foundry.py +4 -4
  205. agno/reasoning/deepseek.py +4 -4
  206. agno/reasoning/default.py +6 -11
  207. agno/reasoning/groq.py +4 -4
  208. agno/reasoning/helpers.py +4 -6
  209. agno/reasoning/ollama.py +4 -4
  210. agno/reasoning/openai.py +4 -4
  211. agno/run/agent.py +633 -0
  212. agno/run/base.py +53 -77
  213. agno/run/cancel.py +81 -0
  214. agno/run/team.py +243 -96
  215. agno/run/workflow.py +550 -12
  216. agno/session/__init__.py +10 -0
  217. agno/session/agent.py +244 -0
  218. agno/session/summary.py +225 -0
  219. agno/session/team.py +262 -0
  220. agno/{storage/session/v2 → session}/workflow.py +47 -24
  221. agno/team/__init__.py +15 -16
  222. agno/team/team.py +3260 -4824
  223. agno/tools/agentql.py +14 -5
  224. agno/tools/airflow.py +9 -4
  225. agno/tools/api.py +7 -3
  226. agno/tools/apify.py +2 -46
  227. agno/tools/arxiv.py +8 -3
  228. agno/tools/aws_lambda.py +7 -5
  229. agno/tools/aws_ses.py +7 -1
  230. agno/tools/baidusearch.py +4 -1
  231. agno/tools/bitbucket.py +4 -4
  232. agno/tools/brandfetch.py +14 -11
  233. agno/tools/bravesearch.py +4 -1
  234. agno/tools/brightdata.py +43 -23
  235. agno/tools/browserbase.py +13 -4
  236. agno/tools/calcom.py +12 -10
  237. agno/tools/calculator.py +10 -27
  238. agno/tools/cartesia.py +20 -17
  239. agno/tools/{clickup_tool.py → clickup.py} +12 -25
  240. agno/tools/confluence.py +8 -8
  241. agno/tools/crawl4ai.py +7 -1
  242. agno/tools/csv_toolkit.py +9 -8
  243. agno/tools/dalle.py +22 -12
  244. agno/tools/daytona.py +13 -16
  245. agno/tools/decorator.py +6 -3
  246. agno/tools/desi_vocal.py +17 -8
  247. agno/tools/discord.py +11 -8
  248. agno/tools/docker.py +30 -42
  249. agno/tools/duckdb.py +34 -53
  250. agno/tools/duckduckgo.py +8 -7
  251. agno/tools/e2b.py +62 -62
  252. agno/tools/eleven_labs.py +36 -29
  253. agno/tools/email.py +4 -1
  254. agno/tools/evm.py +7 -1
  255. agno/tools/exa.py +19 -14
  256. agno/tools/fal.py +30 -30
  257. agno/tools/file.py +9 -8
  258. agno/tools/financial_datasets.py +25 -44
  259. agno/tools/firecrawl.py +17 -18
  260. agno/tools/function.py +127 -18
  261. agno/tools/giphy.py +23 -11
  262. agno/tools/github.py +48 -126
  263. agno/tools/gmail.py +45 -61
  264. agno/tools/google_bigquery.py +7 -6
  265. agno/tools/google_maps.py +11 -26
  266. agno/tools/googlesearch.py +7 -2
  267. agno/tools/googlesheets.py +21 -17
  268. agno/tools/hackernews.py +9 -5
  269. agno/tools/jina.py +5 -4
  270. agno/tools/jira.py +18 -9
  271. agno/tools/knowledge.py +31 -32
  272. agno/tools/linear.py +18 -33
  273. agno/tools/linkup.py +5 -1
  274. agno/tools/local_file_system.py +8 -5
  275. agno/tools/lumalab.py +32 -20
  276. agno/tools/mcp.py +1 -2
  277. agno/tools/mem0.py +18 -12
  278. agno/tools/memori.py +14 -10
  279. agno/tools/mlx_transcribe.py +3 -2
  280. agno/tools/models/azure_openai.py +33 -15
  281. agno/tools/models/gemini.py +59 -32
  282. agno/tools/models/groq.py +30 -23
  283. agno/tools/models/nebius.py +28 -12
  284. agno/tools/models_labs.py +40 -16
  285. agno/tools/moviepy_video.py +7 -6
  286. agno/tools/neo4j.py +10 -8
  287. agno/tools/newspaper.py +7 -2
  288. agno/tools/newspaper4k.py +8 -3
  289. agno/tools/openai.py +58 -32
  290. agno/tools/openbb.py +12 -11
  291. agno/tools/opencv.py +63 -47
  292. agno/tools/openweather.py +14 -12
  293. agno/tools/pandas.py +11 -3
  294. agno/tools/postgres.py +4 -12
  295. agno/tools/pubmed.py +4 -1
  296. agno/tools/python.py +9 -22
  297. agno/tools/reasoning.py +35 -27
  298. agno/tools/reddit.py +11 -26
  299. agno/tools/replicate.py +55 -42
  300. agno/tools/resend.py +4 -1
  301. agno/tools/scrapegraph.py +15 -14
  302. agno/tools/searxng.py +10 -23
  303. agno/tools/serpapi.py +6 -3
  304. agno/tools/serper.py +13 -4
  305. agno/tools/shell.py +9 -2
  306. agno/tools/slack.py +12 -11
  307. agno/tools/sleep.py +3 -2
  308. agno/tools/spider.py +24 -4
  309. agno/tools/sql.py +7 -6
  310. agno/tools/tavily.py +6 -4
  311. agno/tools/telegram.py +12 -4
  312. agno/tools/todoist.py +11 -31
  313. agno/tools/toolkit.py +1 -1
  314. agno/tools/trafilatura.py +22 -6
  315. agno/tools/trello.py +9 -22
  316. agno/tools/twilio.py +10 -3
  317. agno/tools/user_control_flow.py +6 -1
  318. agno/tools/valyu.py +34 -5
  319. agno/tools/visualization.py +19 -28
  320. agno/tools/webbrowser.py +4 -3
  321. agno/tools/webex.py +11 -7
  322. agno/tools/website.py +15 -46
  323. agno/tools/webtools.py +12 -4
  324. agno/tools/whatsapp.py +5 -9
  325. agno/tools/wikipedia.py +20 -13
  326. agno/tools/x.py +14 -13
  327. agno/tools/yfinance.py +13 -40
  328. agno/tools/youtube.py +26 -20
  329. agno/tools/zendesk.py +7 -2
  330. agno/tools/zep.py +10 -7
  331. agno/tools/zoom.py +10 -9
  332. agno/utils/common.py +1 -19
  333. agno/utils/events.py +100 -123
  334. agno/utils/gemini.py +1 -1
  335. agno/utils/knowledge.py +29 -0
  336. agno/utils/log.py +54 -4
  337. agno/utils/mcp.py +68 -10
  338. agno/utils/media.py +39 -0
  339. agno/utils/message.py +12 -1
  340. agno/utils/models/aws_claude.py +1 -1
  341. agno/utils/models/claude.py +6 -12
  342. agno/utils/models/cohere.py +1 -1
  343. agno/utils/models/mistral.py +8 -7
  344. agno/utils/models/schema_utils.py +3 -3
  345. agno/utils/models/watsonx.py +1 -1
  346. agno/utils/openai.py +1 -1
  347. agno/utils/pprint.py +33 -32
  348. agno/utils/print_response/agent.py +779 -0
  349. agno/utils/print_response/team.py +1669 -0
  350. agno/utils/print_response/workflow.py +1451 -0
  351. agno/utils/prompts.py +14 -14
  352. agno/utils/reasoning.py +87 -0
  353. agno/utils/response.py +42 -42
  354. agno/utils/streamlit.py +481 -0
  355. agno/utils/string.py +8 -22
  356. agno/utils/team.py +50 -0
  357. agno/utils/timer.py +2 -2
  358. agno/vectordb/base.py +33 -21
  359. agno/vectordb/cassandra/cassandra.py +287 -23
  360. agno/vectordb/chroma/chromadb.py +482 -59
  361. agno/vectordb/clickhouse/clickhousedb.py +270 -63
  362. agno/vectordb/couchbase/couchbase.py +309 -29
  363. agno/vectordb/lancedb/lance_db.py +360 -21
  364. agno/vectordb/langchaindb/__init__.py +5 -0
  365. agno/vectordb/langchaindb/langchaindb.py +145 -0
  366. agno/vectordb/lightrag/__init__.py +5 -0
  367. agno/vectordb/lightrag/lightrag.py +374 -0
  368. agno/vectordb/llamaindex/llamaindexdb.py +127 -0
  369. agno/vectordb/milvus/milvus.py +242 -32
  370. agno/vectordb/mongodb/mongodb.py +200 -24
  371. agno/vectordb/pgvector/pgvector.py +319 -37
  372. agno/vectordb/pineconedb/pineconedb.py +221 -27
  373. agno/vectordb/qdrant/qdrant.py +334 -14
  374. agno/vectordb/singlestore/singlestore.py +286 -29
  375. agno/vectordb/surrealdb/surrealdb.py +187 -7
  376. agno/vectordb/upstashdb/upstashdb.py +342 -26
  377. agno/vectordb/weaviate/weaviate.py +227 -165
  378. agno/workflow/__init__.py +17 -13
  379. agno/workflow/{v2/condition.py → condition.py} +135 -32
  380. agno/workflow/{v2/loop.py → loop.py} +115 -28
  381. agno/workflow/{v2/parallel.py → parallel.py} +138 -108
  382. agno/workflow/{v2/router.py → router.py} +133 -32
  383. agno/workflow/{v2/step.py → step.py} +207 -49
  384. agno/workflow/{v2/steps.py → steps.py} +147 -66
  385. agno/workflow/types.py +482 -0
  386. agno/workflow/workflow.py +2410 -696
  387. agno-2.0.0.dist-info/METADATA +494 -0
  388. agno-2.0.0.dist-info/RECORD +515 -0
  389. agno-2.0.0.dist-info/licenses/LICENSE +201 -0
  390. agno/agent/metrics.py +0 -110
  391. agno/api/app.py +0 -35
  392. agno/api/playground.py +0 -92
  393. agno/api/schemas/app.py +0 -12
  394. agno/api/schemas/playground.py +0 -22
  395. agno/api/schemas/user.py +0 -35
  396. agno/api/schemas/workspace.py +0 -46
  397. agno/api/user.py +0 -160
  398. agno/api/workflows.py +0 -33
  399. agno/api/workspace.py +0 -175
  400. agno/app/agui/__init__.py +0 -3
  401. agno/app/agui/app.py +0 -17
  402. agno/app/agui/sync_router.py +0 -120
  403. agno/app/base.py +0 -186
  404. agno/app/discord/__init__.py +0 -3
  405. agno/app/fastapi/__init__.py +0 -3
  406. agno/app/fastapi/app.py +0 -107
  407. agno/app/fastapi/async_router.py +0 -457
  408. agno/app/fastapi/sync_router.py +0 -448
  409. agno/app/playground/app.py +0 -228
  410. agno/app/playground/async_router.py +0 -1053
  411. agno/app/playground/deploy.py +0 -249
  412. agno/app/playground/operator.py +0 -183
  413. agno/app/playground/schemas.py +0 -223
  414. agno/app/playground/serve.py +0 -55
  415. agno/app/playground/sync_router.py +0 -1045
  416. agno/app/playground/utils.py +0 -46
  417. agno/app/settings.py +0 -15
  418. agno/app/slack/__init__.py +0 -3
  419. agno/app/slack/app.py +0 -19
  420. agno/app/slack/sync_router.py +0 -92
  421. agno/app/utils.py +0 -54
  422. agno/app/whatsapp/__init__.py +0 -3
  423. agno/app/whatsapp/app.py +0 -15
  424. agno/app/whatsapp/sync_router.py +0 -197
  425. agno/cli/auth_server.py +0 -249
  426. agno/cli/config.py +0 -274
  427. agno/cli/console.py +0 -88
  428. agno/cli/credentials.py +0 -23
  429. agno/cli/entrypoint.py +0 -571
  430. agno/cli/operator.py +0 -357
  431. agno/cli/settings.py +0 -96
  432. agno/cli/ws/ws_cli.py +0 -817
  433. agno/constants.py +0 -13
  434. agno/document/__init__.py +0 -5
  435. agno/document/chunking/semantic.py +0 -45
  436. agno/document/chunking/strategy.py +0 -31
  437. agno/document/reader/__init__.py +0 -5
  438. agno/document/reader/base.py +0 -47
  439. agno/document/reader/docx_reader.py +0 -60
  440. agno/document/reader/gcs/pdf_reader.py +0 -44
  441. agno/document/reader/s3/pdf_reader.py +0 -59
  442. agno/document/reader/s3/text_reader.py +0 -63
  443. agno/document/reader/url_reader.py +0 -59
  444. agno/document/reader/youtube_reader.py +0 -58
  445. agno/embedder/__init__.py +0 -5
  446. agno/embedder/langdb.py +0 -80
  447. agno/embedder/mistral.py +0 -82
  448. agno/embedder/openai.py +0 -78
  449. agno/file/__init__.py +0 -5
  450. agno/file/file.py +0 -16
  451. agno/file/local/csv.py +0 -32
  452. agno/file/local/txt.py +0 -19
  453. agno/infra/app.py +0 -240
  454. agno/infra/base.py +0 -144
  455. agno/infra/context.py +0 -20
  456. agno/infra/db_app.py +0 -52
  457. agno/infra/resource.py +0 -205
  458. agno/infra/resources.py +0 -55
  459. agno/knowledge/agent.py +0 -702
  460. agno/knowledge/arxiv.py +0 -33
  461. agno/knowledge/combined.py +0 -36
  462. agno/knowledge/csv.py +0 -144
  463. agno/knowledge/csv_url.py +0 -124
  464. agno/knowledge/document.py +0 -223
  465. agno/knowledge/docx.py +0 -137
  466. agno/knowledge/firecrawl.py +0 -34
  467. agno/knowledge/gcs/__init__.py +0 -0
  468. agno/knowledge/gcs/base.py +0 -39
  469. agno/knowledge/gcs/pdf.py +0 -125
  470. agno/knowledge/json.py +0 -137
  471. agno/knowledge/langchain.py +0 -71
  472. agno/knowledge/light_rag.py +0 -273
  473. agno/knowledge/llamaindex.py +0 -66
  474. agno/knowledge/markdown.py +0 -154
  475. agno/knowledge/pdf.py +0 -164
  476. agno/knowledge/pdf_bytes.py +0 -42
  477. agno/knowledge/pdf_url.py +0 -148
  478. agno/knowledge/s3/__init__.py +0 -0
  479. agno/knowledge/s3/base.py +0 -64
  480. agno/knowledge/s3/pdf.py +0 -33
  481. agno/knowledge/s3/text.py +0 -34
  482. agno/knowledge/text.py +0 -141
  483. agno/knowledge/url.py +0 -46
  484. agno/knowledge/website.py +0 -179
  485. agno/knowledge/wikipedia.py +0 -32
  486. agno/knowledge/youtube.py +0 -35
  487. agno/memory/agent.py +0 -423
  488. agno/memory/classifier.py +0 -104
  489. agno/memory/db/__init__.py +0 -5
  490. agno/memory/db/base.py +0 -42
  491. agno/memory/db/mongodb.py +0 -189
  492. agno/memory/db/postgres.py +0 -203
  493. agno/memory/db/sqlite.py +0 -193
  494. agno/memory/memory.py +0 -22
  495. agno/memory/row.py +0 -36
  496. agno/memory/summarizer.py +0 -201
  497. agno/memory/summary.py +0 -19
  498. agno/memory/team.py +0 -415
  499. agno/memory/v2/__init__.py +0 -2
  500. agno/memory/v2/db/__init__.py +0 -1
  501. agno/memory/v2/db/base.py +0 -42
  502. agno/memory/v2/db/firestore.py +0 -339
  503. agno/memory/v2/db/mongodb.py +0 -196
  504. agno/memory/v2/db/postgres.py +0 -214
  505. agno/memory/v2/db/redis.py +0 -187
  506. agno/memory/v2/db/schema.py +0 -54
  507. agno/memory/v2/db/sqlite.py +0 -209
  508. agno/memory/v2/manager.py +0 -437
  509. agno/memory/v2/memory.py +0 -1097
  510. agno/memory/v2/schema.py +0 -55
  511. agno/memory/v2/summarizer.py +0 -215
  512. agno/memory/workflow.py +0 -38
  513. agno/models/ollama/tools.py +0 -430
  514. agno/models/qwen/__init__.py +0 -5
  515. agno/playground/__init__.py +0 -10
  516. agno/playground/deploy.py +0 -3
  517. agno/playground/playground.py +0 -3
  518. agno/playground/serve.py +0 -3
  519. agno/playground/settings.py +0 -3
  520. agno/reranker/__init__.py +0 -0
  521. agno/run/response.py +0 -467
  522. agno/run/v2/__init__.py +0 -0
  523. agno/run/v2/workflow.py +0 -567
  524. agno/storage/__init__.py +0 -0
  525. agno/storage/agent/__init__.py +0 -0
  526. agno/storage/agent/dynamodb.py +0 -1
  527. agno/storage/agent/json.py +0 -1
  528. agno/storage/agent/mongodb.py +0 -1
  529. agno/storage/agent/postgres.py +0 -1
  530. agno/storage/agent/singlestore.py +0 -1
  531. agno/storage/agent/sqlite.py +0 -1
  532. agno/storage/agent/yaml.py +0 -1
  533. agno/storage/base.py +0 -60
  534. agno/storage/dynamodb.py +0 -673
  535. agno/storage/firestore.py +0 -297
  536. agno/storage/gcs_json.py +0 -261
  537. agno/storage/in_memory.py +0 -234
  538. agno/storage/json.py +0 -237
  539. agno/storage/mongodb.py +0 -328
  540. agno/storage/mysql.py +0 -685
  541. agno/storage/postgres.py +0 -682
  542. agno/storage/redis.py +0 -336
  543. agno/storage/session/__init__.py +0 -16
  544. agno/storage/session/agent.py +0 -64
  545. agno/storage/session/team.py +0 -63
  546. agno/storage/session/v2/__init__.py +0 -5
  547. agno/storage/session/workflow.py +0 -61
  548. agno/storage/singlestore.py +0 -606
  549. agno/storage/sqlite.py +0 -646
  550. agno/storage/workflow/__init__.py +0 -0
  551. agno/storage/workflow/mongodb.py +0 -1
  552. agno/storage/workflow/postgres.py +0 -1
  553. agno/storage/workflow/sqlite.py +0 -1
  554. agno/storage/yaml.py +0 -241
  555. agno/tools/thinking.py +0 -73
  556. agno/utils/defaults.py +0 -57
  557. agno/utils/filesystem.py +0 -39
  558. agno/utils/git.py +0 -52
  559. agno/utils/json_io.py +0 -30
  560. agno/utils/load_env.py +0 -19
  561. agno/utils/py_io.py +0 -19
  562. agno/utils/pyproject.py +0 -18
  563. agno/utils/resource_filter.py +0 -31
  564. agno/workflow/v2/__init__.py +0 -21
  565. agno/workflow/v2/types.py +0 -357
  566. agno/workflow/v2/workflow.py +0 -3313
  567. agno/workspace/__init__.py +0 -0
  568. agno/workspace/config.py +0 -325
  569. agno/workspace/enums.py +0 -6
  570. agno/workspace/helpers.py +0 -52
  571. agno/workspace/operator.py +0 -757
  572. agno/workspace/settings.py +0 -158
  573. agno-1.8.2.dist-info/METADATA +0 -982
  574. agno-1.8.2.dist-info/RECORD +0 -566
  575. agno-1.8.2.dist-info/entry_points.txt +0 -3
  576. agno-1.8.2.dist-info/licenses/LICENSE +0 -375
  577. /agno/{app → db/migrations}/__init__.py +0 -0
  578. /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
  579. /agno/{cli → integrations}/__init__.py +0 -0
  580. /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
  581. /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
  582. /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
  583. /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
  584. /agno/{app → os/interfaces}/slack/security.py +0 -0
  585. /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
  586. /agno/{file/local → utils/print_response}/__init__.py +0 -0
  587. /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
  588. {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
  589. {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
@@ -1,22 +1,26 @@
1
1
  import inspect
2
+ from copy import copy
2
3
  from dataclasses import dataclass
3
4
  from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
5
+ from uuid import uuid4
4
6
 
5
7
  from pydantic import BaseModel
6
8
 
7
9
  from agno.agent import Agent
8
- from agno.media import Audio, AudioArtifact, Image, ImageArtifact, Video, VideoArtifact
9
- from agno.run.response import RunResponse
10
- from agno.run.team import TeamRunResponse
11
- from agno.run.v2.workflow import (
10
+ from agno.media import Audio, Image, Video
11
+ from agno.models.metrics import Metrics
12
+ from agno.run.agent import RunOutput
13
+ from agno.run.team import TeamRunOutput
14
+ from agno.run.workflow import (
12
15
  StepCompletedEvent,
13
16
  StepStartedEvent,
14
- WorkflowRunResponse,
15
- WorkflowRunResponseEvent,
17
+ WorkflowRunOutput,
18
+ WorkflowRunOutputEvent,
16
19
  )
17
20
  from agno.team import Team
18
21
  from agno.utils.log import log_debug, logger, use_agent_logger, use_team_logger, use_workflow_logger
19
- from agno.workflow.v2.types import StepInput, StepOutput
22
+ from agno.utils.merge_dict import merge_dictionaries
23
+ from agno.workflow.types import StepInput, StepOutput, StepType
20
24
 
21
25
  StepExecutor = Callable[
22
26
  [StepInput],
@@ -89,6 +93,10 @@ class Step:
89
93
  self.timeout_seconds = timeout_seconds
90
94
  self.skip_on_failure = skip_on_failure
91
95
  self.strict_input_validation = strict_input_validation
96
+ self.step_id = step_id
97
+
98
+ if step_id is None:
99
+ self.step_id = str(uuid4())
92
100
 
93
101
  # Set the active executor
94
102
  self._set_active_executor()
@@ -150,19 +158,20 @@ class Step:
150
158
  else:
151
159
  raise ValueError("No executor configured")
152
160
 
153
- def _extract_metrics_from_response(self, response: Union[RunResponse, TeamRunResponse]) -> Optional[Dict[str, Any]]:
161
+ def _extract_metrics_from_response(self, response: Union[RunOutput, TeamRunOutput]) -> Optional[Metrics]:
154
162
  """Extract metrics from agent or team response"""
155
163
  if hasattr(response, "metrics") and response.metrics:
156
- return {
157
- "step_name": self.name,
158
- "executor_type": self._executor_type,
159
- "executor_name": self.executor_name,
160
- "metrics": response.metrics,
161
- }
164
+ return response.metrics
162
165
  return None
163
166
 
164
167
  def execute(
165
- self, step_input: StepInput, session_id: Optional[str] = None, user_id: Optional[str] = None
168
+ self,
169
+ step_input: StepInput,
170
+ session_id: Optional[str] = None,
171
+ user_id: Optional[str] = None,
172
+ workflow_run_response: Optional["WorkflowRunOutput"] = None,
173
+ session_state: Optional[Dict[str, Any]] = None,
174
+ store_executor_outputs: bool = True,
166
175
  ) -> StepOutput:
167
176
  """Execute the step with StepInput, returning final StepOutput (non-streaming)"""
168
177
  log_debug(f"Executing step: {self.name}")
@@ -173,7 +182,7 @@ class Step:
173
182
  # Execute with retries
174
183
  for attempt in range(self.max_retries + 1):
175
184
  try:
176
- response: Union[RunResponse, TeamRunResponse, StepOutput]
185
+ response: Union[RunOutput, TeamRunOutput, StepOutput]
177
186
  if self._executor_type == "function":
178
187
  if inspect.iscoroutinefunction(self.active_executor) or inspect.isasyncgenfunction(
179
188
  self.active_executor
@@ -215,7 +224,7 @@ class Step:
215
224
  else:
216
225
  # For agents and teams, prepare message with context
217
226
  message = self._prepare_message(
218
- step_input.message,
227
+ step_input.input,
219
228
  step_input.previous_step_outputs,
220
229
  )
221
230
 
@@ -234,16 +243,30 @@ class Step:
234
243
  self._convert_video_artifacts_to_videos(step_input.videos) if step_input.videos else None
235
244
  )
236
245
  audios = self._convert_audio_artifacts_to_audio(step_input.audio) if step_input.audio else None
237
- response = self.active_executor.run( # type: ignore[misc]
238
- message=message,
246
+
247
+ kwargs: Dict[str, Any] = {}
248
+ if isinstance(self.active_executor, Team):
249
+ kwargs["store_member_responses"] = True
250
+
251
+ session_state_copy = copy(session_state)
252
+ response = self.active_executor.run( # type: ignore
253
+ input=message, # type: ignore
239
254
  images=images,
240
255
  videos=videos,
241
256
  audio=audios,
242
257
  files=step_input.files,
243
258
  session_id=session_id,
244
259
  user_id=user_id,
260
+ session_state=session_state_copy, # Send a copy to the executor
261
+ **kwargs,
245
262
  )
246
263
 
264
+ # Update workflow session state
265
+ merge_dictionaries(session_state, session_state_copy) # type: ignore
266
+
267
+ if store_executor_outputs and workflow_run_response is not None:
268
+ self._store_executor_response(workflow_run_response, response) # type: ignore
269
+
247
270
  # Switch back to workflow logger after execution
248
271
  use_workflow_logger()
249
272
  else:
@@ -274,9 +297,12 @@ class Step:
274
297
  session_id: Optional[str] = None,
275
298
  user_id: Optional[str] = None,
276
299
  stream_intermediate_steps: bool = False,
277
- workflow_run_response: Optional["WorkflowRunResponse"] = None,
300
+ workflow_run_response: Optional["WorkflowRunOutput"] = None,
301
+ session_state: Optional[Dict[str, Any]] = None,
278
302
  step_index: Optional[Union[int, tuple]] = None,
279
- ) -> Iterator[Union[WorkflowRunResponseEvent, StepOutput]]:
303
+ store_executor_outputs: bool = True,
304
+ parent_step_id: Optional[str] = None,
305
+ ) -> Iterator[Union[WorkflowRunOutputEvent, StepOutput]]:
280
306
  """Execute the step with event-driven streaming support"""
281
307
 
282
308
  if step_input.previous_step_outputs:
@@ -291,6 +317,8 @@ class Step:
291
317
  session_id=workflow_run_response.session_id or "",
292
318
  step_name=self.name,
293
319
  step_index=step_index,
320
+ step_id=self.step_id,
321
+ parent_step_id=parent_step_id,
294
322
  )
295
323
 
296
324
  # Execute with retries and streaming
@@ -341,7 +369,7 @@ class Step:
341
369
  else:
342
370
  # For agents and teams, prepare message with context
343
371
  message = self._prepare_message(
344
- step_input.message,
372
+ step_input.input,
345
373
  step_input.previous_step_outputs,
346
374
  )
347
375
 
@@ -359,21 +387,49 @@ class Step:
359
387
  self._convert_video_artifacts_to_videos(step_input.videos) if step_input.videos else None
360
388
  )
361
389
  audios = self._convert_audio_artifacts_to_audio(step_input.audio) if step_input.audio else None
390
+
391
+ kwargs: Dict[str, Any] = {}
392
+ if isinstance(self.active_executor, Team):
393
+ kwargs["store_member_responses"] = True
394
+
395
+ session_state_copy = copy(session_state)
362
396
  response_stream = self.active_executor.run( # type: ignore[call-overload, misc]
363
- message=message,
397
+ input=message,
364
398
  images=images,
365
399
  videos=videos,
366
400
  audio=audios,
367
401
  files=step_input.files,
368
402
  session_id=session_id,
369
403
  user_id=user_id,
404
+ session_state=session_state_copy, # Send a copy to the executor
370
405
  stream=True,
371
406
  stream_intermediate_steps=stream_intermediate_steps,
407
+ # Pass workflow context directly via kwargs
408
+ workflow_context={
409
+ "workflow_id": workflow_run_response.workflow_id if workflow_run_response else None,
410
+ "workflow_run_id": workflow_run_response.run_id if workflow_run_response else None,
411
+ "step_id": self.step_id,
412
+ "step_name": self.name,
413
+ "step_index": step_index,
414
+ },
415
+ yield_run_response=True,
416
+ **kwargs,
372
417
  )
373
418
 
419
+ active_executor_run_response = None
374
420
  for event in response_stream:
421
+ if isinstance(event, RunOutput) or isinstance(event, TeamRunOutput):
422
+ active_executor_run_response = event
423
+ break
375
424
  yield event # type: ignore[misc]
376
- final_response = self._process_step_output(self.active_executor.run_response) # type: ignore
425
+
426
+ # Update workflow session state
427
+ merge_dictionaries(session_state, session_state_copy) # type: ignore
428
+
429
+ if store_executor_outputs and workflow_run_response is not None:
430
+ self._store_executor_response(workflow_run_response, active_executor_run_response) # type: ignore
431
+
432
+ final_response = self._process_step_output(active_executor_run_response) # type: ignore
377
433
 
378
434
  else:
379
435
  raise ValueError(f"Unsupported executor type: {self._executor_type}")
@@ -400,6 +456,7 @@ class Step:
400
456
  step_index=step_index,
401
457
  content=final_response.content,
402
458
  step_response=final_response,
459
+ parent_step_id=parent_step_id,
403
460
  )
404
461
 
405
462
  return
@@ -422,7 +479,13 @@ class Step:
422
479
  return
423
480
 
424
481
  async def aexecute(
425
- self, step_input: StepInput, session_id: Optional[str] = None, user_id: Optional[str] = None
482
+ self,
483
+ step_input: StepInput,
484
+ session_id: Optional[str] = None,
485
+ user_id: Optional[str] = None,
486
+ workflow_run_response: Optional["WorkflowRunOutput"] = None,
487
+ session_state: Optional[Dict[str, Any]] = None,
488
+ store_executor_outputs: bool = True,
426
489
  ) -> StepOutput:
427
490
  """Execute the step with StepInput, returning final StepOutput (non-streaming)"""
428
491
  logger.info(f"Executing async step (non-streaming): {self.name}")
@@ -492,7 +555,7 @@ class Step:
492
555
  else:
493
556
  # For agents and teams, prepare message with context
494
557
  message = self._prepare_message(
495
- step_input.message,
558
+ step_input.input,
496
559
  step_input.previous_step_outputs,
497
560
  )
498
561
 
@@ -511,16 +574,30 @@ class Step:
511
574
  self._convert_video_artifacts_to_videos(step_input.videos) if step_input.videos else None
512
575
  )
513
576
  audios = self._convert_audio_artifacts_to_audio(step_input.audio) if step_input.audio else None
577
+
578
+ kwargs: Dict[str, Any] = {}
579
+ if isinstance(self.active_executor, Team):
580
+ kwargs["store_member_responses"] = True
581
+
582
+ session_state_copy = copy(session_state)
514
583
  response = await self.active_executor.arun( # type: ignore
515
- message=message,
584
+ input=message, # type: ignore
516
585
  images=images,
517
586
  videos=videos,
518
587
  audio=audios,
519
588
  files=step_input.files,
520
589
  session_id=session_id,
521
590
  user_id=user_id,
591
+ session_state=session_state_copy,
592
+ **kwargs,
522
593
  )
523
594
 
595
+ # Update workflow session state
596
+ merge_dictionaries(session_state, session_state_copy) # type: ignore
597
+
598
+ if store_executor_outputs and workflow_run_response is not None:
599
+ self._store_executor_response(workflow_run_response, response) # type: ignore
600
+
524
601
  # Switch back to workflow logger after execution
525
602
  use_workflow_logger()
526
603
  else:
@@ -551,9 +628,12 @@ class Step:
551
628
  session_id: Optional[str] = None,
552
629
  user_id: Optional[str] = None,
553
630
  stream_intermediate_steps: bool = False,
554
- workflow_run_response: Optional["WorkflowRunResponse"] = None,
631
+ workflow_run_response: Optional["WorkflowRunOutput"] = None,
632
+ session_state: Optional[Dict[str, Any]] = None,
555
633
  step_index: Optional[Union[int, tuple]] = None,
556
- ) -> AsyncIterator[Union[WorkflowRunResponseEvent, StepOutput]]:
634
+ store_executor_outputs: bool = True,
635
+ parent_step_id: Optional[str] = None,
636
+ ) -> AsyncIterator[Union[WorkflowRunOutputEvent, StepOutput]]:
557
637
  """Execute the step with event-driven streaming support"""
558
638
 
559
639
  if step_input.previous_step_outputs:
@@ -568,6 +648,8 @@ class Step:
568
648
  session_id=workflow_run_response.session_id or "",
569
649
  step_name=self.name,
570
650
  step_index=step_index,
651
+ step_id=self.step_id,
652
+ parent_step_id=parent_step_id,
571
653
  )
572
654
 
573
655
  # Execute with retries and streaming
@@ -636,7 +718,7 @@ class Step:
636
718
  else:
637
719
  # For agents and teams, prepare message with context
638
720
  message = self._prepare_message(
639
- step_input.message,
721
+ step_input.input,
640
722
  step_input.previous_step_outputs,
641
723
  )
642
724
 
@@ -654,22 +736,50 @@ class Step:
654
736
  self._convert_video_artifacts_to_videos(step_input.videos) if step_input.videos else None
655
737
  )
656
738
  audios = self._convert_audio_artifacts_to_audio(step_input.audio) if step_input.audio else None
657
- response_stream = await self.active_executor.arun( # type: ignore
658
- message=message,
739
+
740
+ kwargs: Dict[str, Any] = {}
741
+ if isinstance(self.active_executor, Team):
742
+ kwargs["store_member_responses"] = True
743
+
744
+ session_state_copy = copy(session_state)
745
+ response_stream = self.active_executor.arun( # type: ignore
746
+ input=message,
659
747
  images=images,
660
748
  videos=videos,
661
749
  audio=audios,
662
750
  files=step_input.files,
663
751
  session_id=session_id,
664
752
  user_id=user_id,
753
+ session_state=session_state_copy,
665
754
  stream=True,
666
755
  stream_intermediate_steps=stream_intermediate_steps,
756
+ # Pass workflow context directly via kwargs
757
+ workflow_context={
758
+ "workflow_id": workflow_run_response.workflow_id if workflow_run_response else None,
759
+ "workflow_run_id": workflow_run_response.run_id if workflow_run_response else None,
760
+ "step_id": self.step_id,
761
+ "step_name": self.name,
762
+ "step_index": step_index,
763
+ },
764
+ yield_run_response=True,
765
+ **kwargs,
667
766
  )
668
767
 
768
+ active_executor_run_response = None
669
769
  async for event in response_stream:
670
770
  log_debug(f"Received async event from agent: {type(event).__name__}")
771
+ if isinstance(event, RunOutput) or isinstance(event, TeamRunOutput):
772
+ active_executor_run_response = event
773
+ break
671
774
  yield event # type: ignore[misc]
672
- final_response = self._process_step_output(self.active_executor.run_response) # type: ignore
775
+
776
+ # Update workflow session state
777
+ merge_dictionaries(session_state, session_state_copy) # type: ignore
778
+
779
+ if store_executor_outputs and workflow_run_response is not None:
780
+ self._store_executor_response(workflow_run_response, active_executor_run_response) # type: ignore
781
+
782
+ final_response = self._process_step_output(active_executor_run_response) # type: ignore
673
783
  else:
674
784
  raise ValueError(f"Unsupported executor type: {self._executor_type}")
675
785
 
@@ -692,8 +802,10 @@ class Step:
692
802
  session_id=workflow_run_response.session_id or "",
693
803
  step_name=self.name,
694
804
  step_index=step_index,
805
+ step_id=self.step_id,
695
806
  content=final_response.content,
696
807
  step_response=final_response,
808
+ parent_step_id=parent_step_id,
697
809
  )
698
810
  return
699
811
 
@@ -714,6 +826,48 @@ class Step:
714
826
 
715
827
  return
716
828
 
829
+ def _store_executor_response(
830
+ self, workflow_run_response: "WorkflowRunOutput", executor_run_response: Union[RunOutput, TeamRunOutput]
831
+ ) -> None:
832
+ """Store agent/team responses in step_executor_runs if enabled"""
833
+ if self._executor_type in ["agent", "team"]:
834
+ # propogate the workflow run id as parent run id to the executor response
835
+ executor_run_response.parent_run_id = workflow_run_response.run_id
836
+ executor_run_response.workflow_step_id = self.step_id
837
+
838
+ # Get the raw response from the step's active executor
839
+ raw_response = executor_run_response
840
+ if raw_response and isinstance(raw_response, (RunOutput, TeamRunOutput)):
841
+ if workflow_run_response.step_executor_runs is None:
842
+ workflow_run_response.step_executor_runs = []
843
+
844
+ raw_response.workflow_step_id = self.step_id
845
+ # Add the primary executor run
846
+ workflow_run_response.step_executor_runs.append(raw_response)
847
+
848
+ # Add direct member agent runs (in case of a team we force store_member_responses=True here)
849
+ if isinstance(raw_response, TeamRunOutput) and getattr(
850
+ self.active_executor, "store_member_responses", False
851
+ ):
852
+ for mr in raw_response.member_responses or []:
853
+ if isinstance(mr, RunOutput):
854
+ workflow_run_response.step_executor_runs.append(mr)
855
+
856
+ def _get_deepest_content_from_step_output(self, step_output: "StepOutput") -> Optional[str]:
857
+ """
858
+ Extract the deepest content from a step output, handling nested structures like Steps, Router, Loop, etc.
859
+
860
+ For container steps (Steps, Router, Loop, etc.), this will recursively find the content from the
861
+ last actual step rather than using the generic container message.
862
+ """
863
+ # If this step has nested steps (like Steps, Condition, Router, Loop, etc.)
864
+ if hasattr(step_output, "steps") and step_output.steps and len(step_output.steps) > 0:
865
+ # Recursively get content from the last nested step
866
+ return self._get_deepest_content_from_step_output(step_output.steps[-1])
867
+
868
+ # For regular steps, return their content
869
+ return step_output.content # type: ignore
870
+
717
871
  def _prepare_message(
718
872
  self,
719
873
  message: Optional[Union[str, Dict[str, Any], List[Any], BaseModel]],
@@ -723,17 +877,20 @@ class Step:
723
877
 
724
878
  if previous_step_outputs and self._executor_type in ["agent", "team"]:
725
879
  last_output = list(previous_step_outputs.values())[-1] if previous_step_outputs else None
726
- if last_output and last_output.content:
727
- return last_output.content
880
+ if last_output:
881
+ deepest_content = self._get_deepest_content_from_step_output(last_output)
882
+ if deepest_content:
883
+ return deepest_content
728
884
 
729
885
  # If no previous step outputs, return the original message unchanged
730
886
  return message
731
887
 
732
- def _process_step_output(self, response: Union[RunResponse, TeamRunResponse, StepOutput]) -> StepOutput:
888
+ def _process_step_output(self, response: Union[RunOutput, TeamRunOutput, StepOutput]) -> StepOutput:
733
889
  """Create StepOutput from execution response"""
734
890
  if isinstance(response, StepOutput):
735
891
  response.step_name = self.name or "unnamed_step"
736
892
  response.step_id = self.step_id
893
+ response.step_type = StepType.STEP
737
894
  response.executor_type = self._executor_type
738
895
  response.executor_name = self.executor_name
739
896
  return response
@@ -749,44 +906,45 @@ class Step:
749
906
  return StepOutput(
750
907
  step_name=self.name or "unnamed_step",
751
908
  step_id=self.step_id,
909
+ step_type=StepType.STEP,
752
910
  executor_type=self._executor_type,
753
911
  executor_name=self.executor_name,
754
912
  content=response.content,
755
- response=response,
913
+ step_run_id=getattr(response, "run_id", None),
756
914
  images=images,
757
915
  videos=videos,
758
916
  audio=audio,
759
917
  metrics=metrics,
760
918
  )
761
919
 
762
- def _convert_function_result_to_response(self, result: Any) -> RunResponse:
763
- """Convert function execution result to RunResponse"""
764
- if isinstance(result, RunResponse):
920
+ def _convert_function_result_to_response(self, result: Any) -> RunOutput:
921
+ """Convert function execution result to RunOutput"""
922
+ if isinstance(result, RunOutput):
765
923
  return result
766
924
  elif isinstance(result, str):
767
- return RunResponse(content=result)
925
+ return RunOutput(content=result)
768
926
  elif isinstance(result, dict):
769
927
  # If it's a dict, try to extract content
770
928
  content = result.get("content", str(result))
771
- return RunResponse(content=content)
929
+ return RunOutput(content=content)
772
930
  else:
773
931
  # Convert any other type to string
774
- return RunResponse(content=str(result))
932
+ return RunOutput(content=str(result))
775
933
 
776
- def _convert_audio_artifacts_to_audio(self, audio_artifacts: List[AudioArtifact]) -> List[Audio]:
934
+ def _convert_audio_artifacts_to_audio(self, audio_artifacts: List[Audio]) -> List[Audio]:
777
935
  """Convert AudioArtifact objects to Audio objects"""
778
936
  audios = []
779
937
  for audio_artifact in audio_artifacts:
780
938
  if audio_artifact.url:
781
939
  audios.append(Audio(url=audio_artifact.url))
782
- elif audio_artifact.base64_audio: # use base64_audio instead of content
783
- audios.append(Audio(content=audio_artifact.base64_audio))
940
+ elif audio_artifact.content:
941
+ audios.append(Audio(content=audio_artifact.content))
784
942
  else:
785
- logger.warning(f"Skipping AudioArtifact with no URL or base64_audio: {audio_artifact}")
943
+ logger.warning(f"Skipping AudioArtifact with no URL or content: {audio_artifact}")
786
944
  continue
787
945
  return audios
788
946
 
789
- def _convert_image_artifacts_to_images(self, image_artifacts: List[ImageArtifact]) -> List[Image]:
947
+ def _convert_image_artifacts_to_images(self, image_artifacts: List[Image]) -> List[Image]:
790
948
  """
791
949
  Convert ImageArtifact objects to Image objects with proper content handling.
792
950
 
@@ -838,7 +996,7 @@ class Step:
838
996
 
839
997
  return images
840
998
 
841
- def _convert_video_artifacts_to_videos(self, video_artifacts: List[VideoArtifact]) -> List[Video]:
999
+ def _convert_video_artifacts_to_videos(self, video_artifacts: List[Video]) -> List[Video]:
842
1000
  """
843
1001
  Convert VideoArtifact objects to Video objects with proper content handling.
844
1002