Skip to content

spare live runs the interrupted-call repair and render memory linearly - #455

Merged
xandreeddev merged 1 commit into
mainfrom
fix/m2
Nov 2, 2026
Merged

xandreeddev merged 1 commit into
mainfrom
fix/m2

Conversation

@xandreeddev

Copy link
Copy Markdown
Owner

What

  • A concurrent run of an open turn is no longer told that another run's call is interrupted while that call is still running: a build leaves out an exchange of another run of the open turn until each of its calls has a result. The run that made the call, and every request after the turn ended, still answer a missing result with ToolInterrupted.
  • A request shows its results in the order of its calls, whatever order concurrent calls returned in (the journal still records them as they return).
  • Rendering memory is linear in the log's length. Several passes copied an accumulated list or map per entry or result, so a long session's every build was quadratic (about 10 s for 25,600 entries); it now takes about 0.1 s, with byte-identical output (checked against the previous renderer with a property test over generated logs).
  • @xandreed/plugin-agent-loop: a reply cut short is recorded with its calls' ReplyCut answers in the same batch, and runLoop's tool_start/tool_end carry the call's own id instead of an execution id.
  • @xandreed/plugin-models: a streamed chat completion whose body ended with neither a finish reason nor [DONE] finishes unknown, so the loop runs none of a dropped stream's calls; [DONE] or a whole completion without a reason still settles.
  • Minted tool-call ids are call_<turn>_<ordinal>_<step>_<n> (call_<turn>_<ordinal>_p<n> for a planned batch): letters, digits and _ only, short enough for Anthropic's ^[a-zA-Z0-9_-]+$ pairing keys after a provider switch. An id-less provider result pairs with the id-less call of its own tool. Stored ids replay as stored.
  • Migration: toolCallIdOf(run, step, n) drops the tool argument; custom StepLoops and memory strategies rerun their kits (new cut-record, in-flight-exchange, call-order checks, each with a careless self-test). No stored-shape change: STORED_FORMAT is unchanged. The sdk golden changes only in the minted planned id and the fingerprints that follow from it.

Checks

  • bun run typecheck, foundry check: pass
  • bun test: 3675 pass, 4 skip, 2 fail under full-suite load (the byte-store edge accepts its maximum…, the awaiting check of a careless kit loop); both files pass when rerun alone
  • bun run foundry demo, build:packages, verify:packages, docs:generate (no diff), bun run --cwd packages/website check: pass

A concurrent run of an open turn was told that another run's call was interrupted while that call was still running, because the assistant request is now durable before its handlers. A build leaves such an exchange out until every call has a result; the run that made the call and any request after the turn ended still answer a missing result with ToolInterrupted. A request's results now render in the order of its calls, whatever order they returned in, so a request no longer depends on tool timing.

Rendering memory copied an accumulated list or map per entry in several passes (request pairing, presentations, compactions, the repair, tool-message merging, replies), which made every build of a long session quadratic: about ten seconds for 25,600 entries. Each pass is now linear, with byte-identical output, and takes about a tenth of a second there.

The loop records a reply cut short together with its calls' ReplyCut answers, so a stop between two records no longer leaves cut calls rendered as possibly run, and its tool_start and tool_end events carry the call's own id. The chat completions SSE client finishes a body that ended with neither a finish reason nor [DONE] as unknown, so the loop runs none of a dropped stream's calls. Minted tool-call ids are now call_<turn>_<ordinal>_<step>_<n>: letters, digits and underscores only, short enough for every provider's pairing key, and an id-less provider result pairs with the id-less call of its own tool. The memory and step-loop kits gain in-flight-exchange, call-order and cut-record checks with careless self-tests.
@xandreeddev
xandreeddev merged commit 87e34f4 into main Nov 2, 2026
1 check passed
@xandreeddev
xandreeddev deleted the fix/m2 branch November 2, 2026 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant