Dashboard › opencode › Distillation
60dce576-1f3d-4b5d-aca8-740033b32b64["lore_tm_v1_1XNJZItNb2zqNER511gPaq3C7vjRnX3bAf3k9SHOcTw","lore_tm_v1_GbY0BtLWBi21Zg1heHxvbiPgHwjJAMeQ0R-tQ9m4Cyg","lore_tm_v1_9RRyQarRXDNDCxN1tkeUNAL11t-4Mn0KvQUTO72g-JE","lore_tm_v1_x2GOoKydXm7nj6DUFpb_mk_kYGP6YLN8CvImKTDULCc","lore_tm_v1_I4m2J8jajf6HwZqoV-alPixl4SeqxLgatEYnPWxPsV8","lore_tm_v1_Q_7qCxoSNE27XiNzWnn6vhSgp9Xo_rg9lPOd9Go7YRg"]
Date: Sep 16, 2026
/tmp/opencode/session-recovery-final-v6.patch, packages/core/test/session-runner.test.ts replaces the SessionRunCoordinator import with SessionExecutionLocal and SessionRecovery, adds SessionExecutionTable and SessionRecoveryTable, adds sql from drizzle-orm, and defines const executionID = "test-execution".SessionExecutionLocal.make({ run }); run calls sessionRunner.run({ ...claim, force, recoveryInputID }) and applies Effect.ensuring(Effect.suspend(() => runnerFinalizer)). The layer now provides [runnerLayer, LayerNode.compile(Database.node)].insertExecution(id) inserts into SessionExecutionTable with id: "test-execution", session_id: id, owner_id: "test", phase: "ready", time_created: Date.now(), and expires_at: Date.now() + 60_000; conflict on SessionExecutionTable.session_id updates those fields and resets assistant_message_id to null.runnerFinalizer = Effect.void.verifyPartialFlushOnFailure(kind) now expects interrupted partial "tool input" content to match { type: "tool", id: fragmentID(kind, "partial"), state: { status: "error" } }; other fragment kinds continue using fixture.expectedContent.SessionRunner implementation checklist marks local single-drain coordination, optional agent step limits, canonical V2-to-@opencode-ai/llm translation, one llm.stream(request) turn, incremental assistant text/usage/reasoning/provider-error/tool-call persistence, durable pre-side-effect tool-call recording, registry-based local authorization/execution, typed tool outcomes, eager local calls with settlement before continuation, continuation after local results, and active-turn user steering as complete.SessionRunner checklist work includes: durable multi-node ownership; durable busy/retrying/idle/interrupted/terminal-failure statuses; interruption and stale-work rejection after runtime attachment replacement; bounded provider retries and repeated identical tool calls; policy-filtered built-in/MCP/plugin/structured-output tool definitions; incremental snapshots, patches, and retry notices; scoped runtime context, progress updates, attachment normalization, plugins, and cancellation settlement; continuation for compaction or other required conditions; durable final status and replayable output events; streamed-delta coalescing and projected-history indexes; and bounded-background title, summary, compaction-state, and cleanup updates.SessionRunner documentation states runtime-context parity is tracked canonically in specs/v2/session.md; each provider turn must use llm.stream(request); tool execution and continuation remain in the runner; durable continuation recovery is a separate future slice with an explicit retry policy.failInterruptedTools(sessionID) scans projected assistant messages and publishes SessionEvent.Tool.Failed for tools in "pending" or "running" state, with error { type: "unknown", message: "Tool execution interrupted" }; provider metadata preserves executed and conditionally preserves metadata.awaitToolFibers(fibers) is implemented as Effect.raceFirst(FiberSet.join(fibers), FiberSet.awaitEmpty(fibers)).isUserDeclined(cause) treats defects that are PermissionV2.DeclinedError or QuestionV2.RejectedError as user declines, matching V1 behavior where declining a prompt halts the loop instead of becoming model-facing tool output.TurnTransitionError carrying either { _tag: "ContinueAfterCompaction", step } or { _tag: "ContinueAfterOverflowCompaction", step }.loadSystemContext(agent) concurrently loads systemContext.load(), skillGuidance.load(agent), and referenceGuidance.load(), using { concurrency: "unbounded" }, then combines them with SystemContext.combine.runTurnAttempt(sessionID, promotion, step, recoverOverflow?) interrupts if the session’s location.directory or location.workspaceID differs from the active Location.Service; it initializes the context epoch, creates a FiberSet<void, ToolOutputStore.Error>, and tracks needsContinuation and currentStep."steer" calls SessionInput.promoteSteers(db, events, session.id, cutoff); "queue" first adds Number(yield* SessionInput.promoteNextQueued(...)) and then promotes steers. If any input is promoted, currentStep resets to 1.FiberSet.join(self) waits on the set’s deferred and fails with the first fiber failure; FiberSet.awaitEmpty(self) loops while the set is open and nonempty, awaiting fibers until empty, and has no typed failure channel.FiberSet.clear exists in /home/byk/.local/share/opencode/repos/github.com/Effect-TS/effect-smol/packages/effect/src/FiberSet.ts at line 414.