agno 0.1.2__py3-none-any.whl → 2.3.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (723) hide show
  1. agno/__init__.py +8 -0
  2. agno/agent/__init__.py +44 -5
  3. agno/agent/agent.py +10531 -2975
  4. agno/api/agent.py +14 -53
  5. agno/api/api.py +7 -46
  6. agno/api/evals.py +22 -0
  7. agno/api/os.py +17 -0
  8. agno/api/routes.py +6 -25
  9. agno/api/schemas/__init__.py +9 -0
  10. agno/api/schemas/agent.py +6 -9
  11. agno/api/schemas/evals.py +16 -0
  12. agno/api/schemas/os.py +14 -0
  13. agno/api/schemas/team.py +10 -10
  14. agno/api/schemas/utils.py +21 -0
  15. agno/api/schemas/workflows.py +16 -0
  16. agno/api/settings.py +53 -0
  17. agno/api/team.py +22 -26
  18. agno/api/workflow.py +28 -0
  19. agno/cloud/aws/base.py +214 -0
  20. agno/cloud/aws/s3/__init__.py +2 -0
  21. agno/cloud/aws/s3/api_client.py +43 -0
  22. agno/cloud/aws/s3/bucket.py +195 -0
  23. agno/cloud/aws/s3/object.py +57 -0
  24. agno/compression/__init__.py +3 -0
  25. agno/compression/manager.py +247 -0
  26. agno/culture/__init__.py +3 -0
  27. agno/culture/manager.py +956 -0
  28. agno/db/__init__.py +24 -0
  29. agno/db/async_postgres/__init__.py +3 -0
  30. agno/db/base.py +946 -0
  31. agno/db/dynamo/__init__.py +3 -0
  32. agno/db/dynamo/dynamo.py +2781 -0
  33. agno/db/dynamo/schemas.py +442 -0
  34. agno/db/dynamo/utils.py +743 -0
  35. agno/db/firestore/__init__.py +3 -0
  36. agno/db/firestore/firestore.py +2379 -0
  37. agno/db/firestore/schemas.py +181 -0
  38. agno/db/firestore/utils.py +376 -0
  39. agno/db/gcs_json/__init__.py +3 -0
  40. agno/db/gcs_json/gcs_json_db.py +1791 -0
  41. agno/db/gcs_json/utils.py +228 -0
  42. agno/db/in_memory/__init__.py +3 -0
  43. agno/db/in_memory/in_memory_db.py +1312 -0
  44. agno/db/in_memory/utils.py +230 -0
  45. agno/db/json/__init__.py +3 -0
  46. agno/db/json/json_db.py +1777 -0
  47. agno/db/json/utils.py +230 -0
  48. agno/db/migrations/manager.py +199 -0
  49. agno/db/migrations/v1_to_v2.py +635 -0
  50. agno/db/migrations/versions/v2_3_0.py +938 -0
  51. agno/db/mongo/__init__.py +17 -0
  52. agno/db/mongo/async_mongo.py +2760 -0
  53. agno/db/mongo/mongo.py +2597 -0
  54. agno/db/mongo/schemas.py +119 -0
  55. agno/db/mongo/utils.py +276 -0
  56. agno/db/mysql/__init__.py +4 -0
  57. agno/db/mysql/async_mysql.py +2912 -0
  58. agno/db/mysql/mysql.py +2923 -0
  59. agno/db/mysql/schemas.py +186 -0
  60. agno/db/mysql/utils.py +488 -0
  61. agno/db/postgres/__init__.py +4 -0
  62. agno/db/postgres/async_postgres.py +2579 -0
  63. agno/db/postgres/postgres.py +2870 -0
  64. agno/db/postgres/schemas.py +187 -0
  65. agno/db/postgres/utils.py +442 -0
  66. agno/db/redis/__init__.py +3 -0
  67. agno/db/redis/redis.py +2141 -0
  68. agno/db/redis/schemas.py +159 -0
  69. agno/db/redis/utils.py +346 -0
  70. agno/db/schemas/__init__.py +4 -0
  71. agno/db/schemas/culture.py +120 -0
  72. agno/db/schemas/evals.py +34 -0
  73. agno/db/schemas/knowledge.py +40 -0
  74. agno/db/schemas/memory.py +61 -0
  75. agno/db/singlestore/__init__.py +3 -0
  76. agno/db/singlestore/schemas.py +179 -0
  77. agno/db/singlestore/singlestore.py +2877 -0
  78. agno/db/singlestore/utils.py +384 -0
  79. agno/db/sqlite/__init__.py +4 -0
  80. agno/db/sqlite/async_sqlite.py +2911 -0
  81. agno/db/sqlite/schemas.py +181 -0
  82. agno/db/sqlite/sqlite.py +2908 -0
  83. agno/db/sqlite/utils.py +429 -0
  84. agno/db/surrealdb/__init__.py +3 -0
  85. agno/db/surrealdb/metrics.py +292 -0
  86. agno/db/surrealdb/models.py +334 -0
  87. agno/db/surrealdb/queries.py +71 -0
  88. agno/db/surrealdb/surrealdb.py +1908 -0
  89. agno/db/surrealdb/utils.py +147 -0
  90. agno/db/utils.py +118 -0
  91. agno/eval/__init__.py +24 -0
  92. agno/eval/accuracy.py +666 -276
  93. agno/eval/agent_as_judge.py +861 -0
  94. agno/eval/base.py +29 -0
  95. agno/eval/performance.py +779 -0
  96. agno/eval/reliability.py +241 -62
  97. agno/eval/utils.py +120 -0
  98. agno/exceptions.py +143 -1
  99. agno/filters.py +354 -0
  100. agno/guardrails/__init__.py +6 -0
  101. agno/guardrails/base.py +19 -0
  102. agno/guardrails/openai.py +144 -0
  103. agno/guardrails/pii.py +94 -0
  104. agno/guardrails/prompt_injection.py +52 -0
  105. agno/hooks/__init__.py +3 -0
  106. agno/hooks/decorator.py +164 -0
  107. agno/integrations/discord/__init__.py +3 -0
  108. agno/integrations/discord/client.py +203 -0
  109. agno/knowledge/__init__.py +5 -1
  110. agno/{document → knowledge}/chunking/agentic.py +22 -14
  111. agno/{document → knowledge}/chunking/document.py +2 -2
  112. agno/{document → knowledge}/chunking/fixed.py +7 -6
  113. agno/knowledge/chunking/markdown.py +151 -0
  114. agno/{document → knowledge}/chunking/recursive.py +15 -3
  115. agno/knowledge/chunking/row.py +39 -0
  116. agno/knowledge/chunking/semantic.py +91 -0
  117. agno/knowledge/chunking/strategy.py +165 -0
  118. agno/knowledge/content.py +74 -0
  119. agno/knowledge/document/__init__.py +5 -0
  120. agno/{document → knowledge/document}/base.py +12 -2
  121. agno/knowledge/embedder/__init__.py +5 -0
  122. agno/knowledge/embedder/aws_bedrock.py +343 -0
  123. agno/knowledge/embedder/azure_openai.py +210 -0
  124. agno/{embedder → knowledge/embedder}/base.py +8 -0
  125. agno/knowledge/embedder/cohere.py +323 -0
  126. agno/knowledge/embedder/fastembed.py +62 -0
  127. agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
  128. agno/knowledge/embedder/google.py +258 -0
  129. agno/knowledge/embedder/huggingface.py +94 -0
  130. agno/knowledge/embedder/jina.py +182 -0
  131. agno/knowledge/embedder/langdb.py +22 -0
  132. agno/knowledge/embedder/mistral.py +206 -0
  133. agno/knowledge/embedder/nebius.py +13 -0
  134. agno/knowledge/embedder/ollama.py +154 -0
  135. agno/knowledge/embedder/openai.py +195 -0
  136. agno/knowledge/embedder/sentence_transformer.py +63 -0
  137. agno/{embedder → knowledge/embedder}/together.py +1 -1
  138. agno/knowledge/embedder/vllm.py +262 -0
  139. agno/knowledge/embedder/voyageai.py +165 -0
  140. agno/knowledge/knowledge.py +3006 -0
  141. agno/knowledge/reader/__init__.py +7 -0
  142. agno/knowledge/reader/arxiv_reader.py +81 -0
  143. agno/knowledge/reader/base.py +95 -0
  144. agno/knowledge/reader/csv_reader.py +164 -0
  145. agno/knowledge/reader/docx_reader.py +82 -0
  146. agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
  147. agno/knowledge/reader/firecrawl_reader.py +201 -0
  148. agno/knowledge/reader/json_reader.py +88 -0
  149. agno/knowledge/reader/markdown_reader.py +137 -0
  150. agno/knowledge/reader/pdf_reader.py +431 -0
  151. agno/knowledge/reader/pptx_reader.py +101 -0
  152. agno/knowledge/reader/reader_factory.py +313 -0
  153. agno/knowledge/reader/s3_reader.py +89 -0
  154. agno/knowledge/reader/tavily_reader.py +193 -0
  155. agno/knowledge/reader/text_reader.py +127 -0
  156. agno/knowledge/reader/web_search_reader.py +325 -0
  157. agno/knowledge/reader/website_reader.py +455 -0
  158. agno/knowledge/reader/wikipedia_reader.py +91 -0
  159. agno/knowledge/reader/youtube_reader.py +78 -0
  160. agno/knowledge/remote_content/remote_content.py +88 -0
  161. agno/knowledge/reranker/__init__.py +3 -0
  162. agno/{reranker → knowledge/reranker}/base.py +1 -1
  163. agno/{reranker → knowledge/reranker}/cohere.py +2 -2
  164. agno/knowledge/reranker/infinity.py +195 -0
  165. agno/knowledge/reranker/sentence_transformer.py +54 -0
  166. agno/knowledge/types.py +39 -0
  167. agno/knowledge/utils.py +234 -0
  168. agno/media.py +439 -95
  169. agno/memory/__init__.py +16 -3
  170. agno/memory/manager.py +1474 -123
  171. agno/memory/strategies/__init__.py +15 -0
  172. agno/memory/strategies/base.py +66 -0
  173. agno/memory/strategies/summarize.py +196 -0
  174. agno/memory/strategies/types.py +37 -0
  175. agno/models/aimlapi/__init__.py +5 -0
  176. agno/models/aimlapi/aimlapi.py +62 -0
  177. agno/models/anthropic/__init__.py +4 -0
  178. agno/models/anthropic/claude.py +960 -496
  179. agno/models/aws/__init__.py +15 -0
  180. agno/models/aws/bedrock.py +686 -451
  181. agno/models/aws/claude.py +190 -183
  182. agno/models/azure/__init__.py +18 -1
  183. agno/models/azure/ai_foundry.py +489 -0
  184. agno/models/azure/openai_chat.py +89 -40
  185. agno/models/base.py +2477 -550
  186. agno/models/cerebras/__init__.py +12 -0
  187. agno/models/cerebras/cerebras.py +565 -0
  188. agno/models/cerebras/cerebras_openai.py +131 -0
  189. agno/models/cohere/__init__.py +4 -0
  190. agno/models/cohere/chat.py +306 -492
  191. agno/models/cometapi/__init__.py +5 -0
  192. agno/models/cometapi/cometapi.py +74 -0
  193. agno/models/dashscope/__init__.py +5 -0
  194. agno/models/dashscope/dashscope.py +90 -0
  195. agno/models/deepinfra/__init__.py +5 -0
  196. agno/models/deepinfra/deepinfra.py +45 -0
  197. agno/models/deepseek/__init__.py +4 -0
  198. agno/models/deepseek/deepseek.py +110 -9
  199. agno/models/fireworks/__init__.py +4 -0
  200. agno/models/fireworks/fireworks.py +19 -22
  201. agno/models/google/__init__.py +3 -7
  202. agno/models/google/gemini.py +1717 -662
  203. agno/models/google/utils.py +22 -0
  204. agno/models/groq/__init__.py +4 -0
  205. agno/models/groq/groq.py +391 -666
  206. agno/models/huggingface/__init__.py +4 -0
  207. agno/models/huggingface/huggingface.py +266 -538
  208. agno/models/ibm/__init__.py +5 -0
  209. agno/models/ibm/watsonx.py +432 -0
  210. agno/models/internlm/__init__.py +3 -0
  211. agno/models/internlm/internlm.py +20 -3
  212. agno/models/langdb/__init__.py +1 -0
  213. agno/models/langdb/langdb.py +60 -0
  214. agno/models/litellm/__init__.py +14 -0
  215. agno/models/litellm/chat.py +503 -0
  216. agno/models/litellm/litellm_openai.py +42 -0
  217. agno/models/llama_cpp/__init__.py +5 -0
  218. agno/models/llama_cpp/llama_cpp.py +22 -0
  219. agno/models/lmstudio/__init__.py +5 -0
  220. agno/models/lmstudio/lmstudio.py +25 -0
  221. agno/models/message.py +361 -39
  222. agno/models/meta/__init__.py +12 -0
  223. agno/models/meta/llama.py +502 -0
  224. agno/models/meta/llama_openai.py +79 -0
  225. agno/models/metrics.py +120 -0
  226. agno/models/mistral/__init__.py +4 -0
  227. agno/models/mistral/mistral.py +293 -393
  228. agno/models/nebius/__init__.py +3 -0
  229. agno/models/nebius/nebius.py +53 -0
  230. agno/models/nexus/__init__.py +3 -0
  231. agno/models/nexus/nexus.py +22 -0
  232. agno/models/nvidia/__init__.py +4 -0
  233. agno/models/nvidia/nvidia.py +22 -3
  234. agno/models/ollama/__init__.py +4 -2
  235. agno/models/ollama/chat.py +257 -492
  236. agno/models/openai/__init__.py +7 -0
  237. agno/models/openai/chat.py +725 -770
  238. agno/models/openai/like.py +16 -2
  239. agno/models/openai/responses.py +1121 -0
  240. agno/models/openrouter/__init__.py +4 -0
  241. agno/models/openrouter/openrouter.py +62 -5
  242. agno/models/perplexity/__init__.py +5 -0
  243. agno/models/perplexity/perplexity.py +203 -0
  244. agno/models/portkey/__init__.py +3 -0
  245. agno/models/portkey/portkey.py +82 -0
  246. agno/models/requesty/__init__.py +5 -0
  247. agno/models/requesty/requesty.py +69 -0
  248. agno/models/response.py +177 -7
  249. agno/models/sambanova/__init__.py +4 -0
  250. agno/models/sambanova/sambanova.py +23 -4
  251. agno/models/siliconflow/__init__.py +5 -0
  252. agno/models/siliconflow/siliconflow.py +42 -0
  253. agno/models/together/__init__.py +4 -0
  254. agno/models/together/together.py +21 -164
  255. agno/models/utils.py +266 -0
  256. agno/models/vercel/__init__.py +3 -0
  257. agno/models/vercel/v0.py +43 -0
  258. agno/models/vertexai/__init__.py +0 -1
  259. agno/models/vertexai/claude.py +190 -0
  260. agno/models/vllm/__init__.py +3 -0
  261. agno/models/vllm/vllm.py +83 -0
  262. agno/models/xai/__init__.py +2 -0
  263. agno/models/xai/xai.py +111 -7
  264. agno/os/__init__.py +3 -0
  265. agno/os/app.py +1027 -0
  266. agno/os/auth.py +244 -0
  267. agno/os/config.py +126 -0
  268. agno/os/interfaces/__init__.py +1 -0
  269. agno/os/interfaces/a2a/__init__.py +3 -0
  270. agno/os/interfaces/a2a/a2a.py +42 -0
  271. agno/os/interfaces/a2a/router.py +249 -0
  272. agno/os/interfaces/a2a/utils.py +924 -0
  273. agno/os/interfaces/agui/__init__.py +3 -0
  274. agno/os/interfaces/agui/agui.py +47 -0
  275. agno/os/interfaces/agui/router.py +147 -0
  276. agno/os/interfaces/agui/utils.py +574 -0
  277. agno/os/interfaces/base.py +25 -0
  278. agno/os/interfaces/slack/__init__.py +3 -0
  279. agno/os/interfaces/slack/router.py +148 -0
  280. agno/os/interfaces/slack/security.py +30 -0
  281. agno/os/interfaces/slack/slack.py +47 -0
  282. agno/os/interfaces/whatsapp/__init__.py +3 -0
  283. agno/os/interfaces/whatsapp/router.py +210 -0
  284. agno/os/interfaces/whatsapp/security.py +55 -0
  285. agno/os/interfaces/whatsapp/whatsapp.py +36 -0
  286. agno/os/mcp.py +293 -0
  287. agno/os/middleware/__init__.py +9 -0
  288. agno/os/middleware/jwt.py +797 -0
  289. agno/os/router.py +258 -0
  290. agno/os/routers/__init__.py +3 -0
  291. agno/os/routers/agents/__init__.py +3 -0
  292. agno/os/routers/agents/router.py +599 -0
  293. agno/os/routers/agents/schema.py +261 -0
  294. agno/os/routers/evals/__init__.py +3 -0
  295. agno/os/routers/evals/evals.py +450 -0
  296. agno/os/routers/evals/schemas.py +174 -0
  297. agno/os/routers/evals/utils.py +231 -0
  298. agno/os/routers/health.py +31 -0
  299. agno/os/routers/home.py +52 -0
  300. agno/os/routers/knowledge/__init__.py +3 -0
  301. agno/os/routers/knowledge/knowledge.py +1008 -0
  302. agno/os/routers/knowledge/schemas.py +178 -0
  303. agno/os/routers/memory/__init__.py +3 -0
  304. agno/os/routers/memory/memory.py +661 -0
  305. agno/os/routers/memory/schemas.py +88 -0
  306. agno/os/routers/metrics/__init__.py +3 -0
  307. agno/os/routers/metrics/metrics.py +190 -0
  308. agno/os/routers/metrics/schemas.py +47 -0
  309. agno/os/routers/session/__init__.py +3 -0
  310. agno/os/routers/session/session.py +997 -0
  311. agno/os/routers/teams/__init__.py +3 -0
  312. agno/os/routers/teams/router.py +512 -0
  313. agno/os/routers/teams/schema.py +257 -0
  314. agno/os/routers/traces/__init__.py +3 -0
  315. agno/os/routers/traces/schemas.py +414 -0
  316. agno/os/routers/traces/traces.py +499 -0
  317. agno/os/routers/workflows/__init__.py +3 -0
  318. agno/os/routers/workflows/router.py +624 -0
  319. agno/os/routers/workflows/schema.py +75 -0
  320. agno/os/schema.py +534 -0
  321. agno/os/scopes.py +469 -0
  322. agno/{playground → os}/settings.py +7 -15
  323. agno/os/utils.py +973 -0
  324. agno/reasoning/anthropic.py +80 -0
  325. agno/reasoning/azure_ai_foundry.py +67 -0
  326. agno/reasoning/deepseek.py +63 -0
  327. agno/reasoning/default.py +97 -0
  328. agno/reasoning/gemini.py +73 -0
  329. agno/reasoning/groq.py +71 -0
  330. agno/reasoning/helpers.py +24 -1
  331. agno/reasoning/ollama.py +67 -0
  332. agno/reasoning/openai.py +86 -0
  333. agno/reasoning/step.py +2 -1
  334. agno/reasoning/vertexai.py +76 -0
  335. agno/run/__init__.py +6 -0
  336. agno/run/agent.py +822 -0
  337. agno/run/base.py +247 -0
  338. agno/run/cancel.py +81 -0
  339. agno/run/requirement.py +181 -0
  340. agno/run/team.py +767 -0
  341. agno/run/workflow.py +708 -0
  342. agno/session/__init__.py +10 -0
  343. agno/session/agent.py +260 -0
  344. agno/session/summary.py +265 -0
  345. agno/session/team.py +342 -0
  346. agno/session/workflow.py +501 -0
  347. agno/table.py +10 -0
  348. agno/team/__init__.py +37 -0
  349. agno/team/team.py +9536 -0
  350. agno/tools/__init__.py +7 -0
  351. agno/tools/agentql.py +120 -0
  352. agno/tools/airflow.py +22 -12
  353. agno/tools/api.py +122 -0
  354. agno/tools/apify.py +276 -83
  355. agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
  356. agno/tools/aws_lambda.py +28 -7
  357. agno/tools/aws_ses.py +66 -0
  358. agno/tools/baidusearch.py +11 -4
  359. agno/tools/bitbucket.py +292 -0
  360. agno/tools/brandfetch.py +213 -0
  361. agno/tools/bravesearch.py +106 -0
  362. agno/tools/brightdata.py +367 -0
  363. agno/tools/browserbase.py +209 -0
  364. agno/tools/calcom.py +32 -23
  365. agno/tools/calculator.py +24 -37
  366. agno/tools/cartesia.py +187 -0
  367. agno/tools/{clickup_tool.py → clickup.py} +17 -28
  368. agno/tools/confluence.py +91 -26
  369. agno/tools/crawl4ai.py +139 -43
  370. agno/tools/csv_toolkit.py +28 -22
  371. agno/tools/dalle.py +36 -22
  372. agno/tools/daytona.py +475 -0
  373. agno/tools/decorator.py +169 -14
  374. agno/tools/desi_vocal.py +23 -11
  375. agno/tools/discord.py +32 -29
  376. agno/tools/docker.py +716 -0
  377. agno/tools/duckdb.py +76 -81
  378. agno/tools/duckduckgo.py +43 -40
  379. agno/tools/e2b.py +703 -0
  380. agno/tools/eleven_labs.py +65 -54
  381. agno/tools/email.py +13 -5
  382. agno/tools/evm.py +129 -0
  383. agno/tools/exa.py +324 -42
  384. agno/tools/fal.py +39 -35
  385. agno/tools/file.py +196 -30
  386. agno/tools/file_generation.py +356 -0
  387. agno/tools/financial_datasets.py +288 -0
  388. agno/tools/firecrawl.py +108 -33
  389. agno/tools/function.py +960 -122
  390. agno/tools/giphy.py +34 -12
  391. agno/tools/github.py +1294 -97
  392. agno/tools/gmail.py +922 -0
  393. agno/tools/google_bigquery.py +117 -0
  394. agno/tools/google_drive.py +271 -0
  395. agno/tools/google_maps.py +253 -0
  396. agno/tools/googlecalendar.py +607 -107
  397. agno/tools/googlesheets.py +377 -0
  398. agno/tools/hackernews.py +20 -12
  399. agno/tools/jina.py +24 -14
  400. agno/tools/jira.py +48 -19
  401. agno/tools/knowledge.py +218 -0
  402. agno/tools/linear.py +82 -43
  403. agno/tools/linkup.py +58 -0
  404. agno/tools/local_file_system.py +15 -7
  405. agno/tools/lumalab.py +41 -26
  406. agno/tools/mcp/__init__.py +10 -0
  407. agno/tools/mcp/mcp.py +331 -0
  408. agno/tools/mcp/multi_mcp.py +347 -0
  409. agno/tools/mcp/params.py +24 -0
  410. agno/tools/mcp_toolbox.py +284 -0
  411. agno/tools/mem0.py +193 -0
  412. agno/tools/memory.py +419 -0
  413. agno/tools/mlx_transcribe.py +11 -9
  414. agno/tools/models/azure_openai.py +190 -0
  415. agno/tools/models/gemini.py +203 -0
  416. agno/tools/models/groq.py +158 -0
  417. agno/tools/models/morph.py +186 -0
  418. agno/tools/models/nebius.py +124 -0
  419. agno/tools/models_labs.py +163 -82
  420. agno/tools/moviepy_video.py +18 -13
  421. agno/tools/nano_banana.py +151 -0
  422. agno/tools/neo4j.py +134 -0
  423. agno/tools/newspaper.py +15 -4
  424. agno/tools/newspaper4k.py +19 -6
  425. agno/tools/notion.py +204 -0
  426. agno/tools/openai.py +181 -17
  427. agno/tools/openbb.py +27 -20
  428. agno/tools/opencv.py +321 -0
  429. agno/tools/openweather.py +233 -0
  430. agno/tools/oxylabs.py +385 -0
  431. agno/tools/pandas.py +25 -15
  432. agno/tools/parallel.py +314 -0
  433. agno/tools/postgres.py +238 -185
  434. agno/tools/pubmed.py +125 -13
  435. agno/tools/python.py +48 -35
  436. agno/tools/reasoning.py +283 -0
  437. agno/tools/reddit.py +207 -29
  438. agno/tools/redshift.py +406 -0
  439. agno/tools/replicate.py +69 -26
  440. agno/tools/resend.py +11 -6
  441. agno/tools/scrapegraph.py +179 -19
  442. agno/tools/searxng.py +23 -31
  443. agno/tools/serpapi.py +15 -10
  444. agno/tools/serper.py +255 -0
  445. agno/tools/shell.py +23 -12
  446. agno/tools/shopify.py +1519 -0
  447. agno/tools/slack.py +56 -14
  448. agno/tools/sleep.py +8 -6
  449. agno/tools/spider.py +35 -11
  450. agno/tools/spotify.py +919 -0
  451. agno/tools/sql.py +34 -19
  452. agno/tools/tavily.py +158 -8
  453. agno/tools/telegram.py +18 -8
  454. agno/tools/todoist.py +218 -0
  455. agno/tools/toolkit.py +134 -9
  456. agno/tools/trafilatura.py +388 -0
  457. agno/tools/trello.py +25 -28
  458. agno/tools/twilio.py +18 -9
  459. agno/tools/user_control_flow.py +78 -0
  460. agno/tools/valyu.py +228 -0
  461. agno/tools/visualization.py +467 -0
  462. agno/tools/webbrowser.py +28 -0
  463. agno/tools/webex.py +76 -0
  464. agno/tools/website.py +23 -19
  465. agno/tools/webtools.py +45 -0
  466. agno/tools/whatsapp.py +286 -0
  467. agno/tools/wikipedia.py +28 -19
  468. agno/tools/workflow.py +285 -0
  469. agno/tools/{twitter.py → x.py} +142 -46
  470. agno/tools/yfinance.py +41 -39
  471. agno/tools/youtube.py +34 -17
  472. agno/tools/zendesk.py +15 -5
  473. agno/tools/zep.py +454 -0
  474. agno/tools/zoom.py +86 -37
  475. agno/tracing/__init__.py +12 -0
  476. agno/tracing/exporter.py +157 -0
  477. agno/tracing/schemas.py +276 -0
  478. agno/tracing/setup.py +111 -0
  479. agno/utils/agent.py +938 -0
  480. agno/utils/audio.py +37 -1
  481. agno/utils/certs.py +27 -0
  482. agno/utils/code_execution.py +11 -0
  483. agno/utils/common.py +103 -20
  484. agno/utils/cryptography.py +22 -0
  485. agno/utils/dttm.py +33 -0
  486. agno/utils/events.py +700 -0
  487. agno/utils/functions.py +107 -37
  488. agno/utils/gemini.py +426 -0
  489. agno/utils/hooks.py +171 -0
  490. agno/utils/http.py +185 -0
  491. agno/utils/json_schema.py +159 -37
  492. agno/utils/knowledge.py +36 -0
  493. agno/utils/location.py +19 -0
  494. agno/utils/log.py +221 -8
  495. agno/utils/mcp.py +214 -0
  496. agno/utils/media.py +335 -14
  497. agno/utils/merge_dict.py +22 -1
  498. agno/utils/message.py +77 -2
  499. agno/utils/models/ai_foundry.py +50 -0
  500. agno/utils/models/claude.py +373 -0
  501. agno/utils/models/cohere.py +94 -0
  502. agno/utils/models/llama.py +85 -0
  503. agno/utils/models/mistral.py +100 -0
  504. agno/utils/models/openai_responses.py +140 -0
  505. agno/utils/models/schema_utils.py +153 -0
  506. agno/utils/models/watsonx.py +41 -0
  507. agno/utils/openai.py +257 -0
  508. agno/utils/pickle.py +1 -1
  509. agno/utils/pprint.py +124 -8
  510. agno/utils/print_response/agent.py +930 -0
  511. agno/utils/print_response/team.py +1914 -0
  512. agno/utils/print_response/workflow.py +1668 -0
  513. agno/utils/prompts.py +111 -0
  514. agno/utils/reasoning.py +108 -0
  515. agno/utils/response.py +163 -0
  516. agno/utils/serialize.py +32 -0
  517. agno/utils/shell.py +4 -4
  518. agno/utils/streamlit.py +487 -0
  519. agno/utils/string.py +204 -51
  520. agno/utils/team.py +139 -0
  521. agno/utils/timer.py +9 -2
  522. agno/utils/tokens.py +657 -0
  523. agno/utils/tools.py +19 -1
  524. agno/utils/whatsapp.py +305 -0
  525. agno/utils/yaml_io.py +3 -3
  526. agno/vectordb/__init__.py +2 -0
  527. agno/vectordb/base.py +87 -9
  528. agno/vectordb/cassandra/__init__.py +5 -1
  529. agno/vectordb/cassandra/cassandra.py +383 -27
  530. agno/vectordb/chroma/__init__.py +4 -0
  531. agno/vectordb/chroma/chromadb.py +748 -83
  532. agno/vectordb/clickhouse/__init__.py +7 -1
  533. agno/vectordb/clickhouse/clickhousedb.py +554 -53
  534. agno/vectordb/couchbase/__init__.py +3 -0
  535. agno/vectordb/couchbase/couchbase.py +1446 -0
  536. agno/vectordb/lancedb/__init__.py +5 -0
  537. agno/vectordb/lancedb/lance_db.py +730 -98
  538. agno/vectordb/langchaindb/__init__.py +5 -0
  539. agno/vectordb/langchaindb/langchaindb.py +163 -0
  540. agno/vectordb/lightrag/__init__.py +5 -0
  541. agno/vectordb/lightrag/lightrag.py +388 -0
  542. agno/vectordb/llamaindex/__init__.py +3 -0
  543. agno/vectordb/llamaindex/llamaindexdb.py +166 -0
  544. agno/vectordb/milvus/__init__.py +3 -0
  545. agno/vectordb/milvus/milvus.py +966 -78
  546. agno/vectordb/mongodb/__init__.py +9 -1
  547. agno/vectordb/mongodb/mongodb.py +1175 -172
  548. agno/vectordb/pgvector/__init__.py +8 -0
  549. agno/vectordb/pgvector/pgvector.py +599 -115
  550. agno/vectordb/pineconedb/__init__.py +5 -1
  551. agno/vectordb/pineconedb/pineconedb.py +406 -43
  552. agno/vectordb/qdrant/__init__.py +4 -0
  553. agno/vectordb/qdrant/qdrant.py +914 -61
  554. agno/vectordb/redis/__init__.py +9 -0
  555. agno/vectordb/redis/redisdb.py +682 -0
  556. agno/vectordb/singlestore/__init__.py +8 -1
  557. agno/vectordb/singlestore/singlestore.py +771 -0
  558. agno/vectordb/surrealdb/__init__.py +3 -0
  559. agno/vectordb/surrealdb/surrealdb.py +663 -0
  560. agno/vectordb/upstashdb/__init__.py +5 -0
  561. agno/vectordb/upstashdb/upstashdb.py +718 -0
  562. agno/vectordb/weaviate/__init__.py +8 -0
  563. agno/vectordb/weaviate/index.py +15 -0
  564. agno/vectordb/weaviate/weaviate.py +1009 -0
  565. agno/workflow/__init__.py +23 -1
  566. agno/workflow/agent.py +299 -0
  567. agno/workflow/condition.py +759 -0
  568. agno/workflow/loop.py +756 -0
  569. agno/workflow/parallel.py +853 -0
  570. agno/workflow/router.py +723 -0
  571. agno/workflow/step.py +1564 -0
  572. agno/workflow/steps.py +613 -0
  573. agno/workflow/types.py +556 -0
  574. agno/workflow/workflow.py +4327 -514
  575. agno-2.3.13.dist-info/METADATA +639 -0
  576. agno-2.3.13.dist-info/RECORD +613 -0
  577. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
  578. agno-2.3.13.dist-info/licenses/LICENSE +201 -0
  579. agno/api/playground.py +0 -91
  580. agno/api/schemas/playground.py +0 -22
  581. agno/api/schemas/user.py +0 -22
  582. agno/api/schemas/workspace.py +0 -46
  583. agno/api/user.py +0 -160
  584. agno/api/workspace.py +0 -151
  585. agno/cli/auth_server.py +0 -118
  586. agno/cli/config.py +0 -275
  587. agno/cli/console.py +0 -88
  588. agno/cli/credentials.py +0 -23
  589. agno/cli/entrypoint.py +0 -571
  590. agno/cli/operator.py +0 -355
  591. agno/cli/settings.py +0 -85
  592. agno/cli/ws/ws_cli.py +0 -817
  593. agno/constants.py +0 -13
  594. agno/document/__init__.py +0 -1
  595. agno/document/chunking/semantic.py +0 -47
  596. agno/document/chunking/strategy.py +0 -31
  597. agno/document/reader/__init__.py +0 -1
  598. agno/document/reader/arxiv_reader.py +0 -41
  599. agno/document/reader/base.py +0 -22
  600. agno/document/reader/csv_reader.py +0 -84
  601. agno/document/reader/docx_reader.py +0 -46
  602. agno/document/reader/firecrawl_reader.py +0 -99
  603. agno/document/reader/json_reader.py +0 -43
  604. agno/document/reader/pdf_reader.py +0 -219
  605. agno/document/reader/s3/pdf_reader.py +0 -46
  606. agno/document/reader/s3/text_reader.py +0 -51
  607. agno/document/reader/text_reader.py +0 -41
  608. agno/document/reader/website_reader.py +0 -175
  609. agno/document/reader/youtube_reader.py +0 -50
  610. agno/embedder/__init__.py +0 -1
  611. agno/embedder/azure_openai.py +0 -86
  612. agno/embedder/cohere.py +0 -72
  613. agno/embedder/fastembed.py +0 -37
  614. agno/embedder/google.py +0 -73
  615. agno/embedder/huggingface.py +0 -54
  616. agno/embedder/mistral.py +0 -80
  617. agno/embedder/ollama.py +0 -57
  618. agno/embedder/openai.py +0 -74
  619. agno/embedder/sentence_transformer.py +0 -38
  620. agno/embedder/voyageai.py +0 -64
  621. agno/eval/perf.py +0 -201
  622. agno/file/__init__.py +0 -1
  623. agno/file/file.py +0 -16
  624. agno/file/local/csv.py +0 -32
  625. agno/file/local/txt.py +0 -19
  626. agno/infra/app.py +0 -240
  627. agno/infra/base.py +0 -144
  628. agno/infra/context.py +0 -20
  629. agno/infra/db_app.py +0 -52
  630. agno/infra/resource.py +0 -205
  631. agno/infra/resources.py +0 -55
  632. agno/knowledge/agent.py +0 -230
  633. agno/knowledge/arxiv.py +0 -22
  634. agno/knowledge/combined.py +0 -22
  635. agno/knowledge/csv.py +0 -28
  636. agno/knowledge/csv_url.py +0 -19
  637. agno/knowledge/document.py +0 -20
  638. agno/knowledge/docx.py +0 -30
  639. agno/knowledge/json.py +0 -28
  640. agno/knowledge/langchain.py +0 -71
  641. agno/knowledge/llamaindex.py +0 -66
  642. agno/knowledge/pdf.py +0 -28
  643. agno/knowledge/pdf_url.py +0 -26
  644. agno/knowledge/s3/base.py +0 -60
  645. agno/knowledge/s3/pdf.py +0 -21
  646. agno/knowledge/s3/text.py +0 -23
  647. agno/knowledge/text.py +0 -30
  648. agno/knowledge/website.py +0 -88
  649. agno/knowledge/wikipedia.py +0 -31
  650. agno/knowledge/youtube.py +0 -22
  651. agno/memory/agent.py +0 -392
  652. agno/memory/classifier.py +0 -104
  653. agno/memory/db/__init__.py +0 -1
  654. agno/memory/db/base.py +0 -42
  655. agno/memory/db/mongodb.py +0 -189
  656. agno/memory/db/postgres.py +0 -203
  657. agno/memory/db/sqlite.py +0 -193
  658. agno/memory/memory.py +0 -15
  659. agno/memory/row.py +0 -36
  660. agno/memory/summarizer.py +0 -192
  661. agno/memory/summary.py +0 -19
  662. agno/memory/workflow.py +0 -38
  663. agno/models/google/gemini_openai.py +0 -26
  664. agno/models/ollama/hermes.py +0 -221
  665. agno/models/ollama/tools.py +0 -362
  666. agno/models/vertexai/gemini.py +0 -595
  667. agno/playground/__init__.py +0 -3
  668. agno/playground/async_router.py +0 -421
  669. agno/playground/deploy.py +0 -249
  670. agno/playground/operator.py +0 -92
  671. agno/playground/playground.py +0 -91
  672. agno/playground/schemas.py +0 -76
  673. agno/playground/serve.py +0 -55
  674. agno/playground/sync_router.py +0 -405
  675. agno/reasoning/agent.py +0 -68
  676. agno/run/response.py +0 -112
  677. agno/storage/agent/__init__.py +0 -0
  678. agno/storage/agent/base.py +0 -38
  679. agno/storage/agent/dynamodb.py +0 -350
  680. agno/storage/agent/json.py +0 -92
  681. agno/storage/agent/mongodb.py +0 -228
  682. agno/storage/agent/postgres.py +0 -367
  683. agno/storage/agent/session.py +0 -79
  684. agno/storage/agent/singlestore.py +0 -303
  685. agno/storage/agent/sqlite.py +0 -357
  686. agno/storage/agent/yaml.py +0 -93
  687. agno/storage/workflow/__init__.py +0 -0
  688. agno/storage/workflow/base.py +0 -40
  689. agno/storage/workflow/mongodb.py +0 -233
  690. agno/storage/workflow/postgres.py +0 -366
  691. agno/storage/workflow/session.py +0 -60
  692. agno/storage/workflow/sqlite.py +0 -359
  693. agno/tools/googlesearch.py +0 -88
  694. agno/utils/defaults.py +0 -57
  695. agno/utils/filesystem.py +0 -39
  696. agno/utils/git.py +0 -52
  697. agno/utils/json_io.py +0 -30
  698. agno/utils/load_env.py +0 -19
  699. agno/utils/py_io.py +0 -19
  700. agno/utils/pyproject.py +0 -18
  701. agno/utils/resource_filter.py +0 -31
  702. agno/vectordb/singlestore/s2vectordb.py +0 -390
  703. agno/vectordb/singlestore/s2vectordb2.py +0 -355
  704. agno/workspace/__init__.py +0 -0
  705. agno/workspace/config.py +0 -325
  706. agno/workspace/enums.py +0 -6
  707. agno/workspace/helpers.py +0 -48
  708. agno/workspace/operator.py +0 -758
  709. agno/workspace/settings.py +0 -63
  710. agno-0.1.2.dist-info/LICENSE +0 -375
  711. agno-0.1.2.dist-info/METADATA +0 -502
  712. agno-0.1.2.dist-info/RECORD +0 -352
  713. agno-0.1.2.dist-info/entry_points.txt +0 -3
  714. /agno/{cli → db/migrations}/__init__.py +0 -0
  715. /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
  716. /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
  717. /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
  718. /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
  719. /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
  720. /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
  721. /agno/{reranker → utils/models}/__init__.py +0 -0
  722. /agno/{storage → utils/print_response}/__init__.py +0 -0
  723. {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,759 @@
1
+ import inspect
2
+ import warnings
3
+ from dataclasses import dataclass
4
+ from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
5
+ from uuid import uuid4
6
+
7
+ from agno.run.agent import RunOutputEvent
8
+ from agno.run.base import RunContext
9
+ from agno.run.team import TeamRunOutputEvent
10
+ from agno.run.workflow import (
11
+ ConditionExecutionCompletedEvent,
12
+ ConditionExecutionStartedEvent,
13
+ WorkflowRunOutput,
14
+ WorkflowRunOutputEvent,
15
+ )
16
+ from agno.session.workflow import WorkflowSession
17
+ from agno.utils.log import log_debug, logger
18
+ from agno.workflow.step import Step
19
+ from agno.workflow.types import StepInput, StepOutput, StepType
20
+
21
+ WorkflowSteps = List[
22
+ Union[
23
+ Callable[
24
+ [StepInput], Union[StepOutput, Awaitable[StepOutput], Iterator[StepOutput], AsyncIterator[StepOutput]]
25
+ ],
26
+ Step,
27
+ "Steps", # type: ignore # noqa: F821
28
+ "Loop", # type: ignore # noqa: F821
29
+ "Parallel", # type: ignore # noqa: F821
30
+ "Condition", # type: ignore # noqa: F821
31
+ "Router", # type: ignore # noqa: F821
32
+ ]
33
+ ]
34
+
35
+
36
+ @dataclass
37
+ class Condition:
38
+ """A condition that executes a step (or list of steps) if the condition is met"""
39
+
40
+ # Evaluator should only return boolean
41
+ evaluator: Union[
42
+ Callable[[StepInput], bool],
43
+ Callable[[StepInput], Awaitable[bool]],
44
+ bool,
45
+ ]
46
+ steps: WorkflowSteps
47
+
48
+ name: Optional[str] = None
49
+ description: Optional[str] = None
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.loop import Loop
56
+ from agno.workflow.parallel import Parallel
57
+ from agno.workflow.router import Router
58
+ from agno.workflow.step import Step
59
+ from agno.workflow.steps import Steps
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
+ condition_step_outputs: Optional[Dict[str, StepOutput]] = None,
81
+ ) -> StepInput:
82
+ """Helper to update step input from step outputs - mirrors Loop 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
+ all_images = sum([out.images or [] for out in step_outputs], [])
89
+ all_videos = sum([out.videos or [] for out in step_outputs], [])
90
+ all_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
+ all_images = step_outputs.images or []
96
+ all_videos = step_outputs.videos or []
97
+ all_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 condition_step_outputs:
104
+ updated_previous_step_outputs.update(condition_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 + all_images,
112
+ videos=current_videos + all_videos,
113
+ audio=current_audio + all_audio,
114
+ )
115
+
116
+ def _evaluate_condition(self, step_input: StepInput, session_state: Optional[Dict[str, Any]] = None) -> bool:
117
+ """Evaluate the condition and return boolean result"""
118
+ if isinstance(self.evaluator, bool):
119
+ return self.evaluator
120
+
121
+ if callable(self.evaluator):
122
+ if session_state is not None and self._evaluator_has_session_state_param():
123
+ result = self.evaluator(step_input, session_state=session_state) # type: ignore[call-arg]
124
+ else:
125
+ result = self.evaluator(step_input)
126
+
127
+ if isinstance(result, bool):
128
+ return result
129
+ else:
130
+ logger.warning(f"Condition evaluator returned unexpected type: {type(result)}, expected bool")
131
+ return False
132
+
133
+ return False
134
+
135
+ async def _aevaluate_condition(self, step_input: StepInput, session_state: Optional[Dict[str, Any]] = None) -> bool:
136
+ """Async version of condition evaluation"""
137
+ if isinstance(self.evaluator, bool):
138
+ return self.evaluator
139
+
140
+ if callable(self.evaluator):
141
+ has_session_state = session_state is not None and self._evaluator_has_session_state_param()
142
+
143
+ if inspect.iscoroutinefunction(self.evaluator):
144
+ if has_session_state:
145
+ result = await self.evaluator(step_input, session_state=session_state) # type: ignore[call-arg]
146
+ else:
147
+ result = await self.evaluator(step_input)
148
+ else:
149
+ if has_session_state:
150
+ result = self.evaluator(step_input, session_state=session_state) # type: ignore[call-arg]
151
+ else:
152
+ result = self.evaluator(step_input)
153
+
154
+ if isinstance(result, bool):
155
+ return result
156
+ else:
157
+ logger.warning(f"Condition evaluator returned unexpected type: {type(result)}, expected bool")
158
+ return False
159
+
160
+ return False
161
+
162
+ def _evaluator_has_session_state_param(self) -> bool:
163
+ """Check if the evaluator function has a session_state parameter"""
164
+ if not callable(self.evaluator):
165
+ return False
166
+
167
+ try:
168
+ sig = inspect.signature(self.evaluator)
169
+ return "session_state" in sig.parameters
170
+ except Exception:
171
+ return False
172
+
173
+ def execute(
174
+ self,
175
+ step_input: StepInput,
176
+ session_id: Optional[str] = None,
177
+ user_id: Optional[str] = None,
178
+ workflow_run_response: Optional[WorkflowRunOutput] = None,
179
+ store_executor_outputs: bool = True,
180
+ run_context: Optional[RunContext] = None,
181
+ session_state: Optional[Dict[str, Any]] = None,
182
+ workflow_session: Optional[WorkflowSession] = None,
183
+ add_workflow_history_to_steps: Optional[bool] = False,
184
+ num_history_runs: int = 3,
185
+ background_tasks: Optional[Any] = None,
186
+ ) -> StepOutput:
187
+ """Execute the condition and its steps with sequential chaining if condition is true"""
188
+ log_debug(f"Condition Start: {self.name}", center=True, symbol="-")
189
+
190
+ conditional_step_id = str(uuid4())
191
+
192
+ self._prepare_steps()
193
+
194
+ # Evaluate the condition
195
+ if run_context is not None and run_context.session_state is not None:
196
+ condition_result = self._evaluate_condition(step_input, session_state=run_context.session_state)
197
+ else:
198
+ condition_result = self._evaluate_condition(step_input, session_state=session_state)
199
+
200
+ log_debug(f"Condition {self.name} evaluated to: {condition_result}")
201
+
202
+ if not condition_result:
203
+ log_debug(f"Condition {self.name} not met, skipping {len(self.steps)} steps")
204
+ return StepOutput(
205
+ step_name=self.name,
206
+ step_id=conditional_step_id,
207
+ step_type=StepType.CONDITION,
208
+ content=f"Condition {self.name} not met - skipped {len(self.steps)} steps",
209
+ success=True,
210
+ )
211
+
212
+ log_debug(f"Condition {self.name} met, executing {len(self.steps)} steps")
213
+ all_results: List[StepOutput] = []
214
+ current_step_input = step_input
215
+ condition_step_outputs = {}
216
+
217
+ for i, step in enumerate(self.steps):
218
+ try:
219
+ step_output = step.execute( # type: ignore[union-attr]
220
+ current_step_input,
221
+ session_id=session_id,
222
+ user_id=user_id,
223
+ workflow_run_response=workflow_run_response,
224
+ store_executor_outputs=store_executor_outputs,
225
+ run_context=run_context,
226
+ session_state=session_state,
227
+ workflow_session=workflow_session,
228
+ add_workflow_history_to_steps=add_workflow_history_to_steps,
229
+ num_history_runs=num_history_runs,
230
+ background_tasks=background_tasks,
231
+ )
232
+
233
+ # Handle both single StepOutput and List[StepOutput] (from Loop/Condition/Router steps)
234
+ if isinstance(step_output, list):
235
+ all_results.extend(step_output)
236
+ if step_output:
237
+ step_name = getattr(step, "name", f"step_{i}")
238
+ log_debug(f"Executing condition step {i + 1}/{len(self.steps)}: {step_name}")
239
+
240
+ condition_step_outputs[step_name] = step_output[-1]
241
+
242
+ if any(output.stop for output in step_output):
243
+ logger.info(f"Early termination requested by condition step {step_name}")
244
+ break
245
+ else:
246
+ all_results.append(step_output)
247
+ step_name = getattr(step, "name", f"step_{i}")
248
+ condition_step_outputs[step_name] = step_output
249
+
250
+ if step_output.stop:
251
+ logger.info(f"Early termination requested by condition step {step_name}")
252
+ break
253
+
254
+ step_name = getattr(step, "name", f"step_{i}")
255
+ log_debug(f"Condition step {step_name} completed")
256
+
257
+ current_step_input = self._update_step_input_from_outputs(
258
+ current_step_input, step_output, condition_step_outputs
259
+ )
260
+
261
+ except Exception as e:
262
+ step_name = getattr(step, "name", f"step_{i}")
263
+ logger.error(f"Condition step {step_name} failed: {e}")
264
+ error_output = StepOutput(
265
+ step_name=step_name,
266
+ content=f"Step {step_name} failed: {str(e)}",
267
+ success=False,
268
+ error=str(e),
269
+ )
270
+ all_results.append(error_output)
271
+ break
272
+
273
+ log_debug(f"Condition End: {self.name} ({len(all_results)} results)", center=True, symbol="-")
274
+
275
+ return StepOutput(
276
+ step_name=self.name,
277
+ step_id=conditional_step_id,
278
+ step_type=StepType.CONDITION,
279
+ content=f"Condition {self.name} completed with {len(all_results)} results",
280
+ success=all(result.success for result in all_results) if all_results else True,
281
+ error=None,
282
+ stop=False,
283
+ steps=all_results,
284
+ )
285
+
286
+ def execute_stream(
287
+ self,
288
+ step_input: StepInput,
289
+ session_id: Optional[str] = None,
290
+ user_id: Optional[str] = None,
291
+ stream_events: bool = False,
292
+ stream_intermediate_steps: bool = False, # type: ignore
293
+ stream_executor_events: bool = True,
294
+ workflow_run_response: Optional[WorkflowRunOutput] = None,
295
+ step_index: Optional[Union[int, tuple]] = None,
296
+ store_executor_outputs: bool = True,
297
+ run_context: Optional[RunContext] = None,
298
+ session_state: Optional[Dict[str, Any]] = None,
299
+ parent_step_id: Optional[str] = None,
300
+ workflow_session: Optional[WorkflowSession] = None,
301
+ add_workflow_history_to_steps: Optional[bool] = False,
302
+ num_history_runs: int = 3,
303
+ background_tasks: Optional[Any] = None,
304
+ ) -> Iterator[Union[WorkflowRunOutputEvent, StepOutput]]:
305
+ """Execute the condition with streaming support - mirrors Loop logic"""
306
+ log_debug(f"Condition Start: {self.name}", center=True, symbol="-")
307
+
308
+ conditional_step_id = str(uuid4())
309
+
310
+ self._prepare_steps()
311
+
312
+ # Evaluate the condition
313
+ if run_context is not None and run_context.session_state is not None:
314
+ condition_result = self._evaluate_condition(step_input, session_state=run_context.session_state)
315
+ else:
316
+ condition_result = self._evaluate_condition(step_input, session_state=session_state)
317
+ log_debug(f"Condition {self.name} evaluated to: {condition_result}")
318
+
319
+ # Considering both stream_events and stream_intermediate_steps (deprecated)
320
+ if stream_intermediate_steps is not None:
321
+ warnings.warn(
322
+ "The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
323
+ DeprecationWarning,
324
+ stacklevel=2,
325
+ )
326
+ stream_events = stream_events or stream_intermediate_steps
327
+
328
+ if stream_events and workflow_run_response:
329
+ # Yield condition started event
330
+ yield ConditionExecutionStartedEvent(
331
+ run_id=workflow_run_response.run_id or "",
332
+ workflow_name=workflow_run_response.workflow_name or "",
333
+ workflow_id=workflow_run_response.workflow_id or "",
334
+ session_id=workflow_run_response.session_id or "",
335
+ step_name=self.name,
336
+ step_index=step_index,
337
+ condition_result=condition_result,
338
+ step_id=conditional_step_id,
339
+ parent_step_id=parent_step_id,
340
+ )
341
+
342
+ if not condition_result:
343
+ if stream_events and workflow_run_response:
344
+ # Yield condition completed event for empty case
345
+ yield ConditionExecutionCompletedEvent(
346
+ run_id=workflow_run_response.run_id or "",
347
+ workflow_name=workflow_run_response.workflow_name or "",
348
+ workflow_id=workflow_run_response.workflow_id or "",
349
+ session_id=workflow_run_response.session_id or "",
350
+ step_name=self.name,
351
+ step_index=step_index,
352
+ condition_result=False,
353
+ executed_steps=0,
354
+ step_results=[],
355
+ step_id=conditional_step_id,
356
+ parent_step_id=parent_step_id,
357
+ )
358
+ return
359
+
360
+ log_debug(f"Condition {self.name} met, executing {len(self.steps)} steps")
361
+ all_results = []
362
+ current_step_input = step_input
363
+ condition_step_outputs = {}
364
+
365
+ for i, step in enumerate(self.steps):
366
+ try:
367
+ step_outputs_for_step = []
368
+
369
+ # Create child index for each step within condition
370
+ if step_index is None or isinstance(step_index, int):
371
+ # Condition is a main step - child steps get x.1, x.2, x.3 format
372
+ child_step_index = (step_index if step_index is not None else 1, i)
373
+ else:
374
+ # Condition is already a child step - child steps get same parent number: x.y, x.y, x.y
375
+ child_step_index = step_index
376
+
377
+ # Stream step execution
378
+ for event in step.execute_stream( # type: ignore[union-attr]
379
+ current_step_input,
380
+ session_id=session_id,
381
+ user_id=user_id,
382
+ stream_events=stream_events,
383
+ stream_executor_events=stream_executor_events,
384
+ workflow_run_response=workflow_run_response,
385
+ step_index=child_step_index,
386
+ store_executor_outputs=store_executor_outputs,
387
+ run_context=run_context,
388
+ session_state=session_state,
389
+ parent_step_id=conditional_step_id,
390
+ workflow_session=workflow_session,
391
+ add_workflow_history_to_steps=add_workflow_history_to_steps,
392
+ num_history_runs=num_history_runs,
393
+ background_tasks=background_tasks,
394
+ ):
395
+ if isinstance(event, StepOutput):
396
+ step_outputs_for_step.append(event)
397
+ all_results.append(event)
398
+ else:
399
+ # Yield other events (streaming content, step events, etc.)
400
+ yield event
401
+
402
+ step_name = getattr(step, "name", f"step_{i}")
403
+ log_debug(f"Condition step {step_name} streaming completed")
404
+
405
+ if step_outputs_for_step:
406
+ if len(step_outputs_for_step) == 1:
407
+ condition_step_outputs[step_name] = step_outputs_for_step[0]
408
+
409
+ if step_outputs_for_step[0].stop:
410
+ logger.info(f"Early termination requested by condition step {step_name}")
411
+ break
412
+
413
+ current_step_input = self._update_step_input_from_outputs(
414
+ current_step_input, step_outputs_for_step[0], condition_step_outputs
415
+ )
416
+ else:
417
+ # Use last output
418
+ condition_step_outputs[step_name] = step_outputs_for_step[-1]
419
+
420
+ if any(output.stop for output in step_outputs_for_step):
421
+ logger.info(f"Early termination requested by condition step {step_name}")
422
+ break
423
+
424
+ current_step_input = self._update_step_input_from_outputs(
425
+ current_step_input, step_outputs_for_step, condition_step_outputs
426
+ )
427
+
428
+ except Exception as e:
429
+ step_name = getattr(step, "name", f"step_{i}")
430
+ logger.error(f"Condition step {step_name} streaming failed: {e}")
431
+ error_output = StepOutput(
432
+ step_name=step_name,
433
+ content=f"Step {step_name} failed: {str(e)}",
434
+ success=False,
435
+ error=str(e),
436
+ )
437
+ all_results.append(error_output)
438
+ break
439
+
440
+ log_debug(f"Condition End: {self.name} ({len(all_results)} results)", center=True, symbol="-")
441
+ if stream_events and workflow_run_response:
442
+ # Yield condition completed event
443
+ yield ConditionExecutionCompletedEvent(
444
+ run_id=workflow_run_response.run_id or "",
445
+ workflow_name=workflow_run_response.workflow_name or "",
446
+ workflow_id=workflow_run_response.workflow_id or "",
447
+ session_id=workflow_run_response.session_id or "",
448
+ step_name=self.name,
449
+ step_index=step_index,
450
+ condition_result=True,
451
+ executed_steps=len(self.steps),
452
+ step_results=all_results,
453
+ step_id=conditional_step_id,
454
+ parent_step_id=parent_step_id,
455
+ )
456
+
457
+ yield StepOutput(
458
+ step_name=self.name,
459
+ step_id=conditional_step_id,
460
+ step_type=StepType.CONDITION,
461
+ content=f"Condition {self.name} completed with {len(all_results)} results",
462
+ success=all(result.success for result in all_results) if all_results else True,
463
+ steps=all_results,
464
+ )
465
+
466
+ async def aexecute(
467
+ self,
468
+ step_input: StepInput,
469
+ session_id: Optional[str] = None,
470
+ user_id: Optional[str] = None,
471
+ workflow_run_response: Optional[WorkflowRunOutput] = None,
472
+ store_executor_outputs: bool = True,
473
+ run_context: Optional[RunContext] = None,
474
+ session_state: Optional[Dict[str, Any]] = None,
475
+ workflow_session: Optional[WorkflowSession] = None,
476
+ add_workflow_history_to_steps: Optional[bool] = False,
477
+ num_history_runs: int = 3,
478
+ background_tasks: Optional[Any] = None,
479
+ ) -> StepOutput:
480
+ """Async execute the condition and its steps with sequential chaining"""
481
+ log_debug(f"Condition Start: {self.name}", center=True, symbol="-")
482
+
483
+ conditional_step_id = str(uuid4())
484
+
485
+ self._prepare_steps()
486
+
487
+ # Evaluate the condition
488
+ if run_context is not None and run_context.session_state is not None:
489
+ condition_result = await self._aevaluate_condition(step_input, session_state=run_context.session_state)
490
+ else:
491
+ condition_result = await self._aevaluate_condition(step_input, session_state=session_state)
492
+ log_debug(f"Condition {self.name} evaluated to: {condition_result}")
493
+
494
+ if not condition_result:
495
+ log_debug(f"Condition {self.name} not met, skipping {len(self.steps)} steps")
496
+ return StepOutput(
497
+ step_name=self.name,
498
+ step_id=str(uuid4()),
499
+ step_type=StepType.CONDITION,
500
+ content=f"Condition {self.name} not met - skipped {len(self.steps)} steps",
501
+ success=True,
502
+ )
503
+
504
+ log_debug(f"Condition {self.name} met, executing {len(self.steps)} steps")
505
+
506
+ # Chain steps sequentially like Loop does
507
+ all_results: List[StepOutput] = []
508
+ current_step_input = step_input
509
+ condition_step_outputs = {}
510
+
511
+ for i, step in enumerate(self.steps):
512
+ try:
513
+ step_output = await step.aexecute( # type: ignore[union-attr]
514
+ current_step_input,
515
+ session_id=session_id,
516
+ user_id=user_id,
517
+ workflow_run_response=workflow_run_response,
518
+ store_executor_outputs=store_executor_outputs,
519
+ run_context=run_context,
520
+ session_state=session_state,
521
+ workflow_session=workflow_session,
522
+ add_workflow_history_to_steps=add_workflow_history_to_steps,
523
+ num_history_runs=num_history_runs,
524
+ background_tasks=background_tasks,
525
+ )
526
+
527
+ # Handle both single StepOutput and List[StepOutput]
528
+ if isinstance(step_output, list):
529
+ all_results.extend(step_output)
530
+ if step_output:
531
+ step_name = getattr(step, "name", f"step_{i}")
532
+ condition_step_outputs[step_name] = step_output[-1]
533
+
534
+ if any(output.stop for output in step_output):
535
+ logger.info(f"Early termination requested by condition step {step_name}")
536
+ break
537
+ else:
538
+ all_results.append(step_output)
539
+ step_name = getattr(step, "name", f"step_{i}")
540
+ condition_step_outputs[step_name] = step_output
541
+
542
+ if step_output.stop:
543
+ logger.info(f"Early termination requested by condition step {step_name}")
544
+ break
545
+
546
+ step_name = getattr(step, "name", f"step_{i}")
547
+ log_debug(f"Condition step {step_name} async completed")
548
+
549
+ current_step_input = self._update_step_input_from_outputs(
550
+ current_step_input, step_output, condition_step_outputs
551
+ )
552
+
553
+ except Exception as e:
554
+ step_name = getattr(step, "name", f"step_{i}")
555
+ logger.error(f"Condition step {step_name} async failed: {e}")
556
+ error_output = StepOutput(
557
+ step_name=step_name,
558
+ content=f"Step {step_name} failed: {str(e)}",
559
+ success=False,
560
+ error=str(e),
561
+ )
562
+ all_results.append(error_output)
563
+ break
564
+
565
+ log_debug(f"Condition End: {self.name} ({len(all_results)} results)", center=True, symbol="-")
566
+
567
+ return StepOutput(
568
+ step_name=self.name,
569
+ step_id=conditional_step_id,
570
+ step_type=StepType.CONDITION,
571
+ content=f"Condition {self.name} completed with {len(all_results)} results",
572
+ success=all(result.success for result in all_results) if all_results else True,
573
+ error=None,
574
+ stop=False,
575
+ steps=all_results,
576
+ )
577
+
578
+ async def aexecute_stream(
579
+ self,
580
+ step_input: StepInput,
581
+ session_id: Optional[str] = None,
582
+ user_id: Optional[str] = None,
583
+ stream_events: bool = False,
584
+ stream_intermediate_steps: bool = False,
585
+ stream_executor_events: bool = True,
586
+ workflow_run_response: Optional[WorkflowRunOutput] = None,
587
+ step_index: Optional[Union[int, tuple]] = None,
588
+ store_executor_outputs: bool = True,
589
+ run_context: Optional[RunContext] = None,
590
+ session_state: Optional[Dict[str, Any]] = None,
591
+ parent_step_id: Optional[str] = None,
592
+ workflow_session: Optional[WorkflowSession] = None,
593
+ add_workflow_history_to_steps: Optional[bool] = False,
594
+ num_history_runs: int = 3,
595
+ background_tasks: Optional[Any] = None,
596
+ ) -> AsyncIterator[Union[WorkflowRunOutputEvent, TeamRunOutputEvent, RunOutputEvent, StepOutput]]:
597
+ """Async execute the condition with streaming support - mirrors Loop logic"""
598
+ log_debug(f"Condition Start: {self.name}", center=True, symbol="-")
599
+
600
+ conditional_step_id = str(uuid4())
601
+
602
+ self._prepare_steps()
603
+
604
+ # Evaluate the condition
605
+ if run_context is not None and run_context.session_state is not None:
606
+ condition_result = await self._aevaluate_condition(step_input, session_state=run_context.session_state)
607
+ else:
608
+ condition_result = await self._aevaluate_condition(step_input, session_state=session_state)
609
+ log_debug(f"Condition {self.name} evaluated to: {condition_result}")
610
+
611
+ # Considering both stream_events and stream_intermediate_steps (deprecated)
612
+ if stream_intermediate_steps is not None:
613
+ warnings.warn(
614
+ "The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
615
+ DeprecationWarning,
616
+ stacklevel=2,
617
+ )
618
+ stream_events = stream_events or stream_intermediate_steps
619
+
620
+ if stream_events and workflow_run_response:
621
+ # Yield condition started event
622
+ yield ConditionExecutionStartedEvent(
623
+ run_id=workflow_run_response.run_id or "",
624
+ workflow_name=workflow_run_response.workflow_name or "",
625
+ workflow_id=workflow_run_response.workflow_id or "",
626
+ session_id=workflow_run_response.session_id or "",
627
+ step_name=self.name,
628
+ step_index=step_index,
629
+ condition_result=condition_result,
630
+ step_id=conditional_step_id,
631
+ parent_step_id=parent_step_id,
632
+ )
633
+
634
+ if not condition_result:
635
+ if stream_events and workflow_run_response:
636
+ # Yield condition completed event for empty case
637
+ yield ConditionExecutionCompletedEvent(
638
+ run_id=workflow_run_response.run_id or "",
639
+ workflow_name=workflow_run_response.workflow_name or "",
640
+ workflow_id=workflow_run_response.workflow_id or "",
641
+ session_id=workflow_run_response.session_id or "",
642
+ step_name=self.name,
643
+ step_index=step_index,
644
+ condition_result=False,
645
+ executed_steps=0,
646
+ step_results=[],
647
+ step_id=conditional_step_id,
648
+ parent_step_id=parent_step_id,
649
+ )
650
+ return
651
+
652
+ log_debug(f"Condition {self.name} met, executing {len(self.steps)} steps")
653
+
654
+ # Chain steps sequentially like Loop does
655
+ all_results = []
656
+ current_step_input = step_input
657
+ condition_step_outputs = {}
658
+
659
+ for i, step in enumerate(self.steps):
660
+ try:
661
+ step_outputs_for_step = []
662
+
663
+ # Create child index for each step within condition
664
+ if step_index is None or isinstance(step_index, int):
665
+ # Condition is a main step - child steps get x.1, x.2, x.3 format
666
+ child_step_index = (step_index if step_index is not None else 1, i)
667
+ else:
668
+ # Condition is already a child step - child steps get same parent number: x.y, x.y, x.y
669
+ child_step_index = step_index
670
+
671
+ # Stream step execution - mirroring Loop logic
672
+ async for event in step.aexecute_stream( # type: ignore[union-attr]
673
+ current_step_input,
674
+ session_id=session_id,
675
+ user_id=user_id,
676
+ stream_events=stream_events,
677
+ stream_executor_events=stream_executor_events,
678
+ workflow_run_response=workflow_run_response,
679
+ step_index=child_step_index,
680
+ store_executor_outputs=store_executor_outputs,
681
+ run_context=run_context,
682
+ session_state=session_state,
683
+ parent_step_id=conditional_step_id,
684
+ workflow_session=workflow_session,
685
+ add_workflow_history_to_steps=add_workflow_history_to_steps,
686
+ num_history_runs=num_history_runs,
687
+ background_tasks=background_tasks,
688
+ ):
689
+ if isinstance(event, StepOutput):
690
+ step_outputs_for_step.append(event)
691
+ all_results.append(event)
692
+ else:
693
+ # Yield other events (streaming content, step events, etc.)
694
+ yield event
695
+
696
+ step_name = getattr(step, "name", f"step_{i}")
697
+ log_debug(f"Condition step {step_name} async streaming completed")
698
+
699
+ if step_outputs_for_step:
700
+ if len(step_outputs_for_step) == 1:
701
+ condition_step_outputs[step_name] = step_outputs_for_step[0]
702
+
703
+ if step_outputs_for_step[0].stop:
704
+ logger.info(f"Early termination requested by condition step {step_name}")
705
+ break
706
+
707
+ current_step_input = self._update_step_input_from_outputs(
708
+ current_step_input, step_outputs_for_step[0], condition_step_outputs
709
+ )
710
+ else:
711
+ # Use last output
712
+ condition_step_outputs[step_name] = step_outputs_for_step[-1]
713
+
714
+ if any(output.stop for output in step_outputs_for_step):
715
+ logger.info(f"Early termination requested by condition step {step_name}")
716
+ break
717
+
718
+ current_step_input = self._update_step_input_from_outputs(
719
+ current_step_input, step_outputs_for_step, condition_step_outputs
720
+ )
721
+
722
+ except Exception as e:
723
+ step_name = getattr(step, "name", f"step_{i}")
724
+ logger.error(f"Condition step {step_name} async streaming failed: {e}")
725
+ error_output = StepOutput(
726
+ step_name=step_name,
727
+ content=f"Step {step_name} failed: {str(e)}",
728
+ success=False,
729
+ error=str(e),
730
+ )
731
+ all_results.append(error_output)
732
+ break
733
+
734
+ log_debug(f"Condition End: {self.name} ({len(all_results)} results)", center=True, symbol="-")
735
+
736
+ if stream_events and workflow_run_response:
737
+ # Yield condition completed event
738
+ yield ConditionExecutionCompletedEvent(
739
+ run_id=workflow_run_response.run_id or "",
740
+ workflow_name=workflow_run_response.workflow_name or "",
741
+ workflow_id=workflow_run_response.workflow_id or "",
742
+ session_id=workflow_run_response.session_id or "",
743
+ step_name=self.name,
744
+ step_index=step_index,
745
+ condition_result=True,
746
+ executed_steps=len(self.steps),
747
+ step_results=all_results,
748
+ step_id=conditional_step_id,
749
+ parent_step_id=parent_step_id,
750
+ )
751
+
752
+ yield StepOutput(
753
+ step_name=self.name,
754
+ step_id=conditional_step_id,
755
+ step_type=StepType.CONDITION,
756
+ content=f"Condition {self.name} completed with {len(all_results)} results",
757
+ success=all(result.success for result in all_results) if all_results else True,
758
+ steps=all_results,
759
+ )