@dudousxd/nestjs-agent 1.39.0 → 2.0.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 (40) hide show
  1. package/README.md +14 -7
  2. package/dist/a2ui/index.cjs +1 -0
  3. package/dist/a2ui/index.cjs.map +1 -1
  4. package/dist/a2ui/index.d.cts +3 -2
  5. package/dist/a2ui/index.d.ts +3 -2
  6. package/dist/a2ui/index.js +2 -1
  7. package/dist/a2ui/index.js.map +1 -1
  8. package/dist/{chat-queue.service-YjiKVTKE.d.ts → chat-queue.service-BjPCw4Pf.d.ts} +104 -43
  9. package/dist/{chat-queue.service-fopUN313.d.cts → chat-queue.service-C49HIuEV.d.cts} +104 -43
  10. package/dist/durable/index.cjs +13572 -1754
  11. package/dist/durable/index.cjs.map +1 -1
  12. package/dist/durable/index.d.cts +6 -6
  13. package/dist/durable/index.d.ts +6 -6
  14. package/dist/durable/index.js +12228 -390
  15. package/dist/durable/index.js.map +1 -1
  16. package/dist/genui/index.cjs.map +1 -1
  17. package/dist/genui/index.d.cts +4 -6
  18. package/dist/genui/index.d.ts +4 -6
  19. package/dist/genui/index.js.map +1 -1
  20. package/dist/{index-BJFM1tG8.d.cts → index-BBkyvNUi.d.cts} +1 -1
  21. package/dist/{index-De98CGXa.d.ts → index-CRCbsO6E.d.ts} +1 -1
  22. package/dist/index.cjs +12408 -450
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +318 -18
  25. package/dist/index.d.ts +318 -18
  26. package/dist/index.js +12313 -346
  27. package/dist/index.js.map +1 -1
  28. package/dist/media/index.cjs +4 -9
  29. package/dist/media/index.cjs.map +1 -1
  30. package/dist/media/index.d.cts +14 -3
  31. package/dist/media/index.d.ts +14 -3
  32. package/dist/media/index.js +6 -11
  33. package/dist/media/index.js.map +1 -1
  34. package/dist/workflows/index.cjs +1496 -0
  35. package/dist/workflows/index.cjs.map +1 -0
  36. package/dist/workflows/index.d.cts +158 -0
  37. package/dist/workflows/index.d.ts +158 -0
  38. package/dist/workflows/index.js +1464 -0
  39. package/dist/workflows/index.js.map +1 -0
  40. package/package.json +39 -8
package/dist/index.d.ts CHANGED
@@ -1,17 +1,20 @@
1
- import { DynamicModule, Type, OnApplicationBootstrap, OnModuleInit, ConflictException, OnModuleDestroy } from '@nestjs/common';
2
- import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, d as AgentProtocolAdapter, A as AgentDepsFactory, e as AgentSkillsOptions, C as ChatQueueService } from './chat-queue.service-YjiKVTKE.js';
3
- export { f as AGENT_TOOL_BRAND, g as AgentAttachmentsOptions, h as AgentDeps, i as AgentEngine, j as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, L as LedgerQuotaProvider, Q as QueuePlan, k as QueueSettleOutcome, l as QueuedTurn, m as QueuedTurnStarter, n as QuotaLimits, o as QuotaWindowLimits, p as defineTool, q as delegateToolName, r as provideAgentTool, s as provideAgentTools, u as utcDay } from './chat-queue.service-YjiKVTKE.js';
1
+ import { DynamicModule, OnModuleInit, Type, OnApplicationBootstrap, ConflictException, OnModuleDestroy } from '@nestjs/common';
2
+ import { b as AgentModuleOptions, c as AgentModuleAsyncOptions, d as AgentProtocolAdapter, A as AgentDepsFactory, e as AgentSkillsOptions, C as ChatQueueService } from './chat-queue.service-BjPCw4Pf.js';
3
+ export { f as AGENT_TOOL_BRAND, g as AgentAttachmentsOptions, h as AgentDeps, i as AgentDurableOptions, j as AgentEngine, k as AgentFunctionCaller, l as AgentMemoryOptions, a as AgentSurface, F as FunctionalTool, L as LedgerQuotaProvider, Q as QueuePlan, m as QueueSettleOutcome, n as QueuedTurn, o as QueuedTurnStarter, p as QuotaLimits, q as QuotaWindowLimits, r as defaultAgentFunctionCaller, s as defineTool, t as delegateToolName, u as durableEngineOf, v as provideAgentTool, w as provideAgentTools, x as utcDay } from './chat-queue.service-BjPCw4Pf.js';
4
4
  import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
5
- import { ActorResolver, AttachmentStagingStore, AgentApprovalPort, Actor, AgentStore, StagedAttachment, MessageAttachment, ModelCatalog, AgentClientConfig, ToolSpec, ToolPresentation, AgentHistoryWindow, AgentIntake, Persona, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, MessageFeedbackValue, MessageFeedback, ModelCatalogView, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunner, AgentRunInput, AgentRunStartOptions, HumanReply, ChatQueueState, TokenStreamSink, SinkWriter, SubscribeOptions, ActionProposalOutcome, ActionProposal } from '@dudousxd/nestjs-agent-core';
5
+ import { ModelProvider, ModelCatalog, ModelTurnArgs, ModelTurnResult, DescribedModel, PriceCatalogEntry, ToolPresentation, ToolSpec, RolesPolicy, Actor, ActorResolver, AttachmentStagingStore, AgentApprovalPort, AgentStore, StagedAttachment, MessageAttachment, AgentClientConfig, ToolCanRequirement, AgentHistoryWindow, AgentIntake, Persona, SkillContext, ToolRegistry, AgentRegistry, PromptContributor, SkillsConfig, SkillCatalogEntry, MessageFeedbackValue, MessageFeedback, ModelCatalogView, ToolCatalogEntry, MemoryConfig, MemoryDigestEntry, SkillProvider, AgentRunner, AgentRunInput, AgentRunStartOptions, HumanReply, ChatQueueState, TokenStreamSink, SinkWriter, SubscribeOptions, ActionProposalOutcome, ActionProposal, PageContext, AgentCatalogEntry } from '@dudousxd/nestjs-agent-core';
6
6
  export * from '@dudousxd/nestjs-agent-core';
7
7
  export { FunctionalToolDefinition } from '@dudousxd/nestjs-agent-core';
8
+ import { ModuleRef, DiscoveryService, MetadataScanner } from '@nestjs/core';
9
+ import { AiModels, AiModuleOptions, AgentFunctionOptions } from '@nestjs/ai';
10
+ import { ResilienceService } from '@nestjs/resilience';
11
+ import { AuthorizationService } from '@nestjs/authorization';
8
12
  import { A2uiOptions } from '@dudousxd/nestjs-agent-core/a2ui';
9
13
  import { Request, Response } from 'express';
10
- import { A as AgentService, a as ActionProposalService } from './index-De98CGXa.js';
11
- export { b as A2uiAdapterOptions, c as A2uiRunHandler, d as AttachmentLimits, C as ChatParams, e as ChatSendMode, f as ChatSendResult, D as DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, g as DEFAULT_MAX_ATTACHMENT_BYTES, F as ForkThreadParams, M as MAX_ATTACHMENTS_PER_MESSAGE, N as NO_USER_MESSAGE_CODE, Q as QueuedSend, T as ThreadDefaultAgentReader, h as ThreadModelReader, i as a2uiAdapter, j as attachmentLimits } from './index-De98CGXa.js';
14
+ import { A as AgentService, a as ActionProposalService } from './index-CRCbsO6E.js';
15
+ export { b as A2uiAdapterOptions, c as A2uiRunHandler, d as AttachmentLimits, C as ChatParams, e as ChatSendMode, f as ChatSendResult, D as DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES, g as DEFAULT_MAX_ATTACHMENT_BYTES, F as ForkThreadParams, M as MAX_ATTACHMENTS_PER_MESSAGE, N as NO_USER_MESSAGE_CODE, Q as QueuedSend, T as ThreadDefaultAgentReader, h as ThreadModelReader, i as a2uiAdapter, j as attachmentLimits } from './index-CRCbsO6E.js';
12
16
  import { AgentGenui } from './genui/index.js';
