feat(llm): resume the Claude Code session across a kill-chain phase - #149
Open
N3thunt3r69 wants to merge 1 commit into
Open
feat(llm): resume the Claude Code session across a kill-chain phase#149N3thunt3r69 wants to merge 1 commit into
N3thunt3r69 wants to merge 1 commit into
Conversation
Every ReAct iteration flattens the growing transcript into a brand-new prompt and spawns a fresh `claude -p` process. Within one task that is a quadratic resend; across a mission it also means each spawn re-pays Claude Code's own CLAUDE.md/skills/MCP bootstrap tax from scratch, since T3MP3ST never told the CLI these calls belong to one session. LocalAgentAdapter now tracks the Claude Code session id from the JSON envelope and passes it back in with --resume on every later call, so the CLI carries the accumulated transcript itself and the repeated part is billed at cache-read pricing instead of resent. The session is scoped to one kill-chain phase: TempestCommand drops it for every operator right after advancePhase(), since local-agent operators are spawned once for the whole mission and would otherwise carry one session across all 7 phases. A stale or expired session id fails fast (confirmed against the real CLI: nonzero exit, no JSON on stdout) and localAgentChat retries once without --resume rather than failing the task over it. Verified against the real CLI: a resumed call recalled prior context correctly and dropped from $0.151 to $0.008 (cache_read_input_tokens absorbing the prior turn instead of cache_creation), and an invalid --resume id triggered the fallback and still succeeded. Ran live against an authorized target: the same session id held across all 4 recon tasks in one phase, then a newly spawned operator's first call in the next phase carried no --resume, confirming both the resume and the reset. Full suite: 764/764, no regressions.
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.
Follow-up to #139/#140. That fix stopped
AgentLoop's token budget check from being blind, but the deeper cost driver is architectural: every ReAct iteration resends the whole growing transcript as a brand-newclaude -pprocess, and each of those spawns re-pays Claude Code's own CLAUDE.md/skills/MCP bootstrap tax from scratch. This uses Claude Code's--resumeto carry one session across a kill-chain phase instead, so the repeated part is billed at cache-read pricing instead of resent.Contribution Receipt
--resume) across a kill-chain phase, with a fallback to a fresh session if the resumed one is stale.npm run typecheck-> passnpm test-> pass (764/764 vitest, 11/11 ops-preflight, 19/19 model-matrix, refusal-frontier self-test)npm run doctor-> pass (30/33, 3 warnings: semgrep/promptfoo missing, API health offline with the server not running — no blockers)npm run verify-claims-> pass (27/27, no headline numbers changed)--resumerecall, the cost drop, and the stale-session failure shape; (2) a live recon-phase mission via/api/mission/startagainst an authorized external target, confirmed viapsthat the session id held across all 4 recon tasks in one phase and that a newly spawned operator's first call in the next phase carried no--resume. Both deleted/stopped after use, no logs retained.--resumefallback fires on any failure once a session id is in play, not only a confirmed-stale one; a real transient error on the resumed call pays one extra spawn before surfacing. Session scope is tied toadvancePhase()only — Codex/Hermes/OpenCode/Oh My Pi are untouched (Claude-only, same as Claude Code local-agent responses carry nousage:AgentLoop's token budget check never fires #139/fix(llm): populate usage for the Claude Code local-agent path #140). Mission-level state (the running phase/task graph) still does not survive a server restart, so a resumed session id would already be moot in that case; this PR does not change that.