@dudousxd/nestjs-agent-dashboard 0.17.0 → 0.19.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.
Files changed (36) hide show
  1. package/README.md +28 -132
  2. package/dist/client/agent-client.d.ts +47 -1
  3. package/dist/client/agent-client.d.ts.map +1 -1
  4. package/dist/client/agent-client.js +0 -4
  5. package/dist/client/agent-client.js.map +1 -1
  6. package/dist/server/index.cjs +286 -1373
  7. package/dist/server/index.cjs.map +1 -1
  8. package/dist/server/index.d.cts +37 -287
  9. package/dist/server/index.d.ts +37 -287
  10. package/dist/server/index.js +239 -1323
  11. package/dist/server/index.js.map +1 -1
  12. package/dist/spa/assets/index-B1znMy6W.css +1 -0
  13. package/dist/spa/assets/{index-DKPuTuEx.js → index-DzukxAmy.js} +1 -1
  14. package/dist/spa/assets/index-eW1zMwDF.js +25 -0
  15. package/dist/spa/assets/{preview-BgeSHiwH.js → preview-Ch59R-LE.js} +1 -1
  16. package/dist/spa/index.html +3 -3
  17. package/dist/spa/preview.html +3 -3
  18. package/package.json +6 -20
  19. package/dist/client/console-session.d.ts +0 -63
  20. package/dist/client/console-session.d.ts.map +0 -1
  21. package/dist/client/console-session.js +0 -107
  22. package/dist/client/console-session.js.map +0 -1
  23. package/dist/react/index.d.ts +0 -4
  24. package/dist/react/index.d.ts.map +0 -1
  25. package/dist/react/index.js +0 -14
  26. package/dist/react/index.js.map +0 -1
  27. package/dist/react/open-console-button.d.ts +0 -26
  28. package/dist/react/open-console-button.d.ts.map +0 -1
  29. package/dist/react/open-console-button.js +0 -29
  30. package/dist/react/open-console-button.js.map +0 -1
  31. package/dist/react/use-open-console.d.ts +0 -34
  32. package/dist/react/use-open-console.d.ts.map +0 -1
  33. package/dist/react/use-open-console.js +0 -70
  34. package/dist/react/use-open-console.js.map +0 -1
  35. package/dist/spa/assets/index-B2rAzTPe.js +0 -25
  36. package/dist/spa/assets/index-P6B28Wyx.css +0 -1
@@ -29,430 +29,39 @@ __export(index_exports, {
29
29
  AGENT_PRICING_STORE: () => AGENT_PRICING_STORE,
30
30
  AgentApiController: () => AgentApiController,
31
31
  AgentApiModule: () => AgentApiModule,
32
- AgentDashboardAuthController: () => AgentDashboardAuthController,
33
32
  AgentDashboardModule: () => AgentDashboardModule,
34
33
  AgentUiController: () => AgentUiController,
35
34
  DASHBOARD_API_PATH: () => DASHBOARD_API_PATH,
36
35
  DASHBOARD_APPROVAL_ACTOR_REF: () => DASHBOARD_APPROVAL_ACTOR_REF,
37
- DASHBOARD_AUTH: () => DASHBOARD_AUTH,
38
36
  DASHBOARD_BASE_PATH: () => DASHBOARD_BASE_PATH,
39
37
  DashboardService: () => DashboardService,
40
38
  agentDashboardMountPaths: () => agentDashboardMountPaths,
41
- parsePriceInput: () => parsePriceInput,
42
- resolveDashboardAuth: () => resolveDashboardAuth
39
+ parsePriceInput: () => parsePriceInput
43
40
  });
44
41
  module.exports = __toCommonJS(index_exports);
45
42
 
46
43
  // src/server/agent-api.controller.ts
47
- var import_common6 = require("@nestjs/common");
48
-
49
- // src/server/auth/dashboard-auth.guard.ts
50
- var import_common = require("@nestjs/common");
51
-
52
- // src/server/tokens.ts
53
- var AGENT_GOVERNANCE_QUERIES = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:governance-queries");
54
- var AGENT_ACTOR_DIRECTORY = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:actor-directory");
55
- var AGENT_PRICING_STORE = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:pricing-store");
56
- var AGENT_APPROVAL_PORT = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:approval-port");
57
- var AGENT_ACTOR_RESOLVER = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:actor-resolver");
58
- var DASHBOARD_BASE_PATH = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:base-path");
59
- var DASHBOARD_API_PATH = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:api-path");
60
- var DASHBOARD_APPROVAL_ACTOR_REF = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:approval-actor-ref");
61
- var DASHBOARD_AUTH = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:dashboard-auth");
62
-
63
- // src/server/auth/cookie-header.ts
64
- function parseCookieHeader(header) {
65
- const cookies = {};
66
- if (typeof header !== "string" || header === "") return cookies;
67
- for (const segment of header.split(";")) {
68
- const eq = segment.indexOf("=");
69
- if (eq <= 0) continue;
70
- const name = segment.slice(0, eq).trim();
71
- if (name === "") continue;
72
- let rawValue = segment.slice(eq + 1).trim();
73
- if (rawValue.length >= 2 && rawValue.startsWith('"') && rawValue.endsWith('"')) {
74
- rawValue = rawValue.slice(1, -1);
75
- }
76
- if (name in cookies) continue;
77
- try {
78
- cookies[name] = decodeURIComponent(rawValue);
79
- } catch {
80
- cookies[name] = rawValue;
81
- }
82
- }
83
- return cookies;
84
- }
85
- __name(parseCookieHeader, "parseCookieHeader");
86
- function serializeSetCookie(name, value, options) {
87
- const parts = [
88
- `${name}=${options.clear ? "" : encodeURIComponent(value)}`
89
- ];
90
- parts.push(`Path=${options.path}`);
91
- parts.push("HttpOnly");
92
- parts.push("SameSite=Lax");
93
- if (options.secure) parts.push("Secure");
94
- if (options.clear) {
95
- parts.push("Max-Age=0");
96
- parts.push("Expires=Thu, 01 Jan 1970 00:00:00 GMT");
97
- } else {
98
- parts.push(`Max-Age=${options.maxAgeSeconds}`);
99
- }
100
- return parts.join("; ");
101
- }
102
- __name(serializeSetCookie, "serializeSetCookie");
103
-
104
- // src/server/auth/http-request.ts
105
- function isRecord(value) {
106
- return typeof value === "object" && value !== null;
107
- }
108
- __name(isRecord, "isRecord");
109
- function readHeaders(request) {
110
- if (!isRecord(request)) return {};
111
- const headers = request.headers;
112
- return isRecord(headers) ? headers : {};
113
- }
114
- __name(readHeaders, "readHeaders");
115
- function headerToString(value) {
116
- if (typeof value === "string") return value;
117
- if (Array.isArray(value) && value.every((part) => typeof part === "string")) {
118
- return value.join(",");
119
- }
120
- return void 0;
121
- }
122
- __name(headerToString, "headerToString");
123
- function readCookieHeader(request) {
124
- return headerToString(readHeaders(request).cookie);
125
- }
126
- __name(readCookieHeader, "readCookieHeader");
127
- function isHttpsRequest(request) {
128
- if (isRecord(request) && request.protocol === "https") return true;
129
- const forwarded = headerToString(readHeaders(request)["x-forwarded-proto"]);
130
- if (forwarded === void 0) return false;
131
- return forwarded.split(",").map((proto) => proto.trim().toLowerCase()).includes("https");
132
- }
133
- __name(isHttpsRequest, "isHttpsRequest");
134
- function readOriginalUrl(request) {
135
- if (!isRecord(request)) return "/";
136
- const originalUrl = request.originalUrl;
137
- if (typeof originalUrl === "string" && originalUrl !== "") return originalUrl;
138
- const url = request.url;
139
- return typeof url === "string" && url !== "" ? url : "/";
140
- }
141
- __name(readOriginalUrl, "readOriginalUrl");
142
- function attachSession(request, session) {
143
- if (!isRecord(request)) return;
144
- const target = request;
145
- target.dashboardSession = session;
146
- }
147
- __name(attachSession, "attachSession");
148
-
149
- // src/server/auth/response.ts
150
- function isRecord2(value) {
151
- return typeof value === "object" && value !== null;
152
- }
153
- __name(isRecord2, "isRecord");
154
- function isHeaderCapableResponse(value) {
155
- return isRecord2(value) && typeof value.getHeader === "function" && typeof value.setHeader === "function";
156
- }
157
- __name(isHeaderCapableResponse, "isHeaderCapableResponse");
158
- function resolveHeaderCapableResponse(response) {
159
- if (isHeaderCapableResponse(response)) return response;
160
- if (isRecord2(response) && isHeaderCapableResponse(response.raw)) return response.raw;
161
- return null;
162
- }
163
- __name(resolveHeaderCapableResponse, "resolveHeaderCapableResponse");
164
- function existingSetCookies(response) {
165
- const current = response.getHeader("set-cookie");
166
- if (Array.isArray(current)) return current;
167
- if (typeof current === "string") return [
168
- current
169
- ];
170
- return [];
171
- }
172
- __name(existingSetCookies, "existingSetCookies");
173
- function appendSetCookie(response, cookie) {
174
- const raw = resolveHeaderCapableResponse(response);
175
- if (!raw) return;
176
- raw.setHeader("set-cookie", [
177
- ...existingSetCookies(raw),
178
- cookie
179
- ]);
180
- }
181
- __name(appendSetCookie, "appendSetCookie");
182
- function isRawNodeResponse(value) {
183
- return isRecord2(value) && typeof value.getHeader === "function" && typeof value.setHeader === "function" && typeof value.end === "function";
184
- }
185
- __name(isRawNodeResponse, "isRawNodeResponse");
186
- function resolveRawResponse(response) {
187
- if (isRawNodeResponse(response)) return response;
188
- if (isRecord2(response) && isRawNodeResponse(response.raw)) return response.raw;
189
- return null;
190
- }
191
- __name(resolveRawResponse, "resolveRawResponse");
192
- function responseAlreadyWritten(response) {
193
- const raw = resolveRawResponse(response);
194
- return raw?.headersSent === true;
195
- }
196
- __name(responseAlreadyWritten, "responseAlreadyWritten");
197
- function sendHtml(response, status, html) {
198
- const raw = resolveRawResponse(response);
199
- if (!raw) return;
200
- raw.statusCode = status;
201
- raw.setHeader("content-type", "text/html; charset=utf-8");
202
- raw.setHeader("cache-control", "no-store, must-revalidate");
203
- raw.end(html);
204
- }
205
- __name(sendHtml, "sendHtml");
206
- function sendRedirect(response, status, location) {
207
- const raw = resolveRawResponse(response);
208
- if (!raw) return;
209
- raw.statusCode = status;
210
- raw.setHeader("location", location);
211
- raw.end();
212
- }
213
- __name(sendRedirect, "sendRedirect");
214
-
215
- // src/server/auth/session-cookie.ts
216
- var import_node_crypto = require("crypto");
217
- var EXP_GRACE_MS = 3e4;
218
- function base64urlEncode(value) {
219
- return Buffer.from(value, "utf8").toString("base64url");
220
- }
221
- __name(base64urlEncode, "base64urlEncode");
222
- function base64urlDecode(value) {
223
- return Buffer.from(value, "base64url").toString("utf8");
224
- }
225
- __name(base64urlDecode, "base64urlDecode");
226
- function hmac(secret, payload) {
227
- return (0, import_node_crypto.createHmac)("sha256", secret).update(payload).digest("base64url");
228
- }
229
- __name(hmac, "hmac");
230
- function signSessionCookie(user, options) {
231
- const issuedAt = options.now ?? Date.now();
232
- const session = {
233
- sub: user.id,
234
- ...user.name !== void 0 ? {
235
- name: user.name
236
- } : {},
237
- roles: user.roles ?? [],
238
- iat: issuedAt,
239
- exp: issuedAt + options.ttlMs
240
- };
241
- const encodedPayload = base64urlEncode(JSON.stringify(session));
242
- const signature = hmac(options.secret, encodedPayload);
243
- return `${encodedPayload}.${signature}`;
244
- }
245
- __name(signSessionCookie, "signSessionCookie");
246
- function isSessionPayload(value) {
247
- if (typeof value !== "object" || value === null) return false;
248
- const record = {
249
- ...value
250
- };
251
- if (typeof record.sub !== "string") return false;
252
- if (record.name !== void 0 && typeof record.name !== "string") return false;
253
- if (!Array.isArray(record.roles)) return false;
254
- if (!record.roles.every((role) => typeof role === "string")) return false;
255
- if (typeof record.iat !== "number" || !Number.isFinite(record.iat)) return false;
256
- if (typeof record.exp !== "number" || !Number.isFinite(record.exp)) return false;
257
- return true;
258
- }
259
- __name(isSessionPayload, "isSessionPayload");
260
- function verifySessionCookie(value, options) {
261
- try {
262
- const dot = value.indexOf(".");
263
- if (dot <= 0 || dot === value.length - 1) return null;
264
- const encodedPayload = value.slice(0, dot);
265
- const providedSignature = value.slice(dot + 1);
266
- const expectedSignature = hmac(options.secret, encodedPayload);
267
- const provided = Buffer.from(providedSignature, "base64url");
268
- const expected = Buffer.from(expectedSignature, "base64url");
269
- if (provided.length !== expected.length) return null;
270
- if (!(0, import_node_crypto.timingSafeEqual)(provided, expected)) return null;
271
- const decoded = JSON.parse(base64urlDecode(encodedPayload));
272
- if (!isSessionPayload(decoded)) return null;
273
- const now = options.now ?? Date.now();
274
- if (now > decoded.exp + EXP_GRACE_MS) return null;
275
- const session = {
276
- sub: decoded.sub,
277
- ...decoded.name !== void 0 ? {
278
- name: decoded.name
279
- } : {},
280
- roles: decoded.roles,
281
- iat: decoded.iat,
282
- exp: decoded.exp
283
- };
284
- return session;
285
- } catch {
286
- return null;
287
- }
288
- }
289
- __name(verifySessionCookie, "verifySessionCookie");
290
-
291
- // src/server/auth/session-cookie-io.ts
292
- var SESSION_COOKIE_NAME = "agent_dashboard_session";
293
- var COOKIE_PATH = "/";
294
- function issueSessionCookie(user, context) {
295
- const value = signSessionCookie(user, {
296
- secret: context.auth.secret,
297
- ttlMs: context.auth.ttlMs,
298
- ...context.now !== void 0 ? {
299
- now: context.now
300
- } : {}
301
- });
302
- const cookie = serializeSetCookie(SESSION_COOKIE_NAME, value, {
303
- path: COOKIE_PATH,
304
- maxAgeSeconds: Math.floor(context.auth.ttlMs / 1e3),
305
- secure: isHttpsRequest(context.request)
306
- });
307
- appendSetCookie(context.response, cookie);
308
- }
309
- __name(issueSessionCookie, "issueSessionCookie");
310
- function clearSessionCookie(context) {
311
- const cookie = serializeSetCookie(SESSION_COOKIE_NAME, "", {
312
- path: COOKIE_PATH,
313
- maxAgeSeconds: 0,
314
- secure: isHttpsRequest(context.request),
315
- clear: true
316
- });
317
- appendSetCookie(context.response, cookie);
318
- }
319
- __name(clearSessionCookie, "clearSessionCookie");
320
- var inFlightRevalidations = /* @__PURE__ */ new Map();
321
- function revalidationKey(session) {
322
- return `${session.sub}:${session.iat}`;
323
- }
324
- __name(revalidationKey, "revalidationKey");
325
- function getOrStartRevalidation(auth, session, user) {
326
- const hook = auth.revalidate;
327
- if (!hook) return Promise.resolve(true);
328
- const key = revalidationKey(session);
329
- const inFlight = inFlightRevalidations.get(key);
330
- if (inFlight) return inFlight;
331
- const outcome = (async () => {
332
- try {
333
- return await hook(user);
334
- } catch {
335
- return false;
336
- }
337
- })().finally(() => {
338
- inFlightRevalidations.delete(key);
339
- });
340
- inFlightRevalidations.set(key, outcome);
341
- return outcome;
342
- }
343
- __name(getOrStartRevalidation, "getOrStartRevalidation");
344
- async function maybeRenewSession(auth, session, request, response, now = Date.now()) {
345
- if (now - session.iat <= auth.ttlMs / 2) return true;
346
- const user = {
347
- id: session.sub,
348
- ...session.name !== void 0 ? {
349
- name: session.name
350
- } : {},
351
- roles: session.roles
352
- };
353
- const allowed = await getOrStartRevalidation(auth, session, user);
354
- if (!allowed) {
355
- clearSessionCookie({
356
- request,
357
- response
358
- });
359
- return false;
360
- }
361
- issueSessionCookie(user, {
362
- auth,
363
- request,
364
- response,
365
- now
366
- });
367
- return true;
368
- }
369
- __name(maybeRenewSession, "maybeRenewSession");
370
-
371
- // src/server/auth/dashboard-auth.guard.ts
372
- function _ts_decorate(decorators, target, key, desc) {
373
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
374
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
375
- r = Reflect.decorate(decorators, target, key, desc);
376
- } else {
377
- for (var i = decorators.length - 1; i >= 0; i--) {
378
- if (d = decorators[i]) {
379
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
380
- }
381
- }
382
- }
383
- return c > 3 && r && Object.defineProperty(target, key, r), r;
384
- }
385
- __name(_ts_decorate, "_ts_decorate");
386
- function _ts_metadata(metadataKey, metadataValue) {
387
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
388
- return Reflect.metadata(metadataKey, metadataValue);
389
- }
390
- }
391
- __name(_ts_metadata, "_ts_metadata");
392
- function _ts_param(paramIndex, decorator) {
393
- return function(target, key) {
394
- decorator(target, key, paramIndex);
395
- };
396
- }
397
- __name(_ts_param, "_ts_param");
398
- var DashboardAuthGuard = class {
399
- static {
400
- __name(this, "DashboardAuthGuard");
401
- }
402
- auth;
403
- constructor(auth) {
404
- this.auth = auth;
405
- }
406
- async canActivate(context) {
407
- if (!this.auth) return true;
408
- const http = context.switchToHttp();
409
- const request = http.getRequest();
410
- const session = this.verifyRequestSession(request);
411
- if (!session) throw new import_common.UnauthorizedException();
412
- attachSession(request, session);
413
- if (!await maybeRenewSession(this.auth, session, request, http.getResponse())) {
414
- throw new import_common.UnauthorizedException();
415
- }
416
- return true;
417
- }
418
- verifyRequestSession(request) {
419
- const auth = this.auth;
420
- if (!auth) return null;
421
- const cookieValue = parseCookieHeader(readCookieHeader(request))[SESSION_COOKIE_NAME];
422
- if (cookieValue === void 0) return null;
423
- return verifySessionCookie(cookieValue, {
424
- secret: auth.secret
425
- });
426
- }
427
- };
428
- DashboardAuthGuard = _ts_decorate([
429
- (0, import_common.Injectable)(),
430
- _ts_param(0, (0, import_common.Optional)()),
431
- _ts_param(0, (0, import_common.Inject)(DASHBOARD_AUTH)),
432
- _ts_metadata("design:type", Function),
433
- _ts_metadata("design:paramtypes", [
434
- Object
435
- ])
436
- ], DashboardAuthGuard);
44
+ var import_nestjs_agent_core = require("@dudousxd/nestjs-agent-core");
45
+ var import_common5 = require("@nestjs/common");
437
46
 
