@dudousxd/nestjs-agent-telescope 0.8.61 → 0.9.0

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/index.cjs CHANGED
@@ -33,7 +33,9 @@ __export(index_exports, {
33
33
  agentRecentThreadsTableProvider: () => agentRecentThreadsTableProvider,
34
34
  agentRecentToolCallsTableProvider: () => agentRecentToolCallsTableProvider,
35
35
  agentRunErrorsProvider: () => agentRunErrorsProvider,
36
+ agentRunFailureCodesProvider: () => agentRunFailureCodesProvider,
36
37
  agentRunsByAgentTableProvider: () => agentRunsByAgentTableProvider,
38
+ agentRunsCancelledProvider: () => agentRunsCancelledProvider,
37
39
  agentRunsDurationProvider: () => agentRunsDurationProvider,
38
40
  agentRunsFailedProvider: () => agentRunsFailedProvider,
39
41
  agentRunsProvider: () => agentRunsProvider,
@@ -41,6 +43,8 @@ __export(index_exports, {
41
43
  agentRunsSuccessRateProvider: () => agentRunsSuccessRateProvider,
42
44
  agentRunsTotalProvider: () => agentRunsTotalProvider,
43
45
  agentRunsTrendProvider: () => agentRunsTrendProvider,
46
+ agentRunsTtftDistributionProvider: () => agentRunsTtftDistributionProvider,
47
+ agentRunsTtftProvider: () => agentRunsTtftProvider,
44
48
  agentSpendByActorProvider: () => agentSpendByActorProvider,
45
49
  agentSpendByModelProvider: () => agentSpendByModelProvider,
46
50
  agentSpendTotalProvider: () => agentSpendTotalProvider,
@@ -72,6 +76,7 @@ __export(index_exports, {
72
76
  toActorSpendRows: () => toActorSpendRows,
73
77
  toActorSpendSegments: () => toActorSpendSegments,
74
78
  toCollectionRows: () => toCollectionRows,
79
+ toFailureCodeSegments: () => toFailureCodeSegments,
75
80
  toLatencyDistribution: () => toLatencyDistribution,
76
81
  toModelSpendRows: () => toModelSpendRows,
77
82
  toModelSpendSegments: () => toModelSpendSegments,
@@ -90,6 +95,7 @@ __export(index_exports, {
90
95
  toStoreSegments: () => toStoreSegments,
91
96
  toThreadSpendRows: () => toThreadSpendRows,
92
97
  toToolStatTableRows: () => toToolStatTableRows,
98
+ toTtftDistribution: () => toTtftDistribution,
93
99
  toUsageTrendRows: () => toUsageTrendRows,
94
100
  totalCostUsd: () => totalCostUsd,
95
101
  totalTokens: () => totalTokens,
@@ -340,6 +346,43 @@ function agentDashboard(opts = {}) {
340
346
  },
341
347
  // Two duration stats above, not a `distribution` panel: RunMetrics carries only p50/p95
342
348
  // (no raw samples to bucket), so a histogram here would be a permanently-empty box.
349
+ {
350
+ kind: "stat",
351
+ title: "TTFT p50",
352
+ data: {
353
+ provider: "agent.runs.ttft",
354
+ query: {
355
+ metric: "p50"
356
+ }
357
+ },
358
+ format: "duration"
359
+ },
360
+ {
361
+ kind: "stat",
362
+ title: "TTFT p95",
363
+ data: {
364
+ provider: "agent.runs.ttft",
365
+ query: {
366
+ metric: "p95"
367
+ }
368
+ },
369
+ format: "duration"
370
+ },
371
+ {
372
+ // The one histogram in this section: `run.finished` diagnostics carry each run's own
373
+ // `ttftMs`, so the watcher-recorded entries DO have samples to bucket (over what
374
+ // Telescope's storage still holds, not the governance range).
375
+ kind: "distribution",
376
+ title: "Time to first token",
377
+ data: {
378
+ provider: "agent.runs.ttftDistribution"
379
+ },
380
+ markers: [
381
+ "p50",
382
+ "p95"
383
+ ],
384
+ format: "duration"
385
+ },
343
386
  {
344
387
  kind: "timeseries",
345
388
  title: "Runs & failures",
@@ -387,6 +430,30 @@ function agentDashboard(opts = {}) {
387
430
  }
388
431
  ]
389
432
  },
433
+ {
434
+ // Live, from the watcher-recorded diagnostics rather than the run rows: what failed and
435
+ // what was stopped, readable on a host that binds no governance read-model. A cancel is
436
+ // its own number — a user pressing Stop is the control working, not a failure.
437
+ title: "Run outcomes",
438
+ cols: 2,
439
+ panels: [
440
+ {
441
+ kind: "breakdown",
442
+ title: "Failures by code",
443
+ data: {
444
+ provider: "agent.runs.failureCodes"
445
+ },
446
+ style: "donut"
447
+ },
448
+ {
449
+ kind: "stat",
450
+ title: "Cancelled",
451
+ data: {
452
+ provider: "agent.runs.cancelled"
453
+ }
454
+ }
455
+ ]
456
+ },
390
457
  {
391
458
  // The paged list tables: tool calls, threads, runs — each reads the paged SPI
392
459
  // (toolCallsPage/threadsPage/runsPage via `agent.*.paged`) and opts into the renderer's
@@ -783,6 +850,82 @@ function ofEvent(entries, event) {
783
850
  return entries.filter((entry) => entry.content?.event === event);
784
851
  }
785
852
  __name(ofEvent, "ofEvent");
853
+ function firstToolCalls(entries) {
854
+ return ofEvent(entries, "tool-call").filter((entry) => entry.content?.replayed !== true);
855
+ }
856
+ __name(firstToolCalls, "firstToolCalls");
857
+ function percentileOf(samples, fraction) {
858
+ if (samples.length === 0) {
859
+ return null;
860
+ }
861
+ const sorted = [
862
+ ...samples
863
+ ].sort((a, b) => a - b);
864
+ const rank = Math.ceil(fraction * sorted.length);
865
+ return sorted[Math.min(Math.max(rank, 1), sorted.length) - 1] ?? null;
866
+ }
867
+ __name(percentileOf, "percentileOf");
868
+ var TTFT_EDGES = [
869
+ 250,
870
+ 500,
871
+ 1e3,
872
+ 2e3,
873
+ 4e3,
874
+ 8e3,
875
+ 16e3
876
+ ];
877
+ function ttftLabel(index) {
878
+ const upper = TTFT_EDGES[index];
879
+ if (upper === void 0) {
880
+ return `\u2265${TTFT_EDGES[TTFT_EDGES.length - 1] ?? 0}ms`;
881
+ }
882
+ return `${index === 0 ? 0 : TTFT_EDGES[index - 1] ?? 0}\u2013${upper}ms`;
883
+ }
884
+ __name(ttftLabel, "ttftLabel");
885
+ function toTtftDistribution(entries) {
886
+ const samples = [];
887
+ const counts = new Array(TTFT_EDGES.length + 1).fill(0);
888
+ for (const entry of ofEvent(entries, "run.finished")) {
889
+ const ttftMs = entry.content?.ttftMs;
890
+ if (typeof ttftMs !== "number" || entry.content?.parentRunId !== void 0) {
891
+ continue;
892
+ }
893
+ samples.push(ttftMs);
894
+ const found = TTFT_EDGES.findIndex((edge) => ttftMs < edge);
895
+ const index = found === -1 ? TTFT_EDGES.length : found;
896
+ counts[index] = (counts[index] ?? 0) + 1;
897
+ }
898
+ const buckets = counts.map((count, index) => ({
899
+ label: ttftLabel(index),
900
+ count
901
+ }));
902
+ const p50 = percentileOf(samples, 0.5);
903
+ const p95 = percentileOf(samples, 0.95);
904
+ return {
905
+ buckets,
906
+ ...p50 !== null ? {
907
+ p50
908
+ } : {},
909
+ ...p95 !== null ? {
910
+ p95
911
+ } : {}
912
+ };
913
+ }
914
+ __name(toTtftDistribution, "toTtftDistribution");
915
+ function toFailureCodeSegments(entries) {
916
+ const counts = /* @__PURE__ */ new Map();
917
+ for (const entry of ofEvent(entries, "run.failed")) {
918
+ const code = entry.content?.code ?? "unknown";
919
+ counts.set(code, (counts.get(code) ?? 0) + 1);
920
+ }
921
+ return [
922
+ ...counts.entries()
923
+ ].map(([label, value]) => ({
924
+ label,
925
+ value
926
+ })).sort((a, b) => b.value - a.value);
927
+ }
928
+ __name(toFailureCodeSegments, "toFailureCodeSegments");
786
929
  function agentRunsProvider() {
787
930
  return {
788
931
  name: "agent.runs",
@@ -812,7 +955,7 @@ function agentToolsProvider() {
812
955
  return {
813
956
  name: "agent.tools",
814
957
  async resolve(_query, ctx) {
815
- const calls = ofEvent(await fetchEntries(ctx), "tool-call").slice(-50).reverse().map((entry) => ({
958
+ const calls = firstToolCalls(await fetchEntries(ctx)).slice(-50).reverse().map((entry) => ({
816
959
  toolName: entry.content?.toolName ?? "",
817
960
  toolType: entry.content?.toolType ?? "",
818
961
  status: entry.content?.status ?? "",
@@ -829,7 +972,7 @@ function agentToolStatusProvider() {
829
972
  return {
830
973
  name: "agent.toolStatus",
831
974
  async resolve(_query, ctx) {
832
- const calls = ofEvent(await fetchEntries(ctx), "tool-call");
975
+ const calls = firstToolCalls(await fetchEntries(ctx));
833
976
  const counts = /* @__PURE__ */ new Map();
834
977
  for (const call of calls) {
835
978
  const status = call.content?.status ?? "unknown";
@@ -847,6 +990,37 @@ function agentToolStatusProvider() {
847
990
  };
848
991
  }
849
992
  __name(agentToolStatusProvider, "agentToolStatusProvider");
993
+ function agentRunsTtftDistributionProvider() {
994
+ return {
995
+ name: "agent.runs.ttftDistribution",
996
+ async resolve(_query, ctx) {
997
+ return toTtftDistribution(await fetchEntries(ctx));
998
+ }
999
+ };
1000
+ }
1001
+ __name(agentRunsTtftDistributionProvider, "agentRunsTtftDistributionProvider");
1002
+ function agentRunFailureCodesProvider() {
1003
+ return {
1004
+ name: "agent.runs.failureCodes",
1005
+ async resolve(_query, ctx) {
1006
+ return {
1007
+ segments: toFailureCodeSegments(await fetchEntries(ctx))
1008
+ };
1009
+ }
1010
+ };
1011
+ }
1012
+ __name(agentRunFailureCodesProvider, "agentRunFailureCodesProvider");
1013
+ function agentRunsCancelledProvider() {
1014
+ return {
1015
+ name: "agent.runs.cancelled",
1016
+ async resolve(_query, ctx) {
1017
+ return {
1018
+ value: ofEvent(await fetchEntries(ctx), "run.cancelled").length
1019
+ };
1020
+ }
1021
+ };
1022
+ }
1023
+ __name(agentRunsCancelledProvider, "agentRunsCancelledProvider");
850
1024
 
851
1025
  // src/agent-governance-providers.ts
852
1026
  var import_nestjs_agent_core = require("@dudousxd/nestjs-agent-core");
@@ -1004,6 +1178,9 @@ function toRecentRunTableRows(rows) {
1004
1178
  agentName: row.agentName ?? NO_VALUE,
1005
1179
  status: row.status,
1006
1180
  durationMs: row.durationMs ?? NO_VALUE,
1181
+ ttftMs: row.ttftMs ?? NO_VALUE,
1182
+ costUsd: row.costUsd ?? NO_VALUE,
1183
+ modelId: row.modelId ?? NO_VALUE,
1007
1184
  retries: row.retries,
1008
1185
  errorCode: row.errorCode ?? NO_VALUE,
1009
1186
  errorMessage: capErrorMessage(row.errorMessage) ?? NO_VALUE,
@@ -1051,7 +1228,9 @@ var EMPTY_RUN_METRICS = {
1051
1228
  successRate: 0,
1052
1229
  retries: 0,
1053
1230
  durationP50Ms: null,
1054
- durationP95Ms: null
1231
+ durationP95Ms: null,
1232
+ ttftP50Ms: null,
1233
+ ttftP95Ms: null
1055
1234
  };
1056
1235
  function governanceStatProvider(name, fetch, format) {
1057
1236
  return {
@@ -1161,6 +1340,20 @@ function agentRunsDurationProvider() {
1161
1340
  };
1162
1341
  }
1163
1342
  __name(agentRunsDurationProvider, "agentRunsDurationProvider");
1343
+ function agentRunsTtftProvider() {
1344
+ return {
1345
+ name: "agent.runs.ttft",
1346
+ async resolve(query, ctx) {
1347
+ const queries = resolveGovernanceQueries(ctx);
1348
+ const metrics = queries ? await queries.runMetrics(resolveRange(query)) : EMPTY_RUN_METRICS;
1349
+ const value = query?.metric === "p95" ? metrics.ttftP95Ms : metrics.ttftP50Ms;
1350
+ return {
1351
+ value: value ?? 0
1352
+ };
1353
+ }
1354
+ };
1355
+ }
1356
+ __name(agentRunsTtftProvider, "agentRunsTtftProvider");
1164
1357
  function agentRunsByAgentTableProvider() {
1165
1358
  return governanceStatProvider("agent.runs.byAgent", (queries, range) => queries.runsByAgent(range), (rows) => ({
1166
1359
  rows: toRunAgentTableRows(rows)
@@ -1829,6 +2022,10 @@ function agentTelescopeExtension(opts = {}) {
1829
2022
  agentRunsFailedProvider(),
1830
2023
  agentRunsRetriesProvider(),
1831
2024
  agentRunsDurationProvider(),
2025
+ agentRunsTtftProvider(),
2026
+ agentRunsTtftDistributionProvider(),
2027
+ agentRunFailureCodesProvider(),
2028
+ agentRunsCancelledProvider(),
1832
2029
  agentRunsByAgentTableProvider(),
1833
2030
  agentRunErrorsProvider(),
1834
2031
  agentRunsTrendProvider(),
@@ -1870,7 +2067,9 @@ __name(agentTelescopeExtension, "agentTelescopeExtension");
1870
2067
  agentRecentThreadsTableProvider,
1871
2068
  agentRecentToolCallsTableProvider,
1872
2069
  agentRunErrorsProvider,
2070
+ agentRunFailureCodesProvider,
1873
2071
  agentRunsByAgentTableProvider,
2072
+ agentRunsCancelledProvider,
1874
2073
  agentRunsDurationProvider,
1875
2074
  agentRunsFailedProvider,
1876
2075
  agentRunsProvider,
@@ -1878,6 +2077,8 @@ __name(agentTelescopeExtension, "agentTelescopeExtension");
1878
2077
  agentRunsSuccessRateProvider,
1879
2078
  agentRunsTotalProvider,
1880
2079
  agentRunsTrendProvider,
2080
+ agentRunsTtftDistributionProvider,
2081
+ agentRunsTtftProvider,
1881
2082
  agentSpendByActorProvider,
1882
2083
  agentSpendByModelProvider,
1883
2084
  agentSpendTotalProvider,
@@ -1909,6 +2110,7 @@ __name(agentTelescopeExtension, "agentTelescopeExtension");
1909
2110
  toActorSpendRows,
1910
2111
  toActorSpendSegments,
1911
2112
  toCollectionRows,
2113
+ toFailureCodeSegments,
1912
2114
  toLatencyDistribution,
1913
2115
  toModelSpendRows,
1914
2116
  toModelSpendSegments,
@@ -1927,6 +2129,7 @@ __name(agentTelescopeExtension, "agentTelescopeExtension");
1927
2129
  toStoreSegments,
1928
2130
  toThreadSpendRows,
1929
2131
  toToolStatTableRows,
2132
+ toTtftDistribution,
1930
2133
  toUsageTrendRows,
1931
2134
  totalCostUsd,
1932
2135
  totalTokens,