插件贡献有序的 section、动态 context、tool schema 与命名变量;agent 循环每步组装一次并把结果渲染为完整模型提示词。 agent 作用域的 persona 可 shadow 全局默认。
ctx.systemPrompt
2 个 src 文件 · 695 行(最小核心包)
Service 类插件(默认导出 SystemPrompt)
Config: includeHarnessIdentity · includeRuntimeContext · persona · toolOrder
| 项 | 内容 |
|---|---|
| Service | SystemPrompt extends Service,super(ctx, 'systemPrompt');无 inject(纯 Service 插件) |
| Config | includeHarnessIdentity(默认 true,身份 opener)/ includeRuntimeContext(默认 true)/ persona(全局 order-0 persona 模板,空则丢弃)/ toolOrder(显式模型可见工具顺序,必须含恰好一个 '<unlisted-tools>' rest 项,省略则字典序) |
| 事件 | system-prompt/assemble(waterfall,scope 过滤)+ system-prompt/change(emit,全局 unfiltered —— 全局变更影响每个 scope) |
| 常量 | PERSONA_SECTION = 'deployment:persona'、PERSONA_ORDER = 0、TOOL_ORDER_REST = '<unlisted-tools>' |
// 五个注册 API(全部走 ScopedLayers.effect → 返回精确 disposer) section(section: PromptSection): () => void context(context: PromptContext): () => void // 动态 context 贡献,按 order 升序 suppressRuntimeContext(): () => void tools(provider): () => void // { schemas, knownNames? } variable(name, provider): () => void // /^[a-z][a-z0-9_]*$/ assemble(context?: AssembleContext): Promise<PromptAssembly>
{ name, order, text | ((context) => string), complete? } —— name 唯一;order 升序拼接(约定 -100 身份、0 persona、100-199 工具指导);complete: true = 完整提示词{ sections, contexts, tools, variables },merge-extensible{ scope?, signal? },merge-extensible;dsh-agent 声明 agent? DX 字段(经 assembleContextFor 一起设置,绝不单独)complete section(>1 个同时有效 → assemble 拒绝)与 runtimeContextSuppressed(contexts 强制 [])。
toolOrder === undefined → 字典序(码元比较,机器无关);配置了 toolOrder → 未注册名抛错(load 时只校验形状,未注册名在首个 turn 才抛)、
listed 项按序放置、未列出工具在 rest 项处以字典序插入。provider 返回保留名 TOOL_ORDER_REST 本身 → 抛错。
renderPrompt:逐 section 插值 → 丢弃空文本 → '\n\n' 拼接{{ —— {{ 无 }} 是字面量;{{}}/{{{x}}} 是错误;Object.hasOwn 查表防原型链({{constructor}} 是未知);undefined 值 → 抛错;替换值不再被扫描以 { global: true, prepend: true } 挂 system-prompt/assemble,对瀑布权威返回值校验:section/context 名称非空且层内唯一、text 为 string;tool 名称非空;变量名匹配、值为 string 或 undefined。
ctx.systemPrompt.section({ name, order, text, complete? });命名约定 owner:role(harness:identity / deployment:persona / tool:bash);order 分带 -100 身份、0 persona、100-199 工具指导 —— 同 order 按注册顺序,确定性依赖分带约定deployment:persona 即替换部署 persona);经 agent.ctx 注册即 agent-local;要彻底移除(而非替换)只能在瀑布里改 assembly.sections(无删除 API)complete: true 的 section 在 waterfall 后成为唯一 section(工具/context/变量仍解析)ctx.systemPrompt.tools(ctx => ({ schemas, knownNames? })) —— ToolRuntime 自动注册自身为 provider;restriction 后可见集合放 schemas,knownNames 放 restriction 前全集供 toolOrder;不要返回 'ctx.systemPrompt.variable('cwd', ctx => process.cwd()),文本里 {{cwd}} 引用;loop 已注册 model/cwd;返回 undefined = 本组装无值,引用它的 section 渲染失败ctx.on('system-prompt/assemble', ...)(waterfall,必须调 next());从 agent.ctx 注册只影响该 agent{{ 无 }} 是字面量 —— 没有花括号转义语法ToolRuntime.restrict() 而非在瀑布里改 tools