feat(frontend): 润色再沟通接入 AI 反问澄清——选项芯片 + 折答案回炉(WFW-9 M1)
RefinePanel「再沟通」升级为对话式:意见含糊/极短(门控 <10 字,或点「帮我理清方向」)时先调 clarify 预检端点让 AI 反问,渲染 ChoiceChips 选项芯片(+自由输入兜底);作者选/答后 foldClarifications 把答案折进 instruction,再走既有 refine 回炉(零迁移)。清晰意见直接回炉、 不交往返税;预检失败=放行(useClarify 视 error/异常为 needClarification=false,不阻塞润色)。 新增:lib/workbench/clarify.ts(VM 类型+foldClarifications+needsClarifyGate 纯逻辑) + useClarify(SSE 外调映射 snake→VM) + ChoiceChips.tsx;gen:api 重生成客户端。 门禁绿:tsc/lint/vitest 654(+clarify/useClarify 18 例)/build/coverage 95.36%。
This commit is contained in:
173
apps/web/lib/api/schema.d.ts
vendored
173
apps/web/lib/api/schema.d.ts
vendored
@@ -429,6 +429,33 @@ export interface paths {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/projects/{project_id}/chapters/{chapter_no}/refine/clarify": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/**
|
||||
* Clarify Refine
|
||||
* @description 润色预检澄清(WFW-9 M1 路线A 两阶段之「问题」阶段):非流式 JSON,只判不改。
|
||||
*
|
||||
* 独立于既有 refine 端点——只判「作者这条再沟通意见清不清楚」,含糊则反问 1 问 + 给选项,
|
||||
* 清楚则给确认语放行;**绝不改正文**(正文仍走 refine 端点)。analyst 档(不变量 #2)。
|
||||
*
|
||||
* 项目不存在 → 404;无凭据 → 503(dep 解析阶段拦下)。**只读不写库**(不变量 #3);
|
||||
* 末尾 `commit()` 让网关 usage_ledger 落库(add-only,否则记账静默丢失,同 refine 纪律)。
|
||||
* 判别/校验失败在 `run_clarify` 内确定性回退 `need_clarification=false`(不阻塞润色)。
|
||||
*/
|
||||
post: operations["clarify_refine_projects__project_id__chapters__chapter_no__refine_clarify_post"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/templates": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -1109,6 +1136,81 @@ export interface components {
|
||||
/** Note */
|
||||
note?: string | null;
|
||||
};
|
||||
/**
|
||||
* ClarifyDecision
|
||||
* @description 润色预检澄清决策(结构化 LLM 输出 + API 响应)。
|
||||
*
|
||||
* 路线A 两阶段之「问题」阶段:仅判定「要不要反问」并给选项,**不改正文**(正文仍走
|
||||
* 既有 refine 端点)。纯只读(`clarify_refine_spec.writes=()`,不变量 #3)。
|
||||
*
|
||||
* **全字段给默认值守解析韧性**(仿 `StyleDriftReview` 降级范式):LLM 漏产/畸形时
|
||||
* 降级为 `need_clarification=false`(不问、直接放行 refine),绝不阻塞润色主链路。
|
||||
*
|
||||
* - `need_clarification=false` → `questions` 为空、可给一句 `verification` 确认语;
|
||||
* - `need_clarification=true` → `questions` 恰 1 问(v1 硬上限)、`verification` 可空。
|
||||
*/
|
||||
ClarifyDecision: {
|
||||
/**
|
||||
* Need Clarification
|
||||
* @description 是否需要向作者反问澄清(含糊/多走法→true;明确→false)
|
||||
* @default false
|
||||
*/
|
||||
need_clarification: boolean;
|
||||
/**
|
||||
* Questions
|
||||
* @description 反问清单(need_clarification=false 时为空;v1 硬上限 1 问)
|
||||
*/
|
||||
questions?: components["schemas"]["ClarifyQuestion"][];
|
||||
/**
|
||||
* Verification
|
||||
* @description 明确时的一句『我这样理解对吗』确认语(need_clarification=false 时给,可空)
|
||||
*/
|
||||
verification?: string | null;
|
||||
};
|
||||
/**
|
||||
* ClarifyOption
|
||||
* @description 单个澄清选项:展示文案 + 选中回填值(锚定本段/本章的一种具体走法)。
|
||||
*
|
||||
* `value` = 作者选中后折进 refine instruction 字符串的内容(零迁移,不落库)。
|
||||
* 凑不出具体可区分选项时退化为空 options(`ClarifyQuestion.options=[]`),突出自由输入。
|
||||
*/
|
||||
ClarifyOption: {
|
||||
/**
|
||||
* Label
|
||||
* @description 展示文案(作者看到的选项标签)
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* Value
|
||||
* @description 选中后回填/折进 instruction 的具体走法内容
|
||||
*/
|
||||
value: string;
|
||||
};
|
||||
/**
|
||||
* ClarifyQuestion
|
||||
* @description 单条澄清反问:问题 + 2–4 个锚定选项 + 自由输入兜底。
|
||||
*
|
||||
* `options` 常规 2–4 个(锚定本段/本章的具体走法);凑不出具体可区分选项时留空列表,
|
||||
* 退化为纯自由输入。`allow_free_text` 常驻 True——自由输入永远兜底(作者可不选任一项)。
|
||||
*/
|
||||
ClarifyQuestion: {
|
||||
/**
|
||||
* Question
|
||||
* @description 反问的澄清问题(一句话,指向本段的分歧点)
|
||||
*/
|
||||
question: string;
|
||||
/**
|
||||
* Options
|
||||
* @description 2–4 个锚定本段/本章的具体走法选项;凑不出具体选项时为空列表
|
||||
*/
|
||||
options?: components["schemas"]["ClarifyOption"][];
|
||||
/**
|
||||
* Allow Free Text
|
||||
* @description 是否允许自由输入(常驻兜底)
|
||||
* @default true
|
||||
*/
|
||||
allow_free_text: boolean;
|
||||
};
|
||||
/**
|
||||
* ConflictDecision
|
||||
* @description 对最近一次审稿留痕里**某个冲突**(按其在 conflicts 列表的下标定位)的裁决。
|
||||
@@ -1780,6 +1882,23 @@ export interface components {
|
||||
/** Tier Routing */
|
||||
tier_routing?: components["schemas"]["TierRoutingInput"][];
|
||||
};
|
||||
/**
|
||||
* RefineClarifyRequest
|
||||
* @description 润色预检澄清:选段 + 再沟通意见(WFW-9 M1 路线A 两阶段之「问题」阶段)。
|
||||
*
|
||||
* 与 `RefineRequest` 独立——预检只判「意见清不清楚」,不改正文。`instruction` 为作者的
|
||||
* 再沟通意见(可空/极短,正是触发反问的场景);带长度上界防超长入参。响应=`ClarifyDecision`
|
||||
* (在 ww_agents,端点直接返回,供前端 gen:api 生成强类型客户端)。
|
||||
*/
|
||||
RefineClarifyRequest: {
|
||||
/** Segment */
|
||||
segment: string;
|
||||
/**
|
||||
* Instruction
|
||||
* @default
|
||||
*/
|
||||
instruction: string;
|
||||
};
|
||||
/**
|
||||
* RefineRequest
|
||||
* @description 回炉:重写选中段(可选改写指令)。
|
||||
@@ -3310,6 +3429,60 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
clarify_refine_projects__project_id__chapters__chapter_no__refine_clarify_post: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path: {
|
||||
project_id: string;
|
||||
chapter_no: number;
|
||||
};
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/json": components["schemas"]["RefineClarifyRequest"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ClarifyDecision"];
|
||||
};
|
||||
};
|
||||
/** @description 项目不存在 */
|
||||
404: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ErrorEnvelope"];
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
/** @description LLM 不可用 */
|
||||
503: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["ErrorEnvelope"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
list_templates_templates_get: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
|
||||
Reference in New Issue
Block a user