perf(ui): compute xray segment chars from referenced parts
This commit is contained in:
@@ -484,45 +484,27 @@ const MessageTimeline: Component<MessageTimelineProps> = (props) => {
|
|||||||
const result: Record<string, number> = {}
|
const result: Record<string, number> = {}
|
||||||
const resolvedStore = store()
|
const resolvedStore = store()
|
||||||
|
|
||||||
// O(n) pre-pass: group segments by messageId for O(1) lookups below.
|
// Compute live char counts by reading only the parts that the segment
|
||||||
const segmentsByMessageId = new Map<string, TimelineSegment[]>()
|
// references (partIds/toolPartIds). This stays accurate for streamed tool
|
||||||
for (const s of xraySegments()) {
|
// outputs without scanning every part in the message.
|
||||||
let list = segmentsByMessageId.get(s.messageId)
|
for (const segment of xraySegments()) {
|
||||||
if (!list) {
|
const record = resolvedStore.getMessage(segment.messageId)
|
||||||
list = []
|
|
||||||
segmentsByMessageId.set(s.messageId, list)
|
|
||||||
}
|
|
||||||
list.push(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [messageId, segs] of segmentsByMessageId) {
|
|
||||||
const record = resolvedStore.getMessage(messageId)
|
|
||||||
if (!record) {
|
if (!record) {
|
||||||
for (const s of segs) result[s.id] = s.totalChars
|
result[segment.id] = segment.totalChars
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const { orderedParts } = buildRecordDisplayData(props.instanceId, record)
|
const ids = [...(segment.partIds ?? []), ...(segment.toolPartIds ?? [])]
|
||||||
if (!orderedParts?.length) {
|
let chars = 0
|
||||||
for (const s of segs) result[s.id] = s.totalChars
|
for (const partId of ids) {
|
||||||
continue
|
const part = record.parts?.[partId]?.data
|
||||||
|
if (!part) continue
|
||||||
|
chars += getPartCharCount(part)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map partId → fresh char count
|
result[segment.id] = chars > 0 ? chars : segment.totalChars
|
||||||
const partChars = new Map<string, number>()
|
|
||||||
for (const part of orderedParts) {
|
|
||||||
const pid = typeof (part as any)?.id === "string" ? (part as any).id : null
|
|
||||||
if (pid) partChars.set(pid, getPartCharCount(part))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign fresh chars to each segment of this message
|
|
||||||
for (const s of segs) {
|
|
||||||
const ids = [...(s.partIds ?? []), ...(s.toolPartIds ?? [])]
|
|
||||||
let chars = 0
|
|
||||||
for (const pid of ids) chars += partChars.get(pid) ?? 0
|
|
||||||
result[s.id] = chars > 0 ? chars : s.totalChars
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user