opencode-tps-meter 0.1.7 → 0.1.9

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.
@@ -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,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"}
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,CAuyBxC;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
@@ -708,6 +708,7 @@ function TpsMeterPlugin(context) {
708
708
  const messageTokenCache = new Map;
709
709
  const messageRoleCache = new Map;
710
710
  const sessionAgentNameCache = new Map;
711
+ const messageAgentCache = new Map;
711
712
  let primarySessionId = null;
712
713
  const pendingDisplayTimers = new Map;
713
714
  const resolvedConfig = config;
@@ -736,31 +737,25 @@ function TpsMeterPlugin(context) {
736
737
  return `${id.slice(0, 4)}…`;
737
738
  }
738
739
  function buildAgentLabel(messageId, metadata) {
739
- const typeLabel = metadata?.agent?.type?.trim() || metadata?.agentType?.trim() || metadata?.agent?.name?.trim() || metadata?.name?.trim() || "Subagent";
740
+ const typeLabel = metadata?.agent?.type?.trim() || metadata?.agentType?.trim() || metadata?.agent?.name?.trim() || metadata?.name?.trim() || null;
740
741
  const rawId = metadata?.agentId?.trim() || metadata?.agent?.id?.trim() || messageId;
741
742
  const identifier = abbreviateId(rawId);
742
- return `${typeLabel}(${identifier})`;
743
+ return typeLabel ? `${typeLabel}(${identifier})` : identifier;
743
744
  }
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
- }
745
+ function buildTrackerKey(sessionId, messageId) {
752
746
  return `${sessionId}:${messageId}`;
753
747
  }
