contextEngine slot, and what it must still delegate. Part of the Plugin
architecture internals guide.
Context engine plugins
Context engine plugins own session context orchestration for ingest, assembly, and compaction. Register them from your plugin withapi.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.
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: