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