/** * 提示词模板的渲染内核:七份模板统一走 Handlebars。 * * `noEscape` 是必须的——提示词是打进终端的纯文本,默认的 HTML 转义会把 * 引号、`&`、`<` 变成实体,cc 收到的就是一堆 `"`。 * * 这个模块刻意不碰 vscode / 文件系统,方便单测直接跑。 */ import Handlebars from 'handlebars' export type PromptContext = Record /** * 模板上下文 = 工单 state JSON 全量字段 + 调用方补的那几个变量。 * * `extra` 里值为 undefined 的键直接丢掉:否则 `{ planFile: undefined }` 会把 * state 里真有的 planFile 盖成空。 */ export function buildPromptContext(state: PromptContext | undefined, extra: PromptContext): PromptContext { const out: PromptContext = { ...(state ?? {}) } for (const [k, v] of Object.entries(extra)) { if (v !== undefined) out[k] = v } return out } /** 渲染模板;模板有语法错误时抛错,由调用方决定怎么兜。 */ export function renderPromptTemplate(tpl: string, context: PromptContext): string { return Handlebars.compile(tpl, { noEscape: true })(context) }