@dudousxd/nestjs-agent-dashboard 0.4.1 → 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.
@@ -23,6 +23,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
23
23
  var index_exports = {};
24
24
  __export(index_exports, {
25
25
  AGENT_ACTOR_DIRECTORY: () => AGENT_ACTOR_DIRECTORY,
26
+ AGENT_APPROVAL_PORT: () => AGENT_APPROVAL_PORT,
26
27
  AGENT_GOVERNANCE_QUERIES: () => AGENT_GOVERNANCE_QUERIES,
27
28
  AGENT_PRICING_STORE: () => AGENT_PRICING_STORE,
28
29
  AgentApiController: () => AgentApiController,
@@ -30,6 +31,7 @@ __export(index_exports, {
30
31
  AgentDashboardModule: () => AgentDashboardModule,
31
32
  AgentUiController: () => AgentUiController,
32
33
  DASHBOARD_API_PATH: () => DASHBOARD_API_PATH,
34
+ DASHBOARD_APPROVAL_ACTOR_REF: () => DASHBOARD_APPROVAL_ACTOR_REF,
33
35
  DASHBOARD_BASE_PATH: () => DASHBOARD_BASE_PATH,
34
36
  DashboardService: () => DashboardService,
35
37
  agentDashboardMountPaths: () => agentDashboardMountPaths,
@@ -38,35 +40,57 @@ __export(index_exports, {
38
40
  module.exports = __toCommonJS(index_exports);
39
41
 
40
42
  // src/server/agent-api.controller.ts
41
- var import_common3 = require("@nestjs/common");
43
+ var import_common4 = require("@nestjs/common");
42
44
 
43
45
  // src/server/dashboard.service.ts
44
46
  var import_node_diagnostics_channel = require("diagnostics_channel");
45
47
  var import_nestjs_diagnostics = require("@dudousxd/nestjs-diagnostics");
46
- var import_common2 = require("@nestjs/common");
48
+ var import_common3 = require("@nestjs/common");
47
49
  var import_rxjs = require("rxjs");
48
50
 
49
- // src/server/parse-price-input.ts
51
+ // src/server/parse-approval-decision.ts
50
52
  var import_common = require("@nestjs/common");
51
- function parsePriceInput(body) {
53
+ function parseApprovalDecision(body) {
52
54
  if (typeof body !== "object" || body === null) {
53
55
  throw new import_common.BadRequestException("Expected a JSON object body.");
54
56
  }
57
+ const { approved, reason } = body;
58
+ if (typeof approved !== "boolean") {
59
+ throw new import_common.BadRequestException('"approved" must be a boolean.');
60
+ }
61
+ if (reason !== void 0 && typeof reason !== "string") {
62
+ throw new import_common.BadRequestException('"reason" must be a string when present.');
63
+ }
64
+ return {
65
+ approved,
66
+ ...reason !== void 0 ? {
67
+ reason
68
+ } : {}
69
+ };
70
+ }
71
+ __name(parseApprovalDecision, "parseApprovalDecision");
72
+
73
+ // src/server/parse-price-input.ts
74
+ var import_common2 = require("@nestjs/common");
75
+ function parsePriceInput(body) {
76
+ if (typeof body !== "object" || body === null) {
77
+ throw new import_common2.BadRequestException("Expected a JSON object body.");
78
+ }
55
79
  const { modelId, inputPricePer1m, outputPricePer1m, cacheWritePricePer1m, cacheReadPricePer1m } = body;
56
80
  if (typeof modelId !== "string" || modelId.trim().length === 0) {
57
- throw new import_common.BadRequestException('"modelId" must be a non-empty string.');
81
+ throw new import_common2.BadRequestException('"modelId" must be a non-empty string.');
58
82
  }
59
83
  if (!isFiniteNonNegative(inputPricePer1m)) {
60
- throw new import_common.BadRequestException('"inputPricePer1m" must be a non-negative number.');
84
+ throw new import_common2.BadRequestException('"inputPricePer1m" must be a non-negative number.');
61
85
  }
62
86
  if (!isFiniteNonNegative(outputPricePer1m)) {
63
- throw new import_common.BadRequestException('"outputPricePer1m" must be a non-negative number.');
87
+ throw new import_common2.BadRequestException('"outputPricePer1m" must be a non-negative number.');
64
88
  }
65
89
  if (cacheWritePricePer1m !== void 0 && !isFiniteNonNegative(cacheWritePricePer1m)) {
66
- throw new import_common.BadRequestException('"cacheWritePricePer1m" must be a non-negative number when present.');
90
+ throw new import_common2.BadRequestException('"cacheWritePricePer1m" must be a non-negative number when present.');
67
91
  }
68
92
  if (cacheReadPricePer1m !== void 0 && !isFiniteNonNegative(cacheReadPricePer1m)) {
69
- throw new import_common.BadRequestException('"cacheReadPricePer1m" must be a non-negative number when present.');
93
+ throw new import_common2.BadRequestException('"cacheReadPricePer1m" must be a non-negative number when present.');
70
94
  }
71
95
  return {
72
96
  modelId,
@@ -90,8 +114,10 @@ __name(isFiniteNonNegative, "isFiniteNonNegative");
90
114
  var AGENT_GOVERNANCE_QUERIES = Symbol.for("@dudousxd/nestjs-agent:governance-queries");
91
115
  var AGENT_ACTOR_DIRECTORY = Symbol.for("@dudousxd/nestjs-agent:actor-directory");
92
116
  var AGENT_PRICING_STORE = Symbol.for("@dudousxd/nestjs-agent:pricing-store");
117
+ var AGENT_APPROVAL_PORT = Symbol.for("@dudousxd/nestjs-agent:approval-port");
93
118
  var DASHBOARD_BASE_PATH = Symbol.for("@dudousxd/nestjs-agent-dashboard:base-path");
94
119
  var DASHBOARD_API_PATH = Symbol.for("@dudousxd/nestjs-agent-dashboard:api-path");
120
+ var DASHBOARD_APPROVAL_ACTOR_REF = Symbol.for("@dudousxd/nestjs-agent-dashboard:approval-actor-ref");
95
121
 
96
122
  // src/server/dashboard.service.ts
97
123
  function _ts_decorate(decorators, target, key, desc) {
@@ -112,6 +138,7 @@ function _ts_param(paramIndex, decorator) {
112
138
  }
113
139
  __name(_ts_param, "_ts_param");
114
140
  var PRICING_STORE_UNBOUND_MESSAGE = "Pricing CRUD is unavailable: no AGENT_PRICING_STORE is bound. Bind a pricing store (e.g. MikroOrmPricingStore from @dudousxd/nestjs-agent-store-mikro-orm) to enable it.";
141
+ var APPROVAL_PORT_UNBOUND_MESSAGE = "Approve/reject is unavailable: no AGENT_APPROVAL_PORT is bound. Import AgentModule from @dudousxd/nestjs-agent alongside this dashboard to enable it \u2014 the approvals inbox stays read-only until then.";
115
142
  var AGENT_EVENTS = [
116
143
  "run.started",
117
144
  "message",
@@ -131,10 +158,12 @@ var DashboardService = class {
131
158
  queries;
132
159
  actorDirectory;
133
160
  pricingStore;
134
- constructor(queries, actorDirectory, pricingStore) {
161
+ approvalPort;
162
+ constructor(queries, actorDirectory, pricingStore, approvalPort) {
135
163
  this.queries = queries;
136
164
  this.actorDirectory = actorDirectory;
137
165
  this.pricingStore = pricingStore;
166
+ this.approvalPort = approvalPort;
138
167
  }
139
168
  /** Spend/usage overview for a day range: by-model + by-actor spend and the daily trend, in parallel. */
140
169
  async spend(range) {
@@ -155,10 +184,64 @@ var DashboardService = class {
155
184
  const rows = await this.queries.spendByThread(range, limit);
156
185
  return this.withActorLabels(rows);
157
186
  }
187
+ /** Run reliability for a day range: metrics, by-agent/by-error breakdowns and the trend, in parallel. */
188
+ async reliability(range) {
189
+ const [metrics, byAgent, errors, trend] = await Promise.all([
190
+ this.queries.runMetrics(range),
191
+ this.queries.runsByAgent(range),
192
+ this.queries.runErrors(range),
193
+ this.queries.runTrend(range)
194
+ ]);
195
+ return {
196
+ metrics,
197
+ byAgent,
198
+ errors,
199
+ trend
200
+ };
201
+ }
202
+ /** Most recent runs (status/agent/duration/error) for the Reliability recent-runs table. */
203
+ recentRuns(limit) {
204
+ return this.queries.recentRuns(limit);
205
+ }
158
206
  /** Most recent tool calls (status/type/thread) for the Runs & tools activity feed. */
159
207
  recentToolCalls(limit) {
160
208
  return this.queries.recentToolCalls(limit);
161
209
  }
210
+ /** Tool calls sitting `pending_approval`, oldest first, for the cross-thread approvals inbox. */
211
+ pendingApprovals(limit) {
212
+ return this.queries.pendingApprovals(limit);
213
+ }
214
+ /** Per-tool call/failure/rejection/latency rollup for a day range, for the Tools section. */
215
+ toolStats(range) {
216
+ return this.queries.toolStats(range);
217
+ }
218
+ /**
219
+ * Decide a pending HITL tool call from the console. Routes through the OPTIONAL
220
+ * {@link AGENT_APPROVAL_PORT} — bound by `@dudousxd/nestjs-agent` to the SAME signal path chat
221
+ * approvals use — so a 501 here (checked BEFORE body validation, same ordering as
222
+ * {@link upsertPrice}) means "no approval port bound", not "your body was invalid". `executedByRef`
223
+ * is an OPAQUE decider ref the caller resolved from the live request (see
224
+ * `AgentDashboardOptions.approvalActorRef`); omitted when the host didn't configure one.
225
+ */
226
+ async decideApproval(toolCallId, body, executedByRef) {
227
+ if (this.approvalPort === void 0) {
228
+ throw new import_common3.NotImplementedException(APPROVAL_PORT_UNBOUND_MESSAGE);
229
+ }
230
+ const decision = parseApprovalDecision(body);
231
+ const opts = executedByRef !== void 0 ? {
232
+ executedByRef
233
+ } : {};
234
+ if (decision.approved) {
235
+ await this.approvalPort.approve(toolCallId, opts);
236
+ return;
237
+ }
238
+ await this.approvalPort.reject(toolCallId, {
239
+ ...opts,
240
+ ...decision.reason !== void 0 ? {
241
+ reason: decision.reason
242
+ } : {}
243
+ });
244
+ }
162
245
  /** Most recent threads with rolled-up message/token counts. */
163
246
  async recentThreads(limit) {
164
247
  const rows = await this.queries.recentThreads(limit);
@@ -191,7 +274,7 @@ var DashboardService = class {
191
274
  /** Current price row per model, for the pricing tab. 501s when no `AGENT_PRICING_STORE` is bound. */
192
275
  async listPrices() {
193
276
  if (this.pricingStore === void 0) {
194
- throw new import_common2.NotImplementedException(PRICING_STORE_UNBOUND_MESSAGE);
277
+ throw new import_common3.NotImplementedException(PRICING_STORE_UNBOUND_MESSAGE);
195
278
  }
196
279
  return this.pricingStore.listCurrentPrices();
197
280
  }
@@ -202,7 +285,7 @@ var DashboardService = class {
202
285
  */
203
286
  async upsertPrice(body) {
204
287
  if (this.pricingStore === void 0) {
205
- throw new import_common2.NotImplementedException(PRICING_STORE_UNBOUND_MESSAGE);
288
+ throw new import_common3.NotImplementedException(PRICING_STORE_UNBOUND_MESSAGE);
206
289
  }
207
290
  await this.pricingStore.upsertModelPrice(parsePriceInput(body));
208
291
  }
@@ -238,17 +321,20 @@ var DashboardService = class {
238
321
  }
239
322
  };
240
323
  DashboardService = _ts_decorate([
241
- (0, import_common2.Injectable)(),
242
- _ts_param(0, (0, import_common2.Inject)(AGENT_GOVERNANCE_QUERIES)),
243
- _ts_param(1, (0, import_common2.Optional)()),
244
- _ts_param(1, (0, import_common2.Inject)(AGENT_ACTOR_DIRECTORY)),
245
- _ts_param(2, (0, import_common2.Optional)()),
246
- _ts_param(2, (0, import_common2.Inject)(AGENT_PRICING_STORE)),
324
+ (0, import_common3.Injectable)(),
325
+ _ts_param(0, (0, import_common3.Inject)(AGENT_GOVERNANCE_QUERIES)),
326
+ _ts_param(1, (0, import_common3.Optional)()),
327
+ _ts_param(1, (0, import_common3.Inject)(AGENT_ACTOR_DIRECTORY)),
328
+ _ts_param(2, (0, import_common3.Optional)()),
329
+ _ts_param(2, (0, import_common3.Inject)(AGENT_PRICING_STORE)),
330
+ _ts_param(3, (0, import_common3.Optional)()),
331
+ _ts_param(3, (0, import_common3.Inject)(AGENT_APPROVAL_PORT)),
247
332
  _ts_metadata("design:type", Function),
248
333
  _ts_metadata("design:paramtypes", [
249
334
  typeof AgentGovernanceQueries === "undefined" ? Object : AgentGovernanceQueries,
250
335
  typeof ActorDirectory === "undefined" ? Object : ActorDirectory,
251
- typeof AgentPricingStore === "undefined" ? Object : AgentPricingStore
336
+ typeof AgentPricingStore === "undefined" ? Object : AgentPricingStore,
337
+ typeof AgentApprovalPort === "undefined" ? Object : AgentApprovalPort
252
338
  ])
253
339
  ], DashboardService);
254
340
 
@@ -298,8 +384,10 @@ var AgentApiController = class {
298
384
  __name(this, "AgentApiController");
299
385
  }
300
386
  dashboard;
301
- constructor(dashboard) {
387
+ approvalActorRef;
388
+ constructor(dashboard, approvalActorRef) {
302
389
  this.dashboard = dashboard;
390
+ this.approvalActorRef = approvalActorRef;
303
391
  }
304
392
  /** `{ byModel, byActor, trend }` for a day range (defaults to the last 30 days). */
305
393
  spend(from, to) {
@@ -309,10 +397,34 @@ var AgentApiController = class {
309
397
  topThreads(from, to, limit) {
310
398
  return this.dashboard.topThreads(resolveRange(from, to), parseLimit(limit, 10));
311
399
  }
400
+ /** `{ metrics, byAgent, errors, trend }` for a day range (defaults to the last 30 days). */
401
+ reliability(from, to) {
402
+ return this.dashboard.reliability(resolveRange(from, to));
403
+ }
404
+ /** Most recent runs (default 50, max 200) for the Reliability recent-runs table. */
405
+ runs(limit) {
406
+ return this.dashboard.recentRuns(parseLimit(limit, 50));
407
+ }
312
408
  /** Most recent tool calls (default 50, max 200) for the activity feed. */
313
409
  toolCalls(limit) {
314
410
  return this.dashboard.recentToolCalls(parseLimit(limit, 50));
315
411
  }
412
+ /** Tool calls sitting `pending_approval` (default 50, max 200), oldest first — the approvals inbox. */
413
+ approvals(limit) {
414
+ return this.dashboard.pendingApprovals(parseLimit(limit, 50));
415
+ }
416
+ /**
417
+ * Decide a pending HITL tool call. Body `{ approved: boolean; reason?: string }`. 501s (via
418
+ * `DashboardService.decideApproval`) when no `AGENT_APPROVAL_PORT` is bound. `executedByRef`
419
+ * comes from the host's `approvalActorRef` extractor run against the live request, when configured.
420
+ */
421
+ async decideApproval(toolCallId, body, req) {
422
+ await this.dashboard.decideApproval(toolCallId, body, this.approvalActorRef?.(req));
423
+ }
424
+ /** Per-tool call/failure/rejection/latency rollup for a day range (defaults to the last 30 days). */
425
+ tools(from, to) {
426
+ return this.dashboard.toolStats(resolveRange(from, to));
427
+ }
316
428
  /** Most recent threads (default 50, max 200) with rolled-up counts. */
317
429
  threads(limit) {
318
430
  return this.dashboard.recentThreads(parseLimit(limit, 50));
@@ -338,9 +450,9 @@ var AgentApiController = class {
338
450
  }
339
451
  };
340
452
  _ts_decorate2([
341
- (0, import_common3.Get)("spend"),
342
- _ts_param2(0, (0, import_common3.Query)("from")),
343
- _ts_param2(1, (0, import_common3.Query)("to")),
453
+ (0, import_common4.Get)("spend"),
454
+ _ts_param2(0, (0, import_common4.Query)("from")),
455
+ _ts_param2(1, (0, import_common4.Query)("to")),
344
456
  _ts_metadata2("design:type", Function),
345
457
  _ts_metadata2("design:paramtypes", [
346
458
  String,
@@ -349,10 +461,10 @@ _ts_decorate2([
349
461
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
350
462
  ], AgentApiController.prototype, "spend", null);
351
463
  _ts_decorate2([
352
- (0, import_common3.Get)("top-threads"),
353
- _ts_param2(0, (0, import_common3.Query)("from")),
354
- _ts_param2(1, (0, import_common3.Query)("to")),
355
- _ts_param2(2, (0, import_common3.Query)("limit")),
464
+ (0, import_common4.Get)("top-threads"),
465
+ _ts_param2(0, (0, import_common4.Query)("from")),
466
+ _ts_param2(1, (0, import_common4.Query)("to")),
467
+ _ts_param2(2, (0, import_common4.Query)("limit")),
356
468
  _ts_metadata2("design:type", Function),
357
469
  _ts_metadata2("design:paramtypes", [
358
470
  String,
@@ -362,8 +474,28 @@ _ts_decorate2([
362
474
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
363
475
  ], AgentApiController.prototype, "topThreads", null);
364
476
  _ts_decorate2([
365
- (0, import_common3.Get)("tool-calls"),
366
- _ts_param2(0, (0, import_common3.Query)("limit")),
477
+ (0, import_common4.Get)("reliability"),
478
+ _ts_param2(0, (0, import_common4.Query)("from")),
479
+ _ts_param2(1, (0, import_common4.Query)("to")),
480
+ _ts_metadata2("design:type", Function),
481
+ _ts_metadata2("design:paramtypes", [
482
+ String,
483
+ String
484
+ ]),
485
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
486
+ ], AgentApiController.prototype, "reliability", null);
487
+ _ts_decorate2([
488
+ (0, import_common4.Get)("runs"),
489
+ _ts_param2(0, (0, import_common4.Query)("limit")),
490
+ _ts_metadata2("design:type", Function),
491
+ _ts_metadata2("design:paramtypes", [
492
+ String
493
+ ]),
494
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
495
+ ], AgentApiController.prototype, "runs", null);
496
+ _ts_decorate2([
497
+ (0, import_common4.Get)("tool-calls"),
498
+ _ts_param2(0, (0, import_common4.Query)("limit")),
367
499
  _ts_metadata2("design:type", Function),
368
500
  _ts_metadata2("design:paramtypes", [
369
501
  String
@@ -371,8 +503,42 @@ _ts_decorate2([
371
503
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
372
504
  ], AgentApiController.prototype, "toolCalls", null);
373
505
  _ts_decorate2([
374
- (0, import_common3.Get)("threads"),
375
- _ts_param2(0, (0, import_common3.Query)("limit")),
506
+ (0, import_common4.Get)("approvals"),
507
+ _ts_param2(0, (0, import_common4.Query)("limit")),
508
+ _ts_metadata2("design:type", Function),
509
+ _ts_metadata2("design:paramtypes", [
510
+ String
511
+ ]),
512
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
513
+ ], AgentApiController.prototype, "approvals", null);
514
+ _ts_decorate2([
515
+ (0, import_common4.Post)("approvals/:toolCallId"),
516
+ (0, import_common4.HttpCode)(204),
517
+ _ts_param2(0, (0, import_common4.Param)("toolCallId")),
518
+ _ts_param2(1, (0, import_common4.Body)()),
519
+ _ts_param2(2, (0, import_common4.Req)()),
520
+ _ts_metadata2("design:type", Function),
521
+ _ts_metadata2("design:paramtypes", [
522
+ String,
523
+ Object,
524
+ Object
525
+ ]),
526
+ _ts_metadata2("design:returntype", Promise)
527
+ ], AgentApiController.prototype, "decideApproval", null);
528
+ _ts_decorate2([
529
+ (0, import_common4.Get)("tools"),
530
+ _ts_param2(0, (0, import_common4.Query)("from")),
531
+ _ts_param2(1, (0, import_common4.Query)("to")),
532
+ _ts_metadata2("design:type", Function),
533
+ _ts_metadata2("design:paramtypes", [
534
+ String,
535
+ String
536
+ ]),
537
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
538
+ ], AgentApiController.prototype, "tools", null);
539
+ _ts_decorate2([
540
+ (0, import_common4.Get)("threads"),
541
+ _ts_param2(0, (0, import_common4.Query)("limit")),
376
542
  _ts_metadata2("design:type", Function),
377
543
  _ts_metadata2("design:paramtypes", [
378
544
  String
@@ -380,14 +546,14 @@ _ts_decorate2([
380
546
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
381
547
  ], AgentApiController.prototype, "threads", null);
382
548
  _ts_decorate2([
383
- (0, import_common3.Get)("pricing"),
549
+ (0, import_common4.Get)("pricing"),
384
550
  _ts_metadata2("design:type", Function),
385
551
  _ts_metadata2("design:paramtypes", []),
386
552
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
387
553
  ], AgentApiController.prototype, "listPrices", null);
388
554
  _ts_decorate2([
389
- (0, import_common3.Post)("pricing"),
390
- _ts_param2(0, (0, import_common3.Body)()),
555
+ (0, import_common4.Post)("pricing"),
556
+ _ts_param2(0, (0, import_common4.Body)()),
391
557
  _ts_metadata2("design:type", Function),
392
558
  _ts_metadata2("design:paramtypes", [
393
559
  Object
@@ -395,16 +561,18 @@ _ts_decorate2([
395
561
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
396
562
  ], AgentApiController.prototype, "upsertPrice", null);
397
563
  _ts_decorate2([
398
- (0, import_common3.Sse)("stream"),
564
+ (0, import_common4.Sse)("stream"),
399
565
  _ts_metadata2("design:type", Function),
400
566
  _ts_metadata2("design:paramtypes", []),
401
567
  _ts_metadata2("design:returntype", typeof Observable === "undefined" ? Object : Observable)
402
568
  ], AgentApiController.prototype, "stream", null);
403
569
  AgentApiController = _ts_decorate2([
404
- (0, import_common3.Controller)(),
570
+ (0, import_common4.Controller)(),
571
+ _ts_param2(1, (0, import_common4.Inject)(DASHBOARD_APPROVAL_ACTOR_REF)),
405
572
  _ts_metadata2("design:type", Function),
406
573
  _ts_metadata2("design:paramtypes", [
407
- typeof DashboardService === "undefined" ? Object : DashboardService
574
+ typeof DashboardService === "undefined" ? Object : DashboardService,
575
+ Object
408
576
  ])
409
577
  ], AgentApiController);
410
578
 
@@ -435,14 +603,14 @@ __name(agentDashboardMountPaths, "agentDashboardMountPaths");
435
603
 
436
604
  // src/server/agent-dashboard.module.ts
437
605
  var import_reflect_metadata = require("reflect-metadata");
438
- var import_common5 = require("@nestjs/common");
606
+ var import_common6 = require("@nestjs/common");
439
607
  var import_core = require("@nestjs/core");
440
608
 
441
609
  // src/server/agent-ui.controller.ts
442
610
  var import_node_fs = require("fs");
443
611
  var import_node_path = require("path");
444
612
  var import_node_url = require("url");
445
- var import_common4 = require("@nestjs/common");
613
+ var import_common5 = require("@nestjs/common");
446
614
  function _ts_decorate3(decorators, target, key, desc) {
447
615
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
448
616
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -490,7 +658,7 @@ var AgentUiController = class {
490
658
  index() {
491
659
  const indexPath = (0, import_node_path.join)(this.dir, "index.html");
492
660
  if (!(0, import_node_fs.existsSync)(indexPath)) {
493
- throw new import_common4.NotFoundException("Dashboard is not built. Run the package build.");
661
+ throw new import_common5.NotFoundException("Dashboard is not built. Run the package build.");
494
662
  }
495
663
  const html = (0, import_node_fs.readFileSync)(indexPath, "utf8").replaceAll(`="${BUILD_BASE}/`, `="${this.basePath}/`);
496
664
  const inject = `<script>window.__AGENT_BASE__='${this.basePath}';window.__AGENT_API__='${this.apiBasePath}';</script>`;
@@ -498,40 +666,40 @@ var AgentUiController = class {
498
666
  }
499
667
  asset(file) {
500
668
  const safe = (0, import_node_path.basename)(file);
501
- if (safe !== file) throw new import_common4.NotFoundException();
669
+ if (safe !== file) throw new import_common5.NotFoundException();
502
670
  const root = (0, import_node_path.resolve)(this.dir, "assets");
503
671
  const assetPath = (0, import_node_path.resolve)(root, safe);
504
672
  if (!assetPath.startsWith(root + import_node_path.sep) || !(0, import_node_fs.existsSync)(assetPath)) {
505
- throw new import_common4.NotFoundException();
673
+ throw new import_common5.NotFoundException();
506
674
  }
507
675
  const type = CONTENT_TYPES[(0, import_node_path.extname)(safe)] ?? "application/octet-stream";
508
- return new import_common4.StreamableFile((0, import_node_fs.readFileSync)(assetPath), {
676
+ return new import_common5.StreamableFile((0, import_node_fs.readFileSync)(assetPath), {
509
677
  type
510
678
  });
511
679
  }
512
680
  };
513
681
  _ts_decorate3([
514
- (0, import_common4.Get)(),
515
- (0, import_common4.Header)("Content-Type", "text/html; charset=utf-8"),
516
- (0, import_common4.Header)("Cache-Control", "no-store, must-revalidate"),
682
+ (0, import_common5.Get)(),
683
+ (0, import_common5.Header)("Content-Type", "text/html; charset=utf-8"),
684
+ (0, import_common5.Header)("Cache-Control", "no-store, must-revalidate"),
517
685
  _ts_metadata3("design:type", Function),
518
686
  _ts_metadata3("design:paramtypes", []),
519
687
  _ts_metadata3("design:returntype", String)
520
688
  ], AgentUiController.prototype, "index", null);
521
689
  _ts_decorate3([
522
- (0, import_common4.Get)("assets/:file"),
523
- (0, import_common4.Header)("Cache-Control", "public, max-age=31536000, immutable"),
524
- _ts_param3(0, (0, import_common4.Param)("file")),
690
+ (0, import_common5.Get)("assets/:file"),
691
+ (0, import_common5.Header)("Cache-Control", "public, max-age=31536000, immutable"),
692
+ _ts_param3(0, (0, import_common5.Param)("file")),
525
693
  _ts_metadata3("design:type", Function),
526
694
  _ts_metadata3("design:paramtypes", [
527
695
  String
528
696
  ]),
529
- _ts_metadata3("design:returntype", typeof import_common4.StreamableFile === "undefined" ? Object : import_common4.StreamableFile)
697
+ _ts_metadata3("design:returntype", typeof import_common5.StreamableFile === "undefined" ? Object : import_common5.StreamableFile)
530
698
  ], AgentUiController.prototype, "asset", null);
531
699
  AgentUiController = _ts_decorate3([
532
- (0, import_common4.Controller)(),
533
- _ts_param3(0, (0, import_common4.Inject)(DASHBOARD_BASE_PATH)),
534
- _ts_param3(1, (0, import_common4.Inject)(DASHBOARD_API_PATH)),
700
+ (0, import_common5.Controller)(),
701
+ _ts_param3(0, (0, import_common5.Inject)(DASHBOARD_BASE_PATH)),
702
+ _ts_param3(1, (0, import_common5.Inject)(DASHBOARD_API_PATH)),
535
703
  _ts_metadata3("design:type", Function),
536
704
  _ts_metadata3("design:paramtypes", [
537
705
  String,
@@ -573,7 +741,13 @@ var AgentApiModule = class _AgentApiModule {
573
741
  ],
574
742
  providers: [
575
743
  DashboardService,
576
- ...options.guards ?? []
744
+ ...options.guards ?? [],
745
+ // `useValue` even when `options.approvalActorRef` is `undefined` — AgentApiController
746
+ // injects this WITHOUT `@Optional()` (same pattern as `AGENT_QUOTA_STORE`'s factory).
747
+ {
748
+ provide: DASHBOARD_APPROVAL_ACTOR_REF,
749
+ useValue: options.approvalActorRef
750
+ }
577
751
  ],
578
752
  exports: [
579
753
  DashboardService
@@ -582,7 +756,7 @@ var AgentApiModule = class _AgentApiModule {
582
756
  }
583
757
  };
584
758
  AgentApiModule = _ts_decorate4([
585
- (0, import_common5.Module)({})
759
+ (0, import_common6.Module)({})
586
760
  ], AgentApiModule);
587
761
  var AgentDashboardModule = class _AgentDashboardModule {
588
762
  static {
@@ -605,6 +779,9 @@ var AgentDashboardModule = class _AgentDashboardModule {
605
779
  } : {},
606
780
  ...options.guards ? {
607
781
  guards: options.guards
782
+ } : {},
783
+ ...options.approvalActorRef ? {
784
+ approvalActorRef: options.approvalActorRef
608
785
  } : {}
609
786
  }),
610
787
  import_core.RouterModule.register([
@@ -641,11 +818,12 @@ var AgentDashboardModule = class _AgentDashboardModule {
641
818
  }
642
819
  };
643
820
  AgentDashboardModule = _ts_decorate4([
644
- (0, import_common5.Module)({})
821
+ (0, import_common6.Module)({})
645
822
  ], AgentDashboardModule);
646
823
  // Annotate the CommonJS export names for ESM import in node:
647
824
  0 && (module.exports = {
648
825
  AGENT_ACTOR_DIRECTORY,
826
+ AGENT_APPROVAL_PORT,
649
827
  AGENT_GOVERNANCE_QUERIES,
650
828
  AGENT_PRICING_STORE,
651
829
  AgentApiController,
@@ -653,6 +831,7 @@ AgentDashboardModule = _ts_decorate4([
653
831
  AgentDashboardModule,
654
832
  AgentUiController,
655
833
  DASHBOARD_API_PATH,
834
+ DASHBOARD_APPROVAL_ACTOR_REF,
656
835
  DASHBOARD_BASE_PATH,
657
836
  DashboardService,
658
837
  agentDashboardMountPaths,