13
17
  import { StandardSchemaV1 } from '@standard-schema/spec';
14
- import { DiscoveryService, MetadataScanner } from '@nestjs/core';
15
18
  import '@dudousxd/nestjs-agent-core/genui';
16
19
 
17
20
  declare class AgentModule {
@@ -19,6 +22,121 @@ declare class AgentModule {
19
22
  static forRootAsync(options: AgentModuleAsyncOptions): DynamicModule;
20
23
  }
21
24
 
25
+ /**
26
+ * The agent's model when `AgentModule` is given none: `@nestjs/ai`'s `AiModule`, found wherever the
27
+ * application imports it (it need not be global, nor imported next to `AgentModule`). Resolved once
28
+ * every provider exists (`onModuleInit`); a turn, the picker and boot pricing all come after that.
29
+ */
30
+ declare class NestAiModelsBinding implements ModelProvider, OnModuleInit {
31
+ #private;
32
+ private readonly options;
33
+ private readonly moduleRef;
34
+ constructor(options: AgentModuleOptions, moduleRef: ModuleRef);
35
+ /** Whether the agent's turns run on `AiModule`'s models (no `model` and no `engine` configured). */
36
+ get active(): boolean;
37
+ onModuleInit(): void;
38
+ /** The picker's catalog, read through to `AiModule`'s models once they are resolved. */
39
+ readonly catalog: ModelCatalog;
40
+ runTurn(args: ModelTurnArgs): Promise<ModelTurnResult>;
41
+ describeModels(): DescribedModel[];
42
+ /** `AiModule`'s `pricing`, as price rows boot pricing seeds. */
43
+ prices(): PriceCatalogEntry[];
44
+ private get provider();
45
+ private find;
46
+ }
47
+
48
+ /** What {@link nestAiModelProvider} reads off `@nestjs/ai`. */
49
+ interface NestAiModelProviderOptions {
50
+ /** `AiModule`'s model registry: the names a turn picks from, and the `LanguageModel` behind each. */
51
+ models: AiModels;
52
+ /** `AiModule`'s options (`AI_MODULE_OPTIONS`): each model's settings, pricing and fallback, and `defaults`. */
53
+ options: AiModuleOptions;
54
+ /** Resolves a model's `resilience: 'preset'`. Required only when a model or `defaults` names one. */
55
+ resilience?: ResilienceService;
56
+ /** Names the agent's model calls in `onUsage` events. Default `'agent'`. */
57
+ label?: string;
58
+ }
59
+ /** A {@link ModelProvider} over `@nestjs/ai`'s models, with the picker's catalog and their prices. */
60
+ interface NestAiModelProvider extends ModelProvider {
61
+ catalog: ModelCatalog;
62
+ /** Price rows for the models `AiModule` prices (`pricing`), in its unit — read as USD per 1M tokens. */
63
+ prices(): PriceCatalogEntry[];
64
+ }
65
+ /**
66
+ * The agent's models are `@nestjs/ai`'s: a turn picks one of `AiModule.forRoot({ models })` by name
67
+ * (the picker lists them all), and runs under what `AiModule` configures for it — its generation
68
+ * settings, its `retry` and `timeout` (or its `resilience` policy or preset), its `fallback` models,
69
+ * `onUsage`, and its `pricing` for cost.
70
+ *
71
+ * `@nestjs/ai`'s own calls offer the model only `@AgentFunction()` tools and run them themselves; the
72
+ * agent's tools are governed, journaled and approved by the agent loop instead. So the turn itself is
73
+ * one AI SDK call with the loop's tools offered and not run, put under the same policies `@nestjs/ai`
74
+ * puts its calls under, with the same semantics: the timeout is the time to the first frame, and once
75
+ * a frame has reached the reader nothing is retried and no other model takes over — the reader would
76
+ * see the answer twice.
77
+ */
78
+ declare function nestAiModelProvider(config: NestAiModelProviderOptions): NestAiModelProvider;
79
+
80
+ /**
81
+ * What the agent adds to `@nestjs/ai`'s `@AgentFunction()` options: everything `@AiTool` declares
82
+ * that `@nestjs/ai` has no word for.
83
+ */
84
+ interface AgentFunctionGovernance {
85
+ /**
86
+ * `read` runs as the model asks; `action` waits for a person's approval (HITL), as an `action`
87
+ * `@AiTool` does. Default `read` — the same default as `@AiTool`.
88
+ */
89
+ kind?: 'read' | 'action';
90
+ /** Roles allowed to call it, gated by the `RolesPolicy`. Omit → the policy's `defaultRoles`. */
91
+ roles?: string[];
92
+ /** Whether the tool exists in this deployment at all. Omit → it does. */
93
+ enabled?: boolean | (() => boolean | Promise<boolean>);
94
+ /** How the approval card and the tool-call row present it. */
95
+ presentation?: ToolPresentation;
96
+ /** The turn ends once this tool has run. */
97
+ terminal?: boolean;
98
+ /** Explicit identity for pending-only replacement of an `action` (see `@AiTool`). */
99
+ replacementKey?: ToolSpec['replacementKey'];
100
+ }
101
+ /** `@nestjs/ai`'s `@AgentFunction()` options, and the agent's governance. */
102
+ type GovernedAgentFunctionOptions = AgentFunctionOptions & AgentFunctionGovernance;
103
+ /**
104
+ * `@nestjs/ai`'s `@AgentFunction()`, with the agent's governance: the method is an agent function
105
+ * (`@nestjs/ai`'s calls offer it, through its guards, interceptors and pipes), and the agent offers
106
+ * it too, governed — an `action` waits for a person's approval, `roles` gate who is offered it.
107
+ * Authorization is `@nestjs/authorization`'s `@Can()`, stacked on the method: the agent offers the
108
+ * tool only to an actor its abilities allow, and the guard checks the call.
109
+ *
110
+ * ```ts
111
+ * import { AgentFunction } from '@dudousxd/nestjs-agent';
112
+ *
113
+ * @AgentFunction({
114
+ * name: 'refund',
115
+ * description: 'Refund an order',
116
+ * inputSchema: RefundInput,
117
+ * kind: 'action',
118
+ * roles: ['SUPPORT'],
119
+ * })
120
+ * refund(input: RefundInput, ctx: AgentFunctionContext) { … }
121
+ * ```
122
+ *
123
+ * A method with `@nestjs/ai`'s own `@AgentFunction()` is offered to the agent as well, as a `read`
124
+ * tool under the policy's default roles; this one is that, plus the governance. A method takes one
125
+ * of the two, not both.
126
+ */
127
+ declare function AgentFunction(options?: GovernedAgentFunctionOptions): MethodDecorator;
128
+
129
+ /** The user `@nestjs/authorization`'s policies receive for the turn's actor. */
130
+ type AuthorizationUserOf = (actor: Actor) => unknown;
131
+ /**
132
+ * The agent's gate, with `@nestjs/authorization` in it: a tool that requires abilities
133
+ * (`ToolSpec.can`) is offered to, and callable by, an actor every one of them allows
134
+ * (`AuthorizationService.can(policy, ability, user)`) — and, when it names `roles` too, an actor
135
+ * holding one of them. A tool that requires none is the inner policy's call alone. Without an
136
+ * `AuthorizationService` to ask, a tool that requires one reaches nobody: fail closed.
137
+ */
138
+ declare function authorizationGate(inner: RolesPolicy, service: () => AuthorizationService | undefined, userOf: AuthorizationUserOf): RolesPolicy;
139
+
22
140
  interface AgUiAdapterOptions {
23
141
  /** Where the route mounts, under the agent's path. Default `'ag-ui'` → `POST <path>/ag-ui`. */
24
142
  path?: string;
@@ -243,12 +361,6 @@ interface AiToolOptions {
243
361
  * import time, and can't reach the container.
244
362
  */
245
363
  enabled?: boolean | (() => boolean | Promise<boolean>);
246
- /**
247
- * Authz ability checked by an ability-aware RolesPolicy (e.g. `AgentAuthzModule`'s
248
- * `AuthzRolesPolicy` → `gate.forUser(actor).allows(ability)`). Ignored by the default
249
- * role-based policy, which uses `roles`.
250
- */
251
- ability?: string;
252
364
  /**
253
365
  * How a chat surface talks about this tool without naming it — sentence templates over the
254
366
  * call's input, an icon key, the approval prompt's wording, and how its output reads. Never shown
@@ -281,6 +393,12 @@ declare function toolNameFromClass(className: string): string;
281
393
  /**
282
394
  * Marks a provider class as an AI tool. The class must implement `execute(input, ctx)`.
283
395
  * `AiToolDiscoveryService` registers every `@AiTool` provider into the `ToolRegistry` at boot.
396
+ *
397
+ * `execute()` is also a `@nestjs/ai` `@AgentFunction()` (when the input schema produces JSON Schema,
398
+ * as Zod 4's does): with `AiModule` imported, the agent's calls run through the guards, interceptors
399
+ * and pipes `execute()` and the class declare, and `@nestjs/ai`'s own calls can offer the tool —
400
+ * outside a turn, an `action` is refused (only a turn asks a person) and `roles` are checked
401
+ * against the call's `user`.
284
402
  * Only `description` and `input` are required:
285
403
  *
286
404
  * ```ts
@@ -355,14 +473,15 @@ interface AgentOptions {
355
473
  * orchestrator and worth backgrounding in another, and only the person wiring the edge knows
356
474
  * which side of that the user is sitting on.
357
475
  *
358
- * `roles` / `ability` gate who may delegate along the edge (the delegate tool's own), e.g.
359
- * `{ agent: Helper, roles: ['personal_agent'] }` to let a personal agent's turn delegate.
476
+ * `roles` / `can` gate who may delegate along the edge (the delegate tool's own), e.g.
477
+ * `{ agent: Helper, roles: ['personal_agent'] }` to let a personal agent's turn delegate, or
478
+ * `{ agent: Billing, can: [{ policy: BillingPolicy, ability: 'delegate' }] }`.
360
479
  */
361
480
  handoff?: (Type | {
362
481
  agent: Type;
363
482
  detached?: boolean;
364
483
  roles?: string[];
365
- ability?: string;
484
+ can?: readonly ToolCanRequirement[];
366
485
  })[];
367
486
  /**
368
487
  * How much of the thread this agent's turns carry, overriding `AgentModule.forRoot({ history })`.
@@ -497,9 +616,17 @@ declare class AiToolDiscoveryService implements OnApplicationBootstrap {
497
616
  private readonly registry;
498
617
  private readonly agents;
499
618
  private readonly options;
619
+ private readonly moduleRef;
500
620
  private readonly logger;
501
- constructor(discovery: DiscoveryService, registry: ToolRegistry, agents: AgentRegistry, options: AgentModuleOptions);
621
+ constructor(discovery: DiscoveryService, registry: ToolRegistry, agents: AgentRegistry, options: AgentModuleOptions, moduleRef: ModuleRef);
502
622
  onApplicationBootstrap(): void;
623
+ /**
624
+ * How the agent runs an `@AiTool`: through `AiTools.call` when its `execute()` is an agent
625
+ * function `AiModule` found (so its enhancers run), else by calling it.
626
+ */
627
+ private executorOf;
628
+ /** `@nestjs/ai`'s agent functions, wherever the application imports `AiModule`; none without it. */
629
+ private findAiTools;
503
630
  /**
504
631
  * Registers a functional tool's `{ spec, handler }`, skipping it if a tool of the same name is
505
632
  * already registered. Returns whether it was newly registered.
@@ -1043,4 +1170,177 @@ declare class ActionProposalWorkerService implements OnModuleInit, OnModuleDestr
1043
1170
  onModuleDestroy(): Promise<void>;
1044
1171
  }
1045
1172
 
1046
- export { AGENT_CHAT_QUEUE, AGENT_METADATA, AGENT_SERVICE, AI_TOOL_METADATA, ATTACHMENT_PAGE_SIZE, type ActionProposalAdmittedListener, ActionProposalController, ActionProposalService, type ActionProposalSettledListener, ActionProposalWorkerService, type AgUiAdapterOptions, AgUiRunHandler, Agent, AgentApprovalPortAdapter, AgentDepsFactory, AgentDiscoveryService, AgentModule, AgentModuleAsyncOptions, AgentModuleOptions, type AgentOptions, AgentProtocolAdapter, AgentService, AgentSkillsOptions, AiTool, AiToolDiscoveryService, type AiToolOptions, type AnonymousActorOptions, AnonymousActorResolver, AttachmentsController, ChatQueueService, ConfigController, type DeclaredSkill, HeaderActorResolver, InProcessTokenStreamSink, InlineAgentRunner, MemoriesController, MessagesController, ModelsController, QueueController, type RequestUserMapper, type ResolvedAiToolOptions, RunNotActiveException, SKILL_METADATA, SYSTEM_PROMPT_CONTRIBUTOR_METADATA, SYSTEM_PROMPT_METADATA, Skill, type SkillBody, SkillDiscoveryService, type SkillOptions, SkillsController, SystemPrompt, SystemPromptContributor, type ThreadPersonaReader, ToolsController, agUiAdapter, declaredSkillProvider, defaultRequestUserMapper, readAgentMetadata, readAiToolMetadata, readSkillMetadata, requestUserActorResolver, resolveSkillsConfig, skillScope, threadPersona, toolNameFromClass };
1173
+ interface ChatBody {
1174
+ uiCapabilities?: unknown;
1175
+ message: string;
1176
+ threadId?: string;
1177
+ /** Name of the agent to run (orchestrator or a sub-agent). Defaults to the module's default. */
1178
+ agent?: string;
1179
+ /**
1180
+ * One of the agent's personas (`@Agent({ personas })`) to answer as — pinned on the thread. 400
1181
+ * `persona_not_found` when the agent declares none by that id.
1182
+ */
1183
+ persona?: string;
1184
+ /**
1185
+ * Files attached to this message (image/PDF), named by the `mediaId` `POST /agent/attachments`
1186
+ * (or the host's own upload) returned. Any other field sent alongside it is ignored.
1187
+ */
1188
+ attachments?: unknown;
1189
+ pageContext?: PageContext;
1190
+ /** Re-run the last exchange on `threadId` instead of adding a new message. */
1191
+ regenerate?: boolean;
1192
+ /** Start a new thread transient (hidden from history until promoted). Ignored with `threadId`. */
1193
+ transient?: boolean;
1194
+ /** Run this turn on a catalog model (see `GET models`) instead of the thread's pinned one. */
1195
+ model?: string;
1196
+ /**
1197
+ * What to do when the thread already has a turn running: `'auto'` (default) queues it, `'queue'`
1198
+ * always queues it (behind anything already waiting), `'interrupt'` cancels the running turn and
1199
+ * runs this next. See `ChatSendMode`.
1200
+ */
1201
+ mode?: unknown;
1202
+ /** Shorthand for `mode: 'interrupt'`. */
1203
+ interrupt?: boolean;
1204
+ }
1205
+ declare class ChatController {
1206
+ private readonly agent;
1207
+ private readonly actorResolver;
1208
+ constructor(agent: AgentService, actorResolver: ActorResolver);
1209
+ /**
1210
+ * Start a turn and stream it — or, when the thread already has one running, queue the message and
1211
+ * answer `202 { queued: true, messageId, position, queue, … }` (JSON, no stream): it runs when the
1212
+ * turn ahead of it settles, and the stream of the run holding the thread announces it with a
1213
+ * `queue` frame.
1214
+ */
1215
+ chat(req: Request, res: Response, body: ChatBody): Promise<void>;
1216
+ /**
1217
+ * Attach to a run's stream: every buffered frame, then live ones. `?after=<seq>` (or the SSE
1218
+ * `Last-Event-ID` header a browser `EventSource` sends on its own) skips the frames a reconnecting
1219
+ * client already has — see {@link pipe} for how frames are numbered.
1220
+ */
1221
+ stream(req: Request, runId: string, res: Response, after?: string): Promise<void>;
1222
+ cancel(req: Request, runId: string): Promise<{
1223
+ aborted: boolean;
1224
+ }>;
1225
+ /**
1226
+ * Every `data:` frame carries an SSE `id:` — its 1-based sequence number within the run. The
1227
+ * number is a pure function of the run's buffered stream (every sink replays a run from its first
1228
+ * chunk, in write order), so the same frame gets the same number on the POST that started the run
1229
+ * and on any later `GET …/stream`, whichever replica serves it. A reconnecting client passes the
1230
+ * last one it saw as `?after=`; frames at or below it are read off the sink but not re-sent.
1231
+ * `meta`, `done` and `error` carry no id: `meta` is re-sent on every attach, the terminals once.
1232
+ *
1233
+ * A reader that disconnects aborts `gone`, which the sink honours by ending the subscription even
1234
+ * while the run is silent (parked on a person, or never writing again).
1235
+ */
1236
+ private pipe;
1237
+ }
1238
+
1239
+ interface UpdateThreadBody {
1240
+ title?: string;
1241
+ /** `null` clears the thread's default agent. Omitted → left untouched. */
1242
+ defaultAgent?: string | null;
1243
+ /** `null` unpins the thread's model. Omitted → left untouched. Must be offered by the catalog. */
1244
+ model?: string | null;
1245
+ /** `null` clears the thread's persona. Omitted → left untouched. Must be one the agent declares. */
1246
+ persona?: string | null;
1247
+ }
1248
+ declare class ThreadsController {
1249
+ private readonly agent;
1250
+ private readonly actorResolver;
1251
+ constructor(agent: AgentService, actorResolver: ActorResolver);
1252
+ list(req: Request): Promise<_dudousxd_nestjs_agent_core.ThreadSummary[]>;
1253
+ detail(req: Request, id: string): Promise<_dudousxd_nestjs_agent_core.ThreadDetail | null>;
1254
+ remove(req: Request, id: string): Promise<{
1255
+ ok: boolean;
1256
+ }>;
1257
+ fork(req: Request, id: string, messageId: string): Promise<_dudousxd_nestjs_agent_core.ThreadSummary>;
1258
+ /**
1259
+ * Renames the thread and/or sets its default agent. `defaultAgent` is only present in the request
1260
+ * body when the client actually sent the key (JSON has no `undefined`), so `'defaultAgent' in body`
1261
+ * distinguishes "leave it alone" from "set it to null" (clear it) unambiguously.
1262
+ */
1263
+ update(req: Request, id: string, body: UpdateThreadBody): Promise<{
1264
+ ok: boolean;
1265
+ }>;
1266
+ promote(req: Request, id: string): Promise<{
1267
+ ok: boolean;
1268
+ }>;
1269
+ truncateFrom(req: Request, id: string, messageId: string): Promise<{
1270
+ ok: boolean;
1271
+ }>;
1272
+ }
1273
+
1274
+ interface ApproveBody {
1275
+ toolCallId: unknown;
1276
+ /** Approve later calls of the same tool in the same thread without asking. */
1277
+ remember?: unknown;
1278
+ /** The surface the decision came through. Defaults to `'web'`. */
1279
+ via?: unknown;
1280
+ }
1281
+ interface RejectBody {
1282
+ toolCallId: unknown;
1283
+ reason?: unknown;
1284
+ via?: unknown;
1285
+ }
1286
+ interface AnswerBody {
1287
+ toolCallId: unknown;
1288
+ /**
1289
+ * questionId → chosen option values. Omit a question (or the whole object) to take the pre-picked
1290
+ * default the request was shown with — confirming is meant to be enough, so an empty body is a
1291
+ * valid submission rather than an error.
1292
+ */
1293
+ answers?: unknown;
1294
+ /** The surface the answer came through. Defaults to `'web'`. */
1295
+ via?: unknown;
1296
+ }
1297
+ declare class ToolCallController {
1298
+ private readonly agent;
1299
+ private readonly actorResolver;
1300
+ constructor(agent: AgentService, actorResolver: ActorResolver);
1301
+ approve(req: Request, body: ApproveBody): Promise<{
1302
+ ok: boolean;
1303
+ }>;
1304
+ reject(req: Request, body: RejectBody): Promise<{
1305
+ ok: boolean;
1306
+ }>;
1307
+ /**
1308
+ * Settle a parked question set. Alongside `approve`/`reject` rather than under a surface of its
1309
+ * own: an elicitation IS a parked tool call, gated by the same ownership check and delivered
1310
+ * through the same signal.
1311
+ */
1312
+ answer(req: Request, body: AnswerBody): Promise<{
1313
+ ok: boolean;
1314
+ }>;
1315
+ /** Decline to answer and let the agent proceed on the answers it pre-picked. */
1316
+ skip(req: Request, body: {
1317
+ toolCallId: unknown;
1318
+ via?: unknown;
1319
+ }): Promise<{
1320
+ ok: boolean;
1321
+ }>;
1322
+ }
1323
+
1324
+ declare class QuotaController {
1325
+ private readonly agent;
1326
+ private readonly actorResolver;
1327
+ constructor(agent: AgentService, actorResolver: ActorResolver);
1328
+ /**
1329
+ * The caller's budget across windows — `{ windows: [{ period, usedTokens, limitTokens?, usedUsd,
1330
+ * limitUsd?, resetsAt? }], blocked?: { period, reason? } }` — from the bound `QuotaProvider`.
1331
+ */
1332
+ report(req: Request): Promise<_dudousxd_nestjs_agent_core.QuotaReport>;
1333
+ }
1334
+
1335
+ /**
1336
+ * Lists the registered `@Agent`s — and each one's personas — so a host can render an agent or
1337
+ * persona picker instead of hardcoding one.
1338
+ */
1339
+ declare class AgentsController {
1340
+ private readonly agents;
1341
+ private readonly depsFactory;
1342
+ constructor(agents: AgentRegistry, depsFactory: AgentDepsFactory);
1343
+ list(): AgentCatalogEntry[];
1344
+ }
1345
+
1346
+ export { AGENT_CHAT_QUEUE, AGENT_METADATA, AGENT_SERVICE, AI_TOOL_METADATA, ATTACHMENT_PAGE_SIZE, type ActionProposalAdmittedListener, ActionProposalController, ActionProposalService, type ActionProposalSettledListener, ActionProposalWorkerService, type AgUiAdapterOptions, AgUiRunHandler, Agent, AgentApprovalPortAdapter, AgentDepsFactory, AgentDiscoveryService, AgentFunction, type AgentFunctionGovernance, AgentModule, AgentModuleAsyncOptions, AgentModuleOptions, type AgentOptions, AgentProtocolAdapter, AgentService, AgentSkillsOptions, AgentsController, AiTool, AiToolDiscoveryService, type AiToolOptions, type AnonymousActorOptions, AnonymousActorResolver, AttachmentsController, ChatController, ChatQueueService, ConfigController, type DeclaredSkill, type GovernedAgentFunctionOptions, HeaderActorResolver, InProcessTokenStreamSink, InlineAgentRunner, MemoriesController, MessagesController, ModelsController, type NestAiModelProvider, type NestAiModelProviderOptions, NestAiModelsBinding, QueueController, QuotaController, type RequestUserMapper, type ResolvedAiToolOptions, RunNotActiveException, SKILL_METADATA, SYSTEM_PROMPT_CONTRIBUTOR_METADATA, SYSTEM_PROMPT_METADATA, Skill, type SkillBody, SkillDiscoveryService, type SkillOptions, SkillsController, SystemPrompt, SystemPromptContributor, type ThreadPersonaReader, ThreadsController, ToolCallController, ToolsController, agUiAdapter, authorizationGate, declaredSkillProvider, defaultRequestUserMapper, nestAiModelProvider, readAgentMetadata, readAiToolMetadata, readSkillMetadata, requestUserActorResolver, resolveSkillsConfig, skillScope, threadPersona, toolNameFromClass };