@dudousxd/nestjs-agent-dashboard 0.19.1 → 0.20.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 +121 -27
- package/dist/client/agent-client.d.ts +13 -0
- package/dist/client/agent-client.d.ts.map +1 -1
- package/dist/client/agent-client.js +30 -3
- package/dist/client/agent-client.js.map +1 -1
- package/dist/server/index.cjs +437 -49
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +150 -18
- package/dist/server/index.d.ts +150 -18
- package/dist/server/index.js +400 -35
- package/dist/server/index.js.map +1 -1
- package/dist/spa/assets/index-ClnZsvJ1.css +1 -0
- package/dist/spa/assets/index-D3yTBCU0.js +1 -0
- package/dist/spa/assets/{index-eW1zMwDF.js → index-DS11tOEH.js} +1 -1
- package/dist/spa/assets/{preview-Ch59R-LE.js → preview-CbqJ2CAQ.js} +1 -1
- package/dist/spa/index.html +3 -3
- package/dist/spa/preview.html +3 -3
- package/package.json +10 -4
- package/dist/spa/assets/index-B1znMy6W.css +0 -1
- package/dist/spa/assets/index-DzukxAmy.js +0 -1
package/dist/server/index.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
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, StreamableFile } from '@nestjs/common';
|
|
4
|
+
import { ExecutionContext, Type, Logger, DynamicModule, StreamableFile, HttpException, ExceptionFilter, ArgumentsHost, CanActivate, OnModuleInit } from '@nestjs/common';
|
|
5
|
+
import { ModuleRef, HttpAdapterHost } from '@nestjs/core';
|
|
5
6
|
|
|
6
7
|
/** An actor-scoped row decorated with its resolved display label — `null` when unbound or unresolved. */
|
|
7
8
|
interface WithActorLabel {
|
|
@@ -151,8 +152,9 @@ declare class DashboardService {
|
|
|
151
152
|
* JSON + SSE API consumed by the AI-gateway console SPA. Mounted at `apiBasePath` (set by
|
|
152
153
|
* `RouterModule` in {@link AgentDashboardModule.forRoot}), so the controller routes are relative.
|
|
153
154
|
*
|
|
154
|
-
* Who reaches it
|
|
155
|
-
* itself (`routes: false`)
|
|
155
|
+
* Who reaches it: `authorize` on `AgentDashboardModule.forRoot` (checked by `ConsoleAuthorizeGuard`,
|
|
156
|
+
* after the app's `decorators`). Mounted by the app itself (`routes: false`), apply
|
|
157
|
+
* `UseConsoleAuthorize()` to your subclass.
|
|
156
158
|
*/
|
|
157
159
|
declare class AgentApiController {
|
|
158
160
|
private readonly dashboard;
|
|
@@ -293,6 +295,72 @@ interface AgentDashboardMountPathsOptions {
|
|
|
293
295
|
*/
|
|
294
296
|
declare function agentDashboardMountPaths(options?: AgentDashboardMountPathsOptions): string[];
|
|
295
297
|
|
|
298
|
+
/** What an `authorize` check answers. */
|
|
299
|
+
type ConsoleAuthorizeResult = boolean | {
|
|
300
|
+
allowed: true;
|
|
301
|
+
} | {
|
|
302
|
+
allowed: false;
|
|
303
|
+
reason?: 'unauthenticated' | 'forbidden';
|
|
304
|
+
} | {
|
|
305
|
+
redirectTo: string;
|
|
306
|
+
};
|
|
307
|
+
/** Class form: an @Injectable() provider (constructor injection works). */
|
|
308
|
+
interface ConsoleAuthorizer {
|
|
309
|
+
authorize(context: ExecutionContext): ConsoleAuthorizeResult | Promise<ConsoleAuthorizeResult>;
|
|
310
|
+
}
|
|
311
|
+
type ConsoleAuthorizerClass = Type<ConsoleAuthorizer>;
|
|
312
|
+
/** @nestjs/authorization policy check: policy[ability](user). */
|
|
313
|
+
interface ConsolePolicyCheck {
|
|
314
|
+
policy: Type<unknown>;
|
|
315
|
+
ability: string;
|
|
316
|
+
}
|
|
317
|
+
/** Who reaches the console. */
|
|
318
|
+
type ConsoleAuthorize = ((context: ExecutionContext) => ConsoleAuthorizeResult | Promise<ConsoleAuthorizeResult>) | ConsoleAuthorizerClass | (() => Promise<{
|
|
319
|
+
default: ConsoleAuthorizerClass;
|
|
320
|
+
}>) | ConsolePolicyCheck | string;
|
|
321
|
+
/** A normalized `authorize` answer. */
|
|
322
|
+
type ConsoleDecision = {
|
|
323
|
+
allowed: true;
|
|
324
|
+
} | {
|
|
325
|
+
allowed: false;
|
|
326
|
+
reason: 'unauthenticated' | 'forbidden';
|
|
327
|
+
redirectTo?: string;
|
|
328
|
+
};
|
|
329
|
+
/** What a resolved `authorize` is: called once per request, never throws. */
|
|
330
|
+
type ConsoleDecide = (context: ExecutionContext) => Promise<ConsoleDecision>;
|
|
331
|
+
/**
|
|
332
|
+
* The provider that resolves gate names (`authorize: 'console.agent'`), bound globally by
|
|
333
|
+
* `@dudousxd/nestjs-authz`'s `AuthzModule`. A registry symbol, so it is found without depending on
|
|
334
|
+
* that package.
|
|
335
|
+
*/
|
|
336
|
+
declare const CONSOLE_GATE: unique symbol;
|
|
337
|
+
interface ConsoleGate {
|
|
338
|
+
allows(name: string, context: ExecutionContext): Promise<ConsoleAuthorizeResult>;
|
|
339
|
+
}
|
|
340
|
+
/** The one boot warning for a console with no `authorize`. Same wording in every Aviary console. */
|
|
341
|
+
declare const CONSOLE_AUTHORIZE_MISSING_WARNING = "[@dudousxd/nestjs-agent-dashboard] console has no `authorize` configured: it is open outside production and denies every request in production. Set `authorize` in AgentDashboardModule.forRoot().";
|
|
342
|
+
/** Turns any {@link ConsoleAuthorizeResult} into a {@link ConsoleDecision}. */
|
|
343
|
+
declare function normalizeConsoleResult(result: unknown): ConsoleDecision;
|
|
344
|
+
/**
|
|
345
|
+
* Resolves `authorize` into one function the guard calls per request. Configuration mistakes (a
|
|
346
|
+
* gate name without nestjs-authz, a policy without `@nestjs/authorization`) throw here, so call it
|
|
347
|
+
* at boot. The returned function never throws: an error is a `forbidden`.
|
|
348
|
+
*
|
|
349
|
+
* `authorize` omitted: open outside production, `forbidden` for every request in production (read
|
|
350
|
+
* when this runs), and one warning logged (unless `warnIfMissing: false`).
|
|
351
|
+
*/
|
|
352
|
+
declare function resolveConsoleAuthorize(authorize: ConsoleAuthorize | undefined, moduleRef: ModuleRef, options?: {
|
|
353
|
+
logger?: Logger;
|
|
354
|
+
warnIfMissing?: boolean;
|
|
355
|
+
}): Promise<ConsoleDecide>;
|
|
356
|
+
/**
|
|
357
|
+
* `authorize` by a bearer token: allows when `Authorization: Bearer <token>` matches (compared in
|
|
358
|
+
* constant time), else `unauthenticated`. Header only. An empty token throws here, at config time.
|
|
359
|
+
*/
|
|
360
|
+
declare function authorizeByToken(options: {
|
|
361
|
+
token: string | undefined;
|
|
362
|
+
}): (context: ExecutionContext) => ConsoleAuthorizeResult;
|
|
363
|
+
|
|
296
364
|
/**
|
|
297
365
|
* `TReq` mirrors core's `ActorResolver<TReq>` convention: the transport request type
|
|
298
366
|
* {@link AgentDashboardOptions.approvalActorRef} receives. Defaults to `unknown`.
|
|
@@ -310,23 +378,28 @@ interface AgentDashboardOptions<TReq = unknown> {
|
|
|
310
378
|
*/
|
|
311
379
|
apiBasePath?: string;
|
|
312
380
|
/**
|
|
313
|
-
* Who reaches the console
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
* `@nestjs
|
|
317
|
-
* Applied to a per-registration subclass, so nothing sticks to the shared classes.
|
|
381
|
+
* Who reaches the console (the SPA and every API/SSE route): an inline function
|
|
382
|
+
* `(ctx) => boolean | { allowed } | { redirectTo }`, an `@Injectable()` `ConsoleAuthorizer` class,
|
|
383
|
+
* a lazy import of one, `{ policy, ability }` (`@nestjs/authorization`), or a gate name
|
|
384
|
+
* (`@dudousxd/nestjs-authz`). `authorizeByToken({ token })` checks a bearer token.
|
|
318
385
|
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
|
|
322
|
-
|
|
386
|
+
* Omitted: open outside production; in production every request answers 403 (and a warning is
|
|
387
|
+
* logged at boot).
|
|
388
|
+
*/
|
|
389
|
+
authorize?: ConsoleAuthorize;
|
|
390
|
+
/**
|
|
391
|
+
* Class decorators applied to every controller this module mounts, before the console's own
|
|
392
|
+
* `authorize` check — e.g. `[UseGuards(AuthenticationGuard)]` so `request.user` is set when
|
|
393
|
+
* `authorize` runs. Applied to a per-registration subclass, so nothing sticks to the shared
|
|
394
|
+
* classes. They do not replace `authorize`. Static wiring.
|
|
323
395
|
*/
|
|
324
396
|
decorators?: ClassDecorator[];
|
|
325
397
|
/**
|
|
326
398
|
* `false` mounts none of the console's routes, while its services still run — the way NestJS's
|
|
327
399
|
* own packages leave routes to you: serve them from controllers of your own, protected with the
|
|
328
400
|
* official tools, by extending the exported `AgentApiController` / `AgentUiController` under your
|
|
329
|
-
* own path and decorators (the module exports what they inject)
|
|
401
|
+
* own path and decorators (the module exports what they inject); `UseConsoleAuthorize()` applies
|
|
402
|
+
* this module's `authorize` to them. Static wiring.
|
|
330
403
|
*/
|
|
331
404
|
routes?: boolean;
|
|
332
405
|
/** Extra `imports` merged into the console's modules — what a decorator's guard injects. */
|
|
@@ -350,12 +423,12 @@ declare class AgentApiModule {
|
|
|
350
423
|
decorators?: ClassDecorator[];
|
|
351
424
|
routes?: boolean;
|
|
352
425
|
approvalActorRef?: (req: TReq) => string | undefined;
|
|
426
|
+
authorize?: ConsoleAuthorize;
|
|
353
427
|
}): DynamicModule;
|
|
354
428
|
}
|
|
355
429
|
/**
|
|
356
430
|
* The AI-gateway console: the SPA at `basePath` and its JSON API at `apiBasePath`. Who reaches them
|
|
357
|
-
* is
|
|
358
|
-
* `@nestjs/authentication` / `@nestjs/authorization`.
|
|
431
|
+
* is `authorize` (see {@link AgentDashboardOptions.authorize}).
|
|
359
432
|
*/
|
|
360
433
|
declare class AgentDashboardModule {
|
|
361
434
|
static forRoot<TReq = unknown>(options?: AgentDashboardOptions<TReq>): DynamicModule;
|
|
@@ -380,8 +453,9 @@ interface UiPageResponse {
|
|
|
380
453
|
* `<base>/assets`). The path comes from `RouterModule` (set by
|
|
381
454
|
* {@link AgentDashboardModule.forRoot}({ basePath })), so the controller routes are relative.
|
|
382
455
|
*
|
|
383
|
-
* Who reaches it
|
|
384
|
-
* itself (`routes: false`)
|
|
456
|
+
* Who reaches it: `authorize` on `AgentDashboardModule.forRoot` (checked by `ConsoleAuthorizeGuard`,
|
|
457
|
+
* after the app's `decorators`). Mounted by the app itself (`routes: false`), apply
|
|
458
|
+
* `UseConsoleAuthorize()` to your subclass.
|
|
385
459
|
*/
|
|
386
460
|
declare class AgentUiController {
|
|
387
461
|
private readonly basePath;
|
|
@@ -392,6 +466,62 @@ declare class AgentUiController {
|
|
|
392
466
|
asset(file: string): StreamableFile;
|
|
393
467
|
}
|
|
394
468
|
|
|
469
|
+
/** What {@link DashboardConsoleAccess} is built from (bound per `forRoot`). */
|
|
470
|
+
interface DashboardConsoleOptions {
|
|
471
|
+
authorize?: ConsoleAuthorize;
|
|
472
|
+
}
|
|
473
|
+
/** Holds the console's resolved `authorize` check for one registration. */
|
|
474
|
+
declare class DashboardConsoleAccess implements OnModuleInit {
|
|
475
|
+
#private;
|
|
476
|
+
private readonly options;
|
|
477
|
+
private readonly moduleRef;
|
|
478
|
+
constructor(options: DashboardConsoleOptions, moduleRef: ModuleRef);
|
|
479
|
+
/** Resolves `authorize` at boot: a configuration mistake fails the boot, and the warning logs once. */
|
|
480
|
+
onModuleInit(): Promise<void>;
|
|
481
|
+
/** The decision for one request. */
|
|
482
|
+
check(context: ExecutionContext): Promise<ConsoleDecision>;
|
|
483
|
+
}
|
|
484
|
+
/** Marks a controller or handler as serving pages: a denied browser navigation gets HTML or a 302. */
|
|
485
|
+
declare const CONSOLE_PAGE_METADATA = "@dudousxd/nestjs-agent-dashboard:console-page";
|
|
486
|
+
/**
|
|
487
|
+
* On a controller or a handler that serves pages: a denied `GET` that accepts HTML gets a page (or a
|
|
488
|
+
* 302 for `redirectTo`), not JSON.
|
|
489
|
+
*/
|
|
490
|
+
declare const ConsolePage: () => ClassDecorator & MethodDecorator;
|
|
491
|
+
/** Thrown by {@link ConsoleAuthorizeGuard}; its body is the JSON answer even without the filter. */
|
|
492
|
+
declare class ConsoleAccessDenied extends HttpException {
|
|
493
|
+
readonly decision: Exclude<ConsoleDecision, {
|
|
494
|
+
allowed: true;
|
|
495
|
+
}>;
|
|
496
|
+
readonly page: boolean;
|
|
497
|
+
constructor(decision: Exclude<ConsoleDecision, {
|
|
498
|
+
allowed: true;
|
|
499
|
+
}>, page: boolean);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Runs the console's `authorize` on every route of a controller it guards. Applied by the module
|
|
503
|
+
* after the app's `decorators` (so authentication guards have already set `request.user`); a
|
|
504
|
+
* self-mounted controller (`routes: false`) applies it with {@link UseConsoleAuthorize}.
|
|
505
|
+
*/
|
|
506
|
+
declare class ConsoleAuthorizeGuard implements CanActivate {
|
|
507
|
+
private readonly access;
|
|
508
|
+
constructor(access: DashboardConsoleAccess);
|
|
509
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
510
|
+
}
|
|
511
|
+
/** Writes a console denial: JSON for API calls; a 302 or an HTML page (403 / 401) for page navigations. */
|
|
512
|
+
declare class ConsoleAuthorizeFilter implements ExceptionFilter<ConsoleAccessDenied> {
|
|
513
|
+
private readonly adapterHost;
|
|
514
|
+
constructor(adapterHost: HttpAdapterHost);
|
|
515
|
+
catch(exception: ConsoleAccessDenied, host: ArgumentsHost): void;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* The console's access check on a controller of your own (with `routes: false`): the
|
|
519
|
+
* {@link ConsoleAuthorizeGuard} plus the filter that writes its denials. Write it ABOVE your own
|
|
520
|
+
* authentication decorators: class decorators apply bottom-up, so it then runs after them and
|
|
521
|
+
* `request.user` is set.
|
|
522
|
+
*/
|
|
523
|
+
declare function UseConsoleAuthorize(): ClassDecorator & MethodDecorator;
|
|
524
|
+
|
|
395
525
|
/**
|
|
396
526
|
* Minimal shape guard for a `POST <api>/pricing` body — rejects junk before it reaches
|
|
397
527
|
* `AgentPricingStore.upsertModelPrice`. Not a full schema validator (the store adapter owns real
|
|
@@ -455,5 +585,7 @@ declare const DASHBOARD_API_PATH: unique symbol;
|
|
|
455
585
|
* injecting it needs no `@Optional()`.
|
|
456
586
|
*/
|
|
457
587
|
declare const DASHBOARD_APPROVAL_ACTOR_REF: unique symbol;
|
|
588
|
+
/** DI token carrying the console's `authorize` (and whether to warn when it is omitted). */
|
|
589
|
+
declare const DASHBOARD_CONSOLE_OPTIONS: unique symbol;
|
|
458
590
|
|
|
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 };
|
|
591
|
+
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, CONSOLE_AUTHORIZE_MISSING_WARNING, CONSOLE_GATE, CONSOLE_PAGE_METADATA, ConsoleAccessDenied, type ConsoleAuthorize, ConsoleAuthorizeFilter, ConsoleAuthorizeGuard, type ConsoleAuthorizeResult, type ConsoleAuthorizer, type ConsoleAuthorizerClass, type ConsoleDecide, type ConsoleDecision, type ConsoleGate, ConsolePage, type ConsolePolicyCheck, DASHBOARD_API_PATH, DASHBOARD_APPROVAL_ACTOR_REF, DASHBOARD_BASE_PATH, DASHBOARD_CONSOLE_OPTIONS, DashboardConsoleAccess, DashboardService, type LiveAgentEvent, type ReliabilityOverview, type RunDetailWithLabel, type SpendOverview, type ThreadActivityRowWithLabel, type ThreadDetailWithLabel, type ThreadSpendRowWithLabel, UseConsoleAuthorize, type WithActorLabel, agentDashboardMountPaths, authorizeByToken, normalizeConsoleResult, parsePriceInput, resolveConsoleAuthorize };
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
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, StreamableFile } from '@nestjs/common';
|
|
4
|
+
import { ExecutionContext, Type, Logger, DynamicModule, StreamableFile, HttpException, ExceptionFilter, ArgumentsHost, CanActivate, OnModuleInit } from '@nestjs/common';
|
|
5
|
+
import { ModuleRef, HttpAdapterHost } from '@nestjs/core';
|
|
5
6
|
|
|
6
7
|
/** An actor-scoped row decorated with its resolved display label — `null` when unbound or unresolved. */
|
|
7
8
|
interface WithActorLabel {
|
|
@@ -151,8 +152,9 @@ declare class DashboardService {
|
|
|
151
152
|
* JSON + SSE API consumed by the AI-gateway console SPA. Mounted at `apiBasePath` (set by
|
|
152
153
|
* `RouterModule` in {@link AgentDashboardModule.forRoot}), so the controller routes are relative.
|
|
153
154
|
*
|
|
154
|
-
* Who reaches it
|
|
155
|
-
* itself (`routes: false`)
|
|
155
|
+
* Who reaches it: `authorize` on `AgentDashboardModule.forRoot` (checked by `ConsoleAuthorizeGuard`,
|
|
156
|
+
* after the app's `decorators`). Mounted by the app itself (`routes: false`), apply
|
|
157
|
+
* `UseConsoleAuthorize()` to your subclass.
|
|
156
158
|
*/
|
|
157
159
|
declare class AgentApiController {
|
|
158
160
|
private readonly dashboard;
|
|
@@ -293,6 +295,72 @@ interface AgentDashboardMountPathsOptions {
|
|
|
293
295
|
*/
|
|
294
296
|
declare function agentDashboardMountPaths(options?: AgentDashboardMountPathsOptions): string[];
|
|
295
297
|
|
|
298
|
+
/** What an `authorize` check answers. */
|
|
299
|
+
type ConsoleAuthorizeResult = boolean | {
|
|
300
|
+
allowed: true;
|
|
301
|
+
} | {
|
|
302
|
+
allowed: false;
|
|
303
|
+
reason?: 'unauthenticated' | 'forbidden';
|
|
304
|
+
} | {
|
|
305
|
+
redirectTo: string;
|
|
306
|
+
};
|
|
307
|
+
/** Class form: an @Injectable() provider (constructor injection works). */
|
|
308
|
+
interface ConsoleAuthorizer {
|
|
309
|
+
authorize(context: ExecutionContext): ConsoleAuthorizeResult | Promise<ConsoleAuthorizeResult>;
|
|
310
|
+
}
|
|
311
|
+
type ConsoleAuthorizerClass = Type<ConsoleAuthorizer>;
|
|
312
|
+
/** @nestjs/authorization policy check: policy[ability](user). */
|
|
313
|
+
interface ConsolePolicyCheck {
|
|
314
|
+
policy: Type<unknown>;
|
|
315
|
+
ability: string;
|
|
316
|
+
}
|
|
317
|
+
/** Who reaches the console. */
|
|
318
|
+
type ConsoleAuthorize = ((context: ExecutionContext) => ConsoleAuthorizeResult | Promise<ConsoleAuthorizeResult>) | ConsoleAuthorizerClass | (() => Promise<{
|
|
319
|
+
default: ConsoleAuthorizerClass;
|
|
320
|
+
}>) | ConsolePolicyCheck | string;
|
|
321
|
+
/** A normalized `authorize` answer. */
|
|
322
|
+
type ConsoleDecision = {
|
|
323
|
+
allowed: true;
|
|
324
|
+
} | {
|
|
325
|
+
allowed: false;
|
|
326
|
+
reason: 'unauthenticated' | 'forbidden';
|
|
327
|
+
redirectTo?: string;
|
|
328
|
+
};
|
|
329
|
+
/** What a resolved `authorize` is: called once per request, never throws. */
|
|
330
|
+
type ConsoleDecide = (context: ExecutionContext) => Promise<ConsoleDecision>;
|
|
331
|
+
/**
|
|
332
|
+
* The provider that resolves gate names (`authorize: 'console.agent'`), bound globally by
|
|
333
|
+
* `@dudousxd/nestjs-authz`'s `AuthzModule`. A registry symbol, so it is found without depending on
|
|
334
|
+
* that package.
|
|
335
|
+
*/
|
|
336
|
+
declare const CONSOLE_GATE: unique symbol;
|
|
337
|
+
interface ConsoleGate {
|
|
338
|
+
allows(name: string, context: ExecutionContext): Promise<ConsoleAuthorizeResult>;
|
|
339
|
+
}
|
|
340
|
+
/** The one boot warning for a console with no `authorize`. Same wording in every Aviary console. */
|
|
341
|
+
declare const CONSOLE_AUTHORIZE_MISSING_WARNING = "[@dudousxd/nestjs-agent-dashboard] console has no `authorize` configured: it is open outside production and denies every request in production. Set `authorize` in AgentDashboardModule.forRoot().";
|
|
342
|
+
/** Turns any {@link ConsoleAuthorizeResult} into a {@link ConsoleDecision}. */
|
|
343
|
+
declare function normalizeConsoleResult(result: unknown): ConsoleDecision;
|
|
344
|
+
/**
|
|
345
|
+
* Resolves `authorize` into one function the guard calls per request. Configuration mistakes (a
|
|
346
|
+
* gate name without nestjs-authz, a policy without `@nestjs/authorization`) throw here, so call it
|
|
347
|
+
* at boot. The returned function never throws: an error is a `forbidden`.
|
|
348
|
+
*
|
|
349
|
+
* `authorize` omitted: open outside production, `forbidden` for every request in production (read
|
|
350
|
+
* when this runs), and one warning logged (unless `warnIfMissing: false`).
|
|
351
|
+
*/
|
|
352
|
+
declare function resolveConsoleAuthorize(authorize: ConsoleAuthorize | undefined, moduleRef: ModuleRef, options?: {
|
|
353
|
+
logger?: Logger;
|
|
354
|
+
warnIfMissing?: boolean;
|
|
355
|
+
}): Promise<ConsoleDecide>;
|
|
356
|
+
/**
|
|
357
|
+
* `authorize` by a bearer token: allows when `Authorization: Bearer <token>` matches (compared in
|
|
358
|
+
* constant time), else `unauthenticated`. Header only. An empty token throws here, at config time.
|
|
359
|
+
*/
|
|
360
|
+
declare function authorizeByToken(options: {
|
|
361
|
+
token: string | undefined;
|
|
362
|
+
}): (context: ExecutionContext) => ConsoleAuthorizeResult;
|
|
363
|
+
|
|
296
364
|
/**
|
|
297
365
|
* `TReq` mirrors core's `ActorResolver<TReq>` convention: the transport request type
|
|
298
366
|
* {@link AgentDashboardOptions.approvalActorRef} receives. Defaults to `unknown`.
|
|
@@ -310,23 +378,28 @@ interface AgentDashboardOptions<TReq = unknown> {
|
|
|
310
378
|
*/
|
|
311
379
|
apiBasePath?: string;
|
|
312
380
|
/**
|
|
313
|
-
* Who reaches the console
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
* `@nestjs
|
|
317
|
-
* Applied to a per-registration subclass, so nothing sticks to the shared classes.
|
|
381
|
+
* Who reaches the console (the SPA and every API/SSE route): an inline function
|
|
382
|
+
* `(ctx) => boolean | { allowed } | { redirectTo }`, an `@Injectable()` `ConsoleAuthorizer` class,
|
|
383
|
+
* a lazy import of one, `{ policy, ability }` (`@nestjs/authorization`), or a gate name
|
|
384
|
+
* (`@dudousxd/nestjs-authz`). `authorizeByToken({ token })` checks a bearer token.
|
|
318
385
|
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
|
|
322
|
-
|
|
386
|
+
* Omitted: open outside production; in production every request answers 403 (and a warning is
|
|
387
|
+
* logged at boot).
|
|
388
|
+
*/
|
|
389
|
+
authorize?: ConsoleAuthorize;
|
|
390
|
+
/**
|
|
391
|
+
* Class decorators applied to every controller this module mounts, before the console's own
|
|
392
|
+
* `authorize` check — e.g. `[UseGuards(AuthenticationGuard)]` so `request.user` is set when
|
|
393
|
+
* `authorize` runs. Applied to a per-registration subclass, so nothing sticks to the shared
|
|
394
|
+
* classes. They do not replace `authorize`. Static wiring.
|
|
323
395
|
*/
|
|
324
396
|
decorators?: ClassDecorator[];
|
|
325
397
|
/**
|
|
326
398
|
* `false` mounts none of the console's routes, while its services still run — the way NestJS's
|
|
327
399
|
* own packages leave routes to you: serve them from controllers of your own, protected with the
|
|
328
400
|
* official tools, by extending the exported `AgentApiController` / `AgentUiController` under your
|
|
329
|
-
* own path and decorators (the module exports what they inject)
|
|
401
|
+
* own path and decorators (the module exports what they inject); `UseConsoleAuthorize()` applies
|
|
402
|
+
* this module's `authorize` to them. Static wiring.
|
|
330
403
|
*/
|
|
331
404
|
routes?: boolean;
|
|
332
405
|
/** Extra `imports` merged into the console's modules — what a decorator's guard injects. */
|
|
@@ -350,12 +423,12 @@ declare class AgentApiModule {
|
|
|
350
423
|
decorators?: ClassDecorator[];
|
|
351
424
|
routes?: boolean;
|
|
352
425
|
approvalActorRef?: (req: TReq) => string | undefined;
|
|
426
|
+
authorize?: ConsoleAuthorize;
|
|
353
427
|
}): DynamicModule;
|
|
354
428
|
}
|
|
355
429
|
/**
|
|
356
430
|
* The AI-gateway console: the SPA at `basePath` and its JSON API at `apiBasePath`. Who reaches them
|
|
357
|
-
* is
|
|
358
|
-
* `@nestjs/authentication` / `@nestjs/authorization`.
|
|
431
|
+
* is `authorize` (see {@link AgentDashboardOptions.authorize}).
|
|
359
432
|
*/
|
|
360
433
|
declare class AgentDashboardModule {
|
|
361
434
|
static forRoot<TReq = unknown>(options?: AgentDashboardOptions<TReq>): DynamicModule;
|
|
@@ -380,8 +453,9 @@ interface UiPageResponse {
|
|
|
380
453
|
* `<base>/assets`). The path comes from `RouterModule` (set by
|
|
381
454
|
* {@link AgentDashboardModule.forRoot}({ basePath })), so the controller routes are relative.
|
|
382
455
|
*
|
|
383
|
-
* Who reaches it
|
|
384
|
-
* itself (`routes: false`)
|
|
456
|
+
* Who reaches it: `authorize` on `AgentDashboardModule.forRoot` (checked by `ConsoleAuthorizeGuard`,
|
|
457
|
+
* after the app's `decorators`). Mounted by the app itself (`routes: false`), apply
|
|
458
|
+
* `UseConsoleAuthorize()` to your subclass.
|
|
385
459
|
*/
|
|
386
460
|
declare class AgentUiController {
|
|
387
461
|
private readonly basePath;
|
|
@@ -392,6 +466,62 @@ declare class AgentUiController {
|
|
|
392
466
|
asset(file: string): StreamableFile;
|
|
393
467
|
}
|
|
394
468
|
|
|
469
|
+
/** What {@link DashboardConsoleAccess} is built from (bound per `forRoot`). */
|
|
470
|
+
interface DashboardConsoleOptions {
|
|
471
|
+
authorize?: ConsoleAuthorize;
|
|
472
|
+
}
|
|
473
|
+
/** Holds the console's resolved `authorize` check for one registration. */
|
|
474
|
+
declare class DashboardConsoleAccess implements OnModuleInit {
|
|
475
|
+
#private;
|
|
476
|
+
private readonly options;
|
|
477
|
+
private readonly moduleRef;
|
|
478
|
+
constructor(options: DashboardConsoleOptions, moduleRef: ModuleRef);
|
|
479
|
+
/** Resolves `authorize` at boot: a configuration mistake fails the boot, and the warning logs once. */
|
|
480
|
+
onModuleInit(): Promise<void>;
|
|
481
|
+
/** The decision for one request. */
|
|
482
|
+
check(context: ExecutionContext): Promise<ConsoleDecision>;
|
|
483
|
+
}
|
|
484
|
+
/** Marks a controller or handler as serving pages: a denied browser navigation gets HTML or a 302. */
|
|
485
|
+
declare const CONSOLE_PAGE_METADATA = "@dudousxd/nestjs-agent-dashboard:console-page";
|
|
486
|
+
/**
|
|
487
|
+
* On a controller or a handler that serves pages: a denied `GET` that accepts HTML gets a page (or a
|
|
488
|
+
* 302 for `redirectTo`), not JSON.
|
|
489
|
+
*/
|
|
490
|
+
declare const ConsolePage: () => ClassDecorator & MethodDecorator;
|
|
491
|
+
/** Thrown by {@link ConsoleAuthorizeGuard}; its body is the JSON answer even without the filter. */
|
|
492
|
+
declare class ConsoleAccessDenied extends HttpException {
|
|
493
|
+
readonly decision: Exclude<ConsoleDecision, {
|
|
494
|
+
allowed: true;
|
|
495
|
+
}>;
|
|
496
|
+
readonly page: boolean;
|
|
497
|
+
constructor(decision: Exclude<ConsoleDecision, {
|
|
498
|
+
allowed: true;
|
|
499
|
+
}>, page: boolean);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Runs the console's `authorize` on every route of a controller it guards. Applied by the module
|
|
503
|
+
* after the app's `decorators` (so authentication guards have already set `request.user`); a
|
|
504
|
+
* self-mounted controller (`routes: false`) applies it with {@link UseConsoleAuthorize}.
|
|
505
|
+
*/
|
|
506
|
+
declare class ConsoleAuthorizeGuard implements CanActivate {
|
|
507
|
+
private readonly access;
|
|
508
|
+
constructor(access: DashboardConsoleAccess);
|
|
509
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
510
|
+
}
|
|
511
|
+
/** Writes a console denial: JSON for API calls; a 302 or an HTML page (403 / 401) for page navigations. */
|
|
512
|
+
declare class ConsoleAuthorizeFilter implements ExceptionFilter<ConsoleAccessDenied> {
|
|
513
|
+
private readonly adapterHost;
|
|
514
|
+
constructor(adapterHost: HttpAdapterHost);
|
|
515
|
+
catch(exception: ConsoleAccessDenied, host: ArgumentsHost): void;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* The console's access check on a controller of your own (with `routes: false`): the
|
|
519
|
+
* {@link ConsoleAuthorizeGuard} plus the filter that writes its denials. Write it ABOVE your own
|
|
520
|
+
* authentication decorators: class decorators apply bottom-up, so it then runs after them and
|
|
521
|
+
* `request.user` is set.
|
|
522
|
+
*/
|
|
523
|
+
declare function UseConsoleAuthorize(): ClassDecorator & MethodDecorator;
|
|
524
|
+
|
|
395
525
|
/**
|
|
396
526
|
* Minimal shape guard for a `POST <api>/pricing` body — rejects junk before it reaches
|
|
397
527
|
* `AgentPricingStore.upsertModelPrice`. Not a full schema validator (the store adapter owns real
|
|
@@ -455,5 +585,7 @@ declare const DASHBOARD_API_PATH: unique symbol;
|
|
|
455
585
|
* injecting it needs no `@Optional()`.
|
|
456
586
|
*/
|
|
457
587
|
declare const DASHBOARD_APPROVAL_ACTOR_REF: unique symbol;
|
|
588
|
+
/** DI token carrying the console's `authorize` (and whether to warn when it is omitted). */
|
|
589
|
+
declare const DASHBOARD_CONSOLE_OPTIONS: unique symbol;
|
|
458
590
|
|
|
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 };
|
|
591
|
+
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, CONSOLE_AUTHORIZE_MISSING_WARNING, CONSOLE_GATE, CONSOLE_PAGE_METADATA, ConsoleAccessDenied, type ConsoleAuthorize, ConsoleAuthorizeFilter, ConsoleAuthorizeGuard, type ConsoleAuthorizeResult, type ConsoleAuthorizer, type ConsoleAuthorizerClass, type ConsoleDecide, type ConsoleDecision, type ConsoleGate, ConsolePage, type ConsolePolicyCheck, DASHBOARD_API_PATH, DASHBOARD_APPROVAL_ACTOR_REF, DASHBOARD_BASE_PATH, DASHBOARD_CONSOLE_OPTIONS, DashboardConsoleAccess, DashboardService, type LiveAgentEvent, type ReliabilityOverview, type RunDetailWithLabel, type SpendOverview, type ThreadActivityRowWithLabel, type ThreadDetailWithLabel, type ThreadSpendRowWithLabel, UseConsoleAuthorize, type WithActorLabel, agentDashboardMountPaths, authorizeByToken, normalizeConsoleResult, parsePriceInput, resolveConsoleAuthorize };
|