# System Prompt Assembly English | [中文](system-prompt.zh.md) The [system-prompt package](../../packages/core/system-prompt) owns the data exchanged between prompt contributors and one assembly call. The package [README](../../packages/core/system-prompt/README.md) documents registration, ordering, scoping, and rendering behavior; this page records the exact cross-package types that plugins implement or pass. Source: [`packages/core/system-prompt/src/index.ts`](../../packages/core/system-prompt/src/index.ts). ## Assembly context `AssembleContext` identifies the scope layer one assembly resolves and may carry the explicit control signal for that request. It is merge-extensible: `dsh-agent` adds the optional live `agent` field, and `assembleContextFor(agent, signal)` sets the explicit fields together. A bare assembly has neither scope nor signal. ```ts type-equiv /** Merge-extensible context for one prompt assembly. */ interface AssembleContext { /** * Scope whose providers and waterfall listeners participate. When absent, * only global providers and subject-less listeners participate. */ scope?: ScopeKey /** Explicit control signal for the turn that requested this assembly, when any. */ signal?: AbortSignal } ``` ## Tool-provider result `ToolProviderResult.schemas` is the model-visible set for the current assembly. `knownNames` is the provider's pre-restriction name universe used to distinguish a configured-name typo from a known tool that is deliberately hidden in this scope. ```ts type-equiv /** Tool schemas visible in one assembly and their pre-restriction name set. */ interface ToolProviderResult { /** The schemas this provider contributes to THIS assembly. */ readonly schemas: readonly ToolSchema[] /** The pre-restriction name universe for config validation (defaults to `schemas`' names). */ readonly knownNames?: readonly string[] } ``` ## Prompt sections `PromptSection` is a readonly same-process registration contract. Its text may be static or resolved from the current assembly context. ```ts type-equiv /** One contributed section of the system prompt (registry input). */ interface PromptSection { /** Unique name — a duplicate registration throws (see {@link SystemPrompt.section}). */ readonly name: string /** * Sections are concatenated in ascending order. Convention: `-100` is the * harness identity, `0` the deployment persona, tool guidance uses 100–199; * other negative orders also render before the persona. */ readonly order: number /** * Static text or a provider evaluated at each assembly with that assembly's * {@link AssembleContext}. The text may reference `{{variable}}`s — they are * interpolated later, by {@link renderPrompt}. */ readonly text: string | ((context: AssembleContext) => string) } ``` ## Dynamic prompt context `PromptContext` is the cache-safe counterpart to `PromptSection`. The assembly resolves and orders these contributions, while agent-loop logs their complete current snapshot after retained model history only when it changed or compaction removed it. ```ts type-equiv /** Dynamic model context materialized as a durable user-role snapshot. */ interface PromptContext { /** Unique name — a duplicate registration throws (see {@link SystemPrompt.context}). */ readonly name: string /** Contexts are joined in ascending order. */ readonly order: number /** Static text or a provider evaluated for each assembly. Empty text contributes nothing. */ readonly text: string | ((context: AssembleContext) => string) } ``` ## Cordis surface Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` surface lives in [cordis-api/inherited.md](../cordis-api/inherited.md). ### `ctx.systemPrompt` — `SystemPrompt` Registry service for the prompt inputs assembled before each model step. ```ts cordis-catalog /** * Register an ordered prompt section in the calling context's scope. A scoped * section shadows a global section with the same name; duplicates within one * layer and non-finite orders throw. Registration and disposal emit * `system-prompt/change`. * @param section - the section to register. * @returns the exact Cordis effect disposer. */ section(section: PromptSection): () => void /** * Register ordered dynamic context in the calling context's scope. Scoped * entries shadow global entries with the same name. * @param context - the context contribution to register. * @returns the exact Cordis effect disposer. */ context(context: PromptContext): () => void /** * Register a tool-schema provider in the calling context's scope. Global and * matching scoped providers both contribute; returning the reserved * {@link TOOL_ORDER_REST} name makes assembly fail. * @param provider - evaluated for each assembly with its context. * @returns the exact Cordis effect disposer. */ tools(provider: (context: AssembleContext) => ToolProviderResult): () => void /** * Register a prompt variable in the calling context's scope. Scoped values * shadow globals; invalid or duplicate names throw. A provider may return * `undefined`, but rendering a section that references that value then fails. * @param name - the `[a-z][a-z0-9_]*` reference name. * @param provider - evaluated for each assembly. * @returns the exact Cordis effect disposer. */ variable(name: string, provider: (context: AssembleContext) => string | undefined): () => void /** * Assemble global and scoped providers, detach tool parameters, apply * canonical ordering, then run the assembly waterfall. Scoped sections and * variables shadow globals; the returned waterfall value is authoritative. * @param context - the optional scope and plugin-defined assembly fields. * @returns the authoritative post-waterfall assembly. */ async assemble(context: AssembleContext = {}): Promise ``` Source: [`packages/core/system-prompt/src/index.ts:325`](../../packages/core/system-prompt/src/index.ts) ### `system-prompt/*` events #### `system-prompt/assemble` — waterfall Expert waterfall over the assembled sections, contexts, tools, and variables. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners receive only that scope's assemblies. The returned value is authoritative. A supplied signal controls only this explicit assembly request and must not be retained to control later turns. ```ts cordis-catalog /** * Expert waterfall over the assembled sections, contexts, tools, and variables. * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners * receive only that scope's assemblies. The returned value is authoritative. * A supplied signal controls only this explicit assembly request and must not * be retained to control later turns. * @param assembly - the mutable assembly built from registered providers. * @param context - the caller's per-assembly context. * @mode waterfall */ 'system-prompt/assemble'(this: Scoped, assembly: PromptAssembly, context: AssembleContext, next: () => Promise): Promise ``` Types: [Scoped](scope.md) Source: [`packages/core/system-prompt/src/index.ts:29`](../../packages/core/system-prompt/src/index.ts) #### `system-prompt/change` — emit Emitted when any prompt provider changes. This registry notification is unfiltered because a global change affects every scope. ```ts cordis-catalog /** * Emitted when any prompt provider changes. This registry notification is * unfiltered because a global change affects every scope. * @mode emit */ 'system-prompt/change'(): void ``` Source: [`packages/core/system-prompt/src/index.ts:35`](../../packages/core/system-prompt/src/index.ts)