opencode-tps-meter 0.1.8 → 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,CA0yBxC;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;
@@ -741,26 +742,20 @@ function TpsMeterPlugin(context) {
741
742
  const identifier = abbreviateId(rawId);
742
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,27 +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
- const agentName = trackerState.agent?.type || trackerState.agentType || trackerState.agent?.name || sessionAgentNameCache.get(sessionId);
805
- if (agentName) {
806
- const rawId = trackerState.agentId || trackerState.agent?.id || trackerState.messageId;
807
- const identifier = abbreviateId(rawId);
808
- label = `${agentName}(${identifier})`;
809
- } else if (!label.includes("(")) {
810
- label = `agent(${label})`;
811
- }
812
- } else if (sessionId !== primarySessionId) {
813
- isSubagent = true;
814
- const agentName = sessionAgentNameCache.get(sessionId) || "bg";
815
- const shortId = abbreviateId(sessionId.replace(/^ses_/, ""));
816
- label = `${agentName}(${shortId})`;
817
- }
818
- if (!isSubagent)
794
+ const cachedAgentName = messageAgentCache.get(trackerState.messageId);
795
+ const isCrossSession = sessionId !== primarySessionId;
796
+ const isSameSessionAgent = sessionId === primarySessionId && cachedAgentName;
797
+ if (!isCrossSession && !isSameSessionAgent)
819
798
  continue;
