@dudousxd/nestjs-agent 1.39.1 → 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 +37 -6
@@ -1,7 +1,8 @@
1
- import { ResolveToolUiCatalog, ToolUiChannelGuide, ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, Persona, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, createFunctionalTool, QuotaProvider, QuotaQuery, QuotaReport, ActionApprovalMode, BackgroundActorResolver, ActionProposal, ActionProposalOutcome, TextActionProposalConfig, PriceCatalogOptions, ModelCatalog, EmptyRoles, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry, PersonaCatalogEntry, Actor, AttachmentStagingStore, ChatQueueStore, ChatQueueState, AgentRunner, AgentRunInput, AgentStreamEvent, QueuePauseReason } from '@dudousxd/nestjs-agent-core';
1
+ import { ResolveToolUiCatalog, ToolUiChannelGuide, ModelProvider, AgentStore, ToolRegistry, RolesPolicy, ApprovalPolicy, QuotaStore, TokenStreamSink, PromptBuilder, PromptContributor, Persona, ToolTransientRetrySetting, Retriever, AgentPricingStore, HistoryPolicy, InputProcessor, OutputProcessor, AgentIntake, SkillsConfig, MemoryConfig, ToolSpec, ToolHandler, createFunctionalTool, QuotaProvider, QuotaQuery, QuotaReport, Actor, AiToolCtx, ActionApprovalMode, BackgroundActorResolver, ActionProposal, ActionProposalOutcome, TextActionProposalConfig, PriceCatalogOptions, ModelCatalog, EmptyRoles, ActorResolver, AgentHistoryWindow, SkillProvider, ScopeResolver, MemoryProvider, AgentRegistry, PersonaCatalogEntry, AttachmentStagingStore, ChatQueueStore, ChatQueueState, AgentRunner, AgentRunInput, AgentStreamEvent, QueuePauseReason } from '@dudousxd/nestjs-agent-core';
2
2
  import { Catalog } from '@dudousxd/nestjs-agent-core/genui';
3
3
  import { StandardSchemaV1 } from '@standard-schema/spec';
4
- import { Provider, InjectionToken, Type, FactoryProvider, CanActivate, ModuleMetadata, OptionalFactoryDependency } from '@nestjs/common';
4
+ import { Provider, InjectionToken, Type, FactoryProvider, ModuleMetadata, OptionalFactoryDependency } from '@nestjs/common';
5
+ import { AiCaller } from '@nestjs/ai';
5
6
  import { GenuiCatalogResolver, AgentGenui } from './genui/index.cjs';
6
7
 
7
8
  /** Everything `runAgentLoop` needs, minus the per-run `day` the runner stamps. */
@@ -177,6 +178,19 @@ declare class LedgerQuotaProvider implements QuotaProvider {
177
178
  private window;
178
179
  }
179
180
 
181
+ /** Who an `@AgentFunction()` call acts for, from the actor of the turn. */
182
+ /**
183
+ * `ctx` is the call's, when there is one; it is absent where the agent asks `@nestjs/authorization`
184
+ * about the actor before any call (whether to offer a tool).
185
+ */
186
+ type AgentFunctionCaller = (actor: Actor, ctx?: AiToolCtx) => AiCaller;
187
+ /**
188
+ * The default {@link AgentFunctionCaller}: the actor is the `user` (what `@nestjs/ai`'s guards read
189
+ * where there is no request, as in a durable run). No `scopes`: the agent gates tools by roles, so a
190
+ * function that requires scopes is refused unless `agentFunctionCaller` maps the actor to them.
191
+ */
192
+ declare const defaultAgentFunctionCaller: AgentFunctionCaller;
193
+
180
194
  /**
181
195
  * A wire protocol other than the native one, served over the same runs — what `adapters` on
182
196
  * `AgentModule.forRoot` takes. An adapter contributes controllers, mounted under the agent's
@@ -201,11 +215,12 @@ interface AgentProtocolAdapter {
201
215
  * each load `AgentModule` without either one doing the other's job:
202
216
  *
203
217
  * - `'both'` (default): today's behavior, unconditionally — every controller AND the full durable
204
- * engine wiring (when `durable: true`). Zero-config single-pod deployments never touch this.
218
+ * engine wiring (when `durable` is on). Zero-config single-pod deployments never touch this.
205
219
  * - `'http'`: mounts every controller (chat/threads/tool-call/quota/agents/attachments) so the HTTP
206
- * surface is fully functional, but under `durable: true` this pod must never EXECUTE agent work —
207
- * see `AgentDurableModuleOptions.surface` (`@dudousxd/nestjs-agent/durable`), which is where the
208
- * actual step-handler exclusion happens; this flag only controls the controllers here.
220
+ * surface is fully functional, but under `durable` this pod must never EXECUTE agent work. On the
221
+ * `'workflows'` engine that is `WorkflowsModule.forRoot({ worker: false })`; on `'aviary'`,
222
+ * `AgentDurableModuleOptions.surface` (`@dudousxd/nestjs-agent/durable`). This flag only controls
223
+ * the controllers here.
209
224
  * - `'engine'`: mounts NO controllers (an API pod's routes have no business existing on a worker
210
225
  * pod that never receives HTTP traffic) — everything else (registry/tools/model/store/sinks, the
211
226
  * `agent.run` workflow, and its dispatched steps under `AgentDurableModule`) stays wired exactly
@@ -216,6 +231,29 @@ interface AgentProtocolAdapter {
216
231
  * metadata can't be computed from a runtime-injected value).
217
232
  */
