Skip to content

feat(core): interrupt v2 session execution#30850

Merged
kitlangton merged 7 commits into
devfrom
feat/core-v2-interrupt
Jun 5, 2026
Merged

feat(core): interrupt v2 session execution#30850
kitlangton merged 7 commits into
devfrom
feat/core-v2-interrupt

Conversation

@kitlangton

@kitlangton kitlangton commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Stage 1: Interrupt The V2 Runtime

Embedded V2 Sessions execute through a process-global coordinator and a Location-scoped runner:

SessionV2 -> SessionExecution -> SessionRunCoordinator -> SessionRunner

This PR exposes interruption through the public native API:

const opencode = yield* OpenCode.Service
yield* opencode.sessions.interrupt(sessionID)

The call interrupts the active process-local drain and waits for runner cleanup, including partial output flushes and interrupted local tool settlement.

Idle or missing Sessions remain idempotent no-ops at the runtime boundary.

Invariant: one Session has at most one executing generation; interruption settles only after the active owner finishes cleanup.

Stage 2: Record A Durable Interruption Boundary

For a recorded Session, SessionV2.interrupt first publishes the synchronized durable event:

session.next.interrupt.requested

Its aggregate sequence is the ordering boundary between old and new user intent.

sequenceDiagram
  participant App
  participant Events as Session events
  participant Coordinator
  participant Runner
  App->>Events: InterruptRequested
  Events-->>App: interrupt sequence
  App->>Coordinator: interrupt(sessionID, sequence)
  Coordinator->>Runner: interrupt older active work
  Runner-->>Coordinator: cleanup settled
  Coordinator-->>App: settled
Loading

Publishing the event and delivering the local interruption request are uninterruptible together. Caller cancellation cannot commit the durable request without delivering it to the runtime.

InterruptRequested records intent and ordering. It does not claim that an activity was durably settled as interrupted, and it does not project a transcript message.

Invariant: requested interruption is a durable fact; confirmed interruption outcome remains process-local until durable activity lifecycle is designed.

Stage 3: Preserve New Intent Without Restarting Old Work

Prompt admission remains durable and immediate. The coordinator models each execution reason as a coalescible Demand: an explicit run or a wake carrying its admission sequence. Each Session lane keeps one current demand and at most one pending demand, so mode and ordering data cannot drift apart.

seq 10  Prompt B admitted
seq 11  InterruptRequested
seq 12  Prompt C admitted
  • wakes at or before sequence 11 are stale and cannot restart interrupted work
  • wakes after sequence 11 are preserved behind cleanup
  • work after sequence 11 is protected if it starts before the local interrupt delivery arrives
  • queued post-boundary work is also protected
  • repeated interruption requests move the boundary forward
  • delayed older interruption deliveries cannot erase or stop newer work
  • queued and steered inputs remain durable; interruption does not delete submitted user intent

This handles delayed asynchronous wake delivery using durable event order rather than wall-clock timing.

Invariant: an interruption may stop only work at or before its durable boundary, never work admitted after it.

Stage 4: Keep V1 Compatibility And Lifecycle Claims Narrow

  • The legacy V1 HTTP/SDK abort path remains unchanged.
  • V1 continues to use SessionPrompt.cancel / SessionRunState.cancel and live session.status events.
  • The new InterruptRequested event belongs to the V2 Session event model.
  • No durable Interrupted outcome or activity identity is introduced.
  • SessionExecution remains process-global and Session-ID based.
  • Session runners, model resolution, tools, permissions, and filesystem access remain Location-scoped.
  • Different Sessions continue to run and interrupt independently.

Invariant: this PR adds a durable request boundary and process-local execution interruption, not durable activity settlement.

Verification

  • focused coordinator, Session prompt, runner, projector, and recorded-runner suites: 152 tests pass
  • core package typecheck: pass
  • repository-wide typecheck: 22 packages pass
  • three rounds of independent race, code-quality, and test-coverage review; all concrete findings addressed with regression tests
  • git diff --check

The full Core suite remains blocked by an unrelated regression already present on untouched dev: the session_context_epoch migration attempts to create its table twice. The focused interruption suites pass on this branch.

# ------------------------ >8 ------------------------
# Do not modify or remove the line above.
# Everything below it will be ignored.
#
# Conflicts:
#	packages/core/src/location-layer.ts
#	packages/core/src/session/runner/llm.ts
#	packages/core/test/session-runner-recorded.test.ts
#	packages/core/test/session-runner.test.ts
@kitlangton kitlangton enabled auto-merge (squash) June 5, 2026 16:01
@kitlangton kitlangton merged commit 12e3886 into dev Jun 5, 2026
12 checks passed
@kitlangton kitlangton deleted the feat/core-v2-interrupt branch June 5, 2026 16:06
ShamirSecret pushed a commit to ShamirSecret/auto-code-machine that referenced this pull request Jun 6, 2026
aiand-atul added a commit to aiandlabs/aiand-code that referenced this pull request Jun 8, 2026
* feat(app): improve desktop multi-server support (anomalyco#30678)

Co-authored-by: Brendan Allan <git@brendonovich.dev>

* chore: generate

* fix(app): handle tab overflow and scrolling in titlebar (anomalyco#30886)

* fix(app): tab overflow (anomalyco#30894)

* tui: guard path formatting inputs (anomalyco#30469)

Fixes anomalyco#27726, anomalyco#25216, anomalyco#24856, anomalyco#24294, anomalyco#17071, anomalyco#29164, anomalyco#24837, anomalyco#16865, anomalyco#14279, anomalyco#29895

* opencode/run: refresh themes after terminal reloads (anomalyco#30917)

* chore: generate

* fix(tui): fall back to local cwd when editor spawns in attach mode (anomalyco#30583)

* docs: update Go Qwen tiered pricing (anomalyco#30936)

* chore: generate

* feat(tui): add diff hunk navigation (anomalyco#30935)

* chore: rm fuzzy search on references (anomalyco#30931)

* fix: use mapError instead of orDie for context snapshot decoding (anomalyco#30905)

Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>

* fix(core): recover corrupted models cache (anomalyco#30947)

* chore: bun install (anomalyco#30968)

* fix(opencode): resolve Bedrock hang by using node build conditions (anomalyco#30873)

* fix(workflows): retry nix-hashes compute-hash on transient failure (anomalyco#30743)

* fix(stats): scroll model charts to latest on mobile

* fix(opencode): prevent destructive edit matches (anomalyco#30932)

* chore: generate

* fix(core): respect v2 default agents (anomalyco#30969)

* chore: generate

* test(opencode): remove disposal event wait race (anomalyco#30971)

* test(opencode): remove shell timeout output race (anomalyco#30974)

* fix(opencode): gate reasoning summaries by provider (anomalyco#30973)

* feat(core): admit v2 skill guidance (anomalyco#30843)

* fix(workflows): serialize desktop release uploads (anomalyco#30978)

* fix(stats): add mobile chart end spacing

* chore: generate

* sync release versions for v1.16.2

* feat(core): interrupt v2 session execution (anomalyco#30850)

* chore: generate

* feat(core): honor default session models (anomalyco#30982)

* fix(core): harden model selection edges (anomalyco#30987)

* fix(tui): show current location in working copies; order by created; change shortcut; tab to cycle actions in dialog select (anomalyco#30989)

* chore: generate

* feat(core): compact v2 session context (anomalyco#30986)

* fix(opencode): terminate help output with newline (anomalyco#30992)

* fix(opencode): honor Bedrock Mantle config (anomalyco#31001)

* fix(core): preserve model request semantics (anomalyco#30990)

* chore: generate

* feat(core): bound v2 tool output (anomalyco#30999)

* chore: generate

* fix(core): scope Vertex provider transforms (anomalyco#31004)

* feat(core): expose session model switching (anomalyco#31011)

* fix(tui): update tool spacing before layout

* fix(core): recover v2 context overflow (anomalyco#31005)

* fix(core): validate public session model switches (anomalyco#31012)

* feat(tui): delete working copies from move dialog (anomalyco#31017)

* chore: generate

* fix(tui): bootstrap new project copies (anomalyco#31019)

* fix(opencode): limit generated project copy names (anomalyco#31022)

* fix(tui): inject reminder after moving session (anomalyco#31027)

* fix(session): respect directory filter with workspaces (anomalyco#30804)

* feat(app): improve servers UI (anomalyco#30961)

* chore: generate

* feat(app): updates to project avatar (anomalyco#30964)

* chore: generate

* feat(app): sessions list improvements (anomalyco#30941)

* chore: generate

* fix(core): scope v2 prompt cache by session (anomalyco#31036)

Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>

* fix(stats): filter market share to go

* fix(app): increase project session limit and add scrolling (anomalyco#31035)

* fix(core): make V2 reads media-aware and binary-safe (anomalyco#31038)

* chore: update nix node_modules hashes

* feat(opencode): add search to auth logout command (anomalyco#31053)

* feat(opencode): support non-interactive MCP add (anomalyco#31054)

* feat(http-recorder): prepare public beta release (anomalyco#31018)

* refactor(core): simplify filesystem mutation protocol (anomalyco#31059)

* refactor(core): simplify filesystem read protocol (anomalyco#31058)

* chore: update nix node_modules hashes

* refactor(core): simplify search root protocol (anomalyco#31060)

* feat: desktop v2 everything WSL (anomalyco#23407)

* chore: generate

* fix(core): bound prompt cache session keys (anomalyco#31062)

* fix(core): enforce V2 tool permissions (anomalyco#31061)

* feat(opencode): fff search tools (anomalyco#27802)

Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>

* chore: generate

* chore: update nix node_modules hashes

* fix: background agent prompting, lets kill this sleep behavior oml (anomalyco#31162)

* test: fix tool test (anomalyco#31163)

* docs: fix MCP header interpolation example to {env:VAR} (anomalyco#31078)

Co-authored-by: wujunchen <wujunchen@baidu.com>

* chore(http-recorder): disable release automation (anomalyco#31160)

* refactor(core): unify v2 tool architecture (anomalyco#31168)

* fix(core): use static tool type imports (anomalyco#31170)

* docs(v2): update permission rule naming (anomalyco#31167)

* fix(core): isolate image normalization (anomalyco#31165)

* fix(test): release Windows search handles (anomalyco#31172)

* fix(core): harden unified tool runtime (anomalyco#31171)

* test(core): cover managed output read permissions (anomalyco#31166)

* fix(core): preserve session failure causes

* refactor(server): canonicalize service API (anomalyco#31049)

* chore: generate

* chore: update nix node_modules hashes

* fix(tui): sort connect providers alphabetically (anomalyco#30891)

Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>

* feat(desktop): make updates persistent and responsive (anomalyco#31191)

* chore: generate

* refactor(tui): extract standalone package (anomalyco#31193)

* chore: generate

* chore: update nix node_modules hashes

* fix(app): refresh directory MCP status (anomalyco#31194)

* feat(desktop): open attachments in active project (anomalyco#31192)

* chore: generate

* fix(desktop): style home session scrollbar (anomalyco#31202)

* fix(desktop): disable hidden agent cycling (anomalyco#31207)

* test(core): cover skill directory output (anomalyco#31263)

* fix(opencode): avoid duplicate skill catalog (anomalyco#31269)

* chore(opencode): update MCP SDK to 1.29.0 (anomalyco#31268)

* chore: generate

* chore: update nix node_modules hashes

* run: make minimal mode more minimal (anomalyco#31227)

* chore: generate

---------

Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com>
Co-authored-by: Brendan Allan <git@brendonovich.dev>
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: Brendan Allan <14191578+Brendonovich@users.noreply.github.com>
Co-authored-by: Simon Klee <hello@simonklee.dk>
Co-authored-by: pcadena-lila <pcadena@lila.ai>
Co-authored-by: Jack <jack@anoma.ly>
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
Co-authored-by: weiconghe <46336277+weiconghe@users.noreply.github.com>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: alberto <914199+alblez@users.noreply.github.com>
Co-authored-by: Jérôme Benoit <jerome.benoit@sap.com>
Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com>
Co-authored-by: Kit Langton <kit.langton@gmail.com>
Co-authored-by: opencode <opencode@sst.dev>
Co-authored-by: James Long <longster@gmail.com>
Co-authored-by: mridul <65942753+rexdotsh@users.noreply.github.com>
Co-authored-by: Aarav Sareen <96787824+arvsrn@users.noreply.github.com>
Co-authored-by: opencode-agent[bot] <219766164+opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: Dmitriy Kovalenko <dmitriy@iusevimbtw.com>
Co-authored-by: fancivez <384514351@qq.com>
Co-authored-by: wujunchen <wujunchen@baidu.com>
Co-authored-by: Dax <mail@thdxr.com>
Co-authored-by: Robert Douglass <rob@robshouse.net>
Co-authored-by: rekram1-node <rekram1-node@users.noreply.github.com>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant