Commit Graph

4 Commits

Author SHA1 Message Date
Lucas Gomide
3bb87532da fix: dispatch execution_end hook on failed crew and flow executions (#6607)
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Check Documentation Broken Links / Check broken links (push) Waiting to run
Vulnerability Scan / pip-audit (push) Waiting to run
* fix: dispatch execution_end hook on failed crew and flow executions

The `execution_end` interception point only fired after a successful
kickoff, so consumers never learned about failed runs. Crew kickoff
paths (`kickoff`/`akickoff`) and the flow runtime (`kickoff_async`,
`resume_async`) now dispatch it on the failure path too, with new
additive `status` ("completed"/"failed") and `error` fields on
`ExecutionEndContext`. Pairing flags guarantee exactly-once dispatch,
keep the start/end pairing invariant, and the original exception
propagates unchanged.

* fix: track execution_end pairing per invocation for reentrant flows

Reentrant kickoffs on the same Flow instance are supported (usage
aggregation already accommodates them), but the instance-level pairing
booleans let an inner kickoff's completion mark the outer execution as
ended, skipping the outer failure's `execution_end`. The pairing state
now lives in each `kickoff_async` invocation's locals, and the resume
path passes a per-invocation holder into `_resume_async_body`. Crew
keeps its instance flags since crew kickoffs are not reentrant on the
same instance (`kickoff_for_each` copies the crew).
2026-07-21 15:25:06 -04:00
Lucas Gomide
9a49af098b fix: sync kickoff-completed event with OUTPUT hook result (#6571)
* fix: sync kickoff-completed event with OUTPUT hook result

`CrewKickoffCompletedEvent` still carried the pre-hook `TaskOutput`, so
AMP/OTEL consumers never saw `OUTPUT` mutations even though the returned
`CrewOutput` was updated. Sync `final_task_output.raw` from the post-hook
payload before emit, matching `FlowFinishedEvent`.

* style: drop OUTPUT sync comment and rename crew output test
2026-07-16 14:37:56 -04:00
Lucas Gomide
0e5d0ecfb9 feat: add step interception points and rework execution hooks docs around @on (#6518)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* feat: add pre_step and post_step interception points on task execution

Introduces `StepContext` and the two step points in the dispatcher, and
wires them around agent execution in `task.py` (sync and async paths):
`pre_step` fires after `TaskStartedEvent` with the task context as
payload, `post_step` fires before `TaskCompletedEvent` with the
`TaskOutput`, and hook replacements are rebound in both directions.

* feat: wire pre_step and post_step on flow method execution

Dispatches the step points around each flow method with
kind="flow_method": `pre_step` receives the dumped call params and maps
returned edits back onto args/kwargs, `post_step` can rewrite the method
result before it is recorded. Conformance tests cover per-method firing
and output rewriting.

* docs: rework execution hooks page around the @on api

Replaces the standalone interception hooks catalog with a single
`execution-hooks.mdx` page that teaches `@on` as the primary way to
write hooks, covering the full ten-point catalog across task, flow, and
LLM execution. The legacy per-point decorators stay documented in a
closing section, and the `docs.json` navigation drops the removed page.
2026-07-14 14:47:18 -04:00
Lucas Gomide
a194f3867a feat: wire execution-boundary interception points (#6517)
* feat: wire execution-boundary interception points

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.

* fix: correct execution-boundary hook ordering and input aliasing

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.

* chore: drop redundant seam comments from execution-boundary wiring

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.

* fix: keep crew output typed across boundary hook dispatch

`_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.
2026-07-14 10:43:18 -04:00