feat: UserPromptSubmit hydrates recovery note after compaction (Bet 2 slice 4)#174
Closed
kelsonpw wants to merge 4 commits intokelsonpw/agent-loop-precompact-recoveredfrom
Closed
Conversation
Enable prompt caching via excludeDynamicSections on the systemPrompt block passed to query(). Strips per-run / per-machine sections (date, cwd, git status) from the Claude Code preset so the static prefix is byte-identical across turns — the Claude Agent SDK then attaches cache_control internally. Verified upstream that per-run values (projectApiKey, projectId, framework version) already live in the user-message prompt built by buildIntegrationPrompt, not in the system prefix, so the prefix is cacheable as-is with no refactor. Measurement already lives in the Bet 1 observability spine: the `wizard cli: agent completed` event now includes `cache read input tokens`, `cache creation 5m/1h tokens`, and `cache hit rate`. Success threshold per the Bet 2 brief: ≥50% cache hit rate on run 2+. Kill criterion: <40% after two weeks → revert. Defers to follow-up slices: three-phase Planner → Integrator → Instrumenter pipeline, structured status via report_status MCP tool (#125), real PreCompact / PostToolUse / UserPromptSubmit hooks, eval harness. Recreated from closed #123 against flattened open-source main. The original was auto-closed during the 2026-04-20 history reset. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds report_status(kind, code, detail) in-process MCP tool replacing the [STATUS] / [ERROR-MCP-MISSING] / [ERROR-RESOURCE-MISSING] text-marker regex scanner. Gives the --agent NDJSON surface and outro screen a typed source of truth instead of scraping plaintext. - New report_status MCP tool in src/lib/wizard-tools.ts with Zod validation and 5-calls/second-per-(kind,code) rate limit - StatusReporter interface + _activeStatusReporter slot wired per-run - Deleted legacy text-marker scanner from src/lib/agent-interface.ts - New commandment instructing agent to use the tool - +6 tests in report-status.test.ts; removed 2 deprecated regression tests Bet 2 slice 2. Recreated from closed #125 onto kelsonpw/agent-loop-caching-recovered after the 2026-04-20 history reset.
Adds per-attempt AgentState bag that tracks modified files, last structured status, and compaction count. Serializes to a deterministic tmpdir path so a future post-compaction UserPromptSubmit hook can hydrate the agent back with the context that compaction dropped. - New src/lib/agent-state.ts — AgentState class with setAttemptId, recordModifiedFile, recordStatus, recordCompaction, snapshot, persist, snapshotPath, reset. Schema versioned as amplitude-wizard-agent-state/1. - Instantiated per runAgent call; reset between retry attempts. - Wired into StatusReporter.onStatus so the persisted snapshot always carries the most recent status message. - +11 tests (agent-state.test.ts) covering dedup/sort, status tracking, compaction count, JSON schema, tmpdir path, reset semantics. Bet 2 slice 3. Recreated from #126 onto kelsonpw/agent-loop-status-recovered after the 2026-04-20 history reset. Hook-factory wiring for PreCompact and PostToolUse depends on Bet 1 ToolCallCounters landing first (PR #149); this slice ships the persistence primitive so later slices can wire it up with zero merge friction.
When Claude compacts its context mid-run, the wizard feeds it back a short recovery note — what files have been edited, last status, compaction count — so the agent re-orients and continues the run instead of re-writing files or skipping steps. - src/lib/agent-state.ts gains loadSnapshot, consumeSnapshot, buildRecoveryNote helpers. loadSnapshot uses zod validation so a malformed file returns null cleanly (no uncaught JSON errors). consumeSnapshot deletes the file so hydration fires at most once per compaction. - New createUserPromptSubmitHook(state) factory in agent-interface.ts that injects the recovery note via hookSpecificOutput.additionalContext. - Wired into buildHooksConfig so every UserPromptSubmit gets a chance to hydrate. - Stops resetting AgentState between retries so a mid-retry compaction still sees the files modified in the prior attempt. - +11 hydrate tests covering the full load/consume/build/hook pipeline. Bet 2 slice 4. Recreated from #127 onto kelsonpw/agent-loop-precompact-recovered after the 2026-04-20 history reset.
Contributor
🧙 Wizard CIRun the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands: Test all apps:
Test all apps in a directory:
Test an individual app:
Show more apps
Results will be posted here when complete. |
This was referenced Apr 21, 2026
2bee709 to
eb8889a
Compare
4 tasks
4 tasks
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.
What changes for users
When Claude compacts its context mid-run, the wizard feeds it back a short recovery note — what files have been edited, last status, compaction count — so the agent re-orients and keeps going. Without this, a mid-run compaction can leave the agent re-editing files it already modified or skipping steps it already completed. The user sees the same wizard; the agent just remembers what it already did.
Scope of this slice
loadSnapshot(path),consumeSnapshot(path),buildRecoveryNote(snap)helpers insrc/lib/agent-state.ts.loadSnapshotis zod-validated so a malformed file returns null cleanly;consumeSnapshotdeletes the file so hydration fires at most once per compaction cycle.createUserPromptSubmitHook(state)factory insrc/lib/agent-interface.tsthat injects the recovery note viahookSpecificOutput.additionalContext.buildHooksConfigso everyUserPromptSubmitgets a chance to hydrate.AgentStatebetween retries so a mid-retry compaction still sees the files modified in the prior attempt.agent-state-hydrate.test.ts) covering the fullload → consume → build → hookpipeline.How this advances Bet 2
Closes the round-trip started in slice 3 (
precompact, #126). PreCompact persists state to disk;UserPromptSubmitconsumes it on the next turn. The recovery note is intentionally short (compaction count, modified files, last status) so it doesn't blow the context budget we just reclaimed.Scope note — recovered chain
The PreCompact half of this round-trip still depends on Bet 1
ToolCallCounterslanding first (PR #149). Until that merges, snapshots won't be persisted in production — butUserPromptSubmithydration is wired and tested, ready to light up the moment PreCompact writes are turned on.Tests
+11 new (
agent-state-hydrate.test.ts): loadSnapshot null-on-missing, round-trip, null-on-invalid-JSON, null-on-shape-mismatch, consumeSnapshot deletes file, buildRecoveryNote with/without files + status, createUserPromptSubmitHook no-op when absent, injects additionalContext when present, only hydrates once per compaction cycle. 1111 total passing (was 1100 on slice 3 recovered).Test plan
pnpm testgreenpnpm buildsmoke passespnpm trylocally → force a compaction mid-run, verify agent behavior stays consistentDeferred to later Bet 2 slices
ToolCallCounters)Recreated from #127 onto the recovered Bet 2 chain after the 2026-04-20 history reset.
cc @amplitude/growth
Note
Medium Risk
Adds new hook-time prompt augmentation based on persisted snapshots and changes retry behavior by no longer resetting
AgentState, which could affect agent run consistency across stalls/retries if edge cases exist.Overview
After a context compaction, the wizard now rehydrates the next user prompt with a short recovery note (compaction count, files already modified, last status) by loading a persisted snapshot, validating it, and consuming (deleting) it so it only applies once.
This introduces zod-validated snapshot helpers in
agent-state(loadSnapshot,consumeSnapshot,buildRecoveryNote), wires a newcreateUserPromptSubmitHookinto the agent SDK hooks, and adds a dedicated test suite covering snapshot read/consume, recovery note formatting, and one-shot hydration behavior.Reviewed by Cursor Bugbot for commit 2af00ba. Bugbot is set up for automated code reviews on this repo. Configure here.