754
- function getOrCreateMessageTrackerState(sessionId, messageId, partId, metadata) {
748
+ function getOrCreateMessageTrackerState(sessionId, messageId, metadata) {
755
749
  const sessionState = getOrCreateSessionState(sessionId);
756
- const key = buildTrackerKey(sessionId, messageId, partId, metadata);
750
+ const key = buildTrackerKey(sessionId, messageId);
757
751
  let trackerState = sessionState.messageTrackers.get(key);
758
- const nextLabel = buildAgentLabel(messageId, metadata);
752
+ const cachedAgentName = messageAgentCache.get(messageId);
753
+ const agentName = cachedAgentName || metadata?.agent?.type || metadata?.agentType || metadata?.agent?.name || null;
754
+ const nextLabel = agentName ? `${agentName}(${abbreviateId(messageId)})` : abbreviateId(messageId);
759
755
  if (!trackerState) {
760
756
  trackerState = {
761
757
  key,
762
758
  messageId,
763
- partId,
764
759
  tracker: createTracker({
765
760
  sessionId: key,
766
761
  rollingWindowMs: resolvedConfig.rollingWindowMs
@@ -773,7 +768,7 @@ function TpsMeterPlugin(context) {
773
768
  agentType: metadata?.agentType
774
769
  };
775
770
  sessionState.messageTrackers.set(key, trackerState);
776
- } else if (trackerState.label !== nextLabel) {
771
+ } else if (trackerState.label !== nextLabel && nextLabel) {
777
772
  trackerState.label = nextLabel;
778
773
  }
779
774
  if (metadata?.agent) {
@@ -796,19 +791,14 @@ function TpsMeterPlugin(context) {
796
791
  continue;
797
792
  if (now - trackerState.lastUpdated > activityWindow)
798
793
  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)
794
+ const cachedAgentName = messageAgentCache.get(trackerState.messageId);
795
+ const isCrossSession = sessionId !== primarySessionId;
796
+ const isSameSessionAgent = sessionId === primarySessionId && cachedAgentName;
797
+ if (!isCrossSession && !isSameSessionAgent)
811
798
  continue;
799
+ const agentName = cachedAgentName || sessionAgentNameCache.get(sessionId) || "bg";
800
+ const identifier = abbreviateId(trackerState.messageId);
801
+ const label = `${agentName}(${identifier})`;
812
802
  entries.push({
813
803
  id: trackerKey,
814
804
  label,
@@ -820,6 +810,9 @@ function TpsMeterPlugin(context) {
820
810
  }
821
811
  }
822
812
  entries.sort((a, b) => b.instantTps - a.instantTps);
813
+ if (entries.length > 0) {
814
+ logger.debug(`[TpsMeter] getAllActiveAgentsGlobally found ${entries.length} agents: ${entries.map((e) => `${e.label}@${e.instantTps.toFixed(1)}`).join(", ")}`);
815
+ }
823
816
  return entries;
824
817
  }
825
818
  function isPrimarySessionActive(now) {
@@ -830,8 +823,8 @@ function TpsMeterPlugin(context) {
830
823
  return false;
831
824
  const activityWindow = Math.max(resolvedConfig.rollingWindowMs, MIN_TPS_ELAPSED_MS * 4);
832
825
  for (const trackerState of sessionState.messageTrackers.values()) {
833
- const hasAgentMetadata = Boolean(trackerState.agent || trackerState.agentId || trackerState.agentType);
834
- if (hasAgentMetadata)
826
+ const isAgent = Boolean(messageAgentCache.get(trackerState.messageId));
827
+ if (isAgent)
835
828
  continue;
836
829
  if (trackerState.firstTokenAt && now - trackerState.lastUpdated <= activityWindow) {
837
830
  return true;
@@ -930,6 +923,7 @@ function TpsMeterPlugin(context) {
930
923
  messageTokenCache.clear();
931
924
  messageRoleCache.clear();
932
925
  sessionAgentNameCache.clear();
926
+ messageAgentCache.clear();
933
927
  primarySessionId = null;
934
928
  ui.clear();
935
929
  }
@@ -961,12 +955,7 @@ function TpsMeterPlugin(context) {
961
955
  return;
962
956
  }
963
957
  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
- });
958
+ const messageTracker = getOrCreateMessageTrackerState(sessionId, part.messageID);
970
959
  const now = Date.now();
971
960
  cleanupStaleMessages(now);
972
961
  if (!sessionState.aggregateFirstTokenAt) {
@@ -975,14 +964,16 @@ function TpsMeterPlugin(context) {
975
964
  }
976
965
  if (!messageTracker.firstTokenAt) {
977
966
  messageTracker.firstTokenAt = now;
978
- const hasAgentMetadata = Boolean(messageTracker.agent || messageTracker.agentId || messageTracker.agentType);
979
- if (!hasAgentMetadata && primarySessionId === null) {
967
+ const isAgent = Boolean(messageAgentCache.get(part.messageID));
968
+ if (!isAgent && primarySessionId === null) {
980
969
  primarySessionId = sessionId;
981
970
  logger.debug(`[TpsMeter] Primary session set to: ${sessionId}`);
982
971
  }
983
972
  const metaLabel = messageTracker.label;
984
973
  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 ?? "?"}`);
974
+ const trackerKey = messageTracker.key;
975
+ const isBg = sessionId !== primarySessionId;
976
+ logger.info(`[TpsMeter][Debug] tracker initialized ${metaLabel} (${metaInfo}) session=${sessionId} primary=${primarySessionId} isBg=${isBg} key=${trackerKey} message=${part.messageID} part=${part.id ?? "?"}`);
986
977
  }
987
978
  messageTracker.lastUpdated = now;
988
979
  const tokenCount = tokenizer.count(delta);
@@ -1017,11 +1008,18 @@ function TpsMeterPlugin(context) {
1017
1008
  const roleCache = messageRoleCache.get(info.sessionID) || new Map;
1018
1009
  messageRoleCache.set(info.sessionID, roleCache);
1019
1010
  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
- }
1011
+ let agentName;
1012
+ if (typeof info.agent === "string") {
1013
+ agentName = info.agent;
1014
+ } else if (info.agent) {
1015
+ agentName = info.agent.type || info.agent.name || info.agent.id;
1016
+ } else if (info.agentType) {
1017
+ agentName = info.agentType;
1018
+ }
1019
+ if (agentName) {
1020
+ messageAgentCache.set(info.id, agentName);
1021
+ logger.debug(`[TpsMeter] Cached agent name "${agentName}" for message ${info.id}`);
1022
+ sessionAgentNameCache.set(info.sessionID, agentName);
1025
1023
  }
1026
1024
  if (info.role === "assistant") {
1027
1025
  const sessionId = info.sessionID;
@@ -1032,11 +1030,7 @@ function TpsMeterPlugin(context) {
1032
1030
  const reasoningTokens = info.tokens?.reasoning ?? 0;
1033
1031
  const reportedTokens = outputTokens + reasoningTokens;
1034
1032
  const messageId = info.id;
1035
- const messageTracker = getOrCreateMessageTrackerState(sessionId, messageId, undefined, {
1036
- agent: info.agent,
1037
- agentId: info.agentId,
1038
- agentType: info.agentType
1039
- });
1033
+ const messageTracker = getOrCreateMessageTrackerState(sessionId, messageId);
1040
1034
  const previous = tokenCache.get(messageId) ?? 0;
1041
1035
  const nextTokens = Math.max(previous, reportedTokens);
1042
1036
  tokenCache.set(messageId, nextTokens);
package/dist/index.mjs CHANGED
@@ -661,6 +661,7 @@ function TpsMeterPlugin(context) {
661
661
  const messageTokenCache = new Map;
662
662
  const messageRoleCache = new Map;
663
663
  const sessionAgentNameCache = new Map;
664
+ const messageAgentCache = new Map;
664
665
  let primarySessionId = null;
665
666
  const pendingDisplayTimers = new Map;
666
667
  const resolvedConfig = config;
@@ -689,31 +690,25 @@ function TpsMeterPlugin(context) {
689
690
  return `${id.slice(0, 4)}…`;
690
691
  }
691
692
  function buildAgentLabel(messageId, metadata) {
692
- const typeLabel = metadata?.agent?.type?.trim() || metadata?.agentType?.trim() || metadata?.agent?.name?.trim() || metadata?.name?.trim() || "Subagent";
693
+ const typeLabel = metadata?.agent?.type?.trim() || metadata?.agentType?.trim() || metadata?.agent?.name?.trim() || metadata?.name?.trim() || null;
693
694
  const rawId = metadata?.agentId?.trim() || metadata?.agent?.id?.trim() || messageId;
694
695
  const identifier = abbreviateId(rawId);
695
- return `${typeLabel}(${identifier})`;
696
+ return typeLabel ? `${typeLabel}(${identifier})` : identifier;
696
697
  }
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
- }
698
+ function buildTrackerKey(sessionId, messageId) {
705
699
  return `${sessionId}:${messageId}`;
706
700
  }
707
- function getOrCreateMessageTrackerState(sessionId, messageId, partId, metadata) {
701
+ function getOrCreateMessageTrackerState(sessionId, messageId, metadata) {
708
702
  const sessionState = getOrCreateSessionState(sessionId);
709
- const key = buildTrackerKey(sessionId, messageId, partId, metadata);
703
+ const key = buildTrackerKey(sessionId, messageId);
710
704
  let trackerState = sessionState.messageTrackers.get(key);
711
- const nextLabel = buildAgentLabel(messageId, metadata);
705
+ const cachedAgentName = messageAgentCache.get(messageId);
706
+ const agentName = cachedAgentName || metadata?.agent?.type || metadata?.agentType || metadata?.agent?.name || null;
707
+ const nextLabel = agentName ? `${agentName}(${abbreviateId(messageId)})` : abbreviateId(messageId);
712
708
  if (!trackerState) {
713
709
  trackerState = {
714
710
  key,
715
711
  messageId,
716
- partId,
717
712
  tracker: createTracker({
718
713
  sessionId: key,
719
714
  rollingWindowMs: resolvedConfig.rollingWindowMs
@@ -726,7 +721,7 @@ function TpsMeterPlugin(context) {
726
721
  agentType: metadata?.agentType
727
722
  };
728
723
  sessionState.messageTrackers.set(key, trackerState);
729
- } else if (trackerState.label !== nextLabel) {
724
+ } else if (trackerState.label !== nextLabel && nextLabel) {
730
725
  trackerState.label = nextLabel;
731
726
  }
732
727
  if (metadata?.agent) {
@@ -749,19 +744,14 @@ function TpsMeterPlugin(context) {
749
744
  continue;
750
745
  if (now - trackerState.lastUpdated > activityWindow)
751
746
  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)
747
+ const cachedAgentName = messageAgentCache.get(trackerState.messageId);
748
+ const isCrossSession = sessionId !== primarySessionId;
749
+ const isSameSessionAgent = sessionId === primarySessionId && cachedAgentName;
750
+ if (!isCrossSession && !isSameSessionAgent)
764
751
  continue;
752
+ const agentName = cachedAgentName || sessionAgentNameCache.get(sessionId) || "bg";
753
+ const identifier = abbreviateId(trackerState.messageId);
754
+ const label = `${agentName}(${identifier})`;
765
755
  entries.push({
766
756
  id: trackerKey,
767
757
  label,
@@ -773,6 +763,9 @@ function TpsMeterPlugin(context) {
773
763
  }
774
764
  }
775
765
  entries.sort((a, b) => b.instantTps - a.instantTps);
766
+ if (entries.length > 0) {
767
+ logger.debug(`[TpsMeter] getAllActiveAgentsGlobally found ${entries.length} agents: ${entries.map((e) => `${e.label}@${e.instantTps.toFixed(1)}`).join(", ")}`);
768
+ }
776
769
  return entries;
777
770
  }
778
771
  function isPrimarySessionActive(now) {
@@ -783,8 +776,8 @@ function TpsMeterPlugin(context) {
783
776
  return false;
784
777
  const activityWindow = Math.max(resolvedConfig.rollingWindowMs, MIN_TPS_ELAPSED_MS * 4);
785
778
  for (const trackerState of sessionState.messageTrackers.values()) {
786
- const hasAgentMetadata = Boolean(trackerState.agent || trackerState.agentId || trackerState.agentType);
787
- if (hasAgentMetadata)
779
+ const isAgent = Boolean(messageAgentCache.get(trackerState.messageId));
780
+ if (isAgent)
788
781
  continue;
789
782
  if (trackerState.firstTokenAt && now - trackerState.lastUpdated <= activityWindow) {
790
783
  return true;
@@ -883,6 +876,7 @@ function TpsMeterPlugin(context) {
883
876
  messageTokenCache.clear();
884
877
  messageRoleCache.clear();
885
878
  sessionAgentNameCache.clear();
879
+ messageAgentCache.clear();
886
880
  primarySessionId = null;
887
881
  ui.clear();
888
882
  }
@@ -914,12 +908,7 @@ function TpsMeterPlugin(context) {
914
908
  return;
915
909
  }
916
910
  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
- });
911
+ const messageTracker = getOrCreateMessageTrackerState(sessionId, part.messageID);
923
912
  const now = Date.now();
924
913
  cleanupStaleMessages(now);
925
914
  if (!sessionState.aggregateFirstTokenAt) {
@@ -928,14 +917,16 @@ function TpsMeterPlugin(context) {
928
917
  }
929
918
  if (!messageTracker.firstTokenAt) {
930
919
  messageTracker.firstTokenAt = now;
931
- const hasAgentMetadata = Boolean(messageTracker.agent || messageTracker.agentId || messageTracker.agentType);
932
- if (!hasAgentMetadata && primarySessionId === null) {
920
+ const isAgent = Boolean(messageAgentCache.get(part.messageID));
921
+ if (!isAgent && primarySessionId === null) {
933
922
  primarySessionId = sessionId;
934
923
  logger.debug(`[TpsMeter] Primary session set to: ${sessionId}`);
935
924
  }
936
925
  const metaLabel = messageTracker.label;
937
926
  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 ?? "?"}`);
927
+ const trackerKey = messageTracker.key;
928
+ const isBg = sessionId !== primarySessionId;
929
+ logger.info(`[TpsMeter][Debug] tracker initialized ${metaLabel} (${metaInfo}) session=${sessionId} primary=${primarySessionId} isBg=${isBg} key=${trackerKey} message=${part.messageID} part=${part.id ?? "?"}`);
939
930
  }
940
931
  messageTracker.lastUpdated = now;
941
932
  const tokenCount = tokenizer.count(delta);
@@ -970,11 +961,18 @@ function TpsMeterPlugin(context) {
970
961
  const roleCache = messageRoleCache.get(info.sessionID) || new Map;
971
962
  messageRoleCache.set(info.sessionID, roleCache);
972
963
  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
- }
964
+ let agentName;
965
+ if (typeof info.agent === "string") {
966
+ agentName = info.agent;
967
+ } else if (info.agent) {
968
+ agentName = info.agent.type || info.agent.name || info.agent.id;
969
+ } else if (info.agentType) {
970
+ agentName = info.agentType;
971
+ }
972
+ if (agentName) {
973
+ messageAgentCache.set(info.id, agentName);
974
+ logger.debug(`[TpsMeter] Cached agent name "${agentName}" for message ${info.id}`);
975
+ sessionAgentNameCache.set(info.sessionID, agentName);
978
976
  }
979
977
  if (info.role === "assistant") {
980
978
  const sessionId = info.sessionID;
@@ -985,11 +983,7 @@ function TpsMeterPlugin(context) {
985
983
  const reasoningTokens = info.tokens?.reasoning ?? 0;
986
984
  const reportedTokens = outputTokens + reasoningTokens;
987
985
  const messageId = info.id;
988
- const messageTracker = getOrCreateMessageTrackerState(sessionId, messageId, undefined, {
989
- agent: info.agent,
990
- agentId: info.agentId,
991
- agentType: info.agentType
992
- });
986
+ const messageTracker = getOrCreateMessageTrackerState(sessionId, messageId);
993
987
  const previous = tokenCache.get(messageId) ?? 0;
994
988
  const nextTokens = Math.max(previous, reportedTokens);
995
989
  tokenCache.set(messageId, nextTokens);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-tps-meter",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Live tokens-per-second meter for OpenCode",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",