799
+ const agentName = cachedAgentName || sessionAgentNameCache.get(sessionId) || "bg";
800
+ const identifier = abbreviateId(trackerState.messageId);
801
+ const label = `${agentName}(${identifier})`;
820
802
  entries.push({
821
803
  id: trackerKey,
822
804
  label,
@@ -841,8 +823,8 @@ function TpsMeterPlugin(context) {
841
823
  return false;
842
824
  const activityWindow = Math.max(resolvedConfig.rollingWindowMs, MIN_TPS_ELAPSED_MS * 4);
843
825
  for (const trackerState of sessionState.messageTrackers.values()) {
844
- const hasAgentMetadata = Boolean(trackerState.agent || trackerState.agentId || trackerState.agentType);
845
- if (hasAgentMetadata)
826
+ const isAgent = Boolean(messageAgentCache.get(trackerState.messageId));
827
+ if (isAgent)
846
828
  continue;
847
829
  if (trackerState.firstTokenAt && now - trackerState.lastUpdated <= activityWindow) {
848
830
  return true;
@@ -941,6 +923,7 @@ function TpsMeterPlugin(context) {
941
923
  messageTokenCache.clear();
942
924
  messageRoleCache.clear();
943
925
  sessionAgentNameCache.clear();
926
+ messageAgentCache.clear();
944
927
  primarySessionId = null;
945
928
  ui.clear();
946
929
  }
@@ -972,12 +955,7 @@ function TpsMeterPlugin(context) {
972
955
  return;
973
956
  }
974
957
  const sessionState = getOrCreateSessionState(sessionId);
975
- const messageTracker = getOrCreateMessageTrackerState(sessionId, part.messageID, part.id, {
976
- agent: part.agent,
977
- agentId: part.agentId,
978
- agentType: part.agentType,
979
- name: part.name
980
- });
958
+ const messageTracker = getOrCreateMessageTrackerState(sessionId, part.messageID);
981
959
  const now = Date.now();
982
960
  cleanupStaleMessages(now);
983
961
  if (!sessionState.aggregateFirstTokenAt) {
@@ -986,8 +964,8 @@ function TpsMeterPlugin(context) {
986
964
  }
987
965
  if (!messageTracker.firstTokenAt) {
988
966
  messageTracker.firstTokenAt = now;
989
- const hasAgentMetadata = Boolean(messageTracker.agent || messageTracker.agentId || messageTracker.agentType);
990
- if (!hasAgentMetadata && primarySessionId === null) {
967
+ const isAgent = Boolean(messageAgentCache.get(part.messageID));
968
+ if (!isAgent && primarySessionId === null) {
991
969
  primarySessionId = sessionId;
992
970
  logger.debug(`[TpsMeter] Primary session set to: ${sessionId}`);
993
971
  }
@@ -1030,12 +1008,18 @@ function TpsMeterPlugin(context) {
1030
1008
  const roleCache = messageRoleCache.get(info.sessionID) || new Map;
1031
1009
  messageRoleCache.set(info.sessionID, roleCache);
1032
1010
  roleCache.set(info.id, info.role);
1033
- if (info.agent || info.agentType) {
1034
- const agentName = info.agent?.name || info.agent?.type || info.agentType || info.agent?.id;
1035
- if (agentName && typeof agentName === "string") {
1036
- sessionAgentNameCache.set(info.sessionID, agentName);
1037
- logger.debug(`[TpsMeter] Cached agent name "${agentName}" for session ${info.sessionID}`);
1038
- }
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);
1039
1023
  }
1040
1024
  if (info.role === "assistant") {
1041
1025
  const sessionId = info.sessionID;
@@ -1046,11 +1030,7 @@ function TpsMeterPlugin(context) {
1046
1030
  const reasoningTokens = info.tokens?.reasoning ?? 0;
1047
1031
  const reportedTokens = outputTokens + reasoningTokens;
1048
1032
  const messageId = info.id;
1049
- const messageTracker = getOrCreateMessageTrackerState(sessionId, messageId, undefined, {
1050
- agent: info.agent,
1051
- agentId: info.agentId,
1052
- agentType: info.agentType
1053
- });
1033
+ const messageTracker = getOrCreateMessageTrackerState(sessionId, messageId);
1054
1034
  const previous = tokenCache.get(messageId) ?? 0;
1055
1035
  const nextTokens = Math.max(previous, reportedTokens);
1056
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;
@@ -694,26 +695,20 @@ function TpsMeterPlugin(context) {
694
695
  const identifier = abbreviateId(rawId);
695
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,27 +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
- const agentName = trackerState.agent?.type || trackerState.agentType || trackerState.agent?.name || sessionAgentNameCache.get(sessionId);
758
- if (agentName) {
759
- const rawId = trackerState.agentId || trackerState.agent?.id || trackerState.messageId;
760
- const identifier = abbreviateId(rawId);
761
- label = `${agentName}(${identifier})`;
762
- } else if (!label.includes("(")) {
763
- label = `agent(${label})`;
764
- }
765
- } else if (sessionId !== primarySessionId) {
766
- isSubagent = true;
767
- const agentName = sessionAgentNameCache.get(sessionId) || "bg";
768
- const shortId = abbreviateId(sessionId.replace(/^ses_/, ""));
769
- label = `${agentName}(${shortId})`;
770
- }
771
- if (!isSubagent)
747
+ const cachedAgentName = messageAgentCache.get(trackerState.messageId);
748
+ const isCrossSession = sessionId !== primarySessionId;
749
+ const isSameSessionAgent = sessionId === primarySessionId && cachedAgentName;
750
+ if (!isCrossSession && !isSameSessionAgent)
772
751
  continue;
752
+ const agentName = cachedAgentName || sessionAgentNameCache.get(sessionId) || "bg";
753
+ const identifier = abbreviateId(trackerState.messageId);
754
+ const label = `${agentName}(${identifier})`;
773
755
  entries.push({
774
756
  id: trackerKey,
775
757
  label,
@@ -794,8 +776,8 @@ function TpsMeterPlugin(context) {
794
776
  return false;
795
777
  const activityWindow = Math.max(resolvedConfig.rollingWindowMs, MIN_TPS_ELAPSED_MS * 4);
796
778
  for (const trackerState of sessionState.messageTrackers.values()) {
797
- const hasAgentMetadata = Boolean(trackerState.agent || trackerState.agentId || trackerState.agentType);
798
- if (hasAgentMetadata)
779
+ const isAgent = Boolean(messageAgentCache.get(trackerState.messageId));
780
+ if (isAgent)
799
781
  continue;
800
782
  if (trackerState.firstTokenAt && now - trackerState.lastUpdated <= activityWindow) {
801
783
  return true;
@@ -894,6 +876,7 @@ function TpsMeterPlugin(context) {
894
876
  messageTokenCache.clear();
895
877
  messageRoleCache.clear();
896
878
  sessionAgentNameCache.clear();
879
+ messageAgentCache.clear();
897
880
  primarySessionId = null;
898
881
  ui.clear();
899
882
  }
@@ -925,12 +908,7 @@ function TpsMeterPlugin(context) {
925
908
  return;
926
909
  }
927
910
  const sessionState = getOrCreateSessionState(sessionId);
928
- const messageTracker = getOrCreateMessageTrackerState(sessionId, part.messageID, part.id, {
929
- agent: part.agent,
930
- agentId: part.agentId,
931
- agentType: part.agentType,
932
- name: part.name
933
- });
911
+ const messageTracker = getOrCreateMessageTrackerState(sessionId, part.messageID);
934
912
  const now = Date.now();
935
913
  cleanupStaleMessages(now);
936
914
  if (!sessionState.aggregateFirstTokenAt) {
@@ -939,8 +917,8 @@ function TpsMeterPlugin(context) {
939
917
  }
940
918
  if (!messageTracker.firstTokenAt) {
941
919
  messageTracker.firstTokenAt = now;
942
- const hasAgentMetadata = Boolean(messageTracker.agent || messageTracker.agentId || messageTracker.agentType);
943
- if (!hasAgentMetadata && primarySessionId === null) {
920
+ const isAgent = Boolean(messageAgentCache.get(part.messageID));
921
+ if (!isAgent && primarySessionId === null) {
944
922
  primarySessionId = sessionId;
945
923
  logger.debug(`[TpsMeter] Primary session set to: ${sessionId}`);
946
924
  }
@@ -983,12 +961,18 @@ function TpsMeterPlugin(context) {
983
961
  const roleCache = messageRoleCache.get(info.sessionID) || new Map;
984
962
  messageRoleCache.set(info.sessionID, roleCache);
985
963
  roleCache.set(info.id, info.role);
986
- if (info.agent || info.agentType) {
987
- const agentName = info.agent?.name || info.agent?.type || info.agentType || info.agent?.id;
988
- if (agentName && typeof agentName === "string") {
989
- sessionAgentNameCache.set(info.sessionID, agentName);
990
- logger.debug(`[TpsMeter] Cached agent name "${agentName}" for session ${info.sessionID}`);
991
- }
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);
992
976
  }
993
977
  if (info.role === "assistant") {
994
978
  const sessionId = info.sessionID;
@@ -999,11 +983,7 @@ function TpsMeterPlugin(context) {
999
983
  const reasoningTokens = info.tokens?.reasoning ?? 0;
1000
984
  const reportedTokens = outputTokens + reasoningTokens;
1001
985
  const messageId = info.id;
1002
- const messageTracker = getOrCreateMessageTrackerState(sessionId, messageId, undefined, {
1003
- agent: info.agent,
1004
- agentId: info.agentId,
1005
- agentType: info.agentType
1006
- });
986
+ const messageTracker = getOrCreateMessageTrackerState(sessionId, messageId);
1007
987
  const previous = tokenCache.get(messageId) ?? 0;
1008
988
  const nextTokens = Math.max(previous, reportedTokens);
1009
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.8",
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",