@dudousxd/nestjs-agent 1.39.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +14 -7
  2. package/dist/a2ui/index.cjs +1 -0
  3. package/dist/a2ui/index.cjs.map +1 -1
  4. package/dist/a2ui/index.d.cts +3 -2
  5. package/dist/a2ui/index.d.ts +3 -2
  6. package/dist/a2ui/index.js +2 -1
  7. package/dist/a2ui/index.js.map +1 -1
  8. package/dist/{chat-queue.service-YjiKVTKE.d.ts → chat-queue.service-BjPCw4Pf.d.ts} +104 -43
  9. package/dist/{chat-queue.service-fopUN313.d.cts → chat-queue.service-C49HIuEV.d.cts} +104 -43
  10. package/dist/durable/index.cjs +13572 -1754
  11. package/dist/durable/index.cjs.map +1 -1
  12. package/dist/durable/index.d.cts +6 -6
  13. package/dist/durable/index.d.ts +6 -6
  14. package/dist/durable/index.js +12228 -390
  15. package/dist/durable/index.js.map +1 -1
  16. package/dist/genui/index.cjs.map +1 -1
  17. package/dist/genui/index.d.cts +4 -6
  18. package/dist/genui/index.d.ts +4 -6
  19. package/dist/genui/index.js.map +1 -1
  20. package/dist/{index-BJFM1tG8.d.cts → index-BBkyvNUi.d.cts} +1 -1
  21. package/dist/{index-De98CGXa.d.ts → index-CRCbsO6E.d.ts} +1 -1
  22. package/dist/index.cjs +12408 -450
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +318 -18
  25. package/dist/index.d.ts +318 -18
  26. package/dist/index.js +12313 -346
  27. package/dist/index.js.map +1 -1
  28. package/dist/media/index.cjs +4 -9
  29. package/dist/media/index.cjs.map +1 -1
  30. package/dist/media/index.d.cts +14 -3
  31. package/dist/media/index.d.ts +14 -3
  32. package/dist/media/index.js +6 -11
  33. package/dist/media/index.js.map +1 -1
  34. package/dist/workflows/index.cjs +1496 -0
  35. package/dist/workflows/index.cjs.map +1 -0
  36. package/dist/workflows/index.d.cts +158 -0
  37. package/dist/workflows/index.d.ts +158 -0
  38. package/dist/workflows/index.js +1464 -0
  39. package/dist/workflows/index.js.map +1 -0
  40. package/package.json +39 -8
@@ -0,0 +1,1496 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/workflows/index.ts
22
+ var workflows_exports = {};
23
+ __export(workflows_exports, {
24
+ AGENT_REPLY: () => AGENT_REPLY,
25
+ AGENT_RUN_SEGMENT_WORKFLOW: () => AGENT_RUN_SEGMENT_WORKFLOW,
26
+ AGENT_RUN_WORKFLOW: () => AGENT_RUN_WORKFLOW,
27
+ AgentRunFlow: () => AgentRunFlow,
28
+ AgentRunSegmentFlow: () => AgentRunSegmentFlow,
29
+ AgentWorkflowsModule: () => AgentWorkflowsModule,
30
+ WorkflowsAgentRunner: () => WorkflowsAgentRunner,
31
+ replyKey: () => replyKey
32
+ });
33
+ module.exports = __toCommonJS(workflows_exports);
34
+
35
+ // src/workflows/agent-workflows.module.ts
36
+ var import_nestjs_agent_core8 = require("@dudousxd/nestjs-agent-core");
37
+ var import_common3 = require("@nestjs/common");
38
+
39
+ // src/workflows/agent-run.flow.ts
40
+ var import_workflows4 = require("@nestjs/workflows");
41
+
42
+ // src/workflows/agent-turn.executor.ts
43
+ var import_nestjs_agent_core5 = require("@dudousxd/nestjs-agent-core");
44
+ var import_common = require("@nestjs/common");
45
+ var import_workflows3 = require("@nestjs/workflows");
46
+
47
+ // src/agent-deps.ts
48
+ function utcDay(date = /* @__PURE__ */ new Date()) {
49
+ return date.toISOString().slice(0, 10);
50
+ }
51
+ __name(utcDay, "utcDay");
52
+ function childSinkWriter(writer) {
53
+ return {
54
+ write: /* @__PURE__ */ __name((chunk) => writer.write(chunk), "write"),
55
+ // The top-level run owns end/fail — but what the child wrote must not be held back past it.
56
+ end: /* @__PURE__ */ __name(async () => {
57
+ await writer.flush?.();
58
+ }, "end"),
59
+ fail: /* @__PURE__ */ __name(async () => {
60
+ await writer.flush?.();
61
+ }, "fail"),
62
+ flush: /* @__PURE__ */ __name(async () => {
63
+ await writer.flush?.();
64
+ }, "flush")
65
+ };
66
+ }
67
+ __name(childSinkWriter, "childSinkWriter");
68
+
69
+ // src/agent.options.ts
70
+ function durableEngineOf(durable) {
71
+ if (durable === void 0 || durable === false) return void 0;
72
+ if (durable === true) return "workflows";
73
+ return durable.engine ?? "workflows";
74
+ }
75
+ __name(durableEngineOf, "durableEngineOf");
76
+
77
+ // src/queue/chat-queue.token.ts
78
+ var AGENT_CHAT_QUEUE = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:chat-queue");
79
+
80
+ // src/runner/agent-step-bodies.ts
81
+ var import_nestjs_agent_core = require("@dudousxd/nestjs-agent-core");
82
+ var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
83
+ var import_nestjs_agent_core3 = require("@dudousxd/nestjs-agent-core");
84
+ var import_genui = require("@dudousxd/nestjs-agent-core/genui");
85
+ async function runLlmStep(factory, input, options = {}) {
86
+ const deps = factory.forAgent(input.agentName);
87
+ const tools = (0, import_nestjs_agent_core3.withMemoryTool)({
88
+ tools: (0, import_nestjs_agent_core3.withSkillTool)({
89
+ tools: (0, import_nestjs_agent_core3.withAskTool)({
90
+ tools: await deps.registry.definitionsFor(
91
+ input.actor,
92
+ deps.rolesPolicy,
93
+ // The persona narrowing the loop journaled in `persona:resolve` rides the envelope:
94
+ // this worker's own persona config may already say something else.
95
+ (0, import_nestjs_agent_core3.intersectAllowLists)(deps.toolAllowList, input.personaAllowedTools),
96
+ {
97
+ ...input.threadId !== void 0 ? {
98
+ threadId: input.threadId
99
+ } : {},
100
+ ...input.preflightContext?.uiCapabilities !== void 0 ? {
101
+ uiCapabilities: input.preflightContext.uiCapabilities
102
+ } : {},
103
+ channel: (0, import_genui.turnChannel)(input.preflightContext?.pageContext),
104
+ ...input.agentName !== void 0 ? {
105
+ agentName: input.agentName
106
+ } : {}
107
+ }
108
+ ),
109
+ ask: deps.ask
110
+ }),
111
+ enabled: deps.skills !== void 0 && input.builtins?.skills !== false
112
+ }),
113
+ enabled: deps.memory?.provider.write !== void 0 && input.builtins?.memory !== false
114
+ });
115
+ const buffer = input.bufferOutput === true ? (0, import_nestjs_agent_core3.createFrameBuffer)() : void 0;
116
+ let writer;
117
+ let firstText;
118
+ if (buffer !== void 0) {
119
+ writer = buffer.writer;
120
+ } else {
121
+ const opened = await deps.sink.open(input.sinkRunId);
122
+ firstText = (0, import_nestjs_agent_core3.observeFirstText)(input.childSink ? childSinkWriter(opened) : opened);
123
+ writer = firstText.writer;
124
+ }
125
+ const announced = (0, import_nestjs_agent_core3.announcedToolCalls)(writer);
126
+ const previews = (0, import_nestjs_agent_core3.previewToolInputs)(announced.writer, (0, import_nestjs_agent_core3.registryInputPreviews)(deps.registry, tools, {
127
+ actor: input.actor,
128
+ ...input.threadId !== void 0 ? {
129
+ threadId: input.threadId
130
+ } : {},
131
+ ...input.agentName !== void 0 ? {
132
+ agentName: input.agentName
133
+ } : {},
134
+ ...input.preflightContext?.uiCapabilities !== void 0 ? {
135
+ uiCapabilities: input.preflightContext.uiCapabilities
136
+ } : {},
137
+ channel: (0, import_genui.turnChannel)(input.preflightContext?.pageContext)
138
+ }));
139
+ const frames = (0, import_nestjs_agent_core3.observeTurnFrames)(previews.writer);
140
+ const turn = (0, import_nestjs_agent_core3.withTurnFrames)(await (0, import_nestjs_agent_core3.traceLlmTurn)(input.runId, input.step, () => deps.model.runTurn({
141
+ system: input.system,
142
+ messages: input.messages,
143
+ tools,
144
+ sink: frames.writer,
145
+ ...input.model !== void 0 ? {
146
+ model: input.model
147
+ } : {},
148
+ ...options.abortSignal !== void 0 ? {
149
+ abortSignal: options.abortSignal
150
+ } : {}
151
+ })), frames.summary());
152
+ const stamped = (0, import_nestjs_agent_core3.stampToolKinds)(turn, deps);
153
+ await announced.announceRest(stamped.toolCalls, tools);
154
+ const allowedTools = (0, import_nestjs_agent_core3.intersectAllowLists)(deps.toolAllowList, input.personaAllowedTools);
155
+ for (const call of stamped.toolCalls) {
156
+ if (call.kind !== "action") continue;
157
+ try {
158
+ const context = input.preflightContext ?? {
159
+ actor: input.actor,
160
+ threadId: input.threadId ?? "",
161
+ runId: input.runId,
162
+ requestId: input.runId,
163
+ ...input.agentName !== void 0 ? {
164
+ agentName: input.agentName
165
+ } : {}
166
+ };
167
+ if (input.actionApprovalMode === "independent") {
168
+ const spec = deps.registry.spec(call.name);
169
+ call.actionApproval = await (0, import_nestjs_agent_core2.resolveActionProposalApproval)({
170
+ actor: input.actor,
171
+ store: deps.store,
172
+ tool: {
173
+ name: call.name,
174
+ kind: "action",
175
+ ...spec !== void 0 ? {
176
+ spec
177
+ } : {}
178
+ },
179
+ thread: {
180
+ threadId: context.threadId,
181
+ runId: input.runId,
182
+ ...input.agentName !== void 0 ? {
183
+ agentName: input.agentName
184
+ } : {}
185
+ },
186
+ ...deps.approvalPolicy !== void 0 ? {
187
+ policy: deps.approvalPolicy
188
+ } : {}
189
+ });
190
+ }
191
+ if (call.actionApproval?.mode === "ask") {
192
+ call.prepared = await (0, import_nestjs_agent_core2.prepareActionProposal)(deps.registry, call.name, call.input, {
193
+ ...(0, import_nestjs_agent_core3.toolCallContext)(context, call.id),
194
+ emitUi: (0, import_nestjs_agent_core3.createNoopEmitUi)(call.id)
195
+ }, deps.rolesPolicy, allowedTools === void 0 ? {} : {
196
+ allowedTools
197
+ });
198
+ call.preflight = call.prepared.preflight;
199
+ } else {
200
+ call.preflight = await deps.registry.prepare(call.name, call.input, {
201
+ ...(0, import_nestjs_agent_core3.toolCallContext)(context, call.id),
202
+ emitUi: (0, import_nestjs_agent_core3.createNoopEmitUi)(call.id)
203
+ }, deps.rolesPolicy, allowedTools === void 0 ? {} : {
204
+ allowedTools
205
+ });
206
+ }
207
+ } catch (error) {
208
+ if ((0, import_nestjs_agent_core3.isControlFlowSignal)(error) || (0, import_nestjs_agent_core3.isReplayIntegrityError)(error)) throw error;
209
+ call.preflight = {
210
+ status: "failed",
211
+ error: error instanceof Error ? error.message : String(error)
212
+ };
213
+ }
214
+ }
215
+ const shown = previews.shown();
216
+ const previewed = shown.length > 0 ? {
217
+ ...stamped,
218
+ previews: shown
219
+ } : stamped;
220
+ const firstTextAt = firstText?.firstTextAt();
221
+ if (buffer !== void 0) {
222
+ return {
223
+ ...previewed,
224
+ bufferedFrames: buffer.frames()
225
+ };
226
+ }
227
+ return firstTextAt === void 0 ? previewed : {
228
+ ...previewed,
229
+ firstTextAt
230
+ };
231
+ }
232
+ __name(runLlmStep, "runLlmStep");
233
+ async function runToolStep(factory, input, options = {}) {
234
+ const deps = factory.forAgent(input.ctx.agentName);
235
+ if (deps.registry.spec(input.toolName)?.kind === "action" && input.toolType !== "action") {
236
+ 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`);
237
+ }
238
+ const sinkRunId = input.sinkRunId;
239
+ let opened;
240
+ const ui = (0, import_nestjs_agent_core.createNegotiatedUiCollector)(input.toolCallId, input.ctx, deps.resolveUiCatalog, sinkRunId === void 0 ? void 0 : async (event) => {
241
+ opened ??= Promise.resolve(deps.sink.open(sinkRunId)).then((writer) => input.childSink === true ? childSinkWriter(writer) : writer);
242
+ await (await opened).write((0, import_nestjs_agent_core3.encodeStreamEvent)(event));
243
+ });
244
+ const ctx = {
245
+ ...(0, import_nestjs_agent_core3.toolCallContext)(input.ctx, input.toolCallId),
246
+ emitUi: ui.emit,
247
+ ...options.abortSignal !== void 0 ? {
248
+ abortSignal: options.abortSignal
249
+ } : {}
250
+ };
251
+ const localClassify = deps.toolTransientRetry !== false ? deps.toolTransientRetry?.classify : void 0;
252
+ const transientRetry = input.transientRetry === false ? false : {
253
+ attempts: input.transientRetry.attempts,
254
+ backoffMs: input.transientRetry.backoffMs,
255
+ ...localClassify !== void 0 ? {
256
+ classify: localClassify
257
+ } : {}
258
+ };
259
+ const allowedTools = (0, import_nestjs_agent_core3.intersectAllowLists)(deps.toolAllowList, input.allowedTools === void 0 ? void 0 : [
260
+ ...input.allowedTools
261
+ ]);
262
+ let output;
263
+ const toolStartedAt = Date.now();
264
+ try {
265
+ output = await (0, import_nestjs_agent_core3.traceToolExecution)(input.ctx.runId, {
266
+ toolCallId: input.toolCallId,
267
+ toolName: input.toolName,
268
+ toolType: input.toolType
269
+ }, () => (0, import_nestjs_agent_core3.invokeWithTransientRetry)(() => {
270
+ ui.restart();
271
+ const invocation = deps.registry.invoke(input.toolName, input.input, ctx, deps.rolesPolicy, allowedTools === void 0 ? {} : {
272
+ allowedTools
273
+ });
274
+ return input.timeoutMs !== void 0 ? (0, import_nestjs_agent_core3.withToolTimeout)(invocation, input.timeoutMs, input.toolName) : invocation;
275
+ }, transientRetry, {
276
+ onRetry: /* @__PURE__ */ __name((attempt, error) => {
277
+ (0, import_nestjs_agent_core3.publishAgentToolRetry)({
278
+ toolName: input.toolName,
279
+ toolCallId: input.toolCallId,
280
+ attempt,
281
+ message: error instanceof Error ? error.message : String(error)
282
+ });
283
+ }, "onRetry")
284
+ }));
285
+ } catch (error) {
286
+ if (error instanceof Error && error.name === "ToolPreflightDeniedError") {
287
+ return (0, import_nestjs_agent_core3.wrapToolPreflightDenied)(error.message);
288
+ }
289
+ throw error;
290
+ }
291
+ const executionMs = Date.now() - toolStartedAt;
292
+ output = await (0, import_nestjs_agent_core3.withChannelDelivery)(deps, input.ctx, output, ui.components());
293
+ return input.collectUi === true ? (0, import_nestjs_agent_core3.wrapToolStepOutput)(output, ui.components(), ui.text(), executionMs) : output;
294
+ }
295
+ __name(runToolStep, "runToolStep");
296
+
297
+ // src/workflows/agent-reply.signal.ts
298
+ var import_workflows = require("@nestjs/workflows");
299
+ var AGENT_REPLY = new import_workflows.WorkflowSignal("aviary.agent.reply");
300
+ function replyKey(runId, toolCallId) {
301
+ return `${runId}:${toolCallId}`;
302
+ }
303
+ __name(replyKey, "replyKey");
304
+
305
+ // src/workflows/turn-journal.ts
306
+ var import_nestjs_agent_core4 = require("@dudousxd/nestjs-agent-core");
307
+ var import_workflows2 = require("@nestjs/workflows");
308
+ var CONTROL_FLOW_SIGNAL = /* @__PURE__ */ Symbol.for("aviary:durable:control-flow");
309
+ function markControlFlow(error) {
310
+ if ((0, import_workflows2.isWorkflowInterrupt)(error) && typeof error === "object" && error !== null) {
311
+ error[CONTROL_FLOW_SIGNAL] = true;
312
+ }
313
+ return error;
314
+ }
315
+ __name(markControlFlow, "markControlFlow");
316
+ var SegmentBoundary = class extends Error {
317
+ static {
318
+ __name(this, "SegmentBoundary");
319
+ }
320
+ constructor() {
321
+ super("The turn goes on in a child workflow instance");
322
+ this.name = "SegmentBoundary";
323
+ this[CONTROL_FLOW_SIGNAL] = true;
324
+ }
325
+ };
326
+ function isEngineControlFlow(error) {
327
+ return (0, import_workflows2.isWorkflowInterrupt)(error) || error instanceof SegmentBoundary;
328
+ }
329
+ __name(isEngineControlFlow, "isEngineControlFlow");
330
+ function serializeTurnError(error) {
331
+ if (!(error instanceof Error)) {
332
+ return {
333
+ name: "Error",
334
+ message: String(error)
335
+ };
336
+ }
337
+ const props = {};
338
+ for (const [key, value] of Object.entries(error)) {
339
+ if (key === "name" || key === "message" || key === "stack") continue;
340
+ try {
341
+ const json = JSON.stringify(value);
342
+ if (json !== void 0) props[key] = JSON.parse(json);
343
+ } catch {
344
+ }
345
+ }
346
+ return {
347
+ name: error.name,
348
+ message: error.message,
349
+ ...Object.keys(props).length > 0 ? {
350
+ props
351
+ } : {}
352
+ };
353
+ }
354
+ __name(serializeTurnError, "serializeTurnError");
355
+ function stepFailureCause(error) {
356
+ const cause = error.cause;
357
+ if (typeof cause === "object" && cause !== null) {
358
+ const { name, message } = cause;
359
+ if (typeof message === "string") {
360
+ return {
361
+ name: typeof name === "string" ? name : "Error",
362
+ message
363
+ };
364
+ }
365
+ }
366
+ if (cause === void 0 || cause === null) return {
367
+ name: "Error",
368
+ message: error.message
369
+ };
370
+ return {
371
+ name: "Error",
372
+ message: typeof cause === "string" ? cause : safeString(cause)
373
+ };
374
+ }
375
+ __name(stepFailureCause, "stepFailureCause");
376
+ function safeString(value) {
377
+ try {
378
+ return JSON.stringify(value) ?? String(value);
379
+ } catch {
380
+ return String(value);
381
+ }
382
+ }
383
+ __name(safeString, "safeString");
384
+ var KNOWN_ERRORS = {
385
+ QuotaExceededError: import_nestjs_agent_core4.QuotaExceededError,
386
+ RunCancelledError: import_nestjs_agent_core4.RunCancelledError,
387
+ OutputRejectedError: import_nestjs_agent_core4.OutputRejectedError,
388
+ StructuredOutputError: import_nestjs_agent_core4.StructuredOutputError
389
+ };
390
+ function rebuildTurnError(serialized) {
391
+ const prototype = KNOWN_ERRORS[serialized.name]?.prototype ?? Error.prototype;
392
+ const error = Object.create(prototype);
393
+ Object.assign(error, serialized.props ?? {});
394
+ Object.defineProperty(error, "name", {
395
+ value: serialized.name,
396
+ writable: true,
397
+ configurable: true
398
+ });
399
+ Object.defineProperty(error, "message", {
400
+ value: serialized.message,
401
+ writable: true,
402
+ configurable: true
403
+ });
404
+ Object.defineProperty(error, "stack", {
405
+ value: `${serialized.name}: ${serialized.message}`,
406
+ writable: true,
407
+ configurable: true
408
+ });
409
+ return error;
410
+ }
411
+ __name(rebuildTurnError, "rebuildTurnError");
412
+ var TurnJournal = class {
413
+ static {
414
+ __name(this, "TurnJournal");
415
+ }
416
+ counts = /* @__PURE__ */ new Map();
417
+ /** Every operation's outcome so far: the carried ones, then this instance's. */
418
+ outcomes;
419
+ /** Model calls this instance made itself (not carried). */
420
+ liveModelCalls = 0;
421
+ constructor(carried = {}) {
422
+ this.outcomes = {
423
+ ...carried
424
+ };
425
+ }
426
+ /** `base` the first time, `base#2` the second, ... */
427
+ unique(base) {
428
+ const count = (this.counts.get(base) ?? 0) + 1;
429
+ this.counts.set(base, count);
430
+ return count === 1 ? base : `${base}#${count}`;
431
+ }
432
+ /** Was `name` carried from an earlier segment, or already settled in this one? */
433
+ has(name) {
434
+ return name in this.outcomes;
435
+ }
436
+ /**
437
+ * Run `live` (a `ctx` operation) once per run: a name an earlier segment settled answers from
438
+ * `carried`. A failure is recorded too, so a later segment replays it as the same failure; the
439
+ * engine's own control flow is not.
440
+ */
441
+ async op(name, live) {
442
+ const known = this.outcomes[name];
443
+ if (known !== void 0) {
444
+ if ("e" in known) throw rebuildTurnError(known.e);
445
+ return known.v;
446
+ }
447
+ try {
448
+ const value = await live();
449
+ this.outcomes[name] = value === void 0 ? {} : {
450
+ v: value
451
+ };
452
+ return value;
453
+ } catch (error) {
454
+ if (isEngineControlFlow(error)) throw markControlFlow(error);
455
+ this.outcomes[name] = {
456
+ e: serializeTurnError(error)
457
+ };
458
+ throw error;
459
+ }
460
+ }
461
+ };
462
+
463
+ // src/workflows/agent-turn.executor.ts
464
+ function _ts_decorate(decorators, target, key, desc) {
465
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
466
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
467
+ r = Reflect.decorate(decorators, target, key, desc);
468
+ } else {
469
+ for (var i = decorators.length - 1; i >= 0; i--) {
470
+ if (d = decorators[i]) {
471
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
472
+ }
473
+ }
474
+ }
475
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
476
+ }
477
+ __name(_ts_decorate, "_ts_decorate");
478
+ function _ts_metadata(metadataKey, metadataValue) {
479
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
480
+ return Reflect.metadata(metadataKey, metadataValue);
481
+ }
482
+ }
483
+ __name(_ts_metadata, "_ts_metadata");
484
+ function _ts_param(paramIndex, decorator) {
485
+ return function(target, key) {
486
+ decorator(target, key, paramIndex);
487
+ };
488
+ }
489
+ __name(_ts_param, "_ts_param");
490
+ var AGENT_RUN_WORKFLOW = "aviary.agent.run";
491
+ var AGENT_RUN_SEGMENT_WORKFLOW = "aviary.agent.run.segment";
492
+ var DEFAULT_STEPS_PER_INSTANCE = 10;
493
+ var SegmentFailed = class SegmentFailed2 extends Error {
494
+ static {
495
+ __name(this, "SegmentFailed");
496
+ }
497
+ cause;
498
+ constructor(cause) {
499
+ super(cause.message), this.cause = cause;
500
+ this.name = "SegmentFailed";
501
+ }
502
+ };
503
+ function isConfigurationError(error) {
504
+ return error instanceof Error && (error.name === "AiConfigurationError" || error.name === "AgentConfigurationError");
505
+ }
506
+ __name(isConfigurationError, "isConfigurationError");
507
+ function isFatalDefinitionError(error) {
508
+ return (0, import_nestjs_agent_core5.isReplayIntegrityError)(error) || error instanceof Error && (error.name === "WorkflowDefinitionError" || error.name === "WorkflowJournalLimitError");
509
+ }
510
+ __name(isFatalDefinitionError, "isFatalDefinitionError");
511
+ var AgentTurnExecutor = class {
512
+ static {
513
+ __name(this, "AgentTurnExecutor");
514
+ }
515
+ factory;
516
+ store;
517
+ queue;
518
+ client;
519
+ workflowsOptions;
520
+ logger = new import_common.Logger("AgentRunFlow");
521
+ stepsPerInstance;
522
+ constructor(factory, store, options, queue, client, workflowsOptions) {
523
+ this.factory = factory;
524
+ this.store = store;
525
+ this.queue = queue;
526
+ this.client = client;
527
+ this.workflowsOptions = workflowsOptions;
528
+ const durable = options?.durable;
529
+ const configured = durableEngineOf(durable) === "workflows" && typeof durable === "object" ? durable.stepsPerInstance : void 0;
530
+ this.stepsPerInstance = configured !== void 0 && Number.isInteger(configured) && configured > 0 ? configured : DEFAULT_STEPS_PER_INSTANCE;
531
+ }
532
+ /** A turn from its first instance. */
533
+ run(ctx, input) {
534
+ return this.execute(ctx, {
535
+ input,
536
+ runId: ctx.workflowId,
537
+ segment: 0,
538
+ carried: {}
539
+ });
540
+ }
541
+ async execute(ctx, segment) {
542
+ const { input, runId } = segment;
543
+ const journal = new TurnJournal(segment.carried);
544
+ const day = input.day ?? utcDay();
545
+ const deps = this.factory.forAgent(input.agentName);
546
+ const sinkRunId = input.sinkRunId ?? runId;
547
+ const childSink = input.sinkRunId !== void 0;
548
+ const originals = /* @__PURE__ */ new Map();
549
+ const pending = /* @__PURE__ */ new Map();
550
+ const showPending = /* @__PURE__ */ __name(() => ctx.setStatus(pending.size > 0 ? {
551
+ pendingReplies: [
552
+ ...pending.values()
553
+ ]
554
+ } : null), "showPending");
555
+ const checkpoint = /* @__PURE__ */ __name((name, fn) => journal.op(name, async () => {
556
+ const envelope = await this.ctxCall(() => ctx.step(name, async () => {
557
+ try {
558
+ const value = await fn();
559
+ return value === void 0 ? {} : {
560
+ v: value
561
+ };
562
+ } catch (error) {
563
+ originals.set(name, error);
564
+ return {
565
+ e: serializeTurnError(error)
566
+ };
567
+ }
568
+ }));
569
+ if ("e" in envelope) {
570
+ throw originals.get(name) ?? rebuildTurnError(envelope.e);
571
+ }
572
+ return envelope.v;
573
+ }), "checkpoint");
574
+ const step = /* @__PURE__ */ __name((name, fn) => checkpoint(journal.unique(name), fn), "step");
575
+ const awaitReply = /* @__PURE__ */ __name(async (call, timeoutMs) => {
576
+ const name = journal.unique(`reply:${call.id}`);
577
+ pending.set(call.id, {
578
+ key: replyKey(runId, call.id),
579
+ runId,
580
+ toolCallId: call.id,
581
+ toolName: call.toolName,
582
+ kind: call.kind
583
+ });
584
+ showPending();
585
+ const reply = await journal.op(name, () => this.ctxCall(() => ctx.waitForSignal(name, AGENT_REPLY, {
586
+ key: replyKey(runId, call.id),
587
+ ...timeoutMs !== void 0 ? {
588
+ timeout: timeoutMs
589
+ } : {}
590
+ })));
591
+ pending.delete(call.id);
592
+ showPending();
593
+ return reply;
594
+ }, "awaitReply");
595
+ const chainBelow = [
596
+ ...input.delegationPath ?? [],
597
+ ...input.agentName !== void 0 ? [
598
+ input.agentName
599
+ ] : []
600
+ ];
601
+ const subThread = /* @__PURE__ */ __name((agentName) => step(`subthread:${agentName}`, async () => {
602
+ const thread = await this.store.createThread({
603
+ actor: input.actor,
604
+ transient: true
605
+ });
606
+ return thread.id;
607
+ }), "subThread");
608
+ if (input.sinkRunId !== void 0 || input.deliverTo !== void 0) {
609
+ await step("activate", () => this.store.setActiveStream(input.threadId, runId));
610
+ }
611
+ const hooks = {
612
+ runId,
613
+ queueMs: /* @__PURE__ */ __name(async () => {
614
+ const status = await this.client?.getStatus(runId);
615
+ if (status === void 0 || status === null) return void 0;
616
+ const now = this.workflowsOptions?.clock?.now() ?? Date.now();
617
+ const waited = now - status.createdAt;
618
+ return Number.isFinite(waited) && waited >= 0 ? waited : void 0;
619
+ }, "queueMs"),
620
+ openSink: /* @__PURE__ */ __name(async () => {
621
+ if (childSink) {
622
+ return childSinkWriter(await deps.sink.open(sinkRunId));
623
+ }
624
+ const writer = await deps.sink.open(runId);
625
+ return {
626
+ write: /* @__PURE__ */ __name((chunk) => writer.write(chunk), "write"),
627
+ fail: /* @__PURE__ */ __name((failure) => writer.fail(failure), "fail"),
628
+ end: /* @__PURE__ */ __name(async () => {
629
+ const frame = await this.advanceQueue(ctx, step, journal, runId, input, "completed");
630
+ if (frame !== void 0) {
631
+ await writer.write((0, import_nestjs_agent_core5.encodeStreamEvent)(frame));
632
+ }
633
+ await writer.end();
634
+ }, "end")
635
+ };
636
+ }, "openSink"),
637
+ awaitApproval: /* @__PURE__ */ __name(async (call, _toolCtx, opts) => {
638
+ const reply = await awaitReply({
639
+ id: call.id,
640
+ toolName: call.name,
641
+ kind: "approval"
642
+ }, opts?.timeoutMs);
643
+ return reply === null ? {
644
+ approved: false,
645
+ expired: true
646
+ } : reply;
647
+ }, "awaitApproval"),
648
+ awaitAnswers: /* @__PURE__ */ __name(async (request) => {
649
+ const reply = await awaitReply({
650
+ id: request.id,
651
+ toolName: request.source,
652
+ kind: "elicitation"
653
+ });
654
+ return reply ?? {
655
+ approved: false
656
+ };
657
+ }, "awaitAnswers"),
658
+ step,
659
+ parallel: import_nestjs_agent_core5.settleAll,
660
+ isControlFlowError: isEngineControlFlow,
661
+ runAgent: /* @__PURE__ */ __name(async (agentName, task) => {
662
+ const name = journal.unique(`delegate:${agentName}`);
663
+ const subThreadId = await subThread(agentName);
664
+ const child = {
665
+ agentName,
666
+ threadId: subThreadId,
667
+ actor: input.actor,
668
+ userText: task,
669
+ day,
670
+ delegationDepth: (input.delegationDepth ?? 0) + 1,
671
+ delegationPath: chainBelow,
672
+ parentRunId: runId,
673
+ sinkRunId
674
+ };
675
+ return journal.op(name, () => this.ctxCall(() => ctx.executeChild(AGENT_RUN_WORKFLOW, child, {
676
+ id: `${ctx.workflowId}/${name}`
677
+ })));
678
+ }, "runAgent"),
679
+ // A detached delegation outlives the turn that started it, and a Stop on that turn: an
680
+ // abandoned child, not a cancelled one.
681
+ startAgent: /* @__PURE__ */ __name(async ({ agentName, task, toolCallId }) => {
682
+ const name = journal.unique(`detach:${toolCallId}`);
683
+ const subThreadId = await subThread(agentName);
684
+ const child = {
685
+ agentName,
686
+ threadId: subThreadId,
687
+ actor: input.actor,
688
+ userText: task,
689
+ day,
690
+ delegationDepth: (input.delegationDepth ?? 0) + 1,
691
+ delegationPath: chainBelow,
692
+ parentRunId: runId,
693
+ deliverTo: {
694
+ threadId: input.threadId,
695
+ toolCallId
696
+ }
697
+ };
698
+ const childRunId = await journal.op(name, async () => {
699
+ const handle = await this.ctxCall(() => ctx.startChild(AGENT_RUN_WORKFLOW, child, {
700
+ id: `${runId}.detached.${toolCallId}`,
701
+ parentClose: "abandon"
702
+ }));
703
+ return handle.id;
704
+ });
705
+ return {
706
+ runId: childRunId
707
+ };
708
+ }, "startAgent"),
709
+ dispatchLlm: /* @__PURE__ */ __name((index, envelope) => {
710
+ const name = journal.unique(`llm:${index}`);
711
+ if (!journal.has(name)) {
712
+ if (journal.liveModelCalls >= this.stepsPerInstance) {
713
+ throw new SegmentBoundary();
714
+ }
715
+ journal.liveModelCalls += 1;
716
+ }
717
+ return journal.op(name, async () => {
718
+ try {
719
+ return await this.ctxCall(() => ctx.step(name, (attempt) => runLlmStep(this.factory, {
720
+ ...envelope,
721
+ runId,
722
+ step: index,
723
+ sinkRunId,
724
+ childSink
725
+ }, {
726
+ abortSignal: attempt.signal
727
+ }).catch((error) => {
728
+ if (!isConfigurationError(error)) throw error;
729
+ const fatal = new import_workflows3.NonRetryableStepError(error.message);
730
+ fatal.name = error.name;
731
+ throw fatal;
732
+ })));
733
+ } catch (error) {
734
+ if (error instanceof import_workflows3.StepFailedError) {
735
+ throw rebuildTurnError(stepFailureCause(error));
736
+ }
737
+ throw error;
738
+ }
739
+ });
740
+ }, "dispatchLlm"),
741
+ // A tool's failure is a result the model reads, not the step's: the step is retried only after
742
+ // a crash, and the tool's `ctx.idempotencyKey` (`<runId>:<toolCallId>`) is the same on that
743
+ // attempt, so a tool that passes it on does its side effect once.
744
+ dispatchTool: /* @__PURE__ */ __name((call, envelope) => checkpointTool(journal.unique(`tool:${call.id}`), call, envelope), "dispatchTool")
745
+ };
746
+ const checkpointTool = /* @__PURE__ */ __name((name, call, envelope) => journal.op(name, async () => {
747
+ const outcome = await this.ctxCall(() => ctx.step(name, async (attempt) => {
748
+ try {
749
+ const value = await runToolStep(this.factory, {
750
+ ...envelope,
751
+ toolCallId: call.id,
752
+ toolType: call.kind === "action" ? "action" : "read",
753
+ sinkRunId,
754
+ childSink
755
+ }, {
756
+ abortSignal: attempt.signal
757
+ });
758
+ return value === void 0 ? {} : {
759
+ v: value
760
+ };
761
+ } catch (error) {
762
+ originals.set(name, error);
763
+ return {
764
+ e: serializeTurnError(error)
765
+ };
766
+ }
767
+ }));
768
+ if ("e" in outcome) throw originals.get(name) ?? rebuildTurnError(outcome.e);
769
+ return outcome.v;
770
+ }), "checkpointTool");
771
+ try {
772
+ const result = await (0, import_nestjs_agent_core5.runAgentLoop)({
773
+ ...deps,
774
+ day
775
+ }, input, hooks);
776
+ await step("deactivate", () => (0, import_nestjs_agent_core5.releaseThreadRun)(this.store, input.threadId, runId));
777
+ return result;
778
+ } catch (error) {
779
+ if (error instanceof SegmentBoundary) {
780
+ return this.continueInSegment(ctx, {
781
+ ...segment,
782
+ carried: journal.outcomes
783
+ });
784
+ }
785
+ if (isEngineControlFlow(error) || error instanceof SegmentFailed) {
786
+ throw error;
787
+ }
788
+ if (error instanceof import_nestjs_agent_core5.RunCancelledError) {
789
+ await step("deactivate", () => (0, import_nestjs_agent_core5.releaseThreadRun)(this.store, input.threadId, runId));
790
+ await this.settleDetachedParent(step, runId, input, {
791
+ status: "cancelled"
792
+ });
793
+ throw error;
794
+ }
795
+ const durationMs = (0, import_nestjs_agent_core5.runDurationMs)(error);
796
+ const timed = durationMs !== void 0 ? {
797
+ durationMs
798
+ } : {};
799
+ const measured = (0, import_nestjs_agent_core5.runEndTimings)(error);
800
+ const message = error instanceof Error ? error.message : String(error);
801
+ const code = (0, import_nestjs_agent_core5.agentFailureCode)(error);
802
+ this.logger.error(`agent run ${runId} failed (${code}): ${message}`);
803
+ (0, import_nestjs_agent_core5.publishAgentRunFailed)({
804
+ runId,
805
+ threadId: input.threadId,
806
+ code,
807
+ message,
808
+ ...timed,
809
+ ...measured,
810
+ context: (0, import_nestjs_agent_core5.agentRunContext)(input)
811
+ });
812
+ if (isFatalDefinitionError(error)) {
813
+ await (0, import_nestjs_agent_core5.settleDeadRun)(this.store, {
814
+ runId,
815
+ threadId: input.threadId,
816
+ failure: {
817
+ code,
818
+ message,
819
+ ...timed
820
+ }
821
+ });
822
+ await (await hooks.openSink()).fail((0, import_nestjs_agent_core5.streamFailure)(error));
823
+ throw error;
824
+ }
825
+ try {
826
+ await step("persist:run:fail", async () => {
827
+ await this.store.recordRunEnd?.({
828
+ runId,
829
+ status: "failed",
830
+ ...timed,
831
+ errorCode: code,
832
+ errorMessage: message
833
+ });
834
+ await Promise.resolve(this.store.failUnsettledToolCalls?.(runId, import_nestjs_agent_core5.RUN_ENDED_BEFORE_TOOL_CALL)).catch(() => 0);
835
+ });
836
+ const queueFrame = await this.advanceQueue(ctx, step, journal, runId, input, "failed", message);
837
+ await step("deactivate", () => (0, import_nestjs_agent_core5.releaseThreadRun)(this.store, input.threadId, runId));
838
+ await this.settleDetachedParent(step, runId, input, {
839
+ status: "failed",
840
+ error: message
841
+ });
842
+ const writer = await hooks.openSink();
843
+ if (queueFrame !== void 0) {
844
+ await writer.write((0, import_nestjs_agent_core5.encodeStreamEvent)(queueFrame));
845
+ }
846
+ await writer.fail((0, import_nestjs_agent_core5.streamFailure)(error));
847
+ } catch (settling) {
848
+ if (isEngineControlFlow(settling)) throw markControlFlow(settling);
849
+ throw settling;
850
+ }
851
+ throw error;
852
+ }
853
+ }
854
+ /** The turn goes on in a child instance, from what this one (and those before it) settled. */
855
+ async continueInSegment(ctx, segment) {
856
+ const next = {
857
+ ...segment,
858
+ segment: segment.segment + 1
859
+ };
860
+ try {
861
+ return await this.ctxCall(() => ctx.executeChild(AGENT_RUN_SEGMENT_WORKFLOW, next, {
862
+ id: `${segment.runId}~${next.segment}`
863
+ }));
864
+ } catch (error) {
865
+ if (error instanceof import_workflows3.ChildWorkflowFailedError) throw new SegmentFailed(error);
866
+ throw error;
867
+ }
868
+ }
869
+ /**
870
+ * Hand the thread on past this settling turn, as the `aviary` engine does: the decision is one
871
+ * checkpoint, and the next message starts as an abandoned child under its own id, so the turn
872
+ * ending doesn't cancel it.
873
+ */
874
+ async advanceQueue(ctx, step, journal, runId, input, outcome, error) {
875
+ const queue = this.queue;
876
+ if (queue === void 0 || !queue.supported || input.sinkRunId !== void 0 || input.deliverTo !== void 0) {
877
+ return void 0;
878
+ }
879
+ const plan = await step(`queue:${outcome}`, async () => {
880
+ try {
881
+ const settled = outcome === "completed" && await this.isCancelled(runId) ? "cancelled" : outcome;
882
+ return await queue.plan({
883
+ threadId: input.threadId,
884
+ runId,
885
+ outcome: settled,
886
+ ...error !== void 0 ? {
887
+ error
888
+ } : {}
889
+ });
890
+ } catch {
891
+ return {};
892
+ }
893
+ });
894
+ const next = plan.next;
895
+ if (next === void 0) {
896
+ return plan.frame;
897
+ }
898
+ try {
899
+ await journal.op(journal.unique(`queue:start:${next.runId}`), async () => {
900
+ const handle = await this.ctxCall(() => ctx.startChild(AGENT_RUN_WORKFLOW, next.input, {
901
+ id: next.runId,
902
+ parentClose: "abandon"
903
+ }));
904
+ return handle.id;
905
+ });
906
+ return plan.frame;
907
+ } catch (failure) {
908
+ if (isEngineControlFlow(failure)) throw failure;
909
+ const reason = failure instanceof Error ? failure.message : String(failure);
910
+ return step("queue:restore", async () => {
911
+ await queue.restore(input.threadId, next, "start_failed", reason);
912
+ return queue.pausedFrame(input.threadId);
913
+ });
914
+ }
915
+ }
916
+ async isCancelled(runId) {
917
+ try {
918
+ return (await this.client?.getStatus(runId))?.cancelRequested === true;
919
+ } catch {
920
+ return false;
921
+ }
922
+ }
923
+ async settleDetachedParent(step, runId, input, outcome) {
924
+ const delivery = input.deliverTo;
925
+ if (delivery === void 0) return;
926
+ await step("deliver:detached:unsettled", () => (0, import_nestjs_agent_core5.settleUnsettledDelegation)({
927
+ store: this.store,
928
+ delivery,
929
+ agent: input.agentName ?? "default",
930
+ runId,
931
+ status: outcome.status,
932
+ ...outcome.error !== void 0 ? {
933
+ error: outcome.error
934
+ } : {}
935
+ }));
936
+ }
937
+ /** A `ctx` call whose interrupt carries core's control-flow marker. */
938
+ async ctxCall(call) {
939
+ try {
940
+ return await call();
941
+ } catch (error) {
942
+ throw markControlFlow(error);
943
+ }
944
+ }
945
+ };
946
+ AgentTurnExecutor = _ts_decorate([
947
+ (0, import_common.Injectable)(),
948
+ _ts_param(0, (0, import_common.Inject)(import_nestjs_agent_core5.AGENT_DEPS_FACTORY)),
949
+ _ts_param(1, (0, import_common.Inject)(import_nestjs_agent_core5.AGENT_STORE)),
950
+ _ts_param(2, (0, import_common.Optional)()),
951
+ _ts_param(2, (0, import_common.Inject)(import_nestjs_agent_core5.AGENT_OPTIONS)),
952
+ _ts_param(3, (0, import_common.Optional)()),
953
+ _ts_param(3, (0, import_common.Inject)(AGENT_CHAT_QUEUE)),
954
+ _ts_param(4, (0, import_common.Optional)()),
955
+ _ts_param(5, (0, import_common.Optional)()),
956
+ _ts_param(5, (0, import_common.Inject)(import_workflows3.WORKFLOWS_MODULE_OPTIONS)),
957
+ _ts_metadata("design:type", Function),
958
+ _ts_metadata("design:paramtypes", [
959
+ typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
960
+ typeof AgentStore === "undefined" ? Object : AgentStore,
961
+ typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
962
+ typeof ChatQueueService === "undefined" ? Object : ChatQueueService,
963
+ typeof import_workflows3.WorkflowClient === "undefined" ? Object : import_workflows3.WorkflowClient,
964
+ typeof WorkflowsModuleOptions === "undefined" ? Object : WorkflowsModuleOptions
965
+ ])
966
+ ], AgentTurnExecutor);
967
+
968
+ // src/workflows/agent-run.flow.ts
969
+ function _ts_decorate2(decorators, target, key, desc) {
970
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
971
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
972
+ r = Reflect.decorate(decorators, target, key, desc);
973
+ } else {
974
+ for (var i = decorators.length - 1; i >= 0; i--) {
975
+ if (d = decorators[i]) {
976
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
977
+ }
978
+ }
979
+ }
980
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
981
+ }
982
+ __name(_ts_decorate2, "_ts_decorate");
983
+ function _ts_metadata2(metadataKey, metadataValue) {
984
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
985
+ return Reflect.metadata(metadataKey, metadataValue);
986
+ }
987
+ }
988
+ __name(_ts_metadata2, "_ts_metadata");
989
+ var AgentRunFlow = class {
990
+ static {
991
+ __name(this, "AgentRunFlow");
992
+ }
993
+ turns;
994
+ constructor(turns) {
995
+ this.turns = turns;
996
+ }
997
+ run(ctx, input) {
998
+ return this.turns.run(ctx, input);
999
+ }
1000
+ };
1001
+ AgentRunFlow = _ts_decorate2([
1002
+ (0, import_workflows4.Workflow)(AGENT_RUN_WORKFLOW),
1003
+ _ts_metadata2("design:type", Function),
1004
+ _ts_metadata2("design:paramtypes", [
1005
+ typeof AgentTurnExecutor === "undefined" ? Object : AgentTurnExecutor
1006
+ ])
1007
+ ], AgentRunFlow);
1008
+ var AgentRunSegmentFlow = class {
1009
+ static {
1010
+ __name(this, "AgentRunSegmentFlow");
1011
+ }
1012
+ turns;
1013
+ constructor(turns) {
1014
+ this.turns = turns;
1015
+ }
1016
+ run(ctx, segment) {
1017
+ return this.turns.execute(ctx, segment);
1018
+ }
1019
+ };
1020
+ AgentRunSegmentFlow = _ts_decorate2([
1021
+ (0, import_workflows4.Workflow)(AGENT_RUN_SEGMENT_WORKFLOW),
1022
+ _ts_metadata2("design:type", Function),
1023
+ _ts_metadata2("design:paramtypes", [
1024
+ typeof AgentTurnExecutor === "undefined" ? Object : AgentTurnExecutor
1025
+ ])
1026
+ ], AgentRunSegmentFlow);
1027
+
1028
+ // src/workflows/workflows-agent-runner.ts
1029
+ var import_node_crypto = require("crypto");
1030
+ var import_nestjs_agent_core7 = require("@dudousxd/nestjs-agent-core");
1031
+ var import_common2 = require("@nestjs/common");
1032
+ var import_workflows5 = require("@nestjs/workflows");
1033
+
1034
+ // src/in-process-sink.ts
1035
+ var import_nestjs_agent_core6 = require("@dudousxd/nestjs-agent-core");
1036
+ var LIVE_TTL_MS = 36e5;
1037
+ var ENDED_GRACE_MS = 6e4;
1038
+ var InProcessTokenStreamSink = class {
1039
+ static {
1040
+ __name(this, "InProcessTokenStreamSink");
1041
+ }
1042
+ runs = /* @__PURE__ */ new Map();
1043
+ /** Subscribers of a run nothing has opened yet, woken by its `open()`. */
1044
+ waiting = /* @__PURE__ */ new Map();
1045
+ buffer(runId) {
1046
+ let buf = this.runs.get(runId);
1047
+ if (buf === void 0) {
1048
+ buf = {
1049
+ chunks: [],
1050
+ ended: false,
1051
+ notify: /* @__PURE__ */ new Set(),
1052
+ lastWriteAt: Date.now(),
1053
+ expiry: void 0
1054
+ };
1055
+ this.runs.set(runId, buf);
1056
+ this.expireAfter(runId, buf, LIVE_TTL_MS);
1057
+ const waiters = this.waiting.get(runId);
1058
+ this.waiting.delete(runId);
1059
+ for (const resolve of waiters ?? []) {
1060
+ resolve();
1061
+ }
1062
+ }
1063
+ return buf;
1064
+ }
1065
+ expireAfter(runId, buf, ms) {
1066
+ if (buf.expiry !== void 0) {
1067
+ clearTimeout(buf.expiry);
1068
+ }
1069
+ buf.expiry = setTimeout(() => {
1070
+ buf.expiry = void 0;
1071
+ const idle = Date.now() - buf.lastWriteAt;
1072
+ if (!buf.ended && idle < LIVE_TTL_MS) {
1073
+ this.expireAfter(runId, buf, LIVE_TTL_MS - idle);
1074
+ return;
1075
+ }
1076
+ this.drop(runId, buf);
1077
+ }, ms);
1078
+ buf.expiry.unref?.();
1079
+ }
1080
+ /** Forget the run, and let anyone still following it finish as if it had ended. */
1081
+ drop(runId, buf) {
1082
+ if (buf.expiry !== void 0) {
1083
+ clearTimeout(buf.expiry);
1084
+ buf.expiry = void 0;
1085
+ }
1086
+ if (this.runs.get(runId) === buf) {
1087
+ this.runs.delete(runId);
1088
+ }
1089
+ buf.ended = true;
1090
+ this.wake(buf);
1091
+ }
1092
+ wake(buf) {
1093
+ for (const resolve of buf.notify) {
1094
+ resolve();
1095
+ }
1096
+ buf.notify.clear();
1097
+ }
1098
+ finish(runId, buf) {
1099
+ buf.ended = true;
1100
+ this.wake(buf);
1101
+ this.expireAfter(runId, buf, ENDED_GRACE_MS);
1102
+ }
1103
+ /**
1104
+ * The run's writer. Each call finds the run's buffer afresh, so a run that went quiet past the
1105
+ * live TTL (parked on a person) and then writes again starts a new buffer its next subscriber
1106
+ * follows, rather than writing into one nothing reads.
1107
+ */
1108
+ open(runId) {
1109
+ this.buffer(runId);
1110
+ return {
1111
+ write: /* @__PURE__ */ __name((chunk) => {
1112
+ const buf = this.buffer(runId);
1113
+ buf.chunks.push(chunk);
1114
+ buf.lastWriteAt = Date.now();
1115
+ this.wake(buf);
1116
+ }, "write"),
1117
+ end: /* @__PURE__ */ __name(() => {
1118
+ this.finish(runId, this.buffer(runId));
1119
+ }, "end"),
1120
+ fail: /* @__PURE__ */ __name((error) => {
1121
+ const buf = this.buffer(runId);
1122
+ buf.failure = error;
1123
+ this.finish(runId, buf);
1124
+ }, "fail")
1125
+ };
1126
+ }
1127
+ async *subscribe(runId, options = {}) {
1128
+ const { signal } = options;
1129
+ let buf = this.runs.get(runId);
1130
+ while (buf === void 0) {
1131
+ const waiters = this.waiting.get(runId) ?? /* @__PURE__ */ new Set();
1132
+ this.waiting.set(runId, waiters);
1133
+ let resolve = /* @__PURE__ */ __name(() => {
1134
+ }, "resolve");
1135
+ const opened = new Promise((r) => {
1136
+ resolve = r;
1137
+ });
1138
+ waiters.add(resolve);
1139
+ try {
1140
+ if (!await untilAborted(opened, signal)) {
1141
+ return;
1142
+ }
1143
+ } finally {
1144
+ waiters.delete(resolve);
1145
+ if (waiters.size === 0 && this.waiting.get(runId) === waiters) {
1146
+ this.waiting.delete(runId);
1147
+ }
1148
+ }
1149
+ buf = this.runs.get(runId);
1150
+ }
1151
+ let index = 0;
1152
+ while (true) {
1153
+ while (index < buf.chunks.length) {
1154
+ const chunk = buf.chunks[index];
1155
+ index += 1;
1156
+ if (chunk !== void 0) {
1157
+ yield chunk;
1158
+ }
1159
+ }
1160
+ if (buf.ended) {
1161
+ if (buf.failure !== void 0) {
1162
+ throw new import_nestjs_agent_core6.AgentStreamError(buf.failure);
1163
+ }
1164
+ return;
1165
+ }
1166
+ const current = buf;
1167
+ let resolve = /* @__PURE__ */ __name(() => {
1168
+ }, "resolve");
1169
+ const woken = new Promise((r) => {
1170
+ resolve = r;
1171
+ });
1172
+ current.notify.add(resolve);
1173
+ try {
1174
+ if (!await untilAborted(woken, signal)) {
1175
+ return;
1176
+ }
1177
+ } finally {
1178
+ current.notify.delete(resolve);
1179
+ }
1180
+ }
1181
+ }
1182
+ close(runId) {
1183
+ const buf = this.runs.get(runId);
1184
+ if (buf?.expiry !== void 0) {
1185
+ clearTimeout(buf.expiry);
1186
+ }
1187
+ this.runs.delete(runId);
1188
+ }
1189
+ };
1190
+ async function untilAborted(promise, signal) {
1191
+ if (signal === void 0) {
1192
+ await promise;
1193
+ return true;
1194
+ }
1195
+ if (signal.aborted) {
1196
+ return false;
1197
+ }
1198
+ let onAbort = /* @__PURE__ */ __name(() => {
1199
+ }, "onAbort");
1200
+ const aborted = new Promise((resolve) => {
1201
+ onAbort = /* @__PURE__ */ __name(() => resolve(false), "onAbort");
1202
+ signal.addEventListener("abort", onAbort, {
1203
+ once: true
1204
+ });
1205
+ });
1206
+ try {
1207
+ return await Promise.race([
1208
+ promise.then(() => true),
1209
+ aborted
1210
+ ]);
1211
+ } finally {
1212
+ signal.removeEventListener("abort", onAbort);
1213
+ }
1214
+ }
1215
+ __name(untilAborted, "untilAborted");
1216
+
1217
+ // src/workflows/workflows-agent-runner.ts
1218
+ function _ts_decorate3(decorators, target, key, desc) {
1219
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1220
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
1221
+ r = Reflect.decorate(decorators, target, key, desc);
1222
+ } else {
1223
+ for (var i = decorators.length - 1; i >= 0; i--) {
1224
+ if (d = decorators[i]) {
1225
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1226
+ }
1227
+ }
1228
+ }
1229
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1230
+ }
1231
+ __name(_ts_decorate3, "_ts_decorate");
1232
+ function _ts_metadata3(metadataKey, metadataValue) {
1233
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
1234
+ return Reflect.metadata(metadataKey, metadataValue);
1235
+ }
1236
+ }
1237
+ __name(_ts_metadata3, "_ts_metadata");
1238
+ function _ts_param2(paramIndex, decorator) {
1239
+ return function(target, key) {
1240
+ decorator(target, key, paramIndex);
1241
+ };
1242
+ }
1243
+ __name(_ts_param2, "_ts_param");
1244
+ var ENDED = /* @__PURE__ */ new Set([
1245
+ "completed",
1246
+ "failed",
1247
+ "cancelled",
1248
+ "compensation_failed"
1249
+ ]);
1250
+ function recorded(input) {
1251
+ return typeof input === "object" && input !== null ? input : {};
1252
+ }
1253
+ __name(recorded, "recorded");
1254
+ function deliveryOf(input) {
1255
+ const { deliverTo, agentName } = recorded(input);
1256
+ if (typeof deliverTo !== "object" || deliverTo === null || typeof deliverTo.threadId !== "string" || typeof deliverTo.toolCallId !== "string") {
1257
+ return void 0;
1258
+ }
1259
+ return {
1260
+ delivery: deliverTo,
1261
+ agent: typeof agentName === "string" ? agentName : "default"
1262
+ };
1263
+ }
1264
+ __name(deliveryOf, "deliveryOf");
1265
+ function runContextOf(input) {
1266
+ const { actor, agentName, parentRunId } = recorded(input);
1267
+ if (typeof actor?.id !== "string") return void 0;
1268
+ return {
1269
+ actorId: actor.id,
1270
+ ...typeof agentName === "string" ? {
1271
+ agentName
1272
+ } : {},
1273
+ ...typeof actor.tenantRef === "string" ? {
1274
+ tenantRef: actor.tenantRef
1275
+ } : {},
1276
+ ...typeof parentRunId === "string" ? {
1277
+ parentRunId
1278
+ } : {}
1279
+ };
1280
+ }
1281
+ __name(runContextOf, "runContextOf");
1282
+ var WorkflowsAgentRunner = class _WorkflowsAgentRunner {
1283
+ static {
1284
+ __name(this, "WorkflowsAgentRunner");
1285
+ }
1286
+ store;
1287
+ sink;
1288
+ queue;
1289
+ logger = new import_common2.Logger(_WorkflowsAgentRunner.name);
1290
+ client;
1291
+ constructor(store, sink, client, queue) {
1292
+ this.store = store;
1293
+ this.sink = sink;
1294
+ this.queue = queue;
1295
+ if (client === void 0) {
1296
+ throw new Error("AgentWorkflowsModule runs turns on @nestjs/workflows: import WorkflowsModule.forRoot() from '@nestjs/workflows' (WorkflowsModule.forRoot({ worker: false }) on a process that must not run turns, such as an API pod). No WorkflowClient was found.");
1297
+ }
1298
+ this.client = client;
1299
+ if (this.sink instanceof InProcessTokenStreamSink) {
1300
+ this.logger.warn("durable turns with the default InProcessTokenStreamSink, which only buffers tokens in this process: fine while this process runs the workflow worker, but a turn claimed by another process cannot stream to this one. Wire a cross-process TokenStreamSink (e.g. the Redis one) before running several processes.");
1301
+ }
1302
+ }
1303
+ async start(input, options = {}) {
1304
+ const stamped = {
1305
+ ...input,
1306
+ day: input.day ?? utcDay()
1307
+ };
1308
+ const runId = options.runId ?? (0, import_node_crypto.randomUUID)();
1309
+ await this.client.start(AgentRunFlow, stamped, {
1310
+ id: runId
1311
+ });
1312
+ return {
1313
+ runId
1314
+ };
1315
+ }
1316
+ /** Not ended as far as the engine knows. An unknown run counts as running, and so does one it can't be asked about. */
1317
+ async isRunActive(runId) {
1318
+ try {
1319
+ const status = (await this.client.getStatus(runId))?.status;
1320
+ return status === void 0 || !ENDED.has(status);
1321
+ } catch {
1322
+ return true;
1323
+ }
1324
+ }
1325
+ async signal(runId, toolCallId, reply) {
1326
+ const key = replyKey(runId, toolCallId);
1327
+ await this.client.signal(AGENT_REPLY, reply, {
1328
+ key,
1329
+ id: key
1330
+ });
1331
+ }
1332
+ /** The engine's view of a run: status, custom status, waits, children. `null` for an unknown id. */
1333
+ getStatus(runId) {
1334
+ return this.client.getStatus(runId, {
1335
+ children: true
1336
+ });
1337
+ }
1338
+ /**
1339
+ * The calls of run `runId` waiting for a person now, in the instance it started in, in the
1340
+ * instances it went on in, and in the sub-agent runs it delegated to.
1341
+ */
1342
+ async pendingReplies(runId) {
1343
+ const found = [];
1344
+ const visit = /* @__PURE__ */ __name(async (id) => {
1345
+ const details = await this.client.getStatus(id, {
1346
+ children: true
1347
+ });
1348
+ if (details === null) return;
1349
+ const status = details.customStatus;
1350
+ found.push(...status?.pendingReplies ?? []);
1351
+ for (const child of details.children ?? []) {
1352
+ if (!ENDED.has(child.status) && child.parentClose !== "abandon") await visit(child.id);
1353
+ }
1354
+ }, "visit");
1355
+ await visit(runId);
1356
+ return found;
1357
+ }
1358
+ /**
1359
+ * Stop a run: the engine stops the turn at its next `ctx` call (a parked turn at once), and
1360
+ * cancels the sub-agent runs it is waiting on. What the engine knows nothing about is settled
1361
+ * here, as on the `aviary` engine: the delegation a detached run answers, the thread's queue and
1362
+ * live stream, the subscriber's stream (a `cancelled` frame and a normal end), the run's row.
1363
+ */
1364
+ async cancel(runId) {
1365
+ this.logger.log(`cancelling agent run ${runId}`);
1366
+ const details = await this.client.getStatus(runId).catch(() => null);
1367
+ const input = details?.input;
1368
+ const { threadId, sinkRunId, deliverTo } = recorded(input);
1369
+ try {
1370
+ await this.client.cancel(runId, "Stopped");
1371
+ } catch (error) {
1372
+ if (!(error instanceof import_workflows5.WorkflowNotFoundError)) throw error;
1373
+ }
1374
+ const target = deliveryOf(input);
1375
+ if (target !== void 0) {
1376
+ await (0, import_nestjs_agent_core7.settleUnsettledDelegation)({
1377
+ store: this.store,
1378
+ delivery: target.delivery,
1379
+ agent: target.agent,
1380
+ runId,
1381
+ status: "cancelled"
1382
+ }).catch((error) => this.logger.error(`could not settle the delegation of cancelled run ${runId}: ${error instanceof Error ? error.message : String(error)}`));
1383
+ }
1384
+ const writer = await this.sink.open(runId);
1385
+ if (typeof threadId === "string") {
1386
+ const threadTurn = sinkRunId === void 0 && deliverTo === void 0;
1387
+ if (this.queue?.supported === true && threadTurn) {
1388
+ try {
1389
+ const frame = await this.queue.handoff({
1390
+ threadId,
1391
+ runId,
1392
+ outcome: "cancelled"
1393
+ }, (next, nextRunId) => this.start(next, {
1394
+ runId: nextRunId
1395
+ }));
1396
+ if (frame !== void 0) await writer.write((0, import_nestjs_agent_core7.encodeStreamEvent)(frame));
1397
+ } catch (error) {
1398
+ this.logger.error(`could not advance the queue of thread ${threadId} after cancelling ${runId}: ${error instanceof Error ? error.message : String(error)}`);
1399
+ }
1400
+ }
1401
+ await (0, import_nestjs_agent_core7.releaseThreadRun)(this.store, threadId, runId);
1402
+ }
1403
+ await writer.write((0, import_nestjs_agent_core7.encodeStreamEvent)({
1404
+ kind: "cancelled"
1405
+ }));
1406
+ await writer.end();
1407
+ const durationMs = details !== null && details !== void 0 ? Math.max(0, details.updatedAt - details.createdAt) : void 0;
1408
+ const context = runContextOf(input);
1409
+ (0, import_nestjs_agent_core7.publishAgentRunCancelled)({
1410
+ runId,
1411
+ ...typeof threadId === "string" ? {
1412
+ threadId
1413
+ } : {},
1414
+ ...durationMs !== void 0 ? {
1415
+ durationMs
1416
+ } : {},
1417
+ ...context !== void 0 ? {
1418
+ context
1419
+ } : {}
1420
+ });
1421
+ await this.store.recordRunEnd?.({
1422
+ runId,
1423
+ status: "cancelled",
1424
+ ...durationMs !== void 0 ? {
1425
+ durationMs
1426
+ } : {}
1427
+ });
1428
+ }
1429
+ };
1430
+ WorkflowsAgentRunner = _ts_decorate3([
1431
+ (0, import_common2.Injectable)(),
1432
+ _ts_param2(0, (0, import_common2.Inject)(import_nestjs_agent_core7.AGENT_STORE)),
1433
+ _ts_param2(1, (0, import_common2.Inject)(import_nestjs_agent_core7.AGENT_SINK)),
1434
+ _ts_param2(2, (0, import_common2.Optional)()),
1435
+ _ts_param2(3, (0, import_common2.Optional)()),
1436
+ _ts_param2(3, (0, import_common2.Inject)(AGENT_CHAT_QUEUE)),
1437
+ _ts_metadata3("design:type", Function),
1438
+ _ts_metadata3("design:paramtypes", [
1439
+ typeof AgentStore === "undefined" ? Object : AgentStore,
1440
+ typeof TokenStreamSink === "undefined" ? Object : TokenStreamSink,
1441
+ typeof import_workflows5.WorkflowClient === "undefined" ? Object : import_workflows5.WorkflowClient,
1442
+ typeof ChatQueueService === "undefined" ? Object : ChatQueueService
1443
+ ])
1444
+ ], WorkflowsAgentRunner);
1445
+
1446
+ // src/workflows/agent-workflows.module.ts
1447
+ function _ts_decorate4(decorators, target, key, desc) {
1448
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1449
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
1450
+ r = Reflect.decorate(decorators, target, key, desc);
1451
+ } else {
1452
+ for (var i = decorators.length - 1; i >= 0; i--) {
1453
+ if (d = decorators[i]) {
1454
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1455
+ }
1456
+ }
1457
+ }
1458
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1459
+ }
1460
+ __name(_ts_decorate4, "_ts_decorate");
1461
+ var AgentWorkflowsModule = class {
1462
+ static {
1463
+ __name(this, "AgentWorkflowsModule");
1464
+ }
1465
+ };
1466
+ AgentWorkflowsModule = _ts_decorate4([
1467
+ (0, import_common3.Global)(),
1468
+ (0, import_common3.Module)({
1469
+ providers: [
1470
+ AgentTurnExecutor,
1471
+ AgentRunFlow,
1472
+ AgentRunSegmentFlow,
1473
+ WorkflowsAgentRunner,
1474
+ {
1475
+ provide: import_nestjs_agent_core8.AGENT_WORKFLOWS_RUNNER,
1476
+ useExisting: WorkflowsAgentRunner
1477
+ }
1478
+ ],
1479
+ exports: [
1480
+ import_nestjs_agent_core8.AGENT_WORKFLOWS_RUNNER,
1481
+ WorkflowsAgentRunner
1482
+ ]
1483
+ })
1484
+ ], AgentWorkflowsModule);
1485
+ // Annotate the CommonJS export names for ESM import in node:
1486
+ 0 && (module.exports = {
1487
+ AGENT_REPLY,
1488
+ AGENT_RUN_SEGMENT_WORKFLOW,
1489
+ AGENT_RUN_WORKFLOW,
1490
+ AgentRunFlow,
1491
+ AgentRunSegmentFlow,
1492
+ AgentWorkflowsModule,
1493
+ WorkflowsAgentRunner,
1494
+ replyKey
1495
+ });
1496
+ //# sourceMappingURL=index.cjs.map