diff --git a/bioflow_service/app/services/bioflow/runner.py b/bioflow_service/app/services/bioflow/runner.py index ef9c7f4..837c452 100644 --- a/bioflow_service/app/services/bioflow/runner.py +++ b/bioflow_service/app/services/bioflow/runner.py @@ -27,6 +27,7 @@ from pathlib import Path from typing import Any, Awaitable, Callable from .catalog import StageCatalog +from .errors import classify_reason from .events import EventBus from .manifests import ManifestError, locate_manifest, parse_manifest from .recovery import RecoveryBudget @@ -1059,10 +1060,19 @@ class Runner: self._set_stage(record, stage, status=STAGE_FAILED, finished_at=_now_iso(), error=reason) await self._persist_stage(record, stage) + cat, diag, retry, actions = classify_reason(reason, exit_code=exit_code) + guidance = f"阶段 {stage} 执行失败:{reason}。" + if actions: + guidance += "建议:" + ";".join(actions) + "。" self.events.publish("stage_failed", { "job_id": record.id, "stage": stage, "exit_code": exit_code if exit_code is not None else -1, "reason": reason, + "category": cat, "code": reason, "summary": reason, + "diagnosis_status": diag, + "retryable_without_change": retry, + "suggested_actions": actions, + "guidance": guidance, }) def _prefix_for(self, record: JobRecord, stage: str) -> str | None: diff --git a/ui/src/stores/chat.js b/ui/src/stores/chat.js index b45a132..8643c6b 100644 --- a/ui/src/stores/chat.js +++ b/ui/src/stores/chat.js @@ -1170,6 +1170,7 @@ export const useChatStore = defineStore('chat', { if (frame) 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 === 'stage_failed' && data) { patchBioflowGuidance(m, data.guidance); patchBioflowDiagnosis(m, data); this.scrollSeq++; } else if (type === 'job_done' && data) { patchBioflowGuidance(m, data.guidance); const ab = patchBioflowArchiveSuggest(m, data.job_id || jobId); @@ -2272,6 +2273,10 @@ export const useChatStore = defineStore('chat', { patchBioflowGuidance(aMsg, data.guidance || data.message); patchBioflowFile(aMsg, data); this.scrollSeq++; + } else if (type === 'stage_failed' && data) { + patchBioflowGuidance(aMsg, data.guidance); + patchBioflowDiagnosis(aMsg, data); + this.scrollSeq++; } else if (type === 'job_done' && data) { patchBioflowGuidance(aMsg, data.guidance); const blk = patchBioflowArchiveSuggest(aMsg, data.job_id || jobId);