@dudousxd/nestjs-agent-dashboard 0.5.0 → 0.7.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,8 @@ 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_ACTOR_RESOLVER: () => AGENT_ACTOR_RESOLVER,
27
+ AGENT_APPROVAL_PORT: () => AGENT_APPROVAL_PORT,
26
28
  AGENT_GOVERNANCE_QUERIES: () => AGENT_GOVERNANCE_QUERIES,
27
29
  AGENT_PRICING_STORE: () => AGENT_PRICING_STORE,
28
30
  AgentApiController: () => AgentApiController,
@@ -30,6 +32,7 @@ __export(index_exports, {
30
32
  AgentDashboardModule: () => AgentDashboardModule,
31
33
  AgentUiController: () => AgentUiController,
32
34
  DASHBOARD_API_PATH: () => DASHBOARD_API_PATH,
35
+ DASHBOARD_APPROVAL_ACTOR_REF: () => DASHBOARD_APPROVAL_ACTOR_REF,
33
36
  DASHBOARD_BASE_PATH: () => DASHBOARD_BASE_PATH,
34
37
  DashboardService: () => DashboardService,
35
38
  agentDashboardMountPaths: () => agentDashboardMountPaths,
@@ -38,35 +41,57 @@ __export(index_exports, {
38
41
  module.exports = __toCommonJS(index_exports);
39
42
 
40
43
  // src/server/agent-api.controller.ts
41
- var import_common3 = require("@nestjs/common");
44
+ var import_common4 = require("@nestjs/common");
42
45
 
43
46
  // src/server/dashboard.service.ts
44
47
  var import_node_diagnostics_channel = require("diagnostics_channel");
45
48
  var import_nestjs_diagnostics = require("@dudousxd/nestjs-diagnostics");
46
- var import_common2 = require("@nestjs/common");
49
+ var import_common3 = require("@nestjs/common");
47
50
  var import_rxjs = require("rxjs");
48
51
 
49
- // src/server/parse-price-input.ts
52
+ // src/server/parse-approval-decision.ts
50
53
  var import_common = require("@nestjs/common");
51
- function parsePriceInput(body) {
54
+ function parseApprovalDecision(body) {
52
55
  if (typeof body !== "object" || body === null) {
53
56
  throw new import_common.BadRequestException("Expected a JSON object body.");
54
57
  }
58
+ const { approved, reason } = body;
59
+ if (typeof approved !== "boolean") {
60
+ throw new import_common.BadRequestException('"approved" must be a boolean.');
61
+ }
62
+ if (reason !== void 0 && typeof reason !== "string") {
63
+ throw new import_common.BadRequestException('"reason" must be a string when present.');
64
+ }
65
+ return {
66
+ approved,
67
+ ...reason !== void 0 ? {
68
+ reason
69
+ } : {}
70
+ };
71
+ }
72
+ __name(parseApprovalDecision, "parseApprovalDecision");
73
+
74
+ // src/server/parse-price-input.ts
75
+ var import_common2 = require("@nestjs/common");
76
+ function parsePriceInput(body) {
77
+ if (typeof body !== "object" || body === null) {
78
+ throw new import_common2.BadRequestException("Expected a JSON object body.");
79
+ }
55
80
  const { modelId, inputPricePer1m, outputPricePer1m, cacheWritePricePer1m, cacheReadPricePer1m } = body;
56
81
  if (typeof modelId !== "string" || modelId.trim().length === 0) {
57
- throw new import_common.BadRequestException('"modelId" must be a non-empty string.');
82
+ throw new import_common2.BadRequestException('"modelId" must be a non-empty string.');
58
83
  }
59
84
  if (!isFiniteNonNegative(inputPricePer1m)) {
60
- throw new import_common.BadRequestException('"inputPricePer1m" must be a non-negative number.');
85
+ throw new import_common2.BadRequestException('"inputPricePer1m" must be a non-negative number.');
61
86
  }
62
87
  if (!isFiniteNonNegative(outputPricePer1m)) {
63
- throw new import_common.BadRequestException('"outputPricePer1m" must be a non-negative number.');
88
+ throw new import_common2.BadRequestException('"outputPricePer1m" must be a non-negative number.');
64
89
  }
65
90
  if (cacheWritePricePer1m !== void 0 && !isFiniteNonNegative(cacheWritePricePer1m)) {
66
- throw new import_common.BadRequestException('"cacheWritePricePer1m" must be a non-negative number when present.');
91
+ throw new import_common2.BadRequestException('"cacheWritePricePer1m" must be a non-negative number when present.');
67
92
  }
68
93
  if (cacheReadPricePer1m !== void 0 && !isFiniteNonNegative(cacheReadPricePer1m)) {
69
- throw new import_common.BadRequestException('"cacheReadPricePer1m" must be a non-negative number when present.');
94
+ throw new import_common2.BadRequestException('"cacheReadPricePer1m" must be a non-negative number when present.');
70
95
  }
71
96
  return {
72
97
  modelId,
@@ -90,8 +115,11 @@ __name(isFiniteNonNegative, "isFiniteNonNegative");
90
115
  var AGENT_GOVERNANCE_QUERIES = Symbol.for("@dudousxd/nestjs-agent:governance-queries");
91
116
  var AGENT_ACTOR_DIRECTORY = Symbol.for("@dudousxd/nestjs-agent:actor-directory");
92
117
  var AGENT_PRICING_STORE = Symbol.for("@dudousxd/nestjs-agent:pricing-store");
118
+ var AGENT_APPROVAL_PORT = Symbol.for("@dudousxd/nestjs-agent:approval-port");
119
+ var AGENT_ACTOR_RESOLVER = Symbol.for("@dudousxd/nestjs-agent:actor-resolver");
93
120
  var DASHBOARD_BASE_PATH = Symbol.for("@dudousxd/nestjs-agent-dashboard:base-path");
94
121
  var DASHBOARD_API_PATH = Symbol.for("@dudousxd/nestjs-agent-dashboard:api-path");
122
+ var DASHBOARD_APPROVAL_ACTOR_REF = Symbol.for("@dudousxd/nestjs-agent-dashboard:approval-actor-ref");
95
123
 
96
124
  // src/server/dashboard.service.ts
97
125
  function _ts_decorate(decorators, target, key, desc) {
@@ -112,6 +140,7 @@ function _ts_param(paramIndex, decorator) {
112
140
  }
113
141
  __name(_ts_param, "_ts_param");
114
142
  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.";
143
+ 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
144
  var AGENT_EVENTS = [
116
145
  "run.started",
117
146
  "message",
@@ -131,10 +160,12 @@ var DashboardService = class {
131
160
  queries;
132
161
  actorDirectory;
133
162
  pricingStore;
134
- constructor(queries, actorDirectory, pricingStore) {
163
+ approvalPort;
164
+ constructor(queries, actorDirectory, pricingStore, approvalPort) {
135
165
  this.queries = queries;
136
166
  this.actorDirectory = actorDirectory;
137
167
  this.pricingStore = pricingStore;
168
+ this.approvalPort = approvalPort;
138
169
  }
139
170
  /** Spend/usage overview for a day range: by-model + by-actor spend and the daily trend, in parallel. */
140
171
  async spend(range) {
@@ -178,6 +209,41 @@ var DashboardService = class {
178
209
  recentToolCalls(limit) {
179
210
  return this.queries.recentToolCalls(limit);
180
211
  }
212
+ /** Tool calls sitting `pending_approval`, oldest first, for the cross-thread approvals inbox. */
213
+ pendingApprovals(limit) {
214
+ return this.queries.pendingApprovals(limit);
215
+ }
216
+ /** Per-tool call/failure/rejection/latency rollup for a day range, for the Tools section. */
217
+ toolStats(range) {
218
+ return this.queries.toolStats(range);
219
+ }
220
+ /**
221
+ * Decide a pending HITL tool call from the console. Routes through the OPTIONAL
222
+ * {@link AGENT_APPROVAL_PORT} — bound by `@dudousxd/nestjs-agent` to the SAME signal path chat
223
+ * approvals use — so a 501 here (checked BEFORE body validation, same ordering as
224
+ * {@link upsertPrice}) means "no approval port bound", not "your body was invalid". `executedByRef`
225
+ * is an OPAQUE decider ref the caller resolved from the live request (see
226
+ * `AgentDashboardOptions.approvalActorRef`); omitted when the host didn't configure one.
227
+ */
228
+ async decideApproval(toolCallId, body, executedByRef) {
229
+ if (this.approvalPort === void 0) {
230
+ throw new import_common3.NotImplementedException(APPROVAL_PORT_UNBOUND_MESSAGE);
231
+ }
232
+ const decision = parseApprovalDecision(body);
233
+ const opts = executedByRef !== void 0 ? {
234
+ executedByRef
235
+ } : {};
236
+ if (decision.approved) {
237
+ await this.approvalPort.approve(toolCallId, opts);
238
+ return;
239
+ }
240
+ await this.approvalPort.reject(toolCallId, {
241
+ ...opts,
242
+ ...decision.reason !== void 0 ? {
243
+ reason: decision.reason
244
+ } : {}
245
+ });
246
+ }
181
247
  /** Most recent threads with rolled-up message/token counts. */
182
248
  async recentThreads(limit) {
183
249
  const rows = await this.queries.recentThreads(limit);
@@ -210,7 +276,7 @@ var DashboardService = class {
210
276
  /** Current price row per model, for the pricing tab. 501s when no `AGENT_PRICING_STORE` is bound. */
211
277
  async listPrices() {
212
278
  if (this.pricingStore === void 0) {
213
- throw new import_common2.NotImplementedException(PRICING_STORE_UNBOUND_MESSAGE);
279
+ throw new import_common3.NotImplementedException(PRICING_STORE_UNBOUND_MESSAGE);
214
280
  }
215
281
  return this.pricingStore.listCurrentPrices();
216
282
  }
@@ -221,7 +287,7 @@ var DashboardService = class {
221
287
  */
222
288
  async upsertPrice(body) {
223
289
  if (this.pricingStore === void 0) {
224
- throw new import_common2.NotImplementedException(PRICING_STORE_UNBOUND_MESSAGE);
290
+ throw new import_common3.NotImplementedException(PRICING_STORE_UNBOUND_MESSAGE);
225
291
  }
226
292
  await this.pricingStore.upsertModelPrice(parsePriceInput(body));
227
293
  }
@@ -257,17 +323,20 @@ var DashboardService = class {
257
323
  }
258
324
  };
259
325
  DashboardService = _ts_decorate([
260
- (0, import_common2.Injectable)(),
261
- _ts_param(0, (0, import_common2.Inject)(AGENT_GOVERNANCE_QUERIES)),
262
- _ts_param(1, (0, import_common2.Optional)()),
263
- _ts_param(1, (0, import_common2.Inject)(AGENT_ACTOR_DIRECTORY)),
264
- _ts_param(2, (0, import_common2.Optional)()),
265
- _ts_param(2, (0, import_common2.Inject)(AGENT_PRICING_STORE)),
326
+ (0, import_common3.Injectable)(),
327
+ _ts_param(0, (0, import_common3.Inject)(AGENT_GOVERNANCE_QUERIES)),
328
+ _ts_param(1, (0, import_common3.Optional)()),
329
+ _ts_param(1, (0, import_common3.Inject)(AGENT_ACTOR_DIRECTORY)),
330
+ _ts_param(2, (0, import_common3.Optional)()),
331
+ _ts_param(2, (0, import_common3.Inject)(AGENT_PRICING_STORE)),
332
+ _ts_param(3, (0, import_common3.Optional)()),
333
+ _ts_param(3, (0, import_common3.Inject)(AGENT_APPROVAL_PORT)),
266
334
  _ts_metadata("design:type", Function),
267
335
  _ts_metadata("design:paramtypes", [
268
336
  typeof AgentGovernanceQueries === "undefined" ? Object : AgentGovernanceQueries,
269
337
  typeof ActorDirectory === "undefined" ? Object : ActorDirectory,
270
- typeof AgentPricingStore === "undefined" ? Object : AgentPricingStore
338
+ typeof AgentPricingStore === "undefined" ? Object : AgentPricingStore,
339
+ typeof AgentApprovalPort === "undefined" ? Object : AgentApprovalPort
271
340
  ])
272
341
  ], DashboardService);
273
342
 
@@ -317,8 +386,12 @@ var AgentApiController = class {
317
386
  __name(this, "AgentApiController");
318
387
  }
319
388
  dashboard;
320
- constructor(dashboard) {
389
+ approvalActorRef;
390
+ actorResolver;
391
+ constructor(dashboard, approvalActorRef, actorResolver) {
321
392
  this.dashboard = dashboard;
393
+ this.approvalActorRef = approvalActorRef;
394
+ this.actorResolver = actorResolver;
322
395
  }
323
396
  /** `{ byModel, byActor, trend }` for a day range (defaults to the last 30 days). */
324
397
  spend(from, to) {
@@ -340,6 +413,42 @@ var AgentApiController = class {
340
413
  toolCalls(limit) {
341
414
  return this.dashboard.recentToolCalls(parseLimit(limit, 50));
342
415
  }
416
+ /** Tool calls sitting `pending_approval` (default 50, max 200), oldest first — the approvals inbox. */
417
+ approvals(limit) {
418
+ return this.dashboard.pendingApprovals(parseLimit(limit, 50));
419
+ }
420
+ /**
421
+ * Decide a pending HITL tool call. Body `{ approved: boolean; reason?: string }`. 501s (via
422
+ * `DashboardService.decideApproval`) when no `AGENT_APPROVAL_PORT` is bound. `executedByRef`
423
+ * comes from {@link deciderRef} run against the live request.
424
+ */
425
+ async decideApproval(toolCallId, body, req) {
426
+ await this.dashboard.decideApproval(toolCallId, body, await this.deciderRef(req));
427
+ }
428
+ /**
429
+ * WHO decided, as an opaque ref: an explicit `approvalActorRef` override wins outright (no
430
+ * resolver fallback, even when it returns `undefined`); otherwise the AgentModule-configured
431
+ * actor resolver — the same identity seam chat requests use. A resolver that throws is an
432
+ * unauthenticated/unreadable request, not an error to surface: the decision itself was already
433
+ * authorized by the dashboard's guards, so the ref is simply omitted.
434
+ */
435
+ async deciderRef(req) {
436
+ if (this.approvalActorRef !== void 0) {
437
+ return this.approvalActorRef(req);
438
+ }
439
+ if (this.actorResolver === void 0) {
440
+ return void 0;
441
+ }
442
+ try {
443
+ return (await this.actorResolver.resolve(req)).id;
444
+ } catch {
445
+ return void 0;
446
+ }
447
+ }
448
+ /** Per-tool call/failure/rejection/latency rollup for a day range (defaults to the last 30 days). */
449
+ tools(from, to) {
450
+ return this.dashboard.toolStats(resolveRange(from, to));
451
+ }
343
452
  /** Most recent threads (default 50, max 200) with rolled-up counts. */
344
453
  threads(limit) {
345
454
  return this.dashboard.recentThreads(parseLimit(limit, 50));
@@ -365,9 +474,9 @@ var AgentApiController = class {
365
474
  }
366
475
  };
367
476
  _ts_decorate2([
368
- (0, import_common3.Get)("spend"),
369
- _ts_param2(0, (0, import_common3.Query)("from")),
370
- _ts_param2(1, (0, import_common3.Query)("to")),
477
+ (0, import_common4.Get)("spend"),
478
+ _ts_param2(0, (0, import_common4.Query)("from")),
479
+ _ts_param2(1, (0, import_common4.Query)("to")),
371
480
  _ts_metadata2("design:type", Function),
372
481
  _ts_metadata2("design:paramtypes", [
373
482
  String,
@@ -376,10 +485,10 @@ _ts_decorate2([
376
485
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
377
486
  ], AgentApiController.prototype, "spend", null);
378
487
  _ts_decorate2([
379
- (0, import_common3.Get)("top-threads"),
380
- _ts_param2(0, (0, import_common3.Query)("from")),
381
- _ts_param2(1, (0, import_common3.Query)("to")),
382
- _ts_param2(2, (0, import_common3.Query)("limit")),
488
+ (0, import_common4.Get)("top-threads"),
489
+ _ts_param2(0, (0, import_common4.Query)("from")),
490
+ _ts_param2(1, (0, import_common4.Query)("to")),
491
+ _ts_param2(2, (0, import_common4.Query)("limit")),
383
492
  _ts_metadata2("design:type", Function),
384
493
  _ts_metadata2("design:paramtypes", [
385
494
  String,
@@ -389,9 +498,9 @@ _ts_decorate2([
389
498
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
390
499
  ], AgentApiController.prototype, "topThreads", null);
391
500
  _ts_decorate2([
392
- (0, import_common3.Get)("reliability"),
393
- _ts_param2(0, (0, import_common3.Query)("from")),
394
- _ts_param2(1, (0, import_common3.Query)("to")),
501
+ (0, import_common4.Get)("reliability"),
502
+ _ts_param2(0, (0, import_common4.Query)("from")),
503
+ _ts_param2(1, (0, import_common4.Query)("to")),
395
504
  _ts_metadata2("design:type", Function),
396
505
  _ts_metadata2("design:paramtypes", [
397
506
  String,
@@ -400,8 +509,8 @@ _ts_decorate2([
400
509
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
401
510
  ], AgentApiController.prototype, "reliability", null);
402
511
  _ts_decorate2([
403
- (0, import_common3.Get)("runs"),
404
- _ts_param2(0, (0, import_common3.Query)("limit")),
512
+ (0, import_common4.Get)("runs"),
513
+ _ts_param2(0, (0, import_common4.Query)("limit")),
405
514
  _ts_metadata2("design:type", Function),
406
515
  _ts_metadata2("design:paramtypes", [
407
516
  String
@@ -409,8 +518,8 @@ _ts_decorate2([
409
518
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
410
519
  ], AgentApiController.prototype, "runs", null);
411
520
  _ts_decorate2([
412
- (0, import_common3.Get)("tool-calls"),
413
- _ts_param2(0, (0, import_common3.Query)("limit")),
521
+ (0, import_common4.Get)("tool-calls"),
522
+ _ts_param2(0, (0, import_common4.Query)("limit")),
414
523
  _ts_metadata2("design:type", Function),
415
524
  _ts_metadata2("design:paramtypes", [
416
525
  String
@@ -418,8 +527,42 @@ _ts_decorate2([
418
527
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
419
528
  ], AgentApiController.prototype, "toolCalls", null);
420
529
  _ts_decorate2([
421
- (0, import_common3.Get)("threads"),
422
- _ts_param2(0, (0, import_common3.Query)("limit")),
530
+ (0, import_common4.Get)("approvals"),
531
+ _ts_param2(0, (0, import_common4.Query)("limit")),
532
+ _ts_metadata2("design:type", Function),
533
+ _ts_metadata2("design:paramtypes", [
534
+ String
535
+ ]),
536
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
537
+ ], AgentApiController.prototype, "approvals", null);
538
+ _ts_decorate2([
539
+ (0, import_common4.Post)("approvals/:toolCallId"),
540
+ (0, import_common4.HttpCode)(204),
541
+ _ts_param2(0, (0, import_common4.Param)("toolCallId")),
542
+ _ts_param2(1, (0, import_common4.Body)()),
543
+ _ts_param2(2, (0, import_common4.Req)()),
544
+ _ts_metadata2("design:type", Function),
545
+ _ts_metadata2("design:paramtypes", [
546
+ String,
547
+ Object,
548
+ Object
549
+ ]),
550
+ _ts_metadata2("design:returntype", Promise)
551
+ ], AgentApiController.prototype, "decideApproval", null);
552
+ _ts_decorate2([
553
+ (0, import_common4.Get)("tools"),
554
+ _ts_param2(0, (0, import_common4.Query)("from")),
555
+ _ts_param2(1, (0, import_common4.Query)("to")),
556
+ _ts_metadata2("design:type", Function),
557
+ _ts_metadata2("design:paramtypes", [
558
+ String,
559
+ String
560
+ ]),
561
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
562
+ ], AgentApiController.prototype, "tools", null);
563
+ _ts_decorate2([
564
+ (0, import_common4.Get)("threads"),
565
+ _ts_param2(0, (0, import_common4.Query)("limit")),
423
566
  _ts_metadata2("design:type", Function),
424
567
  _ts_metadata2("design:paramtypes", [
425
568
  String
@@ -427,14 +570,14 @@ _ts_decorate2([
427
570
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
428
571
  ], AgentApiController.prototype, "threads", null);
429
572
  _ts_decorate2([
430
- (0, import_common3.Get)("pricing"),
573
+ (0, import_common4.Get)("pricing"),
431
574
  _ts_metadata2("design:type", Function),
432
575
  _ts_metadata2("design:paramtypes", []),
433
576
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
434
577
  ], AgentApiController.prototype, "listPrices", null);
435
578
  _ts_decorate2([
436
- (0, import_common3.Post)("pricing"),
437
- _ts_param2(0, (0, import_common3.Body)()),
579
+ (0, import_common4.Post)("pricing"),
580
+ _ts_param2(0, (0, import_common4.Body)()),
438
581
  _ts_metadata2("design:type", Function),
439
582
  _ts_metadata2("design:paramtypes", [
440
583
  Object
@@ -442,16 +585,21 @@ _ts_decorate2([
442
585
  _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
443
586
  ], AgentApiController.prototype, "upsertPrice", null);
444
587
  _ts_decorate2([
445
- (0, import_common3.Sse)("stream"),
588
+ (0, import_common4.Sse)("stream"),
446
589
  _ts_metadata2("design:type", Function),
447
590
  _ts_metadata2("design:paramtypes", []),
448
591
  _ts_metadata2("design:returntype", typeof Observable === "undefined" ? Object : Observable)
449
592
  ], AgentApiController.prototype, "stream", null);
450
593
  AgentApiController = _ts_decorate2([
451
- (0, import_common3.Controller)(),
594
+ (0, import_common4.Controller)(),
595
+ _ts_param2(1, (0, import_common4.Inject)(DASHBOARD_APPROVAL_ACTOR_REF)),
596
+ _ts_param2(2, (0, import_common4.Optional)()),
597
+ _ts_param2(2, (0, import_common4.Inject)(AGENT_ACTOR_RESOLVER)),
452
598
  _ts_metadata2("design:type", Function),
453
599
  _ts_metadata2("design:paramtypes", [
454
- typeof DashboardService === "undefined" ? Object : DashboardService
600
+ typeof DashboardService === "undefined" ? Object : DashboardService,
601
+ Object,
602
+ typeof ActorResolver === "undefined" ? Object : ActorResolver
455
603
  ])
456
604
  ], AgentApiController);
457
605
 
@@ -482,14 +630,14 @@ __name(agentDashboardMountPaths, "agentDashboardMountPaths");
482
630
 
483
631
  // src/server/agent-dashboard.module.ts
484
632
  var import_reflect_metadata = require("reflect-metadata");
485
- var import_common5 = require("@nestjs/common");
633
+ var import_common6 = require("@nestjs/common");
486
634
  var import_core = require("@nestjs/core");
487
635
 
488
636
  // src/server/agent-ui.controller.ts
489
637
  var import_node_fs = require("fs");
490
638
  var import_node_path = require("path");
491
639
  var import_node_url = require("url");
492
- var import_common4 = require("@nestjs/common");
640
+ var import_common5 = require("@nestjs/common");
493
641
  function _ts_decorate3(decorators, target, key, desc) {
494
642
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
495
643
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -534,10 +682,15 @@ var AgentUiController = class {
534
682
  }
535
683
  // index.html references hash-named bundles, so it MUST NOT be cached (stale bundle = the classic
536
684
  // "stuck loading after a deploy"). The hashed assets below are immutable.
537
- index() {
685
+ index(req, res) {
686
+ if (req.headers["x-inertia"] !== void 0) {
687
+ res.status(409);
688
+ res.setHeader("X-Inertia-Location", req.originalUrl);
689
+ return "";
690
+ }
538
691
  const indexPath = (0, import_node_path.join)(this.dir, "index.html");
539
692
  if (!(0, import_node_fs.existsSync)(indexPath)) {
540
- throw new import_common4.NotFoundException("Dashboard is not built. Run the package build.");
693
+ throw new import_common5.NotFoundException("Dashboard is not built. Run the package build.");
541
694
  }
542
695
  const html = (0, import_node_fs.readFileSync)(indexPath, "utf8").replaceAll(`="${BUILD_BASE}/`, `="${this.basePath}/`);
543
696
  const inject = `<script>window.__AGENT_BASE__='${this.basePath}';window.__AGENT_API__='${this.apiBasePath}';</script>`;
@@ -545,40 +698,47 @@ var AgentUiController = class {
545
698
  }
546
699
  asset(file) {
547
700
  const safe = (0, import_node_path.basename)(file);
548
- if (safe !== file) throw new import_common4.NotFoundException();
701
+ if (safe !== file) throw new import_common5.NotFoundException();
549
702
  const root = (0, import_node_path.resolve)(this.dir, "assets");
550
703
  const assetPath = (0, import_node_path.resolve)(root, safe);
551
704
  if (!assetPath.startsWith(root + import_node_path.sep) || !(0, import_node_fs.existsSync)(assetPath)) {
552
- throw new import_common4.NotFoundException();
705
+ throw new import_common5.NotFoundException();
553
706
  }
554
707
  const type = CONTENT_TYPES[(0, import_node_path.extname)(safe)] ?? "application/octet-stream";
555
- return new import_common4.StreamableFile((0, import_node_fs.readFileSync)(assetPath), {
708
+ return new import_common5.StreamableFile((0, import_node_fs.readFileSync)(assetPath), {
556
709
  type
557
710
  });
558
711
  }
559
712
  };
560
713
  _ts_decorate3([
561
- (0, import_common4.Get)(),
562
- (0, import_common4.Header)("Content-Type", "text/html; charset=utf-8"),
563
- (0, import_common4.Header)("Cache-Control", "no-store, must-revalidate"),
714
+ (0, import_common5.Get)(),
715
+ (0, import_common5.Header)("Content-Type", "text/html; charset=utf-8"),
716
+ (0, import_common5.Header)("Cache-Control", "no-store, must-revalidate"),
717
+ _ts_param3(0, (0, import_common5.Req)()),
718
+ _ts_param3(1, (0, import_common5.Res)({
719
+ passthrough: true
720
+ })),
564
721
  _ts_metadata3("design:type", Function),
565
- _ts_metadata3("design:paramtypes", []),
722
+ _ts_metadata3("design:paramtypes", [
723
+ typeof UiPageRequest === "undefined" ? Object : UiPageRequest,
724
+ typeof UiPageResponse === "undefined" ? Object : UiPageResponse
725
+ ]),
566
726
  _ts_metadata3("design:returntype", String)
567
727
  ], AgentUiController.prototype, "index", null);
568
728
  _ts_decorate3([
569
- (0, import_common4.Get)("assets/:file"),
570
- (0, import_common4.Header)("Cache-Control", "public, max-age=31536000, immutable"),
571
- _ts_param3(0, (0, import_common4.Param)("file")),
729
+ (0, import_common5.Get)("assets/:file"),
730
+ (0, import_common5.Header)("Cache-Control", "public, max-age=31536000, immutable"),
731
+ _ts_param3(0, (0, import_common5.Param)("file")),
572
732
  _ts_metadata3("design:type", Function),
573
733
  _ts_metadata3("design:paramtypes", [
574
734
  String
575
735
  ]),
576
- _ts_metadata3("design:returntype", typeof import_common4.StreamableFile === "undefined" ? Object : import_common4.StreamableFile)
736
+ _ts_metadata3("design:returntype", typeof import_common5.StreamableFile === "undefined" ? Object : import_common5.StreamableFile)
577
737
  ], AgentUiController.prototype, "asset", null);
578
738
  AgentUiController = _ts_decorate3([
579
- (0, import_common4.Controller)(),
580
- _ts_param3(0, (0, import_common4.Inject)(DASHBOARD_BASE_PATH)),
581
- _ts_param3(1, (0, import_common4.Inject)(DASHBOARD_API_PATH)),
739
+ (0, import_common5.Controller)(),
740
+ _ts_param3(0, (0, import_common5.Inject)(DASHBOARD_BASE_PATH)),
741
+ _ts_param3(1, (0, import_common5.Inject)(DASHBOARD_API_PATH)),
582
742
  _ts_metadata3("design:type", Function),
583
743
  _ts_metadata3("design:paramtypes", [
584
744
  String,
@@ -620,7 +780,13 @@ var AgentApiModule = class _AgentApiModule {
620
780
  ],
621
781
  providers: [
622
782
  DashboardService,
623
- ...options.guards ?? []
783
+ ...options.guards ?? [],
784
+ // `useValue` even when `options.approvalActorRef` is `undefined` — AgentApiController
785
+ // injects this WITHOUT `@Optional()` (same pattern as `AGENT_QUOTA_STORE`'s factory).
786
+ {
787
+ provide: DASHBOARD_APPROVAL_ACTOR_REF,
788
+ useValue: options.approvalActorRef
789
+ }
624
790
  ],
625
791
  exports: [
626
792
  DashboardService
@@ -629,7 +795,7 @@ var AgentApiModule = class _AgentApiModule {
629
795
  }
630
796
  };
631
797
  AgentApiModule = _ts_decorate4([
632
- (0, import_common5.Module)({})
798
+ (0, import_common6.Module)({})
633
799
  ], AgentApiModule);
634
800
  var AgentDashboardModule = class _AgentDashboardModule {
635
801
  static {
@@ -652,6 +818,9 @@ var AgentDashboardModule = class _AgentDashboardModule {
652
818
  } : {},
653
819
  ...options.guards ? {
654
820
  guards: options.guards
821
+ } : {},
822
+ ...options.approvalActorRef ? {
823
+ approvalActorRef: options.approvalActorRef
655
824
  } : {}
656
825
  }),
657
826
  import_core.RouterModule.register([
@@ -688,11 +857,13 @@ var AgentDashboardModule = class _AgentDashboardModule {
688
857
  }
689
858
  };
690
859
  AgentDashboardModule = _ts_decorate4([
691
- (0, import_common5.Module)({})
860
+ (0, import_common6.Module)({})
692
861
  ], AgentDashboardModule);
693
862
  // Annotate the CommonJS export names for ESM import in node:
694
863
  0 && (module.exports = {
695
864
  AGENT_ACTOR_DIRECTORY,
865
+ AGENT_ACTOR_RESOLVER,
866
+ AGENT_APPROVAL_PORT,
696
867
  AGENT_GOVERNANCE_QUERIES,
697
868
  AGENT_PRICING_STORE,
698
869
  AgentApiController,
@@ -700,6 +871,7 @@ AgentDashboardModule = _ts_decorate4([
700
871
  AgentDashboardModule,
701
872
  AgentUiController,
702
873
  DASHBOARD_API_PATH,
874
+ DASHBOARD_APPROVAL_ACTOR_REF,
703
875
  DASHBOARD_BASE_PATH,
704
876
  DashboardService,
705
877
  agentDashboardMountPaths,