feat: wire execution-boundary interception points#6517
Conversation
📝 WalkthroughWalkthroughExecution-level interception points and typed contexts are added for crew and flow lifecycle inputs and outputs. Crew kickoff, flow kickoff, flow resume, and completion paths now dispatch these events and apply hook-modified payloads. Conformance tests cover firing, rewriting, propagation, and abortion behavior. ChangesExecution interception
Sequence Diagram(s)sequenceDiagram
participant Caller
participant CrewOrFlow
participant Dispatch
participant Execution
Caller->>CrewOrFlow: start execution with inputs
CrewOrFlow->>Dispatch: dispatch EXECUTION_START
CrewOrFlow->>Dispatch: dispatch INPUT
Dispatch-->>CrewOrFlow: return modified inputs
CrewOrFlow->>Execution: execute with resolved inputs
Execution-->>CrewOrFlow: produce output
CrewOrFlow->>Dispatch: dispatch OUTPUT
CrewOrFlow->>Dispatch: dispatch EXECUTION_END
Dispatch-->>CrewOrFlow: return modified output
CrewOrFlow-->>Caller: return final output
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
790bde5 to
ea20c1a
Compare
8bc4fa2 to
a85e100
Compare
ea20c1a to
73bdfaa
Compare
852a3ec to
cdd79da
Compare
0471ad0 to
8a24330
Compare
f5d67bd to
a867c45
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a867c45. Configure here.
Adds the typed interception contexts (`crewai/hooks/contexts.py`) and wires the `execution_start`, `input`, `output`, and `execution_end` points for both crews and flows through the dispatcher. `prepare_kickoff` and `Flow.kickoff_async` fire `execution_start`/`input` so a hook can rewrite resolved inputs before the run, while `Crew._create_crew_output` and the flow tail fire `output`/`execution_end` so the final result can be observed or replaced. Closes the eight critical-path points without touching the legacy hooks.
Reworks the crew and flow boundary seams flagged in review. `OUTPUT` and `EXECUTION_END` now run before the completion event (`CrewKickoffCompletedEvent` and `FlowFinishedEvent`) so a `HookAborted` no longer leaves a spurious completed signal and a returned payload replacement is honored on the emitted and returned result. Boundary contexts alias `inputs` to the same object as `payload` instead of a fresh dict from `or`, so in-place edits survive read-back. Flows re-publish the resolved inputs into `flow_inputs` baggage after the `INPUT` hook so trigger-payload injection observes hook rewrites, and a resumed flow now dispatches `OUTPUT`/`EXECUTION_END` on its completion path.
Removes two inline comments narrating the OUTPUT/EXECUTION_END dispatch ordering in `crew.py` and the flow runtime, plus a stray sentence about enterprise adapters in the conformance-suite docstring. Comment-only cleanup, no behavior change.
`_create_crew_output` reassigned `crew_output` from the hook contexts' `payload`, which is typed `Any`, so mypy flagged `no-any-return` at the function's return. Cast the payload back to `CrewOutput` after each dispatch and split the `ExecutionEndContext` construction to satisfy `ruff format`'s line-length limit.
a867c45 to
fa0ed74
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/crewai/src/crewai/crew.py (1)
1936-1944: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winEmit
crew_outputin the completion event.OUTPUTandEXECUTION_ENDcan mutate the payload, butCrewKickoffCompletedEventstill sends the pre-interceptionfinal_task_output, so listeners see a different value than the one returned.CrewKickoffCompletedEvent.outputalready acceptsAny, so no schema change is needed.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/crewai/src/crewai/crew.py` around lines 1936 - 1944, Update the CrewKickoffCompletedEvent construction in the crew kickoff completion flow to emit the post-interception crew_output rather than the pre-interception final_task_output. Preserve the existing event metadata and return behavior, using the already-available crew_output value for the event’s output field.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@lib/crewai/src/crewai/crew.py`:
- Around line 1936-1944: Update the CrewKickoffCompletedEvent construction in
the crew kickoff completion flow to emit the post-interception crew_output
rather than the pre-interception final_task_output. Preserve the existing event
metadata and return behavior, using the already-available crew_output value for
the event’s output field.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: c4a5d8ba-18b8-40bd-8706-e572c4deb6b3
📒 Files selected for processing (6)
lib/crewai/src/crewai/crew.pylib/crewai/src/crewai/crews/utils.pylib/crewai/src/crewai/flow/runtime/__init__.pylib/crewai/src/crewai/hooks/contexts.pylib/crewai/src/crewai/hooks/dispatch.pylib/crewai/tests/hooks/test_interception_conformance.py

With the dispatcher in place (#6516, now merged), the execution lifecycle still had no interception seams. This introduces the typed interception contexts and wires
execution_start,input,output, andexecution_endfor both crews and flows:prepare_kickoffandFlow.kickoff_asynclet a hook rewrite resolved inputs before a run, whileCrew._create_crew_outputand the flow tail let the final result be observed or replaced. It closes the eight critical-path points the policy engine needs without touching the legacy hooks.