@dudousxd/nestjs-agent-dashboard 0.18.0 → 0.19.1

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.
@@ -1,7 +1,7 @@
1
1
  import { ActorSpendRow, AgentGovernanceQueries, ActorDirectory, AgentPricingStore, AgentApprovalPort, GovernanceRange, ModelSpendRow, UsageTrendPoint, FeatureSpendRow, ThreadSpendRow, RunMetrics, RunAgentBreakdownRow, RunErrorBreakdownRow, RunTrendPoint, RecentRunRow, ToolCallActivityRow, GovernancePageQuery, ToolCallWhere, GovernancePage, RunWhere, PendingApprovalRow, ApprovalWhere, GovernanceRunDetail, GovernanceThreadDetailQuery, GovernanceThreadDetail, ThreadActivityRow, ToolStatRow, GenuiStats, ThreadWhere, CurrentModelPrice, ActorResolver, ModelPriceInput } from '@dudousxd/nestjs-agent-core';
2
2
  export { ActorDirectory } from '@dudousxd/nestjs-agent-core';
3
3
  import { Observable } from 'rxjs';
4
- import { DynamicModule, Type, CanActivate, Provider, InjectionToken, OptionalFactoryDependency, StreamableFile } from '@nestjs/common';
4
+ import { DynamicModule, StreamableFile } from '@nestjs/common';
5
5
 
6
6
  /** An actor-scoped row decorated with its resolved display label — `null` when unbound or unresolved. */
