Commit d7c3c3e2 by luoqi

feat(web): 深度档 AI 生成把自检问题明细展示出来(section/problem/fix)

deep 策略 verify 阶段把 issues[] 透传到 stream 事件;前端会话过程区展开每条问题的 段落/问题/修法。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
parent e75f756d
......@@ -29,6 +29,8 @@ export interface DeepStepDetail {
pass?: boolean; // verify done
quality?: DeepVerify['quality'] | null; // verify done:质量分
issuesCount?: number; // verify done:发现问题数 / repair running:待修问题数
// verify done / repair running:逐条问题明细(section=出问题的段 · problem=哪里不对 · fix=改法)
issues?: { section: string; problem: string; fix: string }[];
}
/** runStream 逐步 yield 的事件(step 状态切换 + write 逐字 partial)*/
......@@ -220,13 +222,26 @@ export class DeepScriptStrategy {
kind: 'step',
step: 'verify',
status: 'done',
detail: { pass: issues.length === 0, quality, issuesCount: issues.length },
detail: {
pass: issues.length === 0,
quality,
issuesCount: issues.length,
issues: issues.map((i) => ({ section: i.section, problem: i.problem, fix: i.fix })),
},
};
// ── repair(≤1 轮)──
if (issues.length > 0) {
ensureLive();
yield { kind: 'step', step: 'repair', status: 'running', detail: { issuesCount: issues.length } };
yield {
kind: 'step',
step: 'repair',
status: 'running',
detail: {
issuesCount: issues.length,
issues: issues.map((i) => ({ section: i.section, problem: i.problem, fix: i.fix })),
},
};
const w2 = yield* this.streamWrite({ ctx, plan, repairIssues: issues, prevDraft: draft }, runCtx, acc);
draft = w2.output;
invocationId = w2.invocationId;
......
......@@ -36,6 +36,7 @@ export type PlanScriptStreamEvent =
pass?: boolean;
quality?: { natural: number; warmth: number; focus: number; nonPushy: number; overall: number } | null;
issuesCount?: number;
issues?: { section: string; problem: string; fix: string }[];
};
}
| {
......
......@@ -114,16 +114,46 @@ function StepDetail({ step: s }: { step: DeepStep }) {
if (s.step === 'verify') {
const q = d.quality?.overall;
return (
<div className="space-y-1">
<div className="flex flex-wrap items-center gap-x-2 gap-y-0.5 text-[11px] text-slate-500">
<span>接地 + 安全 {d.pass ? '通过' : `${d.issuesCount ?? 0} 处待修`}</span>
{typeof q === 'number' && <span>· 质量 {q.toFixed(1)} / 5</span>}
</div>
<IssueList issues={d.issues} />
</div>
);
}
if (s.step === 'repair' && typeof d.issuesCount === 'number') {
return <div className="text-[11px] text-slate-500">针对 {d.issuesCount} 处问题重写</div>;
return (
<div className="space-y-1">
<div className="text-[11px] text-slate-500">针对 {d.issuesCount} 处问题重写</div>
<IssueList issues={d.issues} />
</div>
);
}
return null;
}
/** 逐条问题明细:出问题的段 + 哪里不对 + 改法。 */
function IssueList({
issues,
}: {
issues?: { section: string; problem: string; fix: string }[];
}) {
if (!issues?.length) return null;
return (
<ul className="space-y-1">
{issues.map((it, i) => (
<li key={i} className="rounded border border-slate-100 bg-white px-2 py-1 text-[11px] leading-snug">
<div className="font-medium text-slate-600">{it.section || `问题 ${i + 1}`}</div>
<div className="break-words text-slate-500">{it.problem}</div>
{it.fix && (
<div className="mt-0.5 break-words text-teal-600">改法:{it.fix}</div>
)}
</li>
))}
</ul>
);
}
......@@ -39,6 +39,7 @@ export interface DeepStep {
pass?: boolean;
quality?: { natural: number; warmth: number; focus: number; nonPushy: number; overall: number } | null;
issuesCount?: number;
issues?: { section: string; problem: string; fix: string }[];
};
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment