|
8 | 8 | import type { |
9 | 9 | ApiChatCompletionToolCall, |
10 | 10 | ChatMessageSiblingInfo, |
| 11 | + ChatMessageTimings, |
11 | 12 | DatabaseMessage |
12 | 13 | } from '$lib/types'; |
13 | 14 |
|
|
104 | 105 | }; |
105 | 106 | }; |
106 | 107 |
|
| 108 | + const sumTimings = (assistantIds: string[]): ChatMessageTimings | undefined => { |
| 109 | + if (assistantIds.length <= 1) return undefined; |
| 110 | +
|
| 111 | + let predicted_n_sum = 0; |
| 112 | + let predicted_ms_sum = 0; |
| 113 | + let prompt_n_sum = 0; |
| 114 | + let prompt_ms_sum = 0; |
| 115 | + let cache_n_sum = 0; |
| 116 | +
|
| 117 | + let hasPredicted = false; |
| 118 | + let hasPrompt = false; |
| 119 | + let hasCache = false; |
| 120 | +
|
| 121 | + for (const id of assistantIds) { |
| 122 | + const m = filteredMessages.find((x) => x.id === id); |
| 123 | + const t = m?.timings; |
| 124 | + if (!t) continue; |
| 125 | +
|
| 126 | + if (typeof t.predicted_n === 'number' && typeof t.predicted_ms === 'number') { |
| 127 | + predicted_n_sum += t.predicted_n; |
| 128 | + predicted_ms_sum += t.predicted_ms; |
| 129 | + hasPredicted = true; |
| 130 | + } |
| 131 | +
|
| 132 | + if (typeof t.prompt_n === 'number' && typeof t.prompt_ms === 'number') { |
| 133 | + prompt_n_sum += t.prompt_n; |
| 134 | + prompt_ms_sum += t.prompt_ms; |
| 135 | + hasPrompt = true; |
| 136 | + } |
| 137 | +
|
| 138 | + if (typeof t.cache_n === 'number') { |
| 139 | + cache_n_sum += t.cache_n; |
| 140 | + hasCache = true; |
| 141 | + } |
| 142 | + } |
| 143 | +
|
| 144 | + if (!hasPredicted && !hasPrompt && !hasCache) return undefined; |
| 145 | +
|
| 146 | + return { |
| 147 | + ...(hasPredicted ? { predicted_n: predicted_n_sum, predicted_ms: predicted_ms_sum } : {}), |
| 148 | + ...(hasPrompt ? { prompt_n: prompt_n_sum, prompt_ms: prompt_ms_sum } : {}), |
| 149 | + ...(hasCache ? { cache_n: cache_n_sum } : {}) |
| 150 | + }; |
| 151 | + }; |
| 152 | +
|
107 | 153 | for (const msg of filteredMessages) { |
108 | 154 | if (visited.has(msg.id)) continue; |
109 | 155 | // Don't render tools directly, but keep them for collection; skip marking visited here |
|
198 | 244 | totalSiblings: 1 |
199 | 245 | }; |
200 | 246 |
|
| 247 | + const aggregatedTimings = sumTimings(toolParentIds); |
| 248 | +
|
201 | 249 | const mergedAssistant: AssistantDisplayMessage = { |
202 | 250 | ...(currentAssistant ?? msg), |
203 | 251 | content: currentAssistant?.content ?? '', |
204 | 252 | thinking: thinkingParts.filter(Boolean).join('\n\n'), |
205 | 253 | toolCalls: toolCallsCombined.length ? JSON.stringify(toolCallsCombined) : '', |
| 254 | + ...(aggregatedTimings ? { timings: aggregatedTimings } : {}), |
206 | 255 | _toolParentIds: toolParentIds, |
207 | 256 | _segments: segments, |
208 | 257 | _actionTargetId: msg.id, |
|
0 commit comments