UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

112 lines (99 loc) • 3.77 kB
--- summary: "Registering a context engine plugin that owns session ingest, assembly, and compaction" read_when: - Adding a context engine plugin - You are replacing or extending the default context pipeline - You need to delegate compaction back to the runtime title: "Context engines" sidebarTitle: "Context engines" --- How a plugin takes over session context orchestration through the `contextEngine` slot, and what it must still delegate. Part of the [Plugin architecture internals](/plugins/architecture-internals) guide. ## Context engine plugins Context engine plugins own session context orchestration for ingest, assembly, and compaction. Register them from your plugin with `api.registerContextEngine(id, factory)`, then select the active engine with `plugins.slots.contextEngine`. Use this when your plugin needs to replace or extend the default context pipeline rather than just add memory search or hooks. ```ts import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core"; export default function (api) { api.registerContextEngine("lossless-claw", (ctx) => ({ info: { id: "lossless-claw", name: "Lossless Claw", ownsCompaction: true, acceptedHostParams: ["sessionKey"], }, async ingest() { return { ingested: true }; }, async assemble({ messages, sessionKey, availableTools, citationsMode }) { return { messages, estimatedTokens: 0, systemPromptAddition: buildMemorySystemPromptAddition({ availableTools: availableTools ?? new Set(), citationsMode, agentSessionKey: sessionKey, }), }; }, async compact() { return { ok: true, compacted: false }; }, })); } ``` The factory `ctx` exposes optional `config`, `agentDir`, and `workspaceDir` values for construction-time initialization. The host completes registered async memory prompt preparation before calling a non-legacy engine's `assemble()`. `buildMemorySystemPromptAddition(...)` stays synchronous and reads that immutable run snapshot while `assemble()` is active. Pass the supplied tool and citation context through unchanged so the snapshot cannot cross run boundaries. `assemble()` may return `contextProjection` when the active harness has a persistent backend thread. Omit it for legacy per-turn projection. Return `{ mode: "thread_bootstrap", epoch }` when the assembled context should be injected once into a backend thread and reused until the epoch changes. Change the epoch after the engine's semantic context changes, such as after an engine-owned compaction pass. Hosts may preserve tool-call metadata, input shape, and redacted tool results in a thread-bootstrap projection so fresh backend threads retain tool continuity without copying raw secret-bearing payloads. If your engine does **not** own the compaction algorithm, keep `compact()` implemented and delegate it explicitly: ```ts import { buildMemorySystemPromptAddition, delegateCompactionToRuntime, } from "openclaw/plugin-sdk/core"; export default function (api) { api.registerContextEngine("my-memory-engine", (ctx) => ({ info: { id: "my-memory-engine", name: "My Memory Engine", ownsCompaction: false, }, async ingest() { return { ingested: true }; }, async assemble({ messages, sessionKey, availableTools, citationsMode }) { return { messages, estimatedTokens: 0, systemPromptAddition: buildMemorySystemPromptAddition({ availableTools: availableTools ?? new Set(), citationsMode, agentSessionKey: sessionKey, }), }; }, async compact(params) { return await delegateCompactionToRuntime(params); }, })); } ```