fix: bind web observe turn summary to prompt trace (#857)
Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -43,15 +43,23 @@ function unique(values){return Array.from(new Set(values.filter(Boolean)));}
|
||||
function numOrNull(value){const n=Number(value); return Number.isFinite(n)?n:null}
|
||||
function promptIndexOf(value){const n=Number(value); return Number.isInteger(n)&&n>0?n:null}
|
||||
function tsMs(value){const ms=Date.parse(String(value||'')); return Number.isFinite(ms)?ms:null}
|
||||
function sessionIdFromUrl(value){const match=String(value||'').match(/\\/workbench\\/sessions\\/(ses_[A-Za-z0-9_-]+)/u); return match?match[1]:null}
|
||||
function commandSessionId(item){return item?.sessionId||item?.detail?.sessionId||item?.input?.sessionId||sessionIdFromUrl(item?.afterUrl)||sessionIdFromUrl(item?.detail?.afterUrl)||null}
|
||||
function commandTraceId(item){return item?.traceId||item?.detail?.chatSubmit?.traceId||item?.detail?.traceId||item?.input?.traceId||null}
|
||||
function promptCommands(){
|
||||
const map=new Map();
|
||||
for(const item of control){
|
||||
if(item.type!=='sendPrompt'||(item.phase!=='started'&&item.phase!=='completed'&&item.phase!=='failed')) continue;
|
||||
const id=item.commandId||item.seq||String(map.size+1);
|
||||
const existing=map.get(id)||{};
|
||||
map.set(id,{...existing,...item,input:{...(existing.input||{}),...(item.input||{})},firstTs:existing.firstTs||item.ts,lastTs:item.ts});
|
||||
map.set(id,{...existing,...item,input:{...(existing.input||{}),...(item.input||{})},sessionId:existing.sessionId||commandSessionId(item),traceId:existing.traceId||commandTraceId(item),firstTs:existing.firstTs||item.ts,lastTs:item.ts});
|
||||
}
|
||||
return Array.from(map.values()).filter((item)=>tsMs(item.firstTs)!==null).sort((a,b)=>tsMs(a.firstTs)-tsMs(b.firstTs));
|
||||
const prompts=Array.from(map.values()).filter((item)=>tsMs(item.firstTs)!==null).sort((a,b)=>tsMs(a.firstTs)-tsMs(b.firstTs));
|
||||
const latestSession=samples.slice().reverse().find((sample)=>sample.routeSessionId||sample.activeSessionId);
|
||||
const sessionId=latestSession?.routeSessionId||latestSession?.activeSessionId||null;
|
||||
if(!sessionId) return prompts;
|
||||
const scoped=prompts.filter((item)=>item.sessionId===sessionId);
|
||||
return scoped.length>0?scoped:prompts;
|
||||
}
|
||||
function segmentFor(index,prompts){
|
||||
const start=tsMs(prompts[index]?.firstTs); const end=index+1<prompts.length?tsMs(prompts[index+1].firstTs):Infinity;
|
||||
@@ -118,7 +126,12 @@ function reportColumnsForPrompt(index,segment){
|
||||
.filter((column)=>segmentIds.size===0||segmentIds.has(column.traceId)||column.source==='turn')
|
||||
.sort((a,b)=>(a.firstSeq??0)-(b.firstSeq??0)||(a.lastSeq??0)-(b.lastSeq??0)||String(a.label||'').localeCompare(String(b.label||'')));
|
||||
}
|
||||
function choosePrimaryTraceId(index,segment){
|
||||
function choosePrimaryTraceId(index,segment,prompt=null){
|
||||
const promptTraceId=commandTraceId(prompt)||prompt?.traceId||null;
|
||||
if(promptTraceId){
|
||||
const segmentIds=new Set(traceIdsFromSamples(segment));
|
||||
if(segmentIds.size===0||segmentIds.has(promptTraceId)) return {traceId:promptTraceId,columns:reportColumnsForPrompt(index,segment)};
|
||||
}
|
||||
const columns=reportColumnsForPrompt(index,segment);
|
||||
const promptIndex=index+1;
|
||||
const promptColumns=columns.filter((column)=>column.promptIndex===promptIndex);
|
||||
@@ -245,7 +258,7 @@ function turnSummaryRows(){
|
||||
return [{round:0,commandId:null,commandType:null,userPreview:'(无 sendPrompt control 记录)',userHash:null,userBytes:null,traceId:allTraceIds[0]||null,status:statusFor(samples,allTraceIds[0]||null),elapsedSeconds:null,recentUpdateSeconds:null,marks:'-',firstSeq:samples[0]?.seq??null,lastSeq:samples[samples.length-1]?.seq??null,lastTs:samples[samples.length-1]?.ts??null,finalResponse:finalResponseFor(samples,allTraceIds[0]||null),valuesRedacted:true}];
|
||||
}
|
||||
return prompts.map((prompt,index)=>{
|
||||
const segment=segmentFor(index,prompts); const segmentControls=controlsFor(index,prompts); const selected=choosePrimaryTraceId(index,segment); const traceId=selected.traceId; const user=userMessageFor(segment,prompt);
|
||||
const segment=segmentFor(index,prompts); const segmentControls=controlsFor(index,prompts); const selected=choosePrimaryTraceId(index,segment,prompt); const traceId=selected.traceId; const user=userMessageFor(segment,prompt);
|
||||
const primaryColumn=selected.columns.find((column)=>column.traceId===traceId)||null;
|
||||
const traceSample=latestSampleForTrace(segment,traceId,primaryColumn?.lastSeq??null);
|
||||
const texts=textsFor(segment,traceId);
|
||||
|
||||
Reference in New Issue
Block a user