@dudousxd/nestjs-agent 0.8.2 → 0.10.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.
@@ -2,10 +2,10 @@ var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
3
 
4
4
  // src/durable/agent-run.workflow.ts
5
- import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY2, AGENT_STORE, QuotaExceededError, publishAgentRunFailed, runAgentLoop } from "@dudousxd/nestjs-agent-core";
5
+ import { AGENT_DEPS_FACTORY, AGENT_STORE, QuotaExceededError, publishAgentRunFailed, runAgentLoop } from "@dudousxd/nestjs-agent-core";
6
6
  import { Workflow } from "@dudousxd/nestjs-durable";
7
7
  import { isWorkflowControlFlowSignal } from "@dudousxd/nestjs-durable-core";
8
- import { Inject as Inject2, Injectable as Injectable2 } from "@nestjs/common";
8
+ import { Inject, Injectable, Optional } from "@nestjs/common";
9
9
 
10
10
  // src/agent-deps.ts
11
11
  function utcDay(date = /* @__PURE__ */ new Date()) {
@@ -23,10 +23,10 @@ function childSinkWriter(writer) {
23
23
  }
24
24
  __name(childSinkWriter, "childSinkWriter");
25
25
 
26
- // src/durable/agent-run.steps.ts
27
- import { AGENT_DEPS_FACTORY, traceLlmTurn, traceToolExecution, withToolTimeout } from "@dudousxd/nestjs-agent-core";
28
- import { Step } from "@dudousxd/nestjs-durable";
29
- import { Inject, Injectable } from "@nestjs/common";
26
+ // src/durable/dispatched-steps.token.ts
27
+ var AGENT_DISPATCHED_STEPS = Symbol.for("@dudousxd/nestjs-agent:dispatched-steps");
28
+
29
+ // src/durable/agent-run.workflow.ts
30
30
  function _ts_decorate(decorators, target, key, desc) {
31
31
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
32
32
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -44,100 +44,6 @@ function _ts_param(paramIndex, decorator) {
44
44
  };
45
45
  }
46
46
  __name(_ts_param, "_ts_param");
47
- var AgentRunSteps = class {
48
- static {
49
- __name(this, "AgentRunSteps");
50
- }
51
- factory;
52
- constructor(factory) {
53
- this.factory = factory;
54
- }
55
- /**
56
- * Retryable: every side effect (persist/quota/stream markers) happens loop-side under
57
- * `hooks.step`, so a durable retry only re-runs the model call and re-streams its tokens — never
58
- * double-writes. NEVER call `writer.end()`/`fail()` here: the workflow owns the stream's lifecycle,
59
- * across however many turns/retries it takes.
60
- */
61
- async llm(input) {
62
- const deps = this.factory.forAgent(input.agentName);
63
- const tools = await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList);
64
- const opened = await deps.sink.open(input.sinkRunId);
65
- const writer = input.childSink ? childSinkWriter(opened) : opened;
66
- return traceLlmTurn(input.runId, input.step, () => deps.model.runTurn({
67
- system: input.system,
68
- messages: input.messages,
69
- tools,
70
- sink: writer
71
- }));
72
- }
73
- /**
74
- * No retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm` above).
75
- * The timeout is applied HERE, handler-side, via `withToolTimeout` — never as a durable dispatch
76
- * `timeoutMs`, which bounds engine liveness (retryable) rather than the tool's own business outcome.
77
- */
78
- async tool(input) {
79
- const deps = this.factory.forAgent(input.ctx.agentName);
80
- const ctx = {
81
- ...input.ctx
82
- };
83
- return traceToolExecution(input.ctx.runId, {
84
- toolCallId: input.toolCallId,
85
- toolName: input.toolName,
86
- toolType: input.toolType
87
- }, () => {
88
- const invocation = deps.registry.invoke(input.toolName, input.input, ctx, deps.rolesPolicy);
89
- return input.timeoutMs !== void 0 ? withToolTimeout(invocation, input.timeoutMs, input.toolName) : invocation;
90
- });
91
- }
92
- };
93
- _ts_decorate([
94
- Step({
95
- retries: 3
96
- }),
97
- _ts_metadata("design:type", Function),
98
- _ts_metadata("design:paramtypes", [
99
- typeof DispatchedLlmInput === "undefined" ? Object : DispatchedLlmInput
100
- ]),
101
- _ts_metadata("design:returntype", Promise)
102
- ], AgentRunSteps.prototype, "llm", null);
103
- _ts_decorate([
104
- Step(),
105
- _ts_metadata("design:type", Function),
106
- _ts_metadata("design:paramtypes", [
107
- typeof DispatchedToolInput === "undefined" ? Object : DispatchedToolInput
108
- ]),
109
- _ts_metadata("design:returntype", Promise)
110
- ], AgentRunSteps.prototype, "tool", null);
111
- AgentRunSteps = _ts_decorate([
112
- Injectable(),
113
- _ts_param(0, Inject(AGENT_DEPS_FACTORY)),
114
- _ts_metadata("design:type", Function),
115
- _ts_metadata("design:paramtypes", [
116
- typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
117
- ])
118
- ], AgentRunSteps);
119
-
120
- // src/durable/dispatched-steps.token.ts
121
- var AGENT_DISPATCHED_STEPS = Symbol.for("@dudousxd/nestjs-agent:dispatched-steps");
122
-
123
- // src/durable/agent-run.workflow.ts
124
- function _ts_decorate2(decorators, target, key, desc) {
125
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
126
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
127
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
128
- return c > 3 && r && Object.defineProperty(target, key, r), r;
129
- }
130
- __name(_ts_decorate2, "_ts_decorate");
131
- function _ts_metadata2(k, v) {
132
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
133
- }
134
- __name(_ts_metadata2, "_ts_metadata");
135
- function _ts_param2(paramIndex, decorator) {
136
- return function(target, key) {
137
- decorator(target, key, paramIndex);
138
- };
139
- }
140
- __name(_ts_param2, "_ts_param");
141
47
  var AgentRunWorkflow = class _AgentRunWorkflow {
142
48
  static {
143
49
  __name(this, "AgentRunWorkflow");
@@ -155,6 +61,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
155
61
  async run(ctx, input) {
156
62
  const day = input.day ?? utcDay();
157
63
  const deps = this.factory.forAgent(input.agentName);
64
+ const dispatchSteps = this.dispatchedSteps ? this.steps : void 0;
158
65
  if (input.sinkRunId !== void 0) {
159
66
  await ctx.localStep("activate", () => this.store.setActiveStream(input.threadId, ctx.runId));
160
67
  }
@@ -192,8 +99,8 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
192
99
  // `ctx.localStep`s, so a turn isn't pinned to this workflow worker for the model call or a tool
193
100
  // execution. `sinkRunId`/`childSink` are sink routing this workflow already resolved above —
194
101
  // core's dispatchLlm signature stays sink-topology-agnostic, so we add them here, not in core.
195
- ...this.dispatchedSteps ? {
196
- dispatchLlm: /* @__PURE__ */ __name((index, envelope) => ctx.step(this.steps.llm, {
102
+ ...dispatchSteps !== void 0 ? {
103
+ dispatchLlm: /* @__PURE__ */ __name((index, envelope) => ctx.step(dispatchSteps.llm, {
197
104
  ...envelope,
198
105
  runId: ctx.runId,
199
106
  step: index,
@@ -205,7 +112,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
205
112
  // ('agent'-kind delegations branch to runAgent earlier in the loop), so anything that
206
113
  // isn't 'action' is defensively 'read' — the same posture core takes for an
207
114
  // unresolvable `kind`.
208
- dispatchTool: /* @__PURE__ */ __name((call, envelope) => ctx.step(this.steps.tool, {
115
+ dispatchTool: /* @__PURE__ */ __name((call, envelope) => ctx.step(dispatchSteps.tool, {
209
116
  ...envelope,
210
117
  toolCallId: call.id,
211
118
  toolType: call.kind === "action" ? "action" : "read"
@@ -246,24 +153,141 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
246
153
  }
247
154
  }
248
155
  };
249
- AgentRunWorkflow = _ts_decorate2([
250
- Injectable2(),
156
+ AgentRunWorkflow = _ts_decorate([
157
+ Injectable(),
251
158
  Workflow({
252
159
  name: "agent.run",
253
160
  version: "1"
254
161
  }),
255
- _ts_param2(0, Inject2(AGENT_DEPS_FACTORY2)),
256
- _ts_param2(1, Inject2(AGENT_STORE)),
257
- _ts_param2(3, Inject2(AGENT_DISPATCHED_STEPS)),
258
- _ts_metadata2("design:type", Function),
259
- _ts_metadata2("design:paramtypes", [
162
+ _ts_param(0, Inject(AGENT_DEPS_FACTORY)),
163
+ _ts_param(1, Inject(AGENT_STORE)),
164
+ _ts_param(2, Optional()),
165
+ _ts_param(3, Inject(AGENT_DISPATCHED_STEPS)),
166
+ _ts_metadata("design:type", Function),
167
+ _ts_metadata("design:paramtypes", [
260
168
  typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
261
169
  typeof AgentStore === "undefined" ? Object : AgentStore,
262
- typeof AgentRunSteps === "undefined" ? Object : AgentRunSteps,
170
+ Object,
263
171
  Boolean
264
172
  ])
265
173
  ], AgentRunWorkflow);
266
174
 
175
+ // src/durable/agent-run.steps.ts
176
+ import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY2, invokeWithTransientRetry, publishAgentToolRetry, traceLlmTurn, traceToolExecution, withToolTimeout } from "@dudousxd/nestjs-agent-core";
177
+ import { Step } from "@dudousxd/nestjs-durable";
178
+ import { Inject as Inject2, Injectable as Injectable2 } from "@nestjs/common";
179
+ function _ts_decorate2(decorators, target, key, desc) {
180
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
181
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
182
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
183
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
184
+ }
185
+ __name(_ts_decorate2, "_ts_decorate");
186
+ function _ts_metadata2(k, v) {
187
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
188
+ }
189
+ __name(_ts_metadata2, "_ts_metadata");
190
+ function _ts_param2(paramIndex, decorator) {
191
+ return function(target, key) {
192
+ decorator(target, key, paramIndex);
193
+ };
194
+ }
195
+ __name(_ts_param2, "_ts_param");
196
+ var AgentRunSteps = class {
197
+ static {
198
+ __name(this, "AgentRunSteps");
199
+ }
200
+ factory;
201
+ constructor(factory) {
202
+ this.factory = factory;
203
+ }
204
+ /**
205
+ * Retryable: every side effect (persist/quota/stream markers) happens loop-side under
206
+ * `hooks.step`, so a durable retry only re-runs the model call and re-streams its tokens — never
207
+ * double-writes. NEVER call `writer.end()`/`fail()` here: the workflow owns the stream's lifecycle,
208
+ * across however many turns/retries it takes.
209
+ */
210
+ async llm(input) {
211
+ const deps = this.factory.forAgent(input.agentName);
212
+ const tools = await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList);
213
+ const opened = await deps.sink.open(input.sinkRunId);
214
+ const writer = input.childSink ? childSinkWriter(opened) : opened;
215
+ return traceLlmTurn(input.runId, input.step, () => deps.model.runTurn({
216
+ system: input.system,
217
+ messages: input.messages,
218
+ tools,
219
+ sink: writer
220
+ }));
221
+ }
222
+ /**
223
+ * NO DURABLE retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm`
224
+ * above). What it does retry, in place, is a CLASSIFIED-TRANSIENT error from the tool's own
225
+ * invocation (a DB deadlock, a lock-wait timeout — see `isTransientToolError`): the server rolled
226
+ * that work back, so re-invoking it is safe, and doing it here (inside this one step, never a new
227
+ * checkpoint) is exactly how the non-dispatched loop path handles it too. The timeout is applied
228
+ * HERE, handler-side, via `withToolTimeout` — never as a durable dispatch `timeoutMs`, which
229
+ * bounds engine liveness (retryable) rather than the tool's own business outcome — and per
230
+ * ATTEMPT, so a retried invocation gets its own fresh timeout window.
231
+ */
232
+ async tool(input) {
233
+ const deps = this.factory.forAgent(input.ctx.agentName);
234
+ const ctx = {
235
+ ...input.ctx
236
+ };
237
+ const localClassify = deps.toolTransientRetry !== false ? deps.toolTransientRetry?.classify : void 0;
238
+ const transientRetry = input.transientRetry === false ? false : {
239
+ attempts: input.transientRetry.attempts,
240
+ backoffMs: input.transientRetry.backoffMs,
241
+ ...localClassify !== void 0 ? {
242
+ classify: localClassify
243
+ } : {}
244
+ };
245
+ return traceToolExecution(input.ctx.runId, {
246
+ toolCallId: input.toolCallId,
247
+ toolName: input.toolName,
248
+ toolType: input.toolType
249
+ }, () => invokeWithTransientRetry(() => {
250
+ const invocation = deps.registry.invoke(input.toolName, input.input, ctx, deps.rolesPolicy);
251
+ return input.timeoutMs !== void 0 ? withToolTimeout(invocation, input.timeoutMs, input.toolName) : invocation;
252
+ }, transientRetry, {
253
+ onRetry: /* @__PURE__ */ __name((attempt, error) => {
254
+ publishAgentToolRetry({
255
+ toolName: input.toolName,
256
+ toolCallId: input.toolCallId,
257
+ attempt,
258
+ message: error instanceof Error ? error.message : String(error)
259
+ });
260
+ }, "onRetry")
261
+ }));
262
+ }
263
+ };
264
+ _ts_decorate2([
265
+ Step({
266
+ retries: 3
267
+ }),
268
+ _ts_metadata2("design:type", Function),
269
+ _ts_metadata2("design:paramtypes", [
270
+ typeof DispatchedLlmInput === "undefined" ? Object : DispatchedLlmInput
271
+ ]),
272
+ _ts_metadata2("design:returntype", Promise)
273
+ ], AgentRunSteps.prototype, "llm", null);
274
+ _ts_decorate2([
275
+ Step(),
276
+ _ts_metadata2("design:type", Function),
277
+ _ts_metadata2("design:paramtypes", [
278
+ typeof DispatchedToolInput === "undefined" ? Object : DispatchedToolInput
279
+ ]),
280
+ _ts_metadata2("design:returntype", Promise)
281
+ ], AgentRunSteps.prototype, "tool", null);
282
+ AgentRunSteps = _ts_decorate2([
283
+ Injectable2(),
284
+ _ts_param2(0, Inject2(AGENT_DEPS_FACTORY2)),
285
+ _ts_metadata2("design:type", Function),
286
+ _ts_metadata2("design:paramtypes", [
287
+ typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
288
+ ])
289
+ ], AgentRunSteps);
290
+
267
291
  // src/durable/durable-agent-runner.ts
268
292
  import { randomUUID } from "node:crypto";
269
293
  import { WorkflowService } from "@dudousxd/nestjs-durable";
@@ -401,16 +425,68 @@ function _ts_decorate4(decorators, target, key, desc) {
401
425
  }
402
426
  __name(_ts_decorate4, "_ts_decorate");
403
427
  var logger = new Logger("AgentDurableModule");
428
+ function runnerProviders() {
429
+ return [
430
+ DurableAgentRunner,
431
+ {
432
+ provide: AGENT_DURABLE_RUNNER,
433
+ useExisting: DurableAgentRunner
434
+ },
435
+ {
436
+ provide: AGENT_DISPATCHED_STEPS,
437
+ useFactory: /* @__PURE__ */ __name((options, sink) => {
438
+ const enabled = options.durable === true && options.dispatchedSteps !== false;
439
+ if (enabled && sink instanceof InProcessTokenStreamSink) {
440
+ logger.warn("Dispatched steps are active (the default under durable: true) with the default InProcessTokenStreamSink, which only buffers tokens in-process. A dispatched `llm` step served by a different worker cannot stream into this buffer. Wire a cross-process TokenStreamSink (e.g. a Redis pub/sub sink) via AgentModule.forRoot({ sink }) before running multi-pod, or set dispatchedSteps: false to keep the turn in-process localSteps.");
441
+ }
442
+ return enabled;
443
+ }, "useFactory"),
444
+ inject: [
445
+ AGENT_OPTIONS,
446
+ AGENT_SINK
447
+ ]
448
+ }
449
+ ];
450
+ }
451
+ __name(runnerProviders, "runnerProviders");
452
+ var AgentDurableHttpModule = class AgentDurableHttpModule2 {
453
+ static {
454
+ __name(this, "AgentDurableHttpModule");
455
+ }
456
+ };
457
+ AgentDurableHttpModule = _ts_decorate4([
458
+ Global(),
459
+ Module({
460
+ providers: [
461
+ AgentRunWorkflow,
462
+ ...runnerProviders()
463
+ ],
464
+ exports: [
465
+ AGENT_DURABLE_RUNNER,
466
+ AgentRunWorkflow,
467
+ AGENT_DISPATCHED_STEPS
468
+ ]
469
+ })
470
+ ], AgentDurableHttpModule);
404
471
  var AgentDurableModule = class _AgentDurableModule {
405
472
  static {
406
473
  __name(this, "AgentDurableModule");
407
474
  }
408
475
  /**
409
- * The dynamic form used by the `agentDurable` helper. The module needs no configuration of its
410
- * own (its providers come from the decorator above), so this just yields the module reference —
411
- * importing `AgentDurableModule` directly stays equivalent.
476
+ * `surface: 'http'` returns the reduced `AgentDurableHttpModule` wiring (no `AgentRunSteps`);
477
+ * everything else (omitted, `'engine'`, `'both'`) returns this module's own full wiring — the
478
+ * class's `@Module` providers above merge in regardless of which DynamicModule shape a caller
479
+ * imports (Nest merges a class's static provider list with whatever a self-referencing
480
+ * `DynamicModule` adds), which is exactly why the reduced case has to be a DIFFERENT module class
481
+ * rather than a conditional subset of this one's own decorator.
412
482
  */
413
- static forRoot() {
483
+ static forRoot(options) {
484
+ if (options?.surface === "http") {
485
+ return {
486
+ module: AgentDurableHttpModule,
487
+ global: true
488
+ };
489
+ }
414
490
  return {
415
491
  module: _AgentDurableModule,
416
492
  global: true
@@ -423,25 +499,7 @@ AgentDurableModule = _ts_decorate4([
423
499
  providers: [
424
500
  AgentRunWorkflow,
425
501
  AgentRunSteps,
426
- DurableAgentRunner,
427
- {
428
- provide: AGENT_DURABLE_RUNNER,
429
- useExisting: DurableAgentRunner
430
- },
431
- {
432
- provide: AGENT_DISPATCHED_STEPS,
433
- useFactory: /* @__PURE__ */ __name((options, sink) => {
434
- const enabled = options.durable === true && options.dispatchedSteps !== false;
435
- if (enabled && sink instanceof InProcessTokenStreamSink) {
436
- logger.warn("Dispatched steps are active (the default under durable: true) with the default InProcessTokenStreamSink, which only buffers tokens in-process. A dispatched `llm` step served by a different worker cannot stream into this buffer. Wire a cross-process TokenStreamSink (e.g. a Redis pub/sub sink) via AgentModule.forRoot({ sink }) before running multi-pod, or set dispatchedSteps: false to keep the turn in-process localSteps.");
437
- }
438
- return enabled;
439
- }, "useFactory"),
440
- inject: [
441
- AGENT_OPTIONS,
442
- AGENT_SINK
443
- ]
444
- }
502
+ ...runnerProviders()
445
503
  ],
446
504
  exports: [
447
505
  AGENT_DURABLE_RUNNER,
@@ -460,7 +518,7 @@ import { DiscoveryModule, RouterModule } from "@nestjs/core";
460
518
  // src/agent-deps.factory.ts
461
519
  import { AGENT_MODEL, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_ROLES_POLICY, AGENT_SINK as AGENT_SINK2, AGENT_STORE as AGENT_STORE2, AGENT_TOOL_REGISTRY, AgentRegistry as AgentRegistry2, ToolRegistry as ToolRegistry2 } from "@dudousxd/nestjs-agent-core";
462
520
  import { AGENT_OPTIONS as AGENT_OPTIONS2 } from "@dudousxd/nestjs-agent-core";
463
- import { Inject as Inject3, Injectable as Injectable4, Optional } from "@nestjs/common";
521
+ import { Inject as Inject3, Injectable as Injectable4, Optional as Optional2 } from "@nestjs/common";
464
522
  function _ts_decorate5(decorators, target, key, desc) {
465
523
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
466
524
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -562,6 +620,9 @@ var AgentDepsFactory2 = class {
562
620
  ...this.options.toolTimeoutMs !== void 0 ? {
563
621
  toolTimeoutMs: this.options.toolTimeoutMs
564
622
  } : {},
623
+ ...this.options.toolTransientRetry !== void 0 ? {
624
+ toolTransientRetry: this.options.toolTransientRetry
625
+ } : {},
565
626
  ...followUpsCount !== void 0 ? {
566
627
  followUpsCount
567
628
  } : {},
@@ -596,7 +657,7 @@ AgentDepsFactory2 = _ts_decorate5([
596
657
  _ts_param3(6, Inject3(AGENT_REGISTRY)),
597
658
  _ts_param3(7, Inject3(AGENT_PROMPT_CONTRIBUTORS)),
598
659
  _ts_param3(8, Inject3(AGENT_QUOTA_STORE)),
599
- _ts_param3(9, Optional()),
660
+ _ts_param3(9, Optional2()),
600
661
  _ts_param3(9, Inject3(AGENT_PRICING_STORE)),
601
662
  _ts_metadata4("design:type", Function),
602
663
  _ts_metadata4("design:paramtypes", [
@@ -1024,7 +1085,7 @@ AgentsController = _ts_decorate8([
1024
1085
 
1025
1086
  // src/controller/attachments.controller.ts
1026
1087
  import { AGENT_ACTOR_RESOLVER, AGENT_ATTACHMENT_STAGING, AGENT_OPTIONS as AGENT_OPTIONS3 } from "@dudousxd/nestjs-agent-core";
1027
- import { BadRequestException as BadRequestException2, Controller as Controller2, Inject as Inject6, NotImplementedException as NotImplementedException2, Optional as Optional2, PayloadTooLargeException, Post, Req, UnsupportedMediaTypeException, UploadedFile, UseInterceptors } from "@nestjs/common";
1088
+ import { BadRequestException as BadRequestException2, Controller as Controller2, Inject as Inject6, NotImplementedException as NotImplementedException2, Optional as Optional3, PayloadTooLargeException, Post, Req, UnsupportedMediaTypeException, UploadedFile, UseInterceptors } from "@nestjs/common";
1028
1089
  import { FileInterceptor } from "@nestjs/platform-express";
1029
1090
  function _ts_decorate9(decorators, target, key, desc) {
1030
1091
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -1117,7 +1178,7 @@ AttachmentsController = _ts_decorate9([
1117
1178
  Controller2("attachments"),
1118
1179
  _ts_param6(0, Inject6(AGENT_OPTIONS3)),
1119
1180
  _ts_param6(1, Inject6(AGENT_ACTOR_RESOLVER)),
1120
- _ts_param6(2, Optional2()),
1181
+ _ts_param6(2, Optional3()),
1121
1182
  _ts_param6(2, Inject6(AGENT_ATTACHMENT_STAGING)),
1122
1183
  _ts_metadata8("design:type", Function),
1123
1184
  _ts_metadata8("design:paramtypes", [
@@ -2225,6 +2286,10 @@ function controllersFor(mountAttachments) {
2225
2286
  ] : BASE_CONTROLLERS;
2226
2287
  }
2227
2288
  __name(controllersFor, "controllersFor");
2289
+ function controllersForSurface(surface, mountAttachments) {
2290
+ return surface === "engine" ? [] : controllersFor(mountAttachments);
2291
+ }
2292
+ __name(controllersForSurface, "controllersForSurface");
2228
2293
  var GUARDS_METADATA = "__guards__";
2229
2294
  function applyGuards(guards) {
2230
2295
  const resolved = guards ?? [];
@@ -2270,7 +2335,7 @@ var AgentModule = class _AgentModule {
2270
2335
  DiscoveryModule,
2271
2336
  routerFor(path)
2272
2337
  ],
2273
- controllers: controllersFor(options.attachments?.upload === true),
2338
+ controllers: controllersForSurface(options.surface, options.attachments?.upload === true),
2274
2339
  providers: [
2275
2340
  {
2276
2341
  provide: AGENT_OPTIONS5,
@@ -2295,17 +2360,21 @@ var AgentModule = class _AgentModule {
2295
2360
  routerFor(path),
2296
2361
  ...options.imports ?? []
2297
2362
  ],
2298
- controllers: controllersFor(options.attachmentsUpload === true),
2363
+ controllers: controllersForSurface(options.surface, options.attachmentsUpload === true),
2299
2364
  providers: [
2300
2365
  {
2301
2366
  provide: AGENT_OPTIONS5,
2302
- // Stamp the STATIC wiring flags onto the factory result: `durable`/`dispatchedSteps` are
2303
- // authoritative on the async config object (they decided the actual wiring above), and
2304
- // `AgentDurableModule` derives the effective dispatched-steps value from AGENT_OPTIONS —
2305
- // without this stamp, an async host would get in-process localSteps despite durable: true.
2367
+ // Stamp the STATIC wiring flags onto the factory result: `durable`/`dispatchedSteps`/
2368
+ // `surface` are authoritative on the async config object (they decided the actual wiring
2369
+ // above), and `AgentDurableModule` derives the effective dispatched-steps value from
2370
+ // AGENT_OPTIONS — without this stamp, an async host would get in-process localSteps
2371
+ // despite durable: true. `surface` isn't read back by anything today (AgentDurableModule
2372
+ // takes its own mirror option — see its doc for why), but it's stamped here too so the
2373
+ // EFFECTIVE value is always observable off AGENT_OPTIONS, sync or async alike.
2306
2374
  useFactory: /* @__PURE__ */ __name(async (...args) => ({
2307
2375
  ...await options.useFactory(...args),
2308
2376
  durable: options.durable ?? false,
2377
+ surface: options.surface ?? "both",
2309
2378
  ...options.dispatchedSteps !== void 0 ? {
2310
2379
  dispatchedSteps: options.dispatchedSteps
2311
2380
  } : {}
@@ -2331,7 +2400,9 @@ function agentDurable(options) {
2331
2400
  ...options,
2332
2401
  durable: true
2333
2402
  }),
2334
- AgentDurableModule.forRoot()
2403
+ AgentDurableModule.forRoot(options.surface !== void 0 ? {
2404
+ surface: options.surface
2405
+ } : {})
2335
2406
  ];
2336
2407
  }
2337
2408
  __name(agentDurable, "agentDurable");