feat(hooks): error event — fires when a turn exits unrecoverably#241
Merged
emal-avala merged 1 commit intomainfrom Apr 24, 2026
Merged
feat(hooks): error event — fires when a turn exits unrecoverably#241emal-avala merged 1 commit intomainfrom
emal-avala merged 1 commit intomainfrom
Conversation
Adds `HookEvent::Error`, a lifecycle event that fires from the turn
driver when an LLM call can't be recovered via retry or reactive
compaction. Context:
{
"session_id": "...",
"turn": 3,
"stage": "llm_call_failed",
"message": "<error text>"
}
Use case: pager integrations, audit logs, and failover automation
want a single place to react to turn failures without tailing stderr
or polling session files.
The `stage` field is a coarse tag ("llm_call_failed" today) so
future fire-sites (tool dispatch failures, permission denies, etc.)
can reuse the same hook surface with a different tag — hooks can
filter on stage if they care about one category.
Integration points updated:
- schema: new variant with rustdoc
- dispatcher: run_hooks test proves matching
- QueryEngine: fire_error_hooks helper + one fire-site at the only
existing `return Err(...)` path in run_turn_with_sink
- /hooks events: catalog, format_hook_event, parse_hook_event all
teach the new name
Tests:
- serde roundtrip: `HookEvent::Error` ↔ `"error"`
- dispatcher: run_hooks fires a hook registered for `Error`
- CLI catalog invariants continue to pass: unique names,
`parse_hook_event_covers_every_variant_in_catalog`
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
HookEvent::Error, a lifecycle event the turn driver fires when an LLM call can't be recovered via retry or reactive compaction. Fills a real gap: today there's no way for a hook to catch turn failures without tailing stderr or polling session files.Hook context
{ "session_id": "…", "turn": 3, "stage": "llm_call_failed", "message": "<error text>" }The
stagefield is a coarse tag ("llm_call_failed" today) so future fire-sites — tool-dispatch failures, permission denies — can reuse the same hook surface with a different tag. Hooks can filter onstageif they care about one category.Example use
Integration
HookEvent::Errorvariant with rustdoc.run_hookstest confirms event matching.QueryEngine::fire_error_hooks(stage, message)helper plus one fire-site at the onlyreturn Err(...)path inrun_turn_with_sink./hooks eventscatalog,format_hook_event, andparse_hook_eventall teach the new name.Tests
HookEvent::Error↔"error"Errorhook actually fires when the event is dispatchedhook_event_catalog_has_unique_names,parse_hook_event_covers_every_variant_in_catalog)Full hook + schema suites pass. Clippy clean under
-D warnings.Test plan
cargo test -p agent-code-lib --lib hooks::cargo test -p agent-code-lib --lib hook_event_serdecargo test -p agent-code --bin agent parse_hook_eventcargo clippy --workspace --tests --no-deps -- -D warningscargo fmt --all --check