218
233
  type AgentSurface = 'http' | 'engine' | 'both';
234
+ /**
235
+ * The durable engine `AgentModuleOptions.durable` runs turns on.
236
+ *
237
+ * - `'workflows'` (what `durable: true` means): NestJS's `@nestjs/workflows`. Import
238
+ * `WorkflowsModule.forRoot()` and `AgentWorkflowsModule` (`@dudousxd/nestjs-agent/workflows`).
239
+ * An API pod that must not run turns imports `WorkflowsModule.forRoot({ worker: false })`.
240
+ * - `'aviary'`: `@dudousxd/nestjs-durable`. Import `DurableModule` and `AgentDurableModule`
241
+ * (`@dudousxd/nestjs-agent/durable`). Choose it for what `@nestjs/workflows` does not do: steps
242
+ * dispatched to a separate fleet over a transport (BullMQ, SQS, ...), Python workers, the
243
+ * SQLite/MikroORM stores, `ctx.patched` for changing a running turn's code in place.
244
+ */
245
+ interface AgentDurableOptions {
246
+ /** Default `'workflows'`. */
247
+ engine?: 'workflows' | 'aviary';
248
+ /**
249
+ * `'workflows'` only: model calls per workflow instance. After that many, the turn goes on in a
250
+ * child instance, so no instance's journal grows past what one segment writes (the same idea as
251
+ * `@nestjs/ai`'s `AiAgents` `stepsPerInstance`). Default 10.
252
+ */
253
+ stepsPerInstance?: number;
254
+ }
255
+ /** Which durable engine `durable` names: `undefined` when the turns run in-process. */
256
+ declare function durableEngineOf(durable: boolean | AgentDurableOptions | undefined): 'workflows' | 'aviary' | undefined;
219
257
  /**
220
258
  * `AgentModuleOptions.attachments` — limits for `POST <base>/attachments`, when the bound
221
259
  * `AGENT_ATTACHMENT_STAGING` store does not declare its own (`AgentMediaAttachmentsModule` does, and
@@ -330,11 +368,25 @@ interface AgentModuleOptions {
330
368
  */
331
369
  actionProposalText?: TextActionProposalConfig;
332
370
  /**
333
- * The LLM provider — `aiSdkModel(openai('gpt-5-mini'))`, or `aiSdkModels({ … })` for a model
334
- * picker (its catalog is used when `models` is omitted). Required unless an `engine` runs the
335
- * turns instead.
371
+ * The LLM provider. Omit it to run on `@nestjs/ai`: the turns use the models of the application's
372
+ * `AiModule.forRoot({ models })` (the picker lists them by name, `default` first), with each
373
+ * model's settings, `retry` / `timeout` / `resilience`, `fallback`, `pricing` and `onUsage`. Set
374
+ * it to replace them — a `FakeModelProvider` in tests, `aiSdkModel(…)` outside `AiModule`. Not
375
+ * needed when an `engine` runs the turns.
336
376
  */
337
377
  model?: ModelProvider;
378
+ /**
379
+ * Offer the application's `@nestjs/ai` `@AgentFunction()` methods as agent tools (default), each
380
+ * governed by this library's `@AgentFunction()` options and run through `AiTools.call`, so its guards, interceptors, pipes
381
+ * and filters apply. `false` leaves them to `@nestjs/ai`'s own calls.
382
+ */
383
+ agentFunctions?: boolean;
384
+ /**
385
+ * Who an `@AgentFunction()` call acts for, from the turn's actor — what its guards read. Default:
386
+ * `{ user: actor }`, with no `scopes` (the agent gates by roles); map the actor to scopes here for
387
+ * functions that declare `scopes`.
388
+ */
389
+ agentFunctionCaller?: AgentFunctionCaller;
338
390
  /**
339
391
  * Where a configured model with no price row gets one, at boot. On application bootstrap every
340
392
  * model the `model` provider describes (`aiSdkModel` / `aiSdkModels`) that the bound
@@ -443,22 +495,21 @@ interface AgentModuleOptions {
443
495
  /** Route prefix the controllers mount under. Defaults to `'agent'` (→ `/agent/chat`, …). */
444
496
  path?: string;
445
497
  /**
446
- * Run each turn as a durable workflow instead of in-process. Requires importing
447
- * `AgentDurableModule` from `@dudousxd/nestjs-agent/durable` and a configured `DurableModule`.
498
+ * Run each turn as a durable workflow instead of in-process: each model call and each tool call
499
+ * is a journaled step, a turn parked on a person survives restarts, and a crashed turn resumes
500
+ * where it was. See {@link AgentDurableOptions} for the two engines; `true` is
501
+ * `{ engine: 'workflows' }`, NestJS's own `@nestjs/workflows`.
448
502
  *
449
- * The turn's model call and its tool executions are dispatched steps
450
- * (`AgentRunSteps.llm` / `AgentRunSteps.tool`), so a `@AiTool` handler runs in whichever worker
451
- * serves the routed group rather than in the pod that took the request. A handler that resolves
452
- * anything per invocation from its caller's execution context — a request-scoped ORM
453
- * EntityManager, an AsyncLocalStorage tenant, a CLS transaction — must establish that context
454
- * itself (`@CreateRequestContext`/`@EnsureRequestContext` under MikroORM), exactly as a `@Step`
455
- * handler does.
503
+ * A `@AiTool` handler runs in whichever worker runs the step rather than in the pod that took the
504
+ * request. A handler that resolves anything per invocation from its caller's execution context (a
505
+ * request-scoped ORM EntityManager, an AsyncLocalStorage tenant, a CLS transaction) must
506
+ * establish that context itself.
456
507
  *
457
508
  * Multi-pod fleets MUST also wire a cross-process token sink (e.g. a Redis pub/sub
458
- * `TokenStreamSink`): the turn runs on whichever worker takes `agent.run`, which may not be the
459
- * pod holding the SSE connection.
509
+ * `TokenStreamSink`): the turn runs on whichever worker claims it, which may not be the pod
510
+ * holding the SSE connection.
460
511
  */
461
- durable?: boolean;
512
+ durable?: boolean | AgentDurableOptions;
462
513
  /**
463
514
  * Static functional tools (`{ spec, handler }`, e.g. from `createExecuteSqlTool`) to register at
464
515
  * boot. For tools that need DI-resolved dependencies, use `provideAgentTool(factory, inject)` in a
@@ -574,14 +625,20 @@ interface AgentModuleOptions {
574
625
  */
575
626
  defaultAgent?: string;
576
627
  /**
577
- * Guard(s) applied uniformly to EVERY controller this module mounts (chat, threads, tool-call,
578
- * quota, agents, attachments, config, …). Third-party controller
579
- * classes can't be annotated with `@UseGuards` by consumers, so without this option every route is
580
- * open beyond whatever `actorResolver` itself enforces. Guard classes are added to this module's
581
- * `providers` so Nest can DI-instantiate them; if a guard has its own dependencies, make sure they
582
- * resolve from this module's imports or a global module.
628
+ * Class decorators applied to EVERY controller this module mounts — the ecosystem's convention,
629
+ * like `@nestjs/mcp`'s own `decorators`: decide who reaches the agent's routes with the official
630
+ * tools, e.g. `[UseGuards(AuthenticationGuard), Can(AgentPolicy, 'chat')]` from
631
+ * `@nestjs/authentication` / `@nestjs/authorization`. Applied to a subclass of each controller made
632
+ * for this registration, so nothing sticks to the shared classes. The controllers are open to
633
+ * `@nestjs/authorization`'s deny-by-default guard otherwise (`CanAnyone()`), and a `@Can()` passed
634
+ * here is still checked. Static wiring.
635
+ *
636
+ * A guard class in `UseGuards(...)` is built by Nest inside this module, so it needs no provider
637
+ * entry, but what it injects must resolve here: from a global module, or (with `forRootAsync`)
638
+ * from a module in `imports` that exports it. The removed `guards` option registered the guard
639
+ * class itself as a provider; nothing does now.
583
640
  */
584
- guards?: Type<CanActivate>[];
641
+ decorators?: ClassDecorator[];
585
642
  /** Upload limits when the staging store declares none. Omit → 20 MiB and the default types. */
586
643
  attachments?: AgentAttachmentsOptions;
587
644
  /**
@@ -590,9 +647,18 @@ interface AgentModuleOptions {
590
647
  * which controllers exist at module-build time, not something a request can flip.
591
648
  */
592
649
  surface?: AgentSurface;
