@dudousxd/nestjs-agent-telescope 0.5.0 → 0.6.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.js CHANGED
@@ -18,15 +18,18 @@ function col(key, label, href) {
18
18
  };
19
19
  }
20
20
  __name(col, "col");
21
+ var DEFAULT_TRACE_HREF = "#/traces/{runId}";
21
22
  function agentDashboard(opts = {}) {
23
+ const runHref = opts.runHref ?? DEFAULT_TRACE_HREF;
22
24
  return {
23
25
  id: "agent.overview",
24
26
  label: "Agent",
25
27
  panels: [],
26
28
  sections: [
27
29
  {
30
+ // Lean: the headline runs/tokens/success numbers only — Reliability below has the detail.
28
31
  title: "Overview",
29
- cols: 2,
32
+ cols: 3,
30
33
  panels: [
31
34
  {
32
35
  kind: "stat",
@@ -41,19 +44,6 @@ function agentDashboard(opts = {}) {
41
44
  data: {
42
45
  provider: "agent.tokens"
43
46
  }
44
- }
45
- ]
46
- },
47
- {
48
- title: "Reliability",
49
- cols: 4,
50
- panels: [
51
- {
52
- kind: "stat",
53
- title: "Runs",
54
- data: {
55
- provider: "agent.runs.total"
56
- }
57
47
  },
58
48
  {
59
49
  kind: "stat",
@@ -62,143 +52,12 @@ function agentDashboard(opts = {}) {
62
52
  provider: "agent.runs.successRate"
63
53
  },
64
54
  format: "percent"
65
- },
66
- {
67
- kind: "stat",
68
- title: "Failed",
69
- data: {
70
- provider: "agent.runs.failed"
71
- }
72
- },
73
- {
74
- kind: "stat",
75
- title: "Retries",
76
- data: {
77
- provider: "agent.runs.retries"
78
- }
79
- }
80
- ]
81
- },
82
- {
83
- title: "Run trends",
84
- cols: 4,
85
- panels: [
86
- {
87
- kind: "timeseries",
88
- title: "Runs & failures",
89
- data: {
90
- provider: "agent.runs.trend"
91
- },
92
- series: [
93
- "runs",
94
- "failed"
95
- ],
96
- style: "stacked"
97
- },
98
- // Two duration stats, not a `distribution` panel: RunMetrics carries only p50/p95 (no
99
- // raw samples to bucket), so a histogram here would be a permanently-empty box.
100
- {
101
- kind: "stat",
102
- title: "Duration p50",
103
- data: {
104
- provider: "agent.runs.duration",
105
- query: {
106
- metric: "p50"
107
- }
108
- },
109
- format: "duration"
110
- },
111
- {
112
- kind: "stat",
113
- title: "Duration p95",
114
- data: {
115
- provider: "agent.runs.duration",
116
- query: {
117
- metric: "p95"
118
- }
119
- },
120
- format: "duration"
121
- },
122
- {
123
- kind: "breakdown",
124
- title: "Run errors",
125
- data: {
126
- provider: "agent.runs.errors"
127
- },
128
- style: "donut"
129
- }
130
- ]
131
- },
132
- {
133
- title: "Runs",
134
- panels: [
135
- {
136
- kind: "table",
137
- title: "Runs by agent",
138
- data: {
139
- provider: "agent.runs.byAgent"
140
- },
141
- columns: [
142
- {
143
- key: "agentName",
144
- label: "Agent"
145
- },
146
- {
147
- key: "runs",
148
- label: "Runs"
149
- },
150
- {
151
- key: "failed",
152
- label: "Failed"
153
- },
154
- {
155
- key: "retries",
156
- label: "Retries"
157
- }
158
- ]
159
- },
160
- {
161
- kind: "table",
162
- title: "Recent runs",
163
- data: {
164
- provider: "agent.runs.recent"
165
- },
166
- // A deliberate SUBSET of the provider's row shape: the full 11-field row overflows the
167
- // card horizontally. Thread/actor/retries/errorCode detail lives in the standalone
168
- // agent dashboard; the provider keeps returning the full row for other consumers.
169
- columns: [
170
- {
171
- key: "startedAt",
172
- label: "Started"
173
- },
174
- col("runId", "Run", opts.runHref),
175
- {
176
- key: "agentName",
177
- label: "Agent"
178
- },
179
- {
180
- key: "status",
181
- label: "Status"
182
- },
183
- {
184
- key: "durationMs",
185
- label: "Duration (ms)"
186
- },
187
- {
188
- key: "errorMessage",
189
- label: "Error"
190
- },
191
- {
192
- key: "promptHash",
193
- label: "Prompt"
194
- }
195
- ]
196
55
  }
197
56
  ]
198
57
  },
199
58
  {
200
59
  title: "Spend",
201
- cols: 2,
60
+ cols: 4,
202
61
  panels: [
203
62
  {
204
63
  kind: "stat",
@@ -235,12 +94,7 @@ function agentDashboard(opts = {}) {
235
94
  "totalTokens"
236
95
  ],
237
96
  style: "area"
238
- }
239
- ]
240
- },
241
- {
242
- title: "Models",
243
- panels: [
97
+ },
244
98
  {
245
99
  kind: "table",
246
100
  title: "Usage & cost by model",
@@ -269,13 +123,7 @@ function agentDashboard(opts = {}) {
269
123
  label: "Cost (USD)"
270
124
  }
271
125
  ]
272
- }
273
- ]
274
- },
275
- {
276
- title: "Actors",
277
- cols: 2,
278
- panels: [
126
+ },
279
127
  {
280
128
  kind: "breakdown",
281
129
  title: "Spend share by actor",
@@ -308,13 +156,7 @@ function agentDashboard(opts = {}) {
308
156
  label: "Cost (USD)"
309
157
  }
310
158
  ]
311
- }
312
- ]
313
- },
314
- {
315
- title: "Threads",
316
- cols: 2,
317
- panels: [
159
+ },
318
160
  {
319
161
  kind: "table",
320
162
  title: "Top threads by cost",
@@ -343,12 +185,192 @@ function agentDashboard(opts = {}) {
343
185
  label: "Cost (USD)"
344
186
  }
345
187
  ]
188
+ }
189
+ ]
190
+ },
191
+ {
192
+ title: "Reliability",
193
+ cols: 3,
194
+ panels: [
195
+ {
196
+ kind: "stat",
197
+ title: "Runs",
198
+ data: {
199
+ provider: "agent.runs.total"
200
+ }
201
+ },
202
+ {
203
+ kind: "stat",
204
+ title: "Success rate",
205
+ data: {
206
+ provider: "agent.runs.successRate"
207
+ },
208
+ format: "percent"
209
+ },
210
+ {
211
+ kind: "stat",
212
+ title: "Failed",
213
+ data: {
214
+ provider: "agent.runs.failed"
215
+ }
216
+ },
217
+ {
218
+ kind: "stat",
219
+ title: "Retries",
220
+ data: {
221
+ provider: "agent.runs.retries"
222
+ }
223
+ },
224
+ {
225
+ kind: "stat",
226
+ title: "Duration p50",
227
+ data: {
228
+ provider: "agent.runs.duration",
229
+ query: {
230
+ metric: "p50"
231
+ }
232
+ },
233
+ format: "duration"
234
+ },
235
+ {
236
+ kind: "stat",
237
+ title: "Duration p95",
238
+ data: {
239
+ provider: "agent.runs.duration",
240
+ query: {
241
+ metric: "p95"
242
+ }
243
+ },
244
+ format: "duration"
245
+ },
246
+ // Two duration stats above, not a `distribution` panel: RunMetrics carries only p50/p95
247
+ // (no raw samples to bucket), so a histogram here would be a permanently-empty box.
248
+ {
249
+ kind: "timeseries",
250
+ title: "Runs & failures",
251
+ data: {
252
+ provider: "agent.runs.trend"
253
+ },
254
+ series: [
255
+ "runs",
256
+ "failed"
257
+ ],
258
+ style: "stacked"
259
+ },
260
+ {
261
+ kind: "breakdown",
262
+ title: "Run errors",
263
+ data: {
264
+ provider: "agent.runs.errors"
265
+ },
266
+ style: "donut"
267
+ },
268
+ {
269
+ kind: "table",
270
+ title: "Runs by agent",
271
+ data: {
272
+ provider: "agent.runs.byAgent"
273
+ },
274
+ columns: [
275
+ {
276
+ key: "agentName",
277
+ label: "Agent"
278
+ },
279
+ {
280
+ key: "runs",
281
+ label: "Runs"
282
+ },
283
+ {
284
+ key: "failed",
285
+ label: "Failed"
286
+ },
287
+ {
288
+ key: "retries",
289
+ label: "Retries"
290
+ }
291
+ ]
292
+ }
293
+ ]
294
+ },
295
+ {
296
+ // The paged list tables: tool calls, threads, runs — each reads the paged SPI
297
+ // (toolCallsPage/threadsPage/runsPage via `agent.*.paged`) and opts into the renderer's
298
+ // pagination (`paged: true`, telescope >= 1.18): prev/next + "Page X of Y".
299
+ title: "Activity",
300
+ cols: 3,
301
+ panels: [
302
+ {
303
+ kind: "table",
304
+ title: "Recent runs",
305
+ paged: true,
306
+ data: {
307
+ provider: "agent.runs.paged"
308
+ },
309
+ // A deliberate SUBSET of the provider's row shape: the full 11-field row overflows the
310
+ // card horizontally. Thread/actor/retries/errorCode detail lives in the standalone
311
+ // agent dashboard; the provider keeps returning the full row for other consumers.
312
+ columns: [
313
+ {
314
+ key: "startedAt",
315
+ label: "Started"
316
+ },
317
+ col("runId", "Run", runHref),
318
+ {
319
+ key: "agentName",
320
+ label: "Agent"
321
+ },
322
+ {
323
+ key: "status",
324
+ label: "Status"
325
+ },
326
+ {
327
+ key: "durationMs",
328
+ label: "Duration (ms)"
329
+ },
330
+ {
331
+ key: "errorMessage",
332
+ label: "Error"
333
+ },
334
+ {
335
+ key: "promptHash",
336
+ label: "Prompt"
337
+ }
338
+ ]
339
+ },
340
+ {
341
+ kind: "table",
342
+ title: "Recent tool calls",
343
+ paged: true,
344
+ data: {
345
+ provider: "agent.tools.paged"
346
+ },
347
+ columns: [
348
+ {
349
+ key: "createdAt",
350
+ label: "When"
351
+ },
352
+ {
353
+ key: "toolName",
354
+ label: "Tool"
355
+ },
356
+ {
357
+ key: "toolType",
358
+ label: "Type"
359
+ },
360
+ {
361
+ key: "status",
362
+ label: "Status"
363
+ },
364
+ col("runId", "Run", runHref),
365
+ col("threadId", "Thread", opts.threadHref)
366
+ ]
346
367
  },
347
368
  {
348
369
  kind: "table",
349
370
  title: "Recently active threads",
371
+ paged: true,
350
372
  data: {
351
- provider: "agent.threads.recent"
373
+ provider: "agent.threads.paged"
352
374
  },
353
375
  columns: [
354
376
  col("threadId", "Thread", opts.threadHref),
@@ -378,7 +400,7 @@ function agentDashboard(opts = {}) {
378
400
  },
379
401
  {
380
402
  title: "Approvals",
381
- cols: 3,
403
+ cols: 2,
382
404
  panels: [
383
405
  {
384
406
  kind: "stat",
@@ -407,6 +429,7 @@ function agentDashboard(opts = {}) {
407
429
  label: "Thread"
408
430
  },
409
431
  col("threadId", "Thread id", opts.threadHref),
432
+ col("runId", "Run", runHref),
410
433
  {
411
434
  key: "actorRef",
412
435
  label: "Actor"
@@ -463,32 +486,6 @@ function agentDashboard(opts = {}) {
463
486
  label: "p95 (ms)"
464
487
  }
465
488
  ]
466
- },
467
- {
468
- kind: "table",
469
- title: "Recent tool calls",
470
- data: {
471
- provider: "agent.tools.recent"
472
- },
473
- columns: [
474
- {
475
- key: "createdAt",
476
- label: "When"
477
- },
478
- {
479
- key: "toolName",
480
- label: "Tool"
481
- },
482
- {
483
- key: "toolType",
484
- label: "Type"
485
- },
486
- {
487
- key: "status",
488
- label: "Status"
489
- },
490
- col("threadId", "Thread", opts.threadHref)
491
- ]
492
489
  }
493
490
  ]
494
491
  }
@@ -589,7 +586,7 @@ function isRecord(value) {
589
586
  }
590
587
  __name(isRecord, "isRecord");
591
588
  function isGovernanceQueries(value) {
592
- return isRecord(value) && typeof value.spendByModel === "function" && typeof value.spendByActor === "function" && typeof value.spendByThread === "function" && typeof value.usageTrend === "function" && typeof value.recentToolCalls === "function" && typeof value.recentThreads === "function" && typeof value.runMetrics === "function" && typeof value.runsByAgent === "function" && typeof value.runErrors === "function" && typeof value.runTrend === "function" && typeof value.recentRuns === "function" && typeof value.pendingApprovals === "function" && typeof value.toolStats === "function";
589
+ return isRecord(value) && typeof value.spendByModel === "function" && typeof value.spendByActor === "function" && typeof value.spendByThread === "function" && typeof value.usageTrend === "function" && typeof value.recentToolCalls === "function" && typeof value.recentThreads === "function" && typeof value.runMetrics === "function" && typeof value.runsByAgent === "function" && typeof value.runErrors === "function" && typeof value.runTrend === "function" && typeof value.recentRuns === "function" && typeof value.pendingApprovals === "function" && typeof value.toolStats === "function" && typeof value.toolCallsPage === "function" && typeof value.threadsPage === "function" && typeof value.runsPage === "function";
593
590
  }
594
591
  __name(isGovernanceQueries, "isGovernanceQueries");
595
592
  function resolveGovernanceQueries(ctx) {
@@ -758,7 +755,8 @@ function toPendingApprovalTableRows(rows) {
758
755
  threadTitle: row.threadTitle,
759
756
  actorRef: row.actorRef,
760
757
  agentName: row.agentName ?? NO_VALUE,
761
- requestedAt: row.requestedAt
758
+ requestedAt: row.requestedAt,
759
+ runId: row.runId
762
760
  }));
763
761
  }
764
762
  __name(toPendingApprovalTableRows, "toPendingApprovalTableRows");
@@ -927,6 +925,41 @@ function governanceLimitProvider(name, defaultLimit, fetch, format) {
927
925
  };
928
926
  }
929
927
  __name(governanceLimitProvider, "governanceLimitProvider");
928
+ function resolvePage(query) {
929
+ const raw = query?.page;
930
+ const value = typeof raw === "number" && Number.isFinite(raw) ? raw : 1;
931
+ return Math.max(1, Math.trunc(value));
932
+ }
933
+ __name(resolvePage, "resolvePage");
934
+ function governancePagedTableProvider(name, defaultLimit, fetch, format) {
935
+ return {
936
+ name,
937
+ async resolve(query, ctx) {
938
+ const queries = resolveGovernanceQueries(ctx);
939
+ const page = resolvePage(query);
940
+ const limit = resolveLimit(query, defaultLimit);
941
+ if (!queries) {
942
+ return {
943
+ rows: [],
944
+ total: 0,
945
+ page,
946
+ limit
947
+ };
948
+ }
949
+ const resolved = await fetch(queries, {
950
+ page,
951
+ pageSize: limit
952
+ });
953
+ return {
954
+ rows: format(resolved.rows),
955
+ total: resolved.total,
956
+ page: resolved.page,
957
+ limit: resolved.pageSize
958
+ };
959
+ }
960
+ };
961
+ }
962
+ __name(governancePagedTableProvider, "governancePagedTableProvider");
930
963
  function agentRecentRunsTableProvider() {
931
964
  return governanceLimitProvider("agent.runs.recent", DEFAULT_RECENT_LIMIT, (queries, limit) => queries.recentRuns(limit), (rows) => ({
932
965
  rows: toRecentRunTableRows(rows)
@@ -945,6 +978,18 @@ function agentRecentThreadsTableProvider() {
945
978
  }));
946
979
  }
947
980
  __name(agentRecentThreadsTableProvider, "agentRecentThreadsTableProvider");
981
+ function agentToolCallsPagedTableProvider() {
982
+ return governancePagedTableProvider("agent.tools.paged", DEFAULT_RECENT_LIMIT, (queries, query) => queries.toolCallsPage(query), toRecentToolCallRows);
983
+ }
984
+ __name(agentToolCallsPagedTableProvider, "agentToolCallsPagedTableProvider");
985
+ function agentThreadsPagedTableProvider() {
986
+ return governancePagedTableProvider("agent.threads.paged", DEFAULT_RECENT_LIMIT, (queries, query) => queries.threadsPage(query), toRecentThreadTableRows);
987
+ }
988
+ __name(agentThreadsPagedTableProvider, "agentThreadsPagedTableProvider");
989
+ function agentRunsPagedTableProvider() {
990
+ return governancePagedTableProvider("agent.runs.paged", DEFAULT_RECENT_LIMIT, (queries, query) => queries.runsPage(query), toRecentRunTableRows);
991
+ }
992
+ __name(agentRunsPagedTableProvider, "agentRunsPagedTableProvider");
948
993
  var PENDING_APPROVALS_COUNT_LIMIT = 500;
949
994
  function agentPendingApprovalsCountProvider() {
950
995
  return {
@@ -1049,6 +1094,9 @@ function agentTelescopeExtension(opts = {}) {
1049
1094
  agentRecentRunsTableProvider(),
1050
1095
  agentRecentToolCallsTableProvider(),
1051
1096
  agentRecentThreadsTableProvider(),
1097
+ agentRunsPagedTableProvider(),
1098
+ agentToolCallsPagedTableProvider(),
1099
+ agentThreadsPagedTableProvider(),
1052
1100
  agentPendingApprovalsCountProvider(),
1053
1101
  agentPendingApprovalsTableProvider(),
1054
1102
  agentToolStatsTableProvider()