openfox 2.0.145 → 2.0.147

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/CHANGELOG.md +22 -0
  3. package/dist/{auto-continue-ZAHNBHPA.js → auto-continue-FGQ63HHR.js} +9 -9
  4. package/dist/{chat-handler-5XMO5XBU.js → chat-handler-VCED3JYF.js} +12 -12
  5. package/dist/{chunk-OVAHNEFG.js → chunk-2PGRX4RH.js} +5 -4
  6. package/dist/{chunk-LG3LQLTZ.js → chunk-2V6QL6IW.js} +290 -120
  7. package/dist/{chunk-2DVAF6HY.js → chunk-5JGRKNMS.js} +3 -3
  8. package/dist/chunk-65KDNVRA.js +7 -0
  9. package/dist/{chunk-2BARKBWV.js → chunk-ABXERHIY.js} +8 -8
  10. package/dist/{chunk-QKPTMHA2.js → chunk-AJMBQMJH.js} +23 -19
  11. package/dist/{chunk-E4F32L4Q.js → chunk-CPRBMVI7.js} +43 -1
  12. package/dist/{chunk-STVJA7IX.js → chunk-CVQYCAMY.js} +3 -3
  13. package/dist/{chunk-HNJ32GRI.js → chunk-ESHP42KO.js} +5 -5
  14. package/dist/{chunk-FLTNKZNQ.js → chunk-KJEOKIH2.js} +4 -4
  15. package/dist/chunk-NHHC3AVI.js +231 -0
  16. package/dist/{chunk-YRSZJ7IZ.js → chunk-NZBO3A3W.js} +2 -2
  17. package/dist/{chunk-3IVJ65IG.js → chunk-ORIPUMOQ.js} +5 -5
  18. package/dist/{chunk-VFHGN3IS.js → chunk-P7KUU5VB.js} +2 -2
  19. package/dist/{chunk-PW5L4WBG.js → chunk-Q6MBLKL4.js} +1 -1
  20. package/dist/{chunk-6FKSGQYO.js → chunk-QHFJRUJV.js} +3 -3
  21. package/dist/{chunk-X2BJFVER.js → chunk-UOBJP4GN.js} +21 -15
  22. package/dist/{chunk-DBTDMK23.js → chunk-YQJ6HEFS.js} +63 -56
  23. package/dist/cli/dev.js +1 -1
  24. package/dist/cli/index.js +1 -1
  25. package/dist/{compactor-53WDNC2S.js → compactor-YY7PO2XE.js} +5 -5
  26. package/dist/{describe-image-IGLGVEOJ.js → describe-image-Z5WS6YU3.js} +8 -8
  27. package/dist/{dynamic-context-7AJC6AII.js → dynamic-context-YLRA34WJ.js} +5 -5
  28. package/dist/{events-ODZ4SSBW.js → events-FTS5W6FX.js} +6 -4
  29. package/dist/{export-import-AH5HBHO6.js → export-import-R4E5BUQS.js} +5 -5
  30. package/dist/{folding-V2R2MZ6Y.js → folding-VWRMYZ5T.js} +4 -2
  31. package/dist/{launch-2QA2EHCT.js → launch-QP2BI3PB.js} +13 -13
  32. package/dist/{orchestrator-L5VINV36.js → orchestrator-7T62RLDL.js} +11 -11
  33. package/dist/package.json +1 -1
  34. package/dist/{path-security-3YFS3GJQ.js → path-security-25P6TQ4R.js} +7 -7
  35. package/dist/{processor-UQ5ITWL6.js → processor-LDLRELLS.js} +11 -11
  36. package/dist/{protocol-Ch2s26bR.d.ts → protocol--oV4P3L_.d.ts} +2 -1
  37. package/dist/{protocol-MRMOB3P4.js → protocol-M4DFHA32.js} +3 -3
  38. package/dist/provider/index.d.ts +4 -4
  39. package/dist/{serve-CIBBSOLM.js → serve-A4AJAH2N.js} +18 -18
  40. package/dist/server/index.d.ts +3 -3
  41. package/dist/server/index.js +17 -17
  42. package/dist/{server-YW3DO4K5.js → server-A3EGJ6MD.js} +16 -16
  43. package/dist/session-stats-Y7WRB5MP.js +23 -0
  44. package/dist/shared/index.d.ts +25 -9
  45. package/dist/shared/index.js +7 -3
  46. package/dist/skill-defaults/workflows/SKILL.md +149 -16
  47. package/dist/stats-2QMXP6G4.js +12 -0
  48. package/dist/{store-AOZ46PBS.js → store-OWOLXB74.js} +3 -3
  49. package/dist/{tools-RG4HDV75.js → tools-MRC27SZG.js} +9 -9
  50. package/dist/{types-BajWwfkt.d.ts → types-NEE5osQN.d.ts} +48 -1
  51. package/dist/{types-BiHNYUUI.d.ts → types-usLcJB6N.d.ts} +1 -1
  52. package/dist/{update-5ENWM2XR.js → update-MLDVVG3D.js} +2 -2
  53. package/dist/web/assets/{index-DL26wmhi.js → index-CkVmYTBd.js} +85 -85
  54. package/dist/web/index.html +1 -1
  55. package/dist/web/sw.js +1 -1
  56. package/package.json +1 -1
  57. package/dist/chunk-7OHXF5GW.js +0 -132
  58. package/dist/chunk-QV4BKKIO.js +0 -7
@@ -36,7 +36,7 @@ import {
36
36
  requireSession,
37
37
  validateActionWithPermission,
38
38
  validateFileForWrite
39
- } from "./chunk-FLTNKZNQ.js";
39
+ } from "./chunk-KJEOKIH2.js";
40
40
  import {
41
41
  serverT
42
42
  } from "./chunk-X7ZAP6YW.js";
@@ -45,7 +45,7 @@ import {
45
45
  extractAbsolutePathsFromCommand,
46
46
  extractSensitivePathsFromCommand,
47
47
  resolveRelativeTraversals
48
- } from "./chunk-STVJA7IX.js";
48
+ } from "./chunk-CVQYCAMY.js";
49
49
  import {
50
50
  TurnMetrics,
51
51
  clearLLMFailure,
@@ -95,10 +95,10 @@ import {
95
95
  import {
96
96
  getCurrentContextWindowId,
97
97
  getCurrentWindowMessageOptions
98
- } from "./chunk-2DVAF6HY.js";
98
+ } from "./chunk-5JGRKNMS.js";
99
99
  import {
100
100
  getEventStore
101
- } from "./chunk-YRSZJ7IZ.js";
101
+ } from "./chunk-NZBO3A3W.js";
102
102
  import {
103
103
  buildContextMessagesFromEventHistory,
104
104
  foldContextState,
@@ -108,7 +108,7 @@ import {
108
108
  handleToolResult,
109
109
  reorderToolMessages,
110
110
  stripOrphanedToolCalls
111
- } from "./chunk-E4F32L4Q.js";
111
+ } from "./chunk-CPRBMVI7.js";
112
112
  import {
113
113
  findAgentById,
114
114
  getRuntimeConfig,
@@ -127,7 +127,7 @@ import {
127
127
  createChatMessageUpdatedMessage,
128
128
  createChatStatsMessage,
129
129
  createQueueStateMessage
130
- } from "./chunk-OVAHNEFG.js";
130
+ } from "./chunk-2PGRX4RH.js";
131
131
  import {
132
132
  getModelProfile,
133
133
  modelSupportsVision
@@ -1162,6 +1162,16 @@ function resolveLLMClientForAgent(agentId, fallbackClient, providerManager, pinn
1162
1162
  override: effectiveEffort ? { ...override, reasoningEffort: effectiveEffort } : override
1163
1163
  };
1164
1164
  }
1165
+ function buildAgentOverrideStatsIdentity(providerManager, client, override) {
1166
+ const provider = providerManager.getProviders().find((p) => p.id === override.providerId);
1167
+ return {
1168
+ providerId: override.providerId,
1169
+ providerName: provider?.name ?? override.providerId,
1170
+ backend: provider?.backend ?? client.getBackend(),
1171
+ model: override.model,
1172
+ ...override.reasoningEffort ? { reasoningEffort: override.reasoningEffort } : {}
1173
+ };
1174
+ }
1165
1175
 
1166
1176
  // src/server/chat/tool-streaming.ts
1167
1177
  function parseProgressMessage(message) {
@@ -1758,7 +1768,7 @@ ${CONTINUE_PROMPT}` : CONTINUE_PROMPT;
1758
1768
  currentMaxTokensOverride = void 0;
1759
1769
  if (!compacting) {
1760
1770
  const contextState = sessionManager.getContextState(sessionId);
1761
- const { shouldCompact, appendCompactionPrompt } = await import("./compactor-53WDNC2S.js");
1771
+ const { shouldCompact, appendCompactionPrompt } = await import("./compactor-YY7PO2XE.js");
1762
1772
  if (shouldCompact(
1763
1773
  contextState.currentTokens,
1764
1774
  contextState.maxTokens,
@@ -2241,14 +2251,7 @@ async function executeSubAgent(options) {
2241
2251
  if (resolved.usedOverride && resolved.override) {
2242
2252
  hasOverride = true;
2243
2253
  llmClient = resolved.client;
2244
- const provider = effectiveProviderManager.getProviders().find((p) => p.id === resolved.override.providerId);
2245
- statsIdentity = {
2246
- providerId: resolved.override.providerId,
2247
- providerName: provider?.name ?? resolved.override.providerId,
2248
- backend: provider?.backend ?? resolved.client.getBackend(),
2249
- model: resolved.override.model,
2250
- ...resolved.override.reasoningEffort ? { reasoningEffort: resolved.override.reasoningEffort } : {}
2251
- };
2254
+ statsIdentity = buildAgentOverrideStatsIdentity(effectiveProviderManager, resolved.client, resolved.override);
2252
2255
  const overrideEffort = effectiveProviderManager.resolveModelEffort(
2253
2256
  resolved.override.providerId,
2254
2257
  resolved.override.model,
@@ -2475,7 +2478,7 @@ var callSubAgentTool = {
2475
2478
  };
2476
2479
  }
2477
2480
  try {
2478
- const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-RG4HDV75.js");
2481
+ const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-MRC27SZG.js");
2479
2482
  const toolRegistry = getToolRegistryForAgent2(agentDef);
2480
2483
  const turnMetrics = new TurnMetrics();
2481
2484
  const result = await executeSubAgent({
@@ -3579,11 +3582,11 @@ var mcpConfigTool = createTool(
3579
3582
  async function notifyContextChanged(sessionId) {
3580
3583
  context.sessionManager.setDynamicContextChanged(sessionId, true);
3581
3584
  mcpNotifyChanged?.(sessionId);
3582
- const { injectContextDriftReminders } = await import("./dynamic-context-7AJC6AII.js");
3585
+ const { injectContextDriftReminders } = await import("./dynamic-context-YLRA34WJ.js");
3583
3586
  await injectContextDriftReminders(context.sessionManager, sessionId);
3584
3587
  }
3585
3588
  async function rebuildTools() {
3586
- const { setMcpTools: setMcpTools2 } = await import("./tools-RG4HDV75.js");
3589
+ const { setMcpTools: setMcpTools2 } = await import("./tools-MRC27SZG.js");
3587
3590
  const mcpTools = createMcpTools(mcpManagerForTools);
3588
3591
  setMcpTools2(mcpTools);
3589
3592
  }
@@ -4702,6 +4705,7 @@ export {
4702
4705
  getAgentModelOverride,
4703
4706
  setAgentModelOverride,
4704
4707
  resolveLLMClientForAgent,
4708
+ buildAgentOverrideStatsIdentity,
4705
4709
  runTopLevelAgentLoop,
4706
4710
  createAssemblyResult,
4707
4711
  getConversationMessages,
@@ -4725,4 +4729,4 @@ export {
4725
4729
  getToolRegistryForAgent,
4726
4730
  createToolRegistry
4727
4731
  };
4728
- //# sourceMappingURL=chunk-QKPTMHA2.js.map
4732
+ //# sourceMappingURL=chunk-AJMBQMJH.js.map
@@ -335,6 +335,47 @@ function applyTurnEventsToSnapshotMessages(initialMessages, events) {
335
335
  });
336
336
  return messages.map((msg) => ({ ...msg, isStreaming: msg.isStreaming ?? true }));
337
337
  }
338
+ function buildSessionStatsMessages(events) {
339
+ const statsById = /* @__PURE__ */ new Map();
340
+ const snapshotEvent = [...events].reverse().find((event) => event.type === "turn.snapshot");
341
+ const snapshotSeq = snapshotEvent?.seq ?? 0;
342
+ if (snapshotEvent) {
343
+ const snapshot = snapshotEvent.data;
344
+ for (const msg of snapshot.messages) {
345
+ if (msg.stats) {
346
+ statsById.set(msg.id, {
347
+ id: msg.id,
348
+ timestamp: new Date(msg.timestamp).toISOString(),
349
+ stats: msg.stats
350
+ });
351
+ }
352
+ }
353
+ }
354
+ const startTimestamps = /* @__PURE__ */ new Map();
355
+ for (const event of events) {
356
+ if (event.seq <= snapshotSeq) continue;
357
+ switch (event.type) {
358
+ case "message.start": {
359
+ const data = event.data;
360
+ startTimestamps.set(data.messageId, event.timestamp);
361
+ break;
362
+ }
363
+ case "message.done": {
364
+ const data = event.data;
365
+ if (data.stats) {
366
+ const timestamp = startTimestamps.get(data.messageId) ?? event.timestamp;
367
+ statsById.set(data.messageId, {
368
+ id: data.messageId,
369
+ timestamp: new Date(timestamp).toISOString(),
370
+ stats: data.stats
371
+ });
372
+ }
373
+ break;
374
+ }
375
+ }
376
+ }
377
+ return Array.from(statsById.values());
378
+ }
338
379
  function buildMessagesFromStoredEvents(events, maxVisibleItems) {
339
380
  const snapshotEvent = [...events].reverse().find((event) => event.type === "turn.snapshot");
340
381
  if (snapshotEvent) {
@@ -957,6 +998,7 @@ function buildSnapshotFromSessionState(input) {
957
998
  export {
958
999
  spreadOptionalMessageFields,
959
1000
  snapshotMessagesToEvents,
1001
+ buildSessionStatsMessages,
960
1002
  buildMessagesFromStoredEvents,
961
1003
  buildContextMessagesFromStoredEvents,
962
1004
  handleMessageThinking,
@@ -983,4 +1025,4 @@ export {
983
1025
  buildSnapshot,
984
1026
  buildSnapshotFromSessionState
985
1027
  };
986
- //# sourceMappingURL=chunk-E4F32L4Q.js.map
1028
+ //# sourceMappingURL=chunk-CPRBMVI7.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  getEventStore
3
- } from "./chunk-YRSZJ7IZ.js";
3
+ } from "./chunk-NZBO3A3W.js";
4
4
  import {
5
5
  createChatPathConfirmationMessage
6
- } from "./chunk-OVAHNEFG.js";
6
+ } from "./chunk-2PGRX4RH.js";
7
7
  import {
8
8
  getPlatformShell
9
9
  } from "./chunk-YEFZ5HBD.js";
@@ -988,4 +988,4 @@ export {
988
988
  getConfirmationSessionId,
989
989
  getPendingConfirmationsBySession
990
990
  };
991
- //# sourceMappingURL=chunk-STVJA7IX.js.map
991
+ //# sourceMappingURL=chunk-CVQYCAMY.js.map
@@ -7,10 +7,10 @@ import {
7
7
  } from "./chunk-ZONLEX2F.js";
8
8
  import {
9
9
  getCurrentContextWindowId
10
- } from "./chunk-2DVAF6HY.js";
10
+ } from "./chunk-5JGRKNMS.js";
11
11
  import {
12
12
  getEventStore
13
- } from "./chunk-YRSZJ7IZ.js";
13
+ } from "./chunk-NZBO3A3W.js";
14
14
  import {
15
15
  findAgentById,
16
16
  getRuntimeConfig,
@@ -329,8 +329,8 @@ function resolveAgentDef(sessionManager, sessionId) {
329
329
  });
330
330
  }
331
331
  async function getEffectiveToolDefinitions(agentDef, sessionId, modelName) {
332
- const { getToolRegistryForAgent } = await import("./tools-RG4HDV75.js");
333
- const { isDescribeImageEligible } = await import("./describe-image-IGLGVEOJ.js");
332
+ const { getToolRegistryForAgent } = await import("./tools-MRC27SZG.js");
333
+ const { isDescribeImageEligible } = await import("./describe-image-Z5WS6YU3.js");
334
334
  const all = getToolRegistryForAgent(agentDef, sessionId).definitions;
335
335
  const eligible = await isDescribeImageEligible(modelName);
336
336
  if (eligible) return all;
@@ -398,4 +398,4 @@ export {
398
398
  computeSessionHash,
399
399
  applyDynamicContext
400
400
  };
401
- //# sourceMappingURL=chunk-HNJ32GRI.js.map
401
+ //# sourceMappingURL=chunk-ESHP42KO.js.map
@@ -5,10 +5,10 @@ import {
5
5
  PathAccessDeniedError,
6
6
  registerPathConfirmation,
7
7
  requestPathAccess
8
- } from "./chunk-STVJA7IX.js";
8
+ } from "./chunk-CVQYCAMY.js";
9
9
  import {
10
10
  getEventStore
11
- } from "./chunk-YRSZJ7IZ.js";
11
+ } from "./chunk-NZBO3A3W.js";
12
12
  import {
13
13
  getRuntimeConfig
14
14
  } from "./chunk-YEW4YEJU.js";
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-V5AC2TV7.js";
18
18
  import {
19
19
  createChatPathConfirmationMessage
20
- } from "./chunk-OVAHNEFG.js";
20
+ } from "./chunk-2PGRX4RH.js";
21
21
  import {
22
22
  modelSupportsVision
23
23
  } from "./chunk-TS5WKTFB.js";
@@ -1152,4 +1152,4 @@ export {
1152
1152
  isDescribeImageEligible,
1153
1153
  describeImageTool
1154
1154
  };
1155
- //# sourceMappingURL=chunk-FLTNKZNQ.js.map
1155
+ //# sourceMappingURL=chunk-KJEOKIH2.js.map
@@ -0,0 +1,231 @@
1
+ // src/shared/stats.ts
2
+ var roundTo1 = (n) => Math.round(n * 10) / 10;
3
+ function hasValidStats(stats) {
4
+ return typeof stats.totalTime === "number" && !Number.isNaN(stats.totalTime);
5
+ }
6
+ function getStatsIdentity(stats) {
7
+ return {
8
+ providerId: stats.providerId,
9
+ providerName: stats.providerName,
10
+ backend: stats.backend,
11
+ model: stats.model
12
+ };
13
+ }
14
+ function getModelGroupKey(identity) {
15
+ return `${identity.providerId}::${identity.model}`;
16
+ }
17
+ function getModelGroupLabel(identity) {
18
+ return `${identity.providerName} > ${identity.model}`;
19
+ }
20
+ function aggregateMessages(messagesWithStats) {
21
+ let totalTime = 0;
22
+ let toolTime = 0;
23
+ let prefillTokens = 0;
24
+ let generationTokens = 0;
25
+ let totalPrefillSource = 0;
26
+ let totalPrefillTime = 0;
27
+ let totalGenTime = 0;
28
+ let llmCallCount = 0;
29
+ for (const msg of messagesWithStats) {
30
+ const stats = msg.stats;
31
+ totalTime += stats.totalTime;
32
+ toolTime += stats.toolTime;
33
+ prefillTokens += stats.prefillTokens;
34
+ generationTokens += stats.generationTokens;
35
+ const prefillSource = stats.prefTokenIncrement ?? stats.prefillTokens;
36
+ const prefillTime = stats.prefillSpeed > 0 ? prefillSource / stats.prefillSpeed : 0;
37
+ const genTime = stats.generationSpeed > 0 ? stats.generationTokens / stats.generationSpeed : 0;
38
+ totalPrefillSource += prefillSource;
39
+ totalPrefillTime += prefillTime;
40
+ totalGenTime += genTime;
41
+ llmCallCount += stats.llmCalls?.length ?? 0;
42
+ }
43
+ return {
44
+ totalTime,
45
+ toolTime,
46
+ prefillTokens,
47
+ generationTokens,
48
+ totalPrefillSource,
49
+ totalPrefillTime,
50
+ totalGenTime,
51
+ responseCount: messagesWithStats.length,
52
+ llmCallCount
53
+ };
54
+ }
55
+ function summaryFields(agg) {
56
+ return {
57
+ totalTime: roundTo1(agg.totalTime),
58
+ aiTime: roundTo1(agg.totalTime - agg.toolTime),
59
+ toolTime: roundTo1(agg.toolTime),
60
+ prefillTokens: agg.prefillTokens,
61
+ generationTokens: agg.generationTokens,
62
+ avgPrefillSpeed: agg.totalPrefillTime > 0 ? roundTo1(agg.totalPrefillSource / agg.totalPrefillTime) : 0,
63
+ avgGenerationSpeed: agg.totalGenTime > 0 ? roundTo1(agg.generationTokens / agg.totalGenTime) : 0,
64
+ responseCount: agg.responseCount,
65
+ llmCallCount: agg.llmCallCount,
66
+ totalPrefillSource: agg.totalPrefillSource,
67
+ totalPrefillTime: agg.totalPrefillTime,
68
+ totalGenTime: agg.totalGenTime
69
+ };
70
+ }
71
+ function buildModelSummary(identity, groupMessages) {
72
+ return {
73
+ ...identity,
74
+ key: getModelGroupKey(identity),
75
+ label: getModelGroupLabel(identity),
76
+ ...summaryFields(aggregateMessages(groupMessages))
77
+ };
78
+ }
79
+ function filterWithStats(messages) {
80
+ return messages.filter((msg) => msg.stats !== void 0 && msg.stats !== null && hasValidStats(msg.stats)).sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
81
+ }
82
+ function buildSessionStats(messagesWithStats) {
83
+ const agg = aggregateMessages(messagesWithStats);
84
+ const dataPoints = [];
85
+ const callDataPoints = [];
86
+ let sessionCallIndex = 0;
87
+ for (const [index, msg] of messagesWithStats.entries()) {
88
+ const stats = msg.stats;
89
+ const identity = getStatsIdentity(stats);
90
+ dataPoints.push({
91
+ messageId: msg.id,
92
+ timestamp: msg.timestamp,
93
+ ...identity,
94
+ mode: stats.mode,
95
+ responseIndex: index + 1,
96
+ prefillTokens: stats.prefillTokens,
97
+ generationTokens: stats.generationTokens,
98
+ prefillSpeed: stats.prefillSpeed,
99
+ generationSpeed: stats.generationSpeed,
100
+ totalTime: stats.totalTime,
101
+ aiTime: stats.totalTime - stats.toolTime,
102
+ toolTime: stats.toolTime
103
+ });
104
+ const llmCalls = stats.llmCalls ?? [];
105
+ for (const call of llmCalls) {
106
+ sessionCallIndex += 1;
107
+ callDataPoints.push({
108
+ messageId: msg.id,
109
+ timestamp: call.timestamp ?? msg.timestamp,
110
+ providerId: call.providerId,
111
+ providerName: call.providerName,
112
+ backend: call.backend,
113
+ model: call.model,
114
+ mode: stats.mode,
115
+ responseIndex: index + 1,
116
+ sessionCallIndex,
117
+ callIndex: call.callIndex,
118
+ promptTokens: call.promptTokens,
119
+ completionTokens: call.completionTokens,
120
+ ttft: call.ttft,
121
+ completionTime: call.completionTime,
122
+ prefillSpeed: call.prefillSpeed,
123
+ generationSpeed: call.generationSpeed,
124
+ totalTime: call.totalTime,
125
+ ...call.temperature !== void 0 && { temperature: call.temperature },
126
+ ...call.topP !== void 0 && { topP: call.topP },
127
+ ...call.topK !== void 0 && { topK: call.topK },
128
+ ...call.maxTokens !== void 0 && { maxTokens: call.maxTokens }
129
+ });
130
+ }
131
+ }
132
+ return {
133
+ ...summaryFields(agg),
134
+ dataPoints,
135
+ callDataPoints
136
+ };
137
+ }
138
+ function groupMessagesByModel(messagesWithStats) {
139
+ const modelBuckets = /* @__PURE__ */ new Map();
140
+ for (const message of messagesWithStats) {
141
+ const key = getModelGroupKey(getStatsIdentity(message.stats));
142
+ const existing = modelBuckets.get(key) ?? [];
143
+ modelBuckets.set(key, [...existing, message]);
144
+ }
145
+ return modelBuckets;
146
+ }
147
+ function computeSessionStats(messages) {
148
+ const messagesWithStats = filterWithStats(messages);
149
+ if (messagesWithStats.length === 0) {
150
+ return null;
151
+ }
152
+ const modelGroups = Array.from(groupMessagesByModel(messagesWithStats).entries()).map(
153
+ ([, groupMessages]) => {
154
+ const identity = getStatsIdentity(groupMessages[0].stats);
155
+ return {
156
+ ...identity,
157
+ key: getModelGroupKey(identity),
158
+ label: getModelGroupLabel(identity),
159
+ ...buildSessionStats(groupMessages)
160
+ };
161
+ }
162
+ );
163
+ return {
164
+ ...buildSessionStats(messagesWithStats),
165
+ modelGroups
166
+ };
167
+ }
168
+ function computeSessionStatsSummary(messages) {
169
+ const messagesWithStats = filterWithStats(messages);
170
+ if (messagesWithStats.length === 0) {
171
+ return null;
172
+ }
173
+ const modelGroups = Array.from(groupMessagesByModel(messagesWithStats).entries()).map(
174
+ ([, groupMessages]) => {
175
+ const identity = getStatsIdentity(groupMessages[0].stats);
176
+ return buildModelSummary(identity, groupMessages);
177
+ }
178
+ );
179
+ return {
180
+ ...summaryFields(aggregateMessages(messagesWithStats)),
181
+ modelGroups
182
+ };
183
+ }
184
+ function mergeLiveStats(base, live) {
185
+ const prefillSource = live.prefTokenIncrement ?? live.prefillTokens;
186
+ const prefillTime = live.prefillSpeed > 0 ? prefillSource / live.prefillSpeed : 0;
187
+ const genTime = live.generationSpeed > 0 ? live.generationTokens / live.generationSpeed : 0;
188
+ const liveCalls = live.llmCalls?.length ?? 0;
189
+ const identity = getStatsIdentity(live);
190
+ const key = getModelGroupKey(identity);
191
+ const mergedAgg = {
192
+ totalTime: (base?.totalTime ?? 0) + live.totalTime,
193
+ toolTime: (base?.toolTime ?? 0) + live.toolTime,
194
+ prefillTokens: (base?.prefillTokens ?? 0) + live.prefillTokens,
195
+ generationTokens: (base?.generationTokens ?? 0) + live.generationTokens,
196
+ totalPrefillSource: (base?.totalPrefillSource ?? 0) + prefillSource,
197
+ totalPrefillTime: (base?.totalPrefillTime ?? 0) + prefillTime,
198
+ totalGenTime: (base?.totalGenTime ?? 0) + genTime,
199
+ responseCount: (base?.responseCount ?? 0) + 1,
200
+ llmCallCount: (base?.llmCallCount ?? 0) + liveCalls
201
+ };
202
+ const modelGroups = (base?.modelGroups ?? []).map((group) => {
203
+ if (group.key !== key) return group;
204
+ const groupAgg = {
205
+ totalTime: group.totalTime + live.totalTime,
206
+ toolTime: group.toolTime + live.toolTime,
207
+ prefillTokens: group.prefillTokens + live.prefillTokens,
208
+ generationTokens: group.generationTokens + live.generationTokens,
209
+ totalPrefillSource: group.totalPrefillSource + prefillSource,
210
+ totalPrefillTime: group.totalPrefillTime + prefillTime,
211
+ totalGenTime: group.totalGenTime + genTime,
212
+ responseCount: group.responseCount + 1,
213
+ llmCallCount: group.llmCallCount + liveCalls
214
+ };
215
+ return { ...group, ...summaryFields(groupAgg) };
216
+ });
217
+ if (!modelGroups.some((group) => group.key === key)) {
218
+ modelGroups.push(buildModelSummary(identity, [{ id: "live", timestamp: (/* @__PURE__ */ new Date()).toISOString(), stats: live }]));
219
+ }
220
+ return {
221
+ ...summaryFields(mergedAgg),
222
+ modelGroups
223
+ };
224
+ }
225
+
226
+ export {
227
+ computeSessionStats,
228
+ computeSessionStatsSummary,
229
+ mergeLiveStats
230
+ };
231
+ //# sourceMappingURL=chunk-NHHC3AVI.js.map
@@ -2,7 +2,7 @@ import {
2
2
  buildSnapshot,
3
3
  foldSessionState,
4
4
  trimSnapshotStreamingOutput
5
- } from "./chunk-E4F32L4Q.js";
5
+ } from "./chunk-CPRBMVI7.js";
6
6
  import {
7
7
  SETTINGS_KEYS
8
8
  } from "./chunk-X6SWZEK7.js";
@@ -1059,4 +1059,4 @@ export {
1059
1059
  initEventStore,
1060
1060
  getEventStore
1061
1061
  };
1062
- //# sourceMappingURL=chunk-YRSZJ7IZ.js.map
1062
+ //# sourceMappingURL=chunk-NZBO3A3W.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  combineEventsWithSnapshot
3
- } from "./chunk-2DVAF6HY.js";
3
+ } from "./chunk-5JGRKNMS.js";
4
4
  import {
5
5
  getEventStore
6
- } from "./chunk-YRSZJ7IZ.js";
6
+ } from "./chunk-NZBO3A3W.js";
7
7
  import {
8
8
  buildMessagesFromStoredEvents,
9
9
  foldPendingConfirmations
10
- } from "./chunk-E4F32L4Q.js";
10
+ } from "./chunk-CPRBMVI7.js";
11
11
  import {
12
12
  updateSessionMetadata
13
13
  } from "./chunk-CCIG3YLG.js";
@@ -20,7 +20,7 @@ import {
20
20
  import {
21
21
  createContextStateMessage,
22
22
  createSessionStateMessage
23
- } from "./chunk-OVAHNEFG.js";
23
+ } from "./chunk-2PGRX4RH.js";
24
24
  import {
25
25
  getMaxVisibleItems
26
26
  } from "./chunk-X6SWZEK7.js";
@@ -219,4 +219,4 @@ export {
219
219
  needsNameGeneration,
220
220
  generateSessionNameForSession
221
221
  };
222
- //# sourceMappingURL=chunk-3IVJ65IG.js.map
222
+ //# sourceMappingURL=chunk-ORIPUMOQ.js.map
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-ZONLEX2F.js";
7
7
  import {
8
8
  getCurrentWindowMessageOptions
9
- } from "./chunk-2DVAF6HY.js";
9
+ } from "./chunk-5JGRKNMS.js";
10
10
 
11
11
  // src/server/context/compactor.ts
12
12
  function appendCompactionPrompt(sessionId, append) {
@@ -36,4 +36,4 @@ export {
36
36
  COMPACTION_MAX_RATIO,
37
37
  shouldCompact
38
38
  };
39
- //# sourceMappingURL=chunk-VFHGN3IS.js.map
39
+ //# sourceMappingURL=chunk-P7KUU5VB.js.map
@@ -26,4 +26,4 @@ export {
26
26
  isClientMessage,
27
27
  isServerMessage
28
28
  };
29
- //# sourceMappingURL=chunk-PW5L4WBG.js.map
29
+ //# sourceMappingURL=chunk-Q6MBLKL4.js.map
@@ -252,7 +252,7 @@ async function runCli(options) {
252
252
  break;
253
253
  }
254
254
  case "update": {
255
- const { runUpdate } = await import("./update-5ENWM2XR.js");
255
+ const { runUpdate } = await import("./update-MLDVVG3D.js");
256
256
  const code = await runUpdate();
257
257
  if (code !== 0) {
258
258
  process.exit(code);
@@ -265,7 +265,7 @@ async function runCli(options) {
265
265
  if (!configExists) {
266
266
  await runNetworkSetup(mode);
267
267
  }
268
- const { runServe } = await import("./serve-CIBBSOLM.js");
268
+ const { runServe } = await import("./serve-A4AJAH2N.js");
269
269
  const serveOptions = { mode };
270
270
  if (values.port) serveOptions.port = parseInt(values.port);
271
271
  if (values["no-browser"] === true) serveOptions.openBrowser = false;
@@ -277,4 +277,4 @@ async function runCli(options) {
277
277
  export {
278
278
  runCli
279
279
  };
280
- //# sourceMappingURL=chunk-6FKSGQYO.js.map
280
+ //# sourceMappingURL=chunk-QHFJRUJV.js.map