feat(hooks): canonical PostToolUseFailure event, mapped for Goose - #14
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughAdds a canonical ChangesPost-tool failure event mapping
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Greptile SummaryThis change introduces a canonical failed-tool hook event, maps Goose's failure event to the after-tool lifecycle phase, and updates related coverage and documentation. A failed Cursor tool call still has no after-tool lifecycle phase: executable validation showed that both Cursor's direct map and the public registry return an empty phase for Confidence Score: 3/5Not safe to merge until T-Rex findings are addressed. T-Rex reproduced 2 failing behaviors at runtime in agents/cursor.go; the change needs fixes before it is safe to merge. Files Needing Attention: agents/cursor.go
What T-Rex did
|
The gap
Goose fires
PostToolUseonly on success. Failures arrive on a separatePostToolUseFailureevent, which nothing in agentx knew about — there was no canonical constant, andGooseAgent.EventPhases()didn't map it.Consequence for a consumer driving session capture off hooks: a turn that ends in a failed tool call produces no event it can act on, so the failure stays invisible until the next successful tool call or
Stop. On a turn that fails and then stops, that's a full turn of lost signal.Cursor has the same split (
postToolUseFailure, camelCase) and the same gap.What this PR ships
HookEventPostToolUseFailure— canonical constant, PascalCase per Goose's spelling. The camelCase Cursor variant already existed asCursorEventPostToolUseFailureand is unchanged.PhaseAfterTool— same phase as the success path, so a consumer drains the failed turn at the same point it would have drained a successful one.EventPhases()now covers seven events.What stays unmapped, and why
Goose fires eleven events. Four are deliberately left out:
BeforeReadFilePreToolUse— reading a file is a tool callBeforeShellExecutionPreToolUse— running a shell command is a tool callAfterFileEditPostToolUse(and success-only)AfterShellExecutionPostToolUse(and success-only)Mapping these would fire a consumer twice per tool call for zero additional signal. A consumer that spawns a subprocess per hook would double its cost in the hot path to learn nothing new.
PhaseCompactalso stays unmapped: Goose has no compaction event at all. That reasoning is now recorded onEventPhases()so the next reader doesn't have to re-derive it — or worse, "fix" it by adding the four.Test Plan
make check— 1134 tests pass, 2 pre-existing skips, 0 lint issuesTestGooseEventPhasesupdated to seven events and still asserts no phase isPhaseCompactallAgentSpecs()GooseeventPhaseCount6 → 7Follow-up
Cut
v0.1.13after merge.sageox/oxbumps to it as part of its Goose adapter work.Summary by CodeRabbit
New Features
Documentation
Tests