agno 2.2.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (575) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +51 -0
  3. agno/agent/agent.py +10405 -0
  4. agno/api/__init__.py +0 -0
  5. agno/api/agent.py +28 -0
  6. agno/api/api.py +40 -0
  7. agno/api/evals.py +22 -0
  8. agno/api/os.py +17 -0
  9. agno/api/routes.py +13 -0
  10. agno/api/schemas/__init__.py +9 -0
  11. agno/api/schemas/agent.py +16 -0
  12. agno/api/schemas/evals.py +16 -0
  13. agno/api/schemas/os.py +14 -0
  14. agno/api/schemas/response.py +6 -0
  15. agno/api/schemas/team.py +16 -0
  16. agno/api/schemas/utils.py +21 -0
  17. agno/api/schemas/workflows.py +16 -0
  18. agno/api/settings.py +53 -0
  19. agno/api/team.py +30 -0
  20. agno/api/workflow.py +28 -0
  21. agno/cloud/aws/base.py +214 -0
  22. agno/cloud/aws/s3/__init__.py +2 -0
  23. agno/cloud/aws/s3/api_client.py +43 -0
  24. agno/cloud/aws/s3/bucket.py +195 -0
  25. agno/cloud/aws/s3/object.py +57 -0
  26. agno/culture/__init__.py +3 -0
  27. agno/culture/manager.py +956 -0
  28. agno/db/__init__.py +24 -0
  29. agno/db/async_postgres/__init__.py +3 -0
  30. agno/db/base.py +598 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2042 -0
  33. agno/db/dynamo/schemas.py +314 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +1795 -0
  37. agno/db/firestore/schemas.py +140 -0
  38. agno/db/firestore/utils.py +376 -0
  39. agno/db/gcs_json/__init__.py +3 -0
  40. agno/db/gcs_json/gcs_json_db.py +1335 -0
  41. agno/db/gcs_json/utils.py +228 -0
  42. agno/db/in_memory/__init__.py +3 -0
  43. agno/db/in_memory/in_memory_db.py +1160 -0
  44. agno/db/in_memory/utils.py +230 -0
  45. agno/db/json/__init__.py +3 -0
  46. agno/db/json/json_db.py +1328 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/__init__.py +0 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/mongo/__init__.py +17 -0
  51. agno/db/mongo/async_mongo.py +2026 -0
  52. agno/db/mongo/mongo.py +1982 -0
  53. agno/db/mongo/schemas.py +87 -0
  54. agno/db/mongo/utils.py +259 -0
  55. agno/db/mysql/__init__.py +3 -0
  56. agno/db/mysql/mysql.py +2308 -0
  57. agno/db/mysql/schemas.py +138 -0
  58. agno/db/mysql/utils.py +355 -0
  59. agno/db/postgres/__init__.py +4 -0
  60. agno/db/postgres/async_postgres.py +1927 -0
  61. agno/db/postgres/postgres.py +2260 -0
  62. agno/db/postgres/schemas.py +139 -0
  63. agno/db/postgres/utils.py +442 -0
  64. agno/db/redis/__init__.py +3 -0
  65. agno/db/redis/redis.py +1660 -0
  66. agno/db/redis/schemas.py +123 -0
  67. agno/db/redis/utils.py +346 -0
  68. agno/db/schemas/__init__.py +4 -0
  69. agno/db/schemas/culture.py +120 -0
  70. agno/db/schemas/evals.py +33 -0
  71. agno/db/schemas/knowledge.py +40 -0
  72. agno/db/schemas/memory.py +46 -0
  73. agno/db/schemas/metrics.py +0 -0
  74. agno/db/singlestore/__init__.py +3 -0
  75. agno/db/singlestore/schemas.py +130 -0
  76. agno/db/singlestore/singlestore.py +2272 -0
  77. agno/db/singlestore/utils.py +384 -0
  78. agno/db/sqlite/__init__.py +4 -0
  79. agno/db/sqlite/async_sqlite.py +2293 -0
  80. agno/db/sqlite/schemas.py +133 -0
  81. agno/db/sqlite/sqlite.py +2288 -0
  82. agno/db/sqlite/utils.py +431 -0
  83. agno/db/surrealdb/__init__.py +3 -0
  84. agno/db/surrealdb/metrics.py +292 -0
  85. agno/db/surrealdb/models.py +309 -0
  86. agno/db/surrealdb/queries.py +71 -0
  87. agno/db/surrealdb/surrealdb.py +1353 -0
  88. agno/db/surrealdb/utils.py +147 -0
  89. agno/db/utils.py +116 -0
  90. agno/debug.py +18 -0
  91. agno/eval/__init__.py +14 -0
  92. agno/eval/accuracy.py +834 -0
  93. agno/eval/performance.py +773 -0
  94. agno/eval/reliability.py +306 -0
  95. agno/eval/utils.py +119 -0
  96. agno/exceptions.py +161 -0
  97. agno/filters.py +354 -0
  98. agno/guardrails/__init__.py +6 -0
  99. agno/guardrails/base.py +19 -0
  100. agno/guardrails/openai.py +144 -0
  101. agno/guardrails/pii.py +94 -0
  102. agno/guardrails/prompt_injection.py +52 -0
  103. agno/integrations/__init__.py +0 -0
  104. agno/integrations/discord/__init__.py +3 -0
  105. agno/integrations/discord/client.py +203 -0
  106. agno/knowledge/__init__.py +5 -0
  107. agno/knowledge/chunking/__init__.py +0 -0
  108. agno/knowledge/chunking/agentic.py +79 -0
  109. agno/knowledge/chunking/document.py +91 -0
  110. agno/knowledge/chunking/fixed.py +57 -0
  111. agno/knowledge/chunking/markdown.py +151 -0
  112. agno/knowledge/chunking/recursive.py +63 -0
  113. agno/knowledge/chunking/row.py +39 -0
  114. agno/knowledge/chunking/semantic.py +86 -0
  115. agno/knowledge/chunking/strategy.py +165 -0
  116. agno/knowledge/content.py +74 -0
  117. agno/knowledge/document/__init__.py +5 -0
  118. agno/knowledge/document/base.py +58 -0
  119. agno/knowledge/embedder/__init__.py +5 -0
  120. agno/knowledge/embedder/aws_bedrock.py +343 -0
  121. agno/knowledge/embedder/azure_openai.py +210 -0
  122. agno/knowledge/embedder/base.py +23 -0
  123. agno/knowledge/embedder/cohere.py +323 -0
  124. agno/knowledge/embedder/fastembed.py +62 -0
  125. agno/knowledge/embedder/fireworks.py +13 -0
  126. agno/knowledge/embedder/google.py +258 -0
  127. agno/knowledge/embedder/huggingface.py +94 -0
  128. agno/knowledge/embedder/jina.py +182 -0
  129. agno/knowledge/embedder/langdb.py +22 -0
  130. agno/knowledge/embedder/mistral.py +206 -0
  131. agno/knowledge/embedder/nebius.py +13 -0
  132. agno/knowledge/embedder/ollama.py +154 -0
  133. agno/knowledge/embedder/openai.py +195 -0
  134. agno/knowledge/embedder/sentence_transformer.py +63 -0
  135. agno/knowledge/embedder/together.py +13 -0
  136. agno/knowledge/embedder/vllm.py +262 -0
  137. agno/knowledge/embedder/voyageai.py +165 -0
  138. agno/knowledge/knowledge.py +1988 -0
  139. agno/knowledge/reader/__init__.py +7 -0
  140. agno/knowledge/reader/arxiv_reader.py +81 -0
  141. agno/knowledge/reader/base.py +95 -0
  142. agno/knowledge/reader/csv_reader.py +166 -0
  143. agno/knowledge/reader/docx_reader.py +82 -0
  144. agno/knowledge/reader/field_labeled_csv_reader.py +292 -0
  145. agno/knowledge/reader/firecrawl_reader.py +201 -0
  146. agno/knowledge/reader/json_reader.py +87 -0
  147. agno/knowledge/reader/markdown_reader.py +137 -0
  148. agno/knowledge/reader/pdf_reader.py +431 -0
  149. agno/knowledge/reader/pptx_reader.py +101 -0
  150. agno/knowledge/reader/reader_factory.py +313 -0
  151. agno/knowledge/reader/s3_reader.py +89 -0
  152. agno/knowledge/reader/tavily_reader.py +194 -0
  153. agno/knowledge/reader/text_reader.py +115 -0
  154. agno/knowledge/reader/web_search_reader.py +372 -0
  155. agno/knowledge/reader/website_reader.py +455 -0
  156. agno/knowledge/reader/wikipedia_reader.py +59 -0
  157. agno/knowledge/reader/youtube_reader.py +78 -0
  158. agno/knowledge/remote_content/__init__.py +0 -0
  159. agno/knowledge/remote_content/remote_content.py +88 -0
  160. agno/knowledge/reranker/__init__.py +3 -0
  161. agno/knowledge/reranker/base.py +14 -0
  162. agno/knowledge/reranker/cohere.py +64 -0
  163. agno/knowledge/reranker/infinity.py +195 -0
  164. agno/knowledge/reranker/sentence_transformer.py +54 -0
  165. agno/knowledge/types.py +39 -0
  166. agno/knowledge/utils.py +189 -0
  167. agno/media.py +462 -0
  168. agno/memory/__init__.py +3 -0
  169. agno/memory/manager.py +1327 -0
  170. agno/models/__init__.py +0 -0
  171. agno/models/aimlapi/__init__.py +5 -0
  172. agno/models/aimlapi/aimlapi.py +45 -0
  173. agno/models/anthropic/__init__.py +5 -0
  174. agno/models/anthropic/claude.py +757 -0
  175. agno/models/aws/__init__.py +15 -0
  176. agno/models/aws/bedrock.py +701 -0
  177. agno/models/aws/claude.py +378 -0
  178. agno/models/azure/__init__.py +18 -0
  179. agno/models/azure/ai_foundry.py +485 -0
  180. agno/models/azure/openai_chat.py +131 -0
  181. agno/models/base.py +2175 -0
  182. agno/models/cerebras/__init__.py +12 -0
  183. agno/models/cerebras/cerebras.py +501 -0
  184. agno/models/cerebras/cerebras_openai.py +112 -0
  185. agno/models/cohere/__init__.py +5 -0
  186. agno/models/cohere/chat.py +389 -0
  187. agno/models/cometapi/__init__.py +5 -0
  188. agno/models/cometapi/cometapi.py +57 -0
  189. agno/models/dashscope/__init__.py +5 -0
  190. agno/models/dashscope/dashscope.py +91 -0
  191. agno/models/deepinfra/__init__.py +5 -0
  192. agno/models/deepinfra/deepinfra.py +28 -0
  193. agno/models/deepseek/__init__.py +5 -0
  194. agno/models/deepseek/deepseek.py +61 -0
  195. agno/models/defaults.py +1 -0
  196. agno/models/fireworks/__init__.py +5 -0
  197. agno/models/fireworks/fireworks.py +26 -0
  198. agno/models/google/__init__.py +5 -0
  199. agno/models/google/gemini.py +1085 -0
  200. agno/models/groq/__init__.py +5 -0
  201. agno/models/groq/groq.py +556 -0
  202. agno/models/huggingface/__init__.py +5 -0
  203. agno/models/huggingface/huggingface.py +491 -0
  204. agno/models/ibm/__init__.py +5 -0
  205. agno/models/ibm/watsonx.py +422 -0
  206. agno/models/internlm/__init__.py +3 -0
  207. agno/models/internlm/internlm.py +26 -0
  208. agno/models/langdb/__init__.py +1 -0
  209. agno/models/langdb/langdb.py +48 -0
  210. agno/models/litellm/__init__.py +14 -0
  211. agno/models/litellm/chat.py +468 -0
  212. agno/models/litellm/litellm_openai.py +25 -0
  213. agno/models/llama_cpp/__init__.py +5 -0
  214. agno/models/llama_cpp/llama_cpp.py +22 -0
  215. agno/models/lmstudio/__init__.py +5 -0
  216. agno/models/lmstudio/lmstudio.py +25 -0
  217. agno/models/message.py +434 -0
  218. agno/models/meta/__init__.py +12 -0
  219. agno/models/meta/llama.py +475 -0
  220. agno/models/meta/llama_openai.py +78 -0
  221. agno/models/metrics.py +120 -0
  222. agno/models/mistral/__init__.py +5 -0
  223. agno/models/mistral/mistral.py +432 -0
  224. agno/models/nebius/__init__.py +3 -0
  225. agno/models/nebius/nebius.py +54 -0
  226. agno/models/nexus/__init__.py +3 -0
  227. agno/models/nexus/nexus.py +22 -0
  228. agno/models/nvidia/__init__.py +5 -0
  229. agno/models/nvidia/nvidia.py +28 -0
  230. agno/models/ollama/__init__.py +5 -0
  231. agno/models/ollama/chat.py +441 -0
  232. agno/models/openai/__init__.py +9 -0
  233. agno/models/openai/chat.py +883 -0
  234. agno/models/openai/like.py +27 -0
  235. agno/models/openai/responses.py +1050 -0
  236. agno/models/openrouter/__init__.py +5 -0
  237. agno/models/openrouter/openrouter.py +66 -0
  238. agno/models/perplexity/__init__.py +5 -0
  239. agno/models/perplexity/perplexity.py +187 -0
  240. agno/models/portkey/__init__.py +3 -0
  241. agno/models/portkey/portkey.py +81 -0
  242. agno/models/requesty/__init__.py +5 -0
  243. agno/models/requesty/requesty.py +52 -0
  244. agno/models/response.py +199 -0
  245. agno/models/sambanova/__init__.py +5 -0
  246. agno/models/sambanova/sambanova.py +28 -0
  247. agno/models/siliconflow/__init__.py +5 -0
  248. agno/models/siliconflow/siliconflow.py +25 -0
  249. agno/models/together/__init__.py +5 -0
  250. agno/models/together/together.py +25 -0
  251. agno/models/utils.py +266 -0
  252. agno/models/vercel/__init__.py +3 -0
  253. agno/models/vercel/v0.py +26 -0
  254. agno/models/vertexai/__init__.py +0 -0
  255. agno/models/vertexai/claude.py +70 -0
  256. agno/models/vllm/__init__.py +3 -0
  257. agno/models/vllm/vllm.py +78 -0
  258. agno/models/xai/__init__.py +3 -0
  259. agno/models/xai/xai.py +113 -0
  260. agno/os/__init__.py +3 -0
  261. agno/os/app.py +876 -0
  262. agno/os/auth.py +57 -0
  263. agno/os/config.py +104 -0
  264. agno/os/interfaces/__init__.py +1 -0
  265. agno/os/interfaces/a2a/__init__.py +3 -0
  266. agno/os/interfaces/a2a/a2a.py +42 -0
  267. agno/os/interfaces/a2a/router.py +250 -0
  268. agno/os/interfaces/a2a/utils.py +924 -0
  269. agno/os/interfaces/agui/__init__.py +3 -0
  270. agno/os/interfaces/agui/agui.py +47 -0
  271. agno/os/interfaces/agui/router.py +144 -0
  272. agno/os/interfaces/agui/utils.py +534 -0
  273. agno/os/interfaces/base.py +25 -0
  274. agno/os/interfaces/slack/__init__.py +3 -0
  275. agno/os/interfaces/slack/router.py +148 -0
  276. agno/os/interfaces/slack/security.py +30 -0
  277. agno/os/interfaces/slack/slack.py +47 -0
  278. agno/os/interfaces/whatsapp/__init__.py +3 -0
  279. agno/os/interfaces/whatsapp/router.py +211 -0
  280. agno/os/interfaces/whatsapp/security.py +53 -0
  281. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  282. agno/os/mcp.py +292 -0
  283. agno/os/middleware/__init__.py +7 -0
  284. agno/os/middleware/jwt.py +233 -0
  285. agno/os/router.py +1763 -0
  286. agno/os/routers/__init__.py +3 -0
  287. agno/os/routers/evals/__init__.py +3 -0
  288. agno/os/routers/evals/evals.py +430 -0
  289. agno/os/routers/evals/schemas.py +142 -0
  290. agno/os/routers/evals/utils.py +162 -0
  291. agno/os/routers/health.py +31 -0
  292. agno/os/routers/home.py +52 -0
  293. agno/os/routers/knowledge/__init__.py +3 -0
  294. agno/os/routers/knowledge/knowledge.py +997 -0
  295. agno/os/routers/knowledge/schemas.py +178 -0
  296. agno/os/routers/memory/__init__.py +3 -0
  297. agno/os/routers/memory/memory.py +515 -0
  298. agno/os/routers/memory/schemas.py +62 -0
  299. agno/os/routers/metrics/__init__.py +3 -0
  300. agno/os/routers/metrics/metrics.py +190 -0
  301. agno/os/routers/metrics/schemas.py +47 -0
  302. agno/os/routers/session/__init__.py +3 -0
  303. agno/os/routers/session/session.py +997 -0
  304. agno/os/schema.py +1055 -0
  305. agno/os/settings.py +43 -0
  306. agno/os/utils.py +630 -0
  307. agno/py.typed +0 -0
  308. agno/reasoning/__init__.py +0 -0
  309. agno/reasoning/anthropic.py +80 -0
  310. agno/reasoning/azure_ai_foundry.py +67 -0
  311. agno/reasoning/deepseek.py +63 -0
  312. agno/reasoning/default.py +97 -0
  313. agno/reasoning/gemini.py +73 -0
  314. agno/reasoning/groq.py +71 -0
  315. agno/reasoning/helpers.py +63 -0
  316. agno/reasoning/ollama.py +67 -0
  317. agno/reasoning/openai.py +86 -0
  318. agno/reasoning/step.py +31 -0
  319. agno/reasoning/vertexai.py +76 -0
  320. agno/run/__init__.py +6 -0
  321. agno/run/agent.py +787 -0
  322. agno/run/base.py +229 -0
  323. agno/run/cancel.py +81 -0
  324. agno/run/messages.py +32 -0
  325. agno/run/team.py +753 -0
  326. agno/run/workflow.py +708 -0
  327. agno/session/__init__.py +10 -0
  328. agno/session/agent.py +295 -0
  329. agno/session/summary.py +265 -0
  330. agno/session/team.py +392 -0
  331. agno/session/workflow.py +205 -0
  332. agno/team/__init__.py +37 -0
  333. agno/team/team.py +8793 -0
  334. agno/tools/__init__.py +10 -0
  335. agno/tools/agentql.py +120 -0
  336. agno/tools/airflow.py +69 -0
  337. agno/tools/api.py +122 -0
  338. agno/tools/apify.py +314 -0
  339. agno/tools/arxiv.py +127 -0
  340. agno/tools/aws_lambda.py +53 -0
  341. agno/tools/aws_ses.py +66 -0
  342. agno/tools/baidusearch.py +89 -0
  343. agno/tools/bitbucket.py +292 -0
  344. agno/tools/brandfetch.py +213 -0
  345. agno/tools/bravesearch.py +106 -0
  346. agno/tools/brightdata.py +367 -0
  347. agno/tools/browserbase.py +209 -0
  348. agno/tools/calcom.py +255 -0
  349. agno/tools/calculator.py +151 -0
  350. agno/tools/cartesia.py +187 -0
  351. agno/tools/clickup.py +244 -0
  352. agno/tools/confluence.py +240 -0
  353. agno/tools/crawl4ai.py +158 -0
  354. agno/tools/csv_toolkit.py +185 -0
  355. agno/tools/dalle.py +110 -0
  356. agno/tools/daytona.py +475 -0
  357. agno/tools/decorator.py +262 -0
  358. agno/tools/desi_vocal.py +108 -0
  359. agno/tools/discord.py +161 -0
  360. agno/tools/docker.py +716 -0
  361. agno/tools/duckdb.py +379 -0
  362. agno/tools/duckduckgo.py +91 -0
  363. agno/tools/e2b.py +703 -0
  364. agno/tools/eleven_labs.py +196 -0
  365. agno/tools/email.py +67 -0
  366. agno/tools/evm.py +129 -0
  367. agno/tools/exa.py +396 -0
  368. agno/tools/fal.py +127 -0
  369. agno/tools/file.py +240 -0
  370. agno/tools/file_generation.py +350 -0
  371. agno/tools/financial_datasets.py +288 -0
  372. agno/tools/firecrawl.py +143 -0
  373. agno/tools/function.py +1187 -0
  374. agno/tools/giphy.py +93 -0
  375. agno/tools/github.py +1760 -0
  376. agno/tools/gmail.py +922 -0
  377. agno/tools/google_bigquery.py +117 -0
  378. agno/tools/google_drive.py +270 -0
  379. agno/tools/google_maps.py +253 -0
  380. agno/tools/googlecalendar.py +674 -0
  381. agno/tools/googlesearch.py +98 -0
  382. agno/tools/googlesheets.py +377 -0
  383. agno/tools/hackernews.py +77 -0
  384. agno/tools/jina.py +101 -0
  385. agno/tools/jira.py +170 -0
  386. agno/tools/knowledge.py +218 -0
  387. agno/tools/linear.py +426 -0
  388. agno/tools/linkup.py +58 -0
  389. agno/tools/local_file_system.py +90 -0
  390. agno/tools/lumalab.py +183 -0
  391. agno/tools/mcp/__init__.py +10 -0
  392. agno/tools/mcp/mcp.py +331 -0
  393. agno/tools/mcp/multi_mcp.py +347 -0
  394. agno/tools/mcp/params.py +24 -0
  395. agno/tools/mcp_toolbox.py +284 -0
  396. agno/tools/mem0.py +193 -0
  397. agno/tools/memori.py +339 -0
  398. agno/tools/memory.py +419 -0
  399. agno/tools/mlx_transcribe.py +139 -0
  400. agno/tools/models/__init__.py +0 -0
  401. agno/tools/models/azure_openai.py +190 -0
  402. agno/tools/models/gemini.py +203 -0
  403. agno/tools/models/groq.py +158 -0
  404. agno/tools/models/morph.py +186 -0
  405. agno/tools/models/nebius.py +124 -0
  406. agno/tools/models_labs.py +195 -0
  407. agno/tools/moviepy_video.py +349 -0
  408. agno/tools/neo4j.py +134 -0
  409. agno/tools/newspaper.py +46 -0
  410. agno/tools/newspaper4k.py +93 -0
  411. agno/tools/notion.py +204 -0
  412. agno/tools/openai.py +202 -0
  413. agno/tools/openbb.py +160 -0
  414. agno/tools/opencv.py +321 -0
  415. agno/tools/openweather.py +233 -0
  416. agno/tools/oxylabs.py +385 -0
  417. agno/tools/pandas.py +102 -0
  418. agno/tools/parallel.py +314 -0
  419. agno/tools/postgres.py +257 -0
  420. agno/tools/pubmed.py +188 -0
  421. agno/tools/python.py +205 -0
  422. agno/tools/reasoning.py +283 -0
  423. agno/tools/reddit.py +467 -0
  424. agno/tools/replicate.py +117 -0
  425. agno/tools/resend.py +62 -0
  426. agno/tools/scrapegraph.py +222 -0
  427. agno/tools/searxng.py +152 -0
  428. agno/tools/serpapi.py +116 -0
  429. agno/tools/serper.py +255 -0
  430. agno/tools/shell.py +53 -0
  431. agno/tools/slack.py +136 -0
  432. agno/tools/sleep.py +20 -0
  433. agno/tools/spider.py +116 -0
  434. agno/tools/sql.py +154 -0
  435. agno/tools/streamlit/__init__.py +0 -0
  436. agno/tools/streamlit/components.py +113 -0
  437. agno/tools/tavily.py +254 -0
  438. agno/tools/telegram.py +48 -0
  439. agno/tools/todoist.py +218 -0
  440. agno/tools/tool_registry.py +1 -0
  441. agno/tools/toolkit.py +146 -0
  442. agno/tools/trafilatura.py +388 -0
  443. agno/tools/trello.py +274 -0
  444. agno/tools/twilio.py +186 -0
  445. agno/tools/user_control_flow.py +78 -0
  446. agno/tools/valyu.py +228 -0
  447. agno/tools/visualization.py +467 -0
  448. agno/tools/webbrowser.py +28 -0
  449. agno/tools/webex.py +76 -0
  450. agno/tools/website.py +54 -0
  451. agno/tools/webtools.py +45 -0
  452. agno/tools/whatsapp.py +286 -0
  453. agno/tools/wikipedia.py +63 -0
  454. agno/tools/workflow.py +278 -0
  455. agno/tools/x.py +335 -0
  456. agno/tools/yfinance.py +257 -0
  457. agno/tools/youtube.py +184 -0
  458. agno/tools/zendesk.py +82 -0
  459. agno/tools/zep.py +454 -0
  460. agno/tools/zoom.py +382 -0
  461. agno/utils/__init__.py +0 -0
  462. agno/utils/agent.py +820 -0
  463. agno/utils/audio.py +49 -0
  464. agno/utils/certs.py +27 -0
  465. agno/utils/code_execution.py +11 -0
  466. agno/utils/common.py +132 -0
  467. agno/utils/dttm.py +13 -0
  468. agno/utils/enum.py +22 -0
  469. agno/utils/env.py +11 -0
  470. agno/utils/events.py +696 -0
  471. agno/utils/format_str.py +16 -0
  472. agno/utils/functions.py +166 -0
  473. agno/utils/gemini.py +426 -0
  474. agno/utils/hooks.py +57 -0
  475. agno/utils/http.py +74 -0
  476. agno/utils/json_schema.py +234 -0
  477. agno/utils/knowledge.py +36 -0
  478. agno/utils/location.py +19 -0
  479. agno/utils/log.py +255 -0
  480. agno/utils/mcp.py +214 -0
  481. agno/utils/media.py +352 -0
  482. agno/utils/merge_dict.py +41 -0
  483. agno/utils/message.py +118 -0
  484. agno/utils/models/__init__.py +0 -0
  485. agno/utils/models/ai_foundry.py +43 -0
  486. agno/utils/models/claude.py +358 -0
  487. agno/utils/models/cohere.py +87 -0
  488. agno/utils/models/llama.py +78 -0
  489. agno/utils/models/mistral.py +98 -0
  490. agno/utils/models/openai_responses.py +140 -0
  491. agno/utils/models/schema_utils.py +153 -0
  492. agno/utils/models/watsonx.py +41 -0
  493. agno/utils/openai.py +257 -0
  494. agno/utils/pickle.py +32 -0
  495. agno/utils/pprint.py +178 -0
  496. agno/utils/print_response/__init__.py +0 -0
  497. agno/utils/print_response/agent.py +842 -0
  498. agno/utils/print_response/team.py +1724 -0
  499. agno/utils/print_response/workflow.py +1668 -0
  500. agno/utils/prompts.py +111 -0
  501. agno/utils/reasoning.py +108 -0
  502. agno/utils/response.py +163 -0
  503. agno/utils/response_iterator.py +17 -0
  504. agno/utils/safe_formatter.py +24 -0
  505. agno/utils/serialize.py +32 -0
  506. agno/utils/shell.py +22 -0
  507. agno/utils/streamlit.py +487 -0
  508. agno/utils/string.py +231 -0
  509. agno/utils/team.py +139 -0
  510. agno/utils/timer.py +41 -0
  511. agno/utils/tools.py +102 -0
  512. agno/utils/web.py +23 -0
  513. agno/utils/whatsapp.py +305 -0
  514. agno/utils/yaml_io.py +25 -0
  515. agno/vectordb/__init__.py +3 -0
  516. agno/vectordb/base.py +127 -0
  517. agno/vectordb/cassandra/__init__.py +5 -0
  518. agno/vectordb/cassandra/cassandra.py +501 -0
  519. agno/vectordb/cassandra/extra_param_mixin.py +11 -0
  520. agno/vectordb/cassandra/index.py +13 -0
  521. agno/vectordb/chroma/__init__.py +5 -0
  522. agno/vectordb/chroma/chromadb.py +929 -0
  523. agno/vectordb/clickhouse/__init__.py +9 -0
  524. agno/vectordb/clickhouse/clickhousedb.py +835 -0
  525. agno/vectordb/clickhouse/index.py +9 -0
  526. agno/vectordb/couchbase/__init__.py +3 -0
  527. agno/vectordb/couchbase/couchbase.py +1442 -0
  528. agno/vectordb/distance.py +7 -0
  529. agno/vectordb/lancedb/__init__.py +6 -0
  530. agno/vectordb/lancedb/lance_db.py +995 -0
  531. agno/vectordb/langchaindb/__init__.py +5 -0
  532. agno/vectordb/langchaindb/langchaindb.py +163 -0
  533. agno/vectordb/lightrag/__init__.py +5 -0
  534. agno/vectordb/lightrag/lightrag.py +388 -0
  535. agno/vectordb/llamaindex/__init__.py +3 -0
  536. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  537. agno/vectordb/milvus/__init__.py +4 -0
  538. agno/vectordb/milvus/milvus.py +1182 -0
  539. agno/vectordb/mongodb/__init__.py +9 -0
  540. agno/vectordb/mongodb/mongodb.py +1417 -0
  541. agno/vectordb/pgvector/__init__.py +12 -0
  542. agno/vectordb/pgvector/index.py +23 -0
  543. agno/vectordb/pgvector/pgvector.py +1462 -0
  544. agno/vectordb/pineconedb/__init__.py +5 -0
  545. agno/vectordb/pineconedb/pineconedb.py +747 -0
  546. agno/vectordb/qdrant/__init__.py +5 -0
  547. agno/vectordb/qdrant/qdrant.py +1134 -0
  548. agno/vectordb/redis/__init__.py +9 -0
  549. agno/vectordb/redis/redisdb.py +694 -0
  550. agno/vectordb/search.py +7 -0
  551. agno/vectordb/singlestore/__init__.py +10 -0
  552. agno/vectordb/singlestore/index.py +41 -0
  553. agno/vectordb/singlestore/singlestore.py +763 -0
  554. agno/vectordb/surrealdb/__init__.py +3 -0
  555. agno/vectordb/surrealdb/surrealdb.py +699 -0
  556. agno/vectordb/upstashdb/__init__.py +5 -0
  557. agno/vectordb/upstashdb/upstashdb.py +718 -0
  558. agno/vectordb/weaviate/__init__.py +8 -0
  559. agno/vectordb/weaviate/index.py +15 -0
  560. agno/vectordb/weaviate/weaviate.py +1005 -0
  561. agno/workflow/__init__.py +23 -0
  562. agno/workflow/agent.py +299 -0
  563. agno/workflow/condition.py +738 -0
  564. agno/workflow/loop.py +735 -0
  565. agno/workflow/parallel.py +824 -0
  566. agno/workflow/router.py +702 -0
  567. agno/workflow/step.py +1432 -0
  568. agno/workflow/steps.py +592 -0
  569. agno/workflow/types.py +520 -0
  570. agno/workflow/workflow.py +4321 -0
  571. agno-2.2.13.dist-info/METADATA +614 -0
  572. agno-2.2.13.dist-info/RECORD +575 -0
  573. agno-2.2.13.dist-info/WHEEL +5 -0
  574. agno-2.2.13.dist-info/licenses/LICENSE +201 -0
  575. agno-2.2.13.dist-info/top_level.txt +1 -0
