diff --git a/scripts/src/hwlab-node-web-observe-collect.ts b/scripts/src/hwlab-node-web-observe-collect.ts index da935ee0..c6be4a05 100644 --- a/scripts/src/hwlab-node-web-observe-collect.ts +++ b/scripts/src/hwlab-node-web-observe-collect.ts @@ -222,6 +222,9 @@ function cleanFinalResponseText(text){ const raw=String(text||'').trim(); if(!raw) return ''; if(/^Code Agent\\s*(?:running|completed|failed|canceled|cancelled)?$/iu.test(raw)) return ''; + if(/^耗时\\s*\\d+\\s*(?:秒|分钟|分|小时)$/u.test(raw)) return ''; + if(/^(completed|failed|canceled|cancelled)!?$/iu.test(raw)) return ''; + if(/^!+$/u.test(raw)) return ''; if(/Code Agent\\s*耗时[\\s\\S]*运行记录/iu.test(raw)) return ''; if(/^sent\\s+当前 AgentRun 请求已取消/u.test(raw)) return ''; if(/^(admitted|run|ok|error)\\s+/iu.test(raw)) return ''; @@ -237,6 +240,9 @@ function finalCandidateText(entry){ const explicit=textOf(entry.item?.finalResponse); if(explicit) return explicit; if(entry.group==='message') return entry.text; + if(entry.group==='traceRow'&&/助手消息|assistant\\s*message/iu.test(entry.text)){ + return String(entry.text||'').replace(/^.*?(?:助手消息|assistant\\s*message)\\s*/iu,''); + } return ''; } function sameAsUserPrompt(entry,text,user){ @@ -248,11 +254,15 @@ function sameAsUserPrompt(entry,text,user){ } 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(); + const scoped=traceId?traceEntries(items,traceId):items.flatMap((sample)=>entryGroups(sample).map((entry)=>({...entry,sample,text:textOf(entry.item)}))); + const unscopedMessages=traceId?items.flatMap((sample)=>entryGroups(sample) + .filter((entry)=>entry.group==='message'&&!itemTraceId(entry.item)) + .map((entry)=>({...entry,sample,text:textOf(entry.item)}))):[]; + const candidates=[...scoped,...unscopedMessages].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(entry.group==='message'&&role&&!/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(finalCandidateText(entry)); if(!text) continue;