@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.cjs CHANGED
@@ -90,15 +90,18 @@ function col(key, label, href) {
90
90
  };
91
91
  }
92
92
  __name(col, "col");
93
+ var DEFAULT_TRACE_HREF = "#/traces/{runId}";
93
94
  function agentDashboard(opts = {}) {
95
+ const runHref = opts.runHref ?? DEFAULT_TRACE_HREF;
94
96
  return {
95
97
  id: "agent.overview",
96
98
  label: "Agent",
97
99
  panels: [],
98
100
  sections: [
99
101
  {
102
+ // Lean: the headline runs/tokens/success numbers only — Reliability below has the detail.
100
103
  title: "Overview",
101
- cols: 2,
104
+ cols: 3,
102
105
  panels: [
103
106
  {
104
107
  kind: "stat",
@@ -113,19 +116,6 @@ function agentDashboard(opts = {}) {
113
116
  data: {
114
117
  provider: "agent.tokens"
115
118
  }
116
- }
117
- ]
118
- },
119
- {
120
- title: "Reliability",
121
- cols: 4,
122
- panels: [
123
- {
124
- kind: "stat",
125
- title: "Runs",
126
- data: {
127
- provider: "agent.runs.total"
128
- }
129
119
  },
130
120
  {
131
121
  kind: "stat",
@@ -134,143 +124,12 @@ function agentDashboard(opts = {}) {
134
124
  provider: "agent.runs.successRate"
135
125
  },
136
126
  format: "percent"
137
- },
138
- {
139
- kind: "stat",
140
- title: "Failed",
141
- data: {
142
- provider: "agent.runs.failed"
143
- }
144
- },
145
- {
146
- kind: "stat",
147
- title: "Retries",
148
- data: {
149
- provider: "agent.runs.retries"
150
- }
151
- }
152
- ]
153
- },
154
- {
155
- title: "Run trends",
156
- cols: 4,
157
- panels: [
158
- {
159
- kind: "timeseries",
160
- title: "Runs & failures",
161
- data: {
162
- provider: "agent.runs.trend"
163
- },
164
- series: [
165
- "runs",
166
- "failed"
167
- ],
168
- style: "stacked"
169
- },
170
- // Two duration stats, not a `distribution` panel: RunMetrics carries only p50/p95 (no
171
- // raw samples to bucket), so a histogram here would be a permanently-empty box.
172
- {
173
- kind: "stat",
174
- title: "Duration p50",
175
- data: {
176
- provider: "agent.runs.duration",
177
- query: {
178
- metric: "p50"
179
- }
180
- },
181
- format: "duration"
182
- },
183
- {
184
- kind: "stat",
185
- title: "Duration p95",
186
- data: {
187
- provider: "agent.runs.duration",
188
- query: {
189
- metric: "p95"
190
- }
191
- },
192
- format: "duration"
193
- },
194
- {
195
- kind: "breakdown",
196
- title: "Run errors",
197
- data: {
198
- provider: "agent.runs.errors"
199
- },
200
- style: "donut"
201
- }
202
- ]
203
- },
204
- {
205
- title: "Runs",
206
- panels: [
207
- {
208
- kind: "table",
209
- title: "Runs by agent",
210
- data: {
211
- provider: "agent.runs.byAgent"
212
- },
213
- columns: [
214
- {
215
- key: "agentName",
216
- label: "Agent"
217
- },
218
- {
219
- key: "runs",
220
- label: "Runs"
221
- },
222
- {
223
- key: "failed",
224
- label: "Failed"
225
- },
226
- {
227
- key: "retries",
228
- label: "Retries"
229
- }
230
- ]
231
- },
232
- {
233
- kind: "table",
234
- title: "Recent runs",
235
- data: {
236
- provider: "agent.runs.recent"
237
- },
238
- // A deliberate SUBSET of the provider's row shape: the full 11-field row overflows the
239
- // card horizontally. Thread/actor/retries/errorCode detail lives in the standalone
240
- // agent dashboard; the provider keeps returning the full row for other consumers.
241
- columns: [
242
- {
243
- key: "startedAt",
244
- label: "Started"
245
- },
246
- col("runId", "Run", opts.runHref),
247
- {
248
- key: "agentName",
249
- label: "Agent"
250
- },
251
- {
252
- key: "status",
253
- label: "Status"
254
- },
255
- {
256
- key: "durationMs",
257
- label: "Duration (ms)"
258
- },
259
- {
260
- key: "errorMessage",
261
- label: "Error"
262
- },
263
- {
264
- key: "promptHash",
265
- label: "Prompt"
266
- }
267
- ]
268
127
  }
269
128
  ]
270
129
  },
271
130
  {
272
131
  title: "Spend",
273
- cols: 2,
132
+ cols: 4,
274
133
  panels: [
275
134
  {
276
135
  kind: "stat",
@@ -307,12 +166,7 @@ function agentDashboard(opts = {}) {
307
166
  "totalTokens"
308
167
  ],
309
168
  style: "area"
310
- }
311
- ]
312
- },
313
- {
314
- title: "Models",
315
- panels: [
169
+ },
316
170
  {
317
171
  kind: "table",
318
172
  title: "Usage & cost by model",
@@ -341,13 +195,7 @@ function agentDashboard(opts = {}) {
341
195
  label: "Cost (USD)"
342
196
  }
343
197
  ]
344
- }
345
- ]
346
- },
347
- {
348
- title: "Actors",
349
- cols: 2,
350
- panels: [
198
+ },
351
199
  {
352
200
  kind: "breakdown",
353
201
  title: "Spend share by actor",
@@ -380,13 +228,7 @@ function agentDashboard(opts = {}) {
380
228
  label: "Cost (USD)"
381
229
  }
382
230
  ]
383
- }
384
- ]
385
- },
386
- {
387
- title: "Threads",
388
- cols: 2,
389
- panels: [
231
+ },
390
232
  {
391
233
  kind: "table",
392
234
  title: "Top threads by cost",
@@ -415,12 +257,192 @@ function agentDashboard(opts = {}) {
415
257
  label: "Cost (USD)"
416
258
  }
417
259
  ]
260
+ }
261
+ ]
262
+ },
263
+ {
264
+ title: "Reliability",
265
+ cols: 3,
266
+ panels: [
267
+ {
268
+ kind: "stat",
269
+ title: "Runs",
270
+ data: {
271
+ provider: "agent.runs.total"
272
+ }
273
+ },
274
+ {
275
+ kind: "stat",
276
+ title: "Success rate",
277
+ data: {
278
+ provider: "agent.runs.successRate"
279
+ },
280
+ format: "percent"
281
+ },
282
+ {
283
+ kind: "stat",
284
+ title: "Failed",
285
+ data: {
286
+ provider: "agent.runs.failed"
287
+ }
288
+ },
289
+ {
290
+ kind: "stat",
291
+ title: "Retries",
292
+ data: {
293
+ provider: "agent.runs.retries"
294
+ }
295
+ },
296
+ {
297
+ kind: "stat",
298
+ title: "Duration p50",
299
+ data: {
300
+ provider: "agent.runs.duration",
301
+ query: {
302
+ metric: "p50"
303
+ }
304
+ },
305
+ format: "duration"
306
+ },
307
+ {
308
+ kind: "stat",
309
+ title: "Duration p95",
310
+ data: {
311
+ provider: "agent.runs.duration",
312
+ query: {
313
+ metric: "p95"
314
+ }
315
+ },
316
+ format: "duration"
317
+ },
318
+ // Two duration stats above, not a `distribution` panel: RunMetrics carries only p50/p95
319
+ // (no raw samples to bucket), so a histogram here would be a permanently-empty box.
320
+ {
321
+ kind: "timeseries",
322
+ title: "Runs & failures",
323
+ data: {
324
+ provider: "agent.runs.trend"
325
+ },
326
+ series: [
327
+ "runs",
328
+ "failed"
329
+ ],
330
+ style: "stacked"
331
+ },
332
+ {
333
+ kind: "breakdown",
334
+ title: "Run errors",
335
+ data: {
336
+ provider: "agent.runs.errors"
337
+ },
338
+ style: "donut"
339
+ },
340
+ {
341
+ kind: "table",
342
+ title: "Runs by agent",
343
+ data: {
344
+ provider: "agent.runs.byAgent"
345
+ },
346
+ columns: [
347
+ {
348
+ key: "agentName",
349
+ label: "Agent"
350
+ },
351
+ {
352
+ key: "runs",
353
+ label: "Runs"
354
+ },
355
+ {
356
+ key: "failed",
357
+ label: "Failed"
358
+ },
359
+ {
360
+ key: "retries",
361
+ label: "Retries"
362
+ }
363
+ ]
364
+ }
365
+ ]
366
+ },
367
+ {
368
+ // The paged list tables: tool calls, threads, runs — each reads the paged SPI
369
+ // (toolCallsPage/threadsPage/runsPage via `agent.*.paged`) and opts into the renderer's
370
+ // pagination (`paged: true`, telescope >= 1.18): prev/next + "Page X of Y".
371
+ title: "Activity",
372
+ cols: 3,
373
+ panels: [
374
+ {
375
+ kind: "table",
376
+ title: "Recent runs",
377
+ paged: true,
378
+ data: {
379
+ provider: "agent.runs.paged"
380
+ },
381
+ // A deliberate SUBSET of the provider's row shape: the full 11-field row overflows the
382
+ // card horizontally. Thread/actor/retries/errorCode detail lives in the standalone
383
+ // agent dashboard; the provider keeps returning the full row for other consumers.
384
+ columns: [
385
+ {
386
+ key: "startedAt",
387
+ label: "Started"
388
+ },
389
+ col("runId", "Run", runHref),
390
+ {
391
+ key: "agentName",
392
+ label: "Agent"
393
+ },
394
+ {
395
+ key: "status",
396
+ label: "Status"
397
+ },
398
+ {
399
+ key: "durationMs",
400
+ label: "Duration (ms)"
401
+ },
402
+ {
403
+ key: "errorMessage",
404
+ label: "Error"
405
+ },
406
+ {
407
+ key: "promptHash",
408
+ label: "Prompt"
409
+ }
410
+ ]
411
+ },
412
+ {
413
+ kind: "table",
414
+ title: "Recent tool calls",
415
+ paged: true,
416
+ data: {
417
+ provider: "agent.tools.paged"
418
+ },
419
+ columns: [
420
+ {
421
+ key: "createdAt",
422
+ label: "When"
423
+ },
424
+ {
425
+ key: "toolName",
426
+ label: "Tool"
427
+ },
428
+ {
429
+ key: "toolType",
430
+ label: "Type"
431
+ },
432
+ {
433
+ key: "status",
434
+ label: "Status"
435
+ },
436
+ col("runId", "Run", runHref),
437
+ col("threadId", "Thread", opts.threadHref)
438
+ ]
418
439
  },
419
440
  {
420
441
  kind: "table",
421
442
  title: "Recently active threads",
443
+ paged: true,
422
444
  data: {
423
- provider: "agent.threads.recent"
445
+ provider: "agent.threads.paged"
424
446
  },
425
447
  columns: [
426
448
  col("threadId", "Thread", opts.threadHref),
@@ -450,7 +472,7 @@ function agentDashboard(opts = {}) {
450
472
  },
451
473
  {
452
474
  title: "Approvals",
453
- cols: 3,
475
+ cols: 2,
454
476
  panels: [
455
477
  {
456
478
  kind: "stat",
@@ -479,6 +501,7 @@ function agentDashboard(opts = {}) {
479
501
  label: "Thread"
480
502
  },
481
503
  col("threadId", "Thread id", opts.threadHref),
504
+ col("runId", "Run", runHref),
482
505
  {
483
506
  key: "actorRef",
484
507
  label: "Actor"
@@ -535,32 +558,6 @@ function agentDashboard(opts = {}) {
535
558
  label: "p95 (ms)"
536
559
  }
537
560
  ]
538
- },
539
- {
540
- kind: "table",
541
- title: "Recent tool calls",
542
- data: {
543
- provider: "agent.tools.recent"
544
- },
545
- columns: [
546
- {
547
- key: "createdAt",
548
- label: "When"
549
- },
550
- {
551
- key: "toolName",
552
- label: "Tool"
553
- },
554
- {
555
- key: "toolType",
556
- label: "Type"
557
- },
558
- {
559
- key: "status",
560
- label: "Status"
561
- },
562
- col("threadId", "Thread", opts.threadHref)
563
- ]
564
561
  }
565
562
  ]
566
563
  }
@@ -661,7 +658,7 @@ function isRecord(value) {
661
658
  }
662
659
  __name(isRecord, "isRecord");
663
660
  function isGovernanceQueries(value) {
664
- 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";
661
+ 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";
665
662
  }
666
663
  __name(isGovernanceQueries, "isGovernanceQueries");
667
664
  function resolveGovernanceQueries(ctx) {
@@ -830,7 +827,8 @@ function toPendingApprovalTableRows(rows) {
830
827
  threadTitle: row.threadTitle,
831
828
  actorRef: row.actorRef,
832
829
  agentName: row.agentName ?? NO_VALUE,
833
- requestedAt: row.requestedAt
830
+ requestedAt: row.requestedAt,
831
+ runId: row.runId
834
832
  }));
835
833
  }
836
834
  __name(toPendingApprovalTableRows, "toPendingApprovalTableRows");
@@ -999,6 +997,41 @@ function governanceLimitProvider(name, defaultLimit, fetch, format) {
999
997
  };
1000
998
  }
1001
999
  __name(governanceLimitProvider, "governanceLimitProvider");
1000
+ function resolvePage(query) {
1001
+ const raw = query?.page;
1002
+ const value = typeof raw === "number" && Number.isFinite(raw) ? raw : 1;
1003
+ return Math.max(1, Math.trunc(value));
1004
+ }
1005
+ __name(resolvePage, "resolvePage");
1006
+ function governancePagedTableProvider(name, defaultLimit, fetch, format) {
1007
+ return {
1008
+ name,
1009
+ async resolve(query, ctx) {
1010
+ const queries = resolveGovernanceQueries(ctx);
1011
+ const page = resolvePage(query);
1012
+ const limit = resolveLimit(query, defaultLimit);
1013
+ if (!queries) {
1014
+ return {
1015
+ rows: [],
1016
+ total: 0,
1017
+ page,
1018
+ limit
1019
+ };
1020
+ }
1021
+ const resolved = await fetch(queries, {
1022
+ page,
1023
+ pageSize: limit
1024
+ });
1025
+ return {
1026
+ rows: format(resolved.rows),
1027
+ total: resolved.total,
1028
+ page: resolved.page,
1029
+ limit: resolved.pageSize
1030
+ };
1031
+ }
1032
+ };
1033
+ }
1034
+ __name(governancePagedTableProvider, "governancePagedTableProvider");
1002
1035
  function agentRecentRunsTableProvider() {
1003
1036
  return governanceLimitProvider("agent.runs.recent", DEFAULT_RECENT_LIMIT, (queries, limit) => queries.recentRuns(limit), (rows) => ({
1004
1037
  rows: toRecentRunTableRows(rows)
@@ -1017,6 +1050,18 @@ function agentRecentThreadsTableProvider() {
1017
1050
  }));
1018
1051
  }
1019
1052
  __name(agentRecentThreadsTableProvider, "agentRecentThreadsTableProvider");
1053
+ function agentToolCallsPagedTableProvider() {
1054
+ return governancePagedTableProvider("agent.tools.paged", DEFAULT_RECENT_LIMIT, (queries, query) => queries.toolCallsPage(query), toRecentToolCallRows);
1055
+ }
1056
+ __name(agentToolCallsPagedTableProvider, "agentToolCallsPagedTableProvider");
1057
+ function agentThreadsPagedTableProvider() {
1058
+ return governancePagedTableProvider("agent.threads.paged", DEFAULT_RECENT_LIMIT, (queries, query) => queries.threadsPage(query), toRecentThreadTableRows);
1059
+ }
1060
+ __name(agentThreadsPagedTableProvider, "agentThreadsPagedTableProvider");
1061
+ function agentRunsPagedTableProvider() {
1062
+ return governancePagedTableProvider("agent.runs.paged", DEFAULT_RECENT_LIMIT, (queries, query) => queries.runsPage(query), toRecentRunTableRows);
1063
+ }
1064
+ __name(agentRunsPagedTableProvider, "agentRunsPagedTableProvider");
1020
1065
  var PENDING_APPROVALS_COUNT_LIMIT = 500;
1021
1066
  function agentPendingApprovalsCountProvider() {
1022
1067
  return {
@@ -1121,6 +1166,9 @@ function agentTelescopeExtension(opts = {}) {
1121
1166
  agentRecentRunsTableProvider(),
1122
1167
  agentRecentToolCallsTableProvider(),
1123
1168
  agentRecentThreadsTableProvider(),
1169
+ agentRunsPagedTableProvider(),
1170
+ agentToolCallsPagedTableProvider(),
1171
+ agentThreadsPagedTableProvider(),
1124
1172
  agentPendingApprovalsCountProvider(),
1125
1173
  agentPendingApprovalsTableProvider(),
1126
1174
  agentToolStatsTableProvider()