agno/workflow/steps.py ADDED
@@ -0,0 +1,592 @@
1
+ from dataclasses import dataclass
2
+ from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
3
+ from uuid import uuid4
4
+
5
+ from agno.run.agent import RunOutputEvent
6
+ from agno.run.base import RunContext
7
+ from agno.run.team import TeamRunOutputEvent
8
+ from agno.run.workflow import (
9
+ StepsExecutionCompletedEvent,
10
+ StepsExecutionStartedEvent,
11
+ WorkflowRunOutput,
12
+ WorkflowRunOutputEvent,
13
+ )
14
+ from agno.session.workflow import WorkflowSession
15
+ from agno.utils.log import log_debug, logger
16
+ from agno.workflow.step import Step, StepInput, StepOutput, StepType
17
+
18
+ WorkflowSteps = List[
19
+ Union[
20
+ Callable[
21
+ [StepInput], Union[StepOutput, Awaitable[StepOutput], Iterator[StepOutput], AsyncIterator[StepOutput]]
22
+ ],
23
+ Step,
24
+ "Steps", # type: ignore # noqa: F821
25
+ "Loop", # type: ignore # noqa: F821
26
+ "Parallel", # type: ignore # noqa: F821
27
+ "Condition", # type: ignore # noqa: F821
28
+ "Router", # type: ignore # noqa: F821
29
+ ]
30
+ ]
31
+
32
+
33
+ @dataclass
34
+ class Steps:
35
+ """A pipeline of steps that execute in order"""
36
+
37
+ # Steps to execute
38
+ steps: WorkflowSteps
39
+
40
+ # Pipeline identification
41
+ name: Optional[str] = None
42
+ description: Optional[str] = None
43
+
44
+ def __init__(
45
+ self, name: Optional[str] = None, description: Optional[str] = None, steps: Optional[List[Any]] = None
46
+ ): # Change to List[Any]
47
+ self.name = name
48
+ self.description = description
49
+ self.steps = steps if steps else []
50
+
51
+ def _prepare_steps(self):
52
+ """Prepare the steps for execution - mirrors workflow logic"""
53
+ from agno.agent.agent import Agent
54
+ from agno.team.team import Team
55
+ from agno.workflow.condition import Condition
56
+ from agno.workflow.loop import Loop
57
+ from agno.workflow.parallel import Parallel
58
+ from agno.workflow.router import Router
59
+ from agno.workflow.step import Step
60
+
61
+ prepared_steps: WorkflowSteps = []
62
+ for step in self.steps:
63
+ if callable(step) and hasattr(step, "__name__"):
64
+ prepared_steps.append(Step(name=step.__name__, description="User-defined callable step", executor=step))
65
+ elif isinstance(step, Agent):
66
+ prepared_steps.append(Step(name=step.name, description=step.description, agent=step))
67
+ elif isinstance(step, Team):
68
+ prepared_steps.append(Step(name=step.name, description=step.description, team=step))
69
+ elif isinstance(step, (Step, Steps, Loop, Parallel, Condition, Router)):
70
+ prepared_steps.append(step)
71
+ else:
72
+ raise ValueError(f"Invalid step type: {type(step).__name__}")
73
+
74
+ self.steps = prepared_steps
75
+
76
+ def _update_step_input_from_outputs(
77
+ self,
78
+ step_input: StepInput,
79
+ step_outputs: Union[StepOutput, List[StepOutput]],
80
+ steps_step_outputs: Optional[Dict[str, StepOutput]] = None,
81
+ ) -> StepInput:
82
+ """Helper to update step input from step outputs - mirrors Condition/Router logic"""
83
+ current_images = step_input.images or []
84
+ current_videos = step_input.videos or []
85
+ current_audio = step_input.audio or []
86
+
87
+ if isinstance(step_outputs, list):
88
+ step_images = sum([out.images or [] for out in step_outputs], [])
89
+ step_videos = sum([out.videos or [] for out in step_outputs], [])
90
+ step_audio = sum([out.audio or [] for out in step_outputs], [])
91
+ # Use the last output's content for chaining
92
+ previous_step_content = step_outputs[-1].content if step_outputs else None
93
+ else:
94
+ # Single output
95
+ step_images = step_outputs.images or []
96
+ step_videos = step_outputs.videos or []
97
+ step_audio = step_outputs.audio or []
98
+ previous_step_content = step_outputs.content
99
+
100
+ updated_previous_step_outputs = {}
101
+ if step_input.previous_step_outputs:
102
+ updated_previous_step_outputs.update(step_input.previous_step_outputs)
103
+ if steps_step_outputs:
104
+ updated_previous_step_outputs.update(steps_step_outputs)
105
+
106
+ return StepInput(
107
+ input=step_input.input,
108
+ previous_step_content=previous_step_content,
109
+ previous_step_outputs=updated_previous_step_outputs,
110
+ additional_data=step_input.additional_data,
111
+ images=current_images + step_images,
112
+ videos=current_videos + step_videos,
113
+ audio=current_audio + step_audio,
114
+ )
115
+
116
+ def execute(
117
+ self,
118
+ step_input: StepInput,
119
+ session_id: Optional[str] = None,
120
+ user_id: Optional[str] = None,
121
+ workflow_run_response: Optional[WorkflowRunOutput] = None,
122
+ run_context: Optional[RunContext] = None,
123
+ session_state: Optional[Dict[str, Any]] = None,
124
+ store_executor_outputs: bool = True,
125
+ workflow_session: Optional[WorkflowSession] = None,
126
+ add_workflow_history_to_steps: Optional[bool] = False,
127
+ num_history_runs: int = 3,
128
+ ) -> StepOutput:
129
+ """Execute all steps in sequence and return the final result"""
130
+ log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
131
+
132
+ steps_id = str(uuid4())
133
+
134
+ self._prepare_steps()
135
+
136
+ if not self.steps:
137
+ return StepOutput(step_name=self.name or "Steps", content="No steps to execute")
138
+
139
+ # Track outputs and pass data between steps - following Condition/Router pattern
140
+ all_results: List[StepOutput] = []
141
+ current_step_input = step_input
142
+ steps_step_outputs = {}
143
+
144
+ try:
145
+ for i, step in enumerate(self.steps):
146
+ step_name = getattr(step, "name", f"step_{i + 1}")
147
+ log_debug(f"Steps {self.name}: Executing step {i + 1}/{len(self.steps)} - {step_name}")
148
+
149
+ # Execute step
150
+ step_output = step.execute( # type: ignore
151
+ current_step_input,
152
+ session_id=session_id,
153
+ user_id=user_id,
154
+ workflow_run_response=workflow_run_response,
155
+ store_executor_outputs=store_executor_outputs,
156
+ run_context=run_context,
157
+ session_state=session_state,
158
+ workflow_session=workflow_session,
159
+ add_workflow_history_to_steps=add_workflow_history_to_steps,
160
+ num_history_runs=num_history_runs,
161
+ )
162
+
163
+ # Handle both single StepOutput and List[StepOutput] (from Loop/Condition/Router steps)
164
+ if isinstance(step_output, list):
165
+ all_results.extend(step_output)
166
+ if step_output:
167
+ steps_step_outputs[step_name] = step_output[-1]
168
+
169
+ if any(output.stop for output in step_output):
170
+ logger.info(f"Early termination requested by step {step_name}")
171
+ break
172
+ else:
173
+ all_results.append(step_output)
174
+ steps_step_outputs[step_name] = step_output
175
+
176
+ if step_output.stop:
177
+ logger.info(f"Early termination requested by step {step_name}")
178
+ break
179
+ log_debug(f"Steps {self.name}: Step {step_name} completed successfully")
180
+
181
+ # Update input for next step with proper chaining
182
+ current_step_input = self._update_step_input_from_outputs(
183
+ current_step_input, step_output, steps_step_outputs
184
+ )
185
+
186
+ log_debug(f"Steps End: {self.name} ({len(all_results)} results)", center=True, symbol="-")
187
+
188
+ return StepOutput(
189
+ step_name=self.name,
190
+ step_id=steps_id,
191
+ step_type=StepType.STEPS,
192
+ content=f"Steps {self.name} completed with {len(all_results)} results",
193
+ success=all(result.success for result in all_results) if all_results else True,
194
+ steps=all_results,
195
+ )
196
+
197
+ except Exception as e:
198
+ logger.error(f"Steps execution failed: {e}")
199
+ return StepOutput(
200
+ step_name=self.name or "Steps",
201
+ content=f"Steps execution failed: {str(e)}",
202
+ success=False,
203
+ error=str(e),
204
+ )
205
+
206
+ def execute_stream(
207
+ self,
208
+ step_input: StepInput,
209
+ workflow_run_response: WorkflowRunOutput,
210
+ run_context: Optional[RunContext] = None,
211
+ session_state: Optional[Dict[str, Any]] = None,
212
+ session_id: Optional[str] = None,
213
+ user_id: Optional[str] = None,
214
+ stream_events: bool = False,
215
+ stream_intermediate_steps: bool = False,
216
+ stream_executor_events: bool = True,
217
+ step_index: Optional[Union[int, tuple]] = None,
218
+ store_executor_outputs: bool = True,
219
+ parent_step_id: Optional[str] = None,
220
+ workflow_session: Optional[WorkflowSession] = None,
221
+ add_workflow_history_to_steps: Optional[bool] = False,
222
+ num_history_runs: int = 3,
223
+ ) -> Iterator[Union[WorkflowRunOutputEvent, TeamRunOutputEvent, RunOutputEvent, StepOutput]]:
224
+ """Execute all steps in sequence with streaming support"""
225
+ log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
226
+
227
+ steps_id = str(uuid4())
228
+
229
+ self._prepare_steps()
230
+
231
+ # Considering both stream_events and stream_intermediate_steps (deprecated)
232
+ stream_events = stream_events or stream_intermediate_steps
233
+
234
+ if stream_events:
235
+ # Yield steps execution started event
236
+ yield StepsExecutionStartedEvent(
237
+ run_id=workflow_run_response.run_id or "",
238
+ workflow_name=workflow_run_response.workflow_name or "",
239
+ workflow_id=workflow_run_response.workflow_id or "",
240
+ session_id=workflow_run_response.session_id or "",
241
+ step_name=self.name,
242
+ step_index=step_index,
243
+ steps_count=len(self.steps),
244
+ step_id=steps_id,
245
+ parent_step_id=parent_step_id,
246
+ )
247
+
248
+ if not self.steps:
249
+ yield StepOutput(step_name=self.name or "Steps", content="No steps to execute")
250
+ return
251
+
252
+ # Track outputs and pass data between steps - following Condition/Router pattern
253
+ all_results = []
254
+ current_step_input = step_input
255
+ steps_step_outputs = {}
256
+
257
+ try:
258
+ for i, step in enumerate(self.steps):
259
+ step_name = getattr(step, "name", f"step_{i + 1}")
260
+ log_debug(f"Steps {self.name}: Executing step {i + 1}/{len(self.steps)} - {step_name}")
261
+
262
+ step_outputs_for_step = []
263
+
264
+ if step_index is None or isinstance(step_index, int):
265
+ # Steps is a main step - child steps get x.1, x.2, x.3 format
266
+ child_step_index = (step_index if step_index is not None else 1, i) # Use i, not i+1
267
+ else:
268
+ # Steps is already a child step - child steps get parent.1, parent.2, parent.3
269
+ child_step_index = step_index + (i,) # Extend the tuple
270
+
271
+ # Stream step execution
272
+ for event in step.execute_stream( # type: ignore
273
+ current_step_input,
274
+ session_id=session_id,
275
+ user_id=user_id,
276
+ run_context=run_context,
277
+ session_state=session_state,
278
+ stream_events=stream_events,
279
+ stream_executor_events=stream_executor_events,
280
+ workflow_run_response=workflow_run_response,
281
+ step_index=child_step_index,
282
+ store_executor_outputs=store_executor_outputs,
283
+ parent_step_id=steps_id,
284
+ workflow_session=workflow_session,
285
+ add_workflow_history_to_steps=add_workflow_history_to_steps,
286
+ num_history_runs=num_history_runs,
287
+ ):
288
+ if isinstance(event, StepOutput):
289
+ step_outputs_for_step.append(event)
290
+ all_results.append(event)
291
+ else:
292
+ # Yield other events (streaming content, step events, etc.)
293
+ yield event
294
+
295
+ # Update step outputs tracking and prepare input for next step
296
+ if step_outputs_for_step:
297
+ if len(step_outputs_for_step) == 1:
298
+ steps_step_outputs[step_name] = step_outputs_for_step[0]
299
+
300
+ if step_outputs_for_step[0].stop:
301
+ logger.info(f"Early termination requested by step {step_name}")
302
+ break
303
+
304
+ current_step_input = self._update_step_input_from_outputs(
305
+ current_step_input, step_outputs_for_step[0], steps_step_outputs
306
+ )
307
+ else:
308
+ # Use last output
309
+ steps_step_outputs[step_name] = step_outputs_for_step[-1]
310
+
311
+ if any(output.stop for output in step_outputs_for_step):
312
+ logger.info(f"Early termination requested by step {step_name}")
313
+ break
314
+
315
+ current_step_input = self._update_step_input_from_outputs(
316
+ current_step_input, step_outputs_for_step, steps_step_outputs
317
+ )
318
+
319
+ log_debug(f"Steps End: {self.name} ({len(all_results)} results)", center=True, symbol="-")
320
+
321
+ if stream_events:
322
+ # Yield steps execution completed event
323
+ yield StepsExecutionCompletedEvent(
324
+ run_id=workflow_run_response.run_id or "",
325
+ workflow_name=workflow_run_response.workflow_name or "",
326
+ workflow_id=workflow_run_response.workflow_id or "",
327
+ session_id=workflow_run_response.session_id or "",
328
+ step_name=self.name,
329
+ step_index=step_index,
330
+ steps_count=len(self.steps),
331
+ executed_steps=len(all_results),
332
+ step_results=all_results,
333
+ step_id=steps_id,
334
+ parent_step_id=parent_step_id,
335
+ )
336
+
337
+ yield StepOutput(
338
+ step_name=self.name,
339
+ step_id=steps_id,
340
+ step_type=StepType.STEPS,
341
+ content=f"Steps {self.name} completed with {len(all_results)} results",
342
+ success=all(result.success for result in all_results) if all_results else True,
343
+ steps=all_results,
344
+ )
345
+
346
+ except Exception as e:
347
+ logger.error(f"Steps streaming failed: {e}")
348
+ error_result = StepOutput(
349
+ step_name=self.name or "Steps",
350
+ content=f"Steps execution failed: {str(e)}",
351
+ success=False,
352
+ error=str(e),
353
+ )
354
+ yield error_result
355
+
356
+ async def aexecute(
357
+ self,
358
+ step_input: StepInput,
359
+ session_id: Optional[str] = None,
360
+ user_id: Optional[str] = None,
361
+ workflow_run_response: Optional[WorkflowRunOutput] = None,
362
+ run_context: Optional[RunContext] = None,
363
+ session_state: Optional[Dict[str, Any]] = None,
364
+ store_executor_outputs: bool = True,
365
+ workflow_session: Optional[WorkflowSession] = None,
366
+ add_workflow_history_to_steps: Optional[bool] = False,
367
+ num_history_runs: int = 3,
368
+ ) -> StepOutput:
369
+ """Execute all steps in sequence asynchronously and return the final result"""
370
+ log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
371
+
372
+ steps_id = str(uuid4())
373
+
374
+ self._prepare_steps()
375
+
376
+ if not self.steps:
377
+ return StepOutput(step_name=self.name or "Steps", content="No steps to execute")
378
+
379
+ # Track outputs and pass data between steps - following Condition/Router pattern
380
+ all_results: List[StepOutput] = []
381
+ current_step_input = step_input
382
+ steps_step_outputs = {}
383
+
384
+ try:
385
+ for i, step in enumerate(self.steps):
386
+ step_name = getattr(step, "name", f"step_{i + 1}")
387
+ log_debug(f"Steps {self.name}: Executing async step {i + 1}/{len(self.steps)} - {step_name}")
388
+
389
+ # Execute step
390
+ step_output = await step.aexecute( # type: ignore
391
+ current_step_input,
392
+ session_id=session_id,
393
+ user_id=user_id,
394
+ workflow_run_response=workflow_run_response,
395
+ store_executor_outputs=store_executor_outputs,
396
+ run_context=run_context,
397
+ session_state=session_state,
398
+ workflow_session=workflow_session,
399
+ add_workflow_history_to_steps=add_workflow_history_to_steps,
400
+ num_history_runs=num_history_runs,
401
+ )
402
+
403
+ # Handle both single StepOutput and List[StepOutput] (from Loop/Condition/Router steps)
404
+ if isinstance(step_output, list):
405
+ all_results.extend(step_output)
406
+ if step_output:
407
+ steps_step_outputs[step_name] = step_output[-1]
408
+
409
+ if any(output.stop for output in step_output):
410
+ logger.info(f"Early termination requested by step {step_name}")
411
+ break
412
+ else:
413
+ all_results.append(step_output)
414
+ steps_step_outputs[step_name] = step_output
415
+
416
+ if step_output.stop:
417
+ logger.info(f"Early termination requested by step {step_name}")
418
+ break
419
+
420
+ # Update input for next step with proper chaining
421
+ current_step_input = self._update_step_input_from_outputs(
422
+ current_step_input, step_output, steps_step_outputs
423
+ )
424
+
425
+ log_debug(f"Steps End: {self.name} ({len(all_results)} results)", center=True, symbol="-")
426
+
427
+ return StepOutput(
428
+ step_name=self.name,
429
+ step_id=steps_id,
430
+ step_type=StepType.STEPS,
431
+ content=f"Steps {self.name} completed with {len(all_results)} results",
432
+ success=all(result.success for result in all_results) if all_results else True,
433
+ steps=all_results,
434
+ )
435
+
436
+ except Exception as e:
437
+ logger.error(f"Async steps execution failed: {e}")
438
+ return StepOutput(
439
+ step_name=self.name or "Steps",
440
+ content=f"Steps execution failed: {str(e)}",
441
+ success=False,
442
+ error=str(e),
443
+ )
444
+
445
+ async def aexecute_stream(
446
+ self,
447
+ step_input: StepInput,
448
+ workflow_run_response: WorkflowRunOutput,
449
+ run_context: Optional[RunContext] = None,
450
+ session_state: Optional[Dict[str, Any]] = None,
451
+ session_id: Optional[str] = None,
452
+ user_id: Optional[str] = None,
453
+ stream_events: bool = False,
454
+ stream_intermediate_steps: bool = False,
455
+ stream_executor_events: bool = True,
456
+ step_index: Optional[Union[int, tuple]] = None,
457
+ store_executor_outputs: bool = True,
458
+ parent_step_id: Optional[str] = None,
459
+ workflow_session: Optional[WorkflowSession] = None,
460
+ add_workflow_history_to_steps: Optional[bool] = False,
461
+ num_history_runs: int = 3,
462
+ ) -> AsyncIterator[Union[WorkflowRunOutputEvent, TeamRunOutputEvent, RunOutputEvent, StepOutput]]:
463
+ """Execute all steps in sequence with async streaming support"""
464
+ log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
465
+
466
+ steps_id = str(uuid4())
467
+
468
+ self._prepare_steps()
469
+
470
+ # Considering both stream_events and stream_intermediate_steps (deprecated)
471
+ stream_events = stream_events or stream_intermediate_steps
472
+
473
+ if stream_events:
474
+ # Yield steps execution started event
475
+ yield StepsExecutionStartedEvent(
476
+ run_id=workflow_run_response.run_id or "",
477
+ workflow_name=workflow_run_response.workflow_name or "",
478
+ workflow_id=workflow_run_response.workflow_id or "",
479
+ session_id=workflow_run_response.session_id or "",
480
+ step_name=self.name,
481
+ step_index=step_index,
482
+ steps_count=len(self.steps),
483
+ step_id=steps_id,
484
+ parent_step_id=parent_step_id,
485
+ )
486
+
487
+ if not self.steps:
488
+ yield StepOutput(step_name=self.name or "Steps", content="No steps to execute")
489
+ return
490
+
491
+ # Track outputs and pass data between steps - following Condition/Router pattern
492
+ all_results = []
493
+ current_step_input = step_input
494
+ steps_step_outputs = {}
495
+
496
+ try:
497
+ for i, step in enumerate(self.steps):
498
+ step_name = getattr(step, "name", f"step_{i + 1}")
499
+ log_debug(f"Steps {self.name}: Executing async step {i + 1}/{len(self.steps)} - {step_name}")
500
+
501
+ step_outputs_for_step = []
502
+
503
+ if step_index is None or isinstance(step_index, int):
504
+ # Steps is a main step - child steps get x.1, x.2, x.3 format
505
+ child_step_index = (step_index if step_index is not None else 1, i) # Use i, not i+1
506
+ else:
507
+ # Steps is already a child step - child steps get parent.1, parent.2, parent.3
508
+ child_step_index = step_index + (i,) # Extend the tuple
509
+
510
+ # Stream step execution
511
+ async for event in step.aexecute_stream( # type: ignore
512
+ current_step_input,
513
+ session_id=session_id,
514
+ user_id=user_id,
515
+ run_context=run_context,
516
+ session_state=session_state,
517
+ stream_events=stream_events,
518
+ stream_executor_events=stream_executor_events,
519
+ workflow_run_response=workflow_run_response,
520
+ step_index=child_step_index,
521
+ store_executor_outputs=store_executor_outputs,
522
+ parent_step_id=steps_id,
523
+ workflow_session=workflow_session,
524
+ add_workflow_history_to_steps=add_workflow_history_to_steps,
525
+ num_history_runs=num_history_runs,
526
+ ):
527
+ if isinstance(event, StepOutput):
528
+ step_outputs_for_step.append(event)
529
+ all_results.append(event)
530
+ else:
531
+ # Yield other events (streaming content, step events, etc.)
532
+ yield event
533
+
534
+ # Update step outputs tracking and prepare input for next step
535
+ if step_outputs_for_step:
536
+ if len(step_outputs_for_step) == 1:
537
+ steps_step_outputs[step_name] = step_outputs_for_step[0]
538
+
539
+ if step_outputs_for_step[0].stop:
540
+ logger.info(f"Early termination requested by step {step_name}")
541
+ break
542
+
543
+ current_step_input = self._update_step_input_from_outputs(
544
+ current_step_input, step_outputs_for_step[0], steps_step_outputs
545
+ )
546
+ else:
547
+ # Use last output
548
+ steps_step_outputs[step_name] = step_outputs_for_step[-1]
549
+
550
+ if any(output.stop for output in step_outputs_for_step):
551
+ logger.info(f"Early termination requested by step {step_name}")
552
+ break
553
+
554
+ current_step_input = self._update_step_input_from_outputs(
555
+ current_step_input, step_outputs_for_step, steps_step_outputs
556
+ )
557
+
558
+ log_debug(f"Steps End: {self.name} ({len(all_results)} results)", center=True, symbol="-")
559
+ # Yield steps execution completed event
560
+ if stream_events:
561
+ yield StepsExecutionCompletedEvent(
562
+ run_id=workflow_run_response.run_id or "",
563
+ workflow_name=workflow_run_response.workflow_name or "",
564
+ workflow_id=workflow_run_response.workflow_id or "",
565
+ session_id=workflow_run_response.session_id or "",
566
+ step_name=self.name,
567
+ step_index=step_index,
568
+ steps_count=len(self.steps),
569
+ executed_steps=len(all_results),
570
+ step_results=all_results,
571
+ step_id=steps_id,
572
+ parent_step_id=parent_step_id,
573
+ )
574
+
575
+ yield StepOutput(
576
+ step_name=self.name,
577
+ step_id=steps_id,
578
+ step_type=StepType.STEPS,
579
+ content=f"Steps {self.name} completed with {len(all_results)} results",
580
+ success=all(result.success for result in all_results) if all_results else True,
581
+ steps=all_results,
582
+ )
583
+
584
+ except Exception as e:
585
+ logger.error(f"Async steps streaming failed: {e}")
586
+ error_result = StepOutput(
587
+ step_name=self.name or "Steps",
588
+ content=f"Steps execution failed: {str(e)}",
589
+ success=False,
590
+ error=str(e),
591
+ )
592
+ yield error_result