Dashboard › opencode › Distillation
6df4a0b2-9715-4d50-87b6-713bebc01172["lore_tm_v1_y673VGazsW-7Qnp0aQ8-9UBXERHRCkr2VM0RZ-TNyD8","lore_tm_v1_KzaQwdNab-w2JAB1mSddtytdweHY-cEtb3lubbN3QJQ","lore_tm_v1_JD5AZJdzCTbxe8x3y2txn98N_9vSLuUDSVD5YJw3GMg","lore_tm_v1_PRS2FKoJSS7htW7eC5N6J-YeYfMQJ1hSCJv79lpqOSw","lore_tm_v1_FLgZh74n3sTQtckVVJECf4S2c9icCr9r-kBBW_6bKGw","lore_tm_v1_88Qo2hMAtJvLOHSkoU5P5lpQZrAg1wv36-Ocr3ft020","lore_tm_v1_So4qjVFeF5tpO1sz8HxpidBkg5hf3euYi0j94UUWB0s"]
Date: Sep 16, 2026
packages/core/src/database/schema.gen.ts defines recovery wake-selection index session_recovery_wake_pending_error_attempts_created_execution_idx on (wake_pending, recovery_error, wake_attempts, time_created, execution_id).packages/core/src/session.ts:422-433 implements wait by validating the session with result.get(sessionID) and returning OperationUnavailableError({ operation: "wait" }); resume validates then calls execution.resume(sessionID); interrupt invokes execution.interrupt(sessionID) inside Effect.uninterruptible.packages/core/src/session.ts:434-453 exposes revert operations: stage calls SessionRevert.stage({ session, messageID: input.messageID, files: input.files }) with Database.Service, EventV2.Service, and the session location provided; clear calls SessionRevert.clear(session) with events and location; commit calls SessionRevert.commit(session) with events.resolvePrompt in packages/core/src/session.ts:461-473 preserves text, agents, and mapped files; file MIME is inferred first from a data: URI, otherwise from FSUtil.mimeType(target), with targets ending in / assigned application/x-directory.packages/core/src/session.ts:475-487 uses service: Service, layer: layer.pipe(Layer.orDie), and dependencies Database.node, EventV2.node, ProjectV2.node, SessionExecution.node, SessionStore.node, LocationServiceMap.node, and SessionProjector.node.packages/core/src/session/compaction.ts uses compaction defaults DEFAULT_BUFFER = 20_000, DEFAULT_KEEP_TOKENS = 8_000, TOOL_OUTPUT_MAX_CHARS = 2_000, and SUMMARY_OUTPUT_TOKENS = 4_096; document configuration can override 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, then ## Relevant Files; rules require every section, terse bullets, preservation of exact paths/symbols/commands/errors/URLs/identifiers, and no mention of compaction or the summary process.packages/core/src/session/compaction.ts require combining <prior-summary> and newer <conversation>, carrying forward unfinished objectives, constraints, directives, decisions, and parallel workstreams; newer conversation wins conflicts, completed work moves from Active to Completed, resolved blockers are updated, and Objective/Next Move reflect current state.serializeToolContent in packages/core/src/session/compaction.ts joins tool content with newlines, emitting text directly and non-text attachments as [Attached ${item.mime}] or [Attached ${item.mime}: ${item.name}]; truncate limits serialized tool and shell output to 2_000 characters and appends \n[truncated].[User], [Assistant], [Assistant reasoning], [Assistant tool call], [Tool result], [Tool error], [System update], [Synthetic context], and [Shell]; user files serialize as [Attached ${file.mime}: ${file.name ?? file.uri}], completed tools include truncated output, errored tools include part.state.error.message, and other tool states include only the call.packages/core/src/session/compaction.ts:143-164 excludes messages of type "compaction", serializes nonempty entries, and walks backward to retain recent conversation within the configured token count, returning older content as head and retained content as recent.buildPrompt creates either a new anchored summary from <conversation> or an updated summary combining <conversation> with <prior-summary>; in both cases it appends SUMMARY_TEMPLATE.compactIfNeeded skips compaction when automatic compaction is disabled, context is absent/nonpositive, or estimated { system, messages, tools } usage is at most context - Math.max(output, config.buffer); otherwise it calls compactAfterOverflow.compactAfterOverflow calculates provider output from input.request.generation?.maxTokens ?? input.model.route.defaults.limits?.output ?? 0, caps summary output at 4_096, and refuses compaction when no eligible selection exists, there is neither older head nor prior compaction, or the prompt estimate exceeds context - summaryOutput.SessionEvent.Compaction.Started with a new SessionMessage.ID, timestamp, and reason: "auto"; streams an LLM request with the same model and HTTP settings, one Message.user(summaryPrompt), no tools, and generation.maxTokens = summaryOutput; then publishes SessionEvent.Compaction.Ended with the accumulated summary text and selected.recent.false if streaming throws LLM.Error, emits any provider-error event, or produces blank summary text; text-delta events are accumulated into the summary. beforeStream runs before the provider stream, eventCommit may commit the Started event, and input.commit may commit the Ended event.SessionContextEpoch.initialize and SessionContextEpoch.prepare in packages/core/src/session/context-epoch.ts require a SessionExecutionClaim.Claim; prepare concurrently loads current SystemContext, the stored epoch, and SessionHistory.latestCompaction(...) with concurrency: "unbounded".prepareOnce calls SystemContext.initialize(value), inserts baseline, snapshot, and the current EventV2.latestSequence(db, sessionID) as baseline_seq through SessionExecutionClaim.transaction, and returns { baseline, baselineSeq }.Schema.decodeUnknownEffect(SystemContext.Snapshot); failures map to ContextSnapshotDecodeError({ sessionID, details: String(error) }).SystemContext.replace(value, snapshot) only when the latest compaction sequence is greater than stored baseline_seq; otherwise it uses SystemContext.reconcile(value, snapshot). Results "Unchanged" and "ReplacementBlocked" retain the stored baseline and sequence, while "ReplacementReady" replaces the persisted generation using the compaction sequence or current latest event sequence.SessionEvent.ContextUpdated with a fresh SessionMessage.ID, timestamp, and result.text; its commit callback advances only the stored snapshot via a claim-guarded transaction. Missing rows during replace or advance die with exact error Context Epoch not found.SessionContextEpoch.reset deletes the row for session_id; initializeOnce is a no-op if one already exists, otherwise initializes and inserts the epoch.packages/core/src/session/run-coordinator.ts defines a per-key SessionRunCoordinator that serializes execution for each key while allowing different keys concurrently. Its interface exposes active, run(key), wake(key), and interrupt(key, cleanup?); each entry tracks done, optional owner, optional exit, pendingWake, and stopping.run(key) starts options.drain(key, true) when idle, joins the active execution when already running, and if execution is stopping waits for its completion before recursively retrying run(key).wake(key) coalesces newly recorded work by setting pendingWake = true on an active entry; when idle it starts options.drain(key, false). A successful run with a pending wake reuses the entry and starts one yielded successor drain; otherwise settlement either removes the key or creates a successor entry.interrupt(key, cleanup = Effect.void) marks an active entry as stopping, clears its current pendingWake, interrupts the owner fiber, runs cleanup, requires the interrupted execution to have settled or throws exact error Interrupted Session execution did not settle, then removes the entry or starts a successor for work that arrived while stopping. Cleanup failure is propagated with Effect.failCause(cleanupExit.cause), and the stop sequence is uninterruptible.packages/core/src/session/runner/index.ts defines SessionRunner.RunError as LLMError | SessionRunnerModel.Error | MessageDecodeError | ContextSnapshotDecodeError | SystemContext.InitializationBlocked | ToolOutputStore.Error.SessionRunner.Interface.run performs one local continuation from already-recorded session history and accepts exact fields sessionID, force, executionID, ownerID, and optional recoveryInputID?: SessionMessage.ID; explicit runs perform one provider attempt even when no durable work is eligible.Context.Service<Service, Interface>()("@opencode/v2/SessionRunner").