Skip to content

Add optional if expression to each.do steps - #6214

Merged
vinibrsl merged 2 commits into
mainfrom
flow-router-inside-each
Jun 18, 2026
Merged

Add optional if expression to each.do steps#6214
vinibrsl merged 2 commits into
mainfrom
flow-router-inside-each

Conversation

@vinibrsl

@vinibrsl vinibrsl commented Jun 18, 2026

Copy link
Copy Markdown
Member

Lets a step inside an each action run conditionally based on a CEL expression evaluated against item and prior step outputs.


Note

Medium Risk
The each.do YAML/JSON shape change breaks existing flow definitions until migrated; runtime behavior for skipped steps (preserving prior output) is new and should be validated by consumers.

Overview
Breaking change: each.do no longer uses single-key maps (normalize: { call: ... }). Steps are now objects with name, action, and an optional if CEL expression.

Each iteration can skip steps when if is false; skipped steps do not update outputs or the iteration’s last result. if must evaluate to a boolean (truthy non-bools raise at runtime). if is only valid on each.do steps, not on top-level method do actions (extra fields are rejected).

Runtime EachAction evaluates if against item and per-iteration outputs, and introduces FlowAtomicActionDefinition so nested steps cannot nest another each. Step name uniqueness is enforced via shared _validate_step_list.

Reviewed by Cursor Bugbot for commit 95f4a12. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Each actions now support explicitly named steps with optional conditional execution via if clauses.
    • Steps execute sequentially within iterations and can be conditionally skipped based on expression evaluation.
    • Step outputs are available to subsequent steps within the same iteration.
  • Changes

    • Refactored each action step schema for improved structure and clarity.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Replaces the shorthand { "<name>": { ... } } inner-action mapping inside each.do with an explicit named-step model (FlowEachStepDefinition) carrying name, optional CEL if_ condition, and an action field. The runtime executor is refactored to evaluate per-step conditions and store outputs by step name, and all tests are updated to the new schema.

Changes

Named step model for each.do

Layer / File(s) Summary
FlowAtomicActionDefinition, FlowEachStepDefinition, and updated FlowEachActionDefinition
lib/crewai/src/crewai/flow/flow_definition.py
Removes RootModel and old FlowInnerActionDefinition/FlowEachInnerActionDefinition types; adds FlowAtomicActionDefinition (discriminated union by call) and FlowEachStepDefinition (name, optional if_, action); changes FlowEachActionDefinition.do to list[FlowEachStepDefinition] with validation via a new _validate_step_list helper; exports both types from __all__.
EachAction runtime: NestedStep types, step loop, if_ evaluation
lib/crewai/src/crewai/flow/runtime/_actions.py
Introduces NestedStepRunner and NestedStep type aliases; refactors EachAction.__init__ to build self.steps; replaces per-item loop with step iteration that evaluates if_ via _condition_matches, runs callables via _build_step_action (sync/async + contextvar propagation), stores outputs by step name, and appends the last step output to results.
Schema contract tests: exports, JSON schema, round-trip
lib/crewai/tests/test_flow_definition.py
Asserts FlowAtomicActionDefinition and FlowEachStepDefinition in __all__ and $defs; updates JSON schema description assertions to "Ordered steps" / "runs only if"; revises example payload assertions; updates round-trip test to {name, action} object shape.
Behavioral tests: renamed existing + new if-clause tests
lib/crewai/tests/test_flow_from_definition.py
Converts all existing each YAML fixtures to named-step form; renames six test functions; adds four new tests covering if clause execution, skipped-step output preservation, non-boolean if rejection, and if rejected at method level; updates step-shape validation and nested-each rejection fixtures.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • akaKuruma
  • joaomdmoura
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding optional if expressions to steps within each actions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch flow-router-inside-each

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@vinibrsl
vinibrsl force-pushed the flow-router-inside-each branch 2 times, most recently from ab7180c to 2105a0e Compare June 18, 2026 17:16
vinibrsl added 2 commits June 18, 2026 10:16
Lets a step inside an `each` action run conditionally based on a CEL
expression evaluated against `item` and prior step `outputs`.
@vinibrsl
vinibrsl force-pushed the flow-router-inside-each branch from 2105a0e to 95f4a12 Compare June 18, 2026 17:16
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{}

@vinibrsl
vinibrsl merged commit b5e23a8 into main Jun 18, 2026
69 of 126 checks passed
@vinibrsl
vinibrsl deleted the flow-router-inside-each branch June 18, 2026 17:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants