@dudousxd/nestjs-agent 1.16.1 → 1.17.1

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.
@@ -30,10 +30,10 @@ __export(durable_exports, {
30
30
  module.exports = __toCommonJS(durable_exports);
31
31
 
32
32
  // src/durable/agent-run.workflow.ts
33
- var import_nestjs_agent_core3 = require("@dudousxd/nestjs-agent-core");
33
+ var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
34
34
  var import_nestjs_durable2 = require("@dudousxd/nestjs-durable");
35
35
  var import_nestjs_durable_core2 = require("@dudousxd/nestjs-durable-core");
36
- var import_common3 = require("@nestjs/common");
36
+ var import_common2 = require("@nestjs/common");
37
37
 
38
38
  // src/agent-deps.ts
39
39
  function utcDay(date = /* @__PURE__ */ new Date()) {
@@ -51,9 +51,26 @@ function childSinkWriter(writer) {
51
51
  }
52
52
  __name(childSinkWriter, "childSinkWriter");
53
53
 
54
- // src/queue/chat-queue.service.ts
54
+ // src/queue/chat-queue.token.ts
55
+ var AGENT_CHAT_QUEUE = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:chat-queue");
56
+
57
+ // src/durable/agent-run.steps.ts
55
58
  var import_nestjs_agent_core = require("@dudousxd/nestjs-agent-core");
59
+ var import_nestjs_durable = require("@dudousxd/nestjs-durable");
56
60
  var import_common = require("@nestjs/common");
61
+
62
+ // src/durable/outside-workflow-ctx.ts
63
+ var import_nestjs_durable_core = require("@dudousxd/nestjs-durable-core");
64
+ function outsideWorkflowCtx(fn) {
65
+ return (0, import_nestjs_durable_core.runInWorkflowCtx)(void 0, fn);
66
+ }
67
+ __name(outsideWorkflowCtx, "outsideWorkflowCtx");
68
+ function stepOf(ctx) {
69
+ return (name, fn, ...rest) => ctx.localStep(name, (...args) => outsideWorkflowCtx(() => fn(...args)), ...rest);
70
+ }
71
+ __name(stepOf, "stepOf");
72
+
73
+ // src/durable/agent-run.steps.ts
57
74
  function _ts_decorate(decorators, target, key, desc) {
58
75
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
59
76
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -80,736 +97,296 @@ function _ts_param(paramIndex, decorator) {
80
97
  };
81
98
  }
82
99
  __name(_ts_param, "_ts_param");
83
- var MAX_DRAIN_ATTEMPTS = 8;
84
- var ChatQueueService = class _ChatQueueService {
100
+ var AgentRunSteps = class {
85
101
  static {
86
- __name(this, "ChatQueueService");
102
+ __name(this, "AgentRunSteps");
103
+ }
104
+ factory;
105
+ constructor(factory) {
106
+ this.factory = factory;
87
107
  }
88
- store;
89
- sink;
90
- quotaProvider;
91
- options;
92
- staging;
93
- logger = new import_common.Logger(_ChatQueueService.name);
94
108
  /**
95
- * Runs this process claimed a thread for and has not handed to a runner yet. A holder in here is
96
- * alive whatever the runner says — it simply has not registered the run yet.
109
+ * Retryable: every side effect (persist/quota/stream markers) happens loop-side under
110
+ * `hooks.step`, so a durable retry only re-runs the model call and re-streams its tokens — never
111
+ * double-writes. NEVER call `writer.end()`/`fail()` here: the workflow owns the stream's lifecycle,
112
+ * across however many turns/retries it takes.
97
113
  */
98
- starting = /* @__PURE__ */ new Set();
99
- constructor(store, sink, quotaProvider, options, staging) {
100
- this.store = store;
101
- this.sink = sink;
102
- this.quotaProvider = quotaProvider;
103
- this.options = options;
104
- this.staging = staging;
105
- }
106
- /** Whether the bound store can hold a queue. Without one, a busy thread is not queued. */
107
- get supported() {
108
- return (0, import_nestjs_agent_core.isChatQueueStore)(this.store);
114
+ llm(input) {
115
+ return outsideWorkflowCtx(() => this.runLlm(input));
109
116
  }
110
- /** The bound store as a queue store, or a 501 naming what is missing. */
111
- queueStore() {
112
- if (!(0, import_nestjs_agent_core.isChatQueueStore)(this.store)) {
113
- throw new import_common.NotImplementedException("Queueing messages requires an AgentStore that implements ChatQueueStore (enqueueMessage, listQueue, \u2026, claimActiveStream, releaseActiveStream); the bound store does not.");
117
+ async runLlm(input) {
118
+ const deps = this.factory.forAgent(input.agentName);
119
+ const tools = (0, import_nestjs_agent_core.withMemoryTool)({
120
+ tools: (0, import_nestjs_agent_core.withSkillTool)({
121
+ tools: (0, import_nestjs_agent_core.withAskTool)({
122
+ tools: await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList, {
123
+ ...input.threadId !== void 0 ? {
124
+ threadId: input.threadId
125
+ } : {},
126
+ ...input.agentName !== void 0 ? {
127
+ agentName: input.agentName
128
+ } : {}
129
+ }),
130
+ ask: deps.ask
131
+ }),
132
+ enabled: deps.skills !== void 0
133
+ }),
134
+ enabled: deps.memory?.provider.write !== void 0
135
+ });
136
+ const buffer = input.bufferOutput === true ? (0, import_nestjs_agent_core.createFrameBuffer)() : void 0;
137
+ let writer;
138
+ if (buffer !== void 0) {
139
+ writer = buffer.writer;
140
+ } else {
141
+ const opened = await deps.sink.open(input.sinkRunId);
142
+ writer = input.childSink ? childSinkWriter(opened) : opened;
114
143
  }
115
- return this.store;
116
- }
117
- async state(threadId) {
118
- const store = this.queueStore();
119
- const [items, paused] = await Promise.all([
120
- store.listQueue(threadId),
121
- store.queuePause(threadId)
122
- ]);
123
- return {
124
- items: items.map(import_nestjs_agent_core.queuedMessageView),
125
- paused
144
+ const frames = (0, import_nestjs_agent_core.observeTurnFrames)(writer);
145
+ const turn = (0, import_nestjs_agent_core.withTurnFrames)(await (0, import_nestjs_agent_core.traceLlmTurn)(input.runId, input.step, () => deps.model.runTurn({
146
+ system: input.system,
147
+ messages: input.messages,
148
+ tools,
149
+ sink: frames.writer,
150
+ ...input.model !== void 0 ? {
151
+ model: input.model
152
+ } : {}
153
+ })), frames.summary());
154
+ const stamped = (0, import_nestjs_agent_core.stampToolKinds)(turn, deps);
155
+ return buffer === void 0 ? stamped : {
156
+ ...stamped,
157
+ bufferedFrames: buffer.frames()
126
158
  };
127
159
  }
128
160
  /**
129
- * Whether `holder` is still running. A run this process is about to start is; otherwise the
130
- * runner decides, and a runner that cannot tell says yes.
161
+ * NO DURABLE retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm`
162
+ * above). What it does retry, in place, is a CLASSIFIED-TRANSIENT error from the tool's own
163
+ * invocation (a DB deadlock, a lock-wait timeout — see `isTransientToolError`): the server rolled
164
+ * that work back, so re-invoking it is safe, and doing it here (inside this one step, never a new
165
+ * checkpoint) is exactly how the non-dispatched loop path handles it too. The timeout is applied
166
+ * HERE, handler-side, via `withToolTimeout` — never as a durable dispatch `timeoutMs`, which
167
+ * bounds engine liveness (retryable) rather than the tool's own business outcome — and per
168
+ * ATTEMPT, so a retried invocation gets its own fresh timeout window.
131
169
  */
132
- async isAlive(holder, runner) {
133
- if (this.starting.has(holder)) {
134
- return true;
135
- }
136
- if (typeof runner.isRunActive !== "function") {
137
- return true;
138
- }
139
- try {
140
- return await runner.isRunActive(holder);
141
- } catch {
142
- return true;
143
- }
170
+ tool(input) {
171
+ return outsideWorkflowCtx(() => this.runTool(input));
144
172
  }
145
- /**
146
- * The run holding `threadId`, or `null` when it is free — a holder the runner reports dead counts
147
- * as free, and is returned as `stale` so the caller can claim over it.
148
- */
149
- async holder(threadId, runner) {
150
- const holder = await this.queueStore().activeRunForThread(threadId);
151
- if (holder === null) {
152
- return {
153
- live: null,
154
- stale: null
155
- };
173
+ async runTool(input) {
174
+ const deps = this.factory.forAgent(input.ctx.agentName);
175
+ if (deps.registry.spec(input.toolName)?.kind === "action" && input.toolType !== "action") {
176
+ throw new Error(`tool "${input.toolName}" is an action tool but was dispatched without approval: the dispatching process resolved its kind against a registry that does not have it`);
156
177
  }
157
- return await this.isAlive(holder, runner) ? {
158
- live: holder,
159
- stale: null
160
- } : {
161
- live: null,
162
- stale: holder
178
+ const sinkRunId = input.sinkRunId;
179
+ let opened;
180
+ const ui = (0, import_nestjs_agent_core.createUiCollector)(input.toolCallId, sinkRunId === void 0 ? void 0 : async (event) => {
181
+ opened ??= Promise.resolve(deps.sink.open(sinkRunId)).then((writer) => input.childSink === true ? childSinkWriter(writer) : writer);
182
+ await (await opened).write((0, import_nestjs_agent_core.encodeStreamEvent)(event));
183
+ });
184
+ const ctx = {
185
+ ...(0, import_nestjs_agent_core.toolCallContext)(input.ctx, input.toolCallId),
186
+ emitUi: ui.emit
187
+ };
188
+ const localClassify = deps.toolTransientRetry !== false ? deps.toolTransientRetry?.classify : void 0;
189
+ const transientRetry = input.transientRetry === false ? false : {
190
+ attempts: input.transientRetry.attempts,
191
+ backoffMs: input.transientRetry.backoffMs,
192
+ ...localClassify !== void 0 ? {
193
+ classify: localClassify
194
+ } : {}
163
195
  };
196
+ const output = await (0, import_nestjs_agent_core.traceToolExecution)(input.ctx.runId, {
197
+ toolCallId: input.toolCallId,
198
+ toolName: input.toolName,
199
+ toolType: input.toolType
200
+ }, () => (0, import_nestjs_agent_core.invokeWithTransientRetry)(() => {
201
+ ui.restart();
202
+ const invocation = deps.registry.invoke(input.toolName, input.input, ctx, deps.rolesPolicy);
203
+ return input.timeoutMs !== void 0 ? (0, import_nestjs_agent_core.withToolTimeout)(invocation, input.timeoutMs, input.toolName) : invocation;
204
+ }, transientRetry, {
205
+ onRetry: /* @__PURE__ */ __name((attempt, error) => {
206
+ (0, import_nestjs_agent_core.publishAgentToolRetry)({
207
+ toolName: input.toolName,
208
+ toolCallId: input.toolCallId,
209
+ attempt,
210
+ message: error instanceof Error ? error.message : String(error)
211
+ });
212
+ }, "onRetry")
213
+ }));
214
+ return input.collectUi === true ? (0, import_nestjs_agent_core.wrapToolStepOutput)(output, ui.components()) : output;
215
+ }
216
+ };
217
+ _ts_decorate([
218
+ (0, import_nestjs_durable.Step)({
219
+ retries: 3
220
+ }),
221
+ _ts_metadata("design:type", Function),
222
+ _ts_metadata("design:paramtypes", [
223
+ typeof DispatchedLlmInput === "undefined" ? Object : DispatchedLlmInput
224
+ ]),
225
+ _ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
226
+ ], AgentRunSteps.prototype, "llm", null);
227
+ _ts_decorate([
228
+ (0, import_nestjs_durable.Step)(),
229
+ _ts_metadata("design:type", Function),
230
+ _ts_metadata("design:paramtypes", [
231
+ typeof DispatchedToolInput === "undefined" ? Object : DispatchedToolInput
232
+ ]),
233
+ _ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
234
+ ], AgentRunSteps.prototype, "tool", null);
235
+ AgentRunSteps = _ts_decorate([
236
+ (0, import_common.Injectable)(),
237
+ _ts_param(0, (0, import_common.Inject)(import_nestjs_agent_core.AGENT_DEPS_FACTORY)),
238
+ _ts_metadata("design:type", Function),
239
+ _ts_metadata("design:paramtypes", [
240
+ typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
241
+ ])
242
+ ], AgentRunSteps);
243
+
244
+ // src/durable/agent-run.workflow.ts
245
+ function _ts_decorate2(decorators, target, key, desc) {
246
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
247
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
248
+ r = Reflect.decorate(decorators, target, key, desc);
249
+ } else {
250
+ for (var i = decorators.length - 1; i >= 0; i--) {
251
+ if (d = decorators[i]) {
252
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
253
+ }
254
+ }
255
+ }
256
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
257
+ }
258
+ __name(_ts_decorate2, "_ts_decorate");
259
+ function _ts_metadata2(metadataKey, metadataValue) {
260
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
261
+ return Reflect.metadata(metadataKey, metadataValue);
262
+ }
263
+ }
264
+ __name(_ts_metadata2, "_ts_metadata");
265
+ function _ts_param2(paramIndex, decorator) {
266
+ return function(target, key) {
267
+ decorator(target, key, paramIndex);
268
+ };
269
+ }
270
+ __name(_ts_param2, "_ts_param");
271
+ var AgentRunWorkflow = class _AgentRunWorkflow {
272
+ static {
273
+ __name(this, "AgentRunWorkflow");
274
+ }
275
+ factory;
276
+ store;
277
+ runs;
278
+ queue;
279
+ logger = new import_common2.Logger(_AgentRunWorkflow.name);
280
+ constructor(factory, store, runs, queue) {
281
+ this.factory = factory;
282
+ this.store = store;
283
+ this.runs = runs;
284
+ this.queue = queue;
164
285
  }
165
286
  /**
166
- * Decide what follows a TOP-LEVEL run that is settling on `threadId`, and move the thread there:
167
- * hand it to the next queued message (claimed and popped here, started by the caller), or pause
168
- * the queue, or release the thread. Call it BEFORE the run's terminal frame, so a client reading
169
- * the stream learns what comes next from the `queue` frame, and so the thread is already free
170
- * when the client sees the run end.
287
+ * Move the thread past this settling turn — to the next queued message, started here as a
288
+ * fire-and-forget `ctx.startChild` under the message's own id, or to a paused/empty queue — and
289
+ * answer the `queue` frame to write before the turn's terminal.
171
290
  *
172
- * A no-op returning `{}` on a store without a queue.
291
+ * Journaled: the decision (which message, claimed and popped) is one `localStep`, so a replay
292
+ * reads it back instead of popping a second message, and the start is the runtime's own
293
+ * replay-safe spawn. Gated by `ctx.patched`, so a run recorded before the queue existed replays
294
+ * against the history it has. A no-op for a sub-agent's run and on a store without a queue.
173
295
  */
174
- async plan(args) {
175
- if (!(0, import_nestjs_agent_core.isChatQueueStore)(this.store)) {
176
- return {};
296
+ async advanceQueue(ctx, input, outcome, error) {
297
+ const queue = this.queue;
298
+ if (queue === void 0 || !queue.supported || input.sinkRunId !== void 0 || input.deliverTo !== void 0) {
299
+ return void 0;
177
300
  }
178
- const store = this.store;
179
- const { threadId, outcome } = args;
180
- if (await store.activeRunForThread(threadId) !== args.runId) {
181
- return {};
301
+ if (!await ctx.patched("agent:chat-queue")) {
302
+ return void 0;
182
303
  }
183
- let holding = args.runId;
184
- for (let attempt = 0; attempt < MAX_DRAIN_ATTEMPTS; attempt += 1) {
185
- const items = await store.listQueue(threadId);
186
- const head = items[0];
187
- if (head === void 0) {
188
- if (holding !== null) {
189
- await store.releaseActiveStream(threadId, holding);
190
- holding = null;
191
- continue;
192
- }
193
- return {};
194
- }
195
- let pause = await store.queuePause(threadId);
196
- if (pause === null) {
197
- const reason = pauseReasonFor(outcome, head);
198
- if (reason !== null) {
199
- pause = {
200
- reason,
201
- ...outcome === "failed" && args.error !== void 0 ? {
202
- message: args.error
203
- } : {},
204
- at: (/* @__PURE__ */ new Date()).toISOString()
205
- };
206
- await store.setQueuePause(threadId, pause);
207
- }
208
- }
209
- if (pause === null) {
210
- const blocked = await this.quotaBlock(head.actor);
211
- if (blocked !== null) {
212
- pause = {
213
- reason: "quota_exceeded",
214
- message: blocked,
215
- at: (/* @__PURE__ */ new Date()).toISOString()
216
- };
217
- await store.setQueuePause(threadId, pause);
218
- }
219
- }
220
- if (pause !== null) {
221
- if (holding !== null) {
222
- await store.releaseActiveStream(threadId, holding);
223
- }
224
- return {
225
- frame: queueFrame(items, pause)
226
- };
227
- }
228
- const claimed = await store.claimActiveStream(threadId, head.id, holding !== null ? {
229
- replacing: holding
230
- } : {});
231
- if (!claimed) {
304
+ const plan = await stepOf(ctx)(`queue:${outcome}`, async () => {
305
+ try {
306
+ const settled = outcome === "completed" && await this.isCancelled(ctx.runId) ? "cancelled" : outcome;
307
+ return await queue.plan({
308
+ threadId: input.threadId,
309
+ runId: ctx.runId,
310
+ outcome: settled,
311
+ ...error !== void 0 ? {
312
+ error
313
+ } : {}
314
+ });
315
+ } catch {
232
316
  return {};
233
317
  }
234
- holding = head.id;
235
- if (!await store.removeQueuedMessage(head.id)) {
236
- await store.releaseActiveStream(threadId, head.id);
237
- holding = null;
238
- continue;
239
- }
240
- const next = {
241
- runId: head.id,
242
- messageId: head.id,
243
- input: await this.inputFor(head)
244
- };
245
- return {
246
- next,
247
- frame: queueFrame(items.slice(1), null, {
248
- messageId: head.id,
249
- runId: head.id
250
- })
251
- };
252
- }
253
- if (holding !== null) {
254
- await store.releaseActiveStream(threadId, holding);
255
- }
256
- return {};
257
- }
258
- /**
259
- * {@link plan}, then start what it picked with `start`. What an in-process settle (the inline
260
- * runner, a durable cancel issued outside a workflow) calls; answers the frame to write.
261
- */
262
- async handoff(args, start) {
263
- const plan = await this.plan(args);
264
- if (plan.next === void 0) {
265
- return plan.frame;
266
- }
267
- return await this.launch(args.threadId, plan.next, start) ? plan.frame : this.pausedFrame(args.threadId);
268
- }
269
- /**
270
- * Start the head of an IDLE thread's queue — after a send queued behind a run that turned out to
271
- * be gone, after a resume, after a stale holder. Does nothing while a live run holds the thread
272
- * (its settle drains) or while the queue is paused. Answers the started run's id, if any.
273
- */
274
- async kick(threadId, runner) {
275
- if (!(0, import_nestjs_agent_core.isChatQueueStore)(this.store)) {
276
- return void 0;
277
- }
278
- const { live, stale } = await this.holder(threadId, runner);
279
- if (live !== null) {
280
- return void 0;
281
- }
282
- if (stale !== null) {
283
- this.logger.warn(`thread ${threadId} was held by run ${stale}, which is no longer running`);
284
- }
285
- const plan = await this.plan({
286
- threadId,
287
- runId: stale,
288
- outcome: "completed"
289
318
  });
290
- if (plan.next === void 0) {
291
- return void 0;
319
+ const next = plan.next;
320
+ if (next === void 0) {
321
+ return plan.frame;
292
322
  }
293
- const started = await this.launch(threadId, plan.next, (input, runId) => runner.start(input, {
294
- runId
295
- }));
296
- if (started && plan.frame !== void 0) {
297
- await this.write(plan.next.runId, plan.frame);
323
+ try {
324
+ await ctx.startChild(_AgentRunWorkflow, next.input, next.runId);
325
+ return plan.frame;
326
+ } catch (failure) {
327
+ if ((0, import_nestjs_durable_core2.isWorkflowControlFlowSignal)(failure)) {
328
+ throw failure;
329
+ }
330
+ const reason = failure instanceof Error ? failure.message : String(failure);
331
+ return stepOf(ctx)("queue:restore", async () => {
332
+ await queue.restore(input.threadId, next, "start_failed", reason);
333
+ return queue.pausedFrame(input.threadId);
334
+ });
298
335
  }
299
- return started ? plan.next.runId : void 0;
300
336
  }
301
337
  /**
302
- * Start a turn the thread is already claimed for. On failure the message goes back to the head of
303
- * the queue, the queue pauses (`start_failed`), and the claim is released — nothing is lost and
304
- * nothing is left holding the thread.
338
+ * Has someone asked this run to stop? Read from the runtime's own run status, which is where
339
+ * `DurableAgentRunner.cancel` puts it — `cancelling` while a compensating cancel is in flight,
340
+ * `cancelled` once it has settled.
341
+ *
342
+ * Costs a run read at each of the loop's observation points (two per step). That is a row the
343
+ * control plane already has, against a turn that is otherwise making model calls, and it buys the
344
+ * property that matters: the answer comes from a place BOTH the canceller and every pod that might
345
+ * replay this run can see.
346
+ *
347
+ * Failing to ask is not a cancel. A tenant with no gateway wired, or an operator briefly
348
+ * unreachable, answers "no" and the run carries on — the alternative is failing healthy runs
349
+ * because a status read timed out. The loop journals that answer like any other, so two processes
350
+ * can never disagree about what was seen here.
305
351
  */
306
- async launch(threadId, next, start) {
307
- this.starting.add(next.runId);
352
+ async isCancelled(runId) {
308
353
  try {
309
- await start(next.input, next.runId);
310
- return true;
311
- } catch (error) {
312
- const message = error instanceof Error ? error.message : String(error);
313
- this.logger.error(`queued message ${next.messageId} could not start: ${message}`);
314
- await this.restore(threadId, next, "start_failed", message);
354
+ const status = (await this.runs?.getRunDetail(runId))?.run.status;
355
+ return status === "cancelled" || status === "cancelling";
356
+ } catch {
315
357
  return false;
316
- } finally {
317
- this.starting.delete(next.runId);
318
358
  }
319
359
  }
320
- /** Put a turn that never started back at the head of its queue, paused, and free the thread. */
321
- async restore(threadId, next, reason, message) {
322
- const store = this.queueStore();
323
- const { input } = next;
324
- await store.enqueueMessage({
325
- threadId,
326
- actor: input.actor,
327
- content: input.userText,
328
- at: "head",
329
- ...input.attachments !== void 0 ? {
330
- attachments: input.attachments
331
- } : {},
332
- ...input.agentName !== void 0 ? {
333
- agentName: input.agentName
334
- } : {},
335
- ...input.model !== void 0 ? {
336
- model: input.model
337
- } : {},
338
- ...input.pageContext !== void 0 ? {
339
- pageContext: input.pageContext
340
- } : {}
341
- });
342
- await store.setQueuePause(threadId, {
343
- reason,
344
- message,
345
- at: (/* @__PURE__ */ new Date()).toISOString()
346
- });
347
- await store.releaseActiveStream(threadId, next.runId);
348
- }
349
- /** A `queue` frame with the thread's current state. */
350
- async pausedFrame(threadId) {
351
- return {
352
- kind: "queue",
353
- queue: await this.state(threadId)
354
- };
355
- }
356
360
  /**
357
- * Tell whoever is watching the thread that its queue changed: a `queue` frame into the stream of
358
- * the run holding it. Best-effort — a thread nobody is streaming has no one to tell, and the next
359
- * read of the thread carries the queue anyway.
361
+ * Settle the delegation a DETACHED run was started for, when that run ends without an answer.
362
+ *
363
+ * The loop delivers its own success (`deliver:detached`) but cannot catch its own crash, and the
364
+ * runtime settles the run row without knowing anything delegated it. Left alone, the card in the
365
+ * calling conversation says "started" for ever — the one state a reader can neither wait on nor
366
+ * act on. A no-op for every other run: only a detached one carries a delivery address.
360
367
  */
361
- async publish(threadId) {
362
- const state = await this.state(threadId);
363
- const holder = await this.queueStore().activeRunForThread(threadId);
364
- if (holder !== null) {
365
- await this.write(holder, {
366
- kind: "queue",
367
- queue: state
368
- }).catch((error) => {
369
- this.logger.warn(`could not publish the queue of thread ${threadId}: ${error instanceof Error ? error.message : String(error)}`);
370
- });
368
+ async settleDetachedParent(ctx, input, outcome) {
369
+ const delivery = input.deliverTo;
370
+ if (delivery === void 0) {
371
+ return;
371
372
  }
372
- return state;
373
- }
374
- async write(runId, frame) {
375
- const writer = await this.sink.open(runId);
376
- await writer.write((0, import_nestjs_agent_core.encodeStreamEvent)(frame));
373
+ await stepOf(ctx)("deliver:detached:unsettled", () => (0, import_nestjs_agent_core2.settleUnsettledDelegation)({
374
+ store: this.store,
375
+ delivery,
376
+ agent: input.agentName ?? "default",
377
+ runId: ctx.runId,
378
+ status: outcome.status,
379
+ ...outcome.error !== void 0 ? {
380
+ error: outcome.error
381
+ } : {}
382
+ }));
377
383
  }
378
- /** Why `actor` may not start a turn now (the quota message), or `null`. */
379
- async quotaBlock(actor) {
380
- if (this.options?.quota === void 0 || this.quotaProvider === void 0) {
381
- return null;
382
- }
383
- try {
384
- const { blocked } = await this.quotaProvider.report({
385
- actor
386
- });
387
- if (blocked === void 0) {
388
- return null;
389
- }
390
- return blocked.reason ?? `The ${blocked.period === "day" ? "daily" : "monthly"} quota is used up`;
391
- } catch {
392
- return null;
393
- }
394
- }
395
- /**
396
- * The turn a queued message starts: everything it was queued with, today's date, and its
397
- * attachments' urls minted afresh — the ones stored at enqueue time may have expired while it
398
- * waited. An attachment the staging store no longer resolves keeps its stored url.
399
- */
400
- async inputFor(message) {
401
- const attachments = await this.freshAttachments(message.actor, message.attachments ?? []);
402
- return {
403
- threadId: message.threadId,
404
- actor: message.actor,
405
- userText: message.content,
406
- day: utcDay(),
407
- ...message.agentName !== void 0 ? {
408
- agentName: message.agentName
409
- } : {},
410
- ...attachments.length > 0 ? {
411
- attachments
412
- } : {},
413
- ...message.pageContext !== void 0 ? {
414
- pageContext: message.pageContext
415
- } : {},
416
- ...message.model !== void 0 ? {
417
- model: message.model
418
- } : {}
419
- };
420
- }
421
- async freshAttachments(actor, attachments) {
422
- const staging = this.staging;
423
- if (attachments.length === 0 || staging === void 0 || typeof staging.resolve !== "function") {
424
- return attachments;
425
- }
426
- return Promise.all(attachments.map(async (attachment) => {
427
- try {
428
- return await staging.resolve({
429
- mediaId: attachment.mediaId,
430
- actor
431
- }) ?? attachment;
432
- } catch {
433
- return attachment;
434
- }
435
- }));
436
- }
437
- };
438
- ChatQueueService = _ts_decorate([
439
- (0, import_common.Injectable)(),
440
- _ts_param(0, (0, import_common.Inject)(import_nestjs_agent_core.AGENT_STORE)),
441
- _ts_param(1, (0, import_common.Inject)(import_nestjs_agent_core.AGENT_SINK)),
442
- _ts_param(2, (0, import_common.Optional)()),
443
- _ts_param(2, (0, import_common.Inject)(import_nestjs_agent_core.AGENT_QUOTA_PROVIDER)),
444
- _ts_param(3, (0, import_common.Optional)()),
445
- _ts_param(3, (0, import_common.Inject)(import_nestjs_agent_core.AGENT_OPTIONS)),
446
- _ts_param(4, (0, import_common.Optional)()),
447
- _ts_param(4, (0, import_common.Inject)(import_nestjs_agent_core.AGENT_ATTACHMENT_STAGING)),
448
- _ts_metadata("design:type", Function),
449
- _ts_metadata("design:paramtypes", [
450
- typeof AgentStore === "undefined" ? Object : AgentStore,
451
- typeof TokenStreamSink === "undefined" ? Object : TokenStreamSink,
452
- typeof QuotaProvider === "undefined" ? Object : QuotaProvider,
453
- typeof Pick === "undefined" ? Object : Pick,
454
- typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore
455
- ])
456
- ], ChatQueueService);
457
- function pauseReasonFor(outcome, head) {
458
- if (outcome === "failed") {
459
- return "run_failed";
460
- }
461
- if (outcome === "cancelled" && head.interrupt !== true) {
462
- return "cancelled";
463
- }
464
- return null;
465
- }
466
- __name(pauseReasonFor, "pauseReasonFor");
467
- function queueFrame(items, paused, started) {
468
- return {
469
- kind: "queue",
470
- queue: {
471
- items: items.map(import_nestjs_agent_core.queuedMessageView),
472
- paused
473
- },
474
- ...started !== void 0 ? {
475
- started
476
- } : {}
477
- };
478
- }
479
- __name(queueFrame, "queueFrame");
480
-
481
- // src/durable/agent-run.steps.ts
482
- var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
483
- var import_nestjs_durable = require("@dudousxd/nestjs-durable");
484
- var import_common2 = require("@nestjs/common");
485
-
486
- // src/durable/outside-workflow-ctx.ts
487
- var import_nestjs_durable_core = require("@dudousxd/nestjs-durable-core");
488
- function outsideWorkflowCtx(fn) {
489
- return (0, import_nestjs_durable_core.runInWorkflowCtx)(void 0, fn);
490
- }
491
- __name(outsideWorkflowCtx, "outsideWorkflowCtx");
492
- function stepOf(ctx) {
493
- return (name, fn, ...rest) => ctx.localStep(name, (...args) => outsideWorkflowCtx(() => fn(...args)), ...rest);
494
- }
495
- __name(stepOf, "stepOf");
496
-
497
- // src/durable/agent-run.steps.ts
498
- function _ts_decorate2(decorators, target, key, desc) {
499
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
500
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
501
- r = Reflect.decorate(decorators, target, key, desc);
502
- } else {
503
- for (var i = decorators.length - 1; i >= 0; i--) {
504
- if (d = decorators[i]) {
505
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
506
- }
507
- }
508
- }
509
- return c > 3 && r && Object.defineProperty(target, key, r), r;
510
- }
511
- __name(_ts_decorate2, "_ts_decorate");
512
- function _ts_metadata2(metadataKey, metadataValue) {
513
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
514
- return Reflect.metadata(metadataKey, metadataValue);
515
- }
516
- }
517
- __name(_ts_metadata2, "_ts_metadata");
518
- function _ts_param2(paramIndex, decorator) {
519
- return function(target, key) {
520
- decorator(target, key, paramIndex);
521
- };
522
- }
523
- __name(_ts_param2, "_ts_param");
524
- var AgentRunSteps = class {
525
- static {
526
- __name(this, "AgentRunSteps");
527
- }
528
- factory;
529
- constructor(factory) {
530
- this.factory = factory;
531
- }
532
- /**
533
- * Retryable: every side effect (persist/quota/stream markers) happens loop-side under
534
- * `hooks.step`, so a durable retry only re-runs the model call and re-streams its tokens — never
535
- * double-writes. NEVER call `writer.end()`/`fail()` here: the workflow owns the stream's lifecycle,
536
- * across however many turns/retries it takes.
537
- */
538
- llm(input) {
539
- return outsideWorkflowCtx(() => this.runLlm(input));
540
- }
541
- async runLlm(input) {
542
- const deps = this.factory.forAgent(input.agentName);
543
- const tools = (0, import_nestjs_agent_core2.withMemoryTool)({
544
- tools: (0, import_nestjs_agent_core2.withSkillTool)({
545
- tools: (0, import_nestjs_agent_core2.withAskTool)({
546
- tools: await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList, {
547
- ...input.threadId !== void 0 ? {
548
- threadId: input.threadId
549
- } : {},
550
- ...input.agentName !== void 0 ? {
551
- agentName: input.agentName
552
- } : {}
553
- }),
554
- ask: deps.ask
555
- }),
556
- enabled: deps.skills !== void 0
557
- }),
558
- enabled: deps.memory?.provider.write !== void 0
559
- });
560
- const buffer = input.bufferOutput === true ? (0, import_nestjs_agent_core2.createFrameBuffer)() : void 0;
561
- let writer;
562
- if (buffer !== void 0) {
563
- writer = buffer.writer;
564
- } else {
565
- const opened = await deps.sink.open(input.sinkRunId);
566
- writer = input.childSink ? childSinkWriter(opened) : opened;
567
- }
568
- const frames = (0, import_nestjs_agent_core2.observeTurnFrames)(writer);
569
- const turn = (0, import_nestjs_agent_core2.withTurnFrames)(await (0, import_nestjs_agent_core2.traceLlmTurn)(input.runId, input.step, () => deps.model.runTurn({
570
- system: input.system,
571
- messages: input.messages,
572
- tools,
573
- sink: frames.writer,
574
- ...input.model !== void 0 ? {
575
- model: input.model
576
- } : {}
577
- })), frames.summary());
578
- const stamped = (0, import_nestjs_agent_core2.stampToolKinds)(turn, deps);
579
- return buffer === void 0 ? stamped : {
580
- ...stamped,
581
- bufferedFrames: buffer.frames()
582
- };
583
- }
584
- /**
585
- * NO DURABLE retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm`
586
- * above). What it does retry, in place, is a CLASSIFIED-TRANSIENT error from the tool's own
587
- * invocation (a DB deadlock, a lock-wait timeout — see `isTransientToolError`): the server rolled
588
- * that work back, so re-invoking it is safe, and doing it here (inside this one step, never a new
589
- * checkpoint) is exactly how the non-dispatched loop path handles it too. The timeout is applied
590
- * HERE, handler-side, via `withToolTimeout` — never as a durable dispatch `timeoutMs`, which
591
- * bounds engine liveness (retryable) rather than the tool's own business outcome — and per
592
- * ATTEMPT, so a retried invocation gets its own fresh timeout window.
593
- */
594
- tool(input) {
595
- return outsideWorkflowCtx(() => this.runTool(input));
596
- }
597
- async runTool(input) {
598
- const deps = this.factory.forAgent(input.ctx.agentName);
599
- if (deps.registry.spec(input.toolName)?.kind === "action" && input.toolType !== "action") {
600
- throw new Error(`tool "${input.toolName}" is an action tool but was dispatched without approval: the dispatching process resolved its kind against a registry that does not have it`);
601
- }
602
- const sinkRunId = input.sinkRunId;
603
- let opened;
604
- const ui = (0, import_nestjs_agent_core2.createUiCollector)(input.toolCallId, sinkRunId === void 0 ? void 0 : async (event) => {
605
- opened ??= Promise.resolve(deps.sink.open(sinkRunId)).then((writer) => input.childSink === true ? childSinkWriter(writer) : writer);
606
- await (await opened).write((0, import_nestjs_agent_core2.encodeStreamEvent)(event));
607
- });
608
- const ctx = {
609
- ...input.ctx,
610
- emitUi: ui.emit
611
- };
612
- const localClassify = deps.toolTransientRetry !== false ? deps.toolTransientRetry?.classify : void 0;
613
- const transientRetry = input.transientRetry === false ? false : {
614
- attempts: input.transientRetry.attempts,
615
- backoffMs: input.transientRetry.backoffMs,
616
- ...localClassify !== void 0 ? {
617
- classify: localClassify
618
- } : {}
619
- };
620
- const output = await (0, import_nestjs_agent_core2.traceToolExecution)(input.ctx.runId, {
621
- toolCallId: input.toolCallId,
622
- toolName: input.toolName,
623
- toolType: input.toolType
624
- }, () => (0, import_nestjs_agent_core2.invokeWithTransientRetry)(() => {
625
- ui.restart();
626
- const invocation = deps.registry.invoke(input.toolName, input.input, ctx, deps.rolesPolicy);
627
- return input.timeoutMs !== void 0 ? (0, import_nestjs_agent_core2.withToolTimeout)(invocation, input.timeoutMs, input.toolName) : invocation;
628
- }, transientRetry, {
629
- onRetry: /* @__PURE__ */ __name((attempt, error) => {
630
- (0, import_nestjs_agent_core2.publishAgentToolRetry)({
631
- toolName: input.toolName,
632
- toolCallId: input.toolCallId,
633
- attempt,
634
- message: error instanceof Error ? error.message : String(error)
635
- });
636
- }, "onRetry")
637
- }));
638
- return input.collectUi === true ? (0, import_nestjs_agent_core2.wrapToolStepOutput)(output, ui.components()) : output;
639
- }
640
- };
641
- _ts_decorate2([
642
- (0, import_nestjs_durable.Step)({
643
- retries: 3
644
- }),
645
- _ts_metadata2("design:type", Function),
646
- _ts_metadata2("design:paramtypes", [
647
- typeof DispatchedLlmInput === "undefined" ? Object : DispatchedLlmInput
648
- ]),
649
- _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
650
- ], AgentRunSteps.prototype, "llm", null);
651
- _ts_decorate2([
652
- (0, import_nestjs_durable.Step)(),
653
- _ts_metadata2("design:type", Function),
654
- _ts_metadata2("design:paramtypes", [
655
- typeof DispatchedToolInput === "undefined" ? Object : DispatchedToolInput
656
- ]),
657
- _ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
658
- ], AgentRunSteps.prototype, "tool", null);
659
- AgentRunSteps = _ts_decorate2([
660
- (0, import_common2.Injectable)(),
661
- _ts_param2(0, (0, import_common2.Inject)(import_nestjs_agent_core2.AGENT_DEPS_FACTORY)),
662
- _ts_metadata2("design:type", Function),
663
- _ts_metadata2("design:paramtypes", [
664
- typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
665
- ])
666
- ], AgentRunSteps);
667
-
668
- // src/durable/agent-run.workflow.ts
669
- function _ts_decorate3(decorators, target, key, desc) {
670
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
671
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
672
- r = Reflect.decorate(decorators, target, key, desc);
673
- } else {
674
- for (var i = decorators.length - 1; i >= 0; i--) {
675
- if (d = decorators[i]) {
676
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
677
- }
678
- }
679
- }
680
- return c > 3 && r && Object.defineProperty(target, key, r), r;
681
- }
682
- __name(_ts_decorate3, "_ts_decorate");
683
- function _ts_metadata3(metadataKey, metadataValue) {
684
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
685
- return Reflect.metadata(metadataKey, metadataValue);
686
- }
687
- }
688
- __name(_ts_metadata3, "_ts_metadata");
689
- function _ts_param3(paramIndex, decorator) {
690
- return function(target, key) {
691
- decorator(target, key, paramIndex);
692
- };
693
- }
694
- __name(_ts_param3, "_ts_param");
695
- var AgentRunWorkflow = class _AgentRunWorkflow {
696
- static {
697
- __name(this, "AgentRunWorkflow");
698
- }
699
- factory;
700
- store;
701
- runs;
702
- queue;
703
- constructor(factory, store, runs, queue) {
704
- this.factory = factory;
705
- this.store = store;
706
- this.runs = runs;
707
- this.queue = queue;
708
- }
709
- /**
710
- * Move the thread past this settling turn — to the next queued message, started here as a
711
- * fire-and-forget `ctx.startChild` under the message's own id, or to a paused/empty queue — and
712
- * answer the `queue` frame to write before the turn's terminal.
713
- *
714
- * Journaled: the decision (which message, claimed and popped) is one `localStep`, so a replay
715
- * reads it back instead of popping a second message, and the start is the runtime's own
716
- * replay-safe spawn. Gated by `ctx.patched`, so a run recorded before the queue existed replays
717
- * against the history it has. A no-op for a sub-agent's run and on a store without a queue.
718
- */
719
- async advanceQueue(ctx, input, outcome, error) {
720
- const queue = this.queue;
721
- if (queue === void 0 || !queue.supported || input.sinkRunId !== void 0 || input.deliverTo !== void 0) {
722
- return void 0;
723
- }
724
- if (!await ctx.patched("agent:chat-queue")) {
725
- return void 0;
726
- }
727
- const plan = await stepOf(ctx)(`queue:${outcome}`, async () => {
728
- try {
729
- const settled = outcome === "completed" && await this.isCancelled(ctx.runId) ? "cancelled" : outcome;
730
- return await queue.plan({
731
- threadId: input.threadId,
732
- runId: ctx.runId,
733
- outcome: settled,
734
- ...error !== void 0 ? {
735
- error
736
- } : {}
737
- });
738
- } catch {
739
- return {};
740
- }
741
- });
742
- const next = plan.next;
743
- if (next === void 0) {
744
- return plan.frame;
745
- }
746
- try {
747
- await ctx.startChild(_AgentRunWorkflow, next.input, next.runId);
748
- return plan.frame;
749
- } catch (failure) {
750
- if ((0, import_nestjs_durable_core2.isWorkflowControlFlowSignal)(failure)) {
751
- throw failure;
752
- }
753
- const reason = failure instanceof Error ? failure.message : String(failure);
754
- return stepOf(ctx)("queue:restore", async () => {
755
- await queue.restore(input.threadId, next, "start_failed", reason);
756
- return queue.pausedFrame(input.threadId);
757
- });
758
- }
759
- }
760
- /**
761
- * Has someone asked this run to stop? Read from the runtime's own run status, which is where
762
- * `DurableAgentRunner.cancel` puts it — `cancelling` while a compensating cancel is in flight,
763
- * `cancelled` once it has settled.
764
- *
765
- * Costs a run read at each of the loop's observation points (two per step). That is a row the
766
- * control plane already has, against a turn that is otherwise making model calls, and it buys the
767
- * property that matters: the answer comes from a place BOTH the canceller and every pod that might
768
- * replay this run can see.
769
- *
770
- * Failing to ask is not a cancel. A tenant with no gateway wired, or an operator briefly
771
- * unreachable, answers "no" and the run carries on — the alternative is failing healthy runs
772
- * because a status read timed out. The loop journals that answer like any other, so two processes
773
- * can never disagree about what was seen here.
774
- */
775
- async isCancelled(runId) {
776
- try {
777
- const status = (await this.runs?.getRunDetail(runId))?.run.status;
778
- return status === "cancelled" || status === "cancelling";
779
- } catch {
780
- return false;
781
- }
782
- }
783
- /**
784
- * Settle the delegation a DETACHED run was started for, when that run ends without an answer.
785
- *
786
- * The loop delivers its own success (`deliver:detached`) but cannot catch its own crash, and the
787
- * runtime settles the run row without knowing anything delegated it. Left alone, the card in the
788
- * calling conversation says "started" for ever — the one state a reader can neither wait on nor
789
- * act on. A no-op for every other run: only a detached one carries a delivery address.
790
- */
791
- async settleDetachedParent(ctx, input, outcome) {
792
- const delivery = input.deliverTo;
793
- if (delivery === void 0) {
794
- return;
795
- }
796
- await stepOf(ctx)("deliver:detached:unsettled", () => (0, import_nestjs_agent_core3.settleUnsettledDelegation)({
797
- store: this.store,
798
- delivery,
799
- agent: input.agentName ?? "default",
800
- runId: ctx.runId,
801
- status: outcome.status,
802
- ...outcome.error !== void 0 ? {
803
- error: outcome.error
804
- } : {}
805
- }));
806
- }
807
- async run(ctx, input) {
808
- const day = input.day ?? utcDay();
809
- const deps = this.factory.forAgent(input.agentName);
810
- const dispatchSteps = await ctx.patched("agent:dispatched-steps");
811
- if (input.sinkRunId !== void 0 || input.deliverTo !== void 0) {
812
- await stepOf(ctx)("activate", () => this.store.setActiveStream(input.threadId, ctx.runId));
384
+ async run(ctx, input) {
385
+ const day = input.day ?? utcDay();
386
+ const deps = this.factory.forAgent(input.agentName);
387
+ const dispatchSteps = await ctx.patched("agent:dispatched-steps");
388
+ if (input.sinkRunId !== void 0 || input.deliverTo !== void 0) {
389
+ await stepOf(ctx)("activate", () => this.store.setActiveStream(input.threadId, ctx.runId));
813
390
  }
814
391
  const sinkRunId = input.sinkRunId ?? ctx.runId;
815
392
  const chainBelow = [
@@ -834,7 +411,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
834
411
  end: /* @__PURE__ */ __name(async () => {
835
412
  const frame = await this.advanceQueue(ctx, input, "completed");
836
413
  if (frame !== void 0) {
837
- await writer.write((0, import_nestjs_agent_core3.encodeStreamEvent)(frame));
414
+ await writer.write((0, import_nestjs_agent_core2.encodeStreamEvent)(frame));
838
415
  }
839
416
  await writer.end();
840
417
  }, "end")
@@ -866,7 +443,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
866
443
  // await, so launching a batch in one tick — what `settleAll` does — fixes the block of
867
444
  // positions in call order however the tools then settle. `ctx.patched` keeps a run that
868
445
  // recorded the one-call-at-a-time shape replaying against that shape.
869
- parallel: import_nestjs_agent_core3.settleAll,
446
+ parallel: import_nestjs_agent_core2.settleAll,
870
447
  cancelled: /* @__PURE__ */ __name(() => this.isCancelled(ctx.runId), "cancelled"),
871
448
  patched: /* @__PURE__ */ __name((id) => ctx.patched(id), "patched"),
872
449
  // Dispatched-step suspends must escape the loop's tool catch — control flow, not a tool
@@ -960,167 +537,457 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
960
537
  } : {}
961
538
  };
962
539
  try {
963
- const result = await (0, import_nestjs_agent_core3.runAgentLoop)({
540
+ const result = await (0, import_nestjs_agent_core2.runAgentLoop)({
964
541
  ...deps,
965
542
  day
966
543
  }, input, hooks);
967
- await stepOf(ctx)("deactivate", () => (0, import_nestjs_agent_core3.releaseThreadRun)(this.store, input.threadId, ctx.runId));
544
+ await stepOf(ctx)("deactivate", () => (0, import_nestjs_agent_core2.releaseThreadRun)(this.store, input.threadId, ctx.runId));
968
545
  return result;
969
546
  } catch (error) {
970
547
  if ((0, import_nestjs_durable_core2.isWorkflowControlFlowSignal)(error)) {
971
548
  throw error;
972
549
  }
973
- if (error instanceof import_nestjs_agent_core3.RunCancelledError) {
974
- await stepOf(ctx)("deactivate", () => (0, import_nestjs_agent_core3.releaseThreadRun)(this.store, input.threadId, ctx.runId));
550
+ if (error instanceof import_nestjs_agent_core2.RunCancelledError) {
551
+ await stepOf(ctx)("deactivate", () => (0, import_nestjs_agent_core2.releaseThreadRun)(this.store, input.threadId, ctx.runId));
975
552
  await this.settleDetachedParent(ctx, input, {
976
553
  status: "cancelled"
977
554
  });
978
555
  throw error;
979
556
  }
980
- if ((0, import_nestjs_agent_core3.isReplayIntegrityError)(error)) {
981
- const failure = {
982
- code: "run_failed",
983
- message: error.message
984
- };
985
- (0, import_nestjs_agent_core3.publishAgentRunFailed)({
557
+ if ((0, import_nestjs_agent_core2.isReplayIntegrityError)(error)) {
558
+ const detail = error.message;
559
+ const code2 = (0, import_nestjs_agent_core2.agentFailureCode)(error);
560
+ this.logger.error(`agent run ${ctx.runId} failed (${code2}): ${detail}`);
561
+ (0, import_nestjs_agent_core2.publishAgentRunFailed)({
562
+ runId: ctx.runId,
563
+ code: code2,
564
+ message: detail
565
+ });
566
+ await (0, import_nestjs_agent_core2.settleDeadRun)(this.store, {
986
567
  runId: ctx.runId,
987
- ...failure
568
+ threadId: input.threadId,
569
+ failure: {
570
+ code: code2,
571
+ message: detail
572
+ }
988
573
  });
989
- await (await hooks.openSink()).fail(failure);
574
+ await (await hooks.openSink()).fail((0, import_nestjs_agent_core2.streamFailure)(error));
990
575
  throw error;
991
576
  }
992
577
  const message = error instanceof Error ? error.message : String(error);
993
- const code = (0, import_nestjs_agent_core3.agentFailureCode)(error);
994
- (0, import_nestjs_agent_core3.publishAgentRunFailed)({
578
+ const code = (0, import_nestjs_agent_core2.agentFailureCode)(error);
579
+ this.logger.error(`agent run ${ctx.runId} failed (${code}): ${message}`);
580
+ (0, import_nestjs_agent_core2.publishAgentRunFailed)({
995
581
  runId: ctx.runId,
996
582
  code,
997
583
  message
998
584
  });
999
- await stepOf(ctx)("persist:run:fail", () => this.store.recordRunEnd?.({
1000
- runId: ctx.runId,
1001
- status: "failed",
1002
- errorCode: code,
1003
- errorMessage: message
1004
- }) ?? Promise.resolve());
585
+ await stepOf(ctx)("persist:run:fail", async () => {
586
+ await this.store.recordRunEnd?.({
587
+ runId: ctx.runId,
588
+ status: "failed",
589
+ errorCode: code,
590
+ errorMessage: message
591
+ });
592
+ await Promise.resolve(this.store.failUnsettledToolCalls?.(ctx.runId, import_nestjs_agent_core2.RUN_ENDED_BEFORE_TOOL_CALL)).catch(() => 0);
593
+ });
1005
594
  const queueFrame2 = await this.advanceQueue(ctx, input, "failed", message);
1006
- await stepOf(ctx)("deactivate", () => (0, import_nestjs_agent_core3.releaseThreadRun)(this.store, input.threadId, ctx.runId));
595
+ await stepOf(ctx)("deactivate", () => (0, import_nestjs_agent_core2.releaseThreadRun)(this.store, input.threadId, ctx.runId));
1007
596
  await this.settleDetachedParent(ctx, input, {
1008
597
  status: "failed",
1009
598
  error: message
1010
599
  });
1011
600
  const writer = await hooks.openSink();
1012
601
  if (queueFrame2 !== void 0) {
1013
- await writer.write((0, import_nestjs_agent_core3.encodeStreamEvent)(queueFrame2));
602
+ await writer.write((0, import_nestjs_agent_core2.encodeStreamEvent)(queueFrame2));
603
+ }
604
+ await writer.fail((0, import_nestjs_agent_core2.streamFailure)(error));
605
+ throw error;
606
+ }
607
+ }
608
+ };
609
+ AgentRunWorkflow = _ts_decorate2([
610
+ (0, import_common2.Injectable)(),
611
+ (0, import_nestjs_durable2.Workflow)({
612
+ name: "agent.run",
613
+ version: "1"
614
+ }),
615
+ _ts_param2(0, (0, import_common2.Inject)(import_nestjs_agent_core2.AGENT_DEPS_FACTORY)),
616
+ _ts_param2(1, (0, import_common2.Inject)(import_nestjs_agent_core2.AGENT_STORE)),
617
+ _ts_param2(2, (0, import_common2.Optional)()),
618
+ _ts_param2(2, (0, import_common2.Inject)(import_nestjs_durable2.RUN_GATEWAY)),
619
+ _ts_param2(3, (0, import_common2.Optional)()),
620
+ _ts_param2(3, (0, import_common2.Inject)(AGENT_CHAT_QUEUE)),
621
+ _ts_metadata2("design:type", Function),
622
+ _ts_metadata2("design:paramtypes", [
623
+ typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
624
+ typeof AgentStore === "undefined" ? Object : AgentStore,
625
+ typeof RunGateway === "undefined" ? Object : RunGateway,
626
+ typeof ChatQueueService === "undefined" ? Object : ChatQueueService
627
+ ])
628
+ ], AgentRunWorkflow);
629
+ function isSignalTimeout(error) {
630
+ return error instanceof Error && error.name === "SignalTimeoutError";
631
+ }
632
+ __name(isSignalTimeout, "isSignalTimeout");
633
+
634
+ // src/durable/durable-agent-runner.ts
635
+ var import_node_crypto = require("crypto");
636
+ var import_nestjs_agent_core4 = require("@dudousxd/nestjs-agent-core");
637
+ var import_nestjs_durable3 = require("@dudousxd/nestjs-durable");
638
+ var import_nestjs_durable_core3 = require("@dudousxd/nestjs-durable-core");
639
+ var import_common3 = require("@nestjs/common");
640
+
641
+ // src/in-process-sink.ts
642
+ var import_nestjs_agent_core3 = require("@dudousxd/nestjs-agent-core");
643
+ var InProcessTokenStreamSink = class {
644
+ static {
645
+ __name(this, "InProcessTokenStreamSink");
646
+ }
647
+ runs = /* @__PURE__ */ new Map();
648
+ buffer(runId) {
649
+ let buf = this.runs.get(runId);
650
+ if (buf === void 0) {
651
+ buf = {
652
+ chunks: [],
653
+ ended: false,
654
+ notify: /* @__PURE__ */ new Set()
655
+ };
656
+ this.runs.set(runId, buf);
657
+ }
658
+ return buf;
659
+ }
660
+ wake(buf) {
661
+ for (const resolve of buf.notify) {
662
+ resolve();
663
+ }
664
+ buf.notify.clear();
665
+ }
666
+ open(runId) {
667
+ const buf = this.buffer(runId);
668
+ return {
669
+ write: /* @__PURE__ */ __name((chunk) => {
670
+ buf.chunks.push(chunk);
671
+ this.wake(buf);
672
+ }, "write"),
673
+ end: /* @__PURE__ */ __name(() => {
674
+ buf.ended = true;
675
+ this.wake(buf);
676
+ }, "end"),
677
+ fail: /* @__PURE__ */ __name((error) => {
678
+ buf.failure = error;
679
+ buf.ended = true;
680
+ this.wake(buf);
681
+ }, "fail")
682
+ };
683
+ }
684
+ async *subscribe(runId) {
685
+ const buf = this.buffer(runId);
686
+ let index = 0;
687
+ while (true) {
688
+ while (index < buf.chunks.length) {
689
+ const chunk = buf.chunks[index];
690
+ index += 1;
691
+ if (chunk !== void 0) {
692
+ yield chunk;
693
+ }
694
+ }
695
+ if (buf.ended) {
696
+ if (buf.failure !== void 0) {
697
+ throw new import_nestjs_agent_core3.AgentStreamError(buf.failure);
698
+ }
699
+ return;
700
+ }
701
+ await new Promise((resolve) => buf.notify.add(resolve));
702
+ }
703
+ }
704
+ close(runId) {
705
+ this.runs.delete(runId);
706
+ }
707
+ };
708
+
709
+ // src/durable/durable-agent-runner.ts
710
+ function _ts_decorate3(decorators, target, key, desc) {
711
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
712
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
713
+ r = Reflect.decorate(decorators, target, key, desc);
714
+ } else {
715
+ for (var i = decorators.length - 1; i >= 0; i--) {
716
+ if (d = decorators[i]) {
717
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
718
+ }
719
+ }
720
+ }
721
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
722
+ }
723
+ __name(_ts_decorate3, "_ts_decorate");
724
+ function _ts_metadata3(metadataKey, metadataValue) {
725
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
726
+ return Reflect.metadata(metadataKey, metadataValue);
727
+ }
728
+ }
729
+ __name(_ts_metadata3, "_ts_metadata");
730
+ function _ts_param3(paramIndex, decorator) {
731
+ return function(target, key) {
732
+ decorator(target, key, paramIndex);
733
+ };
734
+ }
735
+ __name(_ts_param3, "_ts_param");
736
+ function threadOfRun(input) {
737
+ if (typeof input !== "object" || input === null || !("threadId" in input)) {
738
+ return void 0;
739
+ }
740
+ return typeof input.threadId === "string" ? input.threadId : void 0;
741
+ }
742
+ __name(threadOfRun, "threadOfRun");
743
+ function isThreadTurn(input) {
744
+ return typeof input === "object" && input !== null && input.sinkRunId === void 0 && input.deliverTo === void 0;
745
+ }
746
+ __name(isThreadTurn, "isThreadTurn");
747
+ var DurableAgentRunner = class _DurableAgentRunner {
748
+ static {
749
+ __name(this, "DurableAgentRunner");
750
+ }
751
+ workflows;
752
+ runs;
753
+ store;
754
+ sink;
755
+ queue;
756
+ logger = new import_common3.Logger(_DurableAgentRunner.name);
757
+ constructor(workflows, runs, store, sink, queue) {
758
+ this.workflows = workflows;
759
+ this.runs = runs;
760
+ this.store = store;
761
+ this.sink = sink;
762
+ this.queue = queue;
763
+ if (this.sink instanceof InProcessTokenStreamSink) {
764
+ this.logger.warn("durable: true with the default InProcessTokenStreamSink, which only buffers tokens in this process. The worker that runs the turn \u2014 and the one that serves its dispatched `llm` step \u2014 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.");
765
+ }
766
+ }
767
+ async start(input, options = {}) {
768
+ const stamped = {
769
+ ...input,
770
+ day: input.day ?? utcDay()
771
+ };
772
+ const runId = options.runId ?? (0, import_node_crypto.randomUUID)();
773
+ try {
774
+ await this.workflows.start(AgentRunWorkflow, stamped, runId);
775
+ } catch (error) {
776
+ if (!(0, import_nestjs_durable_core3.isWorkflowControlFlowSignal)(error)) {
777
+ throw error;
778
+ }
779
+ }
780
+ return {
781
+ runId
782
+ };
783
+ }
784
+ /**
785
+ * From the runtime's own run row. A run it does not know yet counts as running — a queued turn is
786
+ * claimed before its `startChild` lands — and so does one it cannot be asked about: only a run the
787
+ * runtime reports settled (`completed`/`failed`/`cancelled`/`dead`) is stale.
788
+ */
789
+ async isRunActive(runId) {
790
+ try {
791
+ const status = (await this.runs.getRunDetail(runId))?.run.status;
792
+ return !(status === "completed" || status === "failed" || status === "cancelled" || status === "dead");
793
+ } catch {
794
+ return true;
795
+ }
796
+ }
797
+ async signal(runId, toolCallId2, reply) {
798
+ await this.workflows.signal(`tool:${runId}:${toolCallId2}`, reply);
799
+ }
800
+ /**
801
+ * Stop a run, and settle what the durable runtime knows nothing about.
802
+ *
803
+ * `compensate: true` is the form that gives the BODY a chance: it moves the run to `cancelling`
804
+ * (which is what the workflow's own cancel observation reads) and then re-drives it, so a turn
805
+ * running in-process unwinds at its next safe point instead of finishing. It also guarantees the
806
+ * outcome for the turn that CANNOT observe anything — one parked on `waitForSignal`, suspended
807
+ * inside a position its journal already holds — because that re-drive re-suspends and the runtime
808
+ * settles the run `cancelled` regardless. The cascade to child runs comes with it.
809
+ *
810
+ * Neither of those settles the agent's own state, so this does: the run row gets its own terminal,
811
+ * the thread stops reporting a live stream, and the subscriber gets a `cancelled` frame followed
812
+ * by a normal end.
813
+ *
814
+ * The thread is released HERE rather than left to the body, because a cancelled turn is usually
815
+ * suspended — parked on a human, or on one of the dispatched steps a turn spends most of its life
816
+ * in — and a suspended body never reaches its own catch: the runtime settles the run from outside
817
+ * it. The body still releases the thread on the paths where it does unwind (see
818
+ * `AgentRunWorkflow`); both write the same `null`, and whichever gets there first is right. The
819
+ * thread id comes off the run's own recorded input, so this holds for a sub-agent's subthread too
820
+ * — read best-effort, because a gateway that cannot name the thread must not stop the cancel.
821
+ *
822
+ * A tool already executing is not interrupted, here or anywhere: see `haltIfCancelled` in core.
823
+ */
824
+ async cancel(runId) {
825
+ this.logger.log(`cancelling agent run ${runId}`);
826
+ const input = await this.inputOf(runId);
827
+ const threadId = threadOfRun(input);
828
+ await this.runs.cancel(runId, {
829
+ compensate: true
830
+ });
831
+ const writer = await this.sink.open(runId);
832
+ if (threadId !== void 0) {
833
+ if (this.queue?.supported === true && isThreadTurn(input)) {
834
+ try {
835
+ const frame = await this.queue.handoff({
836
+ threadId,
837
+ runId,
838
+ outcome: "cancelled"
839
+ }, (next, nextRunId) => this.start(next, {
840
+ runId: nextRunId
841
+ }));
842
+ if (frame !== void 0) {
843
+ await writer.write((0, import_nestjs_agent_core4.encodeStreamEvent)(frame));
844
+ }
845
+ } catch (error) {
846
+ this.logger.error(`could not advance the queue of thread ${threadId} after cancelling ${runId}: ${error instanceof Error ? error.message : String(error)}`);
847
+ }
1014
848
  }
1015
- await writer.fail({
1016
- code,
1017
- message
1018
- });
1019
- throw error;
849
+ await (0, import_nestjs_agent_core4.releaseThreadRun)(this.store, threadId, runId);
850
+ }
851
+ await writer.write((0, import_nestjs_agent_core4.encodeStreamEvent)({
852
+ kind: "cancelled"
853
+ }));
854
+ await writer.end();
855
+ await this.store.recordRunEnd?.({
856
+ runId,
857
+ status: "cancelled"
858
+ });
859
+ }
860
+ /**
861
+ * The input a run was started with (which thread it was streaming), or `undefined` where the gateway cannot say.
862
+ *
863
+ * A read failure answers `undefined` instead of propagating, the same posture `AgentRunWorkflow`
864
+ * takes for its own cancel observation: failing to ask is not an answer worth failing a cancel
865
+ * over. This id is only needed to clear the thread's active stream, and a stream still marked live
866
+ * is a far smaller fault than the one a throw here would cause — a run nobody ever told to stop,
867
+ * with a subscriber holding a stream that never settles, from the one call whose entire job is to
868
+ * make a run stop.
869
+ */
870
+ async inputOf(runId) {
871
+ try {
872
+ return (await this.runs.getRunDetail(runId))?.run.input;
873
+ } catch {
874
+ return void 0;
1020
875
  }
1021
876
  }
1022
877
  };
1023
- AgentRunWorkflow = _ts_decorate3([
878
+ DurableAgentRunner = _ts_decorate3([
1024
879
  (0, import_common3.Injectable)(),
1025
- (0, import_nestjs_durable2.Workflow)({
1026
- name: "agent.run",
1027
- version: "1"
1028
- }),
1029
- _ts_param3(0, (0, import_common3.Inject)(import_nestjs_agent_core3.AGENT_DEPS_FACTORY)),
1030
- _ts_param3(1, (0, import_common3.Inject)(import_nestjs_agent_core3.AGENT_STORE)),
1031
- _ts_param3(2, (0, import_common3.Optional)()),
1032
- _ts_param3(2, (0, import_common3.Inject)(import_nestjs_durable2.RUN_GATEWAY)),
1033
- _ts_param3(3, (0, import_common3.Optional)()),
880
+ _ts_param3(1, (0, import_common3.Inject)(import_nestjs_durable3.RUN_GATEWAY)),
881
+ _ts_param3(2, (0, import_common3.Inject)(import_nestjs_agent_core4.AGENT_STORE)),
882
+ _ts_param3(3, (0, import_common3.Inject)(import_nestjs_agent_core4.AGENT_SINK)),
883
+ _ts_param3(4, (0, import_common3.Optional)()),
884
+ _ts_param3(4, (0, import_common3.Inject)(AGENT_CHAT_QUEUE)),
1034
885
  _ts_metadata3("design:type", Function),
1035
886
  _ts_metadata3("design:paramtypes", [
1036
- typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
1037
- typeof AgentStore === "undefined" ? Object : AgentStore,
887
+ typeof import_nestjs_durable3.WorkflowService === "undefined" ? Object : import_nestjs_durable3.WorkflowService,
1038
888
  typeof RunGateway === "undefined" ? Object : RunGateway,
889
+ typeof AgentStore === "undefined" ? Object : AgentStore,
890
+ typeof TokenStreamSink === "undefined" ? Object : TokenStreamSink,
1039
891
  typeof ChatQueueService === "undefined" ? Object : ChatQueueService
1040
892
  ])
1041
- ], AgentRunWorkflow);
1042
- function isSignalTimeout(error) {
1043
- return error instanceof Error && error.name === "SignalTimeoutError";
1044
- }
1045
- __name(isSignalTimeout, "isSignalTimeout");
893
+ ], DurableAgentRunner);
1046
894
 
1047
- // src/durable/durable-agent-runner.ts
1048
- var import_node_crypto = require("crypto");
895
+ // src/durable/agent-durable.module.ts
1049
896
  var import_nestjs_agent_core5 = require("@dudousxd/nestjs-agent-core");
1050
- var import_nestjs_durable3 = require("@dudousxd/nestjs-durable");
1051
- var import_nestjs_durable_core3 = require("@dudousxd/nestjs-durable-core");
1052
897
  var import_common4 = require("@nestjs/common");
1053
-
1054
- // src/in-process-sink.ts
1055
- var import_nestjs_agent_core4 = require("@dudousxd/nestjs-agent-core");
1056
- var InProcessTokenStreamSink = class {
1057
- static {
1058
- __name(this, "InProcessTokenStreamSink");
1059
- }
1060
- runs = /* @__PURE__ */ new Map();
1061
- buffer(runId) {
1062
- let buf = this.runs.get(runId);
1063
- if (buf === void 0) {
1064
- buf = {
1065
- chunks: [],
1066
- ended: false,
1067
- notify: /* @__PURE__ */ new Set()
1068
- };
1069
- this.runs.set(runId, buf);
898
+ function _ts_decorate4(decorators, target, key, desc) {
899
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
900
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
901
+ r = Reflect.decorate(decorators, target, key, desc);
902
+ } else {
903
+ for (var i = decorators.length - 1; i >= 0; i--) {
904
+ if (d = decorators[i]) {
905
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
906
+ }
1070
907
  }
1071
- return buf;
1072
908
  }
1073
- wake(buf) {
1074
- for (const resolve of buf.notify) {
1075
- resolve();
909
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
910
+ }
911
+ __name(_ts_decorate4, "_ts_decorate");
912
+ function runnerProviders() {
913
+ return [
914
+ DurableAgentRunner,
915
+ {
916
+ provide: import_nestjs_agent_core5.AGENT_DURABLE_RUNNER,
917
+ useExisting: DurableAgentRunner
1076
918
  }
1077
- buf.notify.clear();
919
+ ];
920
+ }
921
+ __name(runnerProviders, "runnerProviders");
922
+ var AgentDurableHttpModule = class AgentDurableHttpModule2 {
923
+ static {
924
+ __name(this, "AgentDurableHttpModule");
1078
925
  }
1079
- open(runId) {
1080
- const buf = this.buffer(runId);
1081
- return {
1082
- write: /* @__PURE__ */ __name((chunk) => {
1083
- buf.chunks.push(chunk);
1084
- this.wake(buf);
1085
- }, "write"),
1086
- end: /* @__PURE__ */ __name(() => {
1087
- buf.ended = true;
1088
- this.wake(buf);
1089
- }, "end"),
1090
- fail: /* @__PURE__ */ __name((error) => {
1091
- buf.failure = error;
1092
- buf.ended = true;
1093
- this.wake(buf);
1094
- }, "fail")
1095
- };
926
+ };
927
+ AgentDurableHttpModule = _ts_decorate4([
928
+ (0, import_common4.Global)(),
929
+ (0, import_common4.Module)({
930
+ providers: [
931
+ AgentRunWorkflow,
932
+ ...runnerProviders()
933
+ ],
934
+ exports: [
935
+ import_nestjs_agent_core5.AGENT_DURABLE_RUNNER,
936
+ AgentRunWorkflow
937
+ ]
938
+ })
939
+ ], AgentDurableHttpModule);
940
+ var AgentDurableModule = class _AgentDurableModule {
941
+ static {
942
+ __name(this, "AgentDurableModule");
1096
943
  }
1097
- async *subscribe(runId) {
1098
- const buf = this.buffer(runId);
1099
- let index = 0;
1100
- while (true) {
1101
- while (index < buf.chunks.length) {
1102
- const chunk = buf.chunks[index];
1103
- index += 1;
1104
- if (chunk !== void 0) {
1105
- yield chunk;
1106
- }
1107
- }
1108
- if (buf.ended) {
1109
- if (buf.failure !== void 0) {
1110
- throw new import_nestjs_agent_core4.AgentStreamError(buf.failure);
1111
- }
1112
- return;
1113
- }
1114
- await new Promise((resolve) => buf.notify.add(resolve));
944
+ /**
945
+ * `surface: 'http'` returns the reduced `AgentDurableHttpModule` wiring (no `AgentRunSteps`);
946
+ * everything else (omitted, `'engine'`, `'both'`) returns this module's own full wiring — the
947
+ * class's `@Module` providers above merge in regardless of which DynamicModule shape a caller
948
+ * imports (Nest merges a class's static provider list with whatever a self-referencing
949
+ * `DynamicModule` adds), which is exactly why the reduced case has to be a DIFFERENT module class
950
+ * rather than a conditional subset of this one's own decorator.
951
+ */
952
+ static forRoot(options) {
953
+ if (options?.surface === "http") {
954
+ return {
955
+ module: AgentDurableHttpModule,
956
+ global: true
957
+ };
1115
958
  }
1116
- }
1117
- close(runId) {
1118
- this.runs.delete(runId);
959
+ return {
960
+ module: _AgentDurableModule,
961
+ global: true
962
+ };
1119
963
  }
1120
964
  };
965
+ AgentDurableModule = _ts_decorate4([
966
+ (0, import_common4.Global)(),
967
+ (0, import_common4.Module)({
968
+ providers: [
969
+ AgentRunWorkflow,
970
+ AgentRunSteps,
971
+ ...runnerProviders()
972
+ ],
973
+ exports: [
974
+ import_nestjs_agent_core5.AGENT_DURABLE_RUNNER,
975
+ AgentRunWorkflow,
976
+ AgentRunSteps
977
+ ]
978
+ })
979
+ ], AgentDurableModule);
1121
980
 
1122
- // src/durable/durable-agent-runner.ts
1123
- function _ts_decorate4(decorators, target, key, desc) {
981
+ // src/agent.module.ts
982
+ var import_nestjs_agent_core31 = require("@dudousxd/nestjs-agent-core");
983
+ var import_common27 = require("@nestjs/common");
984
+ var import_core4 = require("@nestjs/core");
985
+
986
+ // src/agent-deps.factory.ts
987
+ var import_nestjs_agent_core6 = require("@dudousxd/nestjs-agent-core");
988
+ var import_nestjs_agent_core7 = require("@dudousxd/nestjs-agent-core");
989
+ var import_common5 = require("@nestjs/common");
990
+ function _ts_decorate5(decorators, target, key, desc) {
1124
991
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1125
992
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
1126
993
  r = Reflect.decorate(decorators, target, key, desc);
@@ -1133,7 +1000,7 @@ function _ts_decorate4(decorators, target, key, desc) {
1133
1000
  }
1134
1001
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1135
1002
  }
1136
- __name(_ts_decorate4, "_ts_decorate");
1003
+ __name(_ts_decorate5, "_ts_decorate");
1137
1004
  function _ts_metadata4(metadataKey, metadataValue) {
1138
1005
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
1139
1006
  return Reflect.metadata(metadataKey, metadataValue);
@@ -1146,168 +1013,242 @@ function _ts_param4(paramIndex, decorator) {
1146
1013
  };
1147
1014
  }
1148
1015
  __name(_ts_param4, "_ts_param");
1149
- function threadOfRun(input) {
1150
- if (typeof input !== "object" || input === null || !("threadId" in input)) {
1151
- return void 0;
1152
- }
1153
- return typeof input.threadId === "string" ? input.threadId : void 0;
1154
- }
1155
- __name(threadOfRun, "threadOfRun");
1156
- function isThreadTurn(input) {
1157
- return typeof input === "object" && input !== null && input.sinkRunId === void 0 && input.deliverTo === void 0;
1016
+ function delegateToolName(args) {
1017
+ const slug = args.target.replace(/[^a-zA-Z0-9]+/g, "_");
1018
+ return args.detached === true ? `start_${slug}` : `ask_${slug}`;
1158
1019
  }
1159
- __name(isThreadTurn, "isThreadTurn");
1160
- var DurableAgentRunner = class _DurableAgentRunner {
1020
+ __name(delegateToolName, "delegateToolName");
1021
+ var AgentDepsFactory2 = class {
1161
1022
  static {
1162
- __name(this, "DurableAgentRunner");
1023
+ __name(this, "AgentDepsFactory");
1163
1024
  }
1164
- workflows;
1165
- runs;
1025
+ options;
1026
+ model;
1166
1027
  store;
1167
1028
  sink;
1168
- queue;
1169
- logger = new import_common4.Logger(_DurableAgentRunner.name);
1170
- constructor(workflows, runs, store, sink, queue) {
1171
- this.workflows = workflows;
1172
- this.runs = runs;
1029
+ rolesPolicy;
1030
+ registry;
1031
+ agents;
1032
+ promptContributors;
1033
+ pricingStore;
1034
+ skills;
1035
+ memory;
1036
+ constructor(options, model, store, sink, rolesPolicy, registry, agents, promptContributors, pricingStore, skills, memory) {
1037
+ this.options = options;
1038
+ this.model = model;
1173
1039
  this.store = store;
1174
1040
  this.sink = sink;
1175
- this.queue = queue;
1176
- if (this.sink instanceof InProcessTokenStreamSink) {
1177
- this.logger.warn("durable: true with the default InProcessTokenStreamSink, which only buffers tokens in this process. The worker that runs the turn \u2014 and the one that serves its dispatched `llm` step \u2014 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.");
1178
- }
1041
+ this.rolesPolicy = rolesPolicy;
1042
+ this.registry = registry;
1043
+ this.agents = agents;
1044
+ this.promptContributors = promptContributors;
1045
+ this.pricingStore = pricingStore;
1046
+ this.skills = skills;
1047
+ this.memory = memory;
1179
1048
  }
1180
- async start(input, options = {}) {
1181
- const stamped = {
1182
- ...input,
1183
- day: input.day ?? utcDay()
1184
- };
1185
- const runId = options.runId ?? (0, import_node_crypto.randomUUID)();
1186
- try {
1187
- await this.workflows.start(AgentRunWorkflow, stamped, runId);
1188
- } catch (error) {
1189
- if (!(0, import_nestjs_durable_core3.isWorkflowControlFlowSignal)(error)) {
1190
- throw error;
1191
- }
1192
- }
1193
- return {
1194
- runId
1195
- };
1049
+ /** The turn's memory seam, shared with the read-back endpoint. Undefined → memory is not configured. */
1050
+ memoryConfig() {
1051
+ return this.memory;
1052
+ }
1053
+ /** The turn's skills seam, shared with the listing endpoint. Undefined → skills are not configured. */
1054
+ skillsConfig() {
1055
+ return this.skills;
1196
1056
  }
1197
1057
  /**
1198
- * From the runtime's own run row. A run it does not know yet counts as running — a queued turn is
1199
- * claimed before its `startChild` lands — and so does one it cannot be asked about: only a run the
1200
- * runtime reports settled (`completed`/`failed`/`cancelled`/`dead`) is stale.
1058
+ * The agent a turn uses when the caller names none: the explicit `defaultAgent` option, else the
1059
+ * sole registered `@Agent` when there is exactly one, else `'default'` (a bare assistant).
1201
1060
  */
1202
- async isRunActive(runId) {
1203
- try {
1204
- const status = (await this.runs.getRunDetail(runId))?.run.status;
1205
- return !(status === "completed" || status === "failed" || status === "cancelled" || status === "dead");
1206
- } catch {
1207
- return true;
1061
+ defaultAgentName() {
1062
+ if (this.options.defaultAgent !== void 0) {
1063
+ return this.options.defaultAgent;
1208
1064
  }
1065
+ const registered = this.agents.list();
1066
+ return registered.length === 1 ? registered[0]?.name ?? "default" : "default";
1209
1067
  }
1210
- async signal(runId, toolCallId2, reply) {
1211
- await this.workflows.signal(`tool:${runId}:${toolCallId2}`, reply);
1212
- }
1213
- /**
1214
- * Stop a run, and settle what the durable runtime knows nothing about.
1215
- *
1216
- * `compensate: true` is the form that gives the BODY a chance: it moves the run to `cancelling`
1217
- * (which is what the workflow's own cancel observation reads) and then re-drives it, so a turn
1218
- * running in-process unwinds at its next safe point instead of finishing. It also guarantees the
1219
- * outcome for the turn that CANNOT observe anything — one parked on `waitForSignal`, suspended
1220
- * inside a position its journal already holds — because that re-drive re-suspends and the runtime
1221
- * settles the run `cancelled` regardless. The cascade to child runs comes with it.
1222
- *
1223
- * Neither of those settles the agent's own state, so this does: the run row gets its own terminal,
1224
- * the thread stops reporting a live stream, and the subscriber gets a `cancelled` frame followed
1225
- * by a normal end.
1226
- *
1227
- * The thread is released HERE rather than left to the body, because a cancelled turn is usually
1228
- * suspended — parked on a human, or on one of the dispatched steps a turn spends most of its life
1229
- * in — and a suspended body never reaches its own catch: the runtime settles the run from outside
1230
- * it. The body still releases the thread on the paths where it does unwind (see
1231
- * `AgentRunWorkflow`); both write the same `null`, and whichever gets there first is right. The
1232
- * thread id comes off the run's own recorded input, so this holds for a sub-agent's subthread too
1233
- * — read best-effort, because a gateway that cannot name the thread must not stop the cancel.
1234
- *
1235
- * A tool already executing is not interrupted, here or anywhere: see `haltIfCancelled` in core.
1236
- */
1237
- async cancel(runId) {
1238
- this.logger.log(`cancelling agent run ${runId}`);
1239
- const input = await this.inputOf(runId);
1240
- const threadId = threadOfRun(input);
1241
- await this.runs.cancel(runId, {
1242
- compensate: true
1243
- });
1244
- const writer = await this.sink.open(runId);
1245
- if (threadId !== void 0) {
1246
- if (this.queue?.supported === true && isThreadTurn(input)) {
1247
- try {
1248
- const frame = await this.queue.handoff({
1249
- threadId,
1250
- runId,
1251
- outcome: "cancelled"
1252
- }, (next, nextRunId) => this.start(next, {
1253
- runId: nextRunId
1254
- }));
1255
- if (frame !== void 0) {
1256
- await writer.write((0, import_nestjs_agent_core5.encodeStreamEvent)(frame));
1257
- }
1258
- } catch (error) {
1259
- this.logger.error(`could not advance the queue of thread ${threadId} after cancelling ${runId}: ${error instanceof Error ? error.message : String(error)}`);
1260
- }
1261
- }
1262
- await (0, import_nestjs_agent_core5.releaseThreadRun)(this.store, threadId, runId);
1068
+ effectiveTools(definition) {
1069
+ if (definition === void 0) {
1070
+ return void 0;
1263
1071
  }
1264
- await writer.write((0, import_nestjs_agent_core5.encodeStreamEvent)({
1265
- kind: "cancelled"
1266
- }));
1267
- await writer.end();
1268
- await this.store.recordRunEnd?.({
1269
- runId,
1270
- status: "cancelled"
1072
+ const delegated = (definition.delegatesTo ?? []).map((edge) => {
1073
+ const { agent, detached } = (0, import_nestjs_agent_core6.normalizeDelegation)(edge);
1074
+ return delegateToolName({
1075
+ target: agent,
1076
+ detached
1077
+ });
1271
1078
  });
1079
+ if (definition.tools === void 0 && delegated.length === 0) {
1080
+ return void 0;
1081
+ }
1082
+ return [
1083
+ ...definition.tools ?? [],
1084
+ ...delegated
1085
+ ];
1086
+ }
1087
+ forAgent(agentName) {
1088
+ const name = agentName ?? this.defaultAgentName();
1089
+ const definition = this.agents.get(name);
1090
+ const toolAllowList = this.effectiveTools(definition);
1091
+ const followUpsCount = this.followUpsCount();
1092
+ const retrieval = this.options.retrieval;
1093
+ const historyPolicy = this.historyPolicy(definition);
1094
+ const ask = definition?.ask ?? this.options.ask;
1095
+ return {
1096
+ model: this.model,
1097
+ store: this.store,
1098
+ sink: this.sink,
1099
+ rolesPolicy: this.rolesPolicy,
1100
+ ...this.options.approvalPolicy !== void 0 ? {
1101
+ approvalPolicy: this.options.approvalPolicy
1102
+ } : {},
1103
+ registry: this.registry,
1104
+ promptContributors: this.promptContributors,
1105
+ systemPrompt: definition?.systemPrompt ?? this.options.systemPrompt ?? "You are a helpful assistant.",
1106
+ maxSteps: definition?.maxSteps ?? 8,
1107
+ ...definition?.maxDelegationDepth !== void 0 ? {
1108
+ maxDelegationDepth: definition.maxDelegationDepth
1109
+ } : {},
1110
+ ...definition?.maxAgentAppearances !== void 0 ? {
1111
+ maxAgentAppearances: definition.maxAgentAppearances
1112
+ } : {},
1113
+ ...definition?.modelId !== void 0 ? {
1114
+ modelId: definition.modelId
1115
+ } : {},
1116
+ ...this.pricingStore !== void 0 ? {
1117
+ pricingStore: this.pricingStore
1118
+ } : {},
1119
+ ...historyPolicy !== void 0 ? {
1120
+ historyPolicy
1121
+ } : {},
1122
+ inputProcessors: this.options.inputProcessors ?? [],
1123
+ outputProcessors: this.options.outputProcessors ?? [],
1124
+ ...definition?.outputSchema !== void 0 ? {
1125
+ outputSchema: definition.outputSchema
1126
+ } : {},
1127
+ ...definition?.outputRepairAttempts !== void 0 ? {
1128
+ outputRepairAttempts: definition.outputRepairAttempts
1129
+ } : {},
1130
+ ...definition?.intake !== void 0 ? {
1131
+ intake: definition.intake
1132
+ } : {},
1133
+ // Most specific wins, exactly as `historyPolicy` resolves: the agent's own `@Agent({ ask })`,
1134
+ // else the module-wide flag. Both are module config, so every process of a deployment agrees.
1135
+ ...ask === true ? {
1136
+ ask: true
1137
+ } : {},
1138
+ // Module-wide, never per-agent: a skill is a procedure, not a persona, and an agent that could
1139
+ // opt out of one would make the catalog depend on which agent a turn happened to select — a
1140
+ // per-turn fact the worker re-deriving the tool list cannot see.
1141
+ ...this.skills !== void 0 ? {
1142
+ skills: this.skills
1143
+ } : {},
1144
+ // Module-wide, never per-agent, for the same reason skills are: which memories a turn carries
1145
+ // cannot depend on which persona answered it, or the worker re-deriving a dispatched turn's
1146
+ // tool list would disagree with the loop about whether `remember` was offered.
1147
+ ...this.memory !== void 0 ? {
1148
+ memory: this.memory
1149
+ } : {},
1150
+ ...toolAllowList !== void 0 ? {
1151
+ toolAllowList
1152
+ } : {},
1153
+ ...this.options.toolTimeoutMs !== void 0 ? {
1154
+ toolTimeoutMs: this.options.toolTimeoutMs
1155
+ } : {},
1156
+ ...this.options.toolTransientRetry !== void 0 ? {
1157
+ toolTransientRetry: this.options.toolTransientRetry
1158
+ } : {},
1159
+ ...followUpsCount !== void 0 ? {
1160
+ followUpsCount
1161
+ } : {},
1162
+ ...retrieval?.mode === "inject" ? {
1163
+ retriever: retrieval.retriever,
1164
+ ...retrieval.topK !== void 0 ? {
1165
+ retrievalTopK: retrieval.topK
1166
+ } : {}
1167
+ } : {}
1168
+ };
1272
1169
  }
1273
1170
  /**
1274
- * The input a run was started with (which thread it was streaming), or `undefined` where the gateway cannot say.
1275
- *
1276
- * A read failure answers `undefined` instead of propagating, the same posture `AgentRunWorkflow`
1277
- * takes for its own cancel observation: failing to ask is not an answer worth failing a cancel
1278
- * over. This id is only needed to clear the thread's active stream, and a stream still marked live
1279
- * is a far smaller fault than the one a throw here would cause — a run nobody ever told to stop,
1280
- * with a subscriber holding a stream that never settles, from the one call whose entire job is to
1281
- * make a run stop.
1171
+ * The ceiling on how much of a thread this agent's turns carry, most specific wins: the agent's
1172
+ * own `@Agent({ history })`, else a module-wide custom `historyPolicy`, else the module-wide
1173
+ * `history` window. Undefined → unbounded, the behaviour of a module that configures none.
1282
1174
  */
1283
- async inputOf(runId) {
1284
- try {
1285
- return (await this.runs.getRunDetail(runId))?.run.input;
1286
- } catch {
1287
- return void 0;
1175
+ historyPolicy(definition) {
1176
+ if (definition?.history !== void 0) {
1177
+ return this.window(definition.history);
1178
+ }
1179
+ if (this.options.historyPolicy !== void 0) {
1180
+ return this.options.historyPolicy;
1181
+ }
1182
+ return this.options.history === void 0 ? void 0 : this.window(this.options.history);
1183
+ }
1184
+ /** Build the built-in window policy from the declarative `{ maxMessages, maxTokens, summarize }`. */
1185
+ window(config) {
1186
+ return (0, import_nestjs_agent_core6.windowHistory)({
1187
+ ...config.maxMessages !== void 0 ? {
1188
+ maxMessages: config.maxMessages
1189
+ } : {},
1190
+ ...config.maxTokens !== void 0 ? {
1191
+ maxTokens: config.maxTokens
1192
+ } : {},
1193
+ // The shared module model, not a per-agent one: an agent's `modelId` is an accounting label,
1194
+ // and only one provider is ever bound.
1195
+ ...config.summarize === true ? {
1196
+ summarize: (0, import_nestjs_agent_core6.summarizeWithModel)(this.model)
1197
+ } : {}
1198
+ });
1199
+ }
1200
+ /** Normalize the `followUps` option (`true` → 3, `{ count }` → count) to a number, or undefined. */
1201
+ followUpsCount() {
1202
+ const followUps = this.options.followUps;
1203
+ if (followUps === true) {
1204
+ return 3;
1205
+ }
1206
+ if (typeof followUps === "object") {
1207
+ return followUps.count;
1288
1208
  }
1209
+ return void 0;
1289
1210
  }
1290
1211
  };
1291
- DurableAgentRunner = _ts_decorate4([
1292
- (0, import_common4.Injectable)(),
1293
- _ts_param4(1, (0, import_common4.Inject)(import_nestjs_durable3.RUN_GATEWAY)),
1294
- _ts_param4(2, (0, import_common4.Inject)(import_nestjs_agent_core5.AGENT_STORE)),
1295
- _ts_param4(3, (0, import_common4.Inject)(import_nestjs_agent_core5.AGENT_SINK)),
1296
- _ts_param4(4, (0, import_common4.Optional)()),
1212
+ AgentDepsFactory2 = _ts_decorate5([
1213
+ (0, import_common5.Injectable)(),
1214
+ _ts_param4(0, (0, import_common5.Inject)(import_nestjs_agent_core7.AGENT_OPTIONS)),
1215
+ _ts_param4(1, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_MODEL)),
1216
+ _ts_param4(2, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_STORE)),
1217
+ _ts_param4(3, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_SINK)),
1218
+ _ts_param4(4, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_ROLES_POLICY)),
1219
+ _ts_param4(5, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_TOOL_REGISTRY)),
1220
+ _ts_param4(6, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_REGISTRY)),
1221
+ _ts_param4(7, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_PROMPT_CONTRIBUTORS)),
1222
+ _ts_param4(8, (0, import_common5.Optional)()),
1223
+ _ts_param4(8, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_PRICING_STORE)),
1224
+ _ts_param4(9, (0, import_common5.Optional)()),
1225
+ _ts_param4(9, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_SKILLS)),
1226
+ _ts_param4(10, (0, import_common5.Optional)()),
1227
+ _ts_param4(10, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_MEMORY)),
1297
1228
  _ts_metadata4("design:type", Function),
1298
1229
  _ts_metadata4("design:paramtypes", [
1299
- typeof import_nestjs_durable3.WorkflowService === "undefined" ? Object : import_nestjs_durable3.WorkflowService,
1300
- typeof RunGateway === "undefined" ? Object : RunGateway,
1230
+ typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
1231
+ typeof ModelProvider === "undefined" ? Object : ModelProvider,
1301
1232
  typeof AgentStore === "undefined" ? Object : AgentStore,
1302
1233
  typeof TokenStreamSink === "undefined" ? Object : TokenStreamSink,
1303
- typeof ChatQueueService === "undefined" ? Object : ChatQueueService
1234
+ typeof RolesPolicy === "undefined" ? Object : RolesPolicy,
1235
+ typeof import_nestjs_agent_core6.ToolRegistry === "undefined" ? Object : import_nestjs_agent_core6.ToolRegistry,
1236
+ typeof import_nestjs_agent_core6.AgentRegistry === "undefined" ? Object : import_nestjs_agent_core6.AgentRegistry,
1237
+ Array,
1238
+ Object,
1239
+ Object,
1240
+ Object
1304
1241
  ])
1305
- ], DurableAgentRunner);
1242
+ ], AgentDepsFactory2);
1306
1243
 
1307
- // src/durable/agent-durable.module.ts
1308
- var import_nestjs_agent_core6 = require("@dudousxd/nestjs-agent-core");
1309
- var import_common5 = require("@nestjs/common");
1310
- function _ts_decorate5(decorators, target, key, desc) {
1244
+ // src/agent.service.ts
1245
+ var import_nestjs_agent_core10 = require("@dudousxd/nestjs-agent-core");
1246
+ var import_common8 = require("@nestjs/common");
1247
+
1248
+ // src/queue/chat-queue.service.ts
1249
+ var import_nestjs_agent_core8 = require("@dudousxd/nestjs-agent-core");
1250
+ var import_common6 = require("@nestjs/common");
1251
+ function _ts_decorate6(decorators, target, key, desc) {
1311
1252
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1312
1253
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
1313
1254
  r = Reflect.decorate(decorators, target, key, desc);
@@ -1320,342 +1261,436 @@ function _ts_decorate5(decorators, target, key, desc) {
1320
1261
  }
1321
1262
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1322
1263
  }
1323
- __name(_ts_decorate5, "_ts_decorate");
1324
- function runnerProviders() {
1325
- return [
1326
- DurableAgentRunner,
1327
- {
1328
- provide: import_nestjs_agent_core6.AGENT_DURABLE_RUNNER,
1329
- useExisting: DurableAgentRunner
1330
- }
1331
- ];
1264
+ __name(_ts_decorate6, "_ts_decorate");
1265
+ function _ts_metadata5(metadataKey, metadataValue) {
1266
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
1267
+ return Reflect.metadata(metadataKey, metadataValue);
1268
+ }
1332
1269
  }
1333
- __name(runnerProviders, "runnerProviders");
1334
- var AgentDurableHttpModule = class AgentDurableHttpModule2 {
1270
+ __name(_ts_metadata5, "_ts_metadata");
1271
+ function _ts_param5(paramIndex, decorator) {
1272
+ return function(target, key) {
1273
+ decorator(target, key, paramIndex);
1274
+ };
1275
+ }
1276
+ __name(_ts_param5, "_ts_param");
1277
+ var MAX_DRAIN_ATTEMPTS = 8;
1278
+ var ChatQueueService2 = class _ChatQueueService {
1335
1279
  static {
1336
- __name(this, "AgentDurableHttpModule");
1280
+ __name(this, "ChatQueueService");
1337
1281
  }
1338
- };
1339
- AgentDurableHttpModule = _ts_decorate5([
1340
- (0, import_common5.Global)(),
1341
- (0, import_common5.Module)({
1342
- providers: [
1343
- AgentRunWorkflow,
1344
- ...runnerProviders()
1345
- ],
1346
- exports: [
1347
- import_nestjs_agent_core6.AGENT_DURABLE_RUNNER,
1348
- AgentRunWorkflow
1349
- ]
1350
- })
1351
- ], AgentDurableHttpModule);
1352
- var AgentDurableModule = class _AgentDurableModule {
1353
- static {
1354
- __name(this, "AgentDurableModule");
1282
+ store;
1283
+ sink;
1284
+ quotaProvider;
1285
+ options;
1286
+ staging;
1287
+ logger = new import_common6.Logger(_ChatQueueService.name);
1288
+ /**
1289
+ * Runs this process claimed a thread for and has not handed to a runner yet. A holder in here is
1290
+ * alive whatever the runner says — it simply has not registered the run yet.
1291
+ */
1292
+ starting = /* @__PURE__ */ new Set();
1293
+ constructor(store, sink, quotaProvider, options, staging) {
1294
+ this.store = store;
1295
+ this.sink = sink;
1296
+ this.quotaProvider = quotaProvider;
1297
+ this.options = options;
1298
+ this.staging = staging;
1299
+ }
1300
+ /** Whether the bound store can hold a queue. Without one, a busy thread is not queued. */
1301
+ get supported() {
1302
+ return (0, import_nestjs_agent_core8.isChatQueueStore)(this.store);
1303
+ }
1304
+ /** The bound store as a queue store, or a 501 naming what is missing. */
1305
+ queueStore() {
1306
+ if (!(0, import_nestjs_agent_core8.isChatQueueStore)(this.store)) {
1307
+ throw new import_common6.NotImplementedException("Queueing messages requires an AgentStore that implements ChatQueueStore (enqueueMessage, listQueue, \u2026, claimActiveStream, releaseActiveStream); the bound store does not.");
1308
+ }
1309
+ return this.store;
1310
+ }
1311
+ async state(threadId) {
1312
+ const store = this.queueStore();
1313
+ const [items, paused] = await Promise.all([
1314
+ store.listQueue(threadId),
1315
+ store.queuePause(threadId)
1316
+ ]);
1317
+ return {
1318
+ items: items.map(import_nestjs_agent_core8.queuedMessageView),
1319
+ paused
1320
+ };
1355
1321
  }
1356
1322
  /**
1357
- * `surface: 'http'` returns the reduced `AgentDurableHttpModule` wiring (no `AgentRunSteps`);
1358
- * everything else (omitted, `'engine'`, `'both'`) returns this module's own full wiring — the
1359
- * class's `@Module` providers above merge in regardless of which DynamicModule shape a caller
1360
- * imports (Nest merges a class's static provider list with whatever a self-referencing
1361
- * `DynamicModule` adds), which is exactly why the reduced case has to be a DIFFERENT module class
1362
- * rather than a conditional subset of this one's own decorator.
1323
+ * Whether `holder` is still running. A run this process is about to start is; otherwise the
1324
+ * runner decides, and a runner that cannot tell says yes.
1363
1325
  */
1364
- static forRoot(options) {
1365
- if (options?.surface === "http") {
1326
+ async isAlive(holder, runner) {
1327
+ if (this.starting.has(holder)) {
1328
+ return true;
1329
+ }
1330
+ if (typeof runner.isRunActive !== "function") {
1331
+ return true;
1332
+ }
1333
+ try {
1334
+ return await runner.isRunActive(holder);
1335
+ } catch {
1336
+ return true;
1337
+ }
1338
+ }
1339
+ /**
1340
+ * The run holding `threadId`, or `null` when it is free — a holder the runner reports dead counts
1341
+ * as free, and is returned as `stale` so the caller can claim over it.
1342
+ */
1343
+ async holder(threadId, runner) {
1344
+ const holder = await this.queueStore().activeRunForThread(threadId);
1345
+ if (holder === null) {
1366
1346
  return {
1367
- module: AgentDurableHttpModule,
1368
- global: true
1347
+ live: null,
1348
+ stale: null
1369
1349
  };
1370
1350
  }
1371
- return {
1372
- module: _AgentDurableModule,
1373
- global: true
1351
+ return await this.isAlive(holder, runner) ? {
1352
+ live: holder,
1353
+ stale: null
1354
+ } : {
1355
+ live: null,
1356
+ stale: holder
1374
1357
  };
1375
1358
  }
1376
- };
1377
- AgentDurableModule = _ts_decorate5([
1378
- (0, import_common5.Global)(),
1379
- (0, import_common5.Module)({
1380
- providers: [
1381
- AgentRunWorkflow,
1382
- AgentRunSteps,
1383
- ...runnerProviders()
1384
- ],
1385
- exports: [
1386
- import_nestjs_agent_core6.AGENT_DURABLE_RUNNER,
1387
- AgentRunWorkflow,
1388
- AgentRunSteps
1389
- ]
1390
- })
1391
- ], AgentDurableModule);
1392
-
1393
- // src/agent.module.ts
1394
- var import_nestjs_agent_core30 = require("@dudousxd/nestjs-agent-core");
1395
- var import_common26 = require("@nestjs/common");
1396
- var import_core4 = require("@nestjs/core");
1397
-
1398
- // src/agent-deps.factory.ts
1399
- var import_nestjs_agent_core7 = require("@dudousxd/nestjs-agent-core");
1400
- var import_nestjs_agent_core8 = require("@dudousxd/nestjs-agent-core");
1401
- var import_common6 = require("@nestjs/common");
1402
- function _ts_decorate6(decorators, target, key, desc) {
1403
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1404
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
1405
- r = Reflect.decorate(decorators, target, key, desc);
1406
- } else {
1407
- for (var i = decorators.length - 1; i >= 0; i--) {
1408
- if (d = decorators[i]) {
1409
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1359
+ /**
1360
+ * Decide what follows a TOP-LEVEL run that is settling on `threadId`, and move the thread there:
1361
+ * hand it to the next queued message (claimed and popped here, started by the caller), or pause
1362
+ * the queue, or release the thread. Call it BEFORE the run's terminal frame, so a client reading
1363
+ * the stream learns what comes next from the `queue` frame, and so the thread is already free
1364
+ * when the client sees the run end.
1365
+ *
1366
+ * A no-op returning `{}` on a store without a queue.
1367
+ */
1368
+ async plan(args) {
1369
+ if (!(0, import_nestjs_agent_core8.isChatQueueStore)(this.store)) {
1370
+ return {};
1371
+ }
1372
+ const store = this.store;
1373
+ const { threadId, outcome } = args;
1374
+ if (await store.activeRunForThread(threadId) !== args.runId) {
1375
+ return {};
1376
+ }
1377
+ let holding = args.runId;
1378
+ for (let attempt = 0; attempt < MAX_DRAIN_ATTEMPTS; attempt += 1) {
1379
+ const items = await store.listQueue(threadId);
1380
+ const head = items[0];
1381
+ if (head === void 0) {
1382
+ if (holding !== null) {
1383
+ await store.releaseActiveStream(threadId, holding);
1384
+ holding = null;
1385
+ continue;
1386
+ }
1387
+ return {};
1388
+ }
1389
+ let pause = await store.queuePause(threadId);
1390
+ if (pause === null) {
1391
+ const reason = pauseReasonFor(outcome, head);
1392
+ if (reason !== null) {
1393
+ pause = {
1394
+ reason,
1395
+ ...outcome === "failed" && args.error !== void 0 ? {
1396
+ message: args.error
1397
+ } : {},
1398
+ at: (/* @__PURE__ */ new Date()).toISOString()
1399
+ };
1400
+ await store.setQueuePause(threadId, pause);
1401
+ }
1402
+ }
1403
+ if (pause === null) {
1404
+ const blocked = await this.quotaBlock(head.actor);
1405
+ if (blocked !== null) {
1406
+ pause = {
1407
+ reason: "quota_exceeded",
1408
+ message: blocked,
1409
+ at: (/* @__PURE__ */ new Date()).toISOString()
1410
+ };
1411
+ await store.setQueuePause(threadId, pause);
1412
+ }
1413
+ }
1414
+ if (pause !== null) {
1415
+ if (holding !== null) {
1416
+ await store.releaseActiveStream(threadId, holding);
1417
+ }
1418
+ return {
1419
+ frame: queueFrame(items, pause)
1420
+ };
1421
+ }
1422
+ const claimed = await store.claimActiveStream(threadId, head.id, holding !== null ? {
1423
+ replacing: holding
1424
+ } : {});
1425
+ if (!claimed) {
1426
+ return {};
1427
+ }
1428
+ holding = head.id;
1429
+ if (!await store.removeQueuedMessage(head.id)) {
1430
+ await store.releaseActiveStream(threadId, head.id);
1431
+ holding = null;
1432
+ continue;
1410
1433
  }
1434
+ const next = {
1435
+ runId: head.id,
1436
+ messageId: head.id,
1437
+ input: await this.inputFor(head)
1438
+ };
1439
+ return {
1440
+ next,
1441
+ frame: queueFrame(items.slice(1), null, {
1442
+ messageId: head.id,
1443
+ runId: head.id
1444
+ })
1445
+ };
1411
1446
  }
1412
- }
1413
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1414
- }
1415
- __name(_ts_decorate6, "_ts_decorate");
1416
- function _ts_metadata5(metadataKey, metadataValue) {
1417
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
1418
- return Reflect.metadata(metadataKey, metadataValue);
1419
- }
1420
- }
1421
- __name(_ts_metadata5, "_ts_metadata");
1422
- function _ts_param5(paramIndex, decorator) {
1423
- return function(target, key) {
1424
- decorator(target, key, paramIndex);
1425
- };
1426
- }
1427
- __name(_ts_param5, "_ts_param");
1428
- function delegateToolName(args) {
1429
- const slug = args.target.replace(/[^a-zA-Z0-9]+/g, "_");
1430
- return args.detached === true ? `start_${slug}` : `ask_${slug}`;
1431
- }
1432
- __name(delegateToolName, "delegateToolName");
1433
- var AgentDepsFactory2 = class {
1434
- static {
1435
- __name(this, "AgentDepsFactory");
1436
- }
1437
- options;
1438
- model;
1439
- store;
1440
- sink;
1441
- rolesPolicy;
1442
- registry;
1443
- agents;
1444
- promptContributors;
1445
- pricingStore;
1446
- skills;
1447
- memory;
1448
- constructor(options, model, store, sink, rolesPolicy, registry, agents, promptContributors, pricingStore, skills, memory) {
1449
- this.options = options;
1450
- this.model = model;
1451
- this.store = store;
1452
- this.sink = sink;
1453
- this.rolesPolicy = rolesPolicy;
1454
- this.registry = registry;
1455
- this.agents = agents;
1456
- this.promptContributors = promptContributors;
1457
- this.pricingStore = pricingStore;
1458
- this.skills = skills;
1459
- this.memory = memory;
1460
- }
1461
- /** The turn's memory seam, shared with the read-back endpoint. Undefined → memory is not configured. */
1462
- memoryConfig() {
1463
- return this.memory;
1464
- }
1465
- /** The turn's skills seam, shared with the listing endpoint. Undefined → skills are not configured. */
1466
- skillsConfig() {
1467
- return this.skills;
1447
+ if (holding !== null) {
1448
+ await store.releaseActiveStream(threadId, holding);
1449
+ }
1450
+ return {};
1468
1451
  }
1469
1452
  /**
1470
- * The agent a turn uses when the caller names none: the explicit `defaultAgent` option, else the
1471
- * sole registered `@Agent` when there is exactly one, else `'default'` (a bare assistant).
1453
+ * {@link plan}, then start what it picked with `start`. What an in-process settle (the inline
1454
+ * runner, a durable cancel issued outside a workflow) calls; answers the frame to write.
1472
1455
  */
1473
- defaultAgentName() {
1474
- if (this.options.defaultAgent !== void 0) {
1475
- return this.options.defaultAgent;
1456
+ async handoff(args, start) {
1457
+ const plan = await this.plan(args);
1458
+ if (plan.next === void 0) {
1459
+ return plan.frame;
1476
1460
  }
1477
- const registered = this.agents.list();
1478
- return registered.length === 1 ? registered[0]?.name ?? "default" : "default";
1461
+ return await this.launch(args.threadId, plan.next, start) ? plan.frame : this.pausedFrame(args.threadId);
1479
1462
  }
1480
- effectiveTools(definition) {
1481
- if (definition === void 0) {
1463
+ /**
1464
+ * Start the head of an IDLE thread's queue — after a send queued behind a run that turned out to
1465
+ * be gone, after a resume, after a stale holder. Does nothing while a live run holds the thread
1466
+ * (its settle drains) or while the queue is paused. Answers the started run's id, if any.
1467
+ */
1468
+ async kick(threadId, runner) {
1469
+ if (!(0, import_nestjs_agent_core8.isChatQueueStore)(this.store)) {
1482
1470
  return void 0;
1483
1471
  }
1484
- const delegated = (definition.delegatesTo ?? []).map((edge) => {
1485
- const { agent, detached } = (0, import_nestjs_agent_core7.normalizeDelegation)(edge);
1486
- return delegateToolName({
1487
- target: agent,
1488
- detached
1489
- });
1472
+ const { live, stale } = await this.holder(threadId, runner);
1473
+ if (live !== null) {
1474
+ return void 0;
1475
+ }
1476
+ if (stale !== null) {
1477
+ this.logger.warn(`thread ${threadId} was held by run ${stale}, which is no longer running`);
1478
+ }
1479
+ const plan = await this.plan({
1480
+ threadId,
1481
+ runId: stale,
1482
+ outcome: "completed"
1490
1483
  });
1491
- if (definition.tools === void 0 && delegated.length === 0) {
1484
+ if (plan.next === void 0) {
1492
1485
  return void 0;
1493
1486
  }
1494
- return [
1495
- ...definition.tools ?? [],
1496
- ...delegated
1497
- ];
1487
+ const started = await this.launch(threadId, plan.next, (input, runId) => runner.start(input, {
1488
+ runId
1489
+ }));
1490
+ if (started && plan.frame !== void 0) {
1491
+ await this.write(plan.next.runId, plan.frame);
1492
+ }
1493
+ return started ? plan.next.runId : void 0;
1498
1494
  }
1499
- forAgent(agentName) {
1500
- const name = agentName ?? this.defaultAgentName();
1501
- const definition = this.agents.get(name);
1502
- const toolAllowList = this.effectiveTools(definition);
1503
- const followUpsCount = this.followUpsCount();
1504
- const retrieval = this.options.retrieval;
1505
- const historyPolicy = this.historyPolicy(definition);
1506
- const ask = definition?.ask ?? this.options.ask;
1507
- return {
1508
- model: this.model,
1509
- store: this.store,
1510
- sink: this.sink,
1511
- rolesPolicy: this.rolesPolicy,
1512
- ...this.options.approvalPolicy !== void 0 ? {
1513
- approvalPolicy: this.options.approvalPolicy
1514
- } : {},
1515
- registry: this.registry,
1516
- promptContributors: this.promptContributors,
1517
- systemPrompt: definition?.systemPrompt ?? this.options.systemPrompt ?? "You are a helpful assistant.",
1518
- maxSteps: definition?.maxSteps ?? 8,
1519
- ...definition?.maxDelegationDepth !== void 0 ? {
1520
- maxDelegationDepth: definition.maxDelegationDepth
1521
- } : {},
1522
- ...definition?.maxAgentAppearances !== void 0 ? {
1523
- maxAgentAppearances: definition.maxAgentAppearances
1524
- } : {},
1525
- ...definition?.modelId !== void 0 ? {
1526
- modelId: definition.modelId
1527
- } : {},
1528
- ...this.pricingStore !== void 0 ? {
1529
- pricingStore: this.pricingStore
1530
- } : {},
1531
- ...historyPolicy !== void 0 ? {
1532
- historyPolicy
1533
- } : {},
1534
- inputProcessors: this.options.inputProcessors ?? [],
1535
- outputProcessors: this.options.outputProcessors ?? [],
1536
- ...definition?.outputSchema !== void 0 ? {
1537
- outputSchema: definition.outputSchema
1538
- } : {},
1539
- ...definition?.outputRepairAttempts !== void 0 ? {
1540
- outputRepairAttempts: definition.outputRepairAttempts
1541
- } : {},
1542
- ...definition?.intake !== void 0 ? {
1543
- intake: definition.intake
1544
- } : {},
1545
- // Most specific wins, exactly as `historyPolicy` resolves: the agent's own `@Agent({ ask })`,
1546
- // else the module-wide flag. Both are module config, so every process of a deployment agrees.
1547
- ...ask === true ? {
1548
- ask: true
1549
- } : {},
1550
- // Module-wide, never per-agent: a skill is a procedure, not a persona, and an agent that could
1551
- // opt out of one would make the catalog depend on which agent a turn happened to select — a
1552
- // per-turn fact the worker re-deriving the tool list cannot see.
1553
- ...this.skills !== void 0 ? {
1554
- skills: this.skills
1555
- } : {},
1556
- // Module-wide, never per-agent, for the same reason skills are: which memories a turn carries
1557
- // cannot depend on which persona answered it, or the worker re-deriving a dispatched turn's
1558
- // tool list would disagree with the loop about whether `remember` was offered.
1559
- ...this.memory !== void 0 ? {
1560
- memory: this.memory
1561
- } : {},
1562
- ...toolAllowList !== void 0 ? {
1563
- toolAllowList
1564
- } : {},
1565
- ...this.options.toolTimeoutMs !== void 0 ? {
1566
- toolTimeoutMs: this.options.toolTimeoutMs
1495
+ /**
1496
+ * Start a turn the thread is already claimed for. On failure the message goes back to the head of
1497
+ * the queue, the queue pauses (`start_failed`), and the claim is released — nothing is lost and
1498
+ * nothing is left holding the thread.
1499
+ */
1500
+ async launch(threadId, next, start) {
1501
+ this.starting.add(next.runId);
1502
+ try {
1503
+ await start(next.input, next.runId);
1504
+ return true;
1505
+ } catch (error) {
1506
+ const message = error instanceof Error ? error.message : String(error);
1507
+ this.logger.error(`queued message ${next.messageId} could not start: ${message}`);
1508
+ await this.restore(threadId, next, "start_failed", message);
1509
+ return false;
1510
+ } finally {
1511
+ this.starting.delete(next.runId);
1512
+ }
1513
+ }
1514
+ /** Put a turn that never started back at the head of its queue, paused, and free the thread. */
1515
+ async restore(threadId, next, reason, message) {
1516
+ const store = this.queueStore();
1517
+ const { input } = next;
1518
+ await store.enqueueMessage({
1519
+ threadId,
1520
+ actor: input.actor,
1521
+ content: input.userText,
1522
+ at: "head",
1523
+ ...input.attachments !== void 0 ? {
1524
+ attachments: input.attachments
1567
1525
  } : {},
1568
- ...this.options.toolTransientRetry !== void 0 ? {
1569
- toolTransientRetry: this.options.toolTransientRetry
1526
+ ...input.agentName !== void 0 ? {
1527
+ agentName: input.agentName
1570
1528
  } : {},
1571
- ...followUpsCount !== void 0 ? {
1572
- followUpsCount
1529
+ ...input.model !== void 0 ? {
1530
+ model: input.model
1573
1531
  } : {},
1574
- ...retrieval?.mode === "inject" ? {
1575
- retriever: retrieval.retriever,
1576
- ...retrieval.topK !== void 0 ? {
1577
- retrievalTopK: retrieval.topK
1578
- } : {}
1532
+ ...input.pageContext !== void 0 ? {
1533
+ pageContext: input.pageContext
1579
1534
  } : {}
1535
+ });
1536
+ await store.setQueuePause(threadId, {
1537
+ reason,
1538
+ message,
1539
+ at: (/* @__PURE__ */ new Date()).toISOString()
1540
+ });
1541
+ await store.releaseActiveStream(threadId, next.runId);
1542
+ }
1543
+ /** A `queue` frame with the thread's current state. */
1544
+ async pausedFrame(threadId) {
1545
+ return {
1546
+ kind: "queue",
1547
+ queue: await this.state(threadId)
1580
1548
  };
1581
1549
  }
1582
1550
  /**
1583
- * The ceiling on how much of a thread this agent's turns carry, most specific wins: the agent's
1584
- * own `@Agent({ history })`, else a module-wide custom `historyPolicy`, else the module-wide
1585
- * `history` window. Undefined → unbounded, the behaviour of a module that configures none.
1551
+ * Tell whoever is watching the thread that its queue changed: a `queue` frame into the stream of
1552
+ * the run holding it. Best-effort — a thread nobody is streaming has no one to tell, and the next
1553
+ * read of the thread carries the queue anyway.
1586
1554
  */
1587
- historyPolicy(definition) {
1588
- if (definition?.history !== void 0) {
1589
- return this.window(definition.history);
1555
+ async publish(threadId) {
1556
+ const state = await this.state(threadId);
1557
+ const holder = await this.queueStore().activeRunForThread(threadId);
1558
+ if (holder !== null) {
1559
+ await this.write(holder, {
1560
+ kind: "queue",
1561
+ queue: state
1562
+ }).catch((error) => {
1563
+ this.logger.warn(`could not publish the queue of thread ${threadId}: ${error instanceof Error ? error.message : String(error)}`);
1564
+ });
1590
1565
  }
1591
- if (this.options.historyPolicy !== void 0) {
1592
- return this.options.historyPolicy;
1566
+ return state;
1567
+ }
1568
+ async write(runId, frame) {
1569
+ const writer = await this.sink.open(runId);
1570
+ await writer.write((0, import_nestjs_agent_core8.encodeStreamEvent)(frame));
1571
+ }
1572
+ /** Why `actor` may not start a turn now (the quota message), or `null`. */
1573
+ async quotaBlock(actor) {
1574
+ if (this.options?.quota === void 0 || this.quotaProvider === void 0) {
1575
+ return null;
1576
+ }
1577
+ try {
1578
+ const { blocked } = await this.quotaProvider.report({
1579
+ actor
1580
+ });
1581
+ if (blocked === void 0) {
1582
+ return null;
1583
+ }
1584
+ return blocked.reason ?? `The ${blocked.period === "day" ? "daily" : "monthly"} quota is used up`;
1585
+ } catch {
1586
+ return null;
1593
1587
  }
1594
- return this.options.history === void 0 ? void 0 : this.window(this.options.history);
1595
1588
  }
1596
- /** Build the built-in window policy from the declarative `{ maxMessages, maxTokens, summarize }`. */
1597
- window(config) {
1598
- return (0, import_nestjs_agent_core7.windowHistory)({
1599
- ...config.maxMessages !== void 0 ? {
1600
- maxMessages: config.maxMessages
1589
+ /**
1590
+ * The turn a queued message starts: everything it was queued with, today's date, and its
1591
+ * attachments' urls minted afresh — the ones stored at enqueue time may have expired while it
1592
+ * waited. An attachment the staging store no longer resolves keeps its stored url.
1593
+ */
1594
+ async inputFor(message) {
1595
+ const attachments = await this.freshAttachments(message.actor, message.attachments ?? []);
1596
+ return {
1597
+ threadId: message.threadId,
1598
+ actor: message.actor,
1599
+ userText: message.content,
1600
+ day: utcDay(),
1601
+ ...message.agentName !== void 0 ? {
1602
+ agentName: message.agentName
1601
1603
  } : {},
1602
- ...config.maxTokens !== void 0 ? {
1603
- maxTokens: config.maxTokens
1604
+ ...attachments.length > 0 ? {
1605
+ attachments
1604
1606
  } : {},
1605
- // The shared module model, not a per-agent one: an agent's `modelId` is an accounting label,
1606
- // and only one provider is ever bound.
1607
- ...config.summarize === true ? {
1608
- summarize: (0, import_nestjs_agent_core7.summarizeWithModel)(this.model)
1607
+ ...message.pageContext !== void 0 ? {
1608
+ pageContext: message.pageContext
1609
+ } : {},
1610
+ ...message.model !== void 0 ? {
1611
+ model: message.model
1609
1612
  } : {}
1610
- });
1613
+ };
1611
1614
  }
1612
- /** Normalize the `followUps` option (`true` → 3, `{ count }` → count) to a number, or undefined. */
1613
- followUpsCount() {
1614
- const followUps = this.options.followUps;
1615
- if (followUps === true) {
1616
- return 3;
1617
- }
1618
- if (typeof followUps === "object") {
1619
- return followUps.count;
1615
+ async freshAttachments(actor, attachments) {
1616
+ const staging = this.staging;
1617
+ if (attachments.length === 0 || staging === void 0 || typeof staging.resolve !== "function") {
1618
+ return attachments;
1620
1619
  }
1621
- return void 0;
1620
+ return Promise.all(attachments.map(async (attachment) => {
1621
+ try {
1622
+ return await staging.resolve({
1623
+ mediaId: attachment.mediaId,
1624
+ actor
1625
+ }) ?? attachment;
1626
+ } catch {
1627
+ return attachment;
1628
+ }
1629
+ }));
1622
1630
  }
1623
1631
  };
1624
- AgentDepsFactory2 = _ts_decorate6([
1632
+ ChatQueueService2 = _ts_decorate6([
1625
1633
  (0, import_common6.Injectable)(),
1626
- _ts_param5(0, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_OPTIONS)),
1627
- _ts_param5(1, (0, import_common6.Inject)(import_nestjs_agent_core7.AGENT_MODEL)),
1628
- _ts_param5(2, (0, import_common6.Inject)(import_nestjs_agent_core7.AGENT_STORE)),
1629
- _ts_param5(3, (0, import_common6.Inject)(import_nestjs_agent_core7.AGENT_SINK)),
1630
- _ts_param5(4, (0, import_common6.Inject)(import_nestjs_agent_core7.AGENT_ROLES_POLICY)),
1631
- _ts_param5(5, (0, import_common6.Inject)(import_nestjs_agent_core7.AGENT_TOOL_REGISTRY)),
1632
- _ts_param5(6, (0, import_common6.Inject)(import_nestjs_agent_core7.AGENT_REGISTRY)),
1633
- _ts_param5(7, (0, import_common6.Inject)(import_nestjs_agent_core7.AGENT_PROMPT_CONTRIBUTORS)),
1634
- _ts_param5(8, (0, import_common6.Optional)()),
1635
- _ts_param5(8, (0, import_common6.Inject)(import_nestjs_agent_core7.AGENT_PRICING_STORE)),
1636
- _ts_param5(9, (0, import_common6.Optional)()),
1637
- _ts_param5(9, (0, import_common6.Inject)(import_nestjs_agent_core7.AGENT_SKILLS)),
1638
- _ts_param5(10, (0, import_common6.Optional)()),
1639
- _ts_param5(10, (0, import_common6.Inject)(import_nestjs_agent_core7.AGENT_MEMORY)),
1634
+ _ts_param5(0, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_STORE)),
1635
+ _ts_param5(1, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_SINK)),
1636
+ _ts_param5(2, (0, import_common6.Optional)()),
1637
+ _ts_param5(2, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_QUOTA_PROVIDER)),
1638
+ _ts_param5(3, (0, import_common6.Optional)()),
1639
+ _ts_param5(3, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_OPTIONS)),
1640
+ _ts_param5(4, (0, import_common6.Optional)()),
1641
+ _ts_param5(4, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_ATTACHMENT_STAGING)),
1640
1642
  _ts_metadata5("design:type", Function),
1641
1643
  _ts_metadata5("design:paramtypes", [
1642
- typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
1643
- typeof ModelProvider === "undefined" ? Object : ModelProvider,
1644
1644
  typeof AgentStore === "undefined" ? Object : AgentStore,
1645
1645
  typeof TokenStreamSink === "undefined" ? Object : TokenStreamSink,
1646
- typeof RolesPolicy === "undefined" ? Object : RolesPolicy,
1647
- typeof import_nestjs_agent_core7.ToolRegistry === "undefined" ? Object : import_nestjs_agent_core7.ToolRegistry,
1648
- typeof import_nestjs_agent_core7.AgentRegistry === "undefined" ? Object : import_nestjs_agent_core7.AgentRegistry,
1649
- Array,
1650
- Object,
1651
- Object,
1652
- Object
1646
+ typeof QuotaProvider === "undefined" ? Object : QuotaProvider,
1647
+ typeof Pick === "undefined" ? Object : Pick,
1648
+ typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore
1653
1649
  ])
1654
- ], AgentDepsFactory2);
1650
+ ], ChatQueueService2);
1651
+ function pauseReasonFor(outcome, head) {
1652
+ if (outcome === "failed") {
1653
+ return "run_failed";
1654
+ }
1655
+ if (outcome === "cancelled" && head.interrupt !== true) {
1656
+ return "cancelled";
1657
+ }
1658
+ return null;
1659
+ }
1660
+ __name(pauseReasonFor, "pauseReasonFor");
1661
+ function queueFrame(items, paused, started) {
1662
+ return {
1663
+ kind: "queue",
1664
+ queue: {
1665
+ items: items.map(import_nestjs_agent_core8.queuedMessageView),
1666
+ paused
1667
+ },
1668
+ ...started !== void 0 ? {
1669
+ started
1670
+ } : {}
1671
+ };
1672
+ }
1673
+ __name(queueFrame, "queueFrame");
1655
1674
 
1656
- // src/agent.service.ts
1675
+ // src/run-not-active.exception.ts
1657
1676
  var import_nestjs_agent_core9 = require("@dudousxd/nestjs-agent-core");
1658
1677
  var import_common7 = require("@nestjs/common");
1678
+ var RunNotActiveException = class extends import_common7.ConflictException {
1679
+ static {
1680
+ __name(this, "RunNotActiveException");
1681
+ }
1682
+ runId;
1683
+ code = import_nestjs_agent_core9.RUN_NOT_ACTIVE_CODE;
1684
+ constructor(runId) {
1685
+ super({
1686
+ statusCode: 409,
1687
+ code: import_nestjs_agent_core9.RUN_NOT_ACTIVE_CODE,
1688
+ message: import_nestjs_agent_core9.RUN_NOT_ACTIVE_MESSAGE
1689
+ }), this.runId = runId;
1690
+ }
1691
+ };
1692
+
1693
+ // src/agent.service.ts
1659
1694
  function _ts_decorate7(decorators, target, key, desc) {
1660
1695
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1661
1696
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -1712,7 +1747,7 @@ var AgentService = class {
1712
1747
  requireQueue() {
1713
1748
  const queue = this.queueing();
1714
1749
  if (queue === void 0) {
1715
- throw new import_common7.NotImplementedException("Queueing messages requires an AgentStore that implements ChatQueueStore; the bound store does not.");
1750
+ throw new import_common8.NotImplementedException("Queueing messages requires an AgentStore that implements ChatQueueStore; the bound store does not.");
1716
1751
  }
1717
1752
  return queue;
1718
1753
  }
@@ -1749,12 +1784,12 @@ var AgentService = class {
1749
1784
  actor
1750
1785
  });
1751
1786
  if (blocked !== void 0) {
1752
- throw new import_common7.HttpException({
1753
- statusCode: import_common7.HttpStatus.TOO_MANY_REQUESTS,
1787
+ throw new import_common8.HttpException({
1788
+ statusCode: import_common8.HttpStatus.TOO_MANY_REQUESTS,
1754
1789
  code: "quota_exceeded",
1755
1790
  period: blocked.period,
1756
1791
  message: blocked.reason ?? `The ${blocked.period === "day" ? "daily" : "monthly"} quota is used up`
1757
- }, import_common7.HttpStatus.TOO_MANY_REQUESTS);
1792
+ }, import_common8.HttpStatus.TOO_MANY_REQUESTS);
1758
1793
  }
1759
1794
  }
1760
1795
  /**
@@ -1782,17 +1817,17 @@ var AgentService = class {
1782
1817
  */
1783
1818
  async assertModelAllowed(actor, agent, model) {
1784
1819
  if (this.models === void 0) {
1785
- throw new import_common7.BadRequestException(`model "${model}" cannot be selected: no ModelCatalog is configured (AgentModule.forRoot({ models }))`);
1820
+ throw new import_common8.BadRequestException(`model "${model}" cannot be selected: no ModelCatalog is configured (AgentModule.forRoot({ models }))`);
1786
1821
  }
1787
- const entry = (0, import_nestjs_agent_core9.findCatalogModel)(await this.models.list({
1822
+ const entry = (0, import_nestjs_agent_core10.findCatalogModel)(await this.models.list({
1788
1823
  actor,
1789
1824
  agent
1790
1825
  }), model);
1791
1826
  if (entry === void 0) {
1792
- throw new import_common7.BadRequestException(`model "${model}" is not offered`);
1827
+ throw new import_common8.BadRequestException(`model "${model}" is not offered`);
1793
1828
  }
1794
1829
  if (!entry.available) {
1795
- throw new import_common7.BadRequestException(`model "${model}" is not available${entry.unavailableReason ? `: ${entry.unavailableReason}` : ""}`);
1830
+ throw new import_common8.BadRequestException(`model "${model}" is not available${entry.unavailableReason ? `: ${entry.unavailableReason}` : ""}`);
1796
1831
  }
1797
1832
  return entry.id;
1798
1833
  }
@@ -1808,7 +1843,7 @@ var AgentService = class {
1808
1843
  })).locked : void 0;
1809
1844
  if (locked !== void 0) {
1810
1845
  if (requested !== void 0 && requested !== locked.model) {
1811
- throw new import_common7.BadRequestException(`model "${requested}" cannot be selected: ${locked.reason ?? `this agent always uses "${locked.model}"`}`);
1846
+ throw new import_common8.BadRequestException(`model "${requested}" cannot be selected: ${locked.reason ?? `this agent always uses "${locked.model}"`}`);
1812
1847
  }
1813
1848
  return locked.model;
1814
1849
  }
@@ -1852,7 +1887,7 @@ var AgentService = class {
1852
1887
  };
1853
1888
  }
1854
1889
  await this.requireQueue().publish(result.threadId);
1855
- throw new import_common7.ConflictException({
1890
+ throw new import_common8.ConflictException({
1856
1891
  statusCode: 409,
1857
1892
  code: "run_active",
1858
1893
  message: `thread ${result.threadId} already has a turn running`
@@ -1870,7 +1905,7 @@ var AgentService = class {
1870
1905
  let threadId = params.threadId;
1871
1906
  if (threadId === void 0) {
1872
1907
  if (params.regenerate === true) {
1873
- throw new import_common7.BadRequestException("regenerate requires an existing threadId");
1908
+ throw new import_common8.BadRequestException("regenerate requires an existing threadId");
1874
1909
  }
1875
1910
  const created = await this.store.createThread({
1876
1911
  actor: params.actor,
@@ -1912,6 +1947,11 @@ var AgentService = class {
1912
1947
  }
1913
1948
  const mode = params.mode ?? "auto";
1914
1949
  const { live, stale } = await queue.holder(threadId, this.runner);
1950
+ if (stale !== null) {
1951
+ await (0, import_nestjs_agent_core10.settleDeadRun)(this.store, {
1952
+ runId: stale
1953
+ });
1954
+ }
1915
1955
  if (live === null && mode !== "queue") {
1916
1956
  const runId = crypto.randomUUID();
1917
1957
  if (await queue.queueStore().claimActiveStream(threadId, runId, stale !== null ? {
@@ -1924,7 +1964,7 @@ var AgentService = class {
1924
1964
  }
1925
1965
  }
1926
1966
  if (params.regenerate === true) {
1927
- throw new import_common7.ConflictException({
1967
+ throw new import_common8.ConflictException({
1928
1968
  statusCode: 409,
1929
1969
  code: "run_active",
1930
1970
  message: "cannot regenerate while a turn is running on this thread"
@@ -2021,7 +2061,7 @@ var AgentService = class {
2021
2061
  const store = queue.queueStore();
2022
2062
  const threadId = await this.assertOwnsQueuedMessage(actor, messageId);
2023
2063
  if (patch.message !== void 0 && patch.message.trim().length === 0) {
2024
- throw new import_common7.BadRequestException("message must not be empty");
2064
+ throw new import_common8.BadRequestException("message must not be empty");
2025
2065
  }
2026
2066
  const attachments = patch.attachments === void 0 || patch.attachments === null ? patch.attachments : await this.resolveAttachments(actor, patch.attachments);
2027
2067
  if (patch.message !== void 0 || attachments !== void 0) {
@@ -2034,15 +2074,15 @@ var AgentService = class {
2034
2074
  } : {}
2035
2075
  });
2036
2076
  if (updated === null) {
2037
- throw new import_common7.GoneException(`queued message ${messageId} already started or was removed`);
2077
+ throw new import_common8.GoneException(`queued message ${messageId} already started or was removed`);
2038
2078
  }
2039
2079
  }
2040
2080
  if (patch.position !== void 0) {
2041
2081
  if (!Number.isInteger(patch.position) || patch.position < 0) {
2042
- throw new import_common7.BadRequestException("position must be a non-negative integer");
2082
+ throw new import_common8.BadRequestException("position must be a non-negative integer");
2043
2083
  }
2044
2084
  if (!await store.moveQueuedMessage(messageId, patch.position)) {
2045
- throw new import_common7.GoneException(`queued message ${messageId} already started or was removed`);
2085
+ throw new import_common8.GoneException(`queued message ${messageId} already started or was removed`);
2046
2086
  }
2047
2087
  }
2048
2088
  return queue.publish(threadId);
@@ -2052,7 +2092,7 @@ var AgentService = class {
2052
2092
  const queue = this.requireQueue();
2053
2093
  const threadId = await this.assertOwnsQueuedMessage(actor, messageId);
2054
2094
  if (!await queue.queueStore().removeQueuedMessage(messageId)) {
2055
- throw new import_common7.GoneException(`queued message ${messageId} already started or was removed`);
2095
+ throw new import_common8.GoneException(`queued message ${messageId} already started or was removed`);
2056
2096
  }
2057
2097
  return queue.publish(threadId);
2058
2098
  }
@@ -2071,7 +2111,7 @@ var AgentService = class {
2071
2111
  const queue = this.requireQueue();
2072
2112
  const store = queue.queueStore();
2073
2113
  const threadId = await this.assertOwnsQueuedMessage(actor, messageId);
2074
- const gone = /* @__PURE__ */ __name(() => new import_common7.GoneException(`queued message ${messageId} already started or was removed`), "gone");
2114
+ const gone = /* @__PURE__ */ __name(() => new import_common8.GoneException(`queued message ${messageId} already started or was removed`), "gone");
2075
2115
  const marked = await store.updateQueuedMessage(messageId, {
2076
2116
  interrupt: true
2077
2117
  });
@@ -2079,7 +2119,7 @@ var AgentService = class {
2079
2119
  throw gone();
2080
2120
  }
2081
2121
  if (marked.interrupt !== true) {
2082
- throw new import_common7.NotImplementedException("Interrupting a queued message requires a ChatQueueStore whose updateQueuedMessage stores `interrupt`; the bound store ignored it.");
2122
+ throw new import_common8.NotImplementedException("Interrupting a queued message requires a ChatQueueStore whose updateQueuedMessage stores `interrupt`; the bound store ignored it.");
2083
2123
  }
2084
2124
  if (!await store.moveQueuedMessage(messageId, 0)) {
2085
2125
  throw gone();
@@ -2138,7 +2178,7 @@ var AgentService = class {
2138
2178
  async assertOwnsQueuedMessage(actor, messageId) {
2139
2179
  const message = await this.requireQueue().queueStore().getQueuedMessage(messageId);
2140
2180
  if (message === null) {
2141
- throw new import_common7.NotFoundException(`queued message ${messageId} not found`);
2181
+ throw new import_common8.NotFoundException(`queued message ${messageId} not found`);
2142
2182
  }
2143
2183
  await this.assertOwnsThread(actor, message.threadId);
2144
2184
  return message.threadId;
@@ -2159,7 +2199,7 @@ var AgentService = class {
2159
2199
  }
2160
2200
  const staging = this.staging;
2161
2201
  if (staging === void 0 || typeof staging.resolve !== "function") {
2162
- throw new import_common7.NotImplementedException("Message attachments require an AGENT_ATTACHMENT_STAGING provider implementing resolve(); attachment urls are never taken from the request.");
2202
+ throw new import_common8.NotImplementedException("Message attachments require an AGENT_ATTACHMENT_STAGING provider implementing resolve(); attachment urls are never taken from the request.");
2163
2203
  }
2164
2204
  const resolved = [];
2165
2205
  for (const ref of refs) {
@@ -2168,7 +2208,7 @@ var AgentService = class {
2168
2208
  actor
2169
2209
  });
2170
2210
  if (attachment === null) {
2171
- throw new import_common7.ForbiddenException(`attachment ${ref.mediaId} is not available to this actor`);
2211
+ throw new import_common8.ForbiddenException(`attachment ${ref.mediaId} is not available to this actor`);
2172
2212
  }
2173
2213
  resolved.push(attachment);
2174
2214
  }
@@ -2272,8 +2312,29 @@ var AgentService = class {
2272
2312
  async signalToolCall(toolCallId2, reply) {
2273
2313
  await this.assertNotExpired(toolCallId2);
2274
2314
  const runId = await this.resolveRunForToolCall(toolCallId2);
2315
+ await this.assertRunWaiting(runId);
2275
2316
  return this.runner.signal(runId, toolCallId2, reply);
2276
2317
  }
2318
+ /**
2319
+ * Refuse a decision addressed at a run that is over (`409 run_not_active`). The runtime would take
2320
+ * the signal and buffer it for a run that never comes back — the person's "yes" is accepted, the
2321
+ * card says so, and nothing runs. Settles the calls the dead run left awaiting a decision on the
2322
+ * way out, so the card stops asking. A runner that cannot say whether a run is alive is taken at
2323
+ * its word that it is, and so is one that fails to answer.
2324
+ */
2325
+ async assertRunWaiting(runId) {
2326
+ if (typeof this.runner.isRunActive !== "function") {
2327
+ return;
2328
+ }
2329
+ const active = await this.runner.isRunActive(runId).catch(() => true);
2330
+ if (active) {
2331
+ return;
2332
+ }
2333
+ await (0, import_nestjs_agent_core10.settleDeadRun)(this.store, {
2334
+ runId
2335
+ });
2336
+ throw new RunNotActiveException(runId);
2337
+ }
2277
2338
  async cancel(actor, runId) {
2278
2339
  await this.assertOwnsActiveStream(actor, runId);
2279
2340
  return this.runner.cancel(runId);
@@ -2317,7 +2378,7 @@ var AgentService = class {
2317
2378
  return;
2318
2379
  }
2319
2380
  if (this.store.updateThread === void 0) {
2320
- throw new import_common7.NotImplementedException("Setting a thread's defaultAgent or model requires an AgentStore that implements updateThread(); the bound store does not support it.");
2381
+ throw new import_common8.NotImplementedException("Setting a thread's defaultAgent or model requires an AgentStore that implements updateThread(); the bound store does not support it.");
2321
2382
  }
2322
2383
  const model = patch.model === void 0 || patch.model === null ? patch.model : await this.assertModelAllowed(actor, patch.defaultAgent ?? await this.resolveAgentName(void 0, threadId), patch.model);
2323
2384
  await this.store.updateThread(threadId, {
@@ -2335,10 +2396,10 @@ var AgentService = class {
2335
2396
  validateTitle(title) {
2336
2397
  const trimmed = title.trim();
2337
2398
  if (trimmed.length === 0) {
2338
- throw new import_common7.BadRequestException("title must not be empty");
2399
+ throw new import_common8.BadRequestException("title must not be empty");
2339
2400
  }
2340
2401
  if (trimmed.length > 200) {
2341
- throw new import_common7.BadRequestException("title must be at most 200 characters");
2402
+ throw new import_common8.BadRequestException("title must be at most 200 characters");
2342
2403
  }
2343
2404
  return trimmed;
2344
2405
  }
@@ -2441,21 +2502,21 @@ var AgentService = class {
2441
2502
  */
2442
2503
  async setMessageFeedback(actor, messageId, input) {
2443
2504
  if (input.value !== null && input.value !== "up" && input.value !== "down") {
2444
- throw new import_common7.BadRequestException("value must be 'up', 'down' or null");
2505
+ throw new import_common8.BadRequestException("value must be 'up', 'down' or null");
2445
2506
  }
2446
2507
  if (input.comment !== void 0 && typeof input.comment !== "string") {
2447
- throw new import_common7.BadRequestException("comment must be a string");
2508
+ throw new import_common8.BadRequestException("comment must be a string");
2448
2509
  }
2449
2510
  const comment = input.comment?.trim();
2450
2511
  if (comment !== void 0 && comment.length > 2e3) {
2451
- throw new import_common7.BadRequestException("comment must be at most 2000 characters");
2512
+ throw new import_common8.BadRequestException("comment must be at most 2000 characters");
2452
2513
  }
2453
2514
  if (this.store.threadOfMessage === void 0 || this.store.setMessageFeedback === void 0) {
2454
- throw new import_common7.NotImplementedException("Message feedback requires an AgentStore that implements threadOfMessage() and setMessageFeedback(); the bound store does not support it.");
2515
+ throw new import_common8.NotImplementedException("Message feedback requires an AgentStore that implements threadOfMessage() and setMessageFeedback(); the bound store does not support it.");
2455
2516
  }
2456
2517
  const threadId = await this.store.threadOfMessage(messageId);
2457
2518
  if (threadId === null) {
2458
- throw new import_common7.NotFoundException(`message ${messageId} not found`);
2519
+ throw new import_common8.NotFoundException(`message ${messageId} not found`);
2459
2520
  }
2460
2521
  await this.assertOwnsThread(actor, threadId);
2461
2522
  const feedback = input.value === null ? null : {
@@ -2503,7 +2564,7 @@ var AgentService = class {
2503
2564
  const list = this.attachmentInventory();
2504
2565
  const referencedMediaIds = this.store.referencedMediaIds?.bind(this.store);
2505
2566
  if (referencedMediaIds === void 0) {
2506
- throw new import_common7.NotImplementedException("Collecting attachments requires an AgentStore that implements referencedMediaIds(); the bound store cannot say which media a message still references, and guessing would delete files that are in use.");
2567
+ throw new import_common8.NotImplementedException("Collecting attachments requires an AgentStore that implements referencedMediaIds(); the bound store cannot say which media a message still references, and guessing would delete files that are in use.");
2507
2568
  }
2508
2569
  const stagedBefore = options.olderThan.toISOString();
2509
2570
  const inventory = await list({
@@ -2525,7 +2586,7 @@ var AgentService = class {
2525
2586
  attachmentInventory() {
2526
2587
  const list = this.staging?.list?.bind(this.staging);
2527
2588
  if (list === void 0) {
2528
- throw new import_common7.NotImplementedException("Listing attachments requires an AGENT_ATTACHMENT_STAGING provider implementing list(); the host owns the staged bytes, so only it can enumerate them.");
2589
+ throw new import_common8.NotImplementedException("Listing attachments requires an AGENT_ATTACHMENT_STAGING provider implementing list(); the host owns the staged bytes, so only it can enumerate them.");
2529
2590
  }
2530
2591
  return list;
2531
2592
  }
@@ -2536,10 +2597,10 @@ var AgentService = class {
2536
2597
  async assertOwnsThread(actor, threadId) {
2537
2598
  const owner = await this.store.ownerOfThread(threadId);
2538
2599
  if (owner === null) {
2539
- throw new import_common7.NotFoundException(`thread ${threadId} not found`);
2600
+ throw new import_common8.NotFoundException(`thread ${threadId} not found`);
2540
2601
  }
2541
2602
  if (owner !== actor.id) {
2542
- throw new import_common7.ForbiddenException("thread belongs to another actor");
2603
+ throw new import_common8.ForbiddenException("thread belongs to another actor");
2543
2604
  }
2544
2605
  }
2545
2606
  /**
@@ -2550,10 +2611,10 @@ var AgentService = class {
2550
2611
  async assertOwnsToolCall(actor, toolCallId2) {
2551
2612
  const owner = await this.store.ownerOfToolCall(toolCallId2);
2552
2613
  if (owner === null) {
2553
- throw new import_common7.NotFoundException(`tool call ${toolCallId2} not found`);
2614
+ throw new import_common8.NotFoundException(`tool call ${toolCallId2} not found`);
2554
2615
  }
2555
2616
  if (owner !== actor.id) {
2556
- throw new import_common7.ForbiddenException("tool call belongs to another actor");
2617
+ throw new import_common8.ForbiddenException("tool call belongs to another actor");
2557
2618
  }
2558
2619
  }
2559
2620
  /**
@@ -2568,12 +2629,12 @@ var AgentService = class {
2568
2629
  if (this.store.toolCallInput === void 0) {
2569
2630
  return;
2570
2631
  }
2571
- const questions = (0, import_nestjs_agent_core9.readElicitationQuestions)(await this.store.toolCallInput(toolCallId2));
2632
+ const questions = (0, import_nestjs_agent_core10.readElicitationQuestions)(await this.store.toolCallInput(toolCallId2));
2572
2633
  for (const question of questions) {
2573
2634
  const submitted = Object.hasOwn(answers2, question.id) ? answers2[question.id] : void 0;
2574
- const problem = (0, import_nestjs_agent_core9.validateElicitationAnswer)(question, submitted ?? question.defaults ?? []);
2635
+ const problem = (0, import_nestjs_agent_core10.validateElicitationAnswer)(question, submitted ?? question.defaults ?? []);
2575
2636
  if (problem !== null) {
2576
- throw new import_common7.BadRequestException(`answers["${question.id}"] ${problem}`);
2637
+ throw new import_common8.BadRequestException(`answers["${question.id}"] ${problem}`);
2577
2638
  }
2578
2639
  }
2579
2640
  }
@@ -2585,21 +2646,21 @@ var AgentService = class {
2585
2646
  */
2586
2647
  async assertMayDecide(actor, toolCallId2) {
2587
2648
  const approval = await this.store.toolCallApproval?.(toolCallId2);
2588
- const approver = approval?.approver ?? import_nestjs_agent_core9.REQUESTER_APPROVER;
2589
- if (approver === import_nestjs_agent_core9.REQUESTER_APPROVER) {
2649
+ const approver = approval?.approver ?? import_nestjs_agent_core10.REQUESTER_APPROVER;
2650
+ if (approver === import_nestjs_agent_core10.REQUESTER_APPROVER) {
2590
2651
  return this.assertOwnsToolCall(actor, toolCallId2);
2591
2652
  }
2592
2653
  const requesterRef = await this.store.ownerOfToolCall(toolCallId2);
2593
2654
  if (requesterRef === null) {
2594
- throw new import_common7.NotFoundException(`tool call ${toolCallId2} not found`);
2655
+ throw new import_common8.NotFoundException(`tool call ${toolCallId2} not found`);
2595
2656
  }
2596
- const allowed = await (0, import_nestjs_agent_core9.mayDecideApproval)(this.deps.forAgent().approvalPolicy, actor, {
2657
+ const allowed = await (0, import_nestjs_agent_core10.mayDecideApproval)(this.deps.forAgent().approvalPolicy, actor, {
2597
2658
  toolCallId: toolCallId2,
2598
2659
  approver,
2599
2660
  requesterRef
2600
2661
  });
2601
2662
  if (!allowed) {
2602
- throw new import_common7.ForbiddenException(`this approval is for ${approver}`);
2663
+ throw new import_common8.ForbiddenException(`this approval is for ${approver}`);
2603
2664
  }
2604
2665
  }
2605
2666
  /**
@@ -2615,7 +2676,7 @@ var AgentService = class {
2615
2676
  }
2616
2677
  const lapsed = approval.status === "expired" || approval.status === "pending_approval" && approval.expiresAt !== null && Date.parse(approval.expiresAt) <= Date.now();
2617
2678
  if (lapsed) {
2618
- throw new import_common7.GoneException(`the approval request for tool call ${toolCallId2} has expired`);
2679
+ throw new import_common8.GoneException(`the approval request for tool call ${toolCallId2} has expired`);
2619
2680
  }
2620
2681
  }
2621
2682
  /**
@@ -2628,7 +2689,7 @@ var AgentService = class {
2628
2689
  async resolveRunForToolCall(toolCallId2) {
2629
2690
  const runId = await this.store.runForToolCall(toolCallId2);
2630
2691
  if (runId === null) {
2631
- throw new import_common7.NotFoundException(`tool call ${toolCallId2} has no active run to signal`);
2692
+ throw new import_common8.NotFoundException(`tool call ${toolCallId2} has no active run to signal`);
2632
2693
  }
2633
2694
  return runId;
2634
2695
  }
@@ -2636,27 +2697,27 @@ var AgentService = class {
2636
2697
  async assertOwnsActiveStream(actor, runId) {
2637
2698
  const owner = await this.store.ownerOfActiveStream(runId);
2638
2699
  if (owner === null) {
2639
- throw new import_common7.NotFoundException(`no active run ${runId}`);
2700
+ throw new import_common8.NotFoundException(`no active run ${runId}`);
2640
2701
  }
2641
2702
  if (owner !== actor.id) {
2642
- throw new import_common7.ForbiddenException("run belongs to another actor");
2703
+ throw new import_common8.ForbiddenException("run belongs to another actor");
2643
2704
  }
2644
2705
  }
2645
2706
  };
2646
2707
  AgentService = _ts_decorate7([
2647
- (0, import_common7.Injectable)(),
2648
- _ts_param6(0, (0, import_common7.Inject)(import_nestjs_agent_core9.AGENT_RUNNER)),
2649
- _ts_param6(1, (0, import_common7.Inject)(import_nestjs_agent_core9.AGENT_STORE)),
2650
- _ts_param6(2, (0, import_common7.Inject)(import_nestjs_agent_core9.AGENT_DEPS_FACTORY)),
2651
- _ts_param6(3, (0, import_common7.Optional)()),
2652
- _ts_param6(3, (0, import_common7.Inject)(import_nestjs_agent_core9.AGENT_ATTACHMENT_STAGING)),
2653
- _ts_param6(4, (0, import_common7.Optional)()),
2654
- _ts_param6(4, (0, import_common7.Inject)(import_nestjs_agent_core9.AGENT_MODEL_CATALOG)),
2655
- _ts_param6(5, (0, import_common7.Optional)()),
2656
- _ts_param6(5, (0, import_common7.Inject)(import_nestjs_agent_core9.AGENT_QUOTA_PROVIDER)),
2657
- _ts_param6(6, (0, import_common7.Optional)()),
2658
- _ts_param6(6, (0, import_common7.Inject)(import_nestjs_agent_core9.AGENT_OPTIONS)),
2659
- _ts_param6(7, (0, import_common7.Optional)()),
2708
+ (0, import_common8.Injectable)(),
2709
+ _ts_param6(0, (0, import_common8.Inject)(import_nestjs_agent_core10.AGENT_RUNNER)),
2710
+ _ts_param6(1, (0, import_common8.Inject)(import_nestjs_agent_core10.AGENT_STORE)),
2711
+ _ts_param6(2, (0, import_common8.Inject)(import_nestjs_agent_core10.AGENT_DEPS_FACTORY)),
2712
+ _ts_param6(3, (0, import_common8.Optional)()),
2713
+ _ts_param6(3, (0, import_common8.Inject)(import_nestjs_agent_core10.AGENT_ATTACHMENT_STAGING)),
2714
+ _ts_param6(4, (0, import_common8.Optional)()),
2715
+ _ts_param6(4, (0, import_common8.Inject)(import_nestjs_agent_core10.AGENT_MODEL_CATALOG)),
2716
+ _ts_param6(5, (0, import_common8.Optional)()),
2717
+ _ts_param6(5, (0, import_common8.Inject)(import_nestjs_agent_core10.AGENT_QUOTA_PROVIDER)),
2718
+ _ts_param6(6, (0, import_common8.Optional)()),
2719
+ _ts_param6(6, (0, import_common8.Inject)(import_nestjs_agent_core10.AGENT_OPTIONS)),
2720
+ _ts_param6(7, (0, import_common8.Optional)()),
2660
2721
  _ts_metadata6("design:type", Function),
2661
2722
  _ts_metadata6("design:paramtypes", [
2662
2723
  typeof AgentRunner === "undefined" ? Object : AgentRunner,
@@ -2666,12 +2727,12 @@ AgentService = _ts_decorate7([
2666
2727
  typeof ModelCatalog === "undefined" ? Object : ModelCatalog,
2667
2728
  typeof QuotaProvider === "undefined" ? Object : QuotaProvider,
2668
2729
  typeof Pick === "undefined" ? Object : Pick,
2669
- typeof ChatQueueService === "undefined" ? Object : ChatQueueService
2730
+ typeof ChatQueueService2 === "undefined" ? Object : ChatQueueService2
2670
2731
  ])
2671
2732
  ], AgentService);
2672
2733
 
2673
2734
  // src/approval-port.adapter.ts
2674
- var import_common8 = require("@nestjs/common");
2735
+ var import_common9 = require("@nestjs/common");
2675
2736
  function _ts_decorate8(decorators, target, key, desc) {
2676
2737
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2677
2738
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -2730,7 +2791,7 @@ var AgentApprovalPortAdapter = class {
2730
2791
  }
2731
2792
  };
2732
2793
  AgentApprovalPortAdapter = _ts_decorate8([
2733
- (0, import_common8.Injectable)(),
2794
+ (0, import_common9.Injectable)(),
2734
2795
  _ts_metadata7("design:type", Function),
2735
2796
  _ts_metadata7("design:paramtypes", [
2736
2797
  typeof AgentService === "undefined" ? Object : AgentService
@@ -2738,8 +2799,8 @@ AgentApprovalPortAdapter = _ts_decorate8([
2738
2799
  ], AgentApprovalPortAdapter);
2739
2800
 
2740
2801
  // src/controller/agents.controller.ts
2741
- var import_nestjs_agent_core10 = require("@dudousxd/nestjs-agent-core");
2742
- var import_common9 = require("@nestjs/common");
2802
+ var import_nestjs_agent_core11 = require("@dudousxd/nestjs-agent-core");
2803
+ var import_common10 = require("@nestjs/common");
2743
2804
  function _ts_decorate9(decorators, target, key, desc) {
2744
2805
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2745
2806
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -2788,25 +2849,25 @@ var AgentsController = class {
2788
2849
  }
2789
2850
  };
2790
2851
  _ts_decorate9([
2791
- (0, import_common9.Get)(),
2852
+ (0, import_common10.Get)(),
2792
2853
  _ts_metadata8("design:type", Function),
2793
2854
  _ts_metadata8("design:paramtypes", []),
2794
2855
  _ts_metadata8("design:returntype", Array)
2795
2856
  ], AgentsController.prototype, "list", null);
2796
2857
  AgentsController = _ts_decorate9([
2797
- (0, import_common9.Controller)("agents"),
2798
- _ts_param7(0, (0, import_common9.Inject)(import_nestjs_agent_core10.AGENT_REGISTRY)),
2799
- _ts_param7(1, (0, import_common9.Inject)(import_nestjs_agent_core10.AGENT_DEPS_FACTORY)),
2858
+ (0, import_common10.Controller)("agents"),
2859
+ _ts_param7(0, (0, import_common10.Inject)(import_nestjs_agent_core11.AGENT_REGISTRY)),
2860
+ _ts_param7(1, (0, import_common10.Inject)(import_nestjs_agent_core11.AGENT_DEPS_FACTORY)),
2800
2861
  _ts_metadata8("design:type", Function),
2801
2862
  _ts_metadata8("design:paramtypes", [
2802
- typeof import_nestjs_agent_core10.AgentRegistry === "undefined" ? Object : import_nestjs_agent_core10.AgentRegistry,
2863
+ typeof import_nestjs_agent_core11.AgentRegistry === "undefined" ? Object : import_nestjs_agent_core11.AgentRegistry,
2803
2864
  typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
2804
2865
  ])
2805
2866
  ], AgentsController);
2806
2867
 
2807
2868
  // src/controller/attachments.controller.ts
2808
- var import_nestjs_agent_core11 = require("@dudousxd/nestjs-agent-core");
2809
- var import_common10 = require("@nestjs/common");
2869
+ var import_nestjs_agent_core12 = require("@dudousxd/nestjs-agent-core");
2870
+ var import_common11 = require("@nestjs/common");
2810
2871
  var import_platform_express = require("@nestjs/platform-express");
2811
2872
 
2812
2873
  // src/attachment-limits.ts
@@ -2894,17 +2955,17 @@ var AttachmentsController = class {
2894
2955
  }
2895
2956
  async upload(req, file) {
2896
2957
  if (this.staging === void 0) {
2897
- throw new import_common10.NotImplementedException("Attachment upload is not configured on this server: bind AGENT_ATTACHMENT_STAGING (e.g. import AgentMediaAttachmentsModule).");
2958
+ throw new import_common11.NotImplementedException("Attachment upload is not configured on this server: bind AGENT_ATTACHMENT_STAGING (e.g. import AgentMediaAttachmentsModule).");
2898
2959
  }
2899
2960
  if (file === void 0) {
2900
- throw new import_common10.BadRequestException('multipart field "file" is required');
2961
+ throw new import_common11.BadRequestException('multipart field "file" is required');
2901
2962
  }
2902
2963
  const { allowedContentTypes, maxBytes } = attachmentLimits(this.options, this.staging);
2903
2964
  if (!allowedContentTypes.includes(file.mimetype)) {
2904
- throw new import_common10.UnsupportedMediaTypeException(`content type "${file.mimetype}" is not allowed (allowed: ${allowedContentTypes.join(", ")})`);
2965
+ throw new import_common11.UnsupportedMediaTypeException(`content type "${file.mimetype}" is not allowed (allowed: ${allowedContentTypes.join(", ")})`);
2905
2966
  }
2906
2967
  if (file.size > maxBytes) {
2907
- throw new import_common10.PayloadTooLargeException(`file exceeds the ${maxBytes}-byte limit`);
2968
+ throw new import_common11.PayloadTooLargeException(`file exceeds the ${maxBytes}-byte limit`);
2908
2969
  }
2909
2970
  const actor = await this.actorResolver.resolve(req);
2910
2971
  return this.staging.stage({
@@ -2917,8 +2978,8 @@ var AttachmentsController = class {
2917
2978
  }
2918
2979
  };
2919
2980
  _ts_decorate10([
2920
- (0, import_common10.Get)(),
2921
- _ts_param8(0, (0, import_common10.Req)()),
2981
+ (0, import_common11.Get)(),
2982
+ _ts_param8(0, (0, import_common11.Req)()),
2922
2983
  _ts_metadata9("design:type", Function),
2923
2984
  _ts_metadata9("design:paramtypes", [
2924
2985
  typeof Request === "undefined" ? Object : Request
@@ -2926,14 +2987,14 @@ _ts_decorate10([
2926
2987
  _ts_metadata9("design:returntype", Promise)
2927
2988
  ], AttachmentsController.prototype, "list", null);
2928
2989
  _ts_decorate10([
2929
- (0, import_common10.Post)(),
2930
- (0, import_common10.UseInterceptors)((0, import_platform_express.FileInterceptor)("file", {
2990
+ (0, import_common11.Post)(),
2991
+ (0, import_common11.UseInterceptors)((0, import_platform_express.FileInterceptor)("file", {
2931
2992
  limits: {
2932
2993
  fileSize: HARD_MAX_ATTACHMENT_BYTES
2933
2994
  }
2934
2995
  })),
2935
- _ts_param8(0, (0, import_common10.Req)()),
2936
- _ts_param8(1, (0, import_common10.UploadedFile)()),
2996
+ _ts_param8(0, (0, import_common11.Req)()),
2997
+ _ts_param8(1, (0, import_common11.UploadedFile)()),
2937
2998
  _ts_metadata9("design:type", Function),
2938
2999
  _ts_metadata9("design:paramtypes", [
2939
3000
  typeof Request === "undefined" ? Object : Request,
@@ -2942,11 +3003,11 @@ _ts_decorate10([
2942
3003
  _ts_metadata9("design:returntype", Promise)
2943
3004
  ], AttachmentsController.prototype, "upload", null);
2944
3005
  AttachmentsController = _ts_decorate10([
2945
- (0, import_common10.Controller)("attachments"),
2946
- _ts_param8(0, (0, import_common10.Inject)(import_nestjs_agent_core11.AGENT_OPTIONS)),
2947
- _ts_param8(1, (0, import_common10.Inject)(import_nestjs_agent_core11.AGENT_ACTOR_RESOLVER)),
2948
- _ts_param8(3, (0, import_common10.Optional)()),
2949
- _ts_param8(3, (0, import_common10.Inject)(import_nestjs_agent_core11.AGENT_ATTACHMENT_STAGING)),
3006
+ (0, import_common11.Controller)("attachments"),
3007
+ _ts_param8(0, (0, import_common11.Inject)(import_nestjs_agent_core12.AGENT_OPTIONS)),
3008
+ _ts_param8(1, (0, import_common11.Inject)(import_nestjs_agent_core12.AGENT_ACTOR_RESOLVER)),
3009
+ _ts_param8(3, (0, import_common11.Optional)()),
3010
+ _ts_param8(3, (0, import_common11.Inject)(import_nestjs_agent_core12.AGENT_ATTACHMENT_STAGING)),
2950
3011
  _ts_metadata9("design:type", Function),
2951
3012
  _ts_metadata9("design:paramtypes", [
2952
3013
  typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
@@ -2957,8 +3018,8 @@ AttachmentsController = _ts_decorate10([
2957
3018
  ], AttachmentsController);
2958
3019
 
2959
3020
  // src/controller/chat.controller.ts
2960
- var import_nestjs_agent_core12 = require("@dudousxd/nestjs-agent-core");
2961
- var import_common11 = require("@nestjs/common");
3021
+ var import_nestjs_agent_core13 = require("@dudousxd/nestjs-agent-core");
3022
+ var import_common12 = require("@nestjs/common");
2962
3023
  function _ts_decorate11(decorators, target, key, desc) {
2963
3024
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2964
3025
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -2995,7 +3056,7 @@ function sendMode(body) {
2995
3056
  if (body.mode === "auto" || body.mode === "queue" || body.mode === "interrupt") {
2996
3057
  return body.mode;
2997
3058
  }
2998
- throw new import_common11.BadRequestException("mode must be 'auto', 'queue' or 'interrupt'");
3059
+ throw new import_common12.BadRequestException("mode must be 'auto', 'queue' or 'interrupt'");
2999
3060
  }
3000
3061
  __name(sendMode, "sendMode");
3001
3062
  function attachmentRefs(claimed) {
@@ -3003,21 +3064,21 @@ function attachmentRefs(claimed) {
3003
3064
  return [];
3004
3065
  }
3005
3066
  if (!Array.isArray(claimed)) {
3006
- throw new import_common11.BadRequestException("attachments must be an array of { mediaId }");
3067
+ throw new import_common12.BadRequestException("attachments must be an array of { mediaId }");
3007
3068
  }
3008
3069
  if (claimed.length > MAX_ATTACHMENTS_PER_MESSAGE) {
3009
- throw new import_common11.BadRequestException(`a message may carry at most ${MAX_ATTACHMENTS_PER_MESSAGE} attachments`);
3070
+ throw new import_common12.BadRequestException(`a message may carry at most ${MAX_ATTACHMENTS_PER_MESSAGE} attachments`);
3010
3071
  }
3011
3072
  return claimed.map((entry) => {
3012
3073
  if (typeof entry !== "object" || entry === null || !("mediaId" in entry)) {
3013
- throw new import_common11.BadRequestException("each attachment must be an object with a mediaId");
3074
+ throw new import_common12.BadRequestException("each attachment must be an object with a mediaId");
3014
3075
  }
3015
3076
  if (Object.keys(entry).some((key) => key !== "mediaId")) {
3016
- throw new import_common11.BadRequestException("attachments are { mediaId } refs \u2014 send nothing but the id");
3077
+ throw new import_common12.BadRequestException("attachments are { mediaId } refs \u2014 send nothing but the id");
3017
3078
  }
3018
3079
  const { mediaId } = entry;
3019
3080
  if (typeof mediaId !== "string" || mediaId.length === 0) {
3020
- throw new import_common11.BadRequestException("each attachment must carry a non-empty string mediaId");
3081
+ throw new import_common12.BadRequestException("each attachment must carry a non-empty string mediaId");
3021
3082
  }
3022
3083
  return {
3023
3084
  mediaId
@@ -3150,13 +3211,10 @@ data: ${line}
3150
3211
  }
3151
3212
  res.write("event: done\ndata: {}\n\n");
3152
3213
  } catch (error) {
3153
- const payload = error instanceof import_nestjs_agent_core12.AgentStreamError ? {
3214
+ const payload = error instanceof import_nestjs_agent_core13.AgentStreamError ? {
3154
3215
  code: error.code,
3155
3216
  message: error.message
3156
- } : {
3157
- code: "run_failed",
3158
- message: error instanceof Error ? error.message : "stream error"
3159
- };
3217
+ } : (0, import_nestjs_agent_core13.streamFailure)(error);
3160
3218
  res.write(`event: error
3161
3219
  data: ${JSON.stringify(payload)}
3162
3220
 
@@ -3166,10 +3224,10 @@ data: ${JSON.stringify(payload)}
3166
3224
  }
3167
3225
  };
3168
3226
  _ts_decorate11([
3169
- (0, import_common11.Post)("chat"),
3170
- _ts_param9(0, (0, import_common11.Req)()),
3171
- _ts_param9(1, (0, import_common11.Res)()),
3172
- _ts_param9(2, (0, import_common11.Body)()),
3227
+ (0, import_common12.Post)("chat"),
3228
+ _ts_param9(0, (0, import_common12.Req)()),
3229
+ _ts_param9(1, (0, import_common12.Res)()),
3230
+ _ts_param9(2, (0, import_common12.Body)()),
3173
3231
  _ts_metadata10("design:type", Function),
3174
3232
  _ts_metadata10("design:paramtypes", [
3175
3233
  typeof Request === "undefined" ? Object : Request,
@@ -3179,11 +3237,11 @@ _ts_decorate11([
3179
3237
  _ts_metadata10("design:returntype", Promise)
3180
3238
  ], ChatController.prototype, "chat", null);
3181
3239
  _ts_decorate11([
3182
- (0, import_common11.Get)("chat/:runId/stream"),
3183
- _ts_param9(0, (0, import_common11.Req)()),
3184
- _ts_param9(1, (0, import_common11.Param)("runId")),
3185
- _ts_param9(2, (0, import_common11.Res)()),
3186
- _ts_param9(3, (0, import_common11.Query)("after")),
3240
+ (0, import_common12.Get)("chat/:runId/stream"),
3241
+ _ts_param9(0, (0, import_common12.Req)()),
3242
+ _ts_param9(1, (0, import_common12.Param)("runId")),
3243
+ _ts_param9(2, (0, import_common12.Res)()),
3244
+ _ts_param9(3, (0, import_common12.Query)("after")),
3187
3245
  _ts_metadata10("design:type", Function),
3188
3246
  _ts_metadata10("design:paramtypes", [
3189
3247
  typeof Request === "undefined" ? Object : Request,
@@ -3194,9 +3252,9 @@ _ts_decorate11([
3194
3252
  _ts_metadata10("design:returntype", Promise)
3195
3253
  ], ChatController.prototype, "stream", null);
3196
3254
  _ts_decorate11([
3197
- (0, import_common11.Post)("chat/:runId/cancel"),
3198
- _ts_param9(0, (0, import_common11.Req)()),
3199
- _ts_param9(1, (0, import_common11.Param)("runId")),
3255
+ (0, import_common12.Post)("chat/:runId/cancel"),
3256
+ _ts_param9(0, (0, import_common12.Req)()),
3257
+ _ts_param9(1, (0, import_common12.Param)("runId")),
3200
3258
  _ts_metadata10("design:type", Function),
3201
3259
  _ts_metadata10("design:paramtypes", [
3202
3260
  typeof Request === "undefined" ? Object : Request,
@@ -3205,8 +3263,8 @@ _ts_decorate11([
3205
3263
  _ts_metadata10("design:returntype", Promise)
3206
3264
  ], ChatController.prototype, "cancel", null);
3207
3265
  ChatController = _ts_decorate11([
3208
- (0, import_common11.Controller)(),
3209
- _ts_param9(1, (0, import_common11.Inject)(import_nestjs_agent_core12.AGENT_ACTOR_RESOLVER)),
3266
+ (0, import_common12.Controller)(),
3267
+ _ts_param9(1, (0, import_common12.Inject)(import_nestjs_agent_core13.AGENT_ACTOR_RESOLVER)),
3210
3268
  _ts_metadata10("design:type", Function),
3211
3269
  _ts_metadata10("design:paramtypes", [
3212
3270
  typeof AgentService === "undefined" ? Object : AgentService,
@@ -3224,8 +3282,8 @@ function parseCursor(raw) {
3224
3282
  __name(parseCursor, "parseCursor");
3225
3283
 
3226
3284
  // src/controller/config.controller.ts
3227
- var import_nestjs_agent_core13 = require("@dudousxd/nestjs-agent-core");
3228
- var import_common12 = require("@nestjs/common");
3285
+ var import_nestjs_agent_core14 = require("@dudousxd/nestjs-agent-core");
3286
+ var import_common13 = require("@nestjs/common");
3229
3287
 
3230
3288
  // src/resolver/anonymous-actor-resolver.ts
3231
3289
  var import_node_crypto2 = require("crypto");
@@ -3372,8 +3430,8 @@ var ConfigController = class {
3372
3430
  }
3373
3431
  };
3374
3432
  _ts_decorate12([
3375
- (0, import_common12.Get)(),
3376
- _ts_param10(0, (0, import_common12.Req)()),
3433
+ (0, import_common13.Get)(),
3434
+ _ts_param10(0, (0, import_common13.Req)()),
3377
3435
  _ts_metadata11("design:type", Function),
3378
3436
  _ts_metadata11("design:paramtypes", [
3379
3437
  typeof Request === "undefined" ? Object : Request
@@ -3381,13 +3439,13 @@ _ts_decorate12([
3381
3439
  _ts_metadata11("design:returntype", Promise)
3382
3440
  ], ConfigController.prototype, "config", null);
3383
3441
  ConfigController = _ts_decorate12([
3384
- (0, import_common12.Controller)("config"),
3385
- _ts_param10(0, (0, import_common12.Inject)(import_nestjs_agent_core13.AGENT_OPTIONS)),
3386
- _ts_param10(1, (0, import_common12.Inject)(import_nestjs_agent_core13.AGENT_ACTOR_RESOLVER)),
3387
- _ts_param10(2, (0, import_common12.Optional)()),
3388
- _ts_param10(2, (0, import_common12.Inject)(import_nestjs_agent_core13.AGENT_ATTACHMENT_STAGING)),
3389
- _ts_param10(3, (0, import_common12.Optional)()),
3390
- _ts_param10(3, (0, import_common12.Inject)(import_nestjs_agent_core13.AGENT_MODEL_CATALOG)),
3442
+ (0, import_common13.Controller)("config"),
3443
+ _ts_param10(0, (0, import_common13.Inject)(import_nestjs_agent_core14.AGENT_OPTIONS)),
3444
+ _ts_param10(1, (0, import_common13.Inject)(import_nestjs_agent_core14.AGENT_ACTOR_RESOLVER)),
3445
+ _ts_param10(2, (0, import_common13.Optional)()),
3446
+ _ts_param10(2, (0, import_common13.Inject)(import_nestjs_agent_core14.AGENT_ATTACHMENT_STAGING)),
3447
+ _ts_param10(3, (0, import_common13.Optional)()),
3448
+ _ts_param10(3, (0, import_common13.Inject)(import_nestjs_agent_core14.AGENT_MODEL_CATALOG)),
3391
3449
  _ts_metadata11("design:type", Function),
3392
3450
  _ts_metadata11("design:paramtypes", [
3393
3451
  typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
@@ -3398,8 +3456,8 @@ ConfigController = _ts_decorate12([
3398
3456
  ], ConfigController);
3399
3457
 
3400
3458
  // src/controller/memories.controller.ts
3401
- var import_nestjs_agent_core14 = require("@dudousxd/nestjs-agent-core");
3402
- var import_common13 = require("@nestjs/common");
3459
+ var import_nestjs_agent_core15 = require("@dudousxd/nestjs-agent-core");
3460
+ var import_common14 = require("@nestjs/common");
3403
3461
  function _ts_decorate13(decorators, target, key, desc) {
3404
3462
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3405
3463
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -3459,20 +3517,20 @@ var MemoriesController = class {
3459
3517
  */
3460
3518
  async forget(req, id) {
3461
3519
  if (this.memory === void 0) {
3462
- throw new import_common13.NotFoundException("No memory is configured in this deployment.");
3520
+ throw new import_common14.NotFoundException("No memory is configured in this deployment.");
3463
3521
  }
3464
3522
  const actor = await this.actorResolver.resolve(req);
3465
3523
  const digest = await this.unbounded("", actor);
3466
3524
  const entry = digest.entries.find((candidate) => candidate.id === id);
3467
3525
  if (entry === void 0) {
3468
- throw new import_common13.NotFoundException(`No memory with id "${id}".`);
3526
+ throw new import_common14.NotFoundException(`No memory with id "${id}".`);
3469
3527
  }
3470
- const verdict = (0, import_nestjs_agent_core14.memoryForgetVerdict)({
3528
+ const verdict = (0, import_nestjs_agent_core15.memoryForgetVerdict)({
3471
3529
  record: entry,
3472
3530
  actor
3473
3531
  });
3474
3532
  if (!verdict.allowed) {
3475
- throw new import_common13.ForbiddenException(verdict.reason);
3533
+ throw new import_common14.ForbiddenException(verdict.reason);
3476
3534
  }
3477
3535
  return {
3478
3536
  forgotten: await this.memory.provider.forget({
@@ -3486,7 +3544,7 @@ var MemoriesController = class {
3486
3544
  }
3487
3545
  async unbounded(threadId, actor) {
3488
3546
  const config = this.memory;
3489
- return await (0, import_nestjs_agent_core14.offerMemories)({
3547
+ return await (0, import_nestjs_agent_core15.offerMemories)({
3490
3548
  config: {
3491
3549
  ...config,
3492
3550
  maxMemories: Number.POSITIVE_INFINITY
@@ -3499,9 +3557,9 @@ var MemoriesController = class {
3499
3557
  }
3500
3558
  };
3501
3559
  _ts_decorate13([
3502
- (0, import_common13.Get)(),
3503
- _ts_param11(0, (0, import_common13.Req)()),
3504
- _ts_param11(1, (0, import_common13.Query)("threadId")),
3560
+ (0, import_common14.Get)(),
3561
+ _ts_param11(0, (0, import_common14.Req)()),
3562
+ _ts_param11(1, (0, import_common14.Query)("threadId")),
3505
3563
  _ts_metadata12("design:type", Function),
3506
3564
  _ts_metadata12("design:paramtypes", [
3507
3565
  typeof Request === "undefined" ? Object : Request,
@@ -3510,9 +3568,9 @@ _ts_decorate13([
3510
3568
  _ts_metadata12("design:returntype", Promise)
3511
3569
  ], MemoriesController.prototype, "list", null);
3512
3570
  _ts_decorate13([
3513
- (0, import_common13.Delete)(":id"),
3514
- _ts_param11(0, (0, import_common13.Req)()),
3515
- _ts_param11(1, (0, import_common13.Param)("id")),
3571
+ (0, import_common14.Delete)(":id"),
3572
+ _ts_param11(0, (0, import_common14.Req)()),
3573
+ _ts_param11(1, (0, import_common14.Param)("id")),
3516
3574
  _ts_metadata12("design:type", Function),
3517
3575
  _ts_metadata12("design:paramtypes", [
3518
3576
  typeof Request === "undefined" ? Object : Request,
@@ -3521,10 +3579,10 @@ _ts_decorate13([
3521
3579
  _ts_metadata12("design:returntype", Promise)
3522
3580
  ], MemoriesController.prototype, "forget", null);
3523
3581
  MemoriesController = _ts_decorate13([
3524
- (0, import_common13.Controller)("memories"),
3525
- _ts_param11(0, (0, import_common13.Inject)(import_nestjs_agent_core14.AGENT_ACTOR_RESOLVER)),
3526
- _ts_param11(1, (0, import_common13.Optional)()),
3527
- _ts_param11(1, (0, import_common13.Inject)(import_nestjs_agent_core14.AGENT_MEMORY)),
3582
+ (0, import_common14.Controller)("memories"),
3583
+ _ts_param11(0, (0, import_common14.Inject)(import_nestjs_agent_core15.AGENT_ACTOR_RESOLVER)),
3584
+ _ts_param11(1, (0, import_common14.Optional)()),
3585
+ _ts_param11(1, (0, import_common14.Inject)(import_nestjs_agent_core15.AGENT_MEMORY)),
3528
3586
  _ts_metadata12("design:type", Function),
3529
3587
  _ts_metadata12("design:paramtypes", [
3530
3588
  typeof ActorResolver === "undefined" ? Object : ActorResolver,
@@ -3533,8 +3591,8 @@ MemoriesController = _ts_decorate13([
3533
3591
  ], MemoriesController);
3534
3592
 
3535
3593
  // src/controller/messages.controller.ts
3536
- var import_nestjs_agent_core15 = require("@dudousxd/nestjs-agent-core");
3537
- var import_common14 = require("@nestjs/common");
3594
+ var import_nestjs_agent_core16 = require("@dudousxd/nestjs-agent-core");
3595
+ var import_common15 = require("@nestjs/common");
3538
3596
  function _ts_decorate14(decorators, target, key, desc) {
3539
3597
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3540
3598
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -3589,11 +3647,11 @@ var MessagesController = class {
3589
3647
  }
3590
3648
  };
3591
3649
  _ts_decorate14([
3592
- (0, import_common14.Post)(":id/feedback"),
3593
- (0, import_common14.HttpCode)(200),
3594
- _ts_param12(0, (0, import_common14.Req)()),
3595
- _ts_param12(1, (0, import_common14.Param)("id")),
3596
- _ts_param12(2, (0, import_common14.Body)()),
3650
+ (0, import_common15.Post)(":id/feedback"),
3651
+ (0, import_common15.HttpCode)(200),
3652
+ _ts_param12(0, (0, import_common15.Req)()),
3653
+ _ts_param12(1, (0, import_common15.Param)("id")),
3654
+ _ts_param12(2, (0, import_common15.Body)()),
3597
3655
  _ts_metadata13("design:type", Function),
3598
3656
  _ts_metadata13("design:paramtypes", [
3599
3657
  typeof Request === "undefined" ? Object : Request,
@@ -3603,8 +3661,8 @@ _ts_decorate14([
3603
3661
  _ts_metadata13("design:returntype", Promise)
3604
3662
  ], MessagesController.prototype, "feedback", null);
3605
3663
  MessagesController = _ts_decorate14([
3606
- (0, import_common14.Controller)("messages"),
3607
- _ts_param12(1, (0, import_common14.Inject)(import_nestjs_agent_core15.AGENT_ACTOR_RESOLVER)),
3664
+ (0, import_common15.Controller)("messages"),
3665
+ _ts_param12(1, (0, import_common15.Inject)(import_nestjs_agent_core16.AGENT_ACTOR_RESOLVER)),
3608
3666
  _ts_metadata13("design:type", Function),
3609
3667
  _ts_metadata13("design:paramtypes", [
3610
3668
  typeof AgentService === "undefined" ? Object : AgentService,
@@ -3613,8 +3671,8 @@ MessagesController = _ts_decorate14([
3613
3671
  ], MessagesController);
3614
3672
 
3615
3673
  // src/controller/models.controller.ts
3616
- var import_nestjs_agent_core16 = require("@dudousxd/nestjs-agent-core");
3617
- var import_common15 = require("@nestjs/common");
3674
+ var import_nestjs_agent_core17 = require("@dudousxd/nestjs-agent-core");
3675
+ var import_common16 = require("@nestjs/common");
3618
3676
  function _ts_decorate15(decorators, target, key, desc) {
3619
3677
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3620
3678
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -3661,9 +3719,9 @@ var ModelsController = class {
3661
3719
  }
3662
3720
  };
3663
3721
  _ts_decorate15([
3664
- (0, import_common15.Get)(),
3665
- _ts_param13(0, (0, import_common15.Req)()),
3666
- _ts_param13(1, (0, import_common15.Query)("agent")),
3722
+ (0, import_common16.Get)(),
3723
+ _ts_param13(0, (0, import_common16.Req)()),
3724
+ _ts_param13(1, (0, import_common16.Query)("agent")),
3667
3725
  _ts_metadata14("design:type", Function),
3668
3726
  _ts_metadata14("design:paramtypes", [
3669
3727
  typeof Request === "undefined" ? Object : Request,
@@ -3672,8 +3730,8 @@ _ts_decorate15([
3672
3730
  _ts_metadata14("design:returntype", Promise)
3673
3731
  ], ModelsController.prototype, "list", null);
3674
3732
  ModelsController = _ts_decorate15([
3675
- (0, import_common15.Controller)("models"),
3676
- _ts_param13(1, (0, import_common15.Inject)(import_nestjs_agent_core16.AGENT_ACTOR_RESOLVER)),
3733
+ (0, import_common16.Controller)("models"),
3734
+ _ts_param13(1, (0, import_common16.Inject)(import_nestjs_agent_core17.AGENT_ACTOR_RESOLVER)),
3677
3735
  _ts_metadata14("design:type", Function),
3678
3736
  _ts_metadata14("design:paramtypes", [
3679
3737
  typeof AgentService === "undefined" ? Object : AgentService,
@@ -3682,8 +3740,8 @@ ModelsController = _ts_decorate15([
3682
3740
  ], ModelsController);
3683
3741
 
3684
3742
  // src/controller/queue.controller.ts
3685
- var import_nestjs_agent_core17 = require("@dudousxd/nestjs-agent-core");
3686
- var import_common16 = require("@nestjs/common");
3743
+ var import_nestjs_agent_core18 = require("@dudousxd/nestjs-agent-core");
3744
+ var import_common17 = require("@nestjs/common");
3687
3745
  function _ts_decorate16(decorators, target, key, desc) {
3688
3746
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3689
3747
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -3733,10 +3791,10 @@ var QueueController = class {
3733
3791
  async update(req, messageId, body) {
3734
3792
  const actor = await this.actorResolver.resolve(req);
3735
3793
  if (body.message !== void 0 && typeof body.message !== "string") {
3736
- throw new import_common16.BadRequestException("message must be a string");
3794
+ throw new import_common17.BadRequestException("message must be a string");
3737
3795
  }
3738
3796
  if (body.position !== void 0 && typeof body.position !== "number") {
3739
- throw new import_common16.BadRequestException("position must be a number");
3797
+ throw new import_common17.BadRequestException("position must be a number");
3740
3798
  }
3741
3799
  const attachments = body.attachments === void 0 ? void 0 : body.attachments === null ? null : attachmentRefs(body.attachments);
3742
3800
  return this.agent.updateQueuedMessage(actor, messageId, {
@@ -3764,9 +3822,9 @@ var QueueController = class {
3764
3822
  }
3765
3823
  };
3766
3824
  _ts_decorate16([
3767
- (0, import_common16.Get)("threads/:id/queue"),
3768
- _ts_param14(0, (0, import_common16.Req)()),
3769
- _ts_param14(1, (0, import_common16.Param)("id")),
3825
+ (0, import_common17.Get)("threads/:id/queue"),
3826
+ _ts_param14(0, (0, import_common17.Req)()),
3827
+ _ts_param14(1, (0, import_common17.Param)("id")),
3770
3828
  _ts_metadata15("design:type", Function),
3771
3829
  _ts_metadata15("design:paramtypes", [
3772
3830
  typeof Request === "undefined" ? Object : Request,
@@ -3775,9 +3833,9 @@ _ts_decorate16([
3775
3833
  _ts_metadata15("design:returntype", Promise)
3776
3834
  ], QueueController.prototype, "list", null);
3777
3835
  _ts_decorate16([
3778
- (0, import_common16.Delete)("threads/:id/queue"),
3779
- _ts_param14(0, (0, import_common16.Req)()),
3780
- _ts_param14(1, (0, import_common16.Param)("id")),
3836
+ (0, import_common17.Delete)("threads/:id/queue"),
3837
+ _ts_param14(0, (0, import_common17.Req)()),
3838
+ _ts_param14(1, (0, import_common17.Param)("id")),
3781
3839
  _ts_metadata15("design:type", Function),
3782
3840
  _ts_metadata15("design:paramtypes", [
3783
3841
  typeof Request === "undefined" ? Object : Request,
@@ -3786,9 +3844,9 @@ _ts_decorate16([
3786
3844
  _ts_metadata15("design:returntype", Promise)
3787
3845
  ], QueueController.prototype, "clear", null);
3788
3846
  _ts_decorate16([
3789
- (0, import_common16.Post)("threads/:id/queue/resume"),
3790
- _ts_param14(0, (0, import_common16.Req)()),
3791
- _ts_param14(1, (0, import_common16.Param)("id")),
3847
+ (0, import_common17.Post)("threads/:id/queue/resume"),
3848
+ _ts_param14(0, (0, import_common17.Req)()),
3849
+ _ts_param14(1, (0, import_common17.Param)("id")),
3792
3850
  _ts_metadata15("design:type", Function),
3793
3851
  _ts_metadata15("design:paramtypes", [
3794
3852
  typeof Request === "undefined" ? Object : Request,
@@ -3797,10 +3855,10 @@ _ts_decorate16([
3797
3855
  _ts_metadata15("design:returntype", Promise)
3798
3856
  ], QueueController.prototype, "resume", null);
3799
3857
  _ts_decorate16([
3800
- (0, import_common16.Patch)("queue/:messageId"),
3801
- _ts_param14(0, (0, import_common16.Req)()),
3802
- _ts_param14(1, (0, import_common16.Param)("messageId")),
3803
- _ts_param14(2, (0, import_common16.Body)()),
3858
+ (0, import_common17.Patch)("queue/:messageId"),
3859
+ _ts_param14(0, (0, import_common17.Req)()),
3860
+ _ts_param14(1, (0, import_common17.Param)("messageId")),
3861
+ _ts_param14(2, (0, import_common17.Body)()),
3804
3862
  _ts_metadata15("design:type", Function),
3805
3863
  _ts_metadata15("design:paramtypes", [
3806
3864
  typeof Request === "undefined" ? Object : Request,
@@ -3810,9 +3868,9 @@ _ts_decorate16([
3810
3868
  _ts_metadata15("design:returntype", Promise)
3811
3869
  ], QueueController.prototype, "update", null);
3812
3870
  _ts_decorate16([
3813
- (0, import_common16.Post)("queue/:messageId/interrupt"),
3814
- _ts_param14(0, (0, import_common16.Req)()),
3815
- _ts_param14(1, (0, import_common16.Param)("messageId")),
3871
+ (0, import_common17.Post)("queue/:messageId/interrupt"),
3872
+ _ts_param14(0, (0, import_common17.Req)()),
3873
+ _ts_param14(1, (0, import_common17.Param)("messageId")),
3816
3874
  _ts_metadata15("design:type", Function),
3817
3875
  _ts_metadata15("design:paramtypes", [
3818
3876
  typeof Request === "undefined" ? Object : Request,
@@ -3821,9 +3879,9 @@ _ts_decorate16([
3821
3879
  _ts_metadata15("design:returntype", Promise)
3822
3880
  ], QueueController.prototype, "interrupt", null);
3823
3881
  _ts_decorate16([
3824
- (0, import_common16.Delete)("queue/:messageId"),
3825
- _ts_param14(0, (0, import_common16.Req)()),
3826
- _ts_param14(1, (0, import_common16.Param)("messageId")),
3882
+ (0, import_common17.Delete)("queue/:messageId"),
3883
+ _ts_param14(0, (0, import_common17.Req)()),
3884
+ _ts_param14(1, (0, import_common17.Param)("messageId")),
3827
3885
  _ts_metadata15("design:type", Function),
3828
3886
  _ts_metadata15("design:paramtypes", [
3829
3887
  typeof Request === "undefined" ? Object : Request,
@@ -3832,8 +3890,8 @@ _ts_decorate16([
3832
3890
  _ts_metadata15("design:returntype", Promise)
3833
3891
  ], QueueController.prototype, "remove", null);
3834
3892
  QueueController = _ts_decorate16([
3835
- (0, import_common16.Controller)(),
3836
- _ts_param14(1, (0, import_common16.Inject)(import_nestjs_agent_core17.AGENT_ACTOR_RESOLVER)),
3893
+ (0, import_common17.Controller)(),
3894
+ _ts_param14(1, (0, import_common17.Inject)(import_nestjs_agent_core18.AGENT_ACTOR_RESOLVER)),
3837
3895
  _ts_metadata15("design:type", Function),
3838
3896
  _ts_metadata15("design:paramtypes", [
3839
3897
  typeof AgentService === "undefined" ? Object : AgentService,
@@ -3842,8 +3900,8 @@ QueueController = _ts_decorate16([
3842
3900
  ], QueueController);
3843
3901
 
3844
3902
  // src/controller/quota.controller.ts
3845
- var import_nestjs_agent_core18 = require("@dudousxd/nestjs-agent-core");
3846
- var import_common17 = require("@nestjs/common");
3903
+ var import_nestjs_agent_core19 = require("@dudousxd/nestjs-agent-core");
3904
+ var import_common18 = require("@nestjs/common");
3847
3905
  function _ts_decorate17(decorators, target, key, desc) {
3848
3906
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3849
3907
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -3890,8 +3948,8 @@ var QuotaController = class {
3890
3948
  }
3891
3949
  };
3892
3950
  _ts_decorate17([
3893
- (0, import_common17.Get)(),
3894
- _ts_param15(0, (0, import_common17.Req)()),
3951
+ (0, import_common18.Get)(),
3952
+ _ts_param15(0, (0, import_common18.Req)()),
3895
3953
  _ts_metadata16("design:type", Function),
3896
3954
  _ts_metadata16("design:paramtypes", [
3897
3955
  typeof Request === "undefined" ? Object : Request
@@ -3899,8 +3957,8 @@ _ts_decorate17([
3899
3957
  _ts_metadata16("design:returntype", Promise)
3900
3958
  ], QuotaController.prototype, "report", null);
3901
3959
  QuotaController = _ts_decorate17([
3902
- (0, import_common17.Controller)("quota"),
3903
- _ts_param15(1, (0, import_common17.Inject)(import_nestjs_agent_core18.AGENT_ACTOR_RESOLVER)),
3960
+ (0, import_common18.Controller)("quota"),
3961
+ _ts_param15(1, (0, import_common18.Inject)(import_nestjs_agent_core19.AGENT_ACTOR_RESOLVER)),
3904
3962
  _ts_metadata16("design:type", Function),
3905
3963
  _ts_metadata16("design:paramtypes", [
3906
3964
  typeof AgentService === "undefined" ? Object : AgentService,
@@ -3909,8 +3967,8 @@ QuotaController = _ts_decorate17([
3909
3967
  ], QuotaController);
3910
3968
 
3911
3969
  // src/controller/skills.controller.ts
3912
- var import_nestjs_agent_core19 = require("@dudousxd/nestjs-agent-core");
3913
- var import_common18 = require("@nestjs/common");
3970
+ var import_nestjs_agent_core20 = require("@dudousxd/nestjs-agent-core");
3971
+ var import_common19 = require("@nestjs/common");
3914
3972
  function _ts_decorate18(decorators, target, key, desc) {
3915
3973
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3916
3974
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -3952,7 +4010,7 @@ var SkillsController = class {
3952
4010
  return [];
3953
4011
  }
3954
4012
  const actor = await this.actorResolver.resolve(req);
3955
- const offer = await (0, import_nestjs_agent_core19.offerSkills)(this.skills, {
4013
+ const offer = await (0, import_nestjs_agent_core20.offerSkills)(this.skills, {
3956
4014
  actor,
3957
4015
  threadId: threadId ?? ""
3958
4016
  });
@@ -3960,9 +4018,9 @@ var SkillsController = class {
3960
4018
  }
3961
4019
  };
3962
4020
  _ts_decorate18([
3963
- (0, import_common18.Get)(),
3964
- _ts_param16(0, (0, import_common18.Req)()),
3965
- _ts_param16(1, (0, import_common18.Query)("threadId")),
4021
+ (0, import_common19.Get)(),
4022
+ _ts_param16(0, (0, import_common19.Req)()),
4023
+ _ts_param16(1, (0, import_common19.Query)("threadId")),
3966
4024
  _ts_metadata17("design:type", Function),
3967
4025
  _ts_metadata17("design:paramtypes", [
3968
4026
  typeof Request === "undefined" ? Object : Request,
@@ -3971,10 +4029,10 @@ _ts_decorate18([
3971
4029
  _ts_metadata17("design:returntype", Promise)
3972
4030
  ], SkillsController.prototype, "list", null);
3973
4031
  SkillsController = _ts_decorate18([
3974
- (0, import_common18.Controller)("skills"),
3975
- _ts_param16(0, (0, import_common18.Inject)(import_nestjs_agent_core19.AGENT_ACTOR_RESOLVER)),
3976
- _ts_param16(1, (0, import_common18.Optional)()),
3977
- _ts_param16(1, (0, import_common18.Inject)(import_nestjs_agent_core19.AGENT_SKILLS)),
4032
+ (0, import_common19.Controller)("skills"),
4033
+ _ts_param16(0, (0, import_common19.Inject)(import_nestjs_agent_core20.AGENT_ACTOR_RESOLVER)),
4034
+ _ts_param16(1, (0, import_common19.Optional)()),
4035
+ _ts_param16(1, (0, import_common19.Inject)(import_nestjs_agent_core20.AGENT_SKILLS)),
3978
4036
  _ts_metadata17("design:type", Function),
3979
4037
  _ts_metadata17("design:paramtypes", [
3980
4038
  typeof ActorResolver === "undefined" ? Object : ActorResolver,
@@ -3983,8 +4041,8 @@ SkillsController = _ts_decorate18([
3983
4041
  ], SkillsController);
3984
4042
 
3985
4043
  // src/controller/threads.controller.ts
3986
- var import_nestjs_agent_core20 = require("@dudousxd/nestjs-agent-core");
3987
- var import_common19 = require("@nestjs/common");
4044
+ var import_nestjs_agent_core21 = require("@dudousxd/nestjs-agent-core");
4045
+ var import_common20 = require("@nestjs/common");
3988
4046
  function _ts_decorate19(decorators, target, key, desc) {
3989
4047
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3990
4048
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -4078,8 +4136,8 @@ var ThreadsController = class {
4078
4136
  }
4079
4137
  };
4080
4138
  _ts_decorate19([
4081
- (0, import_common19.Get)(),
4082
- _ts_param17(0, (0, import_common19.Req)()),
4139
+ (0, import_common20.Get)(),
4140
+ _ts_param17(0, (0, import_common20.Req)()),
4083
4141
  _ts_metadata18("design:type", Function),
4084
4142
  _ts_metadata18("design:paramtypes", [
4085
4143
  typeof Request === "undefined" ? Object : Request
@@ -4087,9 +4145,9 @@ _ts_decorate19([
4087
4145
  _ts_metadata18("design:returntype", Promise)
4088
4146
  ], ThreadsController.prototype, "list", null);
4089
4147
  _ts_decorate19([
4090
- (0, import_common19.Get)(":id"),
4091
- _ts_param17(0, (0, import_common19.Req)()),
4092
- _ts_param17(1, (0, import_common19.Param)("id")),
4148
+ (0, import_common20.Get)(":id"),
4149
+ _ts_param17(0, (0, import_common20.Req)()),
4150
+ _ts_param17(1, (0, import_common20.Param)("id")),
4093
4151
  _ts_metadata18("design:type", Function),
4094
4152
  _ts_metadata18("design:paramtypes", [
4095
4153
  typeof Request === "undefined" ? Object : Request,
@@ -4098,9 +4156,9 @@ _ts_decorate19([
4098
4156
  _ts_metadata18("design:returntype", Promise)
4099
4157
  ], ThreadsController.prototype, "detail", null);
4100
4158
  _ts_decorate19([
4101
- (0, import_common19.Delete)(":id"),
4102
- _ts_param17(0, (0, import_common19.Req)()),
4103
- _ts_param17(1, (0, import_common19.Param)("id")),
4159
+ (0, import_common20.Delete)(":id"),
4160
+ _ts_param17(0, (0, import_common20.Req)()),
4161
+ _ts_param17(1, (0, import_common20.Param)("id")),
4104
4162
  _ts_metadata18("design:type", Function),
4105
4163
  _ts_metadata18("design:paramtypes", [
4106
4164
  typeof Request === "undefined" ? Object : Request,
@@ -4109,10 +4167,10 @@ _ts_decorate19([
4109
4167
  _ts_metadata18("design:returntype", Promise)
4110
4168
  ], ThreadsController.prototype, "remove", null);
4111
4169
  _ts_decorate19([
4112
- (0, import_common19.Post)(":id/fork-from/:messageId"),
4113
- _ts_param17(0, (0, import_common19.Req)()),
4114
- _ts_param17(1, (0, import_common19.Param)("id")),
4115
- _ts_param17(2, (0, import_common19.Param)("messageId")),
4170
+ (0, import_common20.Post)(":id/fork-from/:messageId"),
4171
+ _ts_param17(0, (0, import_common20.Req)()),
4172
+ _ts_param17(1, (0, import_common20.Param)("id")),
4173
+ _ts_param17(2, (0, import_common20.Param)("messageId")),
4116
4174
  _ts_metadata18("design:type", Function),
4117
4175
  _ts_metadata18("design:paramtypes", [
4118
4176
  typeof Request === "undefined" ? Object : Request,
@@ -4122,10 +4180,10 @@ _ts_decorate19([
4122
4180
  _ts_metadata18("design:returntype", Promise)
4123
4181
  ], ThreadsController.prototype, "fork", null);
4124
4182
  _ts_decorate19([
4125
- (0, import_common19.Patch)(":id"),
4126
- _ts_param17(0, (0, import_common19.Req)()),
4127
- _ts_param17(1, (0, import_common19.Param)("id")),
4128
- _ts_param17(2, (0, import_common19.Body)()),
4183
+ (0, import_common20.Patch)(":id"),
4184
+ _ts_param17(0, (0, import_common20.Req)()),
4185
+ _ts_param17(1, (0, import_common20.Param)("id")),
4186
+ _ts_param17(2, (0, import_common20.Body)()),
4129
4187
  _ts_metadata18("design:type", Function),
4130
4188
  _ts_metadata18("design:paramtypes", [
4131
4189
  typeof Request === "undefined" ? Object : Request,
@@ -4135,9 +4193,9 @@ _ts_decorate19([
4135
4193
  _ts_metadata18("design:returntype", Promise)
4136
4194
  ], ThreadsController.prototype, "update", null);
4137
4195
  _ts_decorate19([
4138
- (0, import_common19.Post)(":id/promote"),
4139
- _ts_param17(0, (0, import_common19.Req)()),
4140
- _ts_param17(1, (0, import_common19.Param)("id")),
4196
+ (0, import_common20.Post)(":id/promote"),
4197
+ _ts_param17(0, (0, import_common20.Req)()),
4198
+ _ts_param17(1, (0, import_common20.Param)("id")),
4141
4199
  _ts_metadata18("design:type", Function),
4142
4200
  _ts_metadata18("design:paramtypes", [
4143
4201
  typeof Request === "undefined" ? Object : Request,
@@ -4146,10 +4204,10 @@ _ts_decorate19([
4146
4204
  _ts_metadata18("design:returntype", Promise)
4147
4205
  ], ThreadsController.prototype, "promote", null);
4148
4206
  _ts_decorate19([
4149
- (0, import_common19.Delete)(":id/from/:messageId"),
4150
- _ts_param17(0, (0, import_common19.Req)()),
4151
- _ts_param17(1, (0, import_common19.Param)("id")),
4152
- _ts_param17(2, (0, import_common19.Param)("messageId")),
4207
+ (0, import_common20.Delete)(":id/from/:messageId"),
4208
+ _ts_param17(0, (0, import_common20.Req)()),
4209
+ _ts_param17(1, (0, import_common20.Param)("id")),
4210
+ _ts_param17(2, (0, import_common20.Param)("messageId")),
4153
4211
  _ts_metadata18("design:type", Function),
4154
4212
  _ts_metadata18("design:paramtypes", [
4155
4213
  typeof Request === "undefined" ? Object : Request,
@@ -4159,8 +4217,8 @@ _ts_decorate19([
4159
4217
  _ts_metadata18("design:returntype", Promise)
4160
4218
  ], ThreadsController.prototype, "truncateFrom", null);
4161
4219
  ThreadsController = _ts_decorate19([
4162
- (0, import_common19.Controller)("threads"),
4163
- _ts_param17(1, (0, import_common19.Inject)(import_nestjs_agent_core20.AGENT_ACTOR_RESOLVER)),
4220
+ (0, import_common20.Controller)("threads"),
4221
+ _ts_param17(1, (0, import_common20.Inject)(import_nestjs_agent_core21.AGENT_ACTOR_RESOLVER)),
4164
4222
  _ts_metadata18("design:type", Function),
4165
4223
  _ts_metadata18("design:paramtypes", [
4166
4224
  typeof AgentService === "undefined" ? Object : AgentService,
@@ -4169,8 +4227,8 @@ ThreadsController = _ts_decorate19([
4169
4227
  ], ThreadsController);
4170
4228
 
4171
4229
  // src/controller/tool-call.controller.ts
4172
- var import_nestjs_agent_core21 = require("@dudousxd/nestjs-agent-core");
4173
- var import_common20 = require("@nestjs/common");
4230
+ var import_nestjs_agent_core22 = require("@dudousxd/nestjs-agent-core");
4231
+ var import_common21 = require("@nestjs/common");
4174
4232
  function _ts_decorate20(decorators, target, key, desc) {
4175
4233
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4176
4234
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -4205,7 +4263,7 @@ var MAX_VIA_LENGTH = 64;
4205
4263
  var DEFAULT_VIA = "web";
4206
4264
  function toolCallId(claimed) {
4207
4265
  if (typeof claimed !== "string" || claimed.length === 0) {
4208
- throw new import_common20.BadRequestException("toolCallId must be a non-empty string");
4266
+ throw new import_common21.BadRequestException("toolCallId must be a non-empty string");
4209
4267
  }
4210
4268
  return claimed;
4211
4269
  }
@@ -4215,10 +4273,10 @@ function rejectReason(claimed) {
4215
4273
  return void 0;
4216
4274
  }
4217
4275
  if (typeof claimed !== "string") {
4218
- throw new import_common20.BadRequestException("reason must be a string");
4276
+ throw new import_common21.BadRequestException("reason must be a string");
4219
4277
  }
4220
4278
  if (claimed.length > MAX_REJECT_REASON_LENGTH) {
4221
- throw new import_common20.BadRequestException(`reason must be at most ${MAX_REJECT_REASON_LENGTH} characters`);
4279
+ throw new import_common21.BadRequestException(`reason must be at most ${MAX_REJECT_REASON_LENGTH} characters`);
4222
4280
  }
4223
4281
  return claimed;
4224
4282
  }
@@ -4228,7 +4286,7 @@ function remember(claimed) {
4228
4286
  return false;
4229
4287
  }
4230
4288
  if (typeof claimed !== "boolean") {
4231
- throw new import_common20.BadRequestException("remember must be a boolean");
4289
+ throw new import_common21.BadRequestException("remember must be a boolean");
4232
4290
  }
4233
4291
  return claimed;
4234
4292
  }
@@ -4238,7 +4296,7 @@ function via(claimed) {
4238
4296
  return DEFAULT_VIA;
4239
4297
  }
4240
4298
  if (typeof claimed !== "string" || claimed.length === 0 || claimed.length > MAX_VIA_LENGTH) {
4241
- throw new import_common20.BadRequestException(`via must be a string of 1-${MAX_VIA_LENGTH} characters`);
4299
+ throw new import_common21.BadRequestException(`via must be a string of 1-${MAX_VIA_LENGTH} characters`);
4242
4300
  }
4243
4301
  return claimed;
4244
4302
  }
@@ -4248,26 +4306,26 @@ function answers(claimed) {
4248
4306
  return void 0;
4249
4307
  }
4250
4308
  if (typeof claimed !== "object" || claimed === null || Array.isArray(claimed)) {
4251
- throw new import_common20.BadRequestException("answers must be an object of questionId \u2192 chosen values");
4309
+ throw new import_common21.BadRequestException("answers must be an object of questionId \u2192 chosen values");
4252
4310
  }
4253
4311
  const entries = Object.entries(claimed);
4254
4312
  if (entries.length > MAX_ANSWERED_QUESTIONS) {
4255
- throw new import_common20.BadRequestException(`answers may cover at most ${MAX_ANSWERED_QUESTIONS} questions`);
4313
+ throw new import_common21.BadRequestException(`answers may cover at most ${MAX_ANSWERED_QUESTIONS} questions`);
4256
4314
  }
4257
4315
  const validated = /* @__PURE__ */ Object.create(null);
4258
4316
  for (const [questionId, values] of entries) {
4259
4317
  if (!Array.isArray(values)) {
4260
- throw new import_common20.BadRequestException(`answers["${questionId}"] must be an array of chosen values`);
4318
+ throw new import_common21.BadRequestException(`answers["${questionId}"] must be an array of chosen values`);
4261
4319
  }
4262
4320
  if (values.length > MAX_VALUES_PER_QUESTION) {
4263
- throw new import_common20.BadRequestException(`answers["${questionId}"] may carry at most ${MAX_VALUES_PER_QUESTION} values`);
4321
+ throw new import_common21.BadRequestException(`answers["${questionId}"] may carry at most ${MAX_VALUES_PER_QUESTION} values`);
4264
4322
  }
4265
4323
  for (const value of values) {
4266
4324
  if (typeof value !== "string") {
4267
- throw new import_common20.BadRequestException(`answers["${questionId}"] must contain only strings`);
4325
+ throw new import_common21.BadRequestException(`answers["${questionId}"] must contain only strings`);
4268
4326
  }
4269
4327
  if (value.length > MAX_ANSWER_VALUE_LENGTH) {
4270
- throw new import_common20.BadRequestException(`answers["${questionId}"] values must be at most ${MAX_ANSWER_VALUE_LENGTH} characters`);
4328
+ throw new import_common21.BadRequestException(`answers["${questionId}"] values must be at most ${MAX_ANSWER_VALUE_LENGTH} characters`);
4271
4329
  }
4272
4330
  }
4273
4331
  validated[questionId] = values;
@@ -4330,9 +4388,9 @@ var ToolCallController = class {
4330
4388
  }
4331
4389
  };
4332
4390
  _ts_decorate20([
4333
- (0, import_common20.Post)("approve"),
4334
- _ts_param18(0, (0, import_common20.Req)()),
4335
- _ts_param18(1, (0, import_common20.Body)()),
4391
+ (0, import_common21.Post)("approve"),
4392
+ _ts_param18(0, (0, import_common21.Req)()),
4393
+ _ts_param18(1, (0, import_common21.Body)()),
4336
4394
  _ts_metadata19("design:type", Function),
4337
4395
  _ts_metadata19("design:paramtypes", [
4338
4396
  typeof Request === "undefined" ? Object : Request,
@@ -4341,9 +4399,9 @@ _ts_decorate20([
4341
4399
  _ts_metadata19("design:returntype", Promise)
4342
4400
  ], ToolCallController.prototype, "approve", null);
4343
4401
  _ts_decorate20([
4344
- (0, import_common20.Post)("reject"),
4345
- _ts_param18(0, (0, import_common20.Req)()),
4346
- _ts_param18(1, (0, import_common20.Body)()),
4402
+ (0, import_common21.Post)("reject"),
4403
+ _ts_param18(0, (0, import_common21.Req)()),
4404
+ _ts_param18(1, (0, import_common21.Body)()),
4347
4405
  _ts_metadata19("design:type", Function),
4348
4406
  _ts_metadata19("design:paramtypes", [
4349
4407
  typeof Request === "undefined" ? Object : Request,
@@ -4352,9 +4410,9 @@ _ts_decorate20([
4352
4410
  _ts_metadata19("design:returntype", Promise)
4353
4411
  ], ToolCallController.prototype, "reject", null);
4354
4412
  _ts_decorate20([
4355
- (0, import_common20.Post)("answer"),
4356
- _ts_param18(0, (0, import_common20.Req)()),
4357
- _ts_param18(1, (0, import_common20.Body)()),
4413
+ (0, import_common21.Post)("answer"),
4414
+ _ts_param18(0, (0, import_common21.Req)()),
4415
+ _ts_param18(1, (0, import_common21.Body)()),
4358
4416
  _ts_metadata19("design:type", Function),
4359
4417
  _ts_metadata19("design:paramtypes", [
4360
4418
  typeof Request === "undefined" ? Object : Request,
@@ -4363,9 +4421,9 @@ _ts_decorate20([
4363
4421
  _ts_metadata19("design:returntype", Promise)
4364
4422
  ], ToolCallController.prototype, "answer", null);
4365
4423
  _ts_decorate20([
4366
- (0, import_common20.Post)("skip"),
4367
- _ts_param18(0, (0, import_common20.Req)()),
4368
- _ts_param18(1, (0, import_common20.Body)()),
4424
+ (0, import_common21.Post)("skip"),
4425
+ _ts_param18(0, (0, import_common21.Req)()),
4426
+ _ts_param18(1, (0, import_common21.Body)()),
4369
4427
  _ts_metadata19("design:type", Function),
4370
4428
  _ts_metadata19("design:paramtypes", [
4371
4429
  typeof Request === "undefined" ? Object : Request,
@@ -4374,8 +4432,8 @@ _ts_decorate20([
4374
4432
  _ts_metadata19("design:returntype", Promise)
4375
4433
  ], ToolCallController.prototype, "skip", null);
4376
4434
  ToolCallController = _ts_decorate20([
4377
- (0, import_common20.Controller)("tool-call"),
4378
- _ts_param18(1, (0, import_common20.Inject)(import_nestjs_agent_core21.AGENT_ACTOR_RESOLVER)),
4435
+ (0, import_common21.Controller)("tool-call"),
4436
+ _ts_param18(1, (0, import_common21.Inject)(import_nestjs_agent_core22.AGENT_ACTOR_RESOLVER)),
4379
4437
  _ts_metadata19("design:type", Function),
4380
4438
  _ts_metadata19("design:paramtypes", [
4381
4439
  typeof AgentService === "undefined" ? Object : AgentService,
@@ -4384,8 +4442,8 @@ ToolCallController = _ts_decorate20([
4384
4442
  ], ToolCallController);
4385
4443
 
4386
4444
  // src/controller/tools.controller.ts
4387
- var import_nestjs_agent_core22 = require("@dudousxd/nestjs-agent-core");
4388
- var import_common21 = require("@nestjs/common");
4445
+ var import_nestjs_agent_core23 = require("@dudousxd/nestjs-agent-core");
4446
+ var import_common22 = require("@nestjs/common");
4389
4447
  function _ts_decorate21(decorators, target, key, desc) {
4390
4448
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4391
4449
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -4425,11 +4483,11 @@ var ToolsController = class {
4425
4483
  this.agents = agents;
4426
4484
  }
4427
4485
  async list(req, agent) {
4428
- if (agent !== void 0 && agent !== import_nestjs_agent_core22.ALL_AGENTS && this.agents.get(agent) === void 0) {
4429
- throw new import_common21.NotFoundException(`No agent named "${agent}"`);
4486
+ if (agent !== void 0 && agent !== import_nestjs_agent_core23.ALL_AGENTS && this.agents.get(agent) === void 0) {
4487
+ throw new import_common22.NotFoundException(`No agent named "${agent}"`);
4430
4488
  }
4431
4489
  const actor = await this.actorResolver.resolve(req);
4432
- const names = agent === import_nestjs_agent_core22.ALL_AGENTS ? [
4490
+ const names = agent === import_nestjs_agent_core23.ALL_AGENTS ? [
4433
4491
  void 0,
4434
4492
  ...this.agents.list().map((definition) => definition.name)
4435
4493
  ] : [
@@ -4456,9 +4514,9 @@ var ToolsController = class {
4456
4514
  }
4457
4515
  };
4458
4516
  _ts_decorate21([
4459
- (0, import_common21.Get)(),
4460
- _ts_param19(0, (0, import_common21.Req)()),
4461
- _ts_param19(1, (0, import_common21.Query)("agent")),
4517
+ (0, import_common22.Get)(),
4518
+ _ts_param19(0, (0, import_common22.Req)()),
4519
+ _ts_param19(1, (0, import_common22.Query)("agent")),
4462
4520
  _ts_metadata20("design:type", Function),
4463
4521
  _ts_metadata20("design:paramtypes", [
4464
4522
  typeof Request === "undefined" ? Object : Request,
@@ -4467,21 +4525,21 @@ _ts_decorate21([
4467
4525
  _ts_metadata20("design:returntype", Promise)
4468
4526
  ], ToolsController.prototype, "list", null);
4469
4527
  ToolsController = _ts_decorate21([
4470
- (0, import_common21.Controller)("tools"),
4471
- _ts_param19(0, (0, import_common21.Inject)(import_nestjs_agent_core22.AGENT_ACTOR_RESOLVER)),
4472
- _ts_param19(1, (0, import_common21.Inject)(import_nestjs_agent_core22.AGENT_DEPS_FACTORY)),
4473
- _ts_param19(2, (0, import_common21.Inject)(import_nestjs_agent_core22.AGENT_REGISTRY)),
4528
+ (0, import_common22.Controller)("tools"),
4529
+ _ts_param19(0, (0, import_common22.Inject)(import_nestjs_agent_core23.AGENT_ACTOR_RESOLVER)),
4530
+ _ts_param19(1, (0, import_common22.Inject)(import_nestjs_agent_core23.AGENT_DEPS_FACTORY)),
4531
+ _ts_param19(2, (0, import_common22.Inject)(import_nestjs_agent_core23.AGENT_REGISTRY)),
4474
4532
  _ts_metadata20("design:type", Function),
4475
4533
  _ts_metadata20("design:paramtypes", [
4476
4534
  typeof ActorResolver === "undefined" ? Object : ActorResolver,
4477
4535
  typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
4478
- typeof import_nestjs_agent_core22.AgentRegistry === "undefined" ? Object : import_nestjs_agent_core22.AgentRegistry
4536
+ typeof import_nestjs_agent_core23.AgentRegistry === "undefined" ? Object : import_nestjs_agent_core23.AgentRegistry
4479
4537
  ])
4480
4538
  ], ToolsController);
4481
4539
 
4482
4540
  // src/discovery/agent-discovery.service.ts
4483
- var import_nestjs_agent_core23 = require("@dudousxd/nestjs-agent-core");
4484
- var import_common22 = require("@nestjs/common");
4541
+ var import_nestjs_agent_core24 = require("@dudousxd/nestjs-agent-core");
4542
+ var import_common23 = require("@nestjs/common");
4485
4543
  var import_core = require("@nestjs/core");
4486
4544
 
4487
4545
  // src/decorator/agent.decorator.ts
@@ -4532,7 +4590,7 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
4532
4590
  scanner;
4533
4591
  registry;
4534
4592
  contributors;
4535
- logger = new import_common22.Logger(_AgentDiscoveryService.name);
4593
+ logger = new import_common23.Logger(_AgentDiscoveryService.name);
4536
4594
  constructor(discovery, scanner, registry, contributors) {
4537
4595
  this.discovery = discovery;
4538
4596
  this.scanner = scanner;
@@ -4651,21 +4709,21 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
4651
4709
  }
4652
4710
  };
4653
4711
  AgentDiscoveryService = _ts_decorate22([
4654
- (0, import_common22.Injectable)(),
4655
- _ts_param20(2, (0, import_common22.Inject)(import_nestjs_agent_core23.AGENT_REGISTRY)),
4656
- _ts_param20(3, (0, import_common22.Inject)(import_nestjs_agent_core23.AGENT_PROMPT_CONTRIBUTORS)),
4712
+ (0, import_common23.Injectable)(),
4713
+ _ts_param20(2, (0, import_common23.Inject)(import_nestjs_agent_core24.AGENT_REGISTRY)),
4714
+ _ts_param20(3, (0, import_common23.Inject)(import_nestjs_agent_core24.AGENT_PROMPT_CONTRIBUTORS)),
4657
4715
  _ts_metadata21("design:type", Function),
4658
4716
  _ts_metadata21("design:paramtypes", [
4659
4717
  typeof import_core.DiscoveryService === "undefined" ? Object : import_core.DiscoveryService,
4660
4718
  typeof import_core.MetadataScanner === "undefined" ? Object : import_core.MetadataScanner,
4661
- typeof import_nestjs_agent_core23.AgentRegistry === "undefined" ? Object : import_nestjs_agent_core23.AgentRegistry,
4719
+ typeof import_nestjs_agent_core24.AgentRegistry === "undefined" ? Object : import_nestjs_agent_core24.AgentRegistry,
4662
4720
  Array
4663
4721
  ])
4664
4722
  ], AgentDiscoveryService);
4665
4723
 
4666
4724
  // src/discovery/ai-tool-discovery.service.ts
4667
- var import_nestjs_agent_core24 = require("@dudousxd/nestjs-agent-core");
4668
- var import_common23 = require("@nestjs/common");
4725
+ var import_nestjs_agent_core25 = require("@dudousxd/nestjs-agent-core");
4726
+ var import_common24 = require("@nestjs/common");
4669
4727
  var import_core2 = require("@nestjs/core");
4670
4728
  var import_zod = require("zod");
4671
4729
 
@@ -4719,7 +4777,7 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
4719
4777
  registry;
4720
4778
  agents;
4721
4779
  options;
4722
- logger = new import_common23.Logger(_AiToolDiscoveryService.name);
4780
+ logger = new import_common24.Logger(_AiToolDiscoveryService.name);
4723
4781
  constructor(discovery, registry, agents, options) {
4724
4782
  this.discovery = discovery;
4725
4783
  this.registry = registry;
@@ -4804,7 +4862,7 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
4804
4862
  let delegates = 0;
4805
4863
  for (const definition of this.agents.list()) {
4806
4864
  for (const edge of definition.delegatesTo ?? []) {
4807
- const { agent: target, detached } = (0, import_nestjs_agent_core24.normalizeDelegation)(edge);
4865
+ const { agent: target, detached } = (0, import_nestjs_agent_core25.normalizeDelegation)(edge);
4808
4866
  const targetDefinition = this.agents.get(target);
4809
4867
  if (targetDefinition === void 0) {
4810
4868
  throw new Error(`Agent "${definition.name}" hands off to "${target}", which is not a registered @Agent. Declare it as an @Agent provider or fix the reference.`);
@@ -4855,10 +4913,10 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
4855
4913
  }
4856
4914
  };
4857
4915
  AiToolDiscoveryService = _ts_decorate23([
4858
- (0, import_common23.Injectable)(),
4859
- _ts_param21(1, (0, import_common23.Inject)(import_nestjs_agent_core24.AGENT_TOOL_REGISTRY)),
4860
- _ts_param21(2, (0, import_common23.Inject)(import_nestjs_agent_core24.AGENT_REGISTRY)),
4861
- _ts_param21(3, (0, import_common23.Inject)(import_nestjs_agent_core24.AGENT_OPTIONS)),
4916
+ (0, import_common24.Injectable)(),
4917
+ _ts_param21(1, (0, import_common24.Inject)(import_nestjs_agent_core25.AGENT_TOOL_REGISTRY)),
4918
+ _ts_param21(2, (0, import_common24.Inject)(import_nestjs_agent_core25.AGENT_REGISTRY)),
4919
+ _ts_param21(3, (0, import_common24.Inject)(import_nestjs_agent_core25.AGENT_OPTIONS)),
4862
4920
  _ts_metadata22("design:type", Function),
4863
4921
  _ts_metadata22("design:paramtypes", [
4864
4922
  typeof import_core2.DiscoveryService === "undefined" ? Object : import_core2.DiscoveryService,
@@ -4869,20 +4927,20 @@ AiToolDiscoveryService = _ts_decorate23([
4869
4927
  ], AiToolDiscoveryService);
4870
4928
 
4871
4929
  // src/discovery/skill-discovery.service.ts
4872
- var import_nestjs_agent_core26 = require("@dudousxd/nestjs-agent-core");
4873
- var import_common24 = require("@nestjs/common");
4930
+ var import_nestjs_agent_core27 = require("@dudousxd/nestjs-agent-core");
4931
+ var import_common25 = require("@nestjs/common");
4874
4932
  var import_core3 = require("@nestjs/core");
4875
4933
 
4876
4934
  // src/decorator/skill.decorator.ts
4877
4935
  var import_reflect_metadata4 = require("reflect-metadata");
4878
- var import_nestjs_agent_core25 = require("@dudousxd/nestjs-agent-core");
4936
+ var import_nestjs_agent_core26 = require("@dudousxd/nestjs-agent-core");
4879
4937
  var SKILL_METADATA = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:skill-metadata");
4880
4938
  function readSkillMetadata(target) {
4881
4939
  return Reflect.getMetadata(SKILL_METADATA, target);
4882
4940
  }
4883
4941
  __name(readSkillMetadata, "readSkillMetadata");
4884
4942
  function skillScope(options) {
4885
- return options.scope ?? import_nestjs_agent_core25.GLOBAL_SCOPE;
4943
+ return options.scope ?? import_nestjs_agent_core26.GLOBAL_SCOPE;
4886
4944
  }
4887
4945
  __name(skillScope, "skillScope");
4888
4946
 
@@ -4919,7 +4977,7 @@ var SkillDiscoveryService = class _SkillDiscoveryService {
4919
4977
  }
4920
4978
  discovery;
4921
4979
  declared;
4922
- logger = new import_common24.Logger(_SkillDiscoveryService.name);
4980
+ logger = new import_common25.Logger(_SkillDiscoveryService.name);
4923
4981
  constructor(discovery, declared) {
4924
4982
  this.discovery = discovery;
4925
4983
  this.declared = declared;
@@ -4957,8 +5015,8 @@ var SkillDiscoveryService = class _SkillDiscoveryService {
4957
5015
  }
4958
5016
  };
4959
5017
  SkillDiscoveryService = _ts_decorate24([
4960
- (0, import_common24.Injectable)(),
4961
- _ts_param22(1, (0, import_common24.Inject)(import_nestjs_agent_core26.AGENT_SKILL_SOURCES)),
5018
+ (0, import_common25.Injectable)(),
5019
+ _ts_param22(1, (0, import_common25.Inject)(import_nestjs_agent_core27.AGENT_SKILL_SOURCES)),
4962
5020
  _ts_metadata23("design:type", Function),
4963
5021
  _ts_metadata23("design:paramtypes", [
4964
5022
  typeof import_core3.DiscoveryService === "undefined" ? Object : import_core3.DiscoveryService,
@@ -4967,7 +5025,7 @@ SkillDiscoveryService = _ts_decorate24([
4967
5025
  ], SkillDiscoveryService);
4968
5026
 
4969
5027
  // src/ledger-quota-provider.ts
4970
- var import_nestjs_agent_core27 = require("@dudousxd/nestjs-agent-core");
5028
+ var import_nestjs_agent_core28 = require("@dudousxd/nestjs-agent-core");
4971
5029
  var LedgerQuotaProvider = class {
4972
5030
  static {
4973
5031
  __name(this, "LedgerQuotaProvider");
@@ -4987,12 +5045,12 @@ var LedgerQuotaProvider = class {
4987
5045
  await this.dayWindow(actorRef, now)
4988
5046
  ];
4989
5047
  if (this.store.usageBetween !== void 0) {
4990
- const range = (0, import_nestjs_agent_core27.quotaPeriodRange)("month", now);
5048
+ const range = (0, import_nestjs_agent_core28.quotaPeriodRange)("month", now);
4991
5049
  const used = await this.store.usageBetween(actorRef, range.fromDay, range.toDay);
4992
5050
  windows.push(this.window("month", used.usedTokens, used.costUsd, range.resetsAt));
4993
5051
  }
4994
- const blocked = (0, import_nestjs_agent_core27.exhaustedWindow)(windows);
4995
- const warning = (0, import_nestjs_agent_core27.quotaWarning)(windows);
5052
+ const blocked = (0, import_nestjs_agent_core28.exhaustedWindow)(windows);
5053
+ const warning = (0, import_nestjs_agent_core28.quotaWarning)(windows);
4996
5054
  return {
4997
5055
  windows,
4998
5056
  ...blocked !== void 0 ? {
@@ -5004,7 +5062,7 @@ var LedgerQuotaProvider = class {
5004
5062
  };
5005
5063
  }
5006
5064
  async dayWindow(actorRef, now) {
5007
- const range = (0, import_nestjs_agent_core27.quotaPeriodRange)("day", now);
5065
+ const range = (0, import_nestjs_agent_core28.quotaPeriodRange)("day", now);
5008
5066
  const { usedTokens, costUsd } = await this.store.quotaToday(actorRef, range.fromDay);
5009
5067
  return this.window("day", usedTokens, costUsd, range.resetsAt);
5010
5068
  }
@@ -5029,8 +5087,8 @@ var LedgerQuotaProvider = class {
5029
5087
  };
5030
5088
 
5031
5089
  // src/runner/inline-agent-runner.ts
5032
- var import_nestjs_agent_core28 = require("@dudousxd/nestjs-agent-core");
5033
- var import_common25 = require("@nestjs/common");
5090
+ var import_nestjs_agent_core29 = require("@dudousxd/nestjs-agent-core");
5091
+ var import_common26 = require("@nestjs/common");
5034
5092
  function _ts_decorate25(decorators, target, key, desc) {
5035
5093
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
5036
5094
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -5064,7 +5122,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
5064
5122
  factory;
5065
5123
  store;
5066
5124
  queue;
5067
- logger = new import_common25.Logger(_InlineAgentRunner.name);
5125
+ logger = new import_common26.Logger(_InlineAgentRunner.name);
5068
5126
  pending = /* @__PURE__ */ new Map();
5069
5127
  /**
5070
5128
  * Runs someone has asked to stop. In-process, like `pending`, and for the same reason: this runner
@@ -5084,7 +5142,15 @@ var InlineAgentRunner = class _InlineAgentRunner {
5084
5142
  * that was running it is gone (a restart), and a thread it still holds is a stale claim.
5085
5143
  */
5086
5144
  async isRunActive(runId) {
5087
- return this.live.has(runId);
5145
+ if (this.live.has(runId)) {
5146
+ return true;
5147
+ }
5148
+ for (const key of this.pending.keys()) {
5149
+ if (key.startsWith(`${runId}:`)) {
5150
+ return true;
5151
+ }
5152
+ }
5153
+ return false;
5088
5154
  }
5089
5155
  async start(input, options = {}) {
5090
5156
  const runId = options.runId ?? crypto.randomUUID();
@@ -5105,18 +5171,18 @@ var InlineAgentRunner = class _InlineAgentRunner {
5105
5171
  ],
5106
5172
  input
5107
5173
  });
5108
- void (0, import_nestjs_agent_core28.runAgentLoop)({
5174
+ void (0, import_nestjs_agent_core29.runAgentLoop)({
5109
5175
  ...deps,
5110
5176
  day
5111
- }, input, hooks).then(() => (0, import_nestjs_agent_core28.releaseThreadRun)(this.store, input.threadId, runId)).catch(async (error) => {
5112
- if (error instanceof import_nestjs_agent_core28.RunCancelledError) {
5177
+ }, input, hooks).then(() => (0, import_nestjs_agent_core29.releaseThreadRun)(this.store, input.threadId, runId)).catch(async (error) => {
5178
+ if (error instanceof import_nestjs_agent_core29.RunCancelledError) {
5113
5179
  await this.settleCancelled(runId, input, deps);
5114
5180
  return;
5115
5181
  }
5116
5182
  const message = error instanceof Error ? error.message : String(error);
5117
- const code = (0, import_nestjs_agent_core28.agentFailureCode)(error);
5183
+ const code = (0, import_nestjs_agent_core29.agentFailureCode)(error);
5118
5184
  this.logger.error(`agent run ${runId} failed (${code}): ${message}`);
5119
- (0, import_nestjs_agent_core28.publishAgentRunFailed)({
5185
+ (0, import_nestjs_agent_core29.publishAgentRunFailed)({
5120
5186
  runId,
5121
5187
  code,
5122
5188
  message
@@ -5127,13 +5193,11 @@ var InlineAgentRunner = class _InlineAgentRunner {
5127
5193
  errorCode: code,
5128
5194
  errorMessage: message
5129
5195
  });
5196
+ await Promise.resolve(this.store.failUnsettledToolCalls?.(runId, import_nestjs_agent_core29.RUN_ENDED_BEFORE_TOOL_CALL)).catch(() => 0);
5130
5197
  const writer = await deps.sink.open(runId);
5131
5198
  await this.settleQueue(writer, input, runId, "failed", message);
5132
- await (0, import_nestjs_agent_core28.releaseThreadRun)(this.store, input.threadId, runId);
5133
- await writer.fail({
5134
- code,
5135
- message
5136
- });
5199
+ await (0, import_nestjs_agent_core29.releaseThreadRun)(this.store, input.threadId, runId);
5200
+ await writer.fail((0, import_nestjs_agent_core29.streamFailure)(error));
5137
5201
  }).finally(() => {
5138
5202
  this.cancelled.delete(runId);
5139
5203
  this.live.delete(runId);
@@ -5169,7 +5233,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
5169
5233
  for (const [key, waiter] of this.pending) {
5170
5234
  if (key.startsWith(`${runId}:`)) {
5171
5235
  this.pending.delete(key);
5172
- waiter.reject(new import_nestjs_agent_core28.RunCancelledError());
5236
+ waiter.reject(new import_nestjs_agent_core29.RunCancelledError());
5173
5237
  }
5174
5238
  }
5175
5239
  await Promise.resolve();
@@ -5184,8 +5248,8 @@ var InlineAgentRunner = class _InlineAgentRunner {
5184
5248
  this.logger.log(`agent run ${runId} cancelled`);
5185
5249
  const writer = await deps.sink.open(runId);
5186
5250
  await this.settleQueue(writer, input, runId, "cancelled");
5187
- await (0, import_nestjs_agent_core28.releaseThreadRun)(this.store, input.threadId, runId);
5188
- await writer.write((0, import_nestjs_agent_core28.encodeStreamEvent)({
5251
+ await (0, import_nestjs_agent_core29.releaseThreadRun)(this.store, input.threadId, runId);
5252
+ await writer.write((0, import_nestjs_agent_core29.encodeStreamEvent)({
5189
5253
  kind: "cancelled"
5190
5254
  }));
5191
5255
  await writer.end();
@@ -5220,7 +5284,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
5220
5284
  runId: nextRunId
5221
5285
  }));
5222
5286
  if (frame !== void 0) {
5223
- await writer.write((0, import_nestjs_agent_core28.encodeStreamEvent)(frame));
5287
+ await writer.write((0, import_nestjs_agent_core29.encodeStreamEvent)(frame));
5224
5288
  }
5225
5289
  } catch (failure) {
5226
5290
  this.logger.error(`could not advance the queue of thread ${input.threadId} after run ${runId}: ${failure instanceof Error ? failure.message : String(failure)}`);
@@ -5291,7 +5355,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
5291
5355
  awaitApproval: /* @__PURE__ */ __name((call, _ctx, opts) => this.parkApproval(runId, call.id, opts?.timeoutMs), "awaitApproval"),
5292
5356
  awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
5293
5357
  step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
5294
- parallel: import_nestjs_agent_core28.settleAll,
5358
+ parallel: import_nestjs_agent_core29.settleAll,
5295
5359
  cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId), "cancelled"),
5296
5360
  runAgent: /* @__PURE__ */ __name((agentName, task) => this.runNested({
5297
5361
  agentName,
@@ -5342,7 +5406,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
5342
5406
  awaitApproval: /* @__PURE__ */ __name((call, _ctx, opts) => this.parkApproval(runId, call.id, opts?.timeoutMs), "awaitApproval"),
5343
5407
  awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
5344
5408
  step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
5345
- parallel: import_nestjs_agent_core28.settleAll,
5409
+ parallel: import_nestjs_agent_core29.settleAll,
5346
5410
  cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId), "cancelled"),
5347
5411
  runAgent: /* @__PURE__ */ __name((childName, childTask) => this.runNested({
5348
5412
  agentName: childName,
@@ -5375,7 +5439,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
5375
5439
  }
5376
5440
  }), "startAgent")
5377
5441
  };
5378
- void (0, import_nestjs_agent_core28.runAgentLoop)({
5442
+ void (0, import_nestjs_agent_core29.runAgentLoop)({
5379
5443
  ...deps,
5380
5444
  day
5381
5445
  }, {
@@ -5389,13 +5453,13 @@ var InlineAgentRunner = class _InlineAgentRunner {
5389
5453
  parentRunId,
5390
5454
  deliverTo
5391
5455
  }, hooks).catch(async (error) => {
5392
- const cancelled = error instanceof import_nestjs_agent_core28.RunCancelledError;
5456
+ const cancelled = error instanceof import_nestjs_agent_core29.RunCancelledError;
5393
5457
  const message = error instanceof Error ? error.message : String(error);
5394
5458
  if (!cancelled) {
5395
5459
  this.logger.error(`detached agent run ${runId} failed: ${message}`);
5396
- (0, import_nestjs_agent_core28.publishAgentRunFailed)({
5460
+ (0, import_nestjs_agent_core29.publishAgentRunFailed)({
5397
5461
  runId,
5398
- code: (0, import_nestjs_agent_core28.agentFailureCode)(error),
5462
+ code: (0, import_nestjs_agent_core29.agentFailureCode)(error),
5399
5463
  message
5400
5464
  });
5401
5465
  }
@@ -5403,11 +5467,12 @@ var InlineAgentRunner = class _InlineAgentRunner {
5403
5467
  runId,
5404
5468
  status: cancelled ? "cancelled" : "failed",
5405
5469
  ...cancelled ? {} : {
5406
- errorCode: (0, import_nestjs_agent_core28.agentFailureCode)(error),
5470
+ errorCode: (0, import_nestjs_agent_core29.agentFailureCode)(error),
5407
5471
  errorMessage: message
5408
5472
  }
5409
5473
  });
5410
- await (0, import_nestjs_agent_core28.settleUnsettledDelegation)({
5474
+ await Promise.resolve(this.store.failUnsettledToolCalls?.(runId, import_nestjs_agent_core29.RUN_ENDED_BEFORE_TOOL_CALL)).catch(() => 0);
5475
+ await (0, import_nestjs_agent_core29.settleUnsettledDelegation)({
5411
5476
  store: this.store,
5412
5477
  delivery: deliverTo,
5413
5478
  agent: agentName,
@@ -5446,7 +5511,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
5446
5511
  awaitApproval: /* @__PURE__ */ __name((call, _ctx, opts) => this.parkApproval(runId, call.id, opts?.timeoutMs), "awaitApproval"),
5447
5512
  awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
5448
5513
  step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
5449
- parallel: import_nestjs_agent_core28.settleAll,
5514
+ parallel: import_nestjs_agent_core29.settleAll,
5450
5515
  // A child stops when it is cancelled OR when the run a human is actually watching is: the
5451
5516
  // canceller names the top-level run, which is the only id that ever left the server.
5452
5517
  cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId) || this.cancelled.has(sinkRunId), "cancelled"),
@@ -5481,7 +5546,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
5481
5546
  }), "startAgent")
5482
5547
  };
5483
5548
  try {
5484
- return await (0, import_nestjs_agent_core28.runAgentLoop)({
5549
+ return await (0, import_nestjs_agent_core29.runAgentLoop)({
5485
5550
  ...deps,
5486
5551
  day
5487
5552
  }, {
@@ -5501,15 +5566,15 @@ var InlineAgentRunner = class _InlineAgentRunner {
5501
5566
  }
5502
5567
  };
5503
5568
  InlineAgentRunner = _ts_decorate25([
5504
- (0, import_common25.Injectable)(),
5505
- _ts_param23(0, (0, import_common25.Inject)(import_nestjs_agent_core28.AGENT_DEPS_FACTORY)),
5506
- _ts_param23(1, (0, import_common25.Inject)(import_nestjs_agent_core28.AGENT_STORE)),
5507
- _ts_param23(2, (0, import_common25.Optional)()),
5569
+ (0, import_common26.Injectable)(),
5570
+ _ts_param23(0, (0, import_common26.Inject)(import_nestjs_agent_core29.AGENT_DEPS_FACTORY)),
5571
+ _ts_param23(1, (0, import_common26.Inject)(import_nestjs_agent_core29.AGENT_STORE)),
5572
+ _ts_param23(2, (0, import_common26.Optional)()),
5508
5573
  _ts_metadata24("design:type", Function),
5509
5574
  _ts_metadata24("design:paramtypes", [
5510
5575
  typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
5511
5576
  typeof AgentStore === "undefined" ? Object : AgentStore,
5512
- typeof ChatQueueService === "undefined" ? Object : ChatQueueService
5577
+ typeof ChatQueueService2 === "undefined" ? Object : ChatQueueService2
5513
5578
  ])
5514
5579
  ], InlineAgentRunner);
5515
5580
  function isThreadTurn2(input) {
@@ -5518,7 +5583,7 @@ function isThreadTurn2(input) {
5518
5583
  __name(isThreadTurn2, "isThreadTurn");
5519
5584
 
5520
5585
  // src/skills-config.ts
5521
- var import_nestjs_agent_core29 = require("@dudousxd/nestjs-agent-core");
5586
+ var import_nestjs_agent_core30 = require("@dudousxd/nestjs-agent-core");
5522
5587
  function declaredSkillProvider(declared) {
5523
5588
  return {
5524
5589
  list: /* @__PURE__ */ __name(({ scopes }) => declared.filter((skill) => scopes.includes(skill.scope)).map(({ name, description, scope }) => ({
@@ -5544,7 +5609,7 @@ function resolveSkillsConfig(options, declared) {
5544
5609
  declaredSkillProvider(declared)
5545
5610
  ];
5546
5611
  return {
5547
- provider: providers.length === 1 ? providers[0] : (0, import_nestjs_agent_core29.compositeSkillProvider)(providers),
5612
+ provider: providers.length === 1 ? providers[0] : (0, import_nestjs_agent_core30.compositeSkillProvider)(providers),
5548
5613
  ...options.scopes !== void 0 ? {
5549
5614
  scopes: options.scopes
5550
5615
  } : {},
@@ -5571,11 +5636,11 @@ function _ts_decorate26(decorators, target, key, desc) {
5571
5636
  }
5572
5637
  __name(_ts_decorate26, "_ts_decorate");
5573
5638
  var DEFAULT_PATH = "agent";
5574
- var logger = new import_common26.Logger("AgentModule");
5639
+ var logger = new import_common27.Logger("AgentModule");
5575
5640
  function externalStoreWrapper(modules) {
5576
5641
  for (const module2 of modules.values()) {
5577
5642
  if (module2.metatype === AgentModule) continue;
5578
- const wrapper = module2.providers.get(import_nestjs_agent_core30.AGENT_STORE);
5643
+ const wrapper = module2.providers.get(import_nestjs_agent_core31.AGENT_STORE);
5579
5644
  if (wrapper !== void 0) return wrapper;
5580
5645
  }
5581
5646
  return void 0;
@@ -5606,7 +5671,7 @@ function resolveStore(options, modules) {
5606
5671
  const external = externalStoreWrapper(modules);
5607
5672
  if (external !== void 0) return forwardingStore(external);
5608
5673
  logger.warn("No `store` configured and no store module imported \u2014 using the in-memory store. Threads are lost on restart and not shared between processes: not for production. Pass `store`, or import a store module (e.g. MikroOrmAgentStoreModule.forFeature()).");
5609
- return new import_nestjs_agent_core30.InMemoryAgentStore();
5674
+ return new import_nestjs_agent_core31.InMemoryAgentStore();
5610
5675
  }
5611
5676
  __name(resolveStore, "resolveStore");
5612
5677
  function isQuotaProvider(quota) {
@@ -5622,99 +5687,99 @@ __name(resolveCatalog, "resolveCatalog");
5622
5687
  function sharedProviders(durable) {
5623
5688
  const providers = [
5624
5689
  {
5625
- provide: import_nestjs_agent_core30.AGENT_TOOL_REGISTRY,
5626
- useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core30.ToolRegistry(), "useFactory")
5690
+ provide: import_nestjs_agent_core31.AGENT_TOOL_REGISTRY,
5691
+ useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core31.ToolRegistry(), "useFactory")
5627
5692
  },
5628
5693
  // Starts empty; AgentDiscoveryService populates it from `@Agent`-decorated providers at boot.
5629
5694
  {
5630
- provide: import_nestjs_agent_core30.AGENT_REGISTRY,
5631
- useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core30.AgentRegistry(), "useFactory")
5695
+ provide: import_nestjs_agent_core31.AGENT_REGISTRY,
5696
+ useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core31.AgentRegistry(), "useFactory")
5632
5697
  },
5633
5698
  // A shared, mutable list AgentDiscoveryService fills with `@SystemPromptContributor()` methods.
5634
5699
  {
5635
- provide: import_nestjs_agent_core30.AGENT_PROMPT_CONTRIBUTORS,
5700
+ provide: import_nestjs_agent_core31.AGENT_PROMPT_CONTRIBUTORS,
5636
5701
  useFactory: /* @__PURE__ */ __name(() => [], "useFactory")
5637
5702
  },
5638
5703
  // Likewise for `@Skill`-decorated providers — filled by SkillDiscoveryService at onModuleInit,
5639
5704
  // read lazily by the AGENT_SKILLS provider below (which DI builds before discovery has run).
5640
5705
  {
5641
- provide: import_nestjs_agent_core30.AGENT_SKILL_SOURCES,
5706
+ provide: import_nestjs_agent_core31.AGENT_SKILL_SOURCES,
5642
5707
  useFactory: /* @__PURE__ */ __name(() => [], "useFactory")
5643
5708
  },
5644
5709
  {
5645
5710
  // One resolution, shared by the loop's deps and the listing endpoint: a second one would
5646
5711
  // drift, and a user would be offered a skill the agent cannot reach. `undefined` when the
5647
5712
  // host configured none — which is what keeps the turn's checkpoint sequence unchanged.
5648
- provide: import_nestjs_agent_core30.AGENT_SKILLS,
5713
+ provide: import_nestjs_agent_core31.AGENT_SKILLS,
5649
5714
  useFactory: /* @__PURE__ */ __name((options, declared) => resolveSkillsConfig(options.skills, declared), "useFactory"),
5650
5715
  inject: [
5651
- import_nestjs_agent_core30.AGENT_OPTIONS,
5652
- import_nestjs_agent_core30.AGENT_SKILL_SOURCES
5716
+ import_nestjs_agent_core31.AGENT_OPTIONS,
5717
+ import_nestjs_agent_core31.AGENT_SKILL_SOURCES
5653
5718
  ]
5654
5719
  },
5655
5720
  {
5656
5721
  // One resolution, shared by the loop's deps and the read-back endpoint: a person has to be
5657
5722
  // shown what the model was shown, and two resolutions would eventually disagree about that.
5658
- provide: import_nestjs_agent_core30.AGENT_MEMORY,
5723
+ provide: import_nestjs_agent_core31.AGENT_MEMORY,
5659
5724
  useFactory: /* @__PURE__ */ __name((options) => options.memory, "useFactory"),
5660
5725
  inject: [
5661
- import_nestjs_agent_core30.AGENT_OPTIONS
5726
+ import_nestjs_agent_core31.AGENT_OPTIONS
5662
5727
  ]
5663
5728
  },
5664
5729
  {
5665
- provide: import_nestjs_agent_core30.AGENT_SINK,
5730
+ provide: import_nestjs_agent_core31.AGENT_SINK,
5666
5731
  useFactory: /* @__PURE__ */ __name((options) => options.sink ?? new InProcessTokenStreamSink(), "useFactory"),
5667
5732
  inject: [
5668
- import_nestjs_agent_core30.AGENT_OPTIONS
5733
+ import_nestjs_agent_core31.AGENT_OPTIONS
5669
5734
  ]
5670
5735
  },
5671
5736
  {
5672
- provide: import_nestjs_agent_core30.AGENT_ROLES_POLICY,
5673
- useFactory: /* @__PURE__ */ __name((options) => options.rolesPolicy ?? new import_nestjs_agent_core30.DefaultRolesPolicy(options.defaultRoles), "useFactory"),
5737
+ provide: import_nestjs_agent_core31.AGENT_ROLES_POLICY,
5738
+ useFactory: /* @__PURE__ */ __name((options) => options.rolesPolicy ?? new import_nestjs_agent_core31.DefaultRolesPolicy(options.defaultRoles), "useFactory"),
5674
5739
  inject: [
5675
- import_nestjs_agent_core30.AGENT_OPTIONS
5740
+ import_nestjs_agent_core31.AGENT_OPTIONS
5676
5741
  ]
5677
5742
  },
5678
5743
  {
5679
- provide: import_nestjs_agent_core30.AGENT_ACTOR_RESOLVER,
5744
+ provide: import_nestjs_agent_core31.AGENT_ACTOR_RESOLVER,
5680
5745
  useFactory: /* @__PURE__ */ __name((options) => {
5681
5746
  if (options.actorResolver !== void 0) return options.actorResolver;
5682
5747
  logger.warn("No `actorResolver` configured \u2014 the agent endpoints are PUBLIC: every browser gets its own anonymous identity (an HttpOnly cookie). Set `actorResolver: requestUserActorResolver()` (or your own) to require login.");
5683
5748
  return new AnonymousActorResolver();
5684
5749
  }, "useFactory"),
5685
5750
  inject: [
5686
- import_nestjs_agent_core30.AGENT_OPTIONS
5751
+ import_nestjs_agent_core31.AGENT_OPTIONS
5687
5752
  ]
5688
5753
  },
5689
5754
  {
5690
- provide: import_nestjs_agent_core30.AGENT_MODEL,
5755
+ provide: import_nestjs_agent_core31.AGENT_MODEL,
5691
5756
  useFactory: /* @__PURE__ */ __name((o) => o.model, "useFactory"),
5692
5757
  inject: [
5693
- import_nestjs_agent_core30.AGENT_OPTIONS
5758
+ import_nestjs_agent_core31.AGENT_OPTIONS
5694
5759
  ]
5695
5760
  },
5696
5761
  {
5697
5762
  // `quota` is either a provider of the host's own or ceilings for the built-in ledger one;
5698
5763
  // omitted, the ledger provider still reports usage, with no ceiling to block on.
5699
- provide: import_nestjs_agent_core30.AGENT_QUOTA_PROVIDER,
5764
+ provide: import_nestjs_agent_core31.AGENT_QUOTA_PROVIDER,
5700
5765
  useFactory: /* @__PURE__ */ __name((o, store) => isQuotaProvider(o.quota) ? o.quota : new LedgerQuotaProvider(store, o.quota?.limits, o.quota?.warnAt !== void 0 ? {
5701
5766
  warnAt: o.quota.warnAt
5702
5767
  } : {}), "useFactory"),
5703
5768
  inject: [
5704
- import_nestjs_agent_core30.AGENT_OPTIONS,
5705
- import_nestjs_agent_core30.AGENT_STORE
5769
+ import_nestjs_agent_core31.AGENT_OPTIONS,
5770
+ import_nestjs_agent_core31.AGENT_STORE
5706
5771
  ]
5707
5772
  },
5708
5773
  {
5709
- provide: import_nestjs_agent_core30.AGENT_MODEL_CATALOG,
5774
+ provide: import_nestjs_agent_core31.AGENT_MODEL_CATALOG,
5710
5775
  useFactory: /* @__PURE__ */ __name((o) => resolveCatalog(o), "useFactory"),
5711
5776
  inject: [
5712
- import_nestjs_agent_core30.AGENT_OPTIONS
5777
+ import_nestjs_agent_core31.AGENT_OPTIONS
5713
5778
  ]
5714
5779
  },
5715
5780
  AgentDepsFactory2,
5716
5781
  {
5717
- provide: import_nestjs_agent_core30.AGENT_DEPS_FACTORY,
5782
+ provide: import_nestjs_agent_core31.AGENT_DEPS_FACTORY,
5718
5783
  useExisting: AgentDepsFactory2
5719
5784
  },
5720
5785
  // Populates the registry + contributors (onModuleInit) BEFORE AiToolDiscoveryService synthesizes
@@ -5724,28 +5789,32 @@ function sharedProviders(durable) {
5724
5789
  SkillDiscoveryService,
5725
5790
  // The thread message queue — every surface, since both runners and the durable workflow settle
5726
5791
  // into it, and the chat routes enqueue into it.
5727
- ChatQueueService,
5792
+ ChatQueueService2,
5793
+ {
5794
+ provide: AGENT_CHAT_QUEUE,
5795
+ useExisting: ChatQueueService2
5796
+ },
5728
5797
  InlineAgentRunner,
5729
5798
  AgentService,
5730
5799
  // Bound ALWAYS (durable or inline) — the console's cross-thread approvals inbox routes decisions
5731
5800
  // through AgentService.signalToolCall, which reaches whichever AGENT_RUNNER is bound above.
5732
5801
  AgentApprovalPortAdapter,
5733
5802
  {
5734
- provide: import_nestjs_agent_core30.AGENT_APPROVAL_PORT,
5803
+ provide: import_nestjs_agent_core31.AGENT_APPROVAL_PORT,
5735
5804
  useExisting: AgentApprovalPortAdapter
5736
5805
  }
5737
5806
  ];
5738
5807
  providers.push({
5739
- provide: import_nestjs_agent_core30.AGENT_STORE,
5808
+ provide: import_nestjs_agent_core31.AGENT_STORE,
5740
5809
  useFactory: /* @__PURE__ */ __name((o, modules) => resolveStore(o, modules), "useFactory"),
5741
5810
  inject: [
5742
- import_nestjs_agent_core30.AGENT_OPTIONS,
5811
+ import_nestjs_agent_core31.AGENT_OPTIONS,
5743
5812
  import_core4.ModulesContainer
5744
5813
  ]
5745
5814
  });
5746
5815
  if (durable) {
5747
5816
  providers.push({
5748
- provide: import_nestjs_agent_core30.AGENT_RUNNER,
5817
+ provide: import_nestjs_agent_core31.AGENT_RUNNER,
5749
5818
  useFactory: /* @__PURE__ */ __name((durableRunner) => {
5750
5819
  if (durableRunner === void 0) {
5751
5820
  throw new Error("AgentModule.forRoot({ durable: true }) requires importing AgentDurableModule from '@dudousxd/nestjs-agent/durable' (alongside a configured DurableModule). It was not found.");
@@ -5754,14 +5823,14 @@ function sharedProviders(durable) {
5754
5823
  }, "useFactory"),
5755
5824
  inject: [
5756
5825
  {
5757
- token: import_nestjs_agent_core30.AGENT_DURABLE_RUNNER,
5826
+ token: import_nestjs_agent_core31.AGENT_DURABLE_RUNNER,
5758
5827
  optional: true
5759
5828
  }
5760
5829
  ]
5761
5830
  });
5762
5831
  } else {
5763
5832
  providers.push({
5764
- provide: import_nestjs_agent_core30.AGENT_RUNNER,
5833
+ provide: import_nestjs_agent_core31.AGENT_RUNNER,
5765
5834
  useExisting: InlineAgentRunner
5766
5835
  });
5767
5836
  }
@@ -5770,25 +5839,26 @@ function sharedProviders(durable) {
5770
5839
  __name(sharedProviders, "sharedProviders");
5771
5840
  function exportsFor() {
5772
5841
  return [
5773
- import_nestjs_agent_core30.AGENT_OPTIONS,
5774
- import_nestjs_agent_core30.AGENT_TOOL_REGISTRY,
5775
- import_nestjs_agent_core30.AGENT_REGISTRY,
5776
- import_nestjs_agent_core30.AGENT_SINK,
5777
- import_nestjs_agent_core30.AGENT_ROLES_POLICY,
5778
- import_nestjs_agent_core30.AGENT_ACTOR_RESOLVER,
5779
- import_nestjs_agent_core30.AGENT_MODEL,
5780
- import_nestjs_agent_core30.AGENT_STORE,
5781
- import_nestjs_agent_core30.AGENT_MODEL_CATALOG,
5782
- import_nestjs_agent_core30.AGENT_QUOTA_PROVIDER,
5783
- import_nestjs_agent_core30.AGENT_PROMPT_CONTRIBUTORS,
5784
- import_nestjs_agent_core30.AGENT_SKILLS,
5785
- import_nestjs_agent_core30.AGENT_MEMORY,
5786
- import_nestjs_agent_core30.AGENT_DEPS_FACTORY,
5842
+ import_nestjs_agent_core31.AGENT_OPTIONS,
5843
+ import_nestjs_agent_core31.AGENT_TOOL_REGISTRY,
5844
+ import_nestjs_agent_core31.AGENT_REGISTRY,
5845
+ import_nestjs_agent_core31.AGENT_SINK,
5846
+ import_nestjs_agent_core31.AGENT_ROLES_POLICY,
5847
+ import_nestjs_agent_core31.AGENT_ACTOR_RESOLVER,
5848
+ import_nestjs_agent_core31.AGENT_MODEL,
5849
+ import_nestjs_agent_core31.AGENT_STORE,
5850
+ import_nestjs_agent_core31.AGENT_MODEL_CATALOG,
5851
+ import_nestjs_agent_core31.AGENT_QUOTA_PROVIDER,
5852
+ import_nestjs_agent_core31.AGENT_PROMPT_CONTRIBUTORS,
5853
+ import_nestjs_agent_core31.AGENT_SKILLS,
5854
+ import_nestjs_agent_core31.AGENT_MEMORY,
5855
+ import_nestjs_agent_core31.AGENT_DEPS_FACTORY,
5787
5856
  AgentDepsFactory2,
5788
5857
  AgentService,
5789
- ChatQueueService,
5858
+ ChatQueueService2,
5859
+ AGENT_CHAT_QUEUE,
5790
5860
  InlineAgentRunner,
5791
- import_nestjs_agent_core30.AGENT_APPROVAL_PORT
5861
+ import_nestjs_agent_core31.AGENT_APPROVAL_PORT
5792
5862
  ];
5793
5863
  }
5794
5864
  __name(exportsFor, "exportsFor");
@@ -5852,7 +5922,7 @@ var AgentModule = class _AgentModule {
5852
5922
  controllers: controllersForSurface(options.surface),
5853
5923
  providers: [
5854
5924
  {
5855
- provide: import_nestjs_agent_core30.AGENT_OPTIONS,
5925
+ provide: import_nestjs_agent_core31.AGENT_OPTIONS,
5856
5926
  useValue: options
5857
5927
  },
5858
5928
  ...sharedProviders(options.durable ?? false),
@@ -5875,7 +5945,7 @@ var AgentModule = class _AgentModule {
5875
5945
  controllers: controllersForSurface(options.surface),
5876
5946
  providers: [
5877
5947
  {
5878
- provide: import_nestjs_agent_core30.AGENT_OPTIONS,
5948
+ provide: import_nestjs_agent_core31.AGENT_OPTIONS,
5879
5949
  // Stamp the STATIC wiring flags onto the factory result: `durable`/`surface` are
5880
5950
  // authoritative on the async config object (they decided the actual wiring above), and
5881
5951
  // the durable module reads `durable` back off AGENT_OPTIONS. `surface` isn't read back by
@@ -5897,8 +5967,8 @@ var AgentModule = class _AgentModule {
5897
5967
  }
5898
5968
  };
5899
5969
  AgentModule = _ts_decorate26([
5900
- (0, import_common26.Global)(),
5901
- (0, import_common26.Module)({})
5970
+ (0, import_common27.Global)(),
5971
+ (0, import_common27.Module)({})
5902
5972
  ], AgentModule);
5903
5973
 
5904
5974
  // src/durable/agent-durable.ts