三件事,因为改动在 plan.service / execution.service / types 里交织,合成一次提交。
## 1. fix:话术自报家门串名(线上 bug)
现象:登录人是李倩,话术却写"我是本诊所的客服主管晋芳辰"。
根因:登录客服姓名被烤进 LLM 生成的正文,而 plan_scripts 的 UNIQUE 是 plan_id
(一个 plan 一份话术、不分人),召回池又是共享的 —— 谁先打开触发生成,
姓名就固化给后面所有人看。线上 44 条话术 100% 中招,是必然不是偶发。
解法:姓名不进 LLM,改「生成期占位 → 渲染期回填」
- 新增 shared/agent-identity.ts 作单一源(占位符 + resolveScriptAgent + renderAgentIdentity)
- 稳健/标准/深度三档 prompt 与 format.md 统一输出 【回访客服】(沿用 v8 立的
`{}`=填空 / `【】`=原样保留 的约定,归第二类)
- 四个出口渲染回填:详情聚合、strict Zod 详情、同步重生成、SSE 流式
- DraftPlanScriptInput 去掉 agent 字段
副作用(正向):input_hash 不再含人名 → 同一 plan 不同客服共享 AI 缓存;
工单转派后名字自动跟着换,不用重生成。
三档实跑验证模型都保留了占位符;浏览器验证同一份缓存对两个登录人显示各自姓名。
⚠ ️ 存量 44 条仍是旧正文,需部署后逐条重生成(dist/cli/ai-gen-script.cli.js)。
## 2. refactor:删 plan_executions 两个死字段
- invalid_reason 从没被写过(pac-web 零引用),读回路径也没带它
- abandon_other 写得进没人读,且信息恒冗余 —— 放弃原因是固定复选框无自由文本,
该列只可能取到字面量"其他",而 abandon_reasons 已含 'other'
生产 0 行受影响(执行总数 2,两列全空)。
## 3. feat:宿主回访模式的「关闭机会」闭环
瑞尔侧回访在宿主系统做,PAC 只提供关闭入口做闭环。**刻意不引入新概念**:
不加 closed outcome、不加 close_reasons 列、不加 plan 状态 —— 关闭就是
outcome='abandoned' + abandon_reasons,跟 PAC 自带表单同一条路、同一列。
分叉只在展示层(ABANDON_REASON_META.shownIn,两个面板各渲染各的子集)。
- AbandonReason 扩成两种模式的并集;近义项不合并(两模式按 host 配置二选一、
运行时不共存,同一 host 只出现自己那套 key,统计不会碎)
- 关闭弹窗改多选无上限;「其他」说明写 notes,不另立列
- 原因级抑制窗:各原因 suppressDays 取 max(每个原因独立成立,取最严的);
未配的沿用 outcome 默认 60d,行为跟改造前一致
- 「识别不准确」不再双写 recall_feedback(该表留给拇指控件那条路)
- outcome-form 的中文硬编码数组 + 中译映射表删除,key/label 改为同源
(那张表里「已转介他人→treated_elsewhere」是语义错位)
## 文档
新增「取数说明」(pac-docs)—— 给 DW 团队自助查生产 PG:召回池筛选条件、
关闭操作落表、数据范围过滤(品牌/诊所/时间)、字段字典、常用 SQL。
291 tests passed;service + web 双端 typecheck 干净。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>