438
47
  // src/server/dashboard.service.ts
439
48
  var import_node_diagnostics_channel = require("diagnostics_channel");
440
49
  var import_nestjs_diagnostics = require("@dudousxd/nestjs-diagnostics");
441
- var import_common4 = require("@nestjs/common");
50
+ var import_common3 = require("@nestjs/common");
442
51
  var import_rxjs = require("rxjs");
443
52
 
444
53
  // src/server/parse-approval-decision.ts
445
- var import_common2 = require("@nestjs/common");
54
+ var import_common = require("@nestjs/common");
446
55
  function parseApprovalDecision(body) {
447
56
  if (typeof body !== "object" || body === null) {
448
- throw new import_common2.BadRequestException("Expected a JSON object body.");
57
+ throw new import_common.BadRequestException("Expected a JSON object body.");
449
58
  }
450
59
  const { approved, reason } = body;
451
60
  if (typeof approved !== "boolean") {
452
- throw new import_common2.BadRequestException('"approved" must be a boolean.');
61
+ throw new import_common.BadRequestException('"approved" must be a boolean.');
453
62
  }
454
63
  if (reason !== void 0 && typeof reason !== "string") {
455
- throw new import_common2.BadRequestException('"reason" must be a string when present.');
64
+ throw new import_common.BadRequestException('"reason" must be a string when present.');
456
65
  }
457
66
  return {
458
67
  approved,
@@ -464,26 +73,26 @@ function parseApprovalDecision(body) {
464
73
  __name(parseApprovalDecision, "parseApprovalDecision");
465
74
 
466
75
  // src/server/parse-price-input.ts
467
- var import_common3 = require("@nestjs/common");
76
+ var import_common2 = require("@nestjs/common");
468
77
  function parsePriceInput(body) {
469
78
  if (typeof body !== "object" || body === null) {
470
- throw new import_common3.BadRequestException("Expected a JSON object body.");
79
+ throw new import_common2.BadRequestException("Expected a JSON object body.");
471
80
  }
472
81
  const { modelId, inputPricePer1m, outputPricePer1m, cacheWritePricePer1m, cacheReadPricePer1m } = body;
473
82
  if (typeof modelId !== "string" || modelId.trim().length === 0) {
474
- throw new import_common3.BadRequestException('"modelId" must be a non-empty string.');
83
+ throw new import_common2.BadRequestException('"modelId" must be a non-empty string.');
475
84
  }
476
85
  if (!isFiniteNonNegative(inputPricePer1m)) {
477
- throw new import_common3.BadRequestException('"inputPricePer1m" must be a non-negative number.');
86
+ throw new import_common2.BadRequestException('"inputPricePer1m" must be a non-negative number.');
478
87
  }
479
88
  if (!isFiniteNonNegative(outputPricePer1m)) {
480
- throw new import_common3.BadRequestException('"outputPricePer1m" must be a non-negative number.');
89
+ throw new import_common2.BadRequestException('"outputPricePer1m" must be a non-negative number.');
481
90
  }
482
91
  if (cacheWritePricePer1m !== void 0 && !isFiniteNonNegative(cacheWritePricePer1m)) {
483
- throw new import_common3.BadRequestException('"cacheWritePricePer1m" must be a non-negative number when present.');
92
+ throw new import_common2.BadRequestException('"cacheWritePricePer1m" must be a non-negative number when present.');
484
93
  }
485
94
  if (cacheReadPricePer1m !== void 0 && !isFiniteNonNegative(cacheReadPricePer1m)) {
486
- throw new import_common3.BadRequestException('"cacheReadPricePer1m" must be a non-negative number when present.');
95
+ throw new import_common2.BadRequestException('"cacheReadPricePer1m" must be a non-negative number when present.');
487
96
  }
488
97
  return {
489
98
  modelId,
@@ -503,8 +112,18 @@ function isFiniteNonNegative(value) {
503
112
  }
504
113
  __name(isFiniteNonNegative, "isFiniteNonNegative");
505
114
 
115
+ // src/server/tokens.ts
116
+ var AGENT_GOVERNANCE_QUERIES = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:governance-queries");
117
+ var AGENT_ACTOR_DIRECTORY = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:actor-directory");
118
+ var AGENT_PRICING_STORE = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:pricing-store");
119
+ var AGENT_APPROVAL_PORT = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:approval-port");
120
+ var AGENT_ACTOR_RESOLVER = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:actor-resolver");
121
+ var DASHBOARD_BASE_PATH = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:base-path");
122
+ var DASHBOARD_API_PATH = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:api-path");
123
+ var DASHBOARD_APPROVAL_ACTOR_REF = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:approval-actor-ref");
124
+
506
125
  // src/server/dashboard.service.ts
507
- function _ts_decorate2(decorators, target, key, desc) {
126
+ function _ts_decorate(decorators, target, key, desc) {
508
127
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
509
128
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
510
129
  r = Reflect.decorate(decorators, target, key, desc);
@@ -517,19 +136,19 @@ function _ts_decorate2(decorators, target, key, desc) {
517
136
  }
518
137
  return c > 3 && r && Object.defineProperty(target, key, r), r;
519
138
  }
520
- __name(_ts_decorate2, "_ts_decorate");
521
- function _ts_metadata2(metadataKey, metadataValue) {
139
+ __name(_ts_decorate, "_ts_decorate");
140
+ function _ts_metadata(metadataKey, metadataValue) {
522
141
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
523
142
  return Reflect.metadata(metadataKey, metadataValue);
524
143
  }
525
144
  }
526
- __name(_ts_metadata2, "_ts_metadata");
527
- function _ts_param2(paramIndex, decorator) {
145
+ __name(_ts_metadata, "_ts_metadata");
146
+ function _ts_param(paramIndex, decorator) {
528
147
  return function(target, key) {
529
148
  decorator(target, key, paramIndex);
530
149
  };
531
150
  }
532
- __name(_ts_param2, "_ts_param");
151
+ __name(_ts_param, "_ts_param");
533
152
  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.";
534
153
  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.";
535
154
  var GENUI_STATS_UNSUPPORTED_MESSAGE = "Generative UI telemetry is unavailable: the bound AGENT_GOVERNANCE_QUERIES store does not implement genuiStats. Use a store adapter that records generative-UI calls (recordGenuiCalls) to enable it.";
@@ -563,16 +182,20 @@ var DashboardService = class {
563
182
  }
564
183
  /** Spend/usage overview for a day range: by-model + by-actor spend and the daily trend, in parallel. */
565
184
  async spend(range) {
566
- const [byModel, byActorRaw, trend] = await Promise.all([
185
+ const [byModel, byActorRaw, trend, byFeature] = await Promise.all([
567
186
  this.queries.spendByModel(range),
568
187
  this.queries.spendByActor(range),
569
- this.queries.usageTrend(range)
188
+ this.queries.usageTrend(range),
189
+ this.queries.spendByFeature?.(range)
570
190
  ]);
571
191
  const byActor = await this.withActorLabels(byActorRaw);
572
192
  return {
573
193
  byModel,
574
194
  byActor,
575
- trend
195
+ trend,
196
+ ...byFeature !== void 0 ? {
197
+ byFeature
198
+ } : {}
576
199
  };
577
200
  }
578
201
  /** Top threads by cost for a day range (default 10, highest cost first). */
@@ -631,7 +254,7 @@ var DashboardService = class {
631
254
  async runDetail(runId) {
632
255
  const detail = await this.queries.runDetail(runId);
633
256
  if (detail === null) {
634
- throw new import_common4.NotFoundException(`No run "${runId}".`);
257
+ throw new import_common3.NotFoundException(`No run "${runId}".`);
635
258
  }
636
259
  const [thread] = await this.withActorLabels([
637
260
  detail.thread
@@ -648,7 +271,7 @@ var DashboardService = class {
648
271
  async threadDetail(query) {
649
272
  const detail = await this.queries.threadDetail(query);
650
273
  if (detail === null) {
651
- throw new import_common4.NotFoundException(`No thread "${query.threadId}".`);
274
+ throw new import_common3.NotFoundException(`No thread "${query.threadId}".`);
652
275
  }
653
276
  const [thread] = await this.withActorLabels([
654
277
  detail.thread
@@ -673,7 +296,7 @@ var DashboardService = class {
673
296
  */
674
297
  async genuiStats(range) {
675
298
  if (this.queries.genuiStats === void 0) {
676
- throw new import_common4.NotImplementedException(GENUI_STATS_UNSUPPORTED_MESSAGE);
299
+ throw new import_common3.NotImplementedException(GENUI_STATS_UNSUPPORTED_MESSAGE);
677
300
  }
678
301
  return this.queries.genuiStats(range);
679
302
  }
@@ -687,7 +310,7 @@ var DashboardService = class {
687
310
  */
688
311
  async decideApproval(toolCallId, body, executedByRef) {
689
312
  if (this.approvalPort === void 0) {
690
- throw new import_common4.NotImplementedException(APPROVAL_PORT_UNBOUND_MESSAGE);
313
+ throw new import_common3.NotImplementedException(APPROVAL_PORT_UNBOUND_MESSAGE);
691
314
  }
692
315
  const decision = parseApprovalDecision(body);
693
316
  const opts = executedByRef !== void 0 ? {
@@ -748,7 +371,7 @@ var DashboardService = class {
748
371
  /** Current price row per model, for the pricing tab. 501s when no `AGENT_PRICING_STORE` is bound. */
749
372
  async listPrices() {
750
373
  if (this.pricingStore === void 0) {
751
- throw new import_common4.NotImplementedException(PRICING_STORE_UNBOUND_MESSAGE);
374
+ throw new import_common3.NotImplementedException(PRICING_STORE_UNBOUND_MESSAGE);
752
375
  }
753
376
  return this.pricingStore.listCurrentPrices();
754
377
  }
@@ -759,7 +382,7 @@ var DashboardService = class {
759
382
  */
760
383
  async upsertPrice(body) {
761
384
  if (this.pricingStore === void 0) {
762
- throw new import_common4.NotImplementedException(PRICING_STORE_UNBOUND_MESSAGE);
385
+ throw new import_common3.NotImplementedException(PRICING_STORE_UNBOUND_MESSAGE);
763
386
  }
764
387
  await this.pricingStore.upsertModelPrice(parsePriceInput(body));
765
388
  }
@@ -794,17 +417,17 @@ var DashboardService = class {
794
417
  });
795
418
  }
796
419
  };
797
- DashboardService = _ts_decorate2([
798
- (0, import_common4.Injectable)(),
799
- _ts_param2(0, (0, import_common4.Inject)(AGENT_GOVERNANCE_QUERIES)),
800
- _ts_param2(1, (0, import_common4.Optional)()),
801
- _ts_param2(1, (0, import_common4.Inject)(AGENT_ACTOR_DIRECTORY)),
802
- _ts_param2(2, (0, import_common4.Optional)()),
803
- _ts_param2(2, (0, import_common4.Inject)(AGENT_PRICING_STORE)),
804
- _ts_param2(3, (0, import_common4.Optional)()),
805
- _ts_param2(3, (0, import_common4.Inject)(AGENT_APPROVAL_PORT)),
806
- _ts_metadata2("design:type", Function),
807
- _ts_metadata2("design:paramtypes", [
420
+ DashboardService = _ts_decorate([
421
+ (0, import_common3.Injectable)(),
422
+ _ts_param(0, (0, import_common3.Inject)(AGENT_GOVERNANCE_QUERIES)),
423
+ _ts_param(1, (0, import_common3.Optional)()),
424
+ _ts_param(1, (0, import_common3.Inject)(AGENT_ACTOR_DIRECTORY)),
425
+ _ts_param(2, (0, import_common3.Optional)()),
426
+ _ts_param(2, (0, import_common3.Inject)(AGENT_PRICING_STORE)),
427
+ _ts_param(3, (0, import_common3.Optional)()),
428
+ _ts_param(3, (0, import_common3.Inject)(AGENT_APPROVAL_PORT)),
429
+ _ts_metadata("design:type", Function),
430
+ _ts_metadata("design:paramtypes", [
808
431
  typeof AgentGovernanceQueries === "undefined" ? Object : AgentGovernanceQueries,
809
432
  typeof ActorDirectory === "undefined" ? Object : ActorDirectory,
810
433
  typeof AgentPricingStore === "undefined" ? Object : AgentPricingStore,
@@ -813,7 +436,7 @@ DashboardService = _ts_decorate2([
813
436
  ], DashboardService);
814
437
 
815
438
  // src/server/parse-page-query.ts
816
- var import_common5 = require("@nestjs/common");
439
+ var import_common4 = require("@nestjs/common");
817
440
  var ISO_DAY = /^\d{4}-\d{2}-\d{2}$/;
818
441
  function parsePageNumber(value) {
819
442
  const parsed = value === void 0 ? Number.NaN : Number.parseInt(value, 10);
@@ -824,7 +447,7 @@ __name(parsePageNumber, "parsePageNumber");
824
447
  function assertKnownFields(raw, allowed) {
825
448
  for (const field of Object.keys(raw)) {
826
449
  if (!allowed.includes(field)) {
827
- throw new import_common5.BadRequestException(`Unknown where field "${field}".`);
450
+ throw new import_common4.BadRequestException(`Unknown where field "${field}".`);
828
451
  }
829
452
  }
830
453
  }
@@ -833,7 +456,7 @@ function assertDayFields(raw, dayFields) {
833
456
  for (const field of dayFields) {
834
457
  const value = raw[field];
835
458
  if (value !== void 0 && !ISO_DAY.test(value)) {
836
- throw new import_common5.BadRequestException(`"where[${field}]" must be YYYY-MM-DD.`);
459
+ throw new import_common4.BadRequestException(`"where[${field}]" must be YYYY-MM-DD.`);
837
460
  }
838
461
  }
839
462
  }
@@ -972,7 +595,7 @@ function parseApprovalWhere(raw) {
972
595
  __name(parseApprovalWhere, "parseApprovalWhere");
973
596
 
974
597
  // src/server/agent-api.controller.ts
975
- function _ts_decorate3(decorators, target, key, desc) {
598
+ function _ts_decorate2(decorators, target, key, desc) {
976
599
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
977
600
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
978
601
  r = Reflect.decorate(decorators, target, key, desc);
@@ -985,19 +608,19 @@ function _ts_decorate3(decorators, target, key, desc) {
985
608
  }
986
609
  return c > 3 && r && Object.defineProperty(target, key, r), r;
987
610
  }
988
- __name(_ts_decorate3, "_ts_decorate");
989
- function _ts_metadata3(metadataKey, metadataValue) {
611
+ __name(_ts_decorate2, "_ts_decorate");
612
+ function _ts_metadata2(metadataKey, metadataValue) {
990
613
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
991
614
  return Reflect.metadata(metadataKey, metadataValue);
992
615
  }
993
616
  }
994
- __name(_ts_metadata3, "_ts_metadata");
995
- function _ts_param3(paramIndex, decorator) {
617
+ __name(_ts_metadata2, "_ts_metadata");
618
+ function _ts_param2(paramIndex, decorator) {
996
619
  return function(target, key) {
997
620
  decorator(target, key, paramIndex);
998
621
  };
999
622
  }
1000
- __name(_ts_param3, "_ts_param");
623
+ __name(_ts_param2, "_ts_param");
1001
624
  var DAY_MS = 864e5;
1002
625
  var ISO_DAY2 = /^\d{4}-\d{2}-\d{2}$/;
1003
626
  function utcDay(daysAgo) {
@@ -1215,620 +838,222 @@ var AgentApiController = class {
1215
838
  return this.dashboard.streamEvents();
1216
839
  }
1217
840
  };
1218
- _ts_decorate3([
1219
- (0, import_common6.Get)("spend"),
1220
- _ts_param3(0, (0, import_common6.Query)("from")),
1221
- _ts_param3(1, (0, import_common6.Query)("to")),
1222
- _ts_metadata3("design:type", Function),
1223
- _ts_metadata3("design:paramtypes", [
841
+ _ts_decorate2([
842
+ (0, import_common5.Get)("spend"),
843
+ _ts_param2(0, (0, import_common5.Query)("from")),
844
+ _ts_param2(1, (0, import_common5.Query)("to")),
845
+ _ts_metadata2("design:type", Function),
846
+ _ts_metadata2("design:paramtypes", [
1224
847
  String,
1225
848
  String
1226
849
  ]),
1227
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
850
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1228
851
  ], AgentApiController.prototype, "spend", null);
1229
- _ts_decorate3([
1230
- (0, import_common6.Get)("top-threads"),
1231
- _ts_param3(0, (0, import_common6.Query)("from")),
1232
- _ts_param3(1, (0, import_common6.Query)("to")),
1233
- _ts_param3(2, (0, import_common6.Query)("limit")),
1234
- _ts_metadata3("design:type", Function),
1235
- _ts_metadata3("design:paramtypes", [
852
+ _ts_decorate2([
853
+ (0, import_common5.Get)("top-threads"),
854
+ _ts_param2(0, (0, import_common5.Query)("from")),
855
+ _ts_param2(1, (0, import_common5.Query)("to")),
856
+ _ts_param2(2, (0, import_common5.Query)("limit")),
857
+ _ts_metadata2("design:type", Function),
858
+ _ts_metadata2("design:paramtypes", [
1236
859
  String,
1237
860
  String,
1238
861
  String
1239
862
  ]),
1240
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
863
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1241
864
  ], AgentApiController.prototype, "topThreads", null);
1242
- _ts_decorate3([
1243
- (0, import_common6.Get)("reliability"),
1244
- _ts_param3(0, (0, import_common6.Query)("from")),
1245
- _ts_param3(1, (0, import_common6.Query)("to")),
1246
- _ts_metadata3("design:type", Function),
1247
- _ts_metadata3("design:paramtypes", [
865
+ _ts_decorate2([
866
+ (0, import_common5.Get)("reliability"),
867
+ _ts_param2(0, (0, import_common5.Query)("from")),
868
+ _ts_param2(1, (0, import_common5.Query)("to")),
869
+ _ts_metadata2("design:type", Function),
870
+ _ts_metadata2("design:paramtypes", [
1248
871
  String,
1249
872
  String
1250
873
  ]),
1251
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
874
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1252
875
  ], AgentApiController.prototype, "reliability", null);
1253
- _ts_decorate3([
1254
- (0, import_common6.Get)("runs"),
1255
- _ts_param3(0, (0, import_common6.Query)("limit")),
1256
- _ts_metadata3("design:type", Function),
1257
- _ts_metadata3("design:paramtypes", [
876
+ _ts_decorate2([
877
+ (0, import_common5.Get)("runs"),
878
+ _ts_param2(0, (0, import_common5.Query)("limit")),
879
+ _ts_metadata2("design:type", Function),
880
+ _ts_metadata2("design:paramtypes", [
1258
881
  String
1259
882
  ]),
1260
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
883
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1261
884
  ], AgentApiController.prototype, "runs", null);
1262
- _ts_decorate3([
1263
- (0, import_common6.Get)("runs-page"),
1264
- _ts_param3(0, (0, import_common6.Query)("page")),
1265
- _ts_param3(1, (0, import_common6.Query)("limit")),
1266
- _ts_param3(2, (0, import_common6.Query)("where")),
1267
- _ts_metadata3("design:type", Function),
1268
- _ts_metadata3("design:paramtypes", [
885
+ _ts_decorate2([
886
+ (0, import_common5.Get)("runs-page"),
887
+ _ts_param2(0, (0, import_common5.Query)("page")),
888
+ _ts_param2(1, (0, import_common5.Query)("limit")),
889
+ _ts_param2(2, (0, import_common5.Query)("where")),
890
+ _ts_metadata2("design:type", Function),
891
+ _ts_metadata2("design:paramtypes", [
1269
892
  String,
1270
893
  String,
1271
894
  typeof Record === "undefined" ? Object : Record
1272
895
  ]),
1273
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
896
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1274
897
  ], AgentApiController.prototype, "runsPage", null);
1275
- _ts_decorate3([
1276
- (0, import_common6.Get)("runs/:runId"),
1277
- _ts_param3(0, (0, import_common6.Param)("runId")),
1278
- _ts_metadata3("design:type", Function),
1279
- _ts_metadata3("design:paramtypes", [
898
+ _ts_decorate2([
899
+ (0, import_common5.Get)("runs/:runId"),
900
+ _ts_param2(0, (0, import_common5.Param)("runId")),
901
+ _ts_metadata2("design:type", Function),
902
+ _ts_metadata2("design:paramtypes", [
1280
903
  String
1281
904
  ]),
1282
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
905
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1283
906
  ], AgentApiController.prototype, "runDetail", null);
1284
- _ts_decorate3([
1285
- (0, import_common6.Get)("tool-calls"),
1286
- _ts_param3(0, (0, import_common6.Query)("limit")),
1287
- _ts_metadata3("design:type", Function),
1288
- _ts_metadata3("design:paramtypes", [
907
+ _ts_decorate2([
908
+ (0, import_common5.Get)("tool-calls"),
909
+ _ts_param2(0, (0, import_common5.Query)("limit")),
910
+ _ts_metadata2("design:type", Function),
911
+ _ts_metadata2("design:paramtypes", [
1289
912
  String
1290
913
  ]),
1291
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
914
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1292
915
  ], AgentApiController.prototype, "toolCalls", null);
1293
- _ts_decorate3([
1294
- (0, import_common6.Get)("tool-calls-page"),
1295
- _ts_param3(0, (0, import_common6.Query)("page")),
1296
- _ts_param3(1, (0, import_common6.Query)("limit")),
1297
- _ts_param3(2, (0, import_common6.Query)("where")),
1298
- _ts_metadata3("design:type", Function),
1299
- _ts_metadata3("design:paramtypes", [
916
+ _ts_decorate2([
917
+ (0, import_common5.Get)("tool-calls-page"),
918
+ _ts_param2(0, (0, import_common5.Query)("page")),
919
+ _ts_param2(1, (0, import_common5.Query)("limit")),
920
+ _ts_param2(2, (0, import_common5.Query)("where")),
921
+ _ts_metadata2("design:type", Function),
922
+ _ts_metadata2("design:paramtypes", [
1300
923
  String,
1301
924
  String,
1302
925
  typeof Record === "undefined" ? Object : Record
1303
926
  ]),
1304
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
927
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1305
928
  ], AgentApiController.prototype, "toolCallsPage", null);
1306
- _ts_decorate3([
1307
- (0, import_common6.Get)("approvals"),
1308
- _ts_param3(0, (0, import_common6.Query)("limit")),
1309
- _ts_metadata3("design:type", Function),
1310
- _ts_metadata3("design:paramtypes", [
929
+ _ts_decorate2([
930
+ (0, import_common5.Get)("approvals"),
931
+ _ts_param2(0, (0, import_common5.Query)("limit")),
932
+ _ts_metadata2("design:type", Function),
933
+ _ts_metadata2("design:paramtypes", [
1311
934
  String
1312
935
  ]),
1313
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
936
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1314
937
  ], AgentApiController.prototype, "approvals", null);
1315
- _ts_decorate3([
1316
- (0, import_common6.Get)("approvals-page"),
1317
- _ts_param3(0, (0, import_common6.Query)("page")),
1318
- _ts_param3(1, (0, import_common6.Query)("limit")),
1319
- _ts_param3(2, (0, import_common6.Query)("where")),
1320
- _ts_metadata3("design:type", Function),
1321
- _ts_metadata3("design:paramtypes", [
938
+ _ts_decorate2([
939
+ (0, import_common5.Get)("approvals-page"),
940
+ _ts_param2(0, (0, import_common5.Query)("page")),
941
+ _ts_param2(1, (0, import_common5.Query)("limit")),
942
+ _ts_param2(2, (0, import_common5.Query)("where")),
943
+ _ts_metadata2("design:type", Function),
944
+ _ts_metadata2("design:paramtypes", [
1322
945
  String,
1323
946
  String,
1324
947
  typeof Record === "undefined" ? Object : Record
1325
948
  ]),
1326
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
949
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1327
950
  ], AgentApiController.prototype, "approvalsPage", null);
1328
- _ts_decorate3([
1329
- (0, import_common6.Post)("approvals/:toolCallId"),
1330
- (0, import_common6.HttpCode)(204),
1331
- _ts_param3(0, (0, import_common6.Param)("toolCallId")),
1332
- _ts_param3(1, (0, import_common6.Body)()),
1333
- _ts_param3(2, (0, import_common6.Req)()),
1334
- _ts_metadata3("design:type", Function),
1335
- _ts_metadata3("design:paramtypes", [
951
+ _ts_decorate2([
952
+ (0, import_common5.Post)("approvals/:toolCallId"),
953
+ (0, import_common5.HttpCode)(204),
954
+ _ts_param2(0, (0, import_common5.Param)("toolCallId")),
955
+ _ts_param2(1, (0, import_common5.Body)()),
956
+ _ts_param2(2, (0, import_common5.Req)()),
957
+ _ts_metadata2("design:type", Function),
958
+ _ts_metadata2("design:paramtypes", [
1336
959
  String,
1337
960
  Object,
1338
961
  Object
1339
962
  ]),
1340
- _ts_metadata3("design:returntype", Promise)
963
+ _ts_metadata2("design:returntype", Promise)
1341
964
  ], AgentApiController.prototype, "decideApproval", null);
1342
- _ts_decorate3([
1343
- (0, import_common6.Get)("tools"),
1344
- _ts_param3(0, (0, import_common6.Query)("from")),
1345
- _ts_param3(1, (0, import_common6.Query)("to")),
1346
- _ts_metadata3("design:type", Function),
1347
- _ts_metadata3("design:paramtypes", [
965
+ _ts_decorate2([
966
+ (0, import_common5.Get)("tools"),
967
+ _ts_param2(0, (0, import_common5.Query)("from")),
968
+ _ts_param2(1, (0, import_common5.Query)("to")),
969
+ _ts_metadata2("design:type", Function),
970
+ _ts_metadata2("design:paramtypes", [
1348
971
  String,
1349
972
  String
1350
973
  ]),
1351
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
974
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1352
975
  ], AgentApiController.prototype, "tools", null);
1353
- _ts_decorate3([
1354
- (0, import_common6.Get)("genui"),
1355
- _ts_param3(0, (0, import_common6.Query)("from")),
1356
- _ts_param3(1, (0, import_common6.Query)("to")),
1357
- _ts_metadata3("design:type", Function),
1358
- _ts_metadata3("design:paramtypes", [
976
+ _ts_decorate2([
977
+ (0, import_common5.Get)("genui"),
978
+ _ts_param2(0, (0, import_common5.Query)("from")),
979
+ _ts_param2(1, (0, import_common5.Query)("to")),
980
+ _ts_metadata2("design:type", Function),
981
+ _ts_metadata2("design:paramtypes", [
1359
982
  String,
1360
983
  String
1361
984
  ]),
1362
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
985
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1363
986
  ], AgentApiController.prototype, "genui", null);
1364
- _ts_decorate3([
1365
- (0, import_common6.Get)("threads"),
1366
- _ts_param3(0, (0, import_common6.Query)("limit")),
1367
- _ts_metadata3("design:type", Function),
1368
- _ts_metadata3("design:paramtypes", [
987
+ _ts_decorate2([
988
+ (0, import_common5.Get)("threads"),
989
+ _ts_param2(0, (0, import_common5.Query)("limit")),
990
+ _ts_metadata2("design:type", Function),
991
+ _ts_metadata2("design:paramtypes", [
1369
992
  String
1370
993
  ]),
1371
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
994
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1372
995
  ], AgentApiController.prototype, "threads", null);
1373
- _ts_decorate3([
1374
- (0, import_common6.Get)("threads-page"),
1375
- _ts_param3(0, (0, import_common6.Query)("page")),
1376
- _ts_param3(1, (0, import_common6.Query)("limit")),
1377
- _ts_param3(2, (0, import_common6.Query)("where")),
1378
- _ts_metadata3("design:type", Function),
1379
- _ts_metadata3("design:paramtypes", [
996
+ _ts_decorate2([
997
+ (0, import_common5.Get)("threads-page"),
998
+ _ts_param2(0, (0, import_common5.Query)("page")),
999
+ _ts_param2(1, (0, import_common5.Query)("limit")),
1000
+ _ts_param2(2, (0, import_common5.Query)("where")),
1001
+ _ts_metadata2("design:type", Function),
1002
+ _ts_metadata2("design:paramtypes", [
1380
1003
  String,
1381
1004
  String,
1382
1005
  typeof Record === "undefined" ? Object : Record
1383
1006
  ]),
1384
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1007
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1385
1008
  ], AgentApiController.prototype, "threadsPage", null);
1386
- _ts_decorate3([
1387
- (0, import_common6.Get)("threads/:threadId"),
1388
- _ts_param3(0, (0, import_common6.Param)("threadId")),
1389
- _ts_param3(1, (0, import_common6.Query)("messages")),
1390
- _ts_param3(2, (0, import_common6.Query)("runs")),
1391
- _ts_metadata3("design:type", Function),
1392
- _ts_metadata3("design:paramtypes", [
1009
+ _ts_decorate2([
1010
+ (0, import_common5.Get)("threads/:threadId"),
1011
+ _ts_param2(0, (0, import_common5.Param)("threadId")),
1012
+ _ts_param2(1, (0, import_common5.Query)("messages")),
1013
+ _ts_param2(2, (0, import_common5.Query)("runs")),
1014
+ _ts_metadata2("design:type", Function),
1015
+ _ts_metadata2("design:paramtypes", [
1393
1016
  String,
1394
1017
  String,
1395
1018
  String
1396
1019
  ]),
1397
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1020
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1398
1021
  ], AgentApiController.prototype, "threadDetail", null);
1399
- _ts_decorate3([
1400
- (0, import_common6.Get)("pricing"),
1401
- _ts_metadata3("design:type", Function),
1402
- _ts_metadata3("design:paramtypes", []),
1403
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1022
+ _ts_decorate2([
1023
+ (0, import_common5.Get)("pricing"),
1024
+ _ts_metadata2("design:type", Function),
1025
+ _ts_metadata2("design:paramtypes", []),
1026
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1404
1027
  ], AgentApiController.prototype, "listPrices", null);
1405
- _ts_decorate3([
1406
- (0, import_common6.Post)("pricing"),
1407
- _ts_param3(0, (0, import_common6.Body)()),
1408
- _ts_metadata3("design:type", Function),
1409
- _ts_metadata3("design:paramtypes", [
1028
+ _ts_decorate2([
1029
+ (0, import_common5.Post)("pricing"),
1030
+ _ts_param2(0, (0, import_common5.Body)()),
1031
+ _ts_metadata2("design:type", Function),
1032
+ _ts_metadata2("design:paramtypes", [
1410
1033
  Object
1411
1034
  ]),
1412
- _ts_metadata3("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1035
+ _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
1413
1036
  ], AgentApiController.prototype, "upsertPrice", null);
1414
- _ts_decorate3([
1415
- (0, import_common6.Sse)("stream"),
1416
- _ts_metadata3("design:type", Function),
1417
- _ts_metadata3("design:paramtypes", []),
1418
- _ts_metadata3("design:returntype", typeof Observable === "undefined" ? Object : Observable)
1037
+ _ts_decorate2([
1038
+ (0, import_common5.Sse)("stream"),
1039
+ _ts_metadata2("design:type", Function),
1040
+ _ts_metadata2("design:paramtypes", []),
1041
+ _ts_metadata2("design:returntype", typeof Observable === "undefined" ? Object : Observable)
1419
1042
  ], AgentApiController.prototype, "stream", null);
1420
- AgentApiController = _ts_decorate3([
1421
- (0, import_common6.Controller)(),
1422
- (0, import_common6.UseGuards)(DashboardAuthGuard),
1423
- _ts_param3(1, (0, import_common6.Inject)(DASHBOARD_APPROVAL_ACTOR_REF)),
1424
- _ts_param3(2, (0, import_common6.Optional)()),
1425
- _ts_param3(2, (0, import_common6.Inject)(AGENT_ACTOR_RESOLVER)),
1426
- _ts_metadata3("design:type", Function),
1427
- _ts_metadata3("design:paramtypes", [
1043
+ AgentApiController = _ts_decorate2([
1044
+ (0, import_nestjs_agent_core.CanAnyone)(),
1045
+ (0, import_common5.Controller)(),
1046
+ _ts_param2(1, (0, import_common5.Inject)(DASHBOARD_APPROVAL_ACTOR_REF)),
1047
+ _ts_param2(2, (0, import_common5.Optional)()),
1048
+ _ts_param2(2, (0, import_common5.Inject)(AGENT_ACTOR_RESOLVER)),
1049
+ _ts_metadata2("design:type", Function),
1050
+ _ts_metadata2("design:paramtypes", [
1428
1051
  typeof DashboardService === "undefined" ? Object : DashboardService,
1429
1052
  Object,
1430
1053
  typeof ActorResolver === "undefined" ? Object : ActorResolver
1431
1054
  ])
1432
1055
  ], AgentApiController);
1433
1056
 
1434
- // src/server/agent-dashboard-auth.controller.ts
1435
- var import_common7 = require("@nestjs/common");
1436
-
1437
- // src/server/auth/login-page.ts
1438
- function escapeHtml(value) {
1439
- return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
1440
- }
1441
- __name(escapeHtml, "escapeHtml");
1442
- function pageShell(content, title) {
1443
- return `<!doctype html>
1444
- <html lang="en">
1445
- <head>
1446
- <meta charset="utf-8" />
1447
- <meta name="viewport" content="width=device-width, initial-scale=1" />
1448
- <meta name="robots" content="noindex, nofollow" />
1449
- <title>${title}</title>
1450
- <style>
1451
- :root { color-scheme: dark; }
1452
- * { box-sizing: border-box; }
1453
- body {
1454
- margin: 0;
1455
- min-height: 100vh;
1456
- display: flex;
1457
- align-items: center;
1458
- justify-content: center;
1459
- background: #09090b;
1460
- color: #e4e4e7;
1461
- font: 14px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
1462
- padding: 16px;
1463
- }
1464
- .card {
1465
- width: 100%;
1466
- max-width: 384px;
1467
- border: 1px solid #27272a;
1468
- background: #18181b;
1469
- border-radius: 8px;
1470
- padding: 32px;
1471
- box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.5);
1472
- }
1473
- .brand {
1474
- margin: 0 0 24px;
1475
- text-align: center;
1476
- font-size: 18px;
1477
- font-weight: 600;
1478
- color: #34d399;
1479
- }
1480
- h1 {
1481
- margin: 0 0 12px;
1482
- font-size: 16px;
1483
- font-weight: 600;
1484
- color: #f4f4f5;
1485
- }
1486
- p { margin: 0 0 16px; color: #a1a1aa; }
1487
- form { display: flex; flex-direction: column; gap: 16px; }
1488
- label { display: flex; flex-direction: column; gap: 6px; }
1489
- .field-label {
1490
- font-size: 11px;
1491
- text-transform: uppercase;
1492
- letter-spacing: 0.05em;
1493
- color: #71717a;
1494
- }
1495
- input {
1496
- border-radius: 4px;
1497
- border: 1px solid #3f3f46;
1498
- background: #09090b;
1499
- color: #f4f4f5;
1500
- padding: 8px 12px;
1501
- font: inherit;
1502
- outline: none;
1503
- }
1504
- input:focus { border-color: rgb(52 211 153 / 0.6); }
1505
- .error { margin: 0; font-size: 12px; color: #fb7185; }
1506
- button {
1507
- margin-top: 8px;
1508
- border-radius: 4px;
1509
- border: 1px solid rgb(52 211 153 / 0.4);
1510
- background: rgb(52 211 153 / 0.1);
1511
- color: #6ee7b7;
1512
- padding: 8px 12px;
1513
- font: inherit;
1514
- font-size: 12px;
1515
- font-weight: 500;
1516
- text-transform: uppercase;
1517
- letter-spacing: 0.05em;
1518
- cursor: pointer;
1519
- }
1520
- button:hover { background: rgb(52 211 153 / 0.2); }
1521
- </style>
1522
- </head>
1523
- <body>
1524
- <div class="card">
1525
- ${content}
1526
- </div>
1527
- </body>
1528
- </html>`;
1529
- }
1530
- __name(pageShell, "pageShell");
1531
- function renderLoginPage(options) {
1532
- const action = escapeHtml(options.actionUrl);
1533
- const returnTo = escapeHtml(options.returnTo);
1534
- const errorBanner = options.error === true ? '<p role="alert" class="error">Invalid username or password.</p>' : "";
1535
- return pageShell(`<p class="brand">AI Gateway</p>
1536
- <form method="post" action="${action}">
1537
- <input type="hidden" name="returnTo" value="${returnTo}" />
1538
- <label>
1539
- <span class="field-label">Username</span>
1540
- <input type="text" name="username" autocomplete="username" autofocus />
1541
- </label>
1542
- <label>
1543
- <span class="field-label">Password</span>
1544
- <input type="password" name="password" autocomplete="current-password" />
1545
- </label>
1546
- ${errorBanner}
1547
- <button type="submit">Sign in</button>
1548
- </form>`, "Sign in \u2014 AI Gateway");
1549
- }
1550
- __name(renderLoginPage, "renderLoginPage");
1551
- function renderSessionRequiredPage() {
1552
- return pageShell(`<p class="brand">AI Gateway</p>
1553
- <h1>Open this console from your application</h1>
1554
- <p>Your session is minted by the host app. Use its console launcher to sign in, then reload.</p>`, "Sign in \u2014 AI Gateway");
1555
- }
1556
- __name(renderSessionRequiredPage, "renderSessionRequiredPage");
1557
-
1558
- // src/server/auth/sanitize-return-to.ts
1559
- function sanitizeReturnTo(basePath, returnTo) {
1560
- if (typeof returnTo !== "string" || returnTo === "") return basePath;
1561
- if (!returnTo.startsWith("/") || returnTo.startsWith("//")) return basePath;
1562
- if (returnTo !== basePath && !returnTo.startsWith(`${basePath}/`) && !returnTo.startsWith(`${basePath}?`)) {
1563
- return basePath;
1564
- }
1565
- return returnTo;
1566
- }
1567
- __name(sanitizeReturnTo, "sanitizeReturnTo");
1568
-
1569
- // src/server/agent-dashboard-auth.controller.ts
1570
- function _ts_decorate4(decorators, target, key, desc) {
1571
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1572
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
1573
- r = Reflect.decorate(decorators, target, key, desc);
1574
- } else {
1575
- for (var i = decorators.length - 1; i >= 0; i--) {
1576
- if (d = decorators[i]) {
1577
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1578
- }
1579
- }
1580
- }
1581
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1582
- }
1583
- __name(_ts_decorate4, "_ts_decorate");
1584
- function _ts_metadata4(metadataKey, metadataValue) {
1585
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
1586
- return Reflect.metadata(metadataKey, metadataValue);
1587
- }
1588
- }
1589
- __name(_ts_metadata4, "_ts_metadata");
1590
- function _ts_param4(paramIndex, decorator) {
1591
- return function(target, key) {
1592
- decorator(target, key, paramIndex);
1593
- };
1594
- }
1595
- __name(_ts_param4, "_ts_param");
1596
- function isNonEmptyString(value) {
1597
- return typeof value === "string" && value.trim() !== "";
1598
- }
1599
- __name(isNonEmptyString, "isNonEmptyString");
1600
- function isString(value) {
1601
- return typeof value === "string";
1602
- }
1603
- __name(isString, "isString");
1604
- var AgentDashboardAuthController = class _AgentDashboardAuthController {
1605
- static {
1606
- __name(this, "AgentDashboardAuthController");
1607
- }
1608
- auth;
1609
- basePath;
1610
- logger = new import_common7.Logger(_AgentDashboardAuthController.name);
1611
- /** Warn once PER HOOK KIND (not per request) so a broken hook can't be used to flood the logs. */
1612
- warnedHooks = /* @__PURE__ */ new Set();
1613
- constructor(auth, basePath) {
1614
- this.auth = auth;
1615
- this.basePath = basePath;
1616
- }
1617
- loginPage(req, res, returnToQuery, error) {
1618
- const auth = this.requireAuth();
1619
- if (!auth.modes.includes("login")) throw new import_common7.NotFoundException();
1620
- const returnTo = sanitizeReturnTo(this.basePath, returnToQuery);
1621
- if (this.currentSession(req)) {
1622
- res.status(302);
1623
- res.setHeader("Location", returnTo);
1624
- return "";
1625
- }
1626
- return renderLoginPage({
1627
- actionUrl: `${this.basePath}/auth/login`,
1628
- returnTo,
1629
- error: error !== void 0
1630
- });
1631
- }
1632
- async login(body, req, res) {
1633
- const auth = this.requireAuth();
1634
- if (!auth.modes.includes("login")) throw new import_common7.NotFoundException();
1635
- const returnTo = sanitizeReturnTo(this.basePath, body?.returnTo);
1636
- const username = body?.username;
1637
- const password = body?.password;
1638
- if (!isNonEmptyString(username) || password !== void 0 && !isString(password)) {
1639
- this.redirectToLoginError(res, returnTo);
1640
- return "";
1641
- }
1642
- const user = await this.runHook("login", () => auth.login?.(username.trim(), isString(password) ? password : "") ?? null);
1643
- if (!user) {
1644
- this.redirectToLoginError(res, returnTo);
1645
- return "";
1646
- }
1647
- issueSessionCookie(user, {
1648
- auth,
1649
- request: req,
1650
- response: res
1651
- });
1652
- res.status(302);
1653
- res.setHeader("Location", returnTo);
1654
- return "";
1655
- }
1656
- logout(req, res) {
1657
- clearSessionCookie({
1658
- request: req,
1659
- response: res
1660
- });
1661
- res.status(302);
1662
- res.setHeader("Location", this.auth && !this.auth.modes.includes("login") ? `${this.basePath}/auth/session-required` : `${this.basePath}/auth/login`);
1663
- return "";
1664
- }
1665
- // Mode A: the host frontend (carrying its own auth) POSTs here; the host hook validates the raw
1666
- // request and returns the session user, or `null` to deny. No credential reaches this library.
1667
- async session(request, response) {
1668
- const auth = this.requireAuth();
1669
- if (!auth.modes.includes("session")) throw new import_common7.NotFoundException();
1670
- const user = await this.runHook("session", () => auth.session?.(request) ?? null);
1671
- if (!user) throw new import_common7.UnauthorizedException();
1672
- issueSessionCookie(user, {
1673
- auth,
1674
- request,
1675
- response
1676
- });
1677
- }
1678
- // Mode-A-only landing: the host mints the session, so there is nothing to submit here. Serves
1679
- // as the redirect target `DashboardAuthPageGuard` bounces to instead of `/auth/login`, which
1680
- // 404s under Mode A (see `loginPage` above).
1681
- //
1682
- // Non-passthrough `@Res()` (unlike its sibling routes) because `dashboardAuth.unauthenticatedPage`
1683
- // hands the response to the HOST, which writes and ends it itself — there is no return value for
1684
- // Nest to send, and letting Nest also send one would double-write. The `Content-Type` /
1685
- // `Cache-Control` this route used to carry as decorators move into `sendHtml` for the built-in
1686
- // path; the host owns its own headers on the hook path.
1687
- async sessionRequiredPage(req, res) {
1688
- const auth = this.requireAuth();
1689
- if (auth.modes.includes("login")) throw new import_common7.NotFoundException();
1690
- const hook = auth.unauthenticatedPage;
1691
- if (hook) {
1692
- try {
1693
- await hook({
1694
- request: req,
1695
- response: res,
1696
- basePath: this.basePath
1697
- });
1698
- if (responseAlreadyWritten(res)) return;
1699
- this.warnHookOnce("unauthenticatedPage", "dashboardAuth.unauthenticatedPage returned without writing a response; falling back to the built-in page. The hook must write AND end the response it is given.");
1700
- } catch (error) {
1701
- this.warnHookOnce("unauthenticatedPage", `dashboardAuth.unauthenticatedPage threw; falling back to the built-in page. ${String(error)}`);
1702
- if (responseAlreadyWritten(res)) return;
1703
- }
1704
- }
1705
- sendHtml(res, 200, renderSessionRequiredPage());
1706
- }
1707
- /** Uniform failure: same redirect (generic error flag) whether the user is unknown or the password is wrong. */
1708
- redirectToLoginError(res, returnTo) {
1709
- res.status(303);
1710
- res.setHeader("Location", `${this.basePath}/auth/login?error=1&returnTo=${encodeURIComponent(returnTo)}`);
1711
- }
1712
- currentSession(req) {
1713
- const auth = this.auth;
1714
- if (!auth) return false;
1715
- const cookieValue = parseCookieHeader(readCookieHeader(req))[SESSION_COOKIE_NAME];
1716
- if (cookieValue === void 0) return false;
1717
- return verifySessionCookie(cookieValue, {
1718
- secret: auth.secret
1719
- }) !== null;
1720
- }
1721
- /**
1722
- * Run a host hook (`login` or `session`) defensively: a throw (sync or async) is treated as a
1723
- * denial (`null`) and warn-logged ONCE PER KIND, so a buggy/unreachable hook never 500s the
1724
- * endpoint into a stack-trace leak nor floods the logs on repeated bad attempts.
1725
- */
1726
- async runHook(kind, run) {
1727
- try {
1728
- return await run() ?? null;
1729
- } catch (error) {
1730
- this.warnHookOnce(kind, `AgentDashboardModule dashboardAuth ${kind} hook threw; treating as denial. ${error instanceof Error ? error.message : String(error)}`);
1731
- return null;
1732
- }
1733
- }
1734
- /**
1735
- * Warn once per hook kind for the life of the process, not once per request: a broken hook fires
1736
- * on every denied navigation and would otherwise flood the logs.
1737
- */
1738
- warnHookOnce(kind, message) {
1739
- if (this.warnedHooks.has(kind)) return;
1740
- this.warnedHooks.add(kind);
1741
- this.logger.warn(message);
1742
- }
1743
- requireAuth() {
1744
- if (!this.auth) throw new import_common7.NotFoundException();
1745
- return this.auth;
1746
- }
1747
- };
1748
- _ts_decorate4([
1749
- (0, import_common7.Get)("login"),
1750
- (0, import_common7.Header)("Content-Type", "text/html; charset=utf-8"),
1751
- (0, import_common7.Header)("Cache-Control", "no-store"),
1752
- _ts_param4(0, (0, import_common7.Req)()),
1753
- _ts_param4(1, (0, import_common7.Res)({
1754
- passthrough: true
1755
- })),
1756
- _ts_param4(2, (0, import_common7.Query)("returnTo")),
1757
- _ts_param4(3, (0, import_common7.Query)("error")),
1758
- _ts_metadata4("design:type", Function),
1759
- _ts_metadata4("design:paramtypes", [
1760
- typeof AuthPageRequest === "undefined" ? Object : AuthPageRequest,
1761
- typeof AuthPageResponse === "undefined" ? Object : AuthPageResponse,
1762
- String,
1763
- String
1764
- ]),
1765
- _ts_metadata4("design:returntype", String)
1766
- ], AgentDashboardAuthController.prototype, "loginPage", null);
1767
- _ts_decorate4([
1768
- (0, import_common7.Post)("login"),
1769
- _ts_param4(0, (0, import_common7.Body)()),
1770
- _ts_param4(1, (0, import_common7.Req)()),
1771
- _ts_param4(2, (0, import_common7.Res)({
1772
- passthrough: true
1773
- })),
1774
- _ts_metadata4("design:type", Function),
1775
- _ts_metadata4("design:paramtypes", [
1776
- typeof LoginFormBody === "undefined" ? Object : LoginFormBody,
1777
- Object,
1778
- typeof AuthPageResponse === "undefined" ? Object : AuthPageResponse
1779
- ]),
1780
- _ts_metadata4("design:returntype", Promise)
1781
- ], AgentDashboardAuthController.prototype, "login", null);
1782
- _ts_decorate4([
1783
- (0, import_common7.Post)("logout"),
1784
- _ts_param4(0, (0, import_common7.Req)()),
1785
- _ts_param4(1, (0, import_common7.Res)({
1786
- passthrough: true
1787
- })),
1788
- _ts_metadata4("design:type", Function),
1789
- _ts_metadata4("design:paramtypes", [
1790
- Object,
1791
- typeof AuthPageResponse === "undefined" ? Object : AuthPageResponse
1792
- ]),
1793
- _ts_metadata4("design:returntype", String)
1794
- ], AgentDashboardAuthController.prototype, "logout", null);
1795
- _ts_decorate4([
1796
- (0, import_common7.Post)("session"),
1797
- (0, import_common7.HttpCode)(204),
1798
- _ts_param4(0, (0, import_common7.Req)()),
1799
- _ts_param4(1, (0, import_common7.Res)({
1800
- passthrough: true
1801
- })),
1802
- _ts_metadata4("design:type", Function),
1803
- _ts_metadata4("design:paramtypes", [
1804
- Object,
1805
- Object
1806
- ]),
1807
- _ts_metadata4("design:returntype", Promise)
1808
- ], AgentDashboardAuthController.prototype, "session", null);
1809
- _ts_decorate4([
1810
- (0, import_common7.Get)("session-required"),
1811
- _ts_param4(0, (0, import_common7.Req)()),
1812
- _ts_param4(1, (0, import_common7.Res)()),
1813
- _ts_metadata4("design:type", Function),
1814
- _ts_metadata4("design:paramtypes", [
1815
- typeof AuthPageRequest === "undefined" ? Object : AuthPageRequest,
1816
- Object
1817
- ]),
1818
- _ts_metadata4("design:returntype", Promise)
1819
- ], AgentDashboardAuthController.prototype, "sessionRequiredPage", null);
1820
- AgentDashboardAuthController = _ts_decorate4([
1821
- (0, import_common7.Controller)("auth"),
1822
- _ts_param4(0, (0, import_common7.Optional)()),
1823
- _ts_param4(0, (0, import_common7.Inject)(DASHBOARD_AUTH)),
1824
- _ts_param4(1, (0, import_common7.Inject)(DASHBOARD_BASE_PATH)),
1825
- _ts_metadata4("design:type", Function),
1826
- _ts_metadata4("design:paramtypes", [
1827
- Object,
1828
- String
1829
- ])
1830
- ], AgentDashboardAuthController);
1831
-
1832
1057
  // src/server/normalize-path.ts
1833
1058
  function normalizeDashboardPath(path) {
1834
1059
  return `/${path.replace(/^\/+|\/+$/g, "")}`;
@@ -1855,153 +1080,18 @@ function agentDashboardMountPaths(options) {
1855
1080
  __name(agentDashboardMountPaths, "agentDashboardMountPaths");
1856
1081
 
1857
1082
  // src/server/agent-dashboard.module.ts
1858
- var import_reflect_metadata2 = require("reflect-metadata");
1859
- var import_common11 = require("@nestjs/common");
1083
+ var import_nestjs_agent_core3 = require("@dudousxd/nestjs-agent-core");
1084
+ var import_reflect_metadata = require("reflect-metadata");
1085
+ var import_common7 = require("@nestjs/common");
1860
1086
  var import_core = require("@nestjs/core");
1861
1087
 
1862
1088
  // src/server/agent-ui.controller.ts
1863
1089
  var import_node_fs = require("fs");
1864
1090
  var import_node_path = require("path");
1865
1091
  var import_node_url = require("url");
1866
- var import_common10 = require("@nestjs/common");
1867
-
1868
- // src/server/auth/dashboard-auth-page.guard.ts
1869
- var import_common9 = require("@nestjs/common");
1870
-
1871
- // src/server/auth/dashboard-auth-redirect.ts
1872
- var import_common8 = require("@nestjs/common");
1873
- function _ts_decorate5(decorators, target, key, desc) {
1874
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1875
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
1876
- r = Reflect.decorate(decorators, target, key, desc);
1877
- } else {
1878
- for (var i = decorators.length - 1; i >= 0; i--) {
1879
- if (d = decorators[i]) {
1880
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1881
- }
1882
- }
1883
- }
1884
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1885
- }
1886
- __name(_ts_decorate5, "_ts_decorate");
1887
- var DashboardAuthRedirect = class extends Error {
1888
- static {
1889
- __name(this, "DashboardAuthRedirect");
1890
- }
1891
- redirectTo;
1892
- constructor(redirectTo) {
1893
- super(`Redirect to ${redirectTo}`), this.redirectTo = redirectTo;
1894
- this.name = "DashboardAuthRedirect";
1895
- }
1896
- };
1897
- var DashboardAuthRedirectFilter = class {
1898
- static {
1899
- __name(this, "DashboardAuthRedirectFilter");
1900
- }
1901
- catch(exception, host) {
1902
- const response = host.switchToHttp().getResponse();
1903
- sendRedirect(response, 302, exception.redirectTo);
1904
- }
1905
- };
1906
- DashboardAuthRedirectFilter = _ts_decorate5([
1907
- (0, import_common8.Injectable)(),
1908
- (0, import_common8.Catch)(DashboardAuthRedirect)
1909
- ], DashboardAuthRedirectFilter);
1910
-
1911
- // src/server/auth/dashboard-auth-page.guard.ts
1912
- function _ts_decorate6(decorators, target, key, desc) {
1913
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1914
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
1915
- r = Reflect.decorate(decorators, target, key, desc);
1916
- } else {
1917
- for (var i = decorators.length - 1; i >= 0; i--) {
1918
- if (d = decorators[i]) {
1919
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1920
- }
1921
- }
1922
- }
1923
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1924
- }
1925
- __name(_ts_decorate6, "_ts_decorate");
1926
- function _ts_metadata5(metadataKey, metadataValue) {
1927
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
1928
- return Reflect.metadata(metadataKey, metadataValue);
1929
- }
1930
- }
1931
- __name(_ts_metadata5, "_ts_metadata");
1932
- function _ts_param5(paramIndex, decorator) {
1933
- return function(target, key) {
1934
- decorator(target, key, paramIndex);
1935
- };
1936
- }
1937
- __name(_ts_param5, "_ts_param");
1938
- var DashboardAuthPageGuard = class {
1939
- static {
1940
- __name(this, "DashboardAuthPageGuard");
1941
- }
1942
- auth;
1943
- basePath;
1944
- constructor(auth, basePath) {
1945
- this.auth = auth;
1946
- this.basePath = basePath;
1947
- }
1948
- async canActivate(context) {
1949
- if (!this.auth) return true;
1950
- const auth = this.auth;
1951
- const http = context.switchToHttp();
1952
- const request = http.getRequest();
1953
- const session = this.verifyRequestSession(request);
1954
- if (!session) this.deny(auth, request);
1955
- attachSession(request, session);
1956
- if (!await maybeRenewSession(auth, session, request, http.getResponse())) {
1957
- this.deny(auth, request);
1958
- }
1959
- return true;
1960
- }
1961
- /**
1962
- * No valid session: bounce the browser navigation onward. Under Mode B (`login` configured)
1963
- * that's the built-in login screen, carrying `returnTo` back to the page that was requested.
1964
- * Under Mode-A-only there is no login screen to redirect to — the host mints the session
1965
- * itself — so this instead serves the instruction page rather than redirecting into a 404.
1966
- * Pulled out of `canActivate` so both the "no session at all" and the "revalidate revoked a
1967
- * renewable session" paths reuse the exact same mode-aware deny logic.
1968
- *
1969
- * Takes `auth` explicitly rather than reading `this.auth`: `canActivate`'s `!this.auth` early
1970
- * return narrows the field within that method only — TS doesn't carry it across a method call —
1971
- * so the caller passes the already-narrowed value instead of this method re-deriving (or
1972
- * asserting away) the nullability.
1973
- */
1974
- deny(auth, request) {
1975
- if (!auth.modes.includes("login")) {
1976
- throw new DashboardAuthRedirect(`${this.basePath}/auth/session-required`);
1977
- }
1978
- const returnTo = readOriginalUrl(request);
1979
- throw new DashboardAuthRedirect(`${this.basePath}/auth/login?returnTo=${encodeURIComponent(returnTo)}`);
1980
- }
1981
- verifyRequestSession(request) {
1982
- const auth = this.auth;
1983
- if (!auth) return null;
1984
- const cookieValue = parseCookieHeader(readCookieHeader(request))[SESSION_COOKIE_NAME];
1985
- if (cookieValue === void 0) return null;
1986
- return verifySessionCookie(cookieValue, {
1987
- secret: auth.secret
1988
- });
1989
- }
1990
- };
1991
- DashboardAuthPageGuard = _ts_decorate6([
1992
- (0, import_common9.Injectable)(),
1993
- _ts_param5(0, (0, import_common9.Optional)()),
1994
- _ts_param5(0, (0, import_common9.Inject)(DASHBOARD_AUTH)),
1995
- _ts_param5(1, (0, import_common9.Inject)(DASHBOARD_BASE_PATH)),
1996
- _ts_metadata5("design:type", Function),
1997
- _ts_metadata5("design:paramtypes", [
1998
- Object,
1999
- String
2000
- ])
2001
- ], DashboardAuthPageGuard);
2002
-
2003
- // src/server/agent-ui.controller.ts
2004
- function _ts_decorate7(decorators, target, key, desc) {
1092
+ var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
1093
+ var import_common6 = require("@nestjs/common");
1094
+ function _ts_decorate3(decorators, target, key, desc) {
2005
1095
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2006
1096
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
2007
1097
  r = Reflect.decorate(decorators, target, key, desc);
@@ -2014,19 +1104,19 @@ function _ts_decorate7(decorators, target, key, desc) {
2014
1104
  }
2015
1105
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2016
1106
  }
2017
- __name(_ts_decorate7, "_ts_decorate");
2018
- function _ts_metadata6(metadataKey, metadataValue) {
1107
+ __name(_ts_decorate3, "_ts_decorate");
1108
+ function _ts_metadata3(metadataKey, metadataValue) {
2019
1109
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
2020
1110
  return Reflect.metadata(metadataKey, metadataValue);
2021
1111
  }
2022
1112
  }
2023
- __name(_ts_metadata6, "_ts_metadata");
2024
- function _ts_param6(paramIndex, decorator) {
1113
+ __name(_ts_metadata3, "_ts_metadata");
1114
+ function _ts_param3(paramIndex, decorator) {
2025
1115
  return function(target, key) {
2026
1116
  decorator(target, key, paramIndex);
2027
1117
  };
2028
1118
  }
2029
- __name(_ts_param6, "_ts_param");
1119
+ __name(_ts_param3, "_ts_param");
2030
1120
  var BUILD_BASE = "/ai-gateway";
2031
1121
  function spaDir() {
2032
1122
  return (0, import_node_url.fileURLToPath)(new URL("../spa", __importMetaUrl));
@@ -2062,7 +1152,7 @@ var AgentUiController = class {
2062
1152
  }
2063
1153
  const indexPath = (0, import_node_path.join)(this.dir, "index.html");
2064
1154
  if (!(0, import_node_fs.existsSync)(indexPath)) {
2065
- throw new import_common10.NotFoundException("Dashboard is not built. Run the package build.");
1155
+ throw new import_common6.NotFoundException("Dashboard is not built. Run the package build.");
2066
1156
  }
2067
1157
  const html = (0, import_node_fs.readFileSync)(indexPath, "utf8").replaceAll(`="${BUILD_BASE}/`, `="${this.basePath}/`);
2068
1158
  const inject = `<script>window.__AGENT_BASE__='${this.basePath}';window.__AGENT_API__='${this.apiBasePath}';</script>`;
@@ -2070,155 +1160,57 @@ var AgentUiController = class {
2070
1160
  }
2071
1161
  asset(file) {
2072
1162
  const safe = (0, import_node_path.basename)(file);
2073
- if (safe !== file) throw new import_common10.NotFoundException();
1163
+ if (safe !== file) throw new import_common6.NotFoundException();
2074
1164
  const root = (0, import_node_path.resolve)(this.dir, "assets");
2075
1165
  const assetPath = (0, import_node_path.resolve)(root, safe);
2076
1166
  if (!assetPath.startsWith(root + import_node_path.sep) || !(0, import_node_fs.existsSync)(assetPath)) {
2077
- throw new import_common10.NotFoundException();
1167
+ throw new import_common6.NotFoundException();
2078
1168
  }
2079
1169
  const type = CONTENT_TYPES[(0, import_node_path.extname)(safe)] ?? "application/octet-stream";
2080
- return new import_common10.StreamableFile((0, import_node_fs.readFileSync)(assetPath), {
1170
+ return new import_common6.StreamableFile((0, import_node_fs.readFileSync)(assetPath), {
2081
1171
  type
2082
1172
  });
2083
1173
  }
2084
1174
  };
2085
- _ts_decorate7([
2086
- (0, import_common10.Get)(),
2087
- (0, import_common10.Header)("Content-Type", "text/html; charset=utf-8"),
2088
- (0, import_common10.Header)("Cache-Control", "no-store, must-revalidate"),
2089
- _ts_param6(0, (0, import_common10.Req)()),
2090
- _ts_param6(1, (0, import_common10.Res)({
1175
+ _ts_decorate3([
1176
+ (0, import_common6.Get)(),
1177
+ (0, import_common6.Header)("Content-Type", "text/html; charset=utf-8"),
1178
+ (0, import_common6.Header)("Cache-Control", "no-store, must-revalidate"),
1179
+ _ts_param3(0, (0, import_common6.Req)()),
1180
+ _ts_param3(1, (0, import_common6.Res)({
2091
1181
  passthrough: true
2092
1182
  })),
2093
- _ts_metadata6("design:type", Function),
2094
- _ts_metadata6("design:paramtypes", [
1183
+ _ts_metadata3("design:type", Function),
1184
+ _ts_metadata3("design:paramtypes", [
2095
1185
  typeof UiPageRequest === "undefined" ? Object : UiPageRequest,
2096
1186
  typeof UiPageResponse === "undefined" ? Object : UiPageResponse
2097
1187
  ]),
2098
- _ts_metadata6("design:returntype", String)
1188
+ _ts_metadata3("design:returntype", String)
2099
1189
  ], AgentUiController.prototype, "index", null);
2100
- _ts_decorate7([
2101
- (0, import_common10.Get)("assets/:file"),
2102
- (0, import_common10.Header)("Cache-Control", "public, max-age=31536000, immutable"),
2103
- _ts_param6(0, (0, import_common10.Param)("file")),
2104
- _ts_metadata6("design:type", Function),
2105
- _ts_metadata6("design:paramtypes", [
1190
+ _ts_decorate3([
1191
+ (0, import_common6.Get)("assets/:file"),
1192
+ (0, import_common6.Header)("Cache-Control", "public, max-age=31536000, immutable"),
1193
+ _ts_param3(0, (0, import_common6.Param)("file")),
1194
+ _ts_metadata3("design:type", Function),
1195
+ _ts_metadata3("design:paramtypes", [
2106
1196
  String
2107
1197
  ]),
2108
- _ts_metadata6("design:returntype", typeof import_common10.StreamableFile === "undefined" ? Object : import_common10.StreamableFile)
1198
+ _ts_metadata3("design:returntype", typeof import_common6.StreamableFile === "undefined" ? Object : import_common6.StreamableFile)
2109
1199
  ], AgentUiController.prototype, "asset", null);
2110
- AgentUiController = _ts_decorate7([
2111
- (0, import_common10.Controller)(),
2112
- (0, import_common10.UseGuards)(DashboardAuthPageGuard),
2113
- (0, import_common10.UseFilters)(new DashboardAuthRedirectFilter()),
2114
- _ts_param6(0, (0, import_common10.Inject)(DASHBOARD_BASE_PATH)),
2115
- _ts_param6(1, (0, import_common10.Inject)(DASHBOARD_API_PATH)),
2116
- _ts_metadata6("design:type", Function),
2117
- _ts_metadata6("design:paramtypes", [
1200
+ AgentUiController = _ts_decorate3([
1201
+ (0, import_nestjs_agent_core2.CanAnyone)(),
1202
+ (0, import_common6.Controller)(),
1203
+ _ts_param3(0, (0, import_common6.Inject)(DASHBOARD_BASE_PATH)),
1204
+ _ts_param3(1, (0, import_common6.Inject)(DASHBOARD_API_PATH)),
1205
+ _ts_metadata3("design:type", Function),
1206
+ _ts_metadata3("design:paramtypes", [
2118
1207
  String,
2119
1208
  String
2120
1209
  ])
2121
1210
  ], AgentUiController);
2122
1211
 
2123
- // src/server/auth/dashboard-auth-config.ts
2124
- var DEFAULT_TTL = "8h";
2125
- function unitToMs(unit) {
2126
- switch (unit) {
2127
- case "ms":
2128
- return 1;
2129
- case "s":
2130
- return 1e3;
2131
- case "m":
2132
- return 6e4;
2133
- case "h":
2134
- return 36e5;
2135
- case "d":
2136
- return 864e5;
2137
- default:
2138
- return void 0;
2139
- }
2140
- }
2141
- __name(unitToMs, "unitToMs");
2142
- function durationToMs(duration) {
2143
- const match = /^(\d+)(ms|s|m|h|d)$/.exec(duration.trim());
2144
- const amount = match?.[1];
2145
- const unit = match?.[2] !== void 0 ? unitToMs(match[2]) : void 0;
2146
- if (amount === void 0 || unit === void 0) {
2147
- throw new Error(`AgentDashboardModule dashboardAuth: invalid \`ttl\` duration: ${duration}`);
2148
- }
2149
- return Number(amount) * unit;
2150
- }
2151
- __name(durationToMs, "durationToMs");
2152
- function resolveDashboardAuth(options) {
2153
- if (options === void 0) return null;
2154
- if (typeof options.secret !== "string" || options.secret === "") {
2155
- throw new Error("AgentDashboardModule dashboardAuth: `secret` is required and must be a non-empty string (HMAC-SHA256 signing key, 32+ bytes recommended). Failing closed.");
2156
- }
2157
- const modes = [];
2158
- if (options.session !== void 0) {
2159
- if (typeof options.session !== "function") {
2160
- throw new Error("AgentDashboardModule dashboardAuth: `session` must be a function.");
2161
- }
2162
- modes.push("session");
2163
- }
2164
- if (options.login !== void 0) {
2165
- if (typeof options.login !== "function") {
2166
- throw new Error("AgentDashboardModule dashboardAuth: `login` must be a function.");
2167
- }
2168
- modes.push("login");
2169
- }
2170
- if (options.revalidate !== void 0 && typeof options.revalidate !== "function") {
2171
- throw new Error("AgentDashboardModule dashboardAuth: `revalidate` must be a function.");
2172
- }
2173
- if (options.unauthenticatedPage !== void 0 && typeof options.unauthenticatedPage !== "function") {
2174
- throw new Error("AgentDashboardModule dashboardAuth: `unauthenticatedPage` must be a function.");
2175
- }
2176
- if (modes.length === 0) {
2177
- throw new Error("AgentDashboardModule dashboardAuth: at least one of `session` (the host mints the session from its own auth) or `login` (the built-in login screen) is required \u2014 otherwise the cookie can never be minted. Failing closed.");
2178
- }
2179
- return {
2180
- secret: options.secret,
2181
- ttlMs: durationToMs(options.ttl ?? DEFAULT_TTL),
2182
- modes,
2183
- ...options.session !== void 0 ? {
2184
- session: options.session
2185
- } : {},
2186
- ...options.login !== void 0 ? {
2187
- login: options.login
2188
- } : {},
2189
- ...options.revalidate !== void 0 ? {
2190
- revalidate: options.revalidate
2191
- } : {},
2192
- ...options.unauthenticatedPage !== void 0 ? {
2193
- unauthenticatedPage: options.unauthenticatedPage
2194
- } : {}
2195
- };
2196
- }
2197
- __name(resolveDashboardAuth, "resolveDashboardAuth");
2198
-
2199
- // src/server/guards.ts
2200
- var import_reflect_metadata = require("reflect-metadata");
2201
- var GUARDS_METADATA = "__guards__";
2202
- function isGuardClass(guard) {
2203
- return typeof guard === "function";
2204
- }
2205
- __name(isGuardClass, "isGuardClass");
2206
- function baseGuards(controller) {
2207
- return Reflect.getOwnMetadata(GUARDS_METADATA, controller) ?? [];
2208
- }
2209
- __name(baseGuards, "baseGuards");
2210
- function stampGuards(guards, entries) {
2211
- for (const [controller, base] of entries) {
2212
- Reflect.defineMetadata(GUARDS_METADATA, [
2213
- ...base,
2214
- ...guards ?? []
2215
- ], controller);
2216
- }
2217
- }
2218
- __name(stampGuards, "stampGuards");
2219
-
2220
1212
  // src/server/agent-dashboard.module.ts
2221
- function _ts_decorate8(decorators, target, key, desc) {
1213
+ function _ts_decorate4(decorators, target, key, desc) {
2222
1214
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2223
1215
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
2224
1216
  r = Reflect.decorate(decorators, target, key, desc);
@@ -2231,37 +1223,33 @@ function _ts_decorate8(decorators, target, key, desc) {
2231
1223
  }
2232
1224
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2233
1225
  }
2234
- __name(_ts_decorate8, "_ts_decorate");
2235
- var API_BASE_GUARDS = baseGuards(AgentApiController);
2236
- var UI_BASE_GUARDS = baseGuards(AgentUiController);
1226
+ __name(_ts_decorate4, "_ts_decorate");
2237
1227
  function normalize(path) {
2238
1228
  return normalizeDashboardPath(path);
2239
1229
  }
2240
1230
  __name(normalize, "normalize");
1231
+ function assertProtected(options) {
1232
+ if (process.env.NODE_ENV !== "production") return;
1233
+ if (options.routes === false) return;
1234
+ if ((options.decorators ?? []).length > 0) return;
1235
+ throw new Error("AgentDashboardModule: the AI-gateway console would be served open in production. Say who reaches it, with `decorators: [UseGuards(AuthenticationGuard), Can(ConsolePolicy, 'view')]`, or mount its routes yourself with `routes: false` and extend `AgentApiController` / `AgentUiController` under your own guards.");
1236
+ }
1237
+ __name(assertProtected, "assertProtected");
2241
1238
  var AgentApiModule = class _AgentApiModule {
2242
1239
  static {
2243
1240
  __name(this, "AgentApiModule");
2244
1241
  }
2245
1242
  static register(options) {
2246
- stampGuards(options.guards, [
2247
- [
2248
- AgentApiController,
2249
- API_BASE_GUARDS
2250
- ]
2251
- ]);
2252
1243
  return {
2253
1244
  module: _AgentApiModule,
2254
1245
  imports: [
2255
1246
  ...options.imports ?? []
2256
1247
  ],
2257
- controllers: [
1248
+ controllers: options.routes === false ? [] : (0, import_nestjs_agent_core3.withControllerDecorators)([
2258
1249
  AgentApiController
2259
- ],
1250
+ ], options.decorators),
2260
1251
  providers: [
2261
1252
  DashboardService,
2262
- DashboardAuthGuard,
2263
- options.dashboardAuth,
2264
- ...(options.guards ?? []).filter(isGuardClass),
2265
1253
  // `useValue` even when `options.approvalActorRef` is `undefined` — AgentApiController
2266
1254
  // injects this WITHOUT `@Optional()`.
2267
1255
  {
@@ -2269,134 +1257,60 @@ var AgentApiModule = class _AgentApiModule {
2269
1257
  useValue: options.approvalActorRef
2270
1258
  }
2271
1259
  ],
2272
- // DASHBOARD_AUTH re-exported so AgentUiController/AgentDashboardAuthController (hosted
2273
- // directly by AgentDashboardModule, which imports this module) resolve the SAME instance
2274
- // instead of re-running a host's async factory a second time.
1260
+ // What a self-mounted `AgentApiController` subclass injects, too (`routes: false`).
2275
1261
  exports: [
2276
1262
  DashboardService,
2277
- DASHBOARD_AUTH
1263
+ DASHBOARD_APPROVAL_ACTOR_REF
2278
1264
  ]
2279
1265
  };
2280
1266
  }
2281
1267
  };
2282
- AgentApiModule = _ts_decorate8([
2283
- (0, import_common11.Module)({})
1268
+ AgentApiModule = _ts_decorate4([
1269
+ (0, import_common7.Module)({})
2284
1270
  ], AgentApiModule);
2285
1271
  var AgentDashboardModule = class _AgentDashboardModule {
2286
1272
  static {
2287
1273
  __name(this, "AgentDashboardModule");
2288
1274
  }
2289
1275
  static forRoot(options = {}) {
1276
+ assertProtected(options);
2290
1277
  const basePath = normalize(options.basePath ?? "/ai-gateway");
2291
1278
  const apiBasePath = normalize(options.apiBasePath ?? `${basePath}/api`);
2292
- stampGuards(options.guards, [
2293
- [
2294
- AgentUiController,
2295
- UI_BASE_GUARDS
2296
- ]
2297
- ]);
2298
- const dashboardAuthProvider = {
2299
- provide: DASHBOARD_AUTH,
2300
- useValue: resolveDashboardAuth(options.dashboardAuth)
2301
- };
2302
1279
  return {
2303
1280
  module: _AgentDashboardModule,
2304
1281
  imports: [
2305
1282
  ...options.imports ?? [],
2306
- // Guards + host imports must reach the API controller's HOST module — enhancers resolve
2307
- // from their controller's own module, never from a parent (see AgentApiModule.register).
2308
1283
  // Spread-only-when-set: exactOptionalPropertyTypes rejects an explicit `undefined`.
2309
1284
  AgentApiModule.register({
2310
1285
  ...options.imports ? {
2311
1286
  imports: options.imports
2312
1287
  } : {},
2313
- ...options.guards ? {
2314
- guards: options.guards
1288
+ ...options.decorators ? {
1289
+ decorators: options.decorators
2315
1290
  } : {},
2316
- ...options.approvalActorRef ? {
2317
- approvalActorRef: options.approvalActorRef
2318
- } : {},
2319
- dashboardAuth: dashboardAuthProvider
2320
- }),
2321
- import_core.RouterModule.register([
2322
- {
2323
- path: basePath,
2324
- module: _AgentDashboardModule
2325
- },
2326
- {
2327
- path: apiBasePath,
2328
- module: AgentApiModule
2329
- }
2330
- ])
2331
- ],
2332
- controllers: [
2333
- AgentUiController,
2334
- AgentDashboardAuthController
2335
- ],
2336
- providers: [
2337
- {
2338
- provide: DASHBOARD_BASE_PATH,
2339
- useValue: basePath
2340
- },
2341
- {
2342
- provide: DASHBOARD_API_PATH,
2343
- useValue: apiBasePath
2344
- },
2345
- DashboardAuthPageGuard,
2346
- // AgentUiController is hosted HERE, so its guards DI-instantiate from this module.
2347
- ...(options.guards ?? []).filter(isGuardClass)
2348
- ],
2349
- // Re-export the API module so its DashboardService reaches importers (e.g. the host's own controllers).
2350
- exports: [
2351
- AgentApiModule
2352
- ]
2353
- };
2354
- }
2355
- static forRootAsync(options) {
2356
- const basePath = normalize(options.basePath ?? "/ai-gateway");
2357
- const apiBasePath = normalize(options.apiBasePath ?? `${basePath}/api`);
2358
- stampGuards(options.guards, [
2359
- [
2360
- AgentUiController,
2361
- UI_BASE_GUARDS
2362
- ]
2363
- ]);
2364
- const dashboardAuthProvider = {
2365
- provide: DASHBOARD_AUTH,
2366
- inject: options.inject ?? [],
2367
- useFactory: /* @__PURE__ */ __name(async (...deps) => resolveDashboardAuth(await options.useDashboardAuth(...deps)), "useFactory")
2368
- };
2369
- return {
2370
- module: _AgentDashboardModule,
2371
- imports: [
2372
- ...options.imports ?? [],
2373
- AgentApiModule.register({
2374
- ...options.imports ? {
2375
- imports: options.imports
2376
- } : {},
2377
- ...options.guards ? {
2378
- guards: options.guards
1291
+ ...options.routes === false ? {
1292
+ routes: false
2379
1293
  } : {},
2380
1294
  ...options.approvalActorRef ? {
2381
1295
  approvalActorRef: options.approvalActorRef
2382
- } : {},
2383
- dashboardAuth: dashboardAuthProvider
1296
+ } : {}
2384
1297
  }),
2385
- import_core.RouterModule.register([
2386
- {
2387
- path: basePath,
2388
- module: _AgentDashboardModule
2389
- },
2390
- {
2391
- path: apiBasePath,
2392
- module: AgentApiModule
2393
- }
2394
- ])
2395
- ],
2396
- controllers: [
2397
- AgentUiController,
2398
- AgentDashboardAuthController
1298
+ ...options.routes === false ? [] : [
1299
+ import_core.RouterModule.register([
1300
+ {
1301
+ path: basePath,
1302
+ module: _AgentDashboardModule
1303
+ },
1304
+ {
1305
+ path: apiBasePath,
1306
+ module: AgentApiModule
1307
+ }
1308
+ ])
1309
+ ]
2399
1310
  ],
1311
+ controllers: options.routes === false ? [] : (0, import_nestjs_agent_core3.withControllerDecorators)([
1312
+ AgentUiController
1313
+ ], options.decorators),
2400
1314
  providers: [
2401
1315
  {
2402
1316
  provide: DASHBOARD_BASE_PATH,
@@ -2405,18 +1319,20 @@ var AgentDashboardModule = class _AgentDashboardModule {
2405
1319
  {
2406
1320
  provide: DASHBOARD_API_PATH,
2407
1321
  useValue: apiBasePath
2408
- },
2409
- DashboardAuthPageGuard,
2410
- ...(options.guards ?? []).filter(isGuardClass)
1322
+ }
2411
1323
  ],
1324
+ // Re-export the API module so its DashboardService reaches importers (e.g. the host's own
1325
+ // controllers), and the paths a self-mounted `AgentUiController` subclass injects.
2412
1326
  exports: [
2413
- AgentApiModule
1327
+ AgentApiModule,
1328
+ DASHBOARD_BASE_PATH,
1329
+ DASHBOARD_API_PATH
2414
1330
  ]
2415
1331
  };
2416
1332
  }
2417
1333
  };
2418
- AgentDashboardModule = _ts_decorate8([
2419
- (0, import_common11.Module)({})
1334
+ AgentDashboardModule = _ts_decorate4([
1335
+ (0, import_common7.Module)({})
2420
1336
  ], AgentDashboardModule);
2421
1337
  // Annotate the CommonJS export names for ESM import in node:
2422
1338
  0 && (module.exports = {
@@ -2427,16 +1343,13 @@ AgentDashboardModule = _ts_decorate8([
2427
1343
  AGENT_PRICING_STORE,
2428
1344
  AgentApiController,
2429
1345
  AgentApiModule,
2430
- AgentDashboardAuthController,
2431
1346
  AgentDashboardModule,
2432
1347
  AgentUiController,
2433
1348
  DASHBOARD_API_PATH,
2434
1349
  DASHBOARD_APPROVAL_ACTOR_REF,
2435
- DASHBOARD_AUTH,
2436
1350
  DASHBOARD_BASE_PATH,
2437
1351
  DashboardService,
2438
1352
  agentDashboardMountPaths,
2439
- parsePriceInput,
2440
- resolveDashboardAuth
1353
+ parsePriceInput
2441
1354
  });
2442
1355
  //# sourceMappingURL=index.cjs.map