Dashboard › opencode › Distillation
2d414552-07b1-4b52-af52-22173d750a88["lore_tm_v1_D6AI7Dv1BNws3vHv8sOoJ7MtXbRmoow1PZBXuFgoguo","lore_tm_v1_XI62eFAZiUt3ySdENTH9pKcYSRxvcntIG5Y3KNZ91NQ","lore_tm_v1_hw5BOraX4rMPqHY6g5QfCR_xxO8RtreVpwV2ib23yRE","lore_tm_v1_ozcU2t2QBLSS5SDvdOdf8qaci9KyQ8B2uq8sQ0usZ5Y","lore_tm_v1_awbOqyrlv73RhPNvtjd7uLcg2jc2I5mVZ60oVEOkwlc","lore_tm_v1_7ebvjL3TXuChjmbmGQzvl9YOVKgzMG4VL-v-0XUT1hM","lore_tm_v1_5e2gwnfvYbISxOuUUqO-0el1uuj6whWSGQ9OfOnM15U"]
Date: Sep 16, 2026
packages/core/src/database/migration/20260914170650_session-recovery.ts exports migration ID 20260914170650_session-recovery; its up(tx) adds session_input.wake_pending as integer DEFAULT false NOT NULL and session_input.wake_attempts as integer DEFAULT 0 NOT NULL.20260914170650_session-recovery creates session_execution with columns id, session_id, owner_id, nullable assistant_message_id, phase, time_created, expires_at, and nullable recovery_error; it defines primary key session_execution_pk, phase check session_execution_phase_check allowing 'ready', 'safe', 'unknown', and 'continue', and cascade foreign key fk_session_execution_session_id_session_id_fk from session_id to session.id.20260914170650_session-recovery creates session_recovery with columns session_id, execution_id, nullable assistant_message_id, continuation_message_id, phase, wake_pending integer DEFAULT true NOT NULL, wake_attempts integer DEFAULT 0 NOT NULL, nullable recovery_error, and time_created; it defines primary key session_recovery_pk on execution_id.session_recovery migration foreign keys are fk_session_recovery_session_id_session_id_fk (session_id → session.id, cascade), fk_session_recovery_assistant_message_id_session_message_id_fk (assistant_message_id → session_message.id, cascade), and fk_session_recovery_continuation_message_id_session_input_id_fk (continuation_message_id → session_input.id, cascade).20260914170650_session-recovery creates indexes session_execution_session_idx (unique on session_id), session_execution_owner_idx (on owner_id), session_input_wake_pending_promoted_attempts_time_created_id_idx (on wake_pending, promoted_seq, wake_attempts, time_created, id), session_recovery_continuation_message_idx (unique on continuation_message_id), and session_recovery_wake_pending_error_attempts_created_execution_idx (on wake_pending, recovery_error, wake_attempts, time_created, execution_id).packages/core/schema.json has prevIds containing f14a9b18-8207-487e-a3d3-227e629ba9ad.packages/core/src/session.ts, message listing applies an optional sequence boundary using gt(SessionMessageTable.seq, anchor.seq) for ascending order or lt(...) for descending order, filters by session_id, orders by sequence, optionally applies input.limit, and reverses rows when direction === "previous" before decoding.V2Session.message loads store.message(input.messageID) and returns the message only when its sessionID equals input.sessionID; otherwise it returns undefined.V2Session.context, V2Session.events, and V2Session.history first validate the session with result.get(...); events use events.durable({ aggregateID: input.sessionID, after: input.after }) filtered by isDurableSessionEvent, while history calls EventV2.readAggregate(...) with aggregateID: input.sessionID and manifest SessionDurable.V2Session.prompt runs uninterruptibly, resolves the prompt, uses input.id ?? SessionMessage.ID.create() and input.delivery ?? "steer", then calls SessionInput.admit(...) with requestExecution: input.resume !== false.V2Session.prompt maps a defective SessionInput.LifecycleConflict to PromptConflictError({ sessionID, messageID }); it also raises the same conflict when SessionInput.equivalent(admission.admitted, expected) is false, calls execution.wake(admission.admitted.sessionID) only when admission.shouldWake, and returns admission.admitted.V2Session.shell and V2Session.skill return OperationUnavailableError for operations "shell" and "skill" respectively.V2Session.switchAgent validates the session and publishes SessionEvent.AgentSwitched with a new SessionMessage.ID, current DateTime, and input.agent.V2Session.switchModel avoids publishing when provider ID, model ID, and normalized variant match the current model, where an absent variant normalizes to "default"; otherwise it publishes SessionEvent.ModelSwitched with a new message ID, current timestamp, and input.model.V2Session.compact and V2Session.wait validate session existence and then return OperationUnavailableError for "compact" and "wait" respectively.V2Session.resume validates the session then calls execution.resume(sessionID); V2Session.interrupt executes execution.interrupt(sessionID) inside Effect.uninterruptible.V2Session.revert.stage loads the session and calls SessionRevert.stage({ session, messageID: input.messageID, files: input.files }) with Database.Service, EventV2.Service, and the location-specific layer; revert.clear calls SessionRevert.clear(session) with events and the location layer; revert.commit calls SessionRevert.commit(session) with EventV2.Service.resolvePrompt in packages/core/src/session.ts preserves text, agents, and mapped files; for each file it extracts MIME from a data URI via /^data:([^;,]+)[;,]/i, chooses the URL pathname when URL.canParse(file.uri) or otherwise file.name ?? file.uri, and assigns the extracted MIME, "application/x-directory" for paths ending in /, or FSUtil.mimeType(target).session.ts global node provides Service via layer.pipe(Layer.orDie) and depends on Database.node, EventV2.node, ProjectV2.node, SessionExecution.node, SessionStore.node, LocationServiceMap.node, and SessionProjector.node.packages/core/src/session/recovery-id.ts defines message(executionID, assistantMessageID?) as the supplied assistantMessageID or deterministic SessionMessage.ID.make(\msg_recovery_${executionID}`); continuation(executionID)returnsSessionMessage.ID.make(`msg_recovery_continue_${executionID}`)`.packages/core/src/session/runner/index.ts exports the namespace SessionRunner; RunError is the union of LLMError, SessionRunnerModel.Error, MessageDecodeError, ContextSnapshotDecodeError, SystemContext.InitializationBlocked, and ToolOutputStore.Error.SessionRunner.Interface.run(...) runs one local continuation from already-recorded session history and accepts sessionID: SessionSchema.ID, force: boolean, executionID: string, ownerID: string, and optional recoveryInputID?: SessionMessage.ID; it returns Effect.Effect<void, RunError>.SessionRunner.run contract says eligible durable work is drained, while explicit runs perform one provider attempt even when no work is eligible; its service identifier is @opencode/v2/SessionRunner.