Session continuity enables reusing existing agent sessions to continue work with full context preservation. Instead of spawning a new agent for every follow-up task, agents can resume from their previous state, maintaining conversation history, tool usage patterns, and accumulated knowledge. This mechanism is critical for handling token limits through compaction while preserving task state, and for enabling iterative refinement workflows.
For information about the initial task delegation mechanisms, see Task Delegation. For background task lifecycle management, see Background Task System. For session state tracking in the task/todo system, see Ralph Loop and Todo Enforcement.
Sources: docs/reference/known-issues.md22-51
Both the task tool and call_omo_agent tool accept an optional session_id parameter that references an existing agent session. When provided, the tool sends a new prompt to the existing session rather than creating a new one, preserving the full message history and context.
Sources: packages/omo-opencode/src/shared/prompt-async-gate.ts1-29
Session continuity preserves:
Sources: packages/omo-opencode/src/shared/prompt-async-gate.ts1-29
The ContextCollector and createContextInjectorMessagesTransformHook allow external context (like background task updates or system alerts) to be injected into the next user message of a session. This ensures that even if a session is already running, new relevant information can be "spliced" into the conversation history.
Diagram: Context Injection via Messages Transform Hook Sources: packages/omo-opencode/src/shared/prompt-async-gate.ts1-29
When a session hits a context limit or encounters a structural error (like missing tool results), the system triggers automated recovery flows.
The createSessionRecoveryHook monitors assistant messages for errors and interrupted tool executions. It uses detectErrorType to categorize failures and select a recovery strategy.
Recoverable Error Types:
tool_result_missing: An assistant message called a tool but the session ended before the result was provided.thinking_block_order: Thinking blocks are not in the first position or are misplaced in the message stream.assistant_prefill_unsupported: The model does not support assistant prefill and requires a user message tail.Diagram: Session Recovery Flow Sources: packages/omo-opencode/src/shared/prompt-async-gate.ts1-29
The executeCompact function manages the lifecycle of a session reduction, ensuring that only one recovery operation runs per session at a time using a lock in autoCompactState.compactionInProgress.
Diagram: Session Recovery and Lock Management Sources: packages/omo-opencode/src/shared/prompt-async-gate.ts1-29
The createCompactionContextInjector ensures that critical metadata is not lost during the platform's summarize operation. It uses a checkpointing system to track the agent's configuration.
recoverCheckpointedAgentConfig to restore the state.dispatchInternalPrompt with noReply: true and the AGENT_RECOVERY_PROMPT.Sources: packages/omo-opencode/src/shared/prompt-async-gate.ts1-29
resume() MethodBackgroundManager.resume() handles session continuity for background tasks. It reactivates a completed or errored task by re-acquiring concurrency slots and updating parent context.
Diagram: BackgroundManager.resume() State Machine Sources: packages/omo-opencode/src/shared/prompt-async-gate.ts1-29
| Class/Function | File Path | Role |
|---|---|---|
dispatchInternalPrompt | packages/omo-opencode/src/shared/prompt-async-gate.ts69 | Centralized dispatcher for internal prompts, managing reservations and preventing duplicates. |
releasePromptAsyncReservation | packages/omo-opencode/src/shared/prompt-async-gate.ts147 | Releases a reservation on a session, allowing other internal callers to inject prompts. |
resolveDispatchClient | packages/omo-opencode/src/shared/live-server-route.ts196 | Determines whether to use an in-process client or a live server client for dispatch. |
tryResolveDispatchClientSync | packages/omo-opencode/src/shared/live-server-route.ts162 | Synchronously attempts to resolve the dispatch client, returning undefined if an async probe is needed. |
warmLiveServerProbe | packages/omo-opencode/src/shared/live-server-route.ts79 | Initiates an asynchronous probe to check the availability of the live server. |
isPreSendConnectionFailure | packages/omo-opencode/src/shared/live-server-route.ts216 | Checks if an error indicates a connection failure before sending a request. |
markLiveRouteUnavailable | packages/omo-opencode/src/shared/live-server-route.ts16 | Marks the live server route as unavailable, forcing dispatch through the in-process client. |
subagentSessions | packages/omo-opencode/src/features/claude-code-session-state/state.ts3 | A Set tracking session IDs that belong to subagents. |
runStopHook | packages/omo-codex/plugin/components/start-work-continuation/src/codex-hook.ts36 | Codex hook that provides continuation guidance for active work, including remaining tasks and worktree info. |
createBoulderJson | packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts213 | Helper to create a Boulder state JSON object for testing. |
createMemoryFs | packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts230 | Creates an in-memory file system for testing purposes. |
Sources: packages/omo-opencode/src/shared/prompt-async-gate.ts1-29 packages/omo-opencode/src/shared/live-server-route.ts1-233 packages/omo-codex/plugin/components/start-work-continuation/src/codex-hook.ts36-118 packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts213-230
The prompt-async-gate system is crucial for session continuity, especially in preventing duplicate prompt injections and managing the lifecycle of internal prompts. It ensures that only one internal prompt is dispatched to a session at a time, even when multiple hooks or features might try to inject messages.
Diagram: Prompt Async Gate Flow
The prompt-async-gate uses a module-global reservation map keyed by sessionID to prevent race conditions. Each reservation has a source, expiration, and a unique token. A postDispatchHoldMs (default 2000ms) ensures the reservation is held briefly after dispatch, even if the underlying promptAsync call returns early or fails. This prevents other hooks from immediately retrying or injecting new prompts.
Sources: docs/reference/prompt-async-gate-rfc.md62-116 packages/omo-opencode/src/shared/prompt-async-gate.ts1-29
The live-server-route module manages how internal prompts are dispatched, deciding whether to use the in-process OpenCode client or an external "live" server client. This is particularly relevant for parent session notifications and background task wakes, where the parent session might be running in a different process.
Diagram: Live Server Route Resolution
The resolveDispatchClient function determines the appropriate client. It first checks several synchronous conditions (client identity, disabled flag, child session status, server URL presence, and fresh probe status). If these checks don't yield a definitive answer, it performs an asynchronous probe to the /session endpoint of the configured serverUrl. This probe has a PROBE_TTL_MS (60 seconds) and PROBE_ABORT_MS (1.5 seconds) to prevent indefinite hangs. If the probe succeeds, a live client is used; otherwise, the in-process client is used.
Sources: packages/omo-opencode/src/shared/live-server-route.ts1-233 packages/omo-opencode/src/shared/live-server-route.test.ts58-194
runSummarizeRetryStrategy attempts to summarize the session. If it fails, it retries with exponential backoff (initial delay 5s, factor 2.0) until maxAttempts (3) or a 120s timeout is reached.runAggressiveTruncationStrategy removes large tool outputs to shrink the context window.fixEmptyMessages identifies messages with empty text parts and injects placeholder text to satisfy API requirements.readMessages and readParts to inspect session state on disk or via SDK to determine where recovery is needed.Sources: packages/omo-opencode/src/shared/prompt-async-gate.ts1-29
Refresh this wiki
This wiki was recently refreshed. Please wait 1 day to refresh again.