diff --git a/scripts/src/hwlab-node-web-observe-collect.ts b/scripts/src/hwlab-node-web-observe-collect.ts index 84a9580e..686592de 100644 --- a/scripts/src/hwlab-node-web-observe-collect.ts +++ b/scripts/src/hwlab-node-web-observe-collect.ts @@ -197,7 +197,15 @@ function cleanFinalResponseText(text){ if(/^(轮次完成|轮次失败|轮次取消|已记录)$/u.test(raw.replace(/\\s+/gu,' ').trim())) return ''; return raw; } -function entryRole(entry){return String(entry.item?.role||entry.item?.authorRole||entry.item?.messageRole||entry.item?.speaker||'').toLowerCase()} +function emptyFinalResponse(){return {preview:'(空内容)',textHash:null,textBytes:0,empty:true}} +function terminalFinalStatus(value){return /^(completed|failed|canceled|cancelled|terminal)$/u.test(String(value||'').trim().toLowerCase())} +function entryRole(entry){return String(entry.item?.role||entry.item?.dataRole||entry.item?.authorRole||entry.item?.messageRole||entry.item?.speaker||'').toLowerCase()} +function finalCandidateText(entry){ + const explicit=textOf(entry.item?.finalResponse); + if(explicit) return explicit; + if(entry.group==='message') return entry.text; + return ''; +} function sameAsUserPrompt(entry,text,user){ if(!user) return false; if(user.textHash&&entry.item?.textHash===user.textHash) return true; @@ -206,13 +214,14 @@ function sameAsUserPrompt(entry,text,user){ return userPrefix.length>=18&&textPrefix===userPrefix; } function finalResponseFor(items,traceId,user=null){ + if(!terminalFinalStatus(statusFor(items,traceId))) return emptyFinalResponse(); const candidates=(traceId?traceEntries(items,traceId):items.flatMap((sample)=>entryGroups(sample).map((entry)=>({...entry,sample,text:textOf(entry.item)})))).slice().reverse(); for(const entry of candidates){ const role=entryRole(entry); const entryStatus=String(entry.item?.status||''); if(entry.group==='message'&&!/assistant|agent|system/u.test(role)) continue; if(/用户|user/iu.test(role)||/用户|user/iu.test(entryStatus)) continue; - const status=String(entry.item?.status||'').toLowerCase(); const text=cleanFinalResponseText(entry.text); + const status=String(entry.item?.status||'').toLowerCase(); const text=cleanFinalResponseText(finalCandidateText(entry)); if(!text) continue; if(/^第\\d+轮\\/\\d+[::]?\\s*请/u.test(text)||/^请(执行|帮|回答|修复|调查|用|不要|直接)/u.test(text)) continue; if(sameAsUserPrompt(entry,text,user)) continue; @@ -220,7 +229,7 @@ function finalResponseFor(items,traceId,user=null){ const preview=short(text,180); if(preview)return {preview,textHash:entry.item?.textHash||sha(text),textBytes:entry.item?.textBytes??Buffer.byteLength(text),empty:false}; } - return {preview:'(空内容)',textHash:null,textBytes:0,empty:true}; + return emptyFinalResponse(); } function turnSummaryRows(){ const prompts=promptCommands();