Dashboard › opencode › Distillation
b84f3dc5-b50e-4ed9-83e8-0270e919a726["lore_tm_v1_za7r3A-Hz5r7eHjE9UTcNhmNQjk01caH7ktfp_m6BeI","lore_tm_v1_WNJTGd79nkhXwxLSQIjMUJYfJYLTSGxhlyVxH6bFYVk","lore_tm_v1_ITjy_JcM4EeydoVtuxZBYlN1KwGSm7QqxVNsuALcNH4","lore_tm_v1_MbS_s1PCg3VjQbxKIMsrizSeczbJh2LwBm-U90_YX_I","lore_tm_v1_L5sWAHCy7yURNj4m9Z9pUoCqsauKqKsy7xwpzubmOQ4","lore_tm_v1_MQOulXS40ekVpy7NECYUaWn8kieM66kRj-ByA9-ljiY"]
Date: Sep 17, 2026
packages/core/src/session/runner/index.ts defines SessionRunner.Interface.run() as one local continuation from recorded session history. Inputs are sessionID, force, executionID, ownerID, and optional recoveryInputID; the effect may fail with LLMError, SessionRunnerModel.Error, MessageDecodeError, ContextSnapshotDecodeError, SystemContext.InitializationBlocked, or ToolOutputStore.Error.packages/core/src/session/runner/llm.ts constructs a SessionExecutionClaim.Claim identity from sessionID, executionID, and ownerID. The runnerβs durability TODOs include replacing local ownership with durable multi-node ownership when clustered and durably marking busy, retrying, idle, interrupted, or terminal-failure status.SessionRunner.run() treats recoveryInputID !== undefined as recovery mode. Recovery suppresses checks for pending "steer" and "queue" inputs; otherwise it checks "steer" first and checks "queue" only when no steer is pending. A non-recovery call returns without running when force=false and neither input class is pending.SessionRunner.run() calls failInterruptedTools(sessionID, claim). Initial promotion precedence is { recoveryInputID }, then "steer", then "queue", then undefined.runTurn(sessionID, executionID, promotion, step, ownerID) starting at step=1, increments to result.step + 1, and continues while result.needsContinuation is true. Outside recovery mode, subsequent continuation promotion becomes "steer" and pending steer input can force another continuation."queue" input and starts another outer iteration with promotion "queue" when present. Recovery executes only its recovery work and does not drain later steer or queue inputs.packages/core/src/session/runner/llm.ts exports a location node for SessionRunner.Service; dependencies are EventV2.node, llmClient, AgentV2.node, ToolRegistry.node, SessionRunnerModel.node, SessionStore.node, Location.node, SystemContextRegistry.node, SkillGuidance.node, ReferenceGuidance.node, Config.node, Snapshot.node, and Database.node.packages/core/src/session/compaction.ts defaults to automatic compaction with DEFAULT_BUFFER=20_000, DEFAULT_KEEP_TOKENS=8_000, TOOL_OUTPUT_MAX_CHARS=2_000, and SUMMARY_OUTPUT_TOKENS=4_096. Later config documents override these cumulatively through compaction.auto, compaction.buffer, and compaction.keep.tokens.## Objective; ## Important Details; ## Work State with ### Completed, ### Active, and ### Blocked; ## Next Move with numbered items 1 and 2; and ## Relevant Files. Rules require every section, terse bullets rather than prose, preservation of exact paths/symbols/commands/error strings/URLs/identifiers, and no mention of compaction or the summary process.<prior-summary> with newer <conversation> content. They carry forward still-relevant objectives, constraints, directives, decisions, and parallel workstreams; let newer conversation win conflicts; add new progress and context; move completed work from Active to Completed; update resolved blockers while retaining needed continuation details; and refresh Objective and Next Move.[User]: ... plus file attachments, assistant text as [Assistant]: ..., reasoning as [Assistant reasoning]: ..., tool calls/results/errors with dedicated labels, system messages as [System update]: ..., synthetic messages as [Synthetic context]: ..., and shell messages as [Shell]: command plus output. Tool and shell output beyond 2_000 characters is sliced to 2_000 characters and suffixed with \n[truncated]; non-text tool content becomes [Attached MIME] or [Attached MIME: name]."compaction" messages, serializes the remaining conversation, and walks backward under the configured retained-token budget. It returns older material as head for summarization and retained tail material as recent.buildPrompt() wraps current context in <conversation>. Without a prior summary it requests a new anchored continuation summary; with one, it also wraps it in <prior-summary> and supplies merge/update instructions before the fixed summary template.SessionCompaction.compactAfterOverflow() returns false when the model context limit is absent/non-positive, no usable selection exists, neither older head nor an existing compaction is available, or the estimated summary prompt exceeds context - summaryOutput. summaryOutput is Math.min(configured/default output || 4_096, 4_096).SessionMessage.ID, publishes SessionEvent.Compaction.Started with reason: "auto" and an optional eventCommit, optionally runs beforeStream, and performs an LLM request using the same model and HTTP settings, one user summary message, no tools, and generation.maxTokens=summaryOutput.textDelta chunks and marks any provider error. It converts LLM.Error to a failed summary attempt and returns false if streaming fails, a provider error occurs, or the joined summary is blank.SessionEvent.Compaction.Ended with the same messageID, reason: "auto", generated text, retained recent context, and { commit: input.commit }, then returns true.SessionCompaction.compactIfNeeded() skips when automatic compaction is disabled or the context limit is absent/non-positive. It estimates { system, messages, tools } and compacts only when usage exceeds context - Math.max(output, config.buffer), delegating to compactAfterOverflow().