fix(ui): refresh trajectory artifact checks

This commit is contained in:
_Kerman
2026-07-28 10:56:15 +08:00
parent 57812e4711
commit c73e2ed674
3 changed files with 35 additions and 40 deletions
+8 -9
View File
@@ -206,16 +206,15 @@ it('trajectory and waterfall surface the run_code sub-calls with real timing', a
}, { timeout: 10_000 }) }, { timeout: 10_000 })
const subCells = [...document.querySelectorAll('[data-kind="subtool"]')] const subCells = [...document.querySelectorAll('[data-kind="subtool"]')]
expect({ expect({
// Three Sub cells nested under the run_code Tool cell, in dispatch order, // Three Subtool cells nested under the run_code Tool cell in dispatch
// each with a real +N.Ns own-duration off the start/settle pair (the // order, each paired with its result preview.
// fixture spaces every event 800ms apart — never the em dash).
subCells: subCells.map(cell => visibleText(cell)), subCells: subCells.map(cell => visibleText(cell)),
}).toMatchInlineSnapshot(` }).toMatchInlineSnapshot(`
{ {
"subCells": [ "subCells": [
"#51Subbash · {"command":"ls notes","description":"List notes"}+0.8s", "SUBTOOLbash{"command":"ls notes","description":"List notes"}→demo.txt new-demo.txt",
"#52Subread · {"path":"notes/demo.txt"}+0.8s", "SUBTOOLread{"path":"notes/demo.txt"}→hello fixture",
"#53Subread · {"path":"notes/missing.txt"}+0.8s", "SUBTOOLread{"path":"notes/missing.txt"}→error",
], ],
} }
`) `)
@@ -239,17 +238,17 @@ it('trajectory and waterfall surface the run_code sub-calls with real timing', a
{ {
"label": "bash", "label": "bash",
"timing": "measured", "timing": "measured",
"title": "bash · 0.80s", "title": "bash · 0.80 s",
}, },
{ {
"label": "read", "label": "read",
"timing": "measured", "timing": "measured",
"title": "read · 0.80s", "title": "read · 0.80 s",
}, },
{ {
"label": "read", "label": "read",
"timing": "measured", "timing": "measured",
"title": "read · 0.80s", "title": "read · 0.80 s",
}, },
], ],
} }
@@ -196,23 +196,9 @@ export class FoldAdapter {
} }
const out: ConversationNode[] = [] const out: ConversationNode[] = []
for (const seq of seqs) { for (const seq of seqs) {
const cached = this.nodeCache.get(seq) const node = this.materialize(seq)
if (cached !== undefined) { /* v8 ignore next -- both seq sources only emit indexes present in padded. */
out.push(cached) if (node !== undefined) out.push(node)
continue
}
const event = this.padded[seq]
/* v8 ignore next -- sparse guard: both seq sources (surface fold and degradedSeqs) only emit indexes present in padded. */
if (event === undefined) continue
const node = materializeNode(
event,
this.callIdx,
this.resultViews.get(seq) ?? null,
event.type === 'assistant/message' ? this.assistantTiming(event) : undefined,
event.type === 'assistant/message' ? this.assistantRequestConfig(event) : undefined,
)
this.nodeCache.set(seq, node)
out.push(node)
} }
const value = { nodes: out, degraded: this.degraded } const value = { nodes: out, degraded: this.degraded }
this.nodesResult = { rev: this.rev, value } this.nodesResult = { rev: this.rev, value }
@@ -68,6 +68,11 @@ interface TurnBucket {
groups: LaidGroup[] groups: LaidGroup[]
} }
type InputNode = Extract<
ConversationSnapshot['nodes'][number],
{ kind: 'user' | 'steering' | 'context' }
>
type OrderedLayoutEntry = type OrderedLayoutEntry =
| { | {
kind: 'node' kind: 'node'
@@ -97,6 +102,21 @@ function layoutEntryOrder(entry: OrderedLayoutEntry): number {
: entry.seq : entry.seq
} }
function inputCellDetail(node: InputNode): Pick<
TrajectoryCellProps,
'text' | 'sourceSeq' | 'messageSource' | 'inputDetail' | 'sourceBlocks' | 'timeSeconds' | 'startedAt'
> {
return {
text: summarizeContent(node.content),
sourceSeq: node.seq,
messageSource: node.source,
inputDetail: detailContent(node.content),
sourceBlocks: node.content.map(block => sourceBlock(block)),
timeSeconds: 0,
startedAt: finiteTime(node.time),
}
}
/** /**
* Fold a snapshot into turn → Message/Step groups with expanded cells. * Fold a snapshot into turn → Message/Step groups with expanded cells.
* @param input - nodes plus in-flight partial/runningCalls. * @param input - nodes plus in-flight partial/runningCalls.
@@ -294,15 +314,11 @@ export function deriveTrajectoryLayout(input: TrajectoryLayoutInput): readonly T
pushMessage(turn, { pushMessage(turn, {
absTime: finiteTime(node.time), absTime: finiteTime(node.time),
cell: { cell: {
index: ++index, kind: 'user', text: summarizeContent(node.content), index: ++index,
sourceSeq: node.seq, kind: 'user',
messageSource: node.source, ...inputCellDetail(node),
...(node.meta === undefined ? {} : { messageMeta: node.meta }), ...(node.meta === undefined ? {} : { messageMeta: node.meta }),
opensTurn: node.kind === 'user', opensTurn: node.kind === 'user',
inputDetail: detailContent(node.content),
sourceBlocks: node.content.map(block => sourceBlock(block)),
timeSeconds: 0,
startedAt: finiteTime(node.time),
}, },
}) })
prevAbsTime = finiteTime(node.time) ?? prevAbsTime prevAbsTime = finiteTime(node.time) ?? prevAbsTime
@@ -328,13 +344,7 @@ export function deriveTrajectoryLayout(input: TrajectoryLayoutInput): readonly T
cell: { cell: {
index: ++index, index: ++index,
kind: 'context', kind: 'context',
text: summarizeContent(node.content), ...inputCellDetail(node),
sourceSeq: node.seq,
messageSource: node.source,
inputDetail: detailContent(node.content),
sourceBlocks: node.content.map(block => sourceBlock(block)),
timeSeconds: 0,
startedAt: finiteTime(node.time),
}, },
}) })
prevAbsTime = finiteTime(node.time) ?? prevAbsTime prevAbsTime = finiteTime(node.time) ?? prevAbsTime