7
7
  interface WithActorLabel {
@@ -151,9 +151,8 @@ declare class DashboardService {
151
151
  * JSON + SSE API consumed by the AI-gateway console SPA. Mounted at `apiBasePath` (set by
152
152
  * `RouterModule` in {@link AgentDashboardModule.forRoot}), so the controller routes are relative.
153
153
  *
154
- * `@UseGuards(DashboardAuthGuard)` is a NO-OP unless the host configured `dashboardAuth` — see
155
- * that guard's own doc. Host `guards` (see {@link AgentDashboardOptions.guards}) are APPENDED onto
156
- * this baseline by `stampGuards` (`./guards.js`), never replacing it.
154
+ * Who reaches it is the app's: `decorators` on `AgentDashboardModule.forRoot`, or the app mounts it
155
+ * itself (`routes: false`) — with `@nestjs/authentication` / `@nestjs/authorization`.
157
156
  */
158
157
  declare class AgentApiController {
159
158
  private readonly dashboard;
@@ -263,185 +262,6 @@ declare class AgentApiController {
263
262
  }>;
264
263
  }
265
264
 
266
- /** The session user the host's `login` hook returns to mint a cookie. */
267
- interface DashboardSessionUser {
268
- id: string;
269
- name?: string;
270
- roles?: string[];
271
- }
272
-
273
- /**
274
- * Host hook for Mode A: validates the host's own auth on the raw request POSTed to
275
- * `<basePath>/auth/session`. Return the session user to grant access, or `null` to deny.
276
- */
277
- type SessionHook = (request: unknown) => Promise<DashboardSessionUser | null> | DashboardSessionUser | null;
278
- /** Host hook for Mode B: validates submitted credentials for the built-in login screen. */
279
- type LoginHook = (username: string, password: string) => Promise<DashboardSessionUser | null> | DashboardSessionUser | null;
280
- /**
281
- * Re-checks a LIVE session when the cookie is slid forward. Runs at most once per `ttl/2` PER
282
- * COOKIE GENERATION — the gate is on the inbound cookie's `iat`, so every request still carrying a
283
- * not-yet-renewed cookie would, on its own, invoke this hook again; `maybeRenewSession` de-dupes
284
- * concurrent calls for the same session (`sub` + `iat`) into a single in-flight call, so a page
285
- * load that fires N parallel API calls still costs exactly ONE host round-trip, not N. Still not a
286
- * per-session-lifetime cap — this can run again every `ttl/2` as the session keeps sliding, so a
287
- * slow or expensive check should still debounce/cache across renewal windows on its own. Return
288
- * `false` to revoke (the cookie is cleared and the request denied). Distinct from `session`: that
289
- * hook reads the host's auth off a fresh request, which a console XHR does not carry — this one
290
- * receives the already-minted session.
291
- */
292
- type RevalidateHook = (session: DashboardSessionUser) => Promise<boolean> | boolean;
293
- /** What `unauthenticatedPage` receives. An object (not positional args) so fields can be added later. */
294
- interface UnauthenticatedPageContext {
295
- /**
296
- * The platform-native request — Express' `Request`, Fastify's `FastifyRequest`. Typed `unknown`
297
- * for the same reason `SessionHook`'s is: this package refuses to depend on either platform.
298
- * Cast it to whatever your app actually runs on.
299
- */
300
- request: unknown;
301
- /**
302
- * The platform-native response. The hook OWNS it: it must write AND end it (`res.render(...)`,
303
- * `res.status(401).send(...)`, an Inertia render, ...). If the hook returns without writing, the
304
- * library falls back to its own built-in page rather than leaving the request hanging.
305
- */
306
- response: unknown;
307
- /** Where this console is mounted (e.g. `/ai-gateway`) — useful for a "back to the console" link. */
308
- basePath: string;
309
- }
310
- /**
311
- * Host-owned page for an unauthenticated navigation to the console.
312
- *
313
- * The built-in page cannot know who hosts the console, so it can only say "open this console from
314
- * your application" in the abstract — it can't name the launcher, link to it, or look like the rest
315
- * of the host's product. This hook hands the whole response to the host instead: render through
316
- * your own template engine, your own Inertia page, whatever.
317
- *
318
- * Served at `<basePath>/auth/session-required`, which is where `DashboardAuthPageGuard` already
319
- * redirects a denied Mode-A navigation today — this hook changes what that page CONTAINS, not the
320
- * flow that reaches it.
321
- *
322
- * Deliberately NOT a replacement for Mode B's built-in login form. A host that wants its own login
323
- * UI uses Mode A plus this hook, and posts to `<basePath>/auth/session` from its own page — the
324
- * mint endpoint is the supported primitive for that.
325
- *
326
- * Fail-closed by construction: it only ever runs on a request that has ALREADY been denied. A hook
327
- * that throws, or that returns without writing, falls back to the built-in page — it cannot let
328
- * anyone in.
329
- */
330
- type UnauthenticatedPageHook = (context: UnauthenticatedPageContext) => void | Promise<void>;
331
- /** Which `dashboardAuth` hook(s) a resolved config was given — see `resolveDashboardAuth`. */
332
- type AuthMode = 'session' | 'login';
333
- /**
334
- * Author-facing `dashboardAuth` option (see `AgentDashboardOptions.dashboardAuth`). Gates the
335
- * console (SPA + API) behind a signed session cookie. Two ways to mint that cookie: Mode A
336
- * (`session`) — the host frontend, already carrying its own auth, POSTs to
337
- * `<basePath>/auth/session` and the host hook decides — or Mode B (`login`) — the built-in,
338
- * dependency-free server-rendered login screen. Mirrors `@dudousxd/nestjs-telescope`'s
339
- * `dashboardAuth` two-mode shape. At least one of the two is required so an un-mintable gate is a
340
- * boot error, not a silently-open (or silently-stuck) console.
341
- */
342
- interface DashboardAuthOptions {
343
- /** REQUIRED HMAC-SHA256 signing key (32+ bytes recommended). Missing/empty => boot error (fail closed). */
344
- secret: string;
345
- /** Cookie TTL (duration string `'<n><ms|s|m|h|d>'`, e.g. `'30m'`, `'7d'`). Default `'8h'`. */
346
- ttl?: string;
347
- /**
348
- * Mode A: validates the host's own auth on the raw request POSTed to `<basePath>/auth/session`.
349
- * Return the session user to grant access, or `null` to deny. No credential reaches this
350
- * library — the host decides from whatever it already has (a header, an SSO cookie, ...).
351
- */
352
- session?: SessionHook;
353
- /**
354
- * Mode B: validates submitted username/password. Return the session user to grant access, or
355
- * `null` to deny — the login endpoint responds identically (generic failure) for an unknown user
356
- * and a wrong password, so it never reveals which one was wrong.
357
- */
358
- login?: LoginHook;
359
- /** Re-checks a live session on sliding renewal; see `RevalidateHook`. Not a mode — it cannot
360
- * mint a session, only revoke one already minted by `session`/`login`. */
361
- revalidate?: RevalidateHook;
362
- /** Renders the host's own page for an unauthenticated navigation, in place of the built-in
363
- * "open this console from your application" card; see `UnauthenticatedPageHook`. */
364
- unauthenticatedPage?: UnauthenticatedPageHook;
365
- }
366
- /** Resolved, validated `dashboardAuth` config used by the guards/controller. */
367
- interface ResolvedDashboardAuth {
368
- secret: string;
369
- ttlMs: number;
370
- modes: AuthMode[];
371
- session?: SessionHook;
372
- login?: LoginHook;
373
- revalidate?: RevalidateHook;
374
- unauthenticatedPage?: UnauthenticatedPageHook;
375
- }
376
- /**
377
- * Validate + resolve `dashboardAuth`. Returns `null` when unconfigured (behavior unchanged — the
378
- * console stays open, front it with your own `guards`). Throws at boot (fail closed) when
379
- * configured but missing a secret, when neither `session` nor `login` is given, or when a given
380
- * hook isn't a function — the host learns immediately rather than shipping an open, stuck, or
381
- * un-mintable console.
382
- */
383
- declare function resolveDashboardAuth(options: DashboardAuthOptions | undefined): ResolvedDashboardAuth | null;
384
-
385
- /** The slice of the platform request this controller reads — structural, no Express/Fastify dependency. */
386
- interface AuthPageRequest {
387
- headers: Record<string, string | string[] | undefined>;
388
- }
389
- /** The slice of the platform response this controller writes (passthrough mode — Nest still sends). */
390
- interface AuthPageResponse {
391
- status(code: number): unknown;
392
- setHeader(name: string, value: string): unknown;
393
- }
394
- interface LoginFormBody {
395
- username?: unknown;
396
- password?: unknown;
397
- returnTo?: unknown;
398
- }
399
- /**
400
- * Mounted directly on `AgentDashboardModule` at `<basePath>/auth/*` — a SEPARATE controller from
401
- * `AgentUiController`/`AgentApiController` so it carries neither `DashboardAuthPageGuard`,
402
- * `DashboardAuthGuard`, nor any host `guards`: these routes MINT (and clear) the session cookie the
403
- * built-in gates check for, so they can never be made to require the very auth they grant. Mirrors
404
- * `@dudousxd/nestjs-telescope`'s own auth controller staying outside its `stampGuards` call.
405
- *
406
- * Two ways to mint that cookie, matching `resolveDashboardAuth`'s modes: Mode A (`session`) — the
407
- * host frontend, already carrying its own auth, POSTs to `<basePath>/auth/session` and the host
408
- * hook decides — or Mode B (`login`), a dependency-free, server-rendered login form (GET/POST) —
409
- * the bundled React SPA in this package is a built Vite artifact with no auth-aware UI of its own,
410
- * so gating the actual page navigation needs a self-contained flow that doesn't touch it. Each
411
- * mode's routes 404 when that mode isn't listed in `auth.modes` — the single source of truth for
412
- * which mode(s) are configured, not hook-presence truthiness — and every route 404s outright when
413
- * `dashboardAuth` is unconfigured (`DASHBOARD_AUTH` resolves to `null`) — no dangling login page
414
- * when the feature is off.
415
- */
416
- declare class AgentDashboardAuthController {
417
- private readonly auth;
418
- private readonly basePath;
419
- private readonly logger;
420
- /** Warn once PER HOOK KIND (not per request) so a broken hook can't be used to flood the logs. */
421
- private readonly warnedHooks;
422
- constructor(auth: ResolvedDashboardAuth | null, basePath: string);
423
- loginPage(req: AuthPageRequest, res: AuthPageResponse, returnToQuery?: string, error?: string): string;
424
- login(body: LoginFormBody, req: unknown, res: AuthPageResponse): Promise<string>;
425
- logout(req: unknown, res: AuthPageResponse): string;
426
- session(request: unknown, response: unknown): Promise<void>;
427
- sessionRequiredPage(req: AuthPageRequest, res: unknown): Promise<void>;
428
- /** Uniform failure: same redirect (generic error flag) whether the user is unknown or the password is wrong. */
429
- private redirectToLoginError;
430
- private currentSession;
431
- /**
432
- * Run a host hook (`login` or `session`) defensively: a throw (sync or async) is treated as a
433
- * denial (`null`) and warn-logged ONCE PER KIND, so a buggy/unreachable hook never 500s the
434
- * endpoint into a stack-trace leak nor floods the logs on repeated bad attempts.
435
- */
436
- private runHook;
437
- /**
438
- * Warn once per hook kind for the life of the process, not once per request: a broken hook fires
439
- * on every denied navigation and would otherwise flood the logs.
440
- */
441
- private warnHookOnce;
442
- private requireAuth;
443
- }
444
-
445
265
  /** Same shape {@link AgentDashboardModule.forRoot} accepts — kept local so this stays a pure, DI-free helper. */
446
266
  interface AgentDashboardMountPathsOptions {
447
267
  basePath?: string;
@@ -475,9 +295,7 @@ declare function agentDashboardMountPaths(options?: AgentDashboardMountPathsOpti
475
295
 
476
296
  /**
477
297
  * `TReq` mirrors core's `ActorResolver<TReq>` convention: the transport request type
478
- * {@link AgentDashboardOptions.approvalActorRef} receives. Defaults to `unknown` so untyped usage
479
- * compiles unchanged; a host may narrow it (e.g. `forRoot<Request>({ approvalActorRef: ... })`)
480
- * instead of writing its own `unknown`-narrowing type guard.
298
+ * {@link AgentDashboardOptions.approvalActorRef} receives. Defaults to `unknown`.
481
299
  */
482
300
  interface AgentDashboardOptions<TReq = unknown> {
483
301
  /**
@@ -492,20 +310,26 @@ interface AgentDashboardOptions<TReq = unknown> {
492
310
  */
493
311
  apiBasePath?: string;
494
312
  /**
495
- * Guard classes fronting BOTH dashboard controllers (the SPA at `basePath` and its JSON API at
496
- * `apiBasePath`) — APPENDED onto the built-in `dashboardAuth` gate (a no-op unless configured;
497
- * see {@link dashboardAuth}), so a request must pass BOTH. Omit to leave the routes gated by
498
- * `dashboardAuth` alone (or fully open when that's unset too).
313
+ * Who reaches the console: class decorators applied to every controller this module mounts — the
314
+ * ecosystem's convention, like `@nestjs/mcp`'s `decorators` — with the official tools, e.g.
315
+ * `[UseGuards(AuthenticationGuard), Can(ConsolePolicy, 'view')]` from `@nestjs/authentication` /
316
+ * `@nestjs/authorization`, or a function as a guard instance, `UseGuards({ canActivate })`.
317
+ * Applied to a per-registration subclass, so nothing sticks to the shared classes.
499
318
  *
500
- * A guard's own DEPENDENCIES resolve from this module's `imports` (see {@link imports}) — the
501
- * dashboard module has no application context of its own to pull them from otherwise.
319
+ * In production (`NODE_ENV=production`) the console refuses to boot without them, unless the app
320
+ * mounts the routes itself (`routes: false`): a governance console is never served open there by
321
+ * default. Outside production the routes are open (and to `@nestjs/authorization`'s
322
+ * deny-by-default guard: `CanAnyone()`). Static wiring.
502
323
  */
503
- guards?: Type<CanActivate>[];
324
+ decorators?: ClassDecorator[];
504
325
  /**
505
- * Extra `imports` merged into the dashboard's dynamic module — the DI resolution path for a class
506
- * passed to {@link guards} (or any other provider the controllers need reachable). Typically the
507
- * host's own auth module, e.g. `imports: [AuthModule]` alongside `guards: [JwtAuthGuard]`.
326
+ * `false` mounts none of the console's routes, while its services still run — the way NestJS's
327
+ * own packages leave routes to you: serve them from controllers of your own, protected with the
328
+ * official tools, by extending the exported `AgentApiController` / `AgentUiController` under your
329
+ * own path and decorators (the module exports what they inject). Static wiring.
508
330
  */
331
+ routes?: boolean;
332
+ /** Extra `imports` merged into the console's modules — what a decorator's guard injects. */
509
333
  imports?: DynamicModule['imports'];
510
334
  /**
511
335
  * OVERRIDE for WHO is deciding a HITL approval — invoked on the incoming
@@ -514,95 +338,27 @@ interface AgentDashboardOptions<TReq = unknown> {
514
338
  * DEFAULT (option omitted): the AgentModule-configured actor resolver (`AGENT_ACTOR_RESOLVER`) is
515
339
  * consulted — the same identity seam chat requests use — and its actor id becomes the decider ref
516
340
  * (a throwing resolver, i.e. an unauthenticated request, just omits the ref). Set this only when
517
- * console auth differs from chat auth (e.g. the console sits behind a separate SSO whose principal
518
- * the chat resolver can't read); returning `undefined` leaves `executedByRef` unset — the explicit
519
- * override wins outright, with no resolver fallback.
341
+ * the console's caller is identified differently from chat's; returning `undefined` leaves
342
+ * `executedByRef` unset — the explicit override wins outright, with no resolver fallback.
520
343
  */
521
344
  approvalActorRef?: (req: TReq) => string | undefined;
522
- /**
523
- * Gate the console (SPA + API) behind a built-in, signed session cookie. Two ways to mint it:
524
- *
525
- * - **Mode A (`session`, recommended)**: your host app already has its own auth (SSO/OIDC/
526
- * whatever) — the host frontend, carrying that auth, POSTs to `<basePath>/auth/session`, your
527
- * `session` hook validates the raw request and returns the session user, and this library
528
- * mints its cookie from that. No credential this library understands ever exists; you keep
529
- * your own identity provider as the source of truth. A page-level request with no valid
530
- * session (and only Mode A configured) gets a small server-rendered instruction page telling
531
- * the visitor to sign in through your host app, since there is no login page to redirect to.
532
- * - **Mode B (`login`, standalone fallback)**: no host frontend/IdP to lean on — the console
533
- * serves its own small, dependency-free, server-rendered login page (`GET
534
- * <basePath>/auth/login`) and your `login` hook validates submitted username/password. A
535
- * missing/invalid/expired session redirects a page-level request to that login page with
536
- * `?returnTo=<original url>`.
537
- *
538
- * Either mode can be used alone, or both together (e.g. Mode A for normal use, Mode B as a
539
- * break-glass fallback) — at least one is required, or `forRoot`/`forRootAsync` throws at boot
540
- * (an un-mintable gate is a boot error, not a silently-open or silently-stuck console). An
541
- * unauthenticated API call always gets a plain `401`, regardless of mode — the caller reads the
542
- * status code, not HTML. Composes with `guards` — BOTH gates must pass. See
543
- * `DashboardAuthOptions` for the `secret`/`ttl`/`session`/`login` shape.
544
- */
545
- dashboardAuth?: DashboardAuthOptions;
546
345
  }
547
- /**
548
- * Async variant of {@link AgentDashboardOptions}, for a `session`/`login` hook that needs injected
549
- * services (e.g. an EntityManager to check credentials against a DB). Everything else stays
550
- * static/sync — `basePath`/`apiBasePath`/`guards` are needed at module-build time (the same
551
- * constraint `@dudousxd/nestjs-telescope`'s and `@dudousxd/nestjs-media`'s own `forRootAsync`s
552
- * document), so only the auth piece itself is resolved through DI.
553
- */
554
- interface AgentDashboardAsyncOptions<TReq = unknown> {
555
- basePath?: string;
556
- apiBasePath?: string;
557
- guards?: Type<CanActivate>[];
558
- imports?: DynamicModule['imports'];
559
- approvalActorRef?: (req: TReq) => string | undefined;
560
- /** Providers injected into `useDashboardAuth`, in order. Shared with a guard class's own deps via `imports`. */
561
- inject?: Array<InjectionToken | OptionalFactoryDependency>;
562
- /**
563
- * Build the `dashboardAuth` config from injected deps, or return `undefined` to leave the
564
- * console open (or fronted only by `guards`). See {@link AgentDashboardOptions.dashboardAuth}.
565
- */
566
- useDashboardAuth: (...deps: any[]) => DashboardAuthOptions | undefined | Promise<DashboardAuthOptions | undefined>;
567
- }
568
- /**
569
- * Holds the JSON API + SSE controller and its read service, mounted on its own path by `forRoot`.
570
- * Dynamic: guards are DI-instantiated by the CONTROLLER's host module, so this module — not the
571
- * outer wrapper — must carry the guard classes as providers plus the host's `imports` that resolve
572
- * their dependencies. A static module here made `guards: [SomeGuardWithDeps]` fail at boot with
573
- * "Nest can't resolve dependencies ... in the AgentApiModule context" even when the host passed
574
- * the right `imports` to `forRoot`.
575
- */
346
+ /** Holds the JSON API + SSE controller and its read service, mounted on its own path. */
576
347
  declare class AgentApiModule {
577
348
  static register<TReq = unknown>(options: {
578
349
  imports?: DynamicModule['imports'];
579
- guards?: Type<CanActivate>[];
350
+ decorators?: ClassDecorator[];
351
+ routes?: boolean;
580
352
  approvalActorRef?: (req: TReq) => string | undefined;
581
- /** Provider for `DASHBOARD_AUTH` — a `useValue` (`forRoot`) or a `useFactory` (`forRootAsync`). */
582
- dashboardAuth: Provider;
583
353
  }): DynamicModule;
584
354
  }
585
355
  /**
586
- * Mounts the AI-gateway governance console: the bundled React SPA at `basePath` and its JSON + SSE
587
- * API at `apiBasePath` (default `<basePath>/api`), plus the built-in `dashboardAuth` routes at
588
- * `<basePath>/auth/*` when {@link AgentDashboardOptions.dashboardAuth} is set — `POST
589
- * <basePath>/auth/session` for Mode A (the host mints the session from its own auth) and/or `GET`/
590
- * `POST <basePath>/auth/login` for Mode B (the built-in login screen).
591
- *
592
- * Import via `AgentDashboardModule.forRoot(...)` alongside your `@dudousxd/nestjs-agent` module
593
- * (global), which must provide `AGENT_GOVERNANCE_QUERIES` (bound by a store adapter). Front the
594
- * routes with the first-class `guards` option (plus `imports` for the guards' own dependencies) —
595
- * see {@link AgentDashboardOptions.guards} — and/or the built-in `dashboardAuth` session cookie.
596
- *
597
- * Inertia hosts: the console is a full-page app, not an Inertia page. An in-app `<Link>` visit to
598
- * `basePath` (an XHR carrying `X-Inertia`) is bounced with the protocol's own external-redirect
599
- * mechanism — `409 Conflict` + `X-Inertia-Location: <the visited URL>` — so the Inertia client
600
- * performs a full `window.location` load and the console renders normally. In-app links to the
601
- * console therefore just work; no host-side special-casing needed.
356
+ * The AI-gateway console: the SPA at `basePath` and its JSON API at `apiBasePath`. Who reaches them
357
+ * is the app's — `decorators`, or the app mounts them itself (`routes: false`) — with
358
+ * `@nestjs/authentication` / `@nestjs/authorization`.
602
359
  */
603
360
  declare class AgentDashboardModule {
604
361
  static forRoot<TReq = unknown>(options?: AgentDashboardOptions<TReq>): DynamicModule;
605
- static forRootAsync<TReq = unknown>(options: AgentDashboardAsyncOptions<TReq>): DynamicModule;
606
362
  }
607
363
 
608
364
  /**
@@ -624,11 +380,8 @@ interface UiPageResponse {
624
380
  * `<base>/assets`). The path comes from `RouterModule` (set by
625
381
  * {@link AgentDashboardModule.forRoot}({ basePath })), so the controller routes are relative.
626
382
  *
627
- * `@UseGuards(DashboardAuthPageGuard)` is a NO-OP unless the host configured `dashboardAuth` — see
628
- * that guard's own doc. Host `guards` (see {@link AgentDashboardOptions.guards}) are APPENDED onto
629
- * this baseline by `stampGuards` (`./guards.js`), never replacing it. `@UseFilters` turns the
630
- * guard's redirect-on-deny into an actual 302 response; it is a no-op when the guard never throws
631
- * (i.e. `dashboardAuth` unconfigured).
383
+ * Who reaches it is the app's: `decorators` on `AgentDashboardModule.forRoot`, or the app mounts it
384
+ * itself (`routes: false`) — with `@nestjs/authentication` / `@nestjs/authorization`.
632
385
  */
633
386
  declare class AgentUiController {
634
387
  private readonly basePath;
@@ -702,13 +455,5 @@ declare const DASHBOARD_API_PATH: unique symbol;
702
455
  * injecting it needs no `@Optional()`.
703
456
  */
704
457
  declare const DASHBOARD_APPROVAL_ACTOR_REF: unique symbol;
705
- /**
706
- * DI token carrying the resolved `dashboardAuth` config (`ResolvedDashboardAuth | null`) — `null`
707
- * when the host didn't configure it (the built-in guards are then a no-op, today's behavior
708
- * byte-for-byte). Bound once by `AgentApiModule.register` and re-exported so `AgentUiController`
709
- * and `AgentDashboardAuthController` (hosted directly by `AgentDashboardModule`, which imports
710
- * `AgentApiModule`) resolve the SAME instance rather than re-running a host's async factory twice.
711
- */
712
- declare const DASHBOARD_AUTH: unique symbol;
713
458
 
714
- export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_GOVERNANCE_QUERIES, AGENT_PRICING_STORE, type ActorSpendRowWithLabel, AgentApiController, AgentApiModule, type AgentDashboardAsyncOptions, AgentDashboardAuthController, AgentDashboardModule, type AgentDashboardMountPathsOptions, type AgentDashboardOptions, AgentUiController, type AuthMode, DASHBOARD_API_PATH, DASHBOARD_APPROVAL_ACTOR_REF, DASHBOARD_AUTH, DASHBOARD_BASE_PATH, type DashboardAuthOptions, DashboardService, type LiveAgentEvent, type LoginHook, type ReliabilityOverview, type ResolvedDashboardAuth, type RevalidateHook, type RunDetailWithLabel, type SessionHook, type SpendOverview, type ThreadActivityRowWithLabel, type ThreadDetailWithLabel, type ThreadSpendRowWithLabel, type UnauthenticatedPageContext, type UnauthenticatedPageHook, type WithActorLabel, agentDashboardMountPaths, parsePriceInput, resolveDashboardAuth };
459
+ export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_GOVERNANCE_QUERIES, AGENT_PRICING_STORE, type ActorSpendRowWithLabel, AgentApiController, AgentApiModule, AgentDashboardModule, type AgentDashboardMountPathsOptions, type AgentDashboardOptions, AgentUiController, DASHBOARD_API_PATH, DASHBOARD_APPROVAL_ACTOR_REF, DASHBOARD_BASE_PATH, DashboardService, type LiveAgentEvent, type ReliabilityOverview, type RunDetailWithLabel, type SpendOverview, type ThreadActivityRowWithLabel, type ThreadDetailWithLabel, type ThreadSpendRowWithLabel, type WithActorLabel, agentDashboardMountPaths, parsePriceInput };