650
+ /**
651
+ * `false` mounts none of the agent's routes, while everything else runs — the way NestJS's own
652
+ * packages leave routes to you (`@nestjs/authentication`'s "routes of your own"): serve them from
653
+ * controllers of your own, protected with the official tools. Either call `AgentService` from
654
+ * them, or extend the exported controllers under your own path and decorators:
655
+ * `@Controller('ops/agent/threads') @Can(AgentPolicy, 'chat') class Threads extends ThreadsController {}`.
656
+ * Static wiring, like `surface`.
657
+ */
658
+ routes?: boolean;
593
659
  /**
594
660
  * Wire protocols served alongside the native one, over the same runs — e.g. `[agUiAdapter()]`
595
- * mounts `POST <path>/ag-ui` (AG-UI 1.0). Their controllers mount under `path`, behind `guards`,
661
+ * mounts `POST <path>/ag-ui` (AG-UI 1.0). Their controllers mount under `path`, behind `decorators`,
596
662
  * and not at all on `surface: 'engine'`. STATIC, like `surface`.
597
663
  */
598
664
  adapters?: AgentProtocolAdapter[];
@@ -606,26 +672,21 @@ interface AgentModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
606
672
  */
607
673
  path?: string;
608
674
  /**
609
- * Run each turn as a durable workflow. Static wiring metadata (which `AGENT_RUNNER` to bind), so
610
- * it lives here rather than in the async factory result — the factory resolves too late to swap
611
- * the runner. Requires importing `AgentDurableModule` and a configured `DurableModule`.
612
- */
613
- durable?: boolean;
614
- /**
615
- * Guard(s) applied uniformly to every controller this module mounts. A STATIC field on the async
616
- * config object itself — NOT part of what `useFactory` resolves — because controllers (and the
617
- * enhancers bound to them) are wired at module build time, before any async factory has run. If a
618
- * guard needs async-resolved config (e.g. a secret from a `ConfigService`), have the guard inject
619
- * that service via DI (see `imports`/`inject` above) rather than trying to thread it through
620
- * `useFactory`. Same default-open caveat as `AgentModuleOptions.guards`.
675
+ * Run each turn as a durable workflow (see {@link AgentModuleOptions.durable}). Static wiring
676
+ * metadata (which `AGENT_RUNNER` to bind), so it lives here rather than in the async factory
677
+ * result: the factory resolves too late to swap the runner.
621
678
  */
622
- guards?: Type<CanActivate>[];
679
+ durable?: boolean | AgentDurableOptions;
680
+ /** As {@link AgentModuleOptions.decorators}: static, so it lives here, not in `useFactory`'s result. */
681
+ decorators?: ClassDecorator[];
623
682
  /**
624
683
  * Which half of the module this process mounts (see {@link AgentSurface}). Same static-wiring
625
684
  * reasoning as `durable` above — `useFactory` resolves too late to decide
626
685
  * which controllers exist. Omit → `'both'`, today's behavior with zero change.
627
686
  */
628
687
  surface?: AgentSurface;
688
+ /** As {@link AgentModuleOptions.routes}: static, so it lives here. */
689
+ routes?: boolean;
629
690
  /** Wire protocols served alongside the native one — see `AgentModuleOptions.adapters`. STATIC. */
630
691
  adapters?: AgentProtocolAdapter[];
631
692
  /**
@@ -859,4 +920,4 @@ declare class ChatQueueService {
859
920
  private freshAttachments;
860
921
  }
861
922
 
862
- export { AgentDepsFactory as A, ChatQueueService as C, type FunctionalTool as F, LedgerQuotaProvider as L, type QueuePlan as Q, type AgentSurface as a, type AgentModuleOptions as b, type AgentModuleAsyncOptions as c, type AgentProtocolAdapter as d, type AgentSkillsOptions as e, AGENT_TOOL_BRAND as f, type AgentAttachmentsOptions as g, type AgentDeps as h, type AgentEngine as i, type AgentMemoryOptions as j, type QueueSettleOutcome as k, type QueuedTurn as l, type QueuedTurnStarter as m, type QuotaLimits as n, type QuotaWindowLimits as o, defineTool as p, delegateToolName as q, provideAgentTool as r, provideAgentTools as s, utcDay as u };
923
+ export { AgentDepsFactory as A, ChatQueueService as C, type FunctionalTool as F, LedgerQuotaProvider as L, type QueuePlan as Q, type AgentSurface as a, type AgentModuleOptions as b, type AgentModuleAsyncOptions as c, type AgentProtocolAdapter as d, type AgentSkillsOptions as e, AGENT_TOOL_BRAND as f, type AgentAttachmentsOptions as g, type AgentDeps as h, type AgentDurableOptions as i, type AgentEngine as j, type AgentFunctionCaller as k, type AgentMemoryOptions as l, type QueueSettleOutcome as m, type QueuedTurn as n, type QueuedTurnStarter as o, type QuotaLimits as p, type QuotaWindowLimits as q, defaultAgentFunctionCaller as r, defineTool as s, delegateToolName as t, durableEngineOf as u, provideAgentTool as v, provideAgentTools as w, utcDay as x };