feat(bioflow): 引导帧——卡片环节补自然语言引导气泡(文件/参数/存档/进度) (#006/#007/#008/#010)

This commit is contained in:
2026-10-13 11:04:32 +08:00
parent da8f531bbc
commit 821f3c1c4e
2 changed files with 25 additions and 2 deletions
@@ -803,6 +803,7 @@ class Runner:
"title": record.title,
"progress": 100,
"elapsed_sec": None,
"guidance": "分析已完成,可以存档复用,或直接查看报告。",
})
except asyncio.CancelledError:
# 任务级取消:不落脏状态(阶段取消由 _run_stage 单独处理)
@@ -865,9 +866,17 @@ class Runner:
self._set_stage(record, stage, status=STAGE_WAITING_CONFIRM)
await self._persist_stage(record, stage)
defaults = self._form_defaults(stage, record)
if defaults:
param_str = "、".join(
f"{p.get('name')}(默认 {p.get('default')})" for p in defaults
)
guidance = f"阶段 {stage} 需要确认参数:{param_str}。不调整可直接继续。"
else:
guidance = f"阶段 {stage} 需要你确认后继续。"
self.events.publish("stage_await_confirm", {
"job_id": record.id, "stage": stage,
"form_defaults": defaults,
"guidance": guidance,
})
return "await"
@@ -1041,6 +1050,7 @@ class Runner:
"job_id": record.id, "stage": stage, "exit_code": exit_code,
"manifest_ref": manifest.path,
"metrics": manifest.metrics,
"summary": f"阶段 {stage} 已完成",
})
return "done"
+15 -2
View File
@@ -502,6 +502,15 @@ export function patchBioflowForm(aMsg, data, { rerun = false } = {}) {
}
/** 阶段待文件 → 文件引导块(FR-BIO-005) */
export function patchBioflowGuidance(aMsg, text) {
// 自然语言引导气泡(方案:自然语言主通道,卡片辅助)——弹卡片前先插入一条 text 块。
if (!text) return null;
const html = renderMarkdown(String(text));
if ((aMsg.blocks || []).some((b) => b && b.type === 'text' && b.html === html)) return null;
aMsg.blocks.push({ type: 'text', html });
return true;
}
export function patchBioflowFile(aMsg, data) {
const stage = data.stage;
if (!stage) return null;
@@ -1159,9 +1168,10 @@ export const useChatStore = defineStore('chat', {
onEvent: (type, data) => {
const frame = patchBioflowEvent(m, { type, data });
if (frame) this.scrollSeq++;
if (type === 'stage_await_confirm' && data) { patchBioflowForm(m, data); this.scrollSeq++; }
else if (type === 'stage_await_files' && data) { patchBioflowFile(m, data); this.scrollSeq++; }
if (type === 'stage_await_confirm' && data) { patchBioflowGuidance(m, data.guidance); patchBioflowForm(m, data); this.scrollSeq++; }
else if (type === 'stage_await_files' && data) { patchBioflowGuidance(m, data.guidance || data.message); patchBioflowFile(m, data); this.scrollSeq++; }
else if (type === 'job_done' && data) {
patchBioflowGuidance(m, data.guidance);
const ab = patchBioflowArchiveSuggest(m, data.job_id || jobId);
if (ab) ab.jobId = data.job_id || jobId;
this.scrollSeq++;
@@ -2255,12 +2265,15 @@ export const useChatStore = defineStore('chat', {
const frame = patchBioflowEvent(aMsg, { type, data });
if (frame) this.scrollSeq++;
if (type === 'stage_await_confirm' && data) {
patchBioflowGuidance(aMsg, data.guidance);
patchBioflowForm(aMsg, data);
this.scrollSeq++;
} else if (type === 'stage_await_files' && data) {
patchBioflowGuidance(aMsg, data.guidance || data.message);
patchBioflowFile(aMsg, data);
this.scrollSeq++;
} else if (type === 'job_done' && data) {
patchBioflowGuidance(aMsg, data.guidance);
const blk = patchBioflowArchiveSuggest(aMsg, data.job_id || jobId);
if (blk) blk.jobId = data.job_id || jobId;
bioflow.registerReport({