| // Context-engine public types define the pluggable context-management lifecycle. | |
| import type { AgentMessage } from "../../packages/agent-core/src/types.js"; | |
| import type { MemoryCitationsMode } from "../config/types.memory.js"; | |
| // Result types | |
| export type AssembleResult = { | |
| /** Ordered messages to use as model context */ | |
| messages: AgentMessage[]; | |
| /** Estimated total tokens in assembled context */ | |
| estimatedTokens: number; | |
| /** | |
| * Controls which token estimate the runner treats as authoritative for | |
| * preemptive overflow prechecks. The returned `messages` are always the | |
| * prompt sent to the model; this only affects the precheck's token comparison. | |
| * | |
| * - "assembled": the generic precheck uses only the assembled prompt's estimate | |
| * unless the engine owns compaction; owning engines manage prompt admission. | |
| * - "preassembly_may_overflow": the precheck takes the maximum of the | |
| * assembled estimate and the pre-assembly (unwindowed) session-history | |
| * estimate. Engines opt into this when their assembled view can hide an | |
| * overflow that would still affect the underlying transcript. This opt-in | |
| * keeps the generic precheck active even for engines that own compaction. | |
| * | |
| * Defaults to "assembled". | |
| */ | |
| promptAuthority?: "assembled" | "preassembly_may_overflow"; | |
| /** Optional context-engine-provided instructions prepended to the runtime system prompt */ | |
| systemPromptAddition?: string; | |
| /** | |
| * Optional projection lifecycle for hosts with persistent backend threads. | |
| * | |
| * Context engines that return `thread_bootstrap` ask the host to inject the | |
| * assembled context once for the supplied epoch, then reuse the backend | |
| * thread until the epoch changes. Engines that omit this field retain the | |
| * legacy per-turn projection behavior. | |
| */ | |
| contextProjection?: ContextEngineProjection; | |
| }; | |
| export type ContextEngineProjection = { | |
| /** How the assembled context should be projected into the backend runtime. */ | |
| mode: "per_turn" | "thread_bootstrap"; | |
| /** Stable context epoch. Changing this tells persistent backends to rotate. */ | |
| epoch?: string; | |
| /** Optional diagnostic fingerprint for the projected context payload. */ | |
| fingerprint?: string; | |
| }; | |
| export type ContextEngineOperation = "agent-run" | "manual-compact" | "subagent-spawn"; | |
| export type ContextEngineRuntimeMode = "normal" | "fallback" | "degraded"; | |
| export type ContextEngineSelectionSource = "configured" | "default" | "unknown"; | |
| export type ContextEngineRuntimeReasonCode = | |
| | "provider_timeout" | |
| | "provider_unavailable" | |
| | "rate_limited" | |
| | "context_overflow" | |
| | "runtime_unavailable" | |
| | "unknown"; | |
| export type ContextEngineHostCapability = | |
| | "bootstrap" | |
| | "assemble-before-prompt" | |
| | "after-turn" | |
| | "maintain" | |
| | "compact" | |
| | "runtime-llm-complete" | |
| | "thread-bootstrap-projection"; | |
| export type ContextEngineHostRequirements = { | |
| /** Host capabilities required before the engine can safely serve this operation. */ | |
| requiredCapabilities: ContextEngineHostCapability[]; | |
| /** Optional engine-authored guidance appended to the host compatibility error. */ | |
| unsupportedMessage?: string; | |
| }; | |
| export type ContextEngineRuntimeSettings = { | |
| schemaVersion: 1; | |
| runtime: { | |
| host: "openclaw"; | |
| mode: ContextEngineRuntimeMode; | |
| harnessId: string | null; | |
| runtimeId: string | null; | |
| }; | |
| model: { | |
| requested: string | null; | |
| resolved: string | null; | |
| provider: string | null; | |
| family: string | null; | |
| }; | |
| contextEngineSelection: { | |
| selectedId: string | null; | |
| source: ContextEngineSelectionSource; | |
| }; | |
| executionHost: { | |
| id: string | null; | |
| label: string | null; | |
| }; | |
| limits: { | |
| promptTokenBudget: number | null; | |
| maxOutputTokens: number | null; | |
| }; | |
| diagnostics: { | |
| fallbackReason: ContextEngineRuntimeReasonCode | null; | |
| degradedReason: ContextEngineRuntimeReasonCode | null; | |
| }; | |
| }; | |
| export type CompactResult = { | |
| ok: boolean; | |
| compacted: boolean; | |
| reason?: string; | |
| result?: { | |
| summary?: string; | |
| firstKeptEntryId?: string; | |
| tokensBefore: number; | |
| tokensAfter?: number; | |
| details?: unknown; | |
| /** Session id after compaction, when the runtime rotated transcripts. */ | |
| sessionId?: string; | |
| /** Typed post-compaction live session target; successor when the runtime rotated transcripts. */ | |
| sessionTarget?: ContextEngineSessionTarget; | |
| /** | |
| * Raw session file path after compaction. | |
| * | |
| * @deprecated Use `sessionTarget`. Shipped plugin-sdk contract: released | |
| * third-party context engines (v2026.6.x and earlier) report rotated | |
| * transcripts through this field. Remove once typed session targets are | |
| * the only successor contract. | |
| */ | |
| sessionFile?: string; | |
| }; | |
| }; | |
| /** | |
| * Resolve the post-compaction live transcript identity from a compact result. | |
| * | |
| * Prefers the typed `sessionTarget`. Reading the raw fields is the named | |
| * compat path for shipped third-party engines that predate `sessionTarget`; | |
| * it is removed together with the deprecated `sessionFile` result field. | |
| */ | |
| export function resolveCompactionSuccessorTranscript(result: CompactResult): { | |
| sessionId?: string; | |
| sessionFile?: string; | |
| } { | |
| const target = result.result?.sessionTarget; | |
| return { | |
| sessionId: target?.sessionId ?? result.result?.sessionId, | |
| // Storage-neutral targets carry no raw locator; the deprecated raw field on | |
| // the result remains the only file-era locator shipped engines report. | |
| sessionFile: result.result?.sessionFile, | |
| }; | |
| } | |
| export type IngestResult = { | |
| /** Whether the message was ingested (false if duplicate or no-op) */ | |
| ingested: boolean; | |
| }; | |
| export type IngestBatchResult = { | |
| /** Number of messages ingested from the supplied batch */ | |
| ingestedCount: number; | |
| }; | |
| export type BootstrapResult = { | |
| /** Whether bootstrap ran and initialized the engine's store */ | |
| bootstrapped: boolean; | |
| /** Number of historical messages imported (if applicable) */ | |
| importedMessages?: number; | |
| /** Optional reason when bootstrap was skipped */ | |
| reason?: string; | |
| }; | |
| export type ContextEngineInfo = { | |
| id: string; | |
| name: string; | |
| version?: string; | |
| acceptedHostParams?: string[]; | |
| transcriptSemantics?: { | |
| currentTurnFence?: "before-current-turn-entry-v1"; | |
| turnAdvancementIdempotency?: "atomic-idempotent-v1"; | |
| }; | |
| /** True when the engine manages its own compaction lifecycle. */ | |
| ownsCompaction?: boolean; | |
| /** | |
| * Controls how turn-triggered maintenance should be executed. | |
| * | |
| * Engines remain compatible by default unless the host explicitly opts into | |
| * background turn maintenance. | |
| */ | |
| turnMaintenanceMode?: "foreground" | "background"; | |
| /** | |
| * Host capability requirements for operations where using an unsupported | |
| * runtime would silently degrade or corrupt the engine's behavior. | |
| */ | |
| hostRequirements?: Partial<Record<ContextEngineOperation, ContextEngineHostRequirements>>; | |
| }; | |
| export type SubagentSpawnPreparation = { | |
| /** Roll back pre-spawn setup when subagent launch fails. */ | |
| rollback: () => void | Promise<void>; | |
| }; | |
| export type SubagentEndReason = "deleted" | "completed" | "swept" | "released"; | |
| export type TranscriptRewriteReplacement = { | |
| /** Existing transcript entry id to replace on the active branch. */ | |
| entryId: string; | |
| /** Replacement message content for that entry. */ | |
| message: AgentMessage; | |
| }; | |
| // Local-only: engines consume this shape structurally via rewriteTranscriptEntries; | |
| // the last named importer was the deleted destructive rewrite path (#115271). | |
| type TranscriptRewriteRequest = { | |
| /** Message entry replacements to apply in one branch-and-reappend pass. */ | |
| replacements: TranscriptRewriteReplacement[]; | |
| /** Optional entry-id set that must cover every active-branch entry from the first replacement onward. */ | |
| allowedRewriteSuffixEntryIds?: string[]; | |
| }; | |
| export type TranscriptRewriteResult = { | |
| /** Whether the active branch changed. */ | |
| changed: boolean; | |
| /** Estimated bytes removed from the active branch message payloads. */ | |
| bytesFreed: number; | |
| /** Number of transcript message entries rewritten. */ | |
| rewrittenEntries: number; | |
| /** Optional reason when no rewrite occurred. */ | |
| reason?: string; | |
| }; | |
| export type ContextEngineMaintenanceResult = TranscriptRewriteResult; | |
| type ContextEnginePromptCacheRetention = "none" | "short" | "long" | "in_memory" | "24h"; | |
| type ContextEnginePromptCacheUsage = { | |
| input?: number; | |
| output?: number; | |
| cacheRead?: number; | |
| cacheWrite?: number; | |
| contextUsage?: | |
| | { state: "available"; promptTokens: number; totalTokens: number } | |
| | { state: "unavailable" }; | |
| total?: number; | |
| }; | |
| type ContextEnginePromptCacheObservationChangeCode = | |
| | "aggregateToolResultTruncation" | |
| | "cacheRetention" | |
| | "model" | |
| | "streamStrategy" | |
| | "systemPrompt" | |
| | "tools" | |
| | "transport"; | |
| type ContextEnginePromptCacheObservationChange = { | |
| code: ContextEnginePromptCacheObservationChangeCode; | |
| detail: string; | |
| }; | |
| type ContextEnginePromptCacheObservation = { | |
| broke: boolean; | |
| previousCacheRead?: number; | |
| cacheRead?: number; | |
| changes?: ContextEnginePromptCacheObservationChange[]; | |
| }; | |
| export type ContextEnginePromptCacheInfo = { | |
| /** Runtime-resolved retention for the actual provider/model/request path. */ | |
| retention?: ContextEnginePromptCacheRetention; | |
| /** Usage from the most recent API call, not accumulated retry/tool-loop totals. */ | |
| lastCallUsage?: ContextEnginePromptCacheUsage; | |
| /** Result from the runtime's prompt-cache observability heuristic. */ | |
| observation?: ContextEnginePromptCacheObservation; | |
| /** Last known cache-touch timestamp from runtime-managed cache-TTL bookkeeping. */ | |
| lastCacheTouchAt?: number; | |
| /** Known cache expiry time when the runtime can source it confidently. */ | |
| expiresAt?: number; | |
| }; | |
| type ContextEngineTranscriptStorageInfo = { | |
| /** | |
| * Authoritative transcript backend for this runtime turn. | |
| * | |
| * Hosts may still pass legacy locator fields such as `sessionFile` for older | |
| * plugin contracts, but context engines should use this field to decide | |
| * whether that locator is a live transcript source. | |
| */ | |
| kind: "sqlite"; | |
| }; | |
| export type ContextEngineSessionTarget = { | |
| /** Agent that owns the session in the runtime store. */ | |
| agentId?: string; | |
| /** Runtime session id to compact. */ | |
| sessionId?: string; | |
| /** Stable session key used for aliases, policy, and store resolution. */ | |
| sessionKey?: string; | |
| /** Session store path that scopes the SQLite-backed runtime session. */ | |
| storePath?: string; | |
| /** Optional transport thread identity for session target resolution. */ | |
| threadId?: string | number; | |
| }; | |
| export type ContextEngineRuntimeContext = Record<string, unknown> & { | |
| /** Runtime task working directory; workspaceDir remains the agent bootstrap workspace. */ | |
| cwd?: string; | |
| /** | |
| * True when the host has explicitly opted this maintenance run into | |
| * consuming deferred compaction debt. | |
| */ | |
| allowDeferredCompactionExecution?: boolean; | |
| /** Runtime-resolved context window budget for the active model call. */ | |
| tokenBudget?: number; | |
| /** Selected agent harness id when compaction delegates back to the runtime. */ | |
| agentHarnessId?: string; | |
| /** Best-effort current prompt/context token estimate for this turn. */ | |
| currentTokenCount?: number; | |
| /** Optional prompt-cache telemetry for cache-aware engines. */ | |
| promptCache?: ContextEnginePromptCacheInfo; | |
| /** Authoritative transcript backend for this turn. */ | |
| transcriptStorage?: ContextEngineTranscriptStorageInfo; | |
| /** Storage-neutral runtime session target for compaction delegation. */ | |
| sessionTarget?: ContextEngineSessionTarget; | |
| /** | |
| * Safe transcript rewrite helper implemented by the runtime. | |
| * | |
| * Engines decide what is safe to rewrite; the runtime owns how the session | |
| * DAG is updated on disk. | |
| */ | |
| rewriteTranscriptEntries?: ( | |
| request: TranscriptRewriteRequest, | |
| ) => Promise<TranscriptRewriteResult>; | |
| /** LLM completion capability for engines that need model inference. */ | |
| llm?: { | |
| complete: ( | |
| params: import("../plugins/runtime/types-core.js").LlmCompleteParams, | |
| ) => Promise<import("../plugins/runtime/types-core.js").LlmCompleteResult>; | |
| }; | |
| }; | |
| /** | |
| * ContextEngine defines the pluggable contract for context management. | |
| * | |
| * Required methods define a generic lifecycle; optional methods allow engines | |
| * to provide additional capabilities (retrieval, lineage, etc.). | |
| */ | |
| export interface ContextEngine { | |
| /** Engine identifier and metadata */ | |
| readonly info: ContextEngineInfo; | |
| /** | |
| * Initialize engine state for a session, optionally importing historical context. | |
| */ | |
| bootstrap?(params: { | |
| sessionId: string; | |
| sessionKey?: string; | |
| /** Storage-neutral runtime session target for transcript/session SDK helpers. */ | |
| sessionTarget?: ContextEngineSessionTarget; | |
| sessionFile: string; | |
| runtimeSettings?: ContextEngineRuntimeSettings; | |
| runtimeContext?: ContextEngineRuntimeContext; | |
| }): Promise<BootstrapResult>; | |
| /** | |
| * Run transcript maintenance after bootstrap, successful turns, or compaction. | |
| * | |
| * Engines can use runtimeContext.rewriteTranscriptEntries() to request safe | |
| * branch-and-reappend transcript rewrites without depending on runner internals. | |
| */ | |
| maintain?(params: { | |
| sessionId: string; | |
| sessionKey?: string; | |
| /** Storage-neutral runtime session target for transcript/session SDK helpers. */ | |
| sessionTarget?: ContextEngineSessionTarget; | |
| sessionFile: string; | |
| runtimeSettings?: ContextEngineRuntimeSettings; | |
| runtimeContext?: ContextEngineRuntimeContext; | |
| /** | |
| * Optional caller cancellation for maintenance work that may block. | |
| * Engines should reject promptly when this signal aborts. | |
| */ | |
| abortSignal?: AbortSignal; | |
| }): Promise<ContextEngineMaintenanceResult>; | |
| /** | |
| * Ingest a single message into the engine's store. | |
| */ | |
| ingest(params: { | |
| sessionId: string; | |
| sessionKey?: string; | |
| message: AgentMessage; | |
| /** True when the message belongs to a heartbeat run. */ | |
| isHeartbeat?: boolean; | |
| }): Promise<IngestResult>; | |
| /** | |
| * Ingest a completed turn batch as a single unit. | |
| */ | |
| ingestBatch?(params: { | |
| sessionId: string; | |
| sessionKey?: string; | |
| messages: AgentMessage[]; | |
| /** True when the batch belongs to a heartbeat run. */ | |
| isHeartbeat?: boolean; | |
| }): Promise<IngestBatchResult>; | |
| /** | |
| * Execute optional post-turn lifecycle work after a run attempt completes. | |
| * Engines can use this to persist canonical context and trigger background | |
| * compaction decisions. | |
| */ | |
| afterTurn?(params: { | |
| sessionId: string; | |
| sessionKey?: string; | |
| /** Storage-neutral runtime session target for transcript/session SDK helpers. */ | |
| sessionTarget?: ContextEngineSessionTarget; | |
| sessionFile: string; | |
| messages: AgentMessage[]; | |
| /** Number of messages that existed before the prompt was sent. */ | |
| prePromptMessageCount: number; | |
| /** Optional auto-compaction summary emitted by the runtime. */ | |
| autoCompactionSummary?: string; | |
| /** True when this turn belongs to a heartbeat run. */ | |
| isHeartbeat?: boolean; | |
| /** Optional model context token budget for proactive compaction. */ | |
| tokenBudget?: number; | |
| /** Optional runtime-owned context for engines that need caller state. */ | |
| runtimeSettings?: ContextEngineRuntimeSettings; | |
| runtimeContext?: ContextEngineRuntimeContext; | |
| }): Promise<void>; | |
| /** | |
| * Atomically and idempotently commit one accepted durable transcript turn. | |
| * Messages span the admitted user entry through the accepted terminal entry. | |
| * Hosts may retry the same advancement key after process or plugin failure. | |
| */ | |
| commitTurn?(params: { | |
| advancementKey: string; | |
| admission: import("../config/sessions/transcript-entry-anchor.js").TranscriptTurnAdmission; | |
| terminal: import("../config/sessions/transcript-entry-anchor.js").TranscriptEntryAnchor; | |
| messages: AgentMessage[]; | |
| sessionId: string; | |
| sessionKey?: string; | |
| sessionTarget?: ContextEngineSessionTarget; | |
| runtimeSettings?: ContextEngineRuntimeSettings; | |
| runtimeContext?: ContextEngineRuntimeContext; | |
| isHeartbeat?: boolean; | |
| }): Promise<{ status: "committed" | "duplicate" }>; | |
| /** | |
| * Assemble model context under a token budget. | |
| * Returns an ordered set of messages ready for the model. | |
| */ | |
| assemble(params: { | |
| sessionId: string; | |
| sessionKey?: string; | |
| messages: AgentMessage[]; | |
| tokenBudget?: number; | |
| /** Tool names available for this run so engines can align prompt guidance with runtime tool access. */ | |
| availableTools?: Set<string>; | |
| /** Active memory citation mode when engines want to mirror memory prompt guidance. */ | |
| citationsMode?: MemoryCitationsMode; | |
| /** Current model identifier (e.g. "claude-opus-4", "gpt-4o", "qwen2.5-7b"). | |
| * Allows context engine plugins to adapt formatting per model. */ | |
| model?: string; | |
| /** The incoming user prompt for this turn (useful for retrieval-oriented engines). */ | |
| prompt?: string; | |
| runtimeSettings?: ContextEngineRuntimeSettings; | |
| runtimeContext?: ContextEngineRuntimeContext; | |
| }): Promise<AssembleResult>; | |
| /** | |
| * Compact context to reduce token usage. | |
| * May create summaries, prune old turns, etc. | |
| * | |
| * The host always bounds this call with a finite safety timeout (the same | |
| * one that protects native runtime compaction). Engines that run long | |
| * operations SHOULD additionally honor `abortSignal` so an in-flight | |
| * compaction can be canceled promptly on run abort or host timeout instead | |
| * of running to completion in the background. | |
| */ | |
| compact(params: { | |
| sessionId: string; | |
| sessionKey: string; | |
| /** Caller-resolved owner agent for global session aliases. */ | |
| agentId?: string; | |
| /** Storage-neutral runtime session target for delegated compaction. */ | |
| sessionTarget?: ContextEngineSessionTarget; | |
| tokenBudget?: number; | |
| /** Force compaction even below the default trigger threshold. */ | |
| force?: boolean; | |
| /** Optional live token estimate from the caller's active context. */ | |
| currentTokenCount?: number; | |
| /** Controls convergence target; defaults to budget. */ | |
| compactionTarget?: "budget" | "threshold"; | |
| customInstructions?: string; | |
| /** Optional runtime-owned context for engines that need caller state. */ | |
| runtimeSettings?: ContextEngineRuntimeSettings; | |
| runtimeContext?: ContextEngineRuntimeContext; | |
| /** | |
| * Optional abort signal honored before and during compaction. The host | |
| * aborts it on run-level abort or when its compaction safety timeout | |
| * fires; engines should stop work and reject promptly when it aborts. | |
| */ | |
| abortSignal?: AbortSignal; | |
| }): Promise<CompactResult>; | |
| /** | |
| * Prepare context-engine-managed subagent state before the child run starts. | |
| * | |
| * Implementations can return a rollback handle that is invoked when spawn | |
| * fails after preparation succeeds. | |
| */ | |
| prepareSubagentSpawn?(params: { | |
| parentSessionKey: string; | |
| childSessionKey: string; | |
| contextMode?: "isolated" | "fork"; | |
| parentSessionId?: string; | |
| parentSessionFile?: string; | |
| childSessionId?: string; | |
| childSessionFile?: string; | |
| ttlMs?: number; | |
| }): Promise<SubagentSpawnPreparation | undefined>; | |
| /** | |
| * Notify the context engine that a subagent lifecycle ended. | |
| */ | |
| onSubagentEnded?(params: { childSessionKey: string; reason: SubagentEndReason }): Promise<void>; | |
| /** | |
| * Dispose of any resources held by the engine. | |
| */ | |
| dispose?(): Promise<void>; | |
| } | |