fix(ui): refresh trajectory artifact checks
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user