opencode-tps-meter 0.1.5 → 0.1.7
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.
- package/dist/constants.d.ts +9 -3
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +361 -67
- package/dist/index.mjs +361 -67
- package/dist/tracker.d.ts.map +1 -1
- package/dist/types.d.ts +37 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/ui.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/constants.d.ts
CHANGED
|
@@ -15,11 +15,17 @@ export declare const MAX_BUFFER_SIZE = 100;
|
|
|
15
15
|
/** Minimum window duration for TPS calculation (seconds) to avoid division by near-zero */
|
|
16
16
|
export declare const MIN_WINDOW_DURATION_SECONDS = 0.1;
|
|
17
17
|
/** Token count threshold to trigger burst smoothing (tokens) */
|
|
18
|
-
export declare const BURST_TOKEN_THRESHOLD =
|
|
18
|
+
export declare const BURST_TOKEN_THRESHOLD = 50;
|
|
19
19
|
/** Default EWMA half-life (ms) for smoothing normal streaming */
|
|
20
20
|
export declare const DEFAULT_EWMA_HALF_LIFE_MS = 500;
|
|
21
|
-
/** EWMA half-life (ms) applied during bursts */
|
|
22
|
-
export declare const BURST_EWMA_HALF_LIFE_MS =
|
|
21
|
+
/** EWMA half-life (ms) applied during medium bursts (50-200 tokens) */
|
|
22
|
+
export declare const BURST_EWMA_HALF_LIFE_MS = 3000;
|
|
23
|
+
/** Token count threshold for very large bursts (tool outputs) */
|
|
24
|
+
export declare const LARGE_BURST_THRESHOLD = 200;
|
|
25
|
+
/** EWMA half-life (ms) for very large bursts */
|
|
26
|
+
export declare const LARGE_BURST_EWMA_HALF_LIFE_MS = 5000;
|
|
27
|
+
/** Maximum initial TPS value to prevent startup spikes */
|
|
28
|
+
export declare const MAX_INITIAL_TPS = 100;
|
|
23
29
|
/** Default UI update interval in milliseconds */
|
|
24
30
|
export declare const DEFAULT_UPDATE_INTERVAL_MS = 50;
|
|
25
31
|
/** Minimum interval between toast updates (ms) - prevents UI flooding */
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,+DAA+D;AAC/D,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,mDAAmD;AACnD,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,2FAA2F;AAC3F,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,gEAAgE;AAChE,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,+DAA+D;AAC/D,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,mDAAmD;AACnD,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,2FAA2F;AAC3F,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,gEAAgE;AAChE,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,iEAAiE;AACjE,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,uEAAuE;AACvE,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAE5C,iEAAiE;AACjE,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,gDAAgD;AAChD,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD,0DAA0D;AAC1D,eAAO,MAAM,eAAe,MAAM,CAAC;AAMnC,iDAAiD;AACjD,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,yEAAyE;AACzE,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,qDAAqD;AACrD,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,qDAAqD;AACrD,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAM5C,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,QAAgB,CAAC;AAEhD,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAMzC,yEAAyE;AACzE,eAAO,MAAM,WAAW,IAAI,CAAC;AAE7B,sEAAsE;AACtE,eAAO,MAAM,WAAW,IAAI,CAAC;AAE7B,qEAAqE;AACrE,eAAO,MAAM,cAAc,OAAO,CAAC;AAMnC,uDAAuD;AACvD,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,yDAAyD;AACzD,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAM7C,2DAA2D;AAC3D,eAAO,MAAM,sBAAsB,aAAqC,CAAC;AAEzE,0DAA0D;AAC1D,eAAO,MAAM,oBAAoB,aAAiC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,5 +13,5 @@ import type { PluginContext, PluginHandlers } from "./types.js";
|
|
|
13
13
|
* @returns {PluginHandlers | Record<string, never>} - Event handlers or empty object if disabled
|
|
14
14
|
*/
|
|
15
15
|
export default function TpsMeterPlugin(context: PluginContext): PluginHandlers | Record<string, never>;
|
|
16
|
-
export type { BufferEntry, TPSTrackerOptions, TPSTracker, UIManager, TokenCounter, Config, OpenCodeClient, DisplayState, PluginContext, Logger, MessageEvent, PluginHandlers, } from "./types.js";
|
|
16
|
+
export type { BufferEntry, TPSTrackerOptions, TPSTracker, UIManager, TokenCounter, Config, OpenCodeClient, DisplayState, AgentDisplayState, AgentIdentity, PluginContext, Logger, MessageEvent, PluginHandlers, } from "./types.js";
|
|
17
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EAOf,MAAM,YAAY,CAAC;AAoHpB;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,OAAO,EAAE,aAAa,GACrB,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CA2wBxC;AAGD,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,SAAS,EACT,YAAY,EACZ,MAAM,EACN,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,MAAM,EACN,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -50,9 +50,12 @@ var MIN_TPS_ELAPSED_MS = 250;
|
|
|
50
50
|
var DEFAULT_ROLLING_WINDOW_MS = 1000;
|
|
51
51
|
var MAX_BUFFER_SIZE = 100;
|
|
52
52
|
var MIN_WINDOW_DURATION_SECONDS = 0.1;
|
|
53
|
-
var BURST_TOKEN_THRESHOLD =
|
|
53
|
+
var BURST_TOKEN_THRESHOLD = 50;
|
|
54
54
|
var DEFAULT_EWMA_HALF_LIFE_MS = 500;
|
|
55
|
-
var BURST_EWMA_HALF_LIFE_MS =
|
|
55
|
+
var BURST_EWMA_HALF_LIFE_MS = 3000;
|
|
56
|
+
var LARGE_BURST_THRESHOLD = 200;
|
|
57
|
+
var LARGE_BURST_EWMA_HALF_LIFE_MS = 5000;
|
|
58
|
+
var MAX_INITIAL_TPS = 100;
|
|
56
59
|
var DEFAULT_UPDATE_INTERVAL_MS = 50;
|
|
57
60
|
var MIN_TOAST_INTERVAL_MS = 150;
|
|
58
61
|
var DEFAULT_TOAST_DURATION_MS = 20000;
|
|
@@ -124,11 +127,18 @@ function createTracker(options = {}) {
|
|
|
124
127
|
pruneBuffer(ts);
|
|
125
128
|
const rawTPS = calculateRawTPS(ts);
|
|
126
129
|
if (!hasSmoothedValue) {
|
|
127
|
-
smoothedTps = rawTPS;
|
|
130
|
+
smoothedTps = Math.min(rawTPS, MAX_INITIAL_TPS);
|
|
128
131
|
hasSmoothedValue = true;
|
|
129
132
|
} else {
|
|
130
133
|
const timeDelta = Math.max(1, ts - lastSmoothedAt);
|
|
131
|
-
|
|
134
|
+
let halfLife;
|
|
135
|
+
if (count > LARGE_BURST_THRESHOLD) {
|
|
136
|
+
halfLife = LARGE_BURST_EWMA_HALF_LIFE_MS;
|
|
137
|
+
} else if (count > BURST_TOKEN_THRESHOLD) {
|
|
138
|
+
halfLife = BURST_EWMA_HALF_LIFE_MS;
|
|
139
|
+
} else {
|
|
140
|
+
halfLife = DEFAULT_EWMA_HALF_LIFE_MS;
|
|
141
|
+
}
|
|
132
142
|
const alpha = Math.exp(-Math.LN2 * timeDelta / halfLife);
|
|
133
143
|
smoothedTps = alpha * smoothedTps + (1 - alpha) * rawTPS;
|
|
134
144
|
}
|
|
@@ -204,7 +214,7 @@ function createUIManager(client, config) {
|
|
|
204
214
|
function formatNumberWithCommas(num) {
|
|
205
215
|
return num.toLocaleString("en-US");
|
|
206
216
|
}
|
|
207
|
-
function
|
|
217
|
+
function formatPrimaryLine(state) {
|
|
208
218
|
const parts = [];
|
|
209
219
|
if (uiConfig.showInstant || uiConfig.showAverage) {
|
|
210
220
|
const tpsParts = [];
|
|
@@ -214,7 +224,9 @@ function createUIManager(client, config) {
|
|
|
214
224
|
if (uiConfig.showAverage) {
|
|
215
225
|
tpsParts.push(`(avg ${state.avgTps.toFixed(1)})`);
|
|
216
226
|
}
|
|
217
|
-
|
|
227
|
+
if (tpsParts.length > 0) {
|
|
228
|
+
parts.push(tpsParts.join(" "));
|
|
229
|
+
}
|
|
218
230
|
}
|
|
219
231
|
if (uiConfig.showTotalTokens) {
|
|
220
232
|
parts.push(`tokens: ${formatNumberWithCommas(state.totalTokens)}`);
|
|
@@ -222,7 +234,43 @@ function createUIManager(client, config) {
|
|
|
222
234
|
if (uiConfig.showElapsed) {
|
|
223
235
|
parts.push(formatElapsedTime(state.elapsedMs));
|
|
224
236
|
}
|
|
225
|
-
return parts.join(" | ");
|
|
237
|
+
return parts.length > 0 ? parts.join(" | ") : "TPS meter";
|
|
238
|
+
}
|
|
239
|
+
function formatAgentLine(agent) {
|
|
240
|
+
const segments = [];
|
|
241
|
+
if (uiConfig.showInstant || uiConfig.showAverage) {
|
|
242
|
+
const tpsParts = [];
|
|
243
|
+
if (uiConfig.showInstant) {
|
|
244
|
+
tpsParts.push(`${agent.instantTps.toFixed(1)}`);
|
|
245
|
+
}
|
|
246
|
+
if (uiConfig.showAverage) {
|
|
247
|
+
tpsParts.push(`(avg ${agent.avgTps.toFixed(1)})`);
|
|
248
|
+
}
|
|
249
|
+
if (tpsParts.length > 0) {
|
|
250
|
+
segments.push(tpsParts.join(" "));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (uiConfig.showTotalTokens) {
|
|
254
|
+
segments.push(`tokens: ${formatNumberWithCommas(agent.totalTokens)}`);
|
|
255
|
+
}
|
|
256
|
+
if (uiConfig.showElapsed) {
|
|
257
|
+
segments.push(formatElapsedTime(agent.elapsedMs));
|
|
258
|
+
}
|
|
259
|
+
return `${agent.label} ${segments.join(" | ")}`.trim();
|
|
260
|
+
}
|
|
261
|
+
function formatDisplay(state) {
|
|
262
|
+
const lines = [];
|
|
263
|
+
const hasMainActivity = state.totalTokens > 0;
|
|
264
|
+
if (hasMainActivity) {
|
|
265
|
+
lines.push(formatPrimaryLine(state));
|
|
266
|
+
}
|
|
267
|
+
const agentLines = (state.agents ?? []).filter((agent) => agent.totalTokens > 0).map((agent) => formatAgentLine(agent));
|
|
268
|
+
lines.push(...agentLines);
|
|
269
|
+
if (lines.length === 0) {
|
|
270
|
+
return "TPS meter (idle)";
|
|
271
|
+
}
|
|
272
|
+
return lines.join(`
|
|
273
|
+
`);
|
|
226
274
|
}
|
|
227
275
|
function getColorVariant(instantTps, isFinal) {
|
|
228
276
|
if (isFinal) {
|
|
@@ -303,7 +351,11 @@ function createUIManager(client, config) {
|
|
|
303
351
|
function flushPendingUpdate() {
|
|
304
352
|
if (pendingState) {
|
|
305
353
|
const formatted = formatDisplay(pendingState);
|
|
306
|
-
|
|
354
|
+
let tpsForColor = pendingState.instantTps;
|
|
355
|
+
if (pendingState.totalTokens === 0 && pendingState.agents?.length) {
|
|
356
|
+
tpsForColor = Math.max(...pendingState.agents.map((a) => a.instantTps));
|
|
357
|
+
}
|
|
358
|
+
display(formatted, false, tpsForColor);
|
|
307
359
|
lastDisplayedState = { ...pendingState };
|
|
308
360
|
pendingState = null;
|
|
309
361
|
}
|
|
@@ -321,12 +373,13 @@ function createUIManager(client, config) {
|
|
|
321
373
|
}, delay);
|
|
322
374
|
}
|
|
323
375
|
return {
|
|
324
|
-
updateDisplay(instantTps, avgTps, totalTokens, elapsedMs) {
|
|
376
|
+
updateDisplay(instantTps, avgTps, totalTokens, elapsedMs, agents) {
|
|
325
377
|
pendingState = {
|
|
326
378
|
instantTps,
|
|
327
379
|
avgTps,
|
|
328
380
|
totalTokens,
|
|
329
|
-
elapsedMs
|
|
381
|
+
elapsedMs,
|
|
382
|
+
agents: agents && agents.length > 0 ? agents : undefined
|
|
330
383
|
};
|
|
331
384
|
scheduleFlush();
|
|
332
385
|
},
|
|
@@ -650,34 +703,234 @@ function TpsMeterPlugin(context) {
|
|
|
650
703
|
logger.debug("[TpsMeter] Plugin disabled by configuration");
|
|
651
704
|
return {};
|
|
652
705
|
}
|
|
653
|
-
const
|
|
706
|
+
const sessionTrackers = new Map;
|
|
654
707
|
const partTextCache = new Map;
|
|
655
708
|
const messageTokenCache = new Map;
|
|
656
709
|
const messageRoleCache = new Map;
|
|
657
|
-
const
|
|
658
|
-
|
|
710
|
+
const sessionAgentNameCache = new Map;
|
|
711
|
+
let primarySessionId = null;
|
|
712
|
+
const pendingDisplayTimers = new Map;
|
|
659
713
|
const resolvedConfig = config;
|
|
660
714
|
const ui = createUIManager(safeContext.client || {}, resolvedConfig);
|
|
661
715
|
const tokenizer = createTokenizer(resolvedConfig.fallbackTokenHeuristic === "words_div_0_75" ? "word" : resolvedConfig.fallbackTokenHeuristic === "chars_div_3" ? "code" : "heuristic");
|
|
662
716
|
logger.info("[TpsMeter] Plugin initialized and ready");
|
|
663
|
-
function
|
|
664
|
-
let
|
|
665
|
-
if (!
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
717
|
+
function getOrCreateSessionState(sessionId) {
|
|
718
|
+
let state = sessionTrackers.get(sessionId);
|
|
719
|
+
if (!state) {
|
|
720
|
+
state = {
|
|
721
|
+
aggregate: createTracker({
|
|
722
|
+
sessionId,
|
|
723
|
+
rollingWindowMs: resolvedConfig.rollingWindowMs
|
|
724
|
+
}),
|
|
725
|
+
aggregateFirstTokenAt: null,
|
|
726
|
+
messageTrackers: new Map
|
|
727
|
+
};
|
|
728
|
+
sessionTrackers.set(sessionId, state);
|
|
671
729
|
logger.debug(`[TpsMeter] Created tracker for session: ${sessionId}`);
|
|
672
730
|
}
|
|
673
|
-
return
|
|
731
|
+
return state;
|
|
732
|
+
}
|
|
733
|
+
function abbreviateId(id) {
|
|
734
|
+
if (!id || id.length <= 4)
|
|
735
|
+
return id;
|
|
736
|
+
return `${id.slice(0, 4)}…`;
|
|
737
|
+
}
|
|
738
|
+
function buildAgentLabel(messageId, metadata) {
|
|
739
|
+
const typeLabel = metadata?.agent?.type?.trim() || metadata?.agentType?.trim() || metadata?.agent?.name?.trim() || metadata?.name?.trim() || "Subagent";
|
|
740
|
+
const rawId = metadata?.agentId?.trim() || metadata?.agent?.id?.trim() || messageId;
|
|
741
|
+
const identifier = abbreviateId(rawId);
|
|
742
|
+
return `${typeLabel}(${identifier})`;
|
|
743
|
+
}
|
|
744
|
+
function buildTrackerKey(sessionId, messageId, partId, metadata) {
|
|
745
|
+
const agentId = metadata?.agentId?.trim() || metadata?.agent?.id?.trim() || metadata?.agentType?.trim();
|
|
746
|
+
if (agentId) {
|
|
747
|
+
return `${sessionId}:${messageId}:${agentId}`;
|
|
748
|
+
}
|
|
749
|
+
if (partId) {
|
|
750
|
+
return `${sessionId}:${messageId}:${partId}`;
|
|
751
|
+
}
|
|
752
|
+
return `${sessionId}:${messageId}`;
|
|
753
|
+
}
|
|
754
|
+
function getOrCreateMessageTrackerState(sessionId, messageId, partId, metadata) {
|
|
755
|
+
const sessionState = getOrCreateSessionState(sessionId);
|
|
756
|
+
const key = buildTrackerKey(sessionId, messageId, partId, metadata);
|
|
757
|
+
let trackerState = sessionState.messageTrackers.get(key);
|
|
758
|
+
const nextLabel = buildAgentLabel(messageId, metadata);
|
|
759
|
+
if (!trackerState) {
|
|
760
|
+
trackerState = {
|
|
761
|
+
key,
|
|
762
|
+
messageId,
|
|
763
|
+
partId,
|
|
764
|
+
tracker: createTracker({
|
|
765
|
+
sessionId: key,
|
|
766
|
+
rollingWindowMs: resolvedConfig.rollingWindowMs
|
|
767
|
+
}),
|
|
768
|
+
label: nextLabel,
|
|
769
|
+
firstTokenAt: null,
|
|
770
|
+
lastUpdated: 0,
|
|
771
|
+
agent: metadata?.agent,
|
|
772
|
+
agentId: metadata?.agentId,
|
|
773
|
+
agentType: metadata?.agentType
|
|
774
|
+
};
|
|
775
|
+
sessionState.messageTrackers.set(key, trackerState);
|
|
776
|
+
} else if (trackerState.label !== nextLabel) {
|
|
777
|
+
trackerState.label = nextLabel;
|
|
778
|
+
}
|
|
779
|
+
if (metadata?.agent) {
|
|
780
|
+
trackerState.agent = metadata.agent;
|
|
781
|
+
}
|
|
782
|
+
if (metadata?.agentId) {
|
|
783
|
+
trackerState.agentId = metadata.agentId;
|
|
784
|
+
}
|
|
785
|
+
if (metadata?.agentType) {
|
|
786
|
+
trackerState.agentType = metadata.agentType;
|
|
787
|
+
}
|
|
788
|
+
return trackerState;
|
|
789
|
+
}
|
|
790
|
+
function getAllActiveAgentsGlobally(now) {
|
|
791
|
+
const activityWindow = Math.max(resolvedConfig.rollingWindowMs, MIN_TPS_ELAPSED_MS * 4);
|
|
792
|
+
const entries = [];
|
|
793
|
+
for (const [sessionId, sessionState] of sessionTrackers) {
|
|
794
|
+
for (const [trackerKey, trackerState] of sessionState.messageTrackers) {
|
|
795
|
+
if (!trackerState.firstTokenAt)
|
|
796
|
+
continue;
|
|
797
|
+
if (now - trackerState.lastUpdated > activityWindow)
|
|
798
|
+
continue;
|
|
799
|
+
const hasAgentMetadata = Boolean(trackerState.agent || trackerState.agentId || trackerState.agentType);
|
|
800
|
+
let isSubagent = false;
|
|
801
|
+
let label = trackerState.label;
|
|
802
|
+
if (hasAgentMetadata) {
|
|
803
|
+
isSubagent = true;
|
|
804
|
+
} else if (sessionId !== primarySessionId) {
|
|
805
|
+
isSubagent = true;
|
|
806
|
+
const agentName = sessionAgentNameCache.get(sessionId) || "bg";
|
|
807
|
+
const shortId = abbreviateId(sessionId.replace(/^ses_/, ""));
|
|
808
|
+
label = `${agentName}(${shortId})`;
|
|
809
|
+
}
|
|
810
|
+
if (!isSubagent)
|
|
811
|
+
continue;
|
|
812
|
+
entries.push({
|
|
813
|
+
id: trackerKey,
|
|
814
|
+
label,
|
|
815
|
+
instantTps: trackerState.tracker.getSmoothedTPS(),
|
|
816
|
+
avgTps: trackerState.tracker.getAverageTPS(),
|
|
817
|
+
totalTokens: trackerState.tracker.getTotalTokens(),
|
|
818
|
+
elapsedMs: now - trackerState.firstTokenAt
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
entries.sort((a, b) => b.instantTps - a.instantTps);
|
|
823
|
+
return entries;
|
|
824
|
+
}
|
|
825
|
+
function isPrimarySessionActive(now) {
|
|
826
|
+
if (!primarySessionId)
|
|
827
|
+
return false;
|
|
828
|
+
const sessionState = sessionTrackers.get(primarySessionId);
|
|
829
|
+
if (!sessionState)
|
|
830
|
+
return false;
|
|
831
|
+
const activityWindow = Math.max(resolvedConfig.rollingWindowMs, MIN_TPS_ELAPSED_MS * 4);
|
|
832
|
+
for (const trackerState of sessionState.messageTrackers.values()) {
|
|
833
|
+
const hasAgentMetadata = Boolean(trackerState.agent || trackerState.agentId || trackerState.agentType);
|
|
834
|
+
if (hasAgentMetadata)
|
|
835
|
+
continue;
|
|
836
|
+
if (trackerState.firstTokenAt && now - trackerState.lastUpdated <= activityWindow) {
|
|
837
|
+
return true;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
return false;
|
|
841
|
+
}
|
|
842
|
+
function getActiveAgentDisplayStates(sessionState, now) {
|
|
843
|
+
const activityWindow = Math.max(resolvedConfig.rollingWindowMs, MIN_TPS_ELAPSED_MS * 4);
|
|
844
|
+
const entries = [];
|
|
845
|
+
for (const trackerState of sessionState.messageTrackers.values()) {
|
|
846
|
+
if (!trackerState.firstTokenAt) {
|
|
847
|
+
continue;
|
|
848
|
+
}
|
|
849
|
+
if (now - trackerState.lastUpdated > activityWindow) {
|
|
850
|
+
continue;
|
|
851
|
+
}
|
|
852
|
+
const hasAgentMetadata = Boolean(trackerState.agent || trackerState.agentId || trackerState.agentType);
|
|
853
|
+
if (!hasAgentMetadata) {
|
|
854
|
+
continue;
|
|
855
|
+
}
|
|
856
|
+
entries.push({
|
|
857
|
+
id: trackerState.messageId,
|
|
858
|
+
label: trackerState.label,
|
|
859
|
+
instantTps: trackerState.tracker.getSmoothedTPS(),
|
|
860
|
+
avgTps: trackerState.tracker.getAverageTPS(),
|
|
861
|
+
totalTokens: trackerState.tracker.getTotalTokens(),
|
|
862
|
+
elapsedMs: now - trackerState.firstTokenAt
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
entries.sort((a, b) => b.instantTps - a.instantTps);
|
|
866
|
+
return entries;
|
|
867
|
+
}
|
|
868
|
+
function removeMessageTrackerState(sessionId, messageId) {
|
|
869
|
+
const sessionState = sessionTrackers.get(sessionId);
|
|
870
|
+
if (!sessionState) {
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
for (const [key, state] of sessionState.messageTrackers) {
|
|
874
|
+
if (state.messageId === messageId) {
|
|
875
|
+
sessionState.messageTrackers.delete(key);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
if (sessionState.messageTrackers.size === 0) {
|
|
879
|
+
sessionState.aggregate.reset();
|
|
880
|
+
sessionState.aggregateFirstTokenAt = null;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
function scheduleDisplayTimer(sessionId) {
|
|
884
|
+
const existingTimer = pendingDisplayTimers.get(sessionId);
|
|
885
|
+
if (existingTimer) {
|
|
886
|
+
clearTimeout(existingTimer);
|
|
887
|
+
}
|
|
888
|
+
const timer = setTimeout(() => {
|
|
889
|
+
pendingDisplayTimers.delete(sessionId);
|
|
890
|
+
const sessionState = sessionTrackers.get(sessionId);
|
|
891
|
+
if (!sessionState || !sessionState.aggregateFirstTokenAt) {
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
const now = Date.now();
|
|
895
|
+
const elapsedSinceFirstToken = now - sessionState.aggregateFirstTokenAt;
|
|
896
|
+
if (elapsedSinceFirstToken < MIN_TPS_ELAPSED_MS)
|
|
897
|
+
return;
|
|
898
|
+
const allAgents = getAllActiveAgentsGlobally(now);
|
|
899
|
+
const hasPrimaryActivity = isPrimarySessionActive(now);
|
|
900
|
+
if (hasPrimaryActivity) {
|
|
901
|
+
const smoothedTps = sessionState.aggregate.getSmoothedTPS();
|
|
902
|
+
const avgTps = sessionState.aggregate.getAverageTPS();
|
|
903
|
+
const totalTokens = sessionState.aggregate.getTotalTokens();
|
|
904
|
+
const elapsedMs = sessionState.aggregate.getElapsedMs();
|
|
905
|
+
if (smoothedTps >= resolvedConfig.minVisibleTPS) {
|
|
906
|
+
ui.updateDisplay(smoothedTps, avgTps, totalTokens, elapsedMs, allAgents);
|
|
907
|
+
}
|
|
908
|
+
} else if (allAgents.length > 0) {
|
|
909
|
+
ui.updateDisplay(0, 0, 0, 0, allAgents);
|
|
910
|
+
}
|
|
911
|
+
logger.debug(`[TpsMeter] Timer-triggered display for session ${sessionId}`);
|
|
912
|
+
}, MIN_TPS_ELAPSED_MS + 10);
|
|
913
|
+
pendingDisplayTimers.set(sessionId, timer);
|
|
914
|
+
}
|
|
915
|
+
function clearDisplayTimer(sessionId) {
|
|
916
|
+
const timer = pendingDisplayTimers.get(sessionId);
|
|
917
|
+
if (timer) {
|
|
918
|
+
clearTimeout(timer);
|
|
919
|
+
pendingDisplayTimers.delete(sessionId);
|
|
920
|
+
}
|
|
674
921
|
}
|
|
675
922
|
function cleanup() {
|
|
676
923
|
logger.debug("[TpsMeter] Cleaning up all trackers and UI");
|
|
677
|
-
|
|
924
|
+
for (const timer of pendingDisplayTimers.values()) {
|
|
925
|
+
clearTimeout(timer);
|
|
926
|
+
}
|
|
927
|
+
pendingDisplayTimers.clear();
|
|
928
|
+
sessionTrackers.clear();
|
|
929
|
+
partTextCache.clear();
|
|
930
|
+
messageTokenCache.clear();
|
|
678
931
|
messageRoleCache.clear();
|
|
679
|
-
|
|
680
|
-
|
|
932
|
+
sessionAgentNameCache.clear();
|
|
933
|
+
primarySessionId = null;
|
|
681
934
|
ui.clear();
|
|
682
935
|
}
|
|
683
936
|
function handleMessagePartUpdated(event) {
|
|
@@ -696,11 +949,7 @@ function TpsMeterPlugin(context) {
|
|
|
696
949
|
partTextCache.set(sessionId, sessionCache);
|
|
697
950
|
const cacheKey = `${part.messageID}:${part.id}:${part.type}`;
|
|
698
951
|
const previousText = sessionCache.get(cacheKey) || "";
|
|
699
|
-
|
|
700
|
-
delta = partText.slice(previousText.length);
|
|
701
|
-
} else {
|
|
702
|
-
delta = partText;
|
|
703
|
-
}
|
|
952
|
+
delta = partText.startsWith(previousText) ? partText.slice(previousText.length) : partText;
|
|
704
953
|
sessionCache.set(cacheKey, partText);
|
|
705
954
|
}
|
|
706
955
|
if (!delta || delta.length === 0) {
|
|
@@ -711,35 +960,52 @@ function TpsMeterPlugin(context) {
|
|
|
711
960
|
if (role !== "assistant") {
|
|
712
961
|
return;
|
|
713
962
|
}
|
|
714
|
-
const
|
|
715
|
-
const
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
}
|
|
963
|
+
const sessionState = getOrCreateSessionState(sessionId);
|
|
964
|
+
const messageTracker = getOrCreateMessageTrackerState(sessionId, part.messageID, part.id, {
|
|
965
|
+
agent: part.agent,
|
|
966
|
+
agentId: part.agentId,
|
|
967
|
+
agentType: part.agentType,
|
|
968
|
+
name: part.name
|
|
969
|
+
});
|
|
721
970
|
const now = Date.now();
|
|
722
971
|
cleanupStaleMessages(now);
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
if (firstTokenAt === undefined) {
|
|
727
|
-
firstTokenAt = now;
|
|
728
|
-
firstTokenCache.set(messageId, firstTokenAt);
|
|
972
|
+
if (!sessionState.aggregateFirstTokenAt) {
|
|
973
|
+
sessionState.aggregateFirstTokenAt = now;
|
|
974
|
+
scheduleDisplayTimer(sessionId);
|
|
729
975
|
}
|
|
976
|
+
if (!messageTracker.firstTokenAt) {
|
|
977
|
+
messageTracker.firstTokenAt = now;
|
|
978
|
+
const hasAgentMetadata = Boolean(messageTracker.agent || messageTracker.agentId || messageTracker.agentType);
|
|
979
|
+
if (!hasAgentMetadata && primarySessionId === null) {
|
|
980
|
+
primarySessionId = sessionId;
|
|
981
|
+
logger.debug(`[TpsMeter] Primary session set to: ${sessionId}`);
|
|
982
|
+
}
|
|
983
|
+
const metaLabel = messageTracker.label;
|
|
984
|
+
const metaInfo = messageTracker.agent || messageTracker.agentId || messageTracker.agentType ? `agent=${messageTracker.agent?.type ?? messageTracker.agentType ?? "?"} id=${messageTracker.agent?.id ?? messageTracker.agentId ?? "?"}` : "agent=none";
|
|
985
|
+
logger.info(`[TpsMeter][Debug] tracker initialized ${metaLabel} (${metaInfo}) session=${sessionId} message=${part.messageID} part=${part.id ?? "?"}`);
|
|
986
|
+
}
|
|
987
|
+
messageTracker.lastUpdated = now;
|
|
730
988
|
const tokenCount = tokenizer.count(delta);
|
|
731
|
-
|
|
989
|
+
sessionState.aggregate.recordTokens(tokenCount, now);
|
|
990
|
+
messageTracker.tracker.recordTokens(tokenCount, now);
|
|
732
991
|
const messageCache = messageTokenCache.get(sessionId) || new Map;
|
|
733
992
|
messageTokenCache.set(sessionId, messageCache);
|
|
734
|
-
const previousTokens = messageCache.get(
|
|
735
|
-
messageCache.set(
|
|
736
|
-
const smoothedTps =
|
|
737
|
-
const avgTps =
|
|
738
|
-
const totalTokens =
|
|
739
|
-
const elapsedMs =
|
|
740
|
-
const elapsedSinceFirstToken = Math.max(0, now -
|
|
741
|
-
if (elapsedSinceFirstToken >= MIN_TPS_ELAPSED_MS
|
|
742
|
-
|
|
993
|
+
const previousTokens = messageCache.get(part.messageID) ?? 0;
|
|
994
|
+
messageCache.set(part.messageID, previousTokens + tokenCount);
|
|
995
|
+
const smoothedTps = sessionState.aggregate.getSmoothedTPS();
|
|
996
|
+
const avgTps = sessionState.aggregate.getAverageTPS();
|
|
997
|
+
const totalTokens = sessionState.aggregate.getTotalTokens();
|
|
998
|
+
const elapsedMs = sessionState.aggregate.getElapsedMs();
|
|
999
|
+
const elapsedSinceFirstToken = sessionState.aggregateFirstTokenAt === null ? 0 : Math.max(0, now - sessionState.aggregateFirstTokenAt);
|
|
1000
|
+
if (elapsedSinceFirstToken >= MIN_TPS_ELAPSED_MS) {
|
|
1001
|
+
clearDisplayTimer(sessionId);
|
|
1002
|
+
const allAgents = getAllActiveAgentsGlobally(now);
|
|
1003
|
+
const hasPrimaryActivity = isPrimarySessionActive(now) && smoothedTps >= resolvedConfig.minVisibleTPS;
|
|
1004
|
+
if (hasPrimaryActivity) {
|
|
1005
|
+
ui.updateDisplay(smoothedTps, avgTps, totalTokens, elapsedMs, allAgents);
|
|
1006
|
+
} else if (allAgents.length > 0) {
|
|
1007
|
+
ui.updateDisplay(0, 0, 0, 0, allAgents);
|
|
1008
|
+
}
|
|
743
1009
|
}
|
|
744
1010
|
logger.debug(`[TpsMeter] Session ${sessionId}: +${tokenCount} tokens, TPS: ${smoothedTps.toFixed(1)} (avg: ${avgTps.toFixed(1)})`);
|
|
745
1011
|
}
|
|
@@ -751,25 +1017,33 @@ function TpsMeterPlugin(context) {
|
|
|
751
1017
|
const roleCache = messageRoleCache.get(info.sessionID) || new Map;
|
|
752
1018
|
messageRoleCache.set(info.sessionID, roleCache);
|
|
753
1019
|
roleCache.set(info.id, info.role);
|
|
1020
|
+
if (info.agent || info.agentType) {
|
|
1021
|
+
const agentName = info.agent?.name || info.agent?.type || info.agentType || info.agent?.id;
|
|
1022
|
+
if (agentName && typeof agentName === "string") {
|
|
1023
|
+
sessionAgentNameCache.set(info.sessionID, agentName);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
754
1026
|
if (info.role === "assistant") {
|
|
755
1027
|
const sessionId = info.sessionID;
|
|
756
|
-
const tracker = trackers.get(sessionId);
|
|
757
1028
|
const sessionCache = partTextCache.get(sessionId);
|
|
758
1029
|
const tokenCache = messageTokenCache.get(sessionId) || new Map;
|
|
759
1030
|
messageTokenCache.set(sessionId, tokenCache);
|
|
760
|
-
const firstTokenCache = messageFirstTokenCache.get(sessionId) || new Map;
|
|
761
|
-
messageFirstTokenCache.set(sessionId, firstTokenCache);
|
|
762
1031
|
const outputTokens = info.tokens?.output ?? 0;
|
|
763
1032
|
const reasoningTokens = info.tokens?.reasoning ?? 0;
|
|
764
1033
|
const reportedTokens = outputTokens + reasoningTokens;
|
|
765
1034
|
const messageId = info.id;
|
|
1035
|
+
const messageTracker = getOrCreateMessageTrackerState(sessionId, messageId, undefined, {
|
|
1036
|
+
agent: info.agent,
|
|
1037
|
+
agentId: info.agentId,
|
|
1038
|
+
agentType: info.agentType
|
|
1039
|
+
});
|
|
766
1040
|
const previous = tokenCache.get(messageId) ?? 0;
|
|
767
1041
|
const nextTokens = Math.max(previous, reportedTokens);
|
|
768
1042
|
tokenCache.set(messageId, nextTokens);
|
|
769
|
-
if (info.time?.completed
|
|
1043
|
+
if (info.time?.completed) {
|
|
770
1044
|
const completedAt = info.time?.completed ?? Date.now();
|
|
771
1045
|
const createdAt = info.time?.created ?? completedAt;
|
|
772
|
-
const firstTokenAt =
|
|
1046
|
+
const firstTokenAt = messageTracker.firstTokenAt ?? createdAt;
|
|
773
1047
|
const elapsedMs = Math.max(0, completedAt - firstTokenAt);
|
|
774
1048
|
const cachedTokens = tokenCache.get(messageId) ?? 0;
|
|
775
1049
|
const totalTokens = reportedTokens > 0 ? reportedTokens : cachedTokens;
|
|
@@ -791,7 +1065,7 @@ function TpsMeterPlugin(context) {
|
|
|
791
1065
|
if (info.time?.completed) {
|
|
792
1066
|
tokenCache.delete(messageId);
|
|
793
1067
|
roleCache.delete(messageId);
|
|
794
|
-
|
|
1068
|
+
removeMessageTrackerState(sessionId, messageId);
|
|
795
1069
|
}
|
|
796
1070
|
}
|
|
797
1071
|
if (info.error) {
|
|
@@ -801,13 +1075,13 @@ function TpsMeterPlugin(context) {
|
|
|
801
1075
|
function handleSessionIdle(event) {
|
|
802
1076
|
const sessionId = event.properties.sessionID || "default";
|
|
803
1077
|
logger.debug(`[TpsMeter] Session idle: ${sessionId}`);
|
|
804
|
-
|
|
1078
|
+
clearDisplayTimer(sessionId);
|
|
1079
|
+
sessionTrackers.delete(sessionId);
|
|
805
1080
|
partTextCache.delete(sessionId);
|
|
806
1081
|
messageTokenCache.delete(sessionId);
|
|
807
1082
|
messageRoleCache.delete(sessionId);
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
if (trackers.size === 0) {
|
|
1083
|
+
sessionAgentNameCache.delete(sessionId);
|
|
1084
|
+
if (sessionTrackers.size === 0) {
|
|
811
1085
|
cleanup();
|
|
812
1086
|
}
|
|
813
1087
|
}
|
|
@@ -818,17 +1092,37 @@ function TpsMeterPlugin(context) {
|
|
|
818
1092
|
}
|
|
819
1093
|
lastCleanupTime = now;
|
|
820
1094
|
let cleanedCount = 0;
|
|
821
|
-
for (const [sessionId,
|
|
1095
|
+
for (const [sessionId, sessionState] of sessionTrackers) {
|
|
822
1096
|
const tokenCache = messageTokenCache.get(sessionId);
|
|
823
1097
|
const roleCache = messageRoleCache.get(sessionId);
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
1098
|
+
const sessionCache = partTextCache.get(sessionId);
|
|
1099
|
+
const keysToDelete = [];
|
|
1100
|
+
for (const [key, messageTracker] of sessionState.messageTrackers) {
|
|
1101
|
+
if (messageTracker.lastUpdated > 0 && now - messageTracker.lastUpdated > MAX_MESSAGE_AGE_MS) {
|
|
1102
|
+
keysToDelete.push(key);
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
for (const key of keysToDelete) {
|
|
1106
|
+
const messageTracker = sessionState.messageTrackers.get(key);
|
|
1107
|
+
if (messageTracker) {
|
|
1108
|
+
sessionState.messageTrackers.delete(key);
|
|
1109
|
+
const messageId = messageTracker.messageId;
|
|
827
1110
|
tokenCache?.delete(messageId);
|
|
828
1111
|
roleCache?.delete(messageId);
|
|
1112
|
+
if (sessionCache) {
|
|
1113
|
+
for (const cacheKey of sessionCache.keys()) {
|
|
1114
|
+
if (cacheKey.startsWith(`${messageId}:`)) {
|
|
1115
|
+
sessionCache.delete(cacheKey);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
829
1119
|
cleanedCount++;
|
|
830
1120
|
}
|
|
831
1121
|
}
|
|
1122
|
+
if (sessionState.messageTrackers.size === 0) {
|
|
1123
|
+
sessionState.aggregate.reset();
|
|
1124
|
+
sessionState.aggregateFirstTokenAt = null;
|
|
1125
|
+
}
|
|
832
1126
|
}
|
|
833
1127
|
if (cleanedCount > 0) {
|
|
834
1128
|
logger.debug(`[TpsMeter] Cleaned up ${cleanedCount} stale message entries`);
|
package/dist/index.mjs
CHANGED
|
@@ -3,9 +3,12 @@ var MIN_TPS_ELAPSED_MS = 250;
|
|
|
3
3
|
var DEFAULT_ROLLING_WINDOW_MS = 1000;
|
|
4
4
|
var MAX_BUFFER_SIZE = 100;
|
|
5
5
|
var MIN_WINDOW_DURATION_SECONDS = 0.1;
|
|
6
|
-
var BURST_TOKEN_THRESHOLD =
|
|
6
|
+
var BURST_TOKEN_THRESHOLD = 50;
|
|
7
7
|
var DEFAULT_EWMA_HALF_LIFE_MS = 500;
|
|
8
|
-
var BURST_EWMA_HALF_LIFE_MS =
|
|
8
|
+
var BURST_EWMA_HALF_LIFE_MS = 3000;
|
|
9
|
+
var LARGE_BURST_THRESHOLD = 200;
|
|
10
|
+
var LARGE_BURST_EWMA_HALF_LIFE_MS = 5000;
|
|
11
|
+
var MAX_INITIAL_TPS = 100;
|
|
9
12
|
var DEFAULT_UPDATE_INTERVAL_MS = 50;
|
|
10
13
|
var MIN_TOAST_INTERVAL_MS = 150;
|
|
11
14
|
var DEFAULT_TOAST_DURATION_MS = 20000;
|
|
@@ -77,11 +80,18 @@ function createTracker(options = {}) {
|
|
|
77
80
|
pruneBuffer(ts);
|
|
78
81
|
const rawTPS = calculateRawTPS(ts);
|
|
79
82
|
if (!hasSmoothedValue) {
|
|
80
|
-
smoothedTps = rawTPS;
|
|
83
|
+
smoothedTps = Math.min(rawTPS, MAX_INITIAL_TPS);
|
|
81
84
|
hasSmoothedValue = true;
|
|
82
85
|
} else {
|
|
83
86
|
const timeDelta = Math.max(1, ts - lastSmoothedAt);
|
|
84
|
-
|
|
87
|
+
let halfLife;
|
|
88
|
+
if (count > LARGE_BURST_THRESHOLD) {
|
|
89
|
+
halfLife = LARGE_BURST_EWMA_HALF_LIFE_MS;
|
|
90
|
+
} else if (count > BURST_TOKEN_THRESHOLD) {
|
|
91
|
+
halfLife = BURST_EWMA_HALF_LIFE_MS;
|
|
92
|
+
} else {
|
|
93
|
+
halfLife = DEFAULT_EWMA_HALF_LIFE_MS;
|
|
94
|
+
}
|
|
85
95
|
const alpha = Math.exp(-Math.LN2 * timeDelta / halfLife);
|
|
86
96
|
smoothedTps = alpha * smoothedTps + (1 - alpha) * rawTPS;
|
|
87
97
|
}
|
|
@@ -157,7 +167,7 @@ function createUIManager(client, config) {
|
|
|
157
167
|
function formatNumberWithCommas(num) {
|
|
158
168
|
return num.toLocaleString("en-US");
|
|
159
169
|
}
|
|
160
|
-
function
|
|
170
|
+
function formatPrimaryLine(state) {
|
|
161
171
|
const parts = [];
|
|
162
172
|
if (uiConfig.showInstant || uiConfig.showAverage) {
|
|
163
173
|
const tpsParts = [];
|
|
@@ -167,7 +177,9 @@ function createUIManager(client, config) {
|
|
|
167
177
|
if (uiConfig.showAverage) {
|
|
168
178
|
tpsParts.push(`(avg ${state.avgTps.toFixed(1)})`);
|
|
169
179
|
}
|
|
170
|
-
|
|
180
|
+
if (tpsParts.length > 0) {
|
|
181
|
+
parts.push(tpsParts.join(" "));
|
|
182
|
+
}
|
|
171
183
|
}
|
|
172
184
|
if (uiConfig.showTotalTokens) {
|
|
173
185
|
parts.push(`tokens: ${formatNumberWithCommas(state.totalTokens)}`);
|
|
@@ -175,7 +187,43 @@ function createUIManager(client, config) {
|
|
|
175
187
|
if (uiConfig.showElapsed) {
|
|
176
188
|
parts.push(formatElapsedTime(state.elapsedMs));
|
|
177
189
|
}
|
|
178
|
-
return parts.join(" | ");
|
|
190
|
+
return parts.length > 0 ? parts.join(" | ") : "TPS meter";
|
|
191
|
+
}
|
|
192
|
+
function formatAgentLine(agent) {
|
|
193
|
+
const segments = [];
|
|
194
|
+
if (uiConfig.showInstant || uiConfig.showAverage) {
|
|
195
|
+
const tpsParts = [];
|
|
196
|
+
if (uiConfig.showInstant) {
|
|
197
|
+
tpsParts.push(`${agent.instantTps.toFixed(1)}`);
|
|
198
|
+
}
|
|
199
|
+
if (uiConfig.showAverage) {
|
|
200
|
+
tpsParts.push(`(avg ${agent.avgTps.toFixed(1)})`);
|
|
201
|
+
}
|
|
202
|
+
if (tpsParts.length > 0) {
|
|
203
|
+
segments.push(tpsParts.join(" "));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (uiConfig.showTotalTokens) {
|
|
207
|
+
segments.push(`tokens: ${formatNumberWithCommas(agent.totalTokens)}`);
|
|
208
|
+
}
|
|
209
|
+
if (uiConfig.showElapsed) {
|
|
210
|
+
segments.push(formatElapsedTime(agent.elapsedMs));
|
|
211
|
+
}
|
|
212
|
+
return `${agent.label} ${segments.join(" | ")}`.trim();
|
|
213
|
+
}
|
|
214
|
+
function formatDisplay(state) {
|
|
215
|
+
const lines = [];
|
|
216
|
+
const hasMainActivity = state.totalTokens > 0;
|
|
217
|
+
if (hasMainActivity) {
|
|
218
|
+
lines.push(formatPrimaryLine(state));
|
|
219
|
+
}
|
|
220
|
+
const agentLines = (state.agents ?? []).filter((agent) => agent.totalTokens > 0).map((agent) => formatAgentLine(agent));
|
|
221
|
+
lines.push(...agentLines);
|
|
222
|
+
if (lines.length === 0) {
|
|
223
|
+
return "TPS meter (idle)";
|
|
224
|
+
}
|
|
225
|
+
return lines.join(`
|
|
226
|
+
`);
|
|
179
227
|
}
|
|
180
228
|
function getColorVariant(instantTps, isFinal) {
|
|
181
229
|
if (isFinal) {
|
|
@@ -256,7 +304,11 @@ function createUIManager(client, config) {
|
|
|
256
304
|
function flushPendingUpdate() {
|
|
257
305
|
if (pendingState) {
|
|
258
306
|
const formatted = formatDisplay(pendingState);
|
|
259
|
-
|
|
307
|
+
let tpsForColor = pendingState.instantTps;
|
|
308
|
+
if (pendingState.totalTokens === 0 && pendingState.agents?.length) {
|
|
309
|
+
tpsForColor = Math.max(...pendingState.agents.map((a) => a.instantTps));
|
|
310
|
+
}
|
|
311
|
+
display(formatted, false, tpsForColor);
|
|
260
312
|
lastDisplayedState = { ...pendingState };
|
|
261
313
|
pendingState = null;
|
|
262
314
|
}
|
|
@@ -274,12 +326,13 @@ function createUIManager(client, config) {
|
|
|
274
326
|
}, delay);
|
|
275
327
|
}
|
|
276
328
|
return {
|
|
277
|
-
updateDisplay(instantTps, avgTps, totalTokens, elapsedMs) {
|
|
329
|
+
updateDisplay(instantTps, avgTps, totalTokens, elapsedMs, agents) {
|
|
278
330
|
pendingState = {
|
|
279
331
|
instantTps,
|
|
280
332
|
avgTps,
|
|
281
333
|
totalTokens,
|
|
282
|
-
elapsedMs
|
|
334
|
+
elapsedMs,
|
|
335
|
+
agents: agents && agents.length > 0 ? agents : undefined
|
|
283
336
|
};
|
|
284
337
|
scheduleFlush();
|
|
285
338
|
},
|
|
@@ -603,34 +656,234 @@ function TpsMeterPlugin(context) {
|
|
|
603
656
|
logger.debug("[TpsMeter] Plugin disabled by configuration");
|
|
604
657
|
return {};
|
|
605
658
|
}
|
|
606
|
-
const
|
|
659
|
+
const sessionTrackers = new Map;
|
|
607
660
|
const partTextCache = new Map;
|
|
608
661
|
const messageTokenCache = new Map;
|
|
609
662
|
const messageRoleCache = new Map;
|
|
610
|
-
const
|
|
611
|
-
|
|
663
|
+
const sessionAgentNameCache = new Map;
|
|
664
|
+
let primarySessionId = null;
|
|
665
|
+
const pendingDisplayTimers = new Map;
|
|
612
666
|
const resolvedConfig = config;
|
|
613
667
|
const ui = createUIManager(safeContext.client || {}, resolvedConfig);
|
|
614
668
|
const tokenizer = createTokenizer(resolvedConfig.fallbackTokenHeuristic === "words_div_0_75" ? "word" : resolvedConfig.fallbackTokenHeuristic === "chars_div_3" ? "code" : "heuristic");
|
|
615
669
|
logger.info("[TpsMeter] Plugin initialized and ready");
|
|
616
|
-
function
|
|
617
|
-
let
|
|
618
|
-
if (!
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
670
|
+
function getOrCreateSessionState(sessionId) {
|
|
671
|
+
let state = sessionTrackers.get(sessionId);
|
|
672
|
+
if (!state) {
|
|
673
|
+
state = {
|
|
674
|
+
aggregate: createTracker({
|
|
675
|
+
sessionId,
|
|
676
|
+
rollingWindowMs: resolvedConfig.rollingWindowMs
|
|
677
|
+
}),
|
|
678
|
+
aggregateFirstTokenAt: null,
|
|
679
|
+
messageTrackers: new Map
|
|
680
|
+
};
|
|
681
|
+
sessionTrackers.set(sessionId, state);
|
|
624
682
|
logger.debug(`[TpsMeter] Created tracker for session: ${sessionId}`);
|
|
625
683
|
}
|
|
626
|
-
return
|
|
684
|
+
return state;
|
|
685
|
+
}
|
|
686
|
+
function abbreviateId(id) {
|
|
687
|
+
if (!id || id.length <= 4)
|
|
688
|
+
return id;
|
|
689
|
+
return `${id.slice(0, 4)}…`;
|
|
690
|
+
}
|
|
691
|
+
function buildAgentLabel(messageId, metadata) {
|
|
692
|
+
const typeLabel = metadata?.agent?.type?.trim() || metadata?.agentType?.trim() || metadata?.agent?.name?.trim() || metadata?.name?.trim() || "Subagent";
|
|
693
|
+
const rawId = metadata?.agentId?.trim() || metadata?.agent?.id?.trim() || messageId;
|
|
694
|
+
const identifier = abbreviateId(rawId);
|
|
695
|
+
return `${typeLabel}(${identifier})`;
|
|
696
|
+
}
|
|
697
|
+
function buildTrackerKey(sessionId, messageId, partId, metadata) {
|
|
698
|
+
const agentId = metadata?.agentId?.trim() || metadata?.agent?.id?.trim() || metadata?.agentType?.trim();
|
|
699
|
+
if (agentId) {
|
|
700
|
+
return `${sessionId}:${messageId}:${agentId}`;
|
|
701
|
+
}
|
|
702
|
+
if (partId) {
|
|
703
|
+
return `${sessionId}:${messageId}:${partId}`;
|
|
704
|
+
}
|
|
705
|
+
return `${sessionId}:${messageId}`;
|
|
706
|
+
}
|
|
707
|
+
function getOrCreateMessageTrackerState(sessionId, messageId, partId, metadata) {
|
|
708
|
+
const sessionState = getOrCreateSessionState(sessionId);
|
|
709
|
+
const key = buildTrackerKey(sessionId, messageId, partId, metadata);
|
|
710
|
+
let trackerState = sessionState.messageTrackers.get(key);
|
|
711
|
+
const nextLabel = buildAgentLabel(messageId, metadata);
|
|
712
|
+
if (!trackerState) {
|
|
713
|
+
trackerState = {
|
|
714
|
+
key,
|
|
715
|
+
messageId,
|
|
716
|
+
partId,
|
|
717
|
+
tracker: createTracker({
|
|
718
|
+
sessionId: key,
|
|
719
|
+
rollingWindowMs: resolvedConfig.rollingWindowMs
|
|
720
|
+
}),
|
|
721
|
+
label: nextLabel,
|
|
722
|
+
firstTokenAt: null,
|
|
723
|
+
lastUpdated: 0,
|
|
724
|
+
agent: metadata?.agent,
|
|
725
|
+
agentId: metadata?.agentId,
|
|
726
|
+
agentType: metadata?.agentType
|
|
727
|
+
};
|
|
728
|
+
sessionState.messageTrackers.set(key, trackerState);
|
|
729
|
+
} else if (trackerState.label !== nextLabel) {
|
|
730
|
+
trackerState.label = nextLabel;
|
|
731
|
+
}
|
|
732
|
+
if (metadata?.agent) {
|
|
733
|
+
trackerState.agent = metadata.agent;
|
|
734
|
+
}
|
|
735
|
+
if (metadata?.agentId) {
|
|
736
|
+
trackerState.agentId = metadata.agentId;
|
|
737
|
+
}
|
|
738
|
+
if (metadata?.agentType) {
|
|
739
|
+
trackerState.agentType = metadata.agentType;
|
|
740
|
+
}
|
|
741
|
+
return trackerState;
|
|
742
|
+
}
|
|
743
|
+
function getAllActiveAgentsGlobally(now) {
|
|
744
|
+
const activityWindow = Math.max(resolvedConfig.rollingWindowMs, MIN_TPS_ELAPSED_MS * 4);
|
|
745
|
+
const entries = [];
|
|
746
|
+
for (const [sessionId, sessionState] of sessionTrackers) {
|
|
747
|
+
for (const [trackerKey, trackerState] of sessionState.messageTrackers) {
|
|
748
|
+
if (!trackerState.firstTokenAt)
|
|
749
|
+
continue;
|
|
750
|
+
if (now - trackerState.lastUpdated > activityWindow)
|
|
751
|
+
continue;
|
|
752
|
+
const hasAgentMetadata = Boolean(trackerState.agent || trackerState.agentId || trackerState.agentType);
|
|
753
|
+
let isSubagent = false;
|
|
754
|
+
let label = trackerState.label;
|
|
755
|
+
if (hasAgentMetadata) {
|
|
756
|
+
isSubagent = true;
|
|
757
|
+
} else if (sessionId !== primarySessionId) {
|
|
758
|
+
isSubagent = true;
|
|
759
|
+
const agentName = sessionAgentNameCache.get(sessionId) || "bg";
|
|
760
|
+
const shortId = abbreviateId(sessionId.replace(/^ses_/, ""));
|
|
761
|
+
label = `${agentName}(${shortId})`;
|
|
762
|
+
}
|
|
763
|
+
if (!isSubagent)
|
|
764
|
+
continue;
|
|
765
|
+
entries.push({
|
|
766
|
+
id: trackerKey,
|
|
767
|
+
label,
|
|
768
|
+
instantTps: trackerState.tracker.getSmoothedTPS(),
|
|
769
|
+
avgTps: trackerState.tracker.getAverageTPS(),
|
|
770
|
+
totalTokens: trackerState.tracker.getTotalTokens(),
|
|
771
|
+
elapsedMs: now - trackerState.firstTokenAt
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
entries.sort((a, b) => b.instantTps - a.instantTps);
|
|
776
|
+
return entries;
|
|
777
|
+
}
|
|
778
|
+
function isPrimarySessionActive(now) {
|
|
779
|
+
if (!primarySessionId)
|
|
780
|
+
return false;
|
|
781
|
+
const sessionState = sessionTrackers.get(primarySessionId);
|
|
782
|
+
if (!sessionState)
|
|
783
|
+
return false;
|
|
784
|
+
const activityWindow = Math.max(resolvedConfig.rollingWindowMs, MIN_TPS_ELAPSED_MS * 4);
|
|
785
|
+
for (const trackerState of sessionState.messageTrackers.values()) {
|
|
786
|
+
const hasAgentMetadata = Boolean(trackerState.agent || trackerState.agentId || trackerState.agentType);
|
|
787
|
+
if (hasAgentMetadata)
|
|
788
|
+
continue;
|
|
789
|
+
if (trackerState.firstTokenAt && now - trackerState.lastUpdated <= activityWindow) {
|
|
790
|
+
return true;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
return false;
|
|
794
|
+
}
|
|
795
|
+
function getActiveAgentDisplayStates(sessionState, now) {
|
|
796
|
+
const activityWindow = Math.max(resolvedConfig.rollingWindowMs, MIN_TPS_ELAPSED_MS * 4);
|
|
797
|
+
const entries = [];
|
|
798
|
+
for (const trackerState of sessionState.messageTrackers.values()) {
|
|
799
|
+
if (!trackerState.firstTokenAt) {
|
|
800
|
+
continue;
|
|
801
|
+
}
|
|
802
|
+
if (now - trackerState.lastUpdated > activityWindow) {
|
|
803
|
+
continue;
|
|
804
|
+
}
|
|
805
|
+
const hasAgentMetadata = Boolean(trackerState.agent || trackerState.agentId || trackerState.agentType);
|
|
806
|
+
if (!hasAgentMetadata) {
|
|
807
|
+
continue;
|
|
808
|
+
}
|
|
809
|
+
entries.push({
|
|
810
|
+
id: trackerState.messageId,
|
|
811
|
+
label: trackerState.label,
|
|
812
|
+
instantTps: trackerState.tracker.getSmoothedTPS(),
|
|
813
|
+
avgTps: trackerState.tracker.getAverageTPS(),
|
|
814
|
+
totalTokens: trackerState.tracker.getTotalTokens(),
|
|
815
|
+
elapsedMs: now - trackerState.firstTokenAt
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
entries.sort((a, b) => b.instantTps - a.instantTps);
|
|
819
|
+
return entries;
|
|
820
|
+
}
|
|
821
|
+
function removeMessageTrackerState(sessionId, messageId) {
|
|
822
|
+
const sessionState = sessionTrackers.get(sessionId);
|
|
823
|
+
if (!sessionState) {
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
for (const [key, state] of sessionState.messageTrackers) {
|
|
827
|
+
if (state.messageId === messageId) {
|
|
828
|
+
sessionState.messageTrackers.delete(key);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
if (sessionState.messageTrackers.size === 0) {
|
|
832
|
+
sessionState.aggregate.reset();
|
|
833
|
+
sessionState.aggregateFirstTokenAt = null;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
function scheduleDisplayTimer(sessionId) {
|
|
837
|
+
const existingTimer = pendingDisplayTimers.get(sessionId);
|
|
838
|
+
if (existingTimer) {
|
|
839
|
+
clearTimeout(existingTimer);
|
|
840
|
+
}
|
|
841
|
+
const timer = setTimeout(() => {
|
|
842
|
+
pendingDisplayTimers.delete(sessionId);
|
|
843
|
+
const sessionState = sessionTrackers.get(sessionId);
|
|
844
|
+
if (!sessionState || !sessionState.aggregateFirstTokenAt) {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
const now = Date.now();
|
|
848
|
+
const elapsedSinceFirstToken = now - sessionState.aggregateFirstTokenAt;
|
|
849
|
+
if (elapsedSinceFirstToken < MIN_TPS_ELAPSED_MS)
|
|
850
|
+
return;
|
|
851
|
+
const allAgents = getAllActiveAgentsGlobally(now);
|
|
852
|
+
const hasPrimaryActivity = isPrimarySessionActive(now);
|
|
853
|
+
if (hasPrimaryActivity) {
|
|
854
|
+
const smoothedTps = sessionState.aggregate.getSmoothedTPS();
|
|
855
|
+
const avgTps = sessionState.aggregate.getAverageTPS();
|
|
856
|
+
const totalTokens = sessionState.aggregate.getTotalTokens();
|
|
857
|
+
const elapsedMs = sessionState.aggregate.getElapsedMs();
|
|
858
|
+
if (smoothedTps >= resolvedConfig.minVisibleTPS) {
|
|
859
|
+
ui.updateDisplay(smoothedTps, avgTps, totalTokens, elapsedMs, allAgents);
|
|
860
|
+
}
|
|
861
|
+
} else if (allAgents.length > 0) {
|
|
862
|
+
ui.updateDisplay(0, 0, 0, 0, allAgents);
|
|
863
|
+
}
|
|
864
|
+
logger.debug(`[TpsMeter] Timer-triggered display for session ${sessionId}`);
|
|
865
|
+
}, MIN_TPS_ELAPSED_MS + 10);
|
|
866
|
+
pendingDisplayTimers.set(sessionId, timer);
|
|
867
|
+
}
|
|
868
|
+
function clearDisplayTimer(sessionId) {
|
|
869
|
+
const timer = pendingDisplayTimers.get(sessionId);
|
|
870
|
+
if (timer) {
|
|
871
|
+
clearTimeout(timer);
|
|
872
|
+
pendingDisplayTimers.delete(sessionId);
|
|
873
|
+
}
|
|
627
874
|
}
|
|
628
875
|
function cleanup() {
|
|
629
876
|
logger.debug("[TpsMeter] Cleaning up all trackers and UI");
|
|
630
|
-
|
|
877
|
+
for (const timer of pendingDisplayTimers.values()) {
|
|
878
|
+
clearTimeout(timer);
|
|
879
|
+
}
|
|
880
|
+
pendingDisplayTimers.clear();
|
|
881
|
+
sessionTrackers.clear();
|
|
882
|
+
partTextCache.clear();
|
|
883
|
+
messageTokenCache.clear();
|
|
631
884
|
messageRoleCache.clear();
|
|
632
|
-
|
|
633
|
-
|
|
885
|
+
sessionAgentNameCache.clear();
|
|
886
|
+
primarySessionId = null;
|
|
634
887
|
ui.clear();
|
|
635
888
|
}
|
|
636
889
|
function handleMessagePartUpdated(event) {
|
|
@@ -649,11 +902,7 @@ function TpsMeterPlugin(context) {
|
|
|
649
902
|
partTextCache.set(sessionId, sessionCache);
|
|
650
903
|
const cacheKey = `${part.messageID}:${part.id}:${part.type}`;
|
|
651
904
|
const previousText = sessionCache.get(cacheKey) || "";
|
|
652
|
-
|
|
653
|
-
delta = partText.slice(previousText.length);
|
|
654
|
-
} else {
|
|
655
|
-
delta = partText;
|
|
656
|
-
}
|
|
905
|
+
delta = partText.startsWith(previousText) ? partText.slice(previousText.length) : partText;
|
|
657
906
|
sessionCache.set(cacheKey, partText);
|
|
658
907
|
}
|
|
659
908
|
if (!delta || delta.length === 0) {
|
|
@@ -664,35 +913,52 @@ function TpsMeterPlugin(context) {
|
|
|
664
913
|
if (role !== "assistant") {
|
|
665
914
|
return;
|
|
666
915
|
}
|
|
667
|
-
const
|
|
668
|
-
const
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
}
|
|
916
|
+
const sessionState = getOrCreateSessionState(sessionId);
|
|
917
|
+
const messageTracker = getOrCreateMessageTrackerState(sessionId, part.messageID, part.id, {
|
|
918
|
+
agent: part.agent,
|
|
919
|
+
agentId: part.agentId,
|
|
920
|
+
agentType: part.agentType,
|
|
921
|
+
name: part.name
|
|
922
|
+
});
|
|
674
923
|
const now = Date.now();
|
|
675
924
|
cleanupStaleMessages(now);
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
if (firstTokenAt === undefined) {
|
|
680
|
-
firstTokenAt = now;
|
|
681
|
-
firstTokenCache.set(messageId, firstTokenAt);
|
|
925
|
+
if (!sessionState.aggregateFirstTokenAt) {
|
|
926
|
+
sessionState.aggregateFirstTokenAt = now;
|
|
927
|
+
scheduleDisplayTimer(sessionId);
|
|
682
928
|
}
|
|
929
|
+
if (!messageTracker.firstTokenAt) {
|
|
930
|
+
messageTracker.firstTokenAt = now;
|
|
931
|
+
const hasAgentMetadata = Boolean(messageTracker.agent || messageTracker.agentId || messageTracker.agentType);
|
|
932
|
+
if (!hasAgentMetadata && primarySessionId === null) {
|
|
933
|
+
primarySessionId = sessionId;
|
|
934
|
+
logger.debug(`[TpsMeter] Primary session set to: ${sessionId}`);
|
|
935
|
+
}
|
|
936
|
+
const metaLabel = messageTracker.label;
|
|
937
|
+
const metaInfo = messageTracker.agent || messageTracker.agentId || messageTracker.agentType ? `agent=${messageTracker.agent?.type ?? messageTracker.agentType ?? "?"} id=${messageTracker.agent?.id ?? messageTracker.agentId ?? "?"}` : "agent=none";
|
|
938
|
+
logger.info(`[TpsMeter][Debug] tracker initialized ${metaLabel} (${metaInfo}) session=${sessionId} message=${part.messageID} part=${part.id ?? "?"}`);
|
|
939
|
+
}
|
|
940
|
+
messageTracker.lastUpdated = now;
|
|
683
941
|
const tokenCount = tokenizer.count(delta);
|
|
684
|
-
|
|
942
|
+
sessionState.aggregate.recordTokens(tokenCount, now);
|
|
943
|
+
messageTracker.tracker.recordTokens(tokenCount, now);
|
|
685
944
|
const messageCache = messageTokenCache.get(sessionId) || new Map;
|
|
686
945
|
messageTokenCache.set(sessionId, messageCache);
|
|
687
|
-
const previousTokens = messageCache.get(
|
|
688
|
-
messageCache.set(
|
|
689
|
-
const smoothedTps =
|
|
690
|
-
const avgTps =
|
|
691
|
-
const totalTokens =
|
|
692
|
-
const elapsedMs =
|
|
693
|
-
const elapsedSinceFirstToken = Math.max(0, now -
|
|
694
|
-
if (elapsedSinceFirstToken >= MIN_TPS_ELAPSED_MS
|
|
695
|
-
|
|
946
|
+
const previousTokens = messageCache.get(part.messageID) ?? 0;
|
|
947
|
+
messageCache.set(part.messageID, previousTokens + tokenCount);
|
|
948
|
+
const smoothedTps = sessionState.aggregate.getSmoothedTPS();
|
|
949
|
+
const avgTps = sessionState.aggregate.getAverageTPS();
|
|
950
|
+
const totalTokens = sessionState.aggregate.getTotalTokens();
|
|
951
|
+
const elapsedMs = sessionState.aggregate.getElapsedMs();
|
|
952
|
+
const elapsedSinceFirstToken = sessionState.aggregateFirstTokenAt === null ? 0 : Math.max(0, now - sessionState.aggregateFirstTokenAt);
|
|
953
|
+
if (elapsedSinceFirstToken >= MIN_TPS_ELAPSED_MS) {
|
|
954
|
+
clearDisplayTimer(sessionId);
|
|
955
|
+
const allAgents = getAllActiveAgentsGlobally(now);
|
|
956
|
+
const hasPrimaryActivity = isPrimarySessionActive(now) && smoothedTps >= resolvedConfig.minVisibleTPS;
|
|
957
|
+
if (hasPrimaryActivity) {
|
|
958
|
+
ui.updateDisplay(smoothedTps, avgTps, totalTokens, elapsedMs, allAgents);
|
|
959
|
+
} else if (allAgents.length > 0) {
|
|
960
|
+
ui.updateDisplay(0, 0, 0, 0, allAgents);
|
|
961
|
+
}
|
|
696
962
|
}
|
|
697
963
|
logger.debug(`[TpsMeter] Session ${sessionId}: +${tokenCount} tokens, TPS: ${smoothedTps.toFixed(1)} (avg: ${avgTps.toFixed(1)})`);
|
|
698
964
|
}
|
|
@@ -704,25 +970,33 @@ function TpsMeterPlugin(context) {
|
|
|
704
970
|
const roleCache = messageRoleCache.get(info.sessionID) || new Map;
|
|
705
971
|
messageRoleCache.set(info.sessionID, roleCache);
|
|
706
972
|
roleCache.set(info.id, info.role);
|
|
973
|
+
if (info.agent || info.agentType) {
|
|
974
|
+
const agentName = info.agent?.name || info.agent?.type || info.agentType || info.agent?.id;
|
|
975
|
+
if (agentName && typeof agentName === "string") {
|
|
976
|
+
sessionAgentNameCache.set(info.sessionID, agentName);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
707
979
|
if (info.role === "assistant") {
|
|
708
980
|
const sessionId = info.sessionID;
|
|
709
|
-
const tracker = trackers.get(sessionId);
|
|
710
981
|
const sessionCache = partTextCache.get(sessionId);
|
|
711
982
|
const tokenCache = messageTokenCache.get(sessionId) || new Map;
|
|
712
983
|
messageTokenCache.set(sessionId, tokenCache);
|
|
713
|
-
const firstTokenCache = messageFirstTokenCache.get(sessionId) || new Map;
|
|
714
|
-
messageFirstTokenCache.set(sessionId, firstTokenCache);
|
|
715
984
|
const outputTokens = info.tokens?.output ?? 0;
|
|
716
985
|
const reasoningTokens = info.tokens?.reasoning ?? 0;
|
|
717
986
|
const reportedTokens = outputTokens + reasoningTokens;
|
|
718
987
|
const messageId = info.id;
|
|
988
|
+
const messageTracker = getOrCreateMessageTrackerState(sessionId, messageId, undefined, {
|
|
989
|
+
agent: info.agent,
|
|
990
|
+
agentId: info.agentId,
|
|
991
|
+
agentType: info.agentType
|
|
992
|
+
});
|
|
719
993
|
const previous = tokenCache.get(messageId) ?? 0;
|
|
720
994
|
const nextTokens = Math.max(previous, reportedTokens);
|
|
721
995
|
tokenCache.set(messageId, nextTokens);
|
|
722
|
-
if (info.time?.completed
|
|
996
|
+
if (info.time?.completed) {
|
|
723
997
|
const completedAt = info.time?.completed ?? Date.now();
|
|
724
998
|
const createdAt = info.time?.created ?? completedAt;
|
|
725
|
-
const firstTokenAt =
|
|
999
|
+
const firstTokenAt = messageTracker.firstTokenAt ?? createdAt;
|
|
726
1000
|
const elapsedMs = Math.max(0, completedAt - firstTokenAt);
|
|
727
1001
|
const cachedTokens = tokenCache.get(messageId) ?? 0;
|
|
728
1002
|
const totalTokens = reportedTokens > 0 ? reportedTokens : cachedTokens;
|
|
@@ -744,7 +1018,7 @@ function TpsMeterPlugin(context) {
|
|
|
744
1018
|
if (info.time?.completed) {
|
|
745
1019
|
tokenCache.delete(messageId);
|
|
746
1020
|
roleCache.delete(messageId);
|
|
747
|
-
|
|
1021
|
+
removeMessageTrackerState(sessionId, messageId);
|
|
748
1022
|
}
|
|
749
1023
|
}
|
|
750
1024
|
if (info.error) {
|
|
@@ -754,13 +1028,13 @@ function TpsMeterPlugin(context) {
|
|
|
754
1028
|
function handleSessionIdle(event) {
|
|
755
1029
|
const sessionId = event.properties.sessionID || "default";
|
|
756
1030
|
logger.debug(`[TpsMeter] Session idle: ${sessionId}`);
|
|
757
|
-
|
|
1031
|
+
clearDisplayTimer(sessionId);
|
|
1032
|
+
sessionTrackers.delete(sessionId);
|
|
758
1033
|
partTextCache.delete(sessionId);
|
|
759
1034
|
messageTokenCache.delete(sessionId);
|
|
760
1035
|
messageRoleCache.delete(sessionId);
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
if (trackers.size === 0) {
|
|
1036
|
+
sessionAgentNameCache.delete(sessionId);
|
|
1037
|
+
if (sessionTrackers.size === 0) {
|
|
764
1038
|
cleanup();
|
|
765
1039
|
}
|
|
766
1040
|
}
|
|
@@ -771,17 +1045,37 @@ function TpsMeterPlugin(context) {
|
|
|
771
1045
|
}
|
|
772
1046
|
lastCleanupTime = now;
|
|
773
1047
|
let cleanedCount = 0;
|
|
774
|
-
for (const [sessionId,
|
|
1048
|
+
for (const [sessionId, sessionState] of sessionTrackers) {
|
|
775
1049
|
const tokenCache = messageTokenCache.get(sessionId);
|
|
776
1050
|
const roleCache = messageRoleCache.get(sessionId);
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
1051
|
+
const sessionCache = partTextCache.get(sessionId);
|
|
1052
|
+
const keysToDelete = [];
|
|
1053
|
+
for (const [key, messageTracker] of sessionState.messageTrackers) {
|
|
1054
|
+
if (messageTracker.lastUpdated > 0 && now - messageTracker.lastUpdated > MAX_MESSAGE_AGE_MS) {
|
|
1055
|
+
keysToDelete.push(key);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
for (const key of keysToDelete) {
|
|
1059
|
+
const messageTracker = sessionState.messageTrackers.get(key);
|
|
1060
|
+
if (messageTracker) {
|
|
1061
|
+
sessionState.messageTrackers.delete(key);
|
|
1062
|
+
const messageId = messageTracker.messageId;
|
|
780
1063
|
tokenCache?.delete(messageId);
|
|
781
1064
|
roleCache?.delete(messageId);
|
|
1065
|
+
if (sessionCache) {
|
|
1066
|
+
for (const cacheKey of sessionCache.keys()) {
|
|
1067
|
+
if (cacheKey.startsWith(`${messageId}:`)) {
|
|
1068
|
+
sessionCache.delete(cacheKey);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
782
1072
|
cleanedCount++;
|
|
783
1073
|
}
|
|
784
1074
|
}
|
|
1075
|
+
if (sessionState.messageTrackers.size === 0) {
|
|
1076
|
+
sessionState.aggregate.reset();
|
|
1077
|
+
sessionState.aggregateFirstTokenAt = null;
|
|
1078
|
+
}
|
|
785
1079
|
}
|
|
786
1080
|
if (cleanedCount > 0) {
|
|
787
1081
|
logger.debug(`[TpsMeter] Cleaned up ${cleanedCount} stale message entries`);
|
package/dist/tracker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../src/tracker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAe,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7E;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,iBAAsB,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../src/tracker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAe,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7E;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,iBAAsB,GAAG,UAAU,CAkOzE"}
|
package/dist/types.d.ts
CHANGED
|
@@ -150,6 +150,15 @@ export interface FilePartSource {
|
|
|
150
150
|
name?: string;
|
|
151
151
|
uri?: string;
|
|
152
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Agent identity metadata for primary and sub-agents
|
|
155
|
+
*/
|
|
156
|
+
export interface AgentIdentity {
|
|
157
|
+
id?: string;
|
|
158
|
+
type?: string;
|
|
159
|
+
name?: string;
|
|
160
|
+
description?: string;
|
|
161
|
+
}
|
|
153
162
|
export interface Part {
|
|
154
163
|
id: string;
|
|
155
164
|
sessionID: string;
|
|
@@ -169,6 +178,10 @@ export interface Part {
|
|
|
169
178
|
name?: string;
|
|
170
179
|
error?: unknown;
|
|
171
180
|
auto?: boolean;
|
|
181
|
+
metadata?: Record<string, unknown>;
|
|
182
|
+
agent?: AgentIdentity;
|
|
183
|
+
agentId?: string;
|
|
184
|
+
agentType?: string;
|
|
172
185
|
}
|
|
173
186
|
/**
|
|
174
187
|
* Logger interface for plugin logging
|
|
@@ -216,6 +229,10 @@ export interface MessageEvent {
|
|
|
216
229
|
};
|
|
217
230
|
finish?: string;
|
|
218
231
|
error?: unknown;
|
|
232
|
+
agent?: AgentIdentity;
|
|
233
|
+
metadata?: Record<string, unknown>;
|
|
234
|
+
agentId?: string;
|
|
235
|
+
agentType?: string;
|
|
219
236
|
};
|
|
220
237
|
sessionID?: string;
|
|
221
238
|
};
|
|
@@ -254,6 +271,25 @@ export interface DisplayState {
|
|
|
254
271
|
totalTokens: number;
|
|
255
272
|
/** Elapsed time in milliseconds */
|
|
256
273
|
elapsedMs: number;
|
|
274
|
+
/** Optional per-agent display entries */
|
|
275
|
+
agents?: AgentDisplayState[];
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Display data for an individual agent/subagent stream
|
|
279
|
+
*/
|
|
280
|
+
export interface AgentDisplayState {
|
|
281
|
+
/** Unique identifier (message ID or agent ID) */
|
|
282
|
+
id: string;
|
|
283
|
+
/** Label describing the agent/subagent */
|
|
284
|
+
label: string;
|
|
285
|
+
/** Instantaneous TPS value */
|
|
286
|
+
instantTps: number;
|
|
287
|
+
/** Average TPS value */
|
|
288
|
+
avgTps: number;
|
|
289
|
+
/** Total tokens processed */
|
|
290
|
+
totalTokens: number;
|
|
291
|
+
/** Elapsed time since first token */
|
|
292
|
+
elapsedMs: number;
|
|
257
293
|
}
|
|
258
294
|
/**
|
|
259
295
|
* TPS Tracker options
|
|
@@ -313,7 +349,7 @@ export interface TPSTracker {
|
|
|
313
349
|
*/
|
|
314
350
|
export interface UIManager {
|
|
315
351
|
/** Updates the display with current TPS statistics */
|
|
316
|
-
updateDisplay(instantTps: number, avgTps: number, totalTokens: number, elapsedMs: number): void;
|
|
352
|
+
updateDisplay(instantTps: number, avgTps: number, totalTokens: number, elapsedMs: number, agents?: AgentDisplayState[]): void;
|
|
317
353
|
/** Displays final statistics immediately */
|
|
318
354
|
showFinalStats(totalTokens: number, avgTps: number, elapsedMs: number): void;
|
|
319
355
|
/** Clears the display and cleans up resources */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAmC,SAAS,IAAI,UAAU,EAAE,MAAM,YAAY,CAAC;AAGnH;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,GACb,UAAU,CA+VZ;AAED,eAAe,eAAe,CAAC"}
|