@dudousxd/nestjs-agent-telescope 0.8.60 → 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 +206 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +70 -3
- package/dist/index.d.ts +70 -3
- package/dist/index.js +200 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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 =
|
|
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 =
|
|
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,
|