@dudousxd/nestjs-agent 0.11.1 → 0.12.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.
- package/README.md +60 -0
- package/dist/{agent-deps.factory-D7GdhqdK.d.cts → agent-deps.factory-EROMcBNh.d.cts} +182 -5
- package/dist/{agent-deps.factory-D7GdhqdK.d.ts → agent-deps.factory-EROMcBNh.d.ts} +182 -5
- package/dist/durable/index.cjs +1733 -497
- package/dist/durable/index.cjs.map +1 -1
- package/dist/durable/index.d.cts +78 -32
- package/dist/durable/index.d.ts +78 -32
- package/dist/durable/index.js +1673 -437
- package/dist/durable/index.js.map +1 -1
- package/dist/index.cjs +1349 -284
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +415 -26
- package/dist/index.d.ts +415 -26
- package/dist/index.js +1289 -234
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/durable/index.cjs
CHANGED
|
@@ -31,10 +31,10 @@ __export(durable_exports, {
|
|
|
31
31
|
module.exports = __toCommonJS(durable_exports);
|
|
32
32
|
|
|
33
33
|
// src/durable/agent-run.workflow.ts
|
|
34
|
-
var
|
|
35
|
-
var
|
|
34
|
+
var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
|
|
35
|
+
var import_nestjs_durable2 = require("@dudousxd/nestjs-durable");
|
|
36
36
|
var import_nestjs_durable_core = require("@dudousxd/nestjs-durable-core");
|
|
37
|
-
var
|
|
37
|
+
var import_common2 = require("@nestjs/common");
|
|
38
38
|
|
|
39
39
|
// src/agent-deps.ts
|
|
40
40
|
function utcDay(date = /* @__PURE__ */ new Date()) {
|
|
@@ -52,10 +52,10 @@ function childSinkWriter(writer) {
|
|
|
52
52
|
}
|
|
53
53
|
__name(childSinkWriter, "childSinkWriter");
|
|
54
54
|
|
|
55
|
-
// src/durable/
|
|
56
|
-
var
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
// src/durable/agent-run.steps.ts
|
|
56
|
+
var import_nestjs_agent_core = require("@dudousxd/nestjs-agent-core");
|
|
57
|
+
var import_nestjs_durable = require("@dudousxd/nestjs-durable");
|
|
58
|
+
var import_common = require("@nestjs/common");
|
|
59
59
|
function _ts_decorate(decorators, target, key, desc) {
|
|
60
60
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
61
61
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -73,34 +73,236 @@ function _ts_param(paramIndex, decorator) {
|
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
__name(_ts_param, "_ts_param");
|
|
76
|
+
var AgentRunSteps = class {
|
|
77
|
+
static {
|
|
78
|
+
__name(this, "AgentRunSteps");
|
|
79
|
+
}
|
|
80
|
+
factory;
|
|
81
|
+
constructor(factory) {
|
|
82
|
+
this.factory = factory;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Retryable: every side effect (persist/quota/stream markers) happens loop-side under
|
|
86
|
+
* `hooks.step`, so a durable retry only re-runs the model call and re-streams its tokens — never
|
|
87
|
+
* double-writes. NEVER call `writer.end()`/`fail()` here: the workflow owns the stream's lifecycle,
|
|
88
|
+
* across however many turns/retries it takes.
|
|
89
|
+
*/
|
|
90
|
+
async llm(input) {
|
|
91
|
+
const deps = this.factory.forAgent(input.agentName);
|
|
92
|
+
const tools = (0, import_nestjs_agent_core.withMemoryTool)({
|
|
93
|
+
tools: (0, import_nestjs_agent_core.withSkillTool)({
|
|
94
|
+
tools: (0, import_nestjs_agent_core.withAskTool)({
|
|
95
|
+
tools: await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList),
|
|
96
|
+
ask: deps.ask
|
|
97
|
+
}),
|
|
98
|
+
enabled: deps.skills !== void 0
|
|
99
|
+
}),
|
|
100
|
+
enabled: deps.memory?.provider.write !== void 0
|
|
101
|
+
});
|
|
102
|
+
const buffer = input.bufferOutput === true ? (0, import_nestjs_agent_core.createFrameBuffer)() : void 0;
|
|
103
|
+
let writer;
|
|
104
|
+
if (buffer !== void 0) {
|
|
105
|
+
writer = buffer.writer;
|
|
106
|
+
} else {
|
|
107
|
+
const opened = await deps.sink.open(input.sinkRunId);
|
|
108
|
+
writer = input.childSink ? childSinkWriter(opened) : opened;
|
|
109
|
+
}
|
|
110
|
+
const turn = await (0, import_nestjs_agent_core.traceLlmTurn)(input.runId, input.step, () => deps.model.runTurn({
|
|
111
|
+
system: input.system,
|
|
112
|
+
messages: input.messages,
|
|
113
|
+
tools,
|
|
114
|
+
sink: writer
|
|
115
|
+
}));
|
|
116
|
+
return buffer === void 0 ? turn : {
|
|
117
|
+
...turn,
|
|
118
|
+
bufferedFrames: buffer.frames()
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* NO DURABLE retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm`
|
|
123
|
+
* above). What it does retry, in place, is a CLASSIFIED-TRANSIENT error from the tool's own
|
|
124
|
+
* invocation (a DB deadlock, a lock-wait timeout — see `isTransientToolError`): the server rolled
|
|
125
|
+
* that work back, so re-invoking it is safe, and doing it here (inside this one step, never a new
|
|
126
|
+
* checkpoint) is exactly how the non-dispatched loop path handles it too. The timeout is applied
|
|
127
|
+
* HERE, handler-side, via `withToolTimeout` — never as a durable dispatch `timeoutMs`, which
|
|
128
|
+
* bounds engine liveness (retryable) rather than the tool's own business outcome — and per
|
|
129
|
+
* ATTEMPT, so a retried invocation gets its own fresh timeout window.
|
|
130
|
+
*/
|
|
131
|
+
async tool(input) {
|
|
132
|
+
const deps = this.factory.forAgent(input.ctx.agentName);
|
|
133
|
+
if (deps.registry.spec(input.toolName)?.kind === "action" && input.toolType !== "action") {
|
|
134
|
+
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`);
|
|
135
|
+
}
|
|
136
|
+
const ctx = {
|
|
137
|
+
...input.ctx
|
|
138
|
+
};
|
|
139
|
+
const localClassify = deps.toolTransientRetry !== false ? deps.toolTransientRetry?.classify : void 0;
|
|
140
|
+
const transientRetry = input.transientRetry === false ? false : {
|
|
141
|
+
attempts: input.transientRetry.attempts,
|
|
142
|
+
backoffMs: input.transientRetry.backoffMs,
|
|
143
|
+
...localClassify !== void 0 ? {
|
|
144
|
+
classify: localClassify
|
|
145
|
+
} : {}
|
|
146
|
+
};
|
|
147
|
+
return (0, import_nestjs_agent_core.traceToolExecution)(input.ctx.runId, {
|
|
148
|
+
toolCallId: input.toolCallId,
|
|
149
|
+
toolName: input.toolName,
|
|
150
|
+
toolType: input.toolType
|
|
151
|
+
}, () => (0, import_nestjs_agent_core.invokeWithTransientRetry)(() => {
|
|
152
|
+
const invocation = deps.registry.invoke(input.toolName, input.input, ctx, deps.rolesPolicy);
|
|
153
|
+
return input.timeoutMs !== void 0 ? (0, import_nestjs_agent_core.withToolTimeout)(invocation, input.timeoutMs, input.toolName) : invocation;
|
|
154
|
+
}, transientRetry, {
|
|
155
|
+
onRetry: /* @__PURE__ */ __name((attempt, error) => {
|
|
156
|
+
(0, import_nestjs_agent_core.publishAgentToolRetry)({
|
|
157
|
+
toolName: input.toolName,
|
|
158
|
+
toolCallId: input.toolCallId,
|
|
159
|
+
attempt,
|
|
160
|
+
message: error instanceof Error ? error.message : String(error)
|
|
161
|
+
});
|
|
162
|
+
}, "onRetry")
|
|
163
|
+
}));
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
_ts_decorate([
|
|
167
|
+
(0, import_nestjs_durable.Step)({
|
|
168
|
+
retries: 3
|
|
169
|
+
}),
|
|
170
|
+
_ts_metadata("design:type", Function),
|
|
171
|
+
_ts_metadata("design:paramtypes", [
|
|
172
|
+
typeof DispatchedLlmInput === "undefined" ? Object : DispatchedLlmInput
|
|
173
|
+
]),
|
|
174
|
+
_ts_metadata("design:returntype", Promise)
|
|
175
|
+
], AgentRunSteps.prototype, "llm", null);
|
|
176
|
+
_ts_decorate([
|
|
177
|
+
(0, import_nestjs_durable.Step)(),
|
|
178
|
+
_ts_metadata("design:type", Function),
|
|
179
|
+
_ts_metadata("design:paramtypes", [
|
|
180
|
+
typeof DispatchedToolInput === "undefined" ? Object : DispatchedToolInput
|
|
181
|
+
]),
|
|
182
|
+
_ts_metadata("design:returntype", Promise)
|
|
183
|
+
], AgentRunSteps.prototype, "tool", null);
|
|
184
|
+
AgentRunSteps = _ts_decorate([
|
|
185
|
+
(0, import_common.Injectable)(),
|
|
186
|
+
_ts_param(0, (0, import_common.Inject)(import_nestjs_agent_core.AGENT_DEPS_FACTORY)),
|
|
187
|
+
_ts_metadata("design:type", Function),
|
|
188
|
+
_ts_metadata("design:paramtypes", [
|
|
189
|
+
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
|
|
190
|
+
])
|
|
191
|
+
], AgentRunSteps);
|
|
192
|
+
|
|
193
|
+
// src/durable/dispatched-steps.token.ts
|
|
194
|
+
var AGENT_DISPATCHED_STEPS = Symbol.for("@dudousxd/nestjs-agent:dispatched-steps");
|
|
195
|
+
|
|
196
|
+
// src/durable/agent-run.workflow.ts
|
|
197
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
198
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
199
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
200
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
201
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
202
|
+
}
|
|
203
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
204
|
+
function _ts_metadata2(k, v) {
|
|
205
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
206
|
+
}
|
|
207
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
208
|
+
function _ts_param2(paramIndex, decorator) {
|
|
209
|
+
return function(target, key) {
|
|
210
|
+
decorator(target, key, paramIndex);
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
__name(_ts_param2, "_ts_param");
|
|
76
214
|
var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
77
215
|
static {
|
|
78
216
|
__name(this, "AgentRunWorkflow");
|
|
79
217
|
}
|
|
80
218
|
factory;
|
|
81
219
|
store;
|
|
82
|
-
steps;
|
|
83
220
|
dispatchedSteps;
|
|
84
|
-
|
|
221
|
+
runs;
|
|
222
|
+
constructor(factory, store, dispatchedSteps, runs) {
|
|
85
223
|
this.factory = factory;
|
|
86
224
|
this.store = store;
|
|
87
|
-
this.steps = steps;
|
|
88
225
|
this.dispatchedSteps = dispatchedSteps;
|
|
226
|
+
this.runs = runs;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Has someone asked this run to stop? Read from the runtime's own run status, which is where
|
|
230
|
+
* `DurableAgentRunner.cancel` puts it — `cancelling` while a compensating cancel is in flight,
|
|
231
|
+
* `cancelled` once it has settled.
|
|
232
|
+
*
|
|
233
|
+
* Costs a run read at each of the loop's observation points (two per step). That is a row the
|
|
234
|
+
* control plane already has, against a turn that is otherwise making model calls, and it buys the
|
|
235
|
+
* property that matters: the answer comes from a place BOTH the canceller and every pod that might
|
|
236
|
+
* replay this run can see.
|
|
237
|
+
*
|
|
238
|
+
* Failing to ask is not a cancel. A tenant with no gateway wired, or an operator briefly
|
|
239
|
+
* unreachable, answers "no" and the run carries on — the alternative is failing healthy runs
|
|
240
|
+
* because a status read timed out. The loop journals that answer like any other, so two processes
|
|
241
|
+
* can never disagree about what was seen here.
|
|
242
|
+
*/
|
|
243
|
+
async isCancelled(runId) {
|
|
244
|
+
try {
|
|
245
|
+
const status = (await this.runs?.getRunDetail(runId))?.run.status;
|
|
246
|
+
return status === "cancelled" || status === "cancelling";
|
|
247
|
+
} catch {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Settle the delegation a DETACHED run was started for, when that run ends without an answer.
|
|
253
|
+
*
|
|
254
|
+
* The loop delivers its own success (`deliver:detached`) but cannot catch its own crash, and the
|
|
255
|
+
* runtime settles the run row without knowing anything delegated it. Left alone, the card in the
|
|
256
|
+
* calling conversation says "started" for ever — the one state a reader can neither wait on nor
|
|
257
|
+
* act on. A no-op for every other run: only a detached one carries a delivery address.
|
|
258
|
+
*/
|
|
259
|
+
async settleDetachedParent(ctx, input, outcome) {
|
|
260
|
+
const delivery = input.deliverTo;
|
|
261
|
+
if (delivery === void 0) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
await ctx.localStep("deliver:detached:unsettled", () => (0, import_nestjs_agent_core2.settleUnsettledDelegation)({
|
|
265
|
+
store: this.store,
|
|
266
|
+
delivery,
|
|
267
|
+
agent: input.agentName ?? "default",
|
|
268
|
+
runId: ctx.runId,
|
|
269
|
+
status: outcome.status,
|
|
270
|
+
...outcome.error !== void 0 ? {
|
|
271
|
+
error: outcome.error
|
|
272
|
+
} : {}
|
|
273
|
+
}));
|
|
89
274
|
}
|
|
90
275
|
async run(ctx, input) {
|
|
91
276
|
const day = input.day ?? utcDay();
|
|
92
277
|
const deps = this.factory.forAgent(input.agentName);
|
|
93
|
-
const dispatchSteps = this.dispatchedSteps
|
|
94
|
-
if (input.sinkRunId !== void 0) {
|
|
278
|
+
const dispatchSteps = this.dispatchedSteps && await ctx.patched("agent:dispatched-steps");
|
|
279
|
+
if (input.sinkRunId !== void 0 || input.deliverTo !== void 0) {
|
|
95
280
|
await ctx.localStep("activate", () => this.store.setActiveStream(input.threadId, ctx.runId));
|
|
96
281
|
}
|
|
97
282
|
const sinkRunId = input.sinkRunId ?? ctx.runId;
|
|
283
|
+
const chainBelow = [
|
|
284
|
+
...input.delegationPath ?? [],
|
|
285
|
+
...input.agentName !== void 0 ? [
|
|
286
|
+
input.agentName
|
|
287
|
+
] : []
|
|
288
|
+
];
|
|
98
289
|
const hooks = {
|
|
99
290
|
runId: ctx.runId,
|
|
100
291
|
// A child forwards into the top-level sink but must not end/fail it (the top-level run owns it).
|
|
101
292
|
openSink: /* @__PURE__ */ __name(async () => input.sinkRunId !== void 0 ? childSinkWriter(await deps.sink.open(sinkRunId)) : deps.sink.open(ctx.runId), "openSink"),
|
|
102
293
|
awaitApproval: /* @__PURE__ */ __name((call) => ctx.waitForSignal(`tool:${ctx.runId}:${call.id}`), "awaitApproval"),
|
|
294
|
+
// The same wait, on the same signal key, carrying a typed answer instead of a yes/no — so a
|
|
295
|
+
// question set and an approval reach a parked run through one path, and the HTTP surface that
|
|
296
|
+
// settles either one is the same `POST /agent/tool-call/*` family.
|
|
297
|
+
awaitAnswers: /* @__PURE__ */ __name((request) => ctx.waitForSignal(`tool:${ctx.runId}:${request.id}`), "awaitAnswers"),
|
|
103
298
|
step: /* @__PURE__ */ __name((name, fn) => ctx.localStep(name, fn), "step"),
|
|
299
|
+
// Both durable step primitives take their checkpoint position on the CALL, before their first
|
|
300
|
+
// await, so launching a batch in one tick — what `settleAll` does — fixes the block of
|
|
301
|
+
// positions in call order however the tools then settle. `ctx.patched` keeps a run that
|
|
302
|
+
// recorded the one-call-at-a-time shape replaying against that shape.
|
|
303
|
+
parallel: import_nestjs_agent_core2.settleAll,
|
|
304
|
+
cancelled: /* @__PURE__ */ __name(() => this.isCancelled(ctx.runId), "cancelled"),
|
|
305
|
+
patched: /* @__PURE__ */ __name((id) => ctx.patched(id), "patched"),
|
|
104
306
|
// Dispatched-step suspends must escape the loop's tool catch — control flow, not a tool
|
|
105
307
|
// failure. Marker-based predicate, NOT instanceof: the signal's CLASS differs by runtime
|
|
106
308
|
// (engine in-process throws durable-core's WorkflowSuspended/ContinueAsNew; the BullMQ thin
|
|
@@ -121,15 +323,54 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
121
323
|
userText: task,
|
|
122
324
|
day,
|
|
123
325
|
delegationDepth: (input.delegationDepth ?? 0) + 1,
|
|
326
|
+
delegationPath: chainBelow,
|
|
327
|
+
parentRunId: ctx.runId,
|
|
124
328
|
sinkRunId
|
|
125
329
|
});
|
|
126
330
|
}, "runAgent"),
|
|
331
|
+
// The same delegation, not awaited: `ctx.startChild` records a `spawn:<childRunId>` at this
|
|
332
|
+
// position and returns, so THIS turn ends while the child is still working. Two things the
|
|
333
|
+
// awaited form does are deliberately left off:
|
|
334
|
+
// - no `sinkRunId`. A detached run owns its own stream. Forwarding it into the turn that
|
|
335
|
+
// started it would write tokens, and a pending action-tool frame, into a stream whose
|
|
336
|
+
// reader has already seen `done` — and would put the child's approval card in whatever
|
|
337
|
+
// turn happened to be open. Its approval goes to the pending-approvals surface instead,
|
|
338
|
+
// which it reaches for free: the call is persisted `pending_approval` against the child's
|
|
339
|
+
// OWN runId, and that is what `runForToolCall` answers with.
|
|
340
|
+
// - `deliverTo` instead. The parent's tool result is a receipt, so the answer needs an
|
|
341
|
+
// address of its own, and by the time it exists nobody is holding one.
|
|
342
|
+
startAgent: /* @__PURE__ */ __name(async ({ agentName, task, toolCallId: toolCallId2 }) => {
|
|
343
|
+
const subThreadId = await ctx.localStep(`subthread:${agentName}`, async () => {
|
|
344
|
+
const thread = await this.store.createThread({
|
|
345
|
+
actor: input.actor,
|
|
346
|
+
transient: true
|
|
347
|
+
});
|
|
348
|
+
return thread.id;
|
|
349
|
+
});
|
|
350
|
+
const childRunId = await ctx.startChild(_AgentRunWorkflow, {
|
|
351
|
+
agentName,
|
|
352
|
+
threadId: subThreadId,
|
|
353
|
+
actor: input.actor,
|
|
354
|
+
userText: task,
|
|
355
|
+
day,
|
|
356
|
+
delegationDepth: (input.delegationDepth ?? 0) + 1,
|
|
357
|
+
delegationPath: chainBelow,
|
|
358
|
+
parentRunId: ctx.runId,
|
|
359
|
+
deliverTo: {
|
|
360
|
+
threadId: input.threadId,
|
|
361
|
+
toolCallId: toolCallId2
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
return {
|
|
365
|
+
runId: childRunId
|
|
366
|
+
};
|
|
367
|
+
}, "startAgent"),
|
|
127
368
|
// Routes the two long steps through AgentRunSteps as engine-dispatched `ctx.step`s instead of
|
|
128
369
|
// `ctx.localStep`s, so a turn isn't pinned to this workflow worker for the model call or a tool
|
|
129
370
|
// execution. `sinkRunId`/`childSink` are sink routing this workflow already resolved above —
|
|
130
371
|
// core's dispatchLlm signature stays sink-topology-agnostic, so we add them here, not in core.
|
|
131
|
-
...dispatchSteps
|
|
132
|
-
dispatchLlm: /* @__PURE__ */ __name((index, envelope) => ctx.step(
|
|
372
|
+
...dispatchSteps ? {
|
|
373
|
+
dispatchLlm: /* @__PURE__ */ __name((index, envelope) => ctx.step(AgentRunSteps.prototype.llm, {
|
|
133
374
|
...envelope,
|
|
134
375
|
runId: ctx.runId,
|
|
135
376
|
step: index,
|
|
@@ -141,7 +382,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
141
382
|
// ('agent'-kind delegations branch to runAgent earlier in the loop), so anything that
|
|
142
383
|
// isn't 'action' is defensively 'read' — the same posture core takes for an
|
|
143
384
|
// unresolvable `kind`.
|
|
144
|
-
dispatchTool: /* @__PURE__ */ __name((call, envelope) => ctx.step(
|
|
385
|
+
dispatchTool: /* @__PURE__ */ __name((call, envelope) => ctx.step(AgentRunSteps.prototype.tool, {
|
|
145
386
|
...envelope,
|
|
146
387
|
toolCallId: call.id,
|
|
147
388
|
toolType: call.kind === "action" ? "action" : "read"
|
|
@@ -149,7 +390,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
149
390
|
} : {}
|
|
150
391
|
};
|
|
151
392
|
try {
|
|
152
|
-
const result = await (0,
|
|
393
|
+
const result = await (0, import_nestjs_agent_core2.runAgentLoop)({
|
|
153
394
|
...deps,
|
|
154
395
|
day
|
|
155
396
|
}, input, hooks);
|
|
@@ -159,9 +400,28 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
159
400
|
if ((0, import_nestjs_durable_core.isWorkflowControlFlowSignal)(error)) {
|
|
160
401
|
throw error;
|
|
161
402
|
}
|
|
403
|
+
if (error instanceof import_nestjs_agent_core2.RunCancelledError) {
|
|
404
|
+
await ctx.localStep("deactivate", () => this.store.setActiveStream(input.threadId, null));
|
|
405
|
+
await this.settleDetachedParent(ctx, input, {
|
|
406
|
+
status: "cancelled"
|
|
407
|
+
});
|
|
408
|
+
throw error;
|
|
409
|
+
}
|
|
410
|
+
if ((0, import_nestjs_agent_core2.isReplayIntegrityError)(error)) {
|
|
411
|
+
const failure = {
|
|
412
|
+
code: "run_failed",
|
|
413
|
+
message: error.message
|
|
414
|
+
};
|
|
415
|
+
(0, import_nestjs_agent_core2.publishAgentRunFailed)({
|
|
416
|
+
runId: ctx.runId,
|
|
417
|
+
...failure
|
|
418
|
+
});
|
|
419
|
+
await (await hooks.openSink()).fail(failure);
|
|
420
|
+
throw error;
|
|
421
|
+
}
|
|
162
422
|
const message = error instanceof Error ? error.message : String(error);
|
|
163
|
-
const code =
|
|
164
|
-
(0,
|
|
423
|
+
const code = (0, import_nestjs_agent_core2.agentFailureCode)(error);
|
|
424
|
+
(0, import_nestjs_agent_core2.publishAgentRunFailed)({
|
|
165
425
|
runId: ctx.runId,
|
|
166
426
|
code,
|
|
167
427
|
message
|
|
@@ -173,6 +433,10 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
173
433
|
errorMessage: message
|
|
174
434
|
}) ?? Promise.resolve());
|
|
175
435
|
await ctx.localStep("deactivate", () => this.store.setActiveStream(input.threadId, null));
|
|
436
|
+
await this.settleDetachedParent(ctx, input, {
|
|
437
|
+
status: "failed",
|
|
438
|
+
error: message
|
|
439
|
+
});
|
|
176
440
|
const writer = await hooks.openSink();
|
|
177
441
|
await writer.fail({
|
|
178
442
|
code,
|
|
@@ -182,143 +446,29 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
182
446
|
}
|
|
183
447
|
}
|
|
184
448
|
};
|
|
185
|
-
AgentRunWorkflow =
|
|
186
|
-
(0,
|
|
187
|
-
(0,
|
|
449
|
+
AgentRunWorkflow = _ts_decorate2([
|
|
450
|
+
(0, import_common2.Injectable)(),
|
|
451
|
+
(0, import_nestjs_durable2.Workflow)({
|
|
188
452
|
name: "agent.run",
|
|
189
453
|
version: "1"
|
|
190
454
|
}),
|
|
191
|
-
_ts_param(0, (0, import_common.Inject)(import_nestjs_agent_core.AGENT_DEPS_FACTORY)),
|
|
192
|
-
_ts_param(1, (0, import_common.Inject)(import_nestjs_agent_core.AGENT_STORE)),
|
|
193
|
-
_ts_param(2, (0, import_common.Optional)()),
|
|
194
|
-
_ts_param(3, (0, import_common.Inject)(AGENT_DISPATCHED_STEPS)),
|
|
195
|
-
_ts_metadata("design:type", Function),
|
|
196
|
-
_ts_metadata("design:paramtypes", [
|
|
197
|
-
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
|
|
198
|
-
typeof AgentStore === "undefined" ? Object : AgentStore,
|
|
199
|
-
Object,
|
|
200
|
-
Boolean
|
|
201
|
-
])
|
|
202
|
-
], AgentRunWorkflow);
|
|
203
|
-
|
|
204
|
-
// src/durable/agent-run.steps.ts
|
|
205
|
-
var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
|
|
206
|
-
var import_nestjs_durable2 = require("@dudousxd/nestjs-durable");
|
|
207
|
-
var import_common2 = require("@nestjs/common");
|
|
208
|
-
function _ts_decorate2(decorators, target, key, desc) {
|
|
209
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
210
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
211
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
212
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
213
|
-
}
|
|
214
|
-
__name(_ts_decorate2, "_ts_decorate");
|
|
215
|
-
function _ts_metadata2(k, v) {
|
|
216
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
217
|
-
}
|
|
218
|
-
__name(_ts_metadata2, "_ts_metadata");
|
|
219
|
-
function _ts_param2(paramIndex, decorator) {
|
|
220
|
-
return function(target, key) {
|
|
221
|
-
decorator(target, key, paramIndex);
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
__name(_ts_param2, "_ts_param");
|
|
225
|
-
var AgentRunSteps = class {
|
|
226
|
-
static {
|
|
227
|
-
__name(this, "AgentRunSteps");
|
|
228
|
-
}
|
|
229
|
-
factory;
|
|
230
|
-
constructor(factory) {
|
|
231
|
-
this.factory = factory;
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Retryable: every side effect (persist/quota/stream markers) happens loop-side under
|
|
235
|
-
* `hooks.step`, so a durable retry only re-runs the model call and re-streams its tokens — never
|
|
236
|
-
* double-writes. NEVER call `writer.end()`/`fail()` here: the workflow owns the stream's lifecycle,
|
|
237
|
-
* across however many turns/retries it takes.
|
|
238
|
-
*/
|
|
239
|
-
async llm(input) {
|
|
240
|
-
const deps = this.factory.forAgent(input.agentName);
|
|
241
|
-
const tools = await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList);
|
|
242
|
-
const opened = await deps.sink.open(input.sinkRunId);
|
|
243
|
-
const writer = input.childSink ? childSinkWriter(opened) : opened;
|
|
244
|
-
return (0, import_nestjs_agent_core2.traceLlmTurn)(input.runId, input.step, () => deps.model.runTurn({
|
|
245
|
-
system: input.system,
|
|
246
|
-
messages: input.messages,
|
|
247
|
-
tools,
|
|
248
|
-
sink: writer
|
|
249
|
-
}));
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* NO DURABLE retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm`
|
|
253
|
-
* above). What it does retry, in place, is a CLASSIFIED-TRANSIENT error from the tool's own
|
|
254
|
-
* invocation (a DB deadlock, a lock-wait timeout — see `isTransientToolError`): the server rolled
|
|
255
|
-
* that work back, so re-invoking it is safe, and doing it here (inside this one step, never a new
|
|
256
|
-
* checkpoint) is exactly how the non-dispatched loop path handles it too. The timeout is applied
|
|
257
|
-
* HERE, handler-side, via `withToolTimeout` — never as a durable dispatch `timeoutMs`, which
|
|
258
|
-
* bounds engine liveness (retryable) rather than the tool's own business outcome — and per
|
|
259
|
-
* ATTEMPT, so a retried invocation gets its own fresh timeout window.
|
|
260
|
-
*/
|
|
261
|
-
async tool(input) {
|
|
262
|
-
const deps = this.factory.forAgent(input.ctx.agentName);
|
|
263
|
-
const ctx = {
|
|
264
|
-
...input.ctx
|
|
265
|
-
};
|
|
266
|
-
const localClassify = deps.toolTransientRetry !== false ? deps.toolTransientRetry?.classify : void 0;
|
|
267
|
-
const transientRetry = input.transientRetry === false ? false : {
|
|
268
|
-
attempts: input.transientRetry.attempts,
|
|
269
|
-
backoffMs: input.transientRetry.backoffMs,
|
|
270
|
-
...localClassify !== void 0 ? {
|
|
271
|
-
classify: localClassify
|
|
272
|
-
} : {}
|
|
273
|
-
};
|
|
274
|
-
return (0, import_nestjs_agent_core2.traceToolExecution)(input.ctx.runId, {
|
|
275
|
-
toolCallId: input.toolCallId,
|
|
276
|
-
toolName: input.toolName,
|
|
277
|
-
toolType: input.toolType
|
|
278
|
-
}, () => (0, import_nestjs_agent_core2.invokeWithTransientRetry)(() => {
|
|
279
|
-
const invocation = deps.registry.invoke(input.toolName, input.input, ctx, deps.rolesPolicy);
|
|
280
|
-
return input.timeoutMs !== void 0 ? (0, import_nestjs_agent_core2.withToolTimeout)(invocation, input.timeoutMs, input.toolName) : invocation;
|
|
281
|
-
}, transientRetry, {
|
|
282
|
-
onRetry: /* @__PURE__ */ __name((attempt, error) => {
|
|
283
|
-
(0, import_nestjs_agent_core2.publishAgentToolRetry)({
|
|
284
|
-
toolName: input.toolName,
|
|
285
|
-
toolCallId: input.toolCallId,
|
|
286
|
-
attempt,
|
|
287
|
-
message: error instanceof Error ? error.message : String(error)
|
|
288
|
-
});
|
|
289
|
-
}, "onRetry")
|
|
290
|
-
}));
|
|
291
|
-
}
|
|
292
|
-
};
|
|
293
|
-
_ts_decorate2([
|
|
294
|
-
(0, import_nestjs_durable2.Step)({
|
|
295
|
-
retries: 3
|
|
296
|
-
}),
|
|
297
|
-
_ts_metadata2("design:type", Function),
|
|
298
|
-
_ts_metadata2("design:paramtypes", [
|
|
299
|
-
typeof DispatchedLlmInput === "undefined" ? Object : DispatchedLlmInput
|
|
300
|
-
]),
|
|
301
|
-
_ts_metadata2("design:returntype", Promise)
|
|
302
|
-
], AgentRunSteps.prototype, "llm", null);
|
|
303
|
-
_ts_decorate2([
|
|
304
|
-
(0, import_nestjs_durable2.Step)(),
|
|
305
|
-
_ts_metadata2("design:type", Function),
|
|
306
|
-
_ts_metadata2("design:paramtypes", [
|
|
307
|
-
typeof DispatchedToolInput === "undefined" ? Object : DispatchedToolInput
|
|
308
|
-
]),
|
|
309
|
-
_ts_metadata2("design:returntype", Promise)
|
|
310
|
-
], AgentRunSteps.prototype, "tool", null);
|
|
311
|
-
AgentRunSteps = _ts_decorate2([
|
|
312
|
-
(0, import_common2.Injectable)(),
|
|
313
455
|
_ts_param2(0, (0, import_common2.Inject)(import_nestjs_agent_core2.AGENT_DEPS_FACTORY)),
|
|
456
|
+
_ts_param2(1, (0, import_common2.Inject)(import_nestjs_agent_core2.AGENT_STORE)),
|
|
457
|
+
_ts_param2(2, (0, import_common2.Inject)(AGENT_DISPATCHED_STEPS)),
|
|
458
|
+
_ts_param2(3, (0, import_common2.Optional)()),
|
|
459
|
+
_ts_param2(3, (0, import_common2.Inject)(import_nestjs_durable2.RUN_GATEWAY)),
|
|
314
460
|
_ts_metadata2("design:type", Function),
|
|
315
461
|
_ts_metadata2("design:paramtypes", [
|
|
316
|
-
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
|
|
462
|
+
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
|
|
463
|
+
typeof AgentStore === "undefined" ? Object : AgentStore,
|
|
464
|
+
Boolean,
|
|
465
|
+
typeof RunGateway === "undefined" ? Object : RunGateway
|
|
317
466
|
])
|
|
318
|
-
],
|
|
467
|
+
], AgentRunWorkflow);
|
|
319
468
|
|
|
320
469
|
// src/durable/durable-agent-runner.ts
|
|
321
470
|
var import_node_crypto = require("crypto");
|
|
471
|
+
var import_nestjs_agent_core3 = require("@dudousxd/nestjs-agent-core");
|
|
322
472
|
var import_nestjs_durable3 = require("@dudousxd/nestjs-durable");
|
|
323
473
|
var import_nestjs_durable_core2 = require("@dudousxd/nestjs-durable-core");
|
|
324
474
|
var import_common3 = require("@nestjs/common");
|
|
@@ -333,13 +483,26 @@ function _ts_metadata3(k, v) {
|
|
|
333
483
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
334
484
|
}
|
|
335
485
|
__name(_ts_metadata3, "_ts_metadata");
|
|
336
|
-
|
|
486
|
+
function _ts_param3(paramIndex, decorator) {
|
|
487
|
+
return function(target, key) {
|
|
488
|
+
decorator(target, key, paramIndex);
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
__name(_ts_param3, "_ts_param");
|
|
492
|
+
var DurableAgentRunner = class _DurableAgentRunner {
|
|
337
493
|
static {
|
|
338
494
|
__name(this, "DurableAgentRunner");
|
|
339
495
|
}
|
|
340
496
|
workflows;
|
|
341
|
-
|
|
497
|
+
runs;
|
|
498
|
+
store;
|
|
499
|
+
sink;
|
|
500
|
+
logger = new import_common3.Logger(_DurableAgentRunner.name);
|
|
501
|
+
constructor(workflows, runs, store, sink) {
|
|
342
502
|
this.workflows = workflows;
|
|
503
|
+
this.runs = runs;
|
|
504
|
+
this.store = store;
|
|
505
|
+
this.sink = sink;
|
|
343
506
|
}
|
|
344
507
|
async start(input) {
|
|
345
508
|
const stamped = {
|
|
@@ -358,27 +521,62 @@ var DurableAgentRunner = class {
|
|
|
358
521
|
runId
|
|
359
522
|
};
|
|
360
523
|
}
|
|
361
|
-
async signal(runId,
|
|
362
|
-
await this.workflows.signal(`tool:${runId}:${
|
|
524
|
+
async signal(runId, toolCallId2, reply) {
|
|
525
|
+
await this.workflows.signal(`tool:${runId}:${toolCallId2}`, reply);
|
|
363
526
|
}
|
|
364
|
-
|
|
365
|
-
|
|
527
|
+
/**
|
|
528
|
+
* Stop a run, and settle what the durable runtime knows nothing about.
|
|
529
|
+
*
|
|
530
|
+
* `compensate: true` is the form that gives the BODY a chance: it moves the run to `cancelling`
|
|
531
|
+
* (which is what the workflow's own cancel observation reads) and then re-drives it, so a turn
|
|
532
|
+
* running in-process unwinds at its next safe point instead of finishing. It also guarantees the
|
|
533
|
+
* outcome for the turn that CANNOT observe anything — one parked on `waitForSignal`, suspended
|
|
534
|
+
* inside a position its journal already holds — because that re-drive re-suspends and the runtime
|
|
535
|
+
* settles the run `cancelled` regardless. The cascade to child runs comes with it.
|
|
536
|
+
*
|
|
537
|
+
* Neither of those settles the agent's own state, so this does: the run row gets its own terminal,
|
|
538
|
+
* and the subscriber gets a `cancelled` frame followed by a normal end. Both are keyed by runId
|
|
539
|
+
* alone, which is why they belong here rather than in the body — the body is the only place that
|
|
540
|
+
* knows which THREAD was streaming, so releasing that stays there (see `AgentRunWorkflow`).
|
|
541
|
+
*
|
|
542
|
+
* A tool already executing is not interrupted, here or anywhere: see `haltIfCancelled` in core.
|
|
543
|
+
*/
|
|
544
|
+
async cancel(runId) {
|
|
545
|
+
this.logger.log(`cancelling agent run ${runId}`);
|
|
546
|
+
await this.runs.cancel(runId, {
|
|
547
|
+
compensate: true
|
|
548
|
+
});
|
|
549
|
+
const writer = await this.sink.open(runId);
|
|
550
|
+
await writer.write((0, import_nestjs_agent_core3.encodeStreamEvent)({
|
|
551
|
+
kind: "cancelled"
|
|
552
|
+
}));
|
|
553
|
+
await writer.end();
|
|
554
|
+
await this.store.recordRunEnd?.({
|
|
555
|
+
runId,
|
|
556
|
+
status: "cancelled"
|
|
557
|
+
});
|
|
366
558
|
}
|
|
367
559
|
};
|
|
368
560
|
DurableAgentRunner = _ts_decorate3([
|
|
369
561
|
(0, import_common3.Injectable)(),
|
|
562
|
+
_ts_param3(1, (0, import_common3.Inject)(import_nestjs_durable3.RUN_GATEWAY)),
|
|
563
|
+
_ts_param3(2, (0, import_common3.Inject)(import_nestjs_agent_core3.AGENT_STORE)),
|
|
564
|
+
_ts_param3(3, (0, import_common3.Inject)(import_nestjs_agent_core3.AGENT_SINK)),
|
|
370
565
|
_ts_metadata3("design:type", Function),
|
|
371
566
|
_ts_metadata3("design:paramtypes", [
|
|
372
|
-
typeof import_nestjs_durable3.WorkflowService === "undefined" ? Object : import_nestjs_durable3.WorkflowService
|
|
567
|
+
typeof import_nestjs_durable3.WorkflowService === "undefined" ? Object : import_nestjs_durable3.WorkflowService,
|
|
568
|
+
typeof RunGateway === "undefined" ? Object : RunGateway,
|
|
569
|
+
typeof AgentStore === "undefined" ? Object : AgentStore,
|
|
570
|
+
typeof TokenStreamSink === "undefined" ? Object : TokenStreamSink
|
|
373
571
|
])
|
|
374
572
|
], DurableAgentRunner);
|
|
375
573
|
|
|
376
574
|
// src/durable/agent-durable.module.ts
|
|
377
|
-
var
|
|
575
|
+
var import_nestjs_agent_core5 = require("@dudousxd/nestjs-agent-core");
|
|
378
576
|
var import_common4 = require("@nestjs/common");
|
|
379
577
|
|
|
380
578
|
// src/in-process-sink.ts
|
|
381
|
-
var
|
|
579
|
+
var import_nestjs_agent_core4 = require("@dudousxd/nestjs-agent-core");
|
|
382
580
|
var InProcessTokenStreamSink = class {
|
|
383
581
|
static {
|
|
384
582
|
__name(this, "InProcessTokenStreamSink");
|
|
@@ -433,7 +631,7 @@ var InProcessTokenStreamSink = class {
|
|
|
433
631
|
}
|
|
434
632
|
if (buf.ended) {
|
|
435
633
|
if (buf.failure !== void 0) {
|
|
436
|
-
throw new
|
|
634
|
+
throw new import_nestjs_agent_core4.AgentStreamError(buf.failure);
|
|
437
635
|
}
|
|
438
636
|
return;
|
|
439
637
|
}
|
|
@@ -458,7 +656,7 @@ function runnerProviders() {
|
|
|
458
656
|
return [
|
|
459
657
|
DurableAgentRunner,
|
|
460
658
|
{
|
|
461
|
-
provide:
|
|
659
|
+
provide: import_nestjs_agent_core5.AGENT_DURABLE_RUNNER,
|
|
462
660
|
useExisting: DurableAgentRunner
|
|
463
661
|
},
|
|
464
662
|
{
|
|
@@ -471,8 +669,8 @@ function runnerProviders() {
|
|
|
471
669
|
return enabled;
|
|
472
670
|
}, "useFactory"),
|
|
473
671
|
inject: [
|
|
474
|
-
|
|
475
|
-
|
|
672
|
+
import_nestjs_agent_core5.AGENT_OPTIONS,
|
|
673
|
+
import_nestjs_agent_core5.AGENT_SINK
|
|
476
674
|
]
|
|
477
675
|
}
|
|
478
676
|
];
|
|
@@ -491,7 +689,7 @@ AgentDurableHttpModule = _ts_decorate4([
|
|
|
491
689
|
...runnerProviders()
|
|
492
690
|
],
|
|
493
691
|
exports: [
|
|
494
|
-
|
|
692
|
+
import_nestjs_agent_core5.AGENT_DURABLE_RUNNER,
|
|
495
693
|
AgentRunWorkflow,
|
|
496
694
|
AGENT_DISPATCHED_STEPS
|
|
497
695
|
]
|
|
@@ -531,7 +729,7 @@ AgentDurableModule = _ts_decorate4([
|
|
|
531
729
|
...runnerProviders()
|
|
532
730
|
],
|
|
533
731
|
exports: [
|
|
534
|
-
|
|
732
|
+
import_nestjs_agent_core5.AGENT_DURABLE_RUNNER,
|
|
535
733
|
AgentRunWorkflow,
|
|
536
734
|
AgentRunSteps,
|
|
537
735
|
AGENT_DISPATCHED_STEPS
|
|
@@ -540,13 +738,13 @@ AgentDurableModule = _ts_decorate4([
|
|
|
540
738
|
], AgentDurableModule);
|
|
541
739
|
|
|
542
740
|
// src/agent.module.ts
|
|
543
|
-
var
|
|
544
|
-
var
|
|
545
|
-
var
|
|
741
|
+
var import_nestjs_agent_core23 = require("@dudousxd/nestjs-agent-core");
|
|
742
|
+
var import_common20 = require("@nestjs/common");
|
|
743
|
+
var import_core4 = require("@nestjs/core");
|
|
546
744
|
|
|
547
745
|
// src/agent-deps.factory.ts
|
|
548
|
-
var import_nestjs_agent_core5 = require("@dudousxd/nestjs-agent-core");
|
|
549
746
|
var import_nestjs_agent_core6 = require("@dudousxd/nestjs-agent-core");
|
|
747
|
+
var import_nestjs_agent_core7 = require("@dudousxd/nestjs-agent-core");
|
|
550
748
|
var import_common5 = require("@nestjs/common");
|
|
551
749
|
function _ts_decorate5(decorators, target, key, desc) {
|
|
552
750
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -559,14 +757,15 @@ function _ts_metadata4(k, v) {
|
|
|
559
757
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
560
758
|
}
|
|
561
759
|
__name(_ts_metadata4, "_ts_metadata");
|
|
562
|
-
function
|
|
760
|
+
function _ts_param4(paramIndex, decorator) {
|
|
563
761
|
return function(target, key) {
|
|
564
762
|
decorator(target, key, paramIndex);
|
|
565
763
|
};
|
|
566
764
|
}
|
|
567
|
-
__name(
|
|
568
|
-
function delegateToolName(
|
|
569
|
-
|
|
765
|
+
__name(_ts_param4, "_ts_param");
|
|
766
|
+
function delegateToolName(args) {
|
|
767
|
+
const slug = args.target.replace(/[^a-zA-Z0-9]+/g, "_");
|
|
768
|
+
return args.detached === true ? `start_${slug}` : `ask_${slug}`;
|
|
570
769
|
}
|
|
571
770
|
__name(delegateToolName, "delegateToolName");
|
|
572
771
|
var AgentDepsFactory2 = class {
|
|
@@ -583,7 +782,9 @@ var AgentDepsFactory2 = class {
|
|
|
583
782
|
promptContributors;
|
|
584
783
|
quota;
|
|
585
784
|
pricingStore;
|
|
586
|
-
|
|
785
|
+
skills;
|
|
786
|
+
memory;
|
|
787
|
+
constructor(options, model, store, sink, rolesPolicy, registry, agents, promptContributors, quota, pricingStore, skills, memory) {
|
|
587
788
|
this.options = options;
|
|
588
789
|
this.model = model;
|
|
589
790
|
this.store = store;
|
|
@@ -594,6 +795,16 @@ var AgentDepsFactory2 = class {
|
|
|
594
795
|
this.promptContributors = promptContributors;
|
|
595
796
|
this.quota = quota;
|
|
596
797
|
this.pricingStore = pricingStore;
|
|
798
|
+
this.skills = skills;
|
|
799
|
+
this.memory = memory;
|
|
800
|
+
}
|
|
801
|
+
/** The turn's memory seam, shared with the read-back endpoint. Undefined → memory is not configured. */
|
|
802
|
+
memoryConfig() {
|
|
803
|
+
return this.memory;
|
|
804
|
+
}
|
|
805
|
+
/** The turn's skills seam, shared with the listing endpoint. Undefined → skills are not configured. */
|
|
806
|
+
skillsConfig() {
|
|
807
|
+
return this.skills;
|
|
597
808
|
}
|
|
598
809
|
/**
|
|
599
810
|
* The agent a turn uses when the caller names none: the explicit `defaultAgent` option, else the
|
|
@@ -610,7 +821,13 @@ var AgentDepsFactory2 = class {
|
|
|
610
821
|
if (definition === void 0) {
|
|
611
822
|
return void 0;
|
|
612
823
|
}
|
|
613
|
-
const delegated = (definition.delegatesTo ?? []).map(
|
|
824
|
+
const delegated = (definition.delegatesTo ?? []).map((edge) => {
|
|
825
|
+
const { agent, detached } = (0, import_nestjs_agent_core6.normalizeDelegation)(edge);
|
|
826
|
+
return delegateToolName({
|
|
827
|
+
target: agent,
|
|
828
|
+
detached
|
|
829
|
+
});
|
|
830
|
+
});
|
|
614
831
|
if (definition.tools === void 0 && delegated.length === 0) {
|
|
615
832
|
return void 0;
|
|
616
833
|
}
|
|
@@ -625,6 +842,8 @@ var AgentDepsFactory2 = class {
|
|
|
625
842
|
const toolAllowList = this.effectiveTools(definition);
|
|
626
843
|
const followUpsCount = this.followUpsCount();
|
|
627
844
|
const retrieval = this.options.retrieval;
|
|
845
|
+
const historyPolicy = this.historyPolicy(definition);
|
|
846
|
+
const ask = definition?.ask ?? this.options.ask;
|
|
628
847
|
return {
|
|
629
848
|
model: this.model,
|
|
630
849
|
store: this.store,
|
|
@@ -634,6 +853,12 @@ var AgentDepsFactory2 = class {
|
|
|
634
853
|
promptContributors: this.promptContributors,
|
|
635
854
|
systemPrompt: definition?.systemPrompt ?? "You are a helpful assistant.",
|
|
636
855
|
maxSteps: definition?.maxSteps ?? 8,
|
|
856
|
+
...definition?.maxDelegationDepth !== void 0 ? {
|
|
857
|
+
maxDelegationDepth: definition.maxDelegationDepth
|
|
858
|
+
} : {},
|
|
859
|
+
...definition?.maxAgentAppearances !== void 0 ? {
|
|
860
|
+
maxAgentAppearances: definition.maxAgentAppearances
|
|
861
|
+
} : {},
|
|
637
862
|
...definition?.modelId !== void 0 ? {
|
|
638
863
|
modelId: definition.modelId
|
|
639
864
|
} : {},
|
|
@@ -643,6 +868,37 @@ var AgentDepsFactory2 = class {
|
|
|
643
868
|
...this.pricingStore !== void 0 ? {
|
|
644
869
|
pricingStore: this.pricingStore
|
|
645
870
|
} : {},
|
|
871
|
+
...historyPolicy !== void 0 ? {
|
|
872
|
+
historyPolicy
|
|
873
|
+
} : {},
|
|
874
|
+
inputProcessors: this.options.inputProcessors ?? [],
|
|
875
|
+
outputProcessors: this.options.outputProcessors ?? [],
|
|
876
|
+
...definition?.outputSchema !== void 0 ? {
|
|
877
|
+
outputSchema: definition.outputSchema
|
|
878
|
+
} : {},
|
|
879
|
+
...definition?.outputRepairAttempts !== void 0 ? {
|
|
880
|
+
outputRepairAttempts: definition.outputRepairAttempts
|
|
881
|
+
} : {},
|
|
882
|
+
...definition?.intake !== void 0 ? {
|
|
883
|
+
intake: definition.intake
|
|
884
|
+
} : {},
|
|
885
|
+
// Most specific wins, exactly as `historyPolicy` resolves: the agent's own `@Agent({ ask })`,
|
|
886
|
+
// else the module-wide flag. Both are module config, so every process of a deployment agrees.
|
|
887
|
+
...ask === true ? {
|
|
888
|
+
ask: true
|
|
889
|
+
} : {},
|
|
890
|
+
// Module-wide, never per-agent: a skill is a procedure, not a persona, and an agent that could
|
|
891
|
+
// opt out of one would make the catalog depend on which agent a turn happened to select — a
|
|
892
|
+
// per-turn fact the worker re-deriving the tool list cannot see.
|
|
893
|
+
...this.skills !== void 0 ? {
|
|
894
|
+
skills: this.skills
|
|
895
|
+
} : {},
|
|
896
|
+
// Module-wide, never per-agent, for the same reason skills are: which memories a turn carries
|
|
897
|
+
// cannot depend on which persona answered it, or the worker re-deriving a dispatched turn's
|
|
898
|
+
// tool list would disagree with the loop about whether `remember` was offered.
|
|
899
|
+
...this.memory !== void 0 ? {
|
|
900
|
+
memory: this.memory
|
|
901
|
+
} : {},
|
|
646
902
|
...toolAllowList !== void 0 ? {
|
|
647
903
|
toolAllowList
|
|
648
904
|
} : {},
|
|
@@ -663,6 +919,36 @@ var AgentDepsFactory2 = class {
|
|
|
663
919
|
} : {}
|
|
664
920
|
};
|
|
665
921
|
}
|
|
922
|
+
/**
|
|
923
|
+
* The ceiling on how much of a thread this agent's turns carry, most specific wins: the agent's
|
|
924
|
+
* own `@Agent({ history })`, else a module-wide custom `historyPolicy`, else the module-wide
|
|
925
|
+
* `history` window. Undefined → unbounded, the behaviour of a module that configures none.
|
|
926
|
+
*/
|
|
927
|
+
historyPolicy(definition) {
|
|
928
|
+
if (definition?.history !== void 0) {
|
|
929
|
+
return this.window(definition.history);
|
|
930
|
+
}
|
|
931
|
+
if (this.options.historyPolicy !== void 0) {
|
|
932
|
+
return this.options.historyPolicy;
|
|
933
|
+
}
|
|
934
|
+
return this.options.history === void 0 ? void 0 : this.window(this.options.history);
|
|
935
|
+
}
|
|
936
|
+
/** Build the built-in window policy from the declarative `{ maxMessages, maxTokens, summarize }`. */
|
|
937
|
+
window(config) {
|
|
938
|
+
return (0, import_nestjs_agent_core6.windowHistory)({
|
|
939
|
+
...config.maxMessages !== void 0 ? {
|
|
940
|
+
maxMessages: config.maxMessages
|
|
941
|
+
} : {},
|
|
942
|
+
...config.maxTokens !== void 0 ? {
|
|
943
|
+
maxTokens: config.maxTokens
|
|
944
|
+
} : {},
|
|
945
|
+
// The shared module model, not a per-agent one: an agent's `modelId` is an accounting label,
|
|
946
|
+
// and only one provider is ever bound.
|
|
947
|
+
...config.summarize === true ? {
|
|
948
|
+
summarize: (0, import_nestjs_agent_core6.summarizeWithModel)(this.model)
|
|
949
|
+
} : {}
|
|
950
|
+
});
|
|
951
|
+
}
|
|
666
952
|
/** Normalize the `followUps` option (`true` → 3, `{ count }` → count) to a number, or undefined. */
|
|
667
953
|
followUpsCount() {
|
|
668
954
|
const followUps = this.options.followUps;
|
|
@@ -677,17 +963,21 @@ var AgentDepsFactory2 = class {
|
|
|
677
963
|
};
|
|
678
964
|
AgentDepsFactory2 = _ts_decorate5([
|
|
679
965
|
(0, import_common5.Injectable)(),
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
966
|
+
_ts_param4(0, (0, import_common5.Inject)(import_nestjs_agent_core7.AGENT_OPTIONS)),
|
|
967
|
+
_ts_param4(1, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_MODEL)),
|
|
968
|
+
_ts_param4(2, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_STORE)),
|
|
969
|
+
_ts_param4(3, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_SINK)),
|
|
970
|
+
_ts_param4(4, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_ROLES_POLICY)),
|
|
971
|
+
_ts_param4(5, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_TOOL_REGISTRY)),
|
|
972
|
+
_ts_param4(6, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_REGISTRY)),
|
|
973
|
+
_ts_param4(7, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_PROMPT_CONTRIBUTORS)),
|
|
974
|
+
_ts_param4(8, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_QUOTA_STORE)),
|
|
975
|
+
_ts_param4(9, (0, import_common5.Optional)()),
|
|
976
|
+
_ts_param4(9, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_PRICING_STORE)),
|
|
977
|
+
_ts_param4(10, (0, import_common5.Optional)()),
|
|
978
|
+
_ts_param4(10, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_SKILLS)),
|
|
979
|
+
_ts_param4(11, (0, import_common5.Optional)()),
|
|
980
|
+
_ts_param4(11, (0, import_common5.Inject)(import_nestjs_agent_core6.AGENT_MEMORY)),
|
|
691
981
|
_ts_metadata4("design:type", Function),
|
|
692
982
|
_ts_metadata4("design:paramtypes", [
|
|
693
983
|
typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
|
|
@@ -695,16 +985,18 @@ AgentDepsFactory2 = _ts_decorate5([
|
|
|
695
985
|
typeof AgentStore === "undefined" ? Object : AgentStore,
|
|
696
986
|
typeof TokenStreamSink === "undefined" ? Object : TokenStreamSink,
|
|
697
987
|
typeof RolesPolicy === "undefined" ? Object : RolesPolicy,
|
|
698
|
-
typeof
|
|
699
|
-
typeof
|
|
988
|
+
typeof import_nestjs_agent_core6.ToolRegistry === "undefined" ? Object : import_nestjs_agent_core6.ToolRegistry,
|
|
989
|
+
typeof import_nestjs_agent_core6.AgentRegistry === "undefined" ? Object : import_nestjs_agent_core6.AgentRegistry,
|
|
700
990
|
Array,
|
|
701
991
|
Object,
|
|
992
|
+
Object,
|
|
993
|
+
Object,
|
|
702
994
|
Object
|
|
703
995
|
])
|
|
704
996
|
], AgentDepsFactory2);
|
|
705
997
|
|
|
706
998
|
// src/agent.service.ts
|
|
707
|
-
var
|
|
999
|
+
var import_nestjs_agent_core8 = require("@dudousxd/nestjs-agent-core");
|
|
708
1000
|
var import_common6 = require("@nestjs/common");
|
|
709
1001
|
function _ts_decorate6(decorators, target, key, desc) {
|
|
710
1002
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -717,12 +1009,12 @@ function _ts_metadata5(k, v) {
|
|
|
717
1009
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
718
1010
|
}
|
|
719
1011
|
__name(_ts_metadata5, "_ts_metadata");
|
|
720
|
-
function
|
|
1012
|
+
function _ts_param5(paramIndex, decorator) {
|
|
721
1013
|
return function(target, key) {
|
|
722
1014
|
decorator(target, key, paramIndex);
|
|
723
1015
|
};
|
|
724
1016
|
}
|
|
725
|
-
__name(
|
|
1017
|
+
__name(_ts_param5, "_ts_param");
|
|
726
1018
|
var AgentService = class {
|
|
727
1019
|
static {
|
|
728
1020
|
__name(this, "AgentService");
|
|
@@ -731,14 +1023,17 @@ var AgentService = class {
|
|
|
731
1023
|
store;
|
|
732
1024
|
deps;
|
|
733
1025
|
quota;
|
|
734
|
-
|
|
1026
|
+
staging;
|
|
1027
|
+
constructor(runner, store, deps, quota, staging) {
|
|
735
1028
|
this.runner = runner;
|
|
736
1029
|
this.store = store;
|
|
737
1030
|
this.deps = deps;
|
|
738
1031
|
this.quota = quota;
|
|
1032
|
+
this.staging = staging;
|
|
739
1033
|
}
|
|
740
1034
|
async chat(params) {
|
|
741
1035
|
const agentName = await this.resolveAgentName(params.agentName, params.threadId);
|
|
1036
|
+
const attachments = await this.resolveAttachments(params.actor, params.attachments ?? []);
|
|
742
1037
|
let threadId = params.threadId;
|
|
743
1038
|
if (threadId === void 0) {
|
|
744
1039
|
if (params.regenerate === true) {
|
|
@@ -763,8 +1058,8 @@ var AgentService = class {
|
|
|
763
1058
|
...params.regenerate === true ? {
|
|
764
1059
|
regenerate: true
|
|
765
1060
|
} : {},
|
|
766
|
-
...
|
|
767
|
-
attachments
|
|
1061
|
+
...attachments.length > 0 ? {
|
|
1062
|
+
attachments
|
|
768
1063
|
} : {},
|
|
769
1064
|
...params.pageContext !== void 0 ? {
|
|
770
1065
|
pageContext: params.pageContext
|
|
@@ -777,18 +1072,66 @@ var AgentService = class {
|
|
|
777
1072
|
threadId
|
|
778
1073
|
};
|
|
779
1074
|
}
|
|
1075
|
+
/**
|
|
1076
|
+
* Rebuild this turn's attachments from the staging store, keyed by the ids the caller claimed.
|
|
1077
|
+
* The model provider fetches {@link MessageAttachment.url} verbatim, so that url is only ever
|
|
1078
|
+
* allowed to come from the host's own store — a caller that could name it could point the server
|
|
1079
|
+
* at anything it can reach (cloud metadata, internal services) and read the response back out of
|
|
1080
|
+
* the model's answer.
|
|
1081
|
+
*
|
|
1082
|
+
* No store bound means no way to tell an id the actor owns from one they don't, so a turn simply
|
|
1083
|
+
* cannot carry attachments: 501 rather than trusting the request.
|
|
1084
|
+
*/
|
|
1085
|
+
async resolveAttachments(actor, refs) {
|
|
1086
|
+
if (refs.length === 0) {
|
|
1087
|
+
return [];
|
|
1088
|
+
}
|
|
1089
|
+
const staging = this.staging;
|
|
1090
|
+
if (staging === void 0 || typeof staging.resolve !== "function") {
|
|
1091
|
+
throw new import_common6.NotImplementedException("Message attachments require an AGENT_ATTACHMENT_STAGING provider implementing resolve(); attachment urls are never taken from the request.");
|
|
1092
|
+
}
|
|
1093
|
+
const resolved = [];
|
|
1094
|
+
for (const ref of refs) {
|
|
1095
|
+
const attachment = await staging.resolve({
|
|
1096
|
+
mediaId: ref.mediaId,
|
|
1097
|
+
actor
|
|
1098
|
+
});
|
|
1099
|
+
if (attachment === null) {
|
|
1100
|
+
throw new import_common6.ForbiddenException(`attachment ${ref.mediaId} is not available to this actor`);
|
|
1101
|
+
}
|
|
1102
|
+
resolved.push(attachment);
|
|
1103
|
+
}
|
|
1104
|
+
return resolved;
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* The run's live token stream, WITHOUT an ownership check — for in-process callers that are
|
|
1108
|
+
* already authorized (the MCP bridge, a host's own job code), the same split as
|
|
1109
|
+
* {@link signalToolCall} vs {@link approve}. Anything reachable from a request must go through
|
|
1110
|
+
* {@link subscribeAs} instead: a runId is the only thing standing between a caller and another
|
|
1111
|
+
* actor's answer, tool arguments and tool results.
|
|
1112
|
+
*/
|
|
780
1113
|
subscribe(runId) {
|
|
781
1114
|
return this.deps.forAgent().sink.subscribe(runId);
|
|
782
1115
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
1116
|
+
/**
|
|
1117
|
+
* {@link subscribe}, gated the way {@link cancel} is: only the actor whose thread is currently
|
|
1118
|
+
* streaming this run may read it. A run that has already finished is reported missing rather than
|
|
1119
|
+
* replayed — the runner clears the thread's active stream as the run ends, and that field is what
|
|
1120
|
+
* ownership is derived from.
|
|
1121
|
+
*/
|
|
1122
|
+
async subscribeAs(actor, runId) {
|
|
1123
|
+
await this.assertOwnsActiveStream(actor, runId);
|
|
1124
|
+
return this.subscribe(runId);
|
|
1125
|
+
}
|
|
1126
|
+
async approve(actor, toolCallId2) {
|
|
1127
|
+
await this.assertOwnsToolCall(actor, toolCallId2);
|
|
1128
|
+
return this.signalToolCall(toolCallId2, {
|
|
786
1129
|
approved: true
|
|
787
1130
|
});
|
|
788
1131
|
}
|
|
789
|
-
async reject(actor,
|
|
790
|
-
await this.assertOwnsToolCall(actor,
|
|
791
|
-
return this.signalToolCall(
|
|
1132
|
+
async reject(actor, toolCallId2, reason) {
|
|
1133
|
+
await this.assertOwnsToolCall(actor, toolCallId2);
|
|
1134
|
+
return this.signalToolCall(toolCallId2, {
|
|
792
1135
|
approved: false,
|
|
793
1136
|
...reason !== void 0 ? {
|
|
794
1137
|
reason
|
|
@@ -796,6 +1139,34 @@ var AgentService = class {
|
|
|
796
1139
|
});
|
|
797
1140
|
}
|
|
798
1141
|
/**
|
|
1142
|
+
* Answer a parked question set. An omitted question takes the request's own pre-picked default —
|
|
1143
|
+
* resolved by the LOOP against the request it already holds, so "the user just submitted" and
|
|
1144
|
+
* "the user picked exactly the defaults" persist as the same answers, and no client has to
|
|
1145
|
+
* re-send what it was shown.
|
|
1146
|
+
*/
|
|
1147
|
+
async answer(actor, toolCallId2, answers2 = {}) {
|
|
1148
|
+
await this.assertOwnsToolCall(actor, toolCallId2);
|
|
1149
|
+
const reply = {
|
|
1150
|
+
answers: answers2,
|
|
1151
|
+
answeredByRef: actor.id
|
|
1152
|
+
};
|
|
1153
|
+
return this.signalToolCall(toolCallId2, reply);
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* Decline to answer and let the agent proceed on its own assumptions. NOT the same as confirming
|
|
1157
|
+
* them: the run records this as a rejection, so a reader auditing what the agent was told can
|
|
1158
|
+
* tell a choice the user made from one they refused to make.
|
|
1159
|
+
*/
|
|
1160
|
+
async skip(actor, toolCallId2) {
|
|
1161
|
+
await this.assertOwnsToolCall(actor, toolCallId2);
|
|
1162
|
+
const reply = {
|
|
1163
|
+
answers: {},
|
|
1164
|
+
skipped: true,
|
|
1165
|
+
answeredByRef: actor.id
|
|
1166
|
+
};
|
|
1167
|
+
return this.signalToolCall(toolCallId2, reply);
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
799
1170
|
* The decision core behind approve/reject, WITHOUT an ownership check: resolves the run
|
|
800
1171
|
* currently awaiting `toolCallId` and signals it. `approve`/`reject` above call this after their
|
|
801
1172
|
* own `assertOwnsToolCall` gate; the console `AgentApprovalPort` adapter (bound by `AgentModule`)
|
|
@@ -803,9 +1174,9 @@ var AgentService = class {
|
|
|
803
1174
|
* re-deriving thread ownership here would reject a legitimate operator decision (an operator is
|
|
804
1175
|
* not the thread's own actor).
|
|
805
1176
|
*/
|
|
806
|
-
async signalToolCall(
|
|
807
|
-
const runId = await this.resolveRunForToolCall(
|
|
808
|
-
return this.runner.signal(runId,
|
|
1177
|
+
async signalToolCall(toolCallId2, reply) {
|
|
1178
|
+
const runId = await this.resolveRunForToolCall(toolCallId2);
|
|
1179
|
+
return this.runner.signal(runId, toolCallId2, reply);
|
|
809
1180
|
}
|
|
810
1181
|
async cancel(actor, runId) {
|
|
811
1182
|
await this.assertOwnsActiveStream(actor, runId);
|
|
@@ -872,20 +1243,33 @@ var AgentService = class {
|
|
|
872
1243
|
/**
|
|
873
1244
|
* Agent-selection precedence for a `chat()` call with no explicit `agentName`: the thread's own
|
|
874
1245
|
* `defaultAgent` (if the thread exists and one is set) wins over the module's configured default.
|
|
875
|
-
* Skips the
|
|
1246
|
+
* Skips the store entirely when the caller already named an agent or there's no thread yet.
|
|
1247
|
+
*
|
|
1248
|
+
* What this needs is one nullable scalar, so it asks for one. `getThread` returns the entire
|
|
1249
|
+
* transcript — every message, every persisted tool output — and this discards all of it; on a
|
|
1250
|
+
* long thread with large tool results that is hundreds of kilobytes read per turn, outside the
|
|
1251
|
+
* workflow, for a string. A store predating {@link ThreadDefaultAgentReader} still answers, via
|
|
1252
|
+
* the full read.
|
|
876
1253
|
*/
|
|
877
1254
|
async resolveAgentName(agentName, threadId) {
|
|
878
1255
|
if (agentName !== void 0) {
|
|
879
1256
|
return agentName;
|
|
880
1257
|
}
|
|
881
1258
|
if (threadId !== void 0) {
|
|
882
|
-
const
|
|
883
|
-
if (
|
|
884
|
-
return
|
|
1259
|
+
const threadDefault = await this.threadDefaultAgent(threadId);
|
|
1260
|
+
if (threadDefault !== null) {
|
|
1261
|
+
return threadDefault;
|
|
885
1262
|
}
|
|
886
1263
|
}
|
|
887
1264
|
return this.deps.defaultAgentName();
|
|
888
1265
|
}
|
|
1266
|
+
async threadDefaultAgent(threadId) {
|
|
1267
|
+
const projecting = this.store;
|
|
1268
|
+
if (typeof projecting.defaultAgentForThread === "function") {
|
|
1269
|
+
return projecting.defaultAgentForThread(threadId);
|
|
1270
|
+
}
|
|
1271
|
+
return (await this.store.getThread(threadId))?.defaultAgent ?? null;
|
|
1272
|
+
}
|
|
889
1273
|
async toSummaryView(thread) {
|
|
890
1274
|
return {
|
|
891
1275
|
...thread,
|
|
@@ -908,13 +1292,74 @@ var AgentService = class {
|
|
|
908
1292
|
return this.store.promoteThread(threadId);
|
|
909
1293
|
}
|
|
910
1294
|
/**
|
|
911
|
-
* Drop a message and everything after it — the "edit and resend" / "delete from here" primitive.
|
|
912
|
-
* The client then sends a fresh turn on the truncated thread. Ownership-gated like the other
|
|
913
|
-
* thread-scoped mutations.
|
|
1295
|
+
* Drop a message and everything after it — the "edit and resend" / "delete from here" primitive.
|
|
1296
|
+
* The client then sends a fresh turn on the truncated thread. Ownership-gated like the other
|
|
1297
|
+
* thread-scoped mutations.
|
|
1298
|
+
*/
|
|
1299
|
+
async truncateThreadFrom(actor, threadId, messageId) {
|
|
1300
|
+
await this.assertOwnsThread(actor, threadId);
|
|
1301
|
+
return this.store.truncateFrom(threadId, messageId);
|
|
1302
|
+
}
|
|
1303
|
+
/**
|
|
1304
|
+
* Every file this actor has staged, newest first — across threads, including uploads that were
|
|
1305
|
+
* never sent, which nothing else on this surface can see.
|
|
1306
|
+
*
|
|
1307
|
+
* Metadata only. A url is minted per turn by `resolve` so it can be short-lived, and handing one
|
|
1308
|
+
* back per entry would undo that for the price of rendering a list.
|
|
1309
|
+
*/
|
|
1310
|
+
async listAttachments(actor, options = {}) {
|
|
1311
|
+
const list = this.attachmentInventory();
|
|
1312
|
+
return list({
|
|
1313
|
+
actor,
|
|
1314
|
+
...options.limit !== void 0 ? {
|
|
1315
|
+
limit: options.limit
|
|
1316
|
+
} : {}
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1319
|
+
/**
|
|
1320
|
+
* This actor's staged media that no live message references and that is old enough not to be an
|
|
1321
|
+
* upload in flight — the candidate set for a sweep. Returns them; never deletes them. The bytes
|
|
1322
|
+
* are the host's, and so is the decision.
|
|
1323
|
+
*
|
|
1324
|
+
* `olderThan` is required and has no default. How long a composer may sit open with a file
|
|
1325
|
+
* attached is the host's knowledge, and a library-chosen grace period would eventually delete a
|
|
1326
|
+
* file someone was about to send. The staging store is asked to apply it, and the result is
|
|
1327
|
+
* filtered again here: a store that ignores the hint would otherwise turn this into exactly that
|
|
1328
|
+
* bug, silently.
|
|
1329
|
+
*
|
|
1330
|
+
* Both halves must be answerable or this refuses. An unanswerable reference query means "cannot
|
|
1331
|
+
* tell", and treating it as "nothing is referenced" would hand back every attachment the actor
|
|
1332
|
+
* ever sent, marked safe to delete.
|
|
1333
|
+
*/
|
|
1334
|
+
async collectableAttachments(actor, options) {
|
|
1335
|
+
const list = this.attachmentInventory();
|
|
1336
|
+
const referencedMediaIds = this.store.referencedMediaIds?.bind(this.store);
|
|
1337
|
+
if (referencedMediaIds === void 0) {
|
|
1338
|
+
throw new import_common6.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.");
|
|
1339
|
+
}
|
|
1340
|
+
const stagedBefore = options.olderThan.toISOString();
|
|
1341
|
+
const inventory = await list({
|
|
1342
|
+
actor,
|
|
1343
|
+
stagedBefore,
|
|
1344
|
+
...options.limit !== void 0 ? {
|
|
1345
|
+
limit: options.limit
|
|
1346
|
+
} : {}
|
|
1347
|
+
});
|
|
1348
|
+
const aged = inventory.filter((entry) => entry.createdAt < stagedBefore);
|
|
1349
|
+
const referenced = new Set(await referencedMediaIds(actor.id, aged.map((entry) => entry.mediaId)));
|
|
1350
|
+
return aged.filter((entry) => !referenced.has(entry.mediaId));
|
|
1351
|
+
}
|
|
1352
|
+
/**
|
|
1353
|
+
* The bound staging store's `list`, or a refusal. Absence is never answered with an empty list:
|
|
1354
|
+
* "this host keeps no inventory" and "this actor has no files" are opposite facts that would
|
|
1355
|
+
* otherwise render identically — as a clean file list, and as a sweep that collects nothing.
|
|
914
1356
|
*/
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
1357
|
+
attachmentInventory() {
|
|
1358
|
+
const list = this.staging?.list?.bind(this.staging);
|
|
1359
|
+
if (list === void 0) {
|
|
1360
|
+
throw new import_common6.NotImplementedException("Listing attachments requires an AGENT_ATTACHMENT_STAGING provider implementing list(); the host owns the staged bytes, so only it can enumerate them.");
|
|
1361
|
+
}
|
|
1362
|
+
return list;
|
|
918
1363
|
}
|
|
919
1364
|
/**
|
|
920
1365
|
* The day's usage for the badge: tokens + summed USD cost from the store, and the configured
|
|
@@ -958,24 +1403,26 @@ var AgentService = class {
|
|
|
958
1403
|
* out from run resolution (see {@link resolveRunForToolCall}) so the console `AgentApprovalPort`
|
|
959
1404
|
* adapter can resolve+signal a decision WITHOUT this check — it is authorized upstream instead.
|
|
960
1405
|
*/
|
|
961
|
-
async assertOwnsToolCall(actor,
|
|
962
|
-
const owner = await this.store.ownerOfToolCall(
|
|
1406
|
+
async assertOwnsToolCall(actor, toolCallId2) {
|
|
1407
|
+
const owner = await this.store.ownerOfToolCall(toolCallId2);
|
|
963
1408
|
if (owner === null) {
|
|
964
|
-
throw new import_common6.NotFoundException(`tool call ${
|
|
1409
|
+
throw new import_common6.NotFoundException(`tool call ${toolCallId2} not found`);
|
|
965
1410
|
}
|
|
966
1411
|
if (owner !== actor.id) {
|
|
967
1412
|
throw new import_common6.ForbiddenException("tool call belongs to another actor");
|
|
968
1413
|
}
|
|
969
1414
|
}
|
|
970
1415
|
/**
|
|
971
|
-
* Resolve the run
|
|
972
|
-
* sub-agent's own child run when the pending
|
|
973
|
-
*
|
|
1416
|
+
* Resolve the run awaiting `toolCallId`. Derived server-side from the tool call alone — the client
|
|
1417
|
+
* never knows or supplies a runId, and that run is the sub-agent's own child run when the pending
|
|
1418
|
+
* call belongs to a delegated agent. The store answers from the CALL'S OWN `runId` where it has
|
|
1419
|
+
* one; see `AgentStore.runForToolCall` for why that matters once a thread can hold more than one
|
|
1420
|
+
* live run.
|
|
974
1421
|
*/
|
|
975
|
-
async resolveRunForToolCall(
|
|
976
|
-
const runId = await this.store.runForToolCall(
|
|
1422
|
+
async resolveRunForToolCall(toolCallId2) {
|
|
1423
|
+
const runId = await this.store.runForToolCall(toolCallId2);
|
|
977
1424
|
if (runId === null) {
|
|
978
|
-
throw new import_common6.NotFoundException(`tool call ${
|
|
1425
|
+
throw new import_common6.NotFoundException(`tool call ${toolCallId2} has no active run to signal`);
|
|
979
1426
|
}
|
|
980
1427
|
return runId;
|
|
981
1428
|
}
|
|
@@ -992,16 +1439,19 @@ var AgentService = class {
|
|
|
992
1439
|
};
|
|
993
1440
|
AgentService = _ts_decorate6([
|
|
994
1441
|
(0, import_common6.Injectable)(),
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1442
|
+
_ts_param5(0, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_RUNNER)),
|
|
1443
|
+
_ts_param5(1, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_STORE)),
|
|
1444
|
+
_ts_param5(2, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_DEPS_FACTORY)),
|
|
1445
|
+
_ts_param5(3, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_QUOTA_STORE)),
|
|
1446
|
+
_ts_param5(4, (0, import_common6.Optional)()),
|
|
1447
|
+
_ts_param5(4, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_ATTACHMENT_STAGING)),
|
|
999
1448
|
_ts_metadata5("design:type", Function),
|
|
1000
1449
|
_ts_metadata5("design:paramtypes", [
|
|
1001
1450
|
typeof AgentRunner === "undefined" ? Object : AgentRunner,
|
|
1002
1451
|
typeof AgentStore === "undefined" ? Object : AgentStore,
|
|
1003
1452
|
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
|
|
1004
|
-
Object
|
|
1453
|
+
Object,
|
|
1454
|
+
typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore
|
|
1005
1455
|
])
|
|
1006
1456
|
], AgentService);
|
|
1007
1457
|
|
|
@@ -1026,16 +1476,16 @@ var AgentApprovalPortAdapter = class {
|
|
|
1026
1476
|
constructor(agent) {
|
|
1027
1477
|
this.agent = agent;
|
|
1028
1478
|
}
|
|
1029
|
-
async approve(
|
|
1030
|
-
await this.agent.signalToolCall(
|
|
1479
|
+
async approve(toolCallId2, opts) {
|
|
1480
|
+
await this.agent.signalToolCall(toolCallId2, {
|
|
1031
1481
|
approved: true,
|
|
1032
1482
|
...opts?.executedByRef !== void 0 ? {
|
|
1033
1483
|
executedByRef: opts.executedByRef
|
|
1034
1484
|
} : {}
|
|
1035
1485
|
});
|
|
1036
1486
|
}
|
|
1037
|
-
async reject(
|
|
1038
|
-
await this.agent.signalToolCall(
|
|
1487
|
+
async reject(toolCallId2, opts) {
|
|
1488
|
+
await this.agent.signalToolCall(toolCallId2, {
|
|
1039
1489
|
approved: false,
|
|
1040
1490
|
...opts?.executedByRef !== void 0 ? {
|
|
1041
1491
|
executedByRef: opts.executedByRef
|
|
@@ -1055,7 +1505,7 @@ AgentApprovalPortAdapter = _ts_decorate7([
|
|
|
1055
1505
|
], AgentApprovalPortAdapter);
|
|
1056
1506
|
|
|
1057
1507
|
// src/controller/agents.controller.ts
|
|
1058
|
-
var
|
|
1508
|
+
var import_nestjs_agent_core9 = require("@dudousxd/nestjs-agent-core");
|
|
1059
1509
|
var import_common8 = require("@nestjs/common");
|
|
1060
1510
|
function _ts_decorate8(decorators, target, key, desc) {
|
|
1061
1511
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -1068,12 +1518,12 @@ function _ts_metadata7(k, v) {
|
|
|
1068
1518
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1069
1519
|
}
|
|
1070
1520
|
__name(_ts_metadata7, "_ts_metadata");
|
|
1071
|
-
function
|
|
1521
|
+
function _ts_param6(paramIndex, decorator) {
|
|
1072
1522
|
return function(target, key) {
|
|
1073
1523
|
decorator(target, key, paramIndex);
|
|
1074
1524
|
};
|
|
1075
1525
|
}
|
|
1076
|
-
__name(
|
|
1526
|
+
__name(_ts_param6, "_ts_param");
|
|
1077
1527
|
var AgentsController = class {
|
|
1078
1528
|
static {
|
|
1079
1529
|
__name(this, "AgentsController");
|
|
@@ -1103,17 +1553,17 @@ _ts_decorate8([
|
|
|
1103
1553
|
], AgentsController.prototype, "list", null);
|
|
1104
1554
|
AgentsController = _ts_decorate8([
|
|
1105
1555
|
(0, import_common8.Controller)("agents"),
|
|
1106
|
-
|
|
1107
|
-
|
|
1556
|
+
_ts_param6(0, (0, import_common8.Inject)(import_nestjs_agent_core9.AGENT_REGISTRY)),
|
|
1557
|
+
_ts_param6(1, (0, import_common8.Inject)(import_nestjs_agent_core9.AGENT_DEPS_FACTORY)),
|
|
1108
1558
|
_ts_metadata7("design:type", Function),
|
|
1109
1559
|
_ts_metadata7("design:paramtypes", [
|
|
1110
|
-
typeof
|
|
1560
|
+
typeof import_nestjs_agent_core9.AgentRegistry === "undefined" ? Object : import_nestjs_agent_core9.AgentRegistry,
|
|
1111
1561
|
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
|
|
1112
1562
|
])
|
|
1113
1563
|
], AgentsController);
|
|
1114
1564
|
|
|
1115
1565
|
// src/controller/attachments.controller.ts
|
|
1116
|
-
var
|
|
1566
|
+
var import_nestjs_agent_core10 = require("@dudousxd/nestjs-agent-core");
|
|
1117
1567
|
var import_common9 = require("@nestjs/common");
|
|
1118
1568
|
var import_platform_express = require("@nestjs/platform-express");
|
|
1119
1569
|
function _ts_decorate9(decorators, target, key, desc) {
|
|
@@ -1127,13 +1577,15 @@ function _ts_metadata8(k, v) {
|
|
|
1127
1577
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1128
1578
|
}
|
|
1129
1579
|
__name(_ts_metadata8, "_ts_metadata");
|
|
1130
|
-
function
|
|
1580
|
+
function _ts_param7(paramIndex, decorator) {
|
|
1131
1581
|
return function(target, key) {
|
|
1132
1582
|
decorator(target, key, paramIndex);
|
|
1133
1583
|
};
|
|
1134
1584
|
}
|
|
1135
|
-
__name(
|
|
1585
|
+
__name(_ts_param7, "_ts_param");
|
|
1136
1586
|
var DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
1587
|
+
var HARD_MAX_ATTACHMENT_BYTES = 32 * 1024 * 1024;
|
|
1588
|
+
var ATTACHMENT_PAGE_SIZE = 50;
|
|
1137
1589
|
var DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES = [
|
|
1138
1590
|
"image/png",
|
|
1139
1591
|
"image/jpeg",
|
|
@@ -1149,10 +1601,12 @@ var AttachmentsController = class {
|
|
|
1149
1601
|
}
|
|
1150
1602
|
options;
|
|
1151
1603
|
actorResolver;
|
|
1604
|
+
agents;
|
|
1152
1605
|
staging;
|
|
1153
|
-
constructor(options, actorResolver, staging) {
|
|
1606
|
+
constructor(options, actorResolver, agents, staging) {
|
|
1154
1607
|
this.options = options;
|
|
1155
1608
|
this.actorResolver = actorResolver;
|
|
1609
|
+
this.agents = agents;
|
|
1156
1610
|
this.staging = staging;
|
|
1157
1611
|
}
|
|
1158
1612
|
/**
|
|
@@ -1166,6 +1620,21 @@ var AttachmentsController = class {
|
|
|
1166
1620
|
throw new Error("AgentModule: attachments.upload is true but no AGENT_ATTACHMENT_STAGING provider is bound. Bind one (e.g. `{ provide: AGENT_ATTACHMENT_STAGING, useClass: MyStagingStore }`) in a module imported alongside AgentModule, or set attachments.upload to false.");
|
|
1167
1621
|
}
|
|
1168
1622
|
}
|
|
1623
|
+
/**
|
|
1624
|
+
* The caller's own staged files, newest first — the one question `GET /agent/threads/:id` cannot
|
|
1625
|
+
* answer, since an upload that was never sent belongs to no thread.
|
|
1626
|
+
*
|
|
1627
|
+
* Scoped by the RESOLVED actor and nothing else. There is deliberately no `threadId` filter: a
|
|
1628
|
+
* thread's attachments already ride on its messages in the thread payload, and re-serving them
|
|
1629
|
+
* from here would add a second ownership path to get wrong for information the client already
|
|
1630
|
+
* holds. Metadata only — see {@link StagedAttachment}.
|
|
1631
|
+
*/
|
|
1632
|
+
async list(req) {
|
|
1633
|
+
const actor = await this.actorResolver.resolve(req);
|
|
1634
|
+
return this.agents.listAttachments(actor, {
|
|
1635
|
+
limit: ATTACHMENT_PAGE_SIZE
|
|
1636
|
+
});
|
|
1637
|
+
}
|
|
1169
1638
|
async upload(req, file) {
|
|
1170
1639
|
if (this.staging === void 0) {
|
|
1171
1640
|
throw new import_common9.NotImplementedException("Attachment upload is not configured on this server.");
|
|
@@ -1191,11 +1660,24 @@ var AttachmentsController = class {
|
|
|
1191
1660
|
});
|
|
1192
1661
|
}
|
|
1193
1662
|
};
|
|
1663
|
+
_ts_decorate9([
|
|
1664
|
+
(0, import_common9.Get)(),
|
|
1665
|
+
_ts_param7(0, (0, import_common9.Req)()),
|
|
1666
|
+
_ts_metadata8("design:type", Function),
|
|
1667
|
+
_ts_metadata8("design:paramtypes", [
|
|
1668
|
+
typeof Request === "undefined" ? Object : Request
|
|
1669
|
+
]),
|
|
1670
|
+
_ts_metadata8("design:returntype", Promise)
|
|
1671
|
+
], AttachmentsController.prototype, "list", null);
|
|
1194
1672
|
_ts_decorate9([
|
|
1195
1673
|
(0, import_common9.Post)(),
|
|
1196
|
-
(0, import_common9.UseInterceptors)((0, import_platform_express.FileInterceptor)("file"
|
|
1197
|
-
|
|
1198
|
-
|
|
1674
|
+
(0, import_common9.UseInterceptors)((0, import_platform_express.FileInterceptor)("file", {
|
|
1675
|
+
limits: {
|
|
1676
|
+
fileSize: HARD_MAX_ATTACHMENT_BYTES
|
|
1677
|
+
}
|
|
1678
|
+
})),
|
|
1679
|
+
_ts_param7(0, (0, import_common9.Req)()),
|
|
1680
|
+
_ts_param7(1, (0, import_common9.UploadedFile)()),
|
|
1199
1681
|
_ts_metadata8("design:type", Function),
|
|
1200
1682
|
_ts_metadata8("design:paramtypes", [
|
|
1201
1683
|
typeof Request === "undefined" ? Object : Request,
|
|
@@ -1205,20 +1687,21 @@ _ts_decorate9([
|
|
|
1205
1687
|
], AttachmentsController.prototype, "upload", null);
|
|
1206
1688
|
AttachmentsController = _ts_decorate9([
|
|
1207
1689
|
(0, import_common9.Controller)("attachments"),
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1690
|
+
_ts_param7(0, (0, import_common9.Inject)(import_nestjs_agent_core10.AGENT_OPTIONS)),
|
|
1691
|
+
_ts_param7(1, (0, import_common9.Inject)(import_nestjs_agent_core10.AGENT_ACTOR_RESOLVER)),
|
|
1692
|
+
_ts_param7(3, (0, import_common9.Optional)()),
|
|
1693
|
+
_ts_param7(3, (0, import_common9.Inject)(import_nestjs_agent_core10.AGENT_ATTACHMENT_STAGING)),
|
|
1212
1694
|
_ts_metadata8("design:type", Function),
|
|
1213
1695
|
_ts_metadata8("design:paramtypes", [
|
|
1214
1696
|
typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
|
|
1215
1697
|
typeof ActorResolver === "undefined" ? Object : ActorResolver,
|
|
1698
|
+
typeof AgentService === "undefined" ? Object : AgentService,
|
|
1216
1699
|
Object
|
|
1217
1700
|
])
|
|
1218
1701
|
], AttachmentsController);
|
|
1219
1702
|
|
|
1220
1703
|
// src/controller/chat.controller.ts
|
|
1221
|
-
var
|
|
1704
|
+
var import_nestjs_agent_core11 = require("@dudousxd/nestjs-agent-core");
|
|
1222
1705
|
var import_common10 = require("@nestjs/common");
|
|
1223
1706
|
function _ts_decorate10(decorators, target, key, desc) {
|
|
1224
1707
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -1231,12 +1714,37 @@ function _ts_metadata9(k, v) {
|
|
|
1231
1714
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1232
1715
|
}
|
|
1233
1716
|
__name(_ts_metadata9, "_ts_metadata");
|
|
1234
|
-
function
|
|
1717
|
+
function _ts_param8(paramIndex, decorator) {
|
|
1235
1718
|
return function(target, key) {
|
|
1236
1719
|
decorator(target, key, paramIndex);
|
|
1237
1720
|
};
|
|
1238
1721
|
}
|
|
1239
|
-
__name(
|
|
1722
|
+
__name(_ts_param8, "_ts_param");
|
|
1723
|
+
var MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
1724
|
+
function attachmentRefs(claimed) {
|
|
1725
|
+
if (claimed === void 0) {
|
|
1726
|
+
return [];
|
|
1727
|
+
}
|
|
1728
|
+
if (!Array.isArray(claimed)) {
|
|
1729
|
+
throw new import_common10.BadRequestException("attachments must be an array of { mediaId }");
|
|
1730
|
+
}
|
|
1731
|
+
if (claimed.length > MAX_ATTACHMENTS_PER_MESSAGE) {
|
|
1732
|
+
throw new import_common10.BadRequestException(`a message may carry at most ${MAX_ATTACHMENTS_PER_MESSAGE} attachments`);
|
|
1733
|
+
}
|
|
1734
|
+
return claimed.map((entry) => {
|
|
1735
|
+
if (typeof entry !== "object" || entry === null || !("mediaId" in entry)) {
|
|
1736
|
+
throw new import_common10.BadRequestException("each attachment must be an object with a mediaId");
|
|
1737
|
+
}
|
|
1738
|
+
const { mediaId } = entry;
|
|
1739
|
+
if (typeof mediaId !== "string" || mediaId.length === 0) {
|
|
1740
|
+
throw new import_common10.BadRequestException("each attachment must carry a non-empty string mediaId");
|
|
1741
|
+
}
|
|
1742
|
+
return {
|
|
1743
|
+
mediaId
|
|
1744
|
+
};
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1747
|
+
__name(attachmentRefs, "attachmentRefs");
|
|
1240
1748
|
var ChatController = class {
|
|
1241
1749
|
static {
|
|
1242
1750
|
__name(this, "ChatController");
|
|
@@ -1249,6 +1757,7 @@ var ChatController = class {
|
|
|
1249
1757
|
}
|
|
1250
1758
|
async chat(req, res, body) {
|
|
1251
1759
|
const actor = await this.actorResolver.resolve(req);
|
|
1760
|
+
const attachments = attachmentRefs(body.attachments);
|
|
1252
1761
|
const { runId, threadId } = await this.agent.chat({
|
|
1253
1762
|
actor,
|
|
1254
1763
|
message: body.message,
|
|
@@ -1258,8 +1767,8 @@ var ChatController = class {
|
|
|
1258
1767
|
...body.agent !== void 0 ? {
|
|
1259
1768
|
agentName: body.agent
|
|
1260
1769
|
} : {},
|
|
1261
|
-
...
|
|
1262
|
-
attachments
|
|
1770
|
+
...attachments.length > 0 ? {
|
|
1771
|
+
attachments
|
|
1263
1772
|
} : {},
|
|
1264
1773
|
...body.pageContext !== void 0 ? {
|
|
1265
1774
|
pageContext: body.pageContext
|
|
@@ -1271,10 +1780,11 @@ var ChatController = class {
|
|
|
1271
1780
|
transient: true
|
|
1272
1781
|
} : {}
|
|
1273
1782
|
});
|
|
1274
|
-
await this.pipe(res, runId, threadId);
|
|
1783
|
+
await this.pipe(res, runId, this.agent.subscribe(runId), threadId);
|
|
1275
1784
|
}
|
|
1276
|
-
async stream(runId, res) {
|
|
1277
|
-
await this.
|
|
1785
|
+
async stream(req, runId, res) {
|
|
1786
|
+
const actor = await this.actorResolver.resolve(req);
|
|
1787
|
+
await this.pipe(res, runId, await this.agent.subscribeAs(actor, runId));
|
|
1278
1788
|
}
|
|
1279
1789
|
async cancel(req, runId) {
|
|
1280
1790
|
const actor = await this.actorResolver.resolve(req);
|
|
@@ -1283,7 +1793,7 @@ var ChatController = class {
|
|
|
1283
1793
|
aborted: true
|
|
1284
1794
|
};
|
|
1285
1795
|
}
|
|
1286
|
-
async pipe(res, runId, threadId) {
|
|
1796
|
+
async pipe(res, runId, events, threadId) {
|
|
1287
1797
|
res.setHeader("Content-Type", "text/event-stream");
|
|
1288
1798
|
res.setHeader("Cache-Control", "no-cache");
|
|
1289
1799
|
res.setHeader("Connection", "keep-alive");
|
|
@@ -1301,7 +1811,7 @@ data: ${JSON.stringify({
|
|
|
1301
1811
|
const decoder = new TextDecoder();
|
|
1302
1812
|
let buffer = "";
|
|
1303
1813
|
try {
|
|
1304
|
-
for await (const chunk of
|
|
1814
|
+
for await (const chunk of events) {
|
|
1305
1815
|
buffer += decoder.decode(chunk, {
|
|
1306
1816
|
stream: true
|
|
1307
1817
|
});
|
|
@@ -1324,7 +1834,7 @@ data: ${JSON.stringify({
|
|
|
1324
1834
|
}
|
|
1325
1835
|
res.write("event: done\ndata: {}\n\n");
|
|
1326
1836
|
} catch (error) {
|
|
1327
|
-
const payload = error instanceof
|
|
1837
|
+
const payload = error instanceof import_nestjs_agent_core11.AgentStreamError ? {
|
|
1328
1838
|
code: error.code,
|
|
1329
1839
|
message: error.message
|
|
1330
1840
|
} : {
|
|
@@ -1341,9 +1851,9 @@ data: ${JSON.stringify(payload)}
|
|
|
1341
1851
|
};
|
|
1342
1852
|
_ts_decorate10([
|
|
1343
1853
|
(0, import_common10.Post)("chat"),
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1854
|
+
_ts_param8(0, (0, import_common10.Req)()),
|
|
1855
|
+
_ts_param8(1, (0, import_common10.Res)()),
|
|
1856
|
+
_ts_param8(2, (0, import_common10.Body)()),
|
|
1347
1857
|
_ts_metadata9("design:type", Function),
|
|
1348
1858
|
_ts_metadata9("design:paramtypes", [
|
|
1349
1859
|
typeof Request === "undefined" ? Object : Request,
|
|
@@ -1354,10 +1864,12 @@ _ts_decorate10([
|
|
|
1354
1864
|
], ChatController.prototype, "chat", null);
|
|
1355
1865
|
_ts_decorate10([
|
|
1356
1866
|
(0, import_common10.Get)("chat/:runId/stream"),
|
|
1357
|
-
|
|
1358
|
-
|
|
1867
|
+
_ts_param8(0, (0, import_common10.Req)()),
|
|
1868
|
+
_ts_param8(1, (0, import_common10.Param)("runId")),
|
|
1869
|
+
_ts_param8(2, (0, import_common10.Res)()),
|
|
1359
1870
|
_ts_metadata9("design:type", Function),
|
|
1360
1871
|
_ts_metadata9("design:paramtypes", [
|
|
1872
|
+
typeof Request === "undefined" ? Object : Request,
|
|
1361
1873
|
String,
|
|
1362
1874
|
typeof Response === "undefined" ? Object : Response
|
|
1363
1875
|
]),
|
|
@@ -1365,8 +1877,8 @@ _ts_decorate10([
|
|
|
1365
1877
|
], ChatController.prototype, "stream", null);
|
|
1366
1878
|
_ts_decorate10([
|
|
1367
1879
|
(0, import_common10.Post)("chat/:runId/cancel"),
|
|
1368
|
-
|
|
1369
|
-
|
|
1880
|
+
_ts_param8(0, (0, import_common10.Req)()),
|
|
1881
|
+
_ts_param8(1, (0, import_common10.Param)("runId")),
|
|
1370
1882
|
_ts_metadata9("design:type", Function),
|
|
1371
1883
|
_ts_metadata9("design:paramtypes", [
|
|
1372
1884
|
typeof Request === "undefined" ? Object : Request,
|
|
@@ -1376,7 +1888,7 @@ _ts_decorate10([
|
|
|
1376
1888
|
], ChatController.prototype, "cancel", null);
|
|
1377
1889
|
ChatController = _ts_decorate10([
|
|
1378
1890
|
(0, import_common10.Controller)(),
|
|
1379
|
-
|
|
1891
|
+
_ts_param8(1, (0, import_common10.Inject)(import_nestjs_agent_core11.AGENT_ACTOR_RESOLVER)),
|
|
1380
1892
|
_ts_metadata9("design:type", Function),
|
|
1381
1893
|
_ts_metadata9("design:paramtypes", [
|
|
1382
1894
|
typeof AgentService === "undefined" ? Object : AgentService,
|
|
@@ -1384,8 +1896,8 @@ ChatController = _ts_decorate10([
|
|
|
1384
1896
|
])
|
|
1385
1897
|
], ChatController);
|
|
1386
1898
|
|
|
1387
|
-
// src/controller/
|
|
1388
|
-
var
|
|
1899
|
+
// src/controller/memories.controller.ts
|
|
1900
|
+
var import_nestjs_agent_core12 = require("@dudousxd/nestjs-agent-core");
|
|
1389
1901
|
var import_common11 = require("@nestjs/common");
|
|
1390
1902
|
function _ts_decorate11(decorators, target, key, desc) {
|
|
1391
1903
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -1398,12 +1910,138 @@ function _ts_metadata10(k, v) {
|
|
|
1398
1910
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1399
1911
|
}
|
|
1400
1912
|
__name(_ts_metadata10, "_ts_metadata");
|
|
1401
|
-
function
|
|
1913
|
+
function _ts_param9(paramIndex, decorator) {
|
|
1402
1914
|
return function(target, key) {
|
|
1403
1915
|
decorator(target, key, paramIndex);
|
|
1404
1916
|
};
|
|
1405
1917
|
}
|
|
1406
|
-
__name(
|
|
1918
|
+
__name(_ts_param9, "_ts_param");
|
|
1919
|
+
var MemoriesController = class {
|
|
1920
|
+
static {
|
|
1921
|
+
__name(this, "MemoriesController");
|
|
1922
|
+
}
|
|
1923
|
+
actorResolver;
|
|
1924
|
+
memory;
|
|
1925
|
+
constructor(actorResolver, memory) {
|
|
1926
|
+
this.actorResolver = actorResolver;
|
|
1927
|
+
this.memory = memory;
|
|
1928
|
+
}
|
|
1929
|
+
/**
|
|
1930
|
+
* Every memory this actor can reach, most specific first, each carrying its origin and whatever
|
|
1931
|
+
* wider value it outranks.
|
|
1932
|
+
*
|
|
1933
|
+
* DELIBERATELY IGNORES `maxMemories`. That ceiling is a budget on what one TURN carries; applying
|
|
1934
|
+
* it here would mean a person could not see — and so could not delete — a belief the assistant is
|
|
1935
|
+
* one write away from acting on again. Showing someone more than the model sees is harmless;
|
|
1936
|
+
* showing them less is the failure this endpoint exists to prevent.
|
|
1937
|
+
*/
|
|
1938
|
+
async list(req, threadId) {
|
|
1939
|
+
if (this.memory === void 0) {
|
|
1940
|
+
return [];
|
|
1941
|
+
}
|
|
1942
|
+
const actor = await this.actorResolver.resolve(req);
|
|
1943
|
+
return (await this.unbounded(threadId ?? "", actor)).entries;
|
|
1944
|
+
}
|
|
1945
|
+
/**
|
|
1946
|
+
* Forget one. Authorized against the actor's OWN resolved list, the same way a `skill` load is
|
|
1947
|
+
* authorized against the turn's catalog: an id this actor cannot see is answered as missing rather
|
|
1948
|
+
* than refused, so the endpoint cannot be used to find out which memories exist about other people.
|
|
1949
|
+
*/
|
|
1950
|
+
async forget(req, id) {
|
|
1951
|
+
if (this.memory === void 0) {
|
|
1952
|
+
throw new import_common11.NotFoundException("No memory is configured in this deployment.");
|
|
1953
|
+
}
|
|
1954
|
+
const actor = await this.actorResolver.resolve(req);
|
|
1955
|
+
const digest = await this.unbounded("", actor);
|
|
1956
|
+
const entry = digest.entries.find((candidate) => candidate.id === id);
|
|
1957
|
+
if (entry === void 0) {
|
|
1958
|
+
throw new import_common11.NotFoundException(`No memory with id "${id}".`);
|
|
1959
|
+
}
|
|
1960
|
+
const verdict = (0, import_nestjs_agent_core12.memoryForgetVerdict)({
|
|
1961
|
+
record: entry,
|
|
1962
|
+
actor
|
|
1963
|
+
});
|
|
1964
|
+
if (!verdict.allowed) {
|
|
1965
|
+
throw new import_common11.ForbiddenException(verdict.reason);
|
|
1966
|
+
}
|
|
1967
|
+
return {
|
|
1968
|
+
forgotten: await this.memory.provider.forget({
|
|
1969
|
+
id: entry.id,
|
|
1970
|
+
ctx: {
|
|
1971
|
+
actor,
|
|
1972
|
+
threadId: ""
|
|
1973
|
+
}
|
|
1974
|
+
})
|
|
1975
|
+
};
|
|
1976
|
+
}
|
|
1977
|
+
async unbounded(threadId, actor) {
|
|
1978
|
+
const config = this.memory;
|
|
1979
|
+
return await (0, import_nestjs_agent_core12.offerMemories)({
|
|
1980
|
+
config: {
|
|
1981
|
+
...config,
|
|
1982
|
+
maxMemories: Number.POSITIVE_INFINITY
|
|
1983
|
+
},
|
|
1984
|
+
ctx: {
|
|
1985
|
+
actor,
|
|
1986
|
+
threadId
|
|
1987
|
+
}
|
|
1988
|
+
});
|
|
1989
|
+
}
|
|
1990
|
+
};
|
|
1991
|
+
_ts_decorate11([
|
|
1992
|
+
(0, import_common11.Get)(),
|
|
1993
|
+
_ts_param9(0, (0, import_common11.Req)()),
|
|
1994
|
+
_ts_param9(1, (0, import_common11.Query)("threadId")),
|
|
1995
|
+
_ts_metadata10("design:type", Function),
|
|
1996
|
+
_ts_metadata10("design:paramtypes", [
|
|
1997
|
+
typeof Request === "undefined" ? Object : Request,
|
|
1998
|
+
String
|
|
1999
|
+
]),
|
|
2000
|
+
_ts_metadata10("design:returntype", Promise)
|
|
2001
|
+
], MemoriesController.prototype, "list", null);
|
|
2002
|
+
_ts_decorate11([
|
|
2003
|
+
(0, import_common11.Delete)(":id"),
|
|
2004
|
+
_ts_param9(0, (0, import_common11.Req)()),
|
|
2005
|
+
_ts_param9(1, (0, import_common11.Param)("id")),
|
|
2006
|
+
_ts_metadata10("design:type", Function),
|
|
2007
|
+
_ts_metadata10("design:paramtypes", [
|
|
2008
|
+
typeof Request === "undefined" ? Object : Request,
|
|
2009
|
+
String
|
|
2010
|
+
]),
|
|
2011
|
+
_ts_metadata10("design:returntype", Promise)
|
|
2012
|
+
], MemoriesController.prototype, "forget", null);
|
|
2013
|
+
MemoriesController = _ts_decorate11([
|
|
2014
|
+
(0, import_common11.Controller)("memories"),
|
|
2015
|
+
_ts_param9(0, (0, import_common11.Inject)(import_nestjs_agent_core12.AGENT_ACTOR_RESOLVER)),
|
|
2016
|
+
_ts_param9(1, (0, import_common11.Optional)()),
|
|
2017
|
+
_ts_param9(1, (0, import_common11.Inject)(import_nestjs_agent_core12.AGENT_MEMORY)),
|
|
2018
|
+
_ts_metadata10("design:type", Function),
|
|
2019
|
+
_ts_metadata10("design:paramtypes", [
|
|
2020
|
+
typeof ActorResolver === "undefined" ? Object : ActorResolver,
|
|
2021
|
+
Object
|
|
2022
|
+
])
|
|
2023
|
+
], MemoriesController);
|
|
2024
|
+
|
|
2025
|
+
// src/controller/quota.controller.ts
|
|
2026
|
+
var import_nestjs_agent_core13 = require("@dudousxd/nestjs-agent-core");
|
|
2027
|
+
var import_common12 = require("@nestjs/common");
|
|
2028
|
+
function _ts_decorate12(decorators, target, key, desc) {
|
|
2029
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2030
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2031
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2032
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2033
|
+
}
|
|
2034
|
+
__name(_ts_decorate12, "_ts_decorate");
|
|
2035
|
+
function _ts_metadata11(k, v) {
|
|
2036
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2037
|
+
}
|
|
2038
|
+
__name(_ts_metadata11, "_ts_metadata");
|
|
2039
|
+
function _ts_param10(paramIndex, decorator) {
|
|
2040
|
+
return function(target, key) {
|
|
2041
|
+
decorator(target, key, paramIndex);
|
|
2042
|
+
};
|
|
2043
|
+
}
|
|
2044
|
+
__name(_ts_param10, "_ts_param");
|
|
1407
2045
|
var QuotaController = class {
|
|
1408
2046
|
static {
|
|
1409
2047
|
__name(this, "QuotaController");
|
|
@@ -1419,45 +2057,110 @@ var QuotaController = class {
|
|
|
1419
2057
|
return this.agent.quotaToday(actor.id);
|
|
1420
2058
|
}
|
|
1421
2059
|
};
|
|
1422
|
-
|
|
1423
|
-
(0,
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
2060
|
+
_ts_decorate12([
|
|
2061
|
+
(0, import_common12.Get)("today"),
|
|
2062
|
+
_ts_param10(0, (0, import_common12.Req)()),
|
|
2063
|
+
_ts_metadata11("design:type", Function),
|
|
2064
|
+
_ts_metadata11("design:paramtypes", [
|
|
1427
2065
|
typeof Request === "undefined" ? Object : Request
|
|
1428
2066
|
]),
|
|
1429
|
-
|
|
2067
|
+
_ts_metadata11("design:returntype", Promise)
|
|
1430
2068
|
], QuotaController.prototype, "today", null);
|
|
1431
|
-
QuotaController =
|
|
1432
|
-
(0,
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
2069
|
+
QuotaController = _ts_decorate12([
|
|
2070
|
+
(0, import_common12.Controller)("quota"),
|
|
2071
|
+
_ts_param10(1, (0, import_common12.Inject)(import_nestjs_agent_core13.AGENT_ACTOR_RESOLVER)),
|
|
2072
|
+
_ts_metadata11("design:type", Function),
|
|
2073
|
+
_ts_metadata11("design:paramtypes", [
|
|
1436
2074
|
typeof AgentService === "undefined" ? Object : AgentService,
|
|
1437
2075
|
typeof ActorResolver === "undefined" ? Object : ActorResolver
|
|
1438
2076
|
])
|
|
1439
2077
|
], QuotaController);
|
|
1440
2078
|
|
|
2079
|
+
// src/controller/skills.controller.ts
|
|
2080
|
+
var import_nestjs_agent_core14 = require("@dudousxd/nestjs-agent-core");
|
|
2081
|
+
var import_common13 = require("@nestjs/common");
|
|
2082
|
+
function _ts_decorate13(decorators, target, key, desc) {
|
|
2083
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2084
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2085
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2086
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2087
|
+
}
|
|
2088
|
+
__name(_ts_decorate13, "_ts_decorate");
|
|
2089
|
+
function _ts_metadata12(k, v) {
|
|
2090
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2091
|
+
}
|
|
2092
|
+
__name(_ts_metadata12, "_ts_metadata");
|
|
2093
|
+
function _ts_param11(paramIndex, decorator) {
|
|
2094
|
+
return function(target, key) {
|
|
2095
|
+
decorator(target, key, paramIndex);
|
|
2096
|
+
};
|
|
2097
|
+
}
|
|
2098
|
+
__name(_ts_param11, "_ts_param");
|
|
2099
|
+
var SkillsController = class {
|
|
2100
|
+
static {
|
|
2101
|
+
__name(this, "SkillsController");
|
|
2102
|
+
}
|
|
2103
|
+
actorResolver;
|
|
2104
|
+
skills;
|
|
2105
|
+
constructor(actorResolver, skills) {
|
|
2106
|
+
this.actorResolver = actorResolver;
|
|
2107
|
+
this.skills = skills;
|
|
2108
|
+
}
|
|
2109
|
+
async list(req, threadId) {
|
|
2110
|
+
if (this.skills === void 0) {
|
|
2111
|
+
return [];
|
|
2112
|
+
}
|
|
2113
|
+
const actor = await this.actorResolver.resolve(req);
|
|
2114
|
+
const offer = await (0, import_nestjs_agent_core14.offerSkills)(this.skills, {
|
|
2115
|
+
actor,
|
|
2116
|
+
threadId: threadId ?? ""
|
|
2117
|
+
});
|
|
2118
|
+
return offer.entries;
|
|
2119
|
+
}
|
|
2120
|
+
};
|
|
2121
|
+
_ts_decorate13([
|
|
2122
|
+
(0, import_common13.Get)(),
|
|
2123
|
+
_ts_param11(0, (0, import_common13.Req)()),
|
|
2124
|
+
_ts_param11(1, (0, import_common13.Query)("threadId")),
|
|
2125
|
+
_ts_metadata12("design:type", Function),
|
|
2126
|
+
_ts_metadata12("design:paramtypes", [
|
|
2127
|
+
typeof Request === "undefined" ? Object : Request,
|
|
2128
|
+
String
|
|
2129
|
+
]),
|
|
2130
|
+
_ts_metadata12("design:returntype", Promise)
|
|
2131
|
+
], SkillsController.prototype, "list", null);
|
|
2132
|
+
SkillsController = _ts_decorate13([
|
|
2133
|
+
(0, import_common13.Controller)("skills"),
|
|
2134
|
+
_ts_param11(0, (0, import_common13.Inject)(import_nestjs_agent_core14.AGENT_ACTOR_RESOLVER)),
|
|
2135
|
+
_ts_param11(1, (0, import_common13.Optional)()),
|
|
2136
|
+
_ts_param11(1, (0, import_common13.Inject)(import_nestjs_agent_core14.AGENT_SKILLS)),
|
|
2137
|
+
_ts_metadata12("design:type", Function),
|
|
2138
|
+
_ts_metadata12("design:paramtypes", [
|
|
2139
|
+
typeof ActorResolver === "undefined" ? Object : ActorResolver,
|
|
2140
|
+
Object
|
|
2141
|
+
])
|
|
2142
|
+
], SkillsController);
|
|
2143
|
+
|
|
1441
2144
|
// src/controller/threads.controller.ts
|
|
1442
|
-
var
|
|
1443
|
-
var
|
|
1444
|
-
function
|
|
2145
|
+
var import_nestjs_agent_core15 = require("@dudousxd/nestjs-agent-core");
|
|
2146
|
+
var import_common14 = require("@nestjs/common");
|
|
2147
|
+
function _ts_decorate14(decorators, target, key, desc) {
|
|
1445
2148
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1446
2149
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1447
2150
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1448
2151
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1449
2152
|
}
|
|
1450
|
-
__name(
|
|
1451
|
-
function
|
|
2153
|
+
__name(_ts_decorate14, "_ts_decorate");
|
|
2154
|
+
function _ts_metadata13(k, v) {
|
|
1452
2155
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1453
2156
|
}
|
|
1454
|
-
__name(
|
|
1455
|
-
function
|
|
2157
|
+
__name(_ts_metadata13, "_ts_metadata");
|
|
2158
|
+
function _ts_param12(paramIndex, decorator) {
|
|
1456
2159
|
return function(target, key) {
|
|
1457
2160
|
decorator(target, key, paramIndex);
|
|
1458
2161
|
};
|
|
1459
2162
|
}
|
|
1460
|
-
__name(
|
|
2163
|
+
__name(_ts_param12, "_ts_param");
|
|
1461
2164
|
var ThreadsController = class {
|
|
1462
2165
|
static {
|
|
1463
2166
|
__name(this, "ThreadsController");
|
|
@@ -1521,117 +2224,173 @@ var ThreadsController = class {
|
|
|
1521
2224
|
};
|
|
1522
2225
|
}
|
|
1523
2226
|
};
|
|
1524
|
-
|
|
1525
|
-
(0,
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
2227
|
+
_ts_decorate14([
|
|
2228
|
+
(0, import_common14.Get)(),
|
|
2229
|
+
_ts_param12(0, (0, import_common14.Req)()),
|
|
2230
|
+
_ts_metadata13("design:type", Function),
|
|
2231
|
+
_ts_metadata13("design:paramtypes", [
|
|
1529
2232
|
typeof Request === "undefined" ? Object : Request
|
|
1530
2233
|
]),
|
|
1531
|
-
|
|
2234
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1532
2235
|
], ThreadsController.prototype, "list", null);
|
|
1533
|
-
|
|
1534
|
-
(0,
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
2236
|
+
_ts_decorate14([
|
|
2237
|
+
(0, import_common14.Get)(":id"),
|
|
2238
|
+
_ts_param12(0, (0, import_common14.Req)()),
|
|
2239
|
+
_ts_param12(1, (0, import_common14.Param)("id")),
|
|
2240
|
+
_ts_metadata13("design:type", Function),
|
|
2241
|
+
_ts_metadata13("design:paramtypes", [
|
|
1539
2242
|
typeof Request === "undefined" ? Object : Request,
|
|
1540
2243
|
String
|
|
1541
2244
|
]),
|
|
1542
|
-
|
|
2245
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1543
2246
|
], ThreadsController.prototype, "detail", null);
|
|
1544
|
-
|
|
1545
|
-
(0,
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
2247
|
+
_ts_decorate14([
|
|
2248
|
+
(0, import_common14.Delete)(":id"),
|
|
2249
|
+
_ts_param12(0, (0, import_common14.Req)()),
|
|
2250
|
+
_ts_param12(1, (0, import_common14.Param)("id")),
|
|
2251
|
+
_ts_metadata13("design:type", Function),
|
|
2252
|
+
_ts_metadata13("design:paramtypes", [
|
|
1550
2253
|
typeof Request === "undefined" ? Object : Request,
|
|
1551
2254
|
String
|
|
1552
2255
|
]),
|
|
1553
|
-
|
|
2256
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1554
2257
|
], ThreadsController.prototype, "remove", null);
|
|
1555
|
-
|
|
1556
|
-
(0,
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
2258
|
+
_ts_decorate14([
|
|
2259
|
+
(0, import_common14.Post)(":id/fork-from/:messageId"),
|
|
2260
|
+
_ts_param12(0, (0, import_common14.Req)()),
|
|
2261
|
+
_ts_param12(1, (0, import_common14.Param)("id")),
|
|
2262
|
+
_ts_param12(2, (0, import_common14.Param)("messageId")),
|
|
2263
|
+
_ts_metadata13("design:type", Function),
|
|
2264
|
+
_ts_metadata13("design:paramtypes", [
|
|
1562
2265
|
typeof Request === "undefined" ? Object : Request,
|
|
1563
2266
|
String,
|
|
1564
2267
|
String
|
|
1565
2268
|
]),
|
|
1566
|
-
|
|
2269
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1567
2270
|
], ThreadsController.prototype, "fork", null);
|
|
1568
|
-
|
|
1569
|
-
(0,
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
2271
|
+
_ts_decorate14([
|
|
2272
|
+
(0, import_common14.Patch)(":id"),
|
|
2273
|
+
_ts_param12(0, (0, import_common14.Req)()),
|
|
2274
|
+
_ts_param12(1, (0, import_common14.Param)("id")),
|
|
2275
|
+
_ts_param12(2, (0, import_common14.Body)()),
|
|
2276
|
+
_ts_metadata13("design:type", Function),
|
|
2277
|
+
_ts_metadata13("design:paramtypes", [
|
|
1575
2278
|
typeof Request === "undefined" ? Object : Request,
|
|
1576
2279
|
String,
|
|
1577
2280
|
typeof UpdateThreadBody === "undefined" ? Object : UpdateThreadBody
|
|
1578
2281
|
]),
|
|
1579
|
-
|
|
2282
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1580
2283
|
], ThreadsController.prototype, "update", null);
|
|
1581
|
-
|
|
1582
|
-
(0,
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
2284
|
+
_ts_decorate14([
|
|
2285
|
+
(0, import_common14.Post)(":id/promote"),
|
|
2286
|
+
_ts_param12(0, (0, import_common14.Req)()),
|
|
2287
|
+
_ts_param12(1, (0, import_common14.Param)("id")),
|
|
2288
|
+
_ts_metadata13("design:type", Function),
|
|
2289
|
+
_ts_metadata13("design:paramtypes", [
|
|
1587
2290
|
typeof Request === "undefined" ? Object : Request,
|
|
1588
2291
|
String
|
|
1589
2292
|
]),
|
|
1590
|
-
|
|
2293
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1591
2294
|
], ThreadsController.prototype, "promote", null);
|
|
1592
|
-
|
|
1593
|
-
(0,
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
2295
|
+
_ts_decorate14([
|
|
2296
|
+
(0, import_common14.Delete)(":id/from/:messageId"),
|
|
2297
|
+
_ts_param12(0, (0, import_common14.Req)()),
|
|
2298
|
+
_ts_param12(1, (0, import_common14.Param)("id")),
|
|
2299
|
+
_ts_param12(2, (0, import_common14.Param)("messageId")),
|
|
2300
|
+
_ts_metadata13("design:type", Function),
|
|
2301
|
+
_ts_metadata13("design:paramtypes", [
|
|
1599
2302
|
typeof Request === "undefined" ? Object : Request,
|
|
1600
2303
|
String,
|
|
1601
2304
|
String
|
|
1602
2305
|
]),
|
|
1603
|
-
|
|
2306
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1604
2307
|
], ThreadsController.prototype, "truncateFrom", null);
|
|
1605
|
-
ThreadsController =
|
|
1606
|
-
(0,
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
2308
|
+
ThreadsController = _ts_decorate14([
|
|
2309
|
+
(0, import_common14.Controller)("threads"),
|
|
2310
|
+
_ts_param12(1, (0, import_common14.Inject)(import_nestjs_agent_core15.AGENT_ACTOR_RESOLVER)),
|
|
2311
|
+
_ts_metadata13("design:type", Function),
|
|
2312
|
+
_ts_metadata13("design:paramtypes", [
|
|
1610
2313
|
typeof AgentService === "undefined" ? Object : AgentService,
|
|
1611
2314
|
typeof ActorResolver === "undefined" ? Object : ActorResolver
|
|
1612
2315
|
])
|
|
1613
2316
|
], ThreadsController);
|
|
1614
2317
|
|
|
1615
2318
|
// src/controller/tool-call.controller.ts
|
|
1616
|
-
var
|
|
1617
|
-
var
|
|
1618
|
-
function
|
|
2319
|
+
var import_nestjs_agent_core16 = require("@dudousxd/nestjs-agent-core");
|
|
2320
|
+
var import_common15 = require("@nestjs/common");
|
|
2321
|
+
function _ts_decorate15(decorators, target, key, desc) {
|
|
1619
2322
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1620
2323
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1621
2324
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1622
2325
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1623
2326
|
}
|
|
1624
|
-
__name(
|
|
1625
|
-
function
|
|
2327
|
+
__name(_ts_decorate15, "_ts_decorate");
|
|
2328
|
+
function _ts_metadata14(k, v) {
|
|
1626
2329
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1627
2330
|
}
|
|
1628
|
-
__name(
|
|
1629
|
-
function
|
|
2331
|
+
__name(_ts_metadata14, "_ts_metadata");
|
|
2332
|
+
function _ts_param13(paramIndex, decorator) {
|
|
1630
2333
|
return function(target, key) {
|
|
1631
2334
|
decorator(target, key, paramIndex);
|
|
1632
2335
|
};
|
|
1633
2336
|
}
|
|
1634
|
-
__name(
|
|
2337
|
+
__name(_ts_param13, "_ts_param");
|
|
2338
|
+
var MAX_ANSWERED_QUESTIONS = 100;
|
|
2339
|
+
var MAX_VALUES_PER_QUESTION = 100;
|
|
2340
|
+
var MAX_ANSWER_VALUE_LENGTH = 4096;
|
|
2341
|
+
var MAX_REJECT_REASON_LENGTH = 4096;
|
|
2342
|
+
function toolCallId(claimed) {
|
|
2343
|
+
if (typeof claimed !== "string" || claimed.length === 0) {
|
|
2344
|
+
throw new import_common15.BadRequestException("toolCallId must be a non-empty string");
|
|
2345
|
+
}
|
|
2346
|
+
return claimed;
|
|
2347
|
+
}
|
|
2348
|
+
__name(toolCallId, "toolCallId");
|
|
2349
|
+
function rejectReason(claimed) {
|
|
2350
|
+
if (claimed === void 0) {
|
|
2351
|
+
return void 0;
|
|
2352
|
+
}
|
|
2353
|
+
if (typeof claimed !== "string") {
|
|
2354
|
+
throw new import_common15.BadRequestException("reason must be a string");
|
|
2355
|
+
}
|
|
2356
|
+
if (claimed.length > MAX_REJECT_REASON_LENGTH) {
|
|
2357
|
+
throw new import_common15.BadRequestException(`reason must be at most ${MAX_REJECT_REASON_LENGTH} characters`);
|
|
2358
|
+
}
|
|
2359
|
+
return claimed;
|
|
2360
|
+
}
|
|
2361
|
+
__name(rejectReason, "rejectReason");
|
|
2362
|
+
function answers(claimed) {
|
|
2363
|
+
if (claimed === void 0) {
|
|
2364
|
+
return void 0;
|
|
2365
|
+
}
|
|
2366
|
+
if (typeof claimed !== "object" || claimed === null || Array.isArray(claimed)) {
|
|
2367
|
+
throw new import_common15.BadRequestException("answers must be an object of questionId \u2192 chosen values");
|
|
2368
|
+
}
|
|
2369
|
+
const entries = Object.entries(claimed);
|
|
2370
|
+
if (entries.length > MAX_ANSWERED_QUESTIONS) {
|
|
2371
|
+
throw new import_common15.BadRequestException(`answers may cover at most ${MAX_ANSWERED_QUESTIONS} questions`);
|
|
2372
|
+
}
|
|
2373
|
+
const validated = /* @__PURE__ */ Object.create(null);
|
|
2374
|
+
for (const [questionId, values] of entries) {
|
|
2375
|
+
if (!Array.isArray(values)) {
|
|
2376
|
+
throw new import_common15.BadRequestException(`answers["${questionId}"] must be an array of chosen values`);
|
|
2377
|
+
}
|
|
2378
|
+
if (values.length > MAX_VALUES_PER_QUESTION) {
|
|
2379
|
+
throw new import_common15.BadRequestException(`answers["${questionId}"] may carry at most ${MAX_VALUES_PER_QUESTION} values`);
|
|
2380
|
+
}
|
|
2381
|
+
for (const value of values) {
|
|
2382
|
+
if (typeof value !== "string") {
|
|
2383
|
+
throw new import_common15.BadRequestException(`answers["${questionId}"] must contain only strings`);
|
|
2384
|
+
}
|
|
2385
|
+
if (value.length > MAX_ANSWER_VALUE_LENGTH) {
|
|
2386
|
+
throw new import_common15.BadRequestException(`answers["${questionId}"] values must be at most ${MAX_ANSWER_VALUE_LENGTH} characters`);
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
validated[questionId] = values;
|
|
2390
|
+
}
|
|
2391
|
+
return validated;
|
|
2392
|
+
}
|
|
2393
|
+
__name(answers, "answers");
|
|
1635
2394
|
var ToolCallController = class {
|
|
1636
2395
|
static {
|
|
1637
2396
|
__name(this, "ToolCallController");
|
|
@@ -1644,54 +2403,96 @@ var ToolCallController = class {
|
|
|
1644
2403
|
}
|
|
1645
2404
|
async approve(req, body) {
|
|
1646
2405
|
const actor = await this.actorResolver.resolve(req);
|
|
1647
|
-
await this.agent.approve(actor, body.toolCallId);
|
|
2406
|
+
await this.agent.approve(actor, toolCallId(body.toolCallId));
|
|
1648
2407
|
return {
|
|
1649
2408
|
ok: true
|
|
1650
2409
|
};
|
|
1651
2410
|
}
|
|
1652
2411
|
async reject(req, body) {
|
|
1653
2412
|
const actor = await this.actorResolver.resolve(req);
|
|
1654
|
-
await this.agent.reject(actor, body.toolCallId, body.reason);
|
|
2413
|
+
await this.agent.reject(actor, toolCallId(body.toolCallId), rejectReason(body.reason));
|
|
2414
|
+
return {
|
|
2415
|
+
ok: true
|
|
2416
|
+
};
|
|
2417
|
+
}
|
|
2418
|
+
/**
|
|
2419
|
+
* Settle a parked question set. Alongside `approve`/`reject` rather than under a surface of its
|
|
2420
|
+
* own: an elicitation IS a parked tool call, gated by the same ownership check and delivered
|
|
2421
|
+
* through the same signal.
|
|
2422
|
+
*/
|
|
2423
|
+
async answer(req, body) {
|
|
2424
|
+
const actor = await this.actorResolver.resolve(req);
|
|
2425
|
+
await this.agent.answer(actor, toolCallId(body.toolCallId), answers(body.answers));
|
|
2426
|
+
return {
|
|
2427
|
+
ok: true
|
|
2428
|
+
};
|
|
2429
|
+
}
|
|
2430
|
+
/** Decline to answer and let the agent proceed on the answers it pre-picked. */
|
|
2431
|
+
async skip(req, body) {
|
|
2432
|
+
const actor = await this.actorResolver.resolve(req);
|
|
2433
|
+
await this.agent.skip(actor, toolCallId(body.toolCallId));
|
|
1655
2434
|
return {
|
|
1656
2435
|
ok: true
|
|
1657
2436
|
};
|
|
1658
2437
|
}
|
|
1659
2438
|
};
|
|
1660
|
-
|
|
1661
|
-
(0,
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
2439
|
+
_ts_decorate15([
|
|
2440
|
+
(0, import_common15.Post)("approve"),
|
|
2441
|
+
_ts_param13(0, (0, import_common15.Req)()),
|
|
2442
|
+
_ts_param13(1, (0, import_common15.Body)()),
|
|
2443
|
+
_ts_metadata14("design:type", Function),
|
|
2444
|
+
_ts_metadata14("design:paramtypes", [
|
|
1666
2445
|
typeof Request === "undefined" ? Object : Request,
|
|
1667
2446
|
typeof ApproveBody === "undefined" ? Object : ApproveBody
|
|
1668
2447
|
]),
|
|
1669
|
-
|
|
2448
|
+
_ts_metadata14("design:returntype", Promise)
|
|
1670
2449
|
], ToolCallController.prototype, "approve", null);
|
|
1671
|
-
|
|
1672
|
-
(0,
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
2450
|
+
_ts_decorate15([
|
|
2451
|
+
(0, import_common15.Post)("reject"),
|
|
2452
|
+
_ts_param13(0, (0, import_common15.Req)()),
|
|
2453
|
+
_ts_param13(1, (0, import_common15.Body)()),
|
|
2454
|
+
_ts_metadata14("design:type", Function),
|
|
2455
|
+
_ts_metadata14("design:paramtypes", [
|
|
1677
2456
|
typeof Request === "undefined" ? Object : Request,
|
|
1678
2457
|
typeof RejectBody === "undefined" ? Object : RejectBody
|
|
1679
2458
|
]),
|
|
1680
|
-
|
|
2459
|
+
_ts_metadata14("design:returntype", Promise)
|
|
1681
2460
|
], ToolCallController.prototype, "reject", null);
|
|
1682
|
-
|
|
1683
|
-
(0,
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
2461
|
+
_ts_decorate15([
|
|
2462
|
+
(0, import_common15.Post)("answer"),
|
|
2463
|
+
_ts_param13(0, (0, import_common15.Req)()),
|
|
2464
|
+
_ts_param13(1, (0, import_common15.Body)()),
|
|
2465
|
+
_ts_metadata14("design:type", Function),
|
|
2466
|
+
_ts_metadata14("design:paramtypes", [
|
|
2467
|
+
typeof Request === "undefined" ? Object : Request,
|
|
2468
|
+
typeof AnswerBody === "undefined" ? Object : AnswerBody
|
|
2469
|
+
]),
|
|
2470
|
+
_ts_metadata14("design:returntype", Promise)
|
|
2471
|
+
], ToolCallController.prototype, "answer", null);
|
|
2472
|
+
_ts_decorate15([
|
|
2473
|
+
(0, import_common15.Post)("skip"),
|
|
2474
|
+
_ts_param13(0, (0, import_common15.Req)()),
|
|
2475
|
+
_ts_param13(1, (0, import_common15.Body)()),
|
|
2476
|
+
_ts_metadata14("design:type", Function),
|
|
2477
|
+
_ts_metadata14("design:paramtypes", [
|
|
2478
|
+
typeof Request === "undefined" ? Object : Request,
|
|
2479
|
+
typeof ApproveBody === "undefined" ? Object : ApproveBody
|
|
2480
|
+
]),
|
|
2481
|
+
_ts_metadata14("design:returntype", Promise)
|
|
2482
|
+
], ToolCallController.prototype, "skip", null);
|
|
2483
|
+
ToolCallController = _ts_decorate15([
|
|
2484
|
+
(0, import_common15.Controller)("tool-call"),
|
|
2485
|
+
_ts_param13(1, (0, import_common15.Inject)(import_nestjs_agent_core16.AGENT_ACTOR_RESOLVER)),
|
|
2486
|
+
_ts_metadata14("design:type", Function),
|
|
2487
|
+
_ts_metadata14("design:paramtypes", [
|
|
1687
2488
|
typeof AgentService === "undefined" ? Object : AgentService,
|
|
1688
2489
|
typeof ActorResolver === "undefined" ? Object : ActorResolver
|
|
1689
2490
|
])
|
|
1690
2491
|
], ToolCallController);
|
|
1691
2492
|
|
|
1692
2493
|
// src/discovery/agent-discovery.service.ts
|
|
1693
|
-
var
|
|
1694
|
-
var
|
|
2494
|
+
var import_nestjs_agent_core17 = require("@dudousxd/nestjs-agent-core");
|
|
2495
|
+
var import_common16 = require("@nestjs/common");
|
|
1695
2496
|
var import_core = require("@nestjs/core");
|
|
1696
2497
|
|
|
1697
2498
|
// src/decorator/agent.decorator.ts
|
|
@@ -1708,23 +2509,23 @@ var SYSTEM_PROMPT_METADATA = Symbol.for("@dudousxd/nestjs-agent:system-prompt");
|
|
|
1708
2509
|
var SYSTEM_PROMPT_CONTRIBUTOR_METADATA = Symbol.for("@dudousxd/nestjs-agent:system-prompt-contributor");
|
|
1709
2510
|
|
|
1710
2511
|
// src/discovery/agent-discovery.service.ts
|
|
1711
|
-
function
|
|
2512
|
+
function _ts_decorate16(decorators, target, key, desc) {
|
|
1712
2513
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1713
2514
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1714
2515
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1715
2516
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1716
2517
|
}
|
|
1717
|
-
__name(
|
|
1718
|
-
function
|
|
2518
|
+
__name(_ts_decorate16, "_ts_decorate");
|
|
2519
|
+
function _ts_metadata15(k, v) {
|
|
1719
2520
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1720
2521
|
}
|
|
1721
|
-
__name(
|
|
1722
|
-
function
|
|
2522
|
+
__name(_ts_metadata15, "_ts_metadata");
|
|
2523
|
+
function _ts_param14(paramIndex, decorator) {
|
|
1723
2524
|
return function(target, key) {
|
|
1724
2525
|
decorator(target, key, paramIndex);
|
|
1725
2526
|
};
|
|
1726
2527
|
}
|
|
1727
|
-
__name(
|
|
2528
|
+
__name(_ts_param14, "_ts_param");
|
|
1728
2529
|
var AgentDiscoveryService = class _AgentDiscoveryService {
|
|
1729
2530
|
static {
|
|
1730
2531
|
__name(this, "AgentDiscoveryService");
|
|
@@ -1733,7 +2534,7 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
|
|
|
1733
2534
|
scanner;
|
|
1734
2535
|
registry;
|
|
1735
2536
|
contributors;
|
|
1736
|
-
logger = new
|
|
2537
|
+
logger = new import_common16.Logger(_AgentDiscoveryService.name);
|
|
1737
2538
|
constructor(discovery, scanner, registry, contributors) {
|
|
1738
2539
|
this.discovery = discovery;
|
|
1739
2540
|
this.scanner = scanner;
|
|
@@ -1772,23 +2573,53 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
|
|
|
1772
2573
|
...meta.maxSteps !== void 0 ? {
|
|
1773
2574
|
maxSteps: meta.maxSteps
|
|
1774
2575
|
} : {},
|
|
2576
|
+
...meta.maxDelegationDepth !== void 0 ? {
|
|
2577
|
+
maxDelegationDepth: meta.maxDelegationDepth
|
|
2578
|
+
} : {},
|
|
2579
|
+
...meta.maxAgentAppearances !== void 0 ? {
|
|
2580
|
+
maxAgentAppearances: meta.maxAgentAppearances
|
|
2581
|
+
} : {},
|
|
2582
|
+
...meta.history !== void 0 ? {
|
|
2583
|
+
history: meta.history
|
|
2584
|
+
} : {},
|
|
2585
|
+
...meta.outputSchema !== void 0 ? {
|
|
2586
|
+
outputSchema: meta.outputSchema
|
|
2587
|
+
} : {},
|
|
2588
|
+
...meta.intake !== void 0 ? {
|
|
2589
|
+
intake: meta.intake
|
|
2590
|
+
} : {},
|
|
2591
|
+
...meta.ask !== void 0 ? {
|
|
2592
|
+
ask: meta.ask
|
|
2593
|
+
} : {},
|
|
2594
|
+
...meta.outputRepairAttempts !== void 0 ? {
|
|
2595
|
+
outputRepairAttempts: meta.outputRepairAttempts
|
|
2596
|
+
} : {},
|
|
1775
2597
|
...meta.handoff !== void 0 ? {
|
|
1776
|
-
delegatesTo: this.
|
|
2598
|
+
delegatesTo: this.handoffEdges(meta)
|
|
1777
2599
|
} : {}
|
|
1778
2600
|
};
|
|
1779
2601
|
}
|
|
1780
|
-
/**
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
2602
|
+
/**
|
|
2603
|
+
* Resolve each handoff entry to an {@link AgentDelegation} — its target's registered name, plus
|
|
2604
|
+
* whether that edge detaches (skipping non-agent classes). A bare name is kept for a plain edge
|
|
2605
|
+
* rather than an always-object form, so a definition an older host built by hand still reads.
|
|
2606
|
+
*/
|
|
2607
|
+
handoffEdges(meta) {
|
|
2608
|
+
const edges = [];
|
|
2609
|
+
for (const entry of meta.handoff ?? []) {
|
|
2610
|
+
const target = typeof entry === "function" ? entry : entry.agent;
|
|
2611
|
+
const detached = typeof entry === "function" ? false : entry.detached === true;
|
|
1784
2612
|
const targetMeta = readAgentMetadata(target);
|
|
1785
2613
|
if (targetMeta === void 0) {
|
|
1786
2614
|
this.logger.warn(`Agent "${meta.name}" hands off to ${target.name}, which is not an @Agent \u2014 skipped.`);
|
|
1787
2615
|
continue;
|
|
1788
2616
|
}
|
|
1789
|
-
|
|
2617
|
+
edges.push(detached ? {
|
|
2618
|
+
agent: targetMeta.name,
|
|
2619
|
+
detached: true
|
|
2620
|
+
} : targetMeta.name);
|
|
1790
2621
|
}
|
|
1791
|
-
return
|
|
2622
|
+
return edges;
|
|
1792
2623
|
}
|
|
1793
2624
|
/** Push every `@SystemPromptContributor()` method on `instance` (bound) into the contributor list. */
|
|
1794
2625
|
collectContributors(instance) {
|
|
@@ -1821,22 +2652,22 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
|
|
|
1821
2652
|
return (ctx) => candidate.call(instance, ctx);
|
|
1822
2653
|
}
|
|
1823
2654
|
};
|
|
1824
|
-
AgentDiscoveryService =
|
|
1825
|
-
(0,
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
2655
|
+
AgentDiscoveryService = _ts_decorate16([
|
|
2656
|
+
(0, import_common16.Injectable)(),
|
|
2657
|
+
_ts_param14(2, (0, import_common16.Inject)(import_nestjs_agent_core17.AGENT_REGISTRY)),
|
|
2658
|
+
_ts_param14(3, (0, import_common16.Inject)(import_nestjs_agent_core17.AGENT_PROMPT_CONTRIBUTORS)),
|
|
2659
|
+
_ts_metadata15("design:type", Function),
|
|
2660
|
+
_ts_metadata15("design:paramtypes", [
|
|
1830
2661
|
typeof import_core.DiscoveryService === "undefined" ? Object : import_core.DiscoveryService,
|
|
1831
2662
|
typeof import_core.MetadataScanner === "undefined" ? Object : import_core.MetadataScanner,
|
|
1832
|
-
typeof
|
|
2663
|
+
typeof import_nestjs_agent_core17.AgentRegistry === "undefined" ? Object : import_nestjs_agent_core17.AgentRegistry,
|
|
1833
2664
|
Array
|
|
1834
2665
|
])
|
|
1835
2666
|
], AgentDiscoveryService);
|
|
1836
2667
|
|
|
1837
2668
|
// src/discovery/ai-tool-discovery.service.ts
|
|
1838
|
-
var
|
|
1839
|
-
var
|
|
2669
|
+
var import_nestjs_agent_core18 = require("@dudousxd/nestjs-agent-core");
|
|
2670
|
+
var import_common17 = require("@nestjs/common");
|
|
1840
2671
|
var import_core2 = require("@nestjs/core");
|
|
1841
2672
|
var import_zod = require("zod");
|
|
1842
2673
|
|
|
@@ -1856,23 +2687,23 @@ function isBrandedFunctionalTool(value) {
|
|
|
1856
2687
|
__name(isBrandedFunctionalTool, "isBrandedFunctionalTool");
|
|
1857
2688
|
|
|
1858
2689
|
// src/discovery/ai-tool-discovery.service.ts
|
|
1859
|
-
function
|
|
2690
|
+
function _ts_decorate17(decorators, target, key, desc) {
|
|
1860
2691
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1861
2692
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1862
2693
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1863
2694
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1864
2695
|
}
|
|
1865
|
-
__name(
|
|
1866
|
-
function
|
|
2696
|
+
__name(_ts_decorate17, "_ts_decorate");
|
|
2697
|
+
function _ts_metadata16(k, v) {
|
|
1867
2698
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1868
2699
|
}
|
|
1869
|
-
__name(
|
|
1870
|
-
function
|
|
2700
|
+
__name(_ts_metadata16, "_ts_metadata");
|
|
2701
|
+
function _ts_param15(paramIndex, decorator) {
|
|
1871
2702
|
return function(target, key) {
|
|
1872
2703
|
decorator(target, key, paramIndex);
|
|
1873
2704
|
};
|
|
1874
2705
|
}
|
|
1875
|
-
__name(
|
|
2706
|
+
__name(_ts_param15, "_ts_param");
|
|
1876
2707
|
var AiToolDiscoveryService = class _AiToolDiscoveryService {
|
|
1877
2708
|
static {
|
|
1878
2709
|
__name(this, "AiToolDiscoveryService");
|
|
@@ -1881,7 +2712,7 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
|
|
|
1881
2712
|
registry;
|
|
1882
2713
|
agents;
|
|
1883
2714
|
options;
|
|
1884
|
-
logger = new
|
|
2715
|
+
logger = new import_common17.Logger(_AiToolDiscoveryService.name);
|
|
1885
2716
|
constructor(discovery, registry, agents, options) {
|
|
1886
2717
|
this.discovery = discovery;
|
|
1887
2718
|
this.registry = registry;
|
|
@@ -1948,22 +2779,30 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
|
|
|
1948
2779
|
}
|
|
1949
2780
|
let delegates = 0;
|
|
1950
2781
|
for (const definition of this.agents.list()) {
|
|
1951
|
-
for (const
|
|
2782
|
+
for (const edge of definition.delegatesTo ?? []) {
|
|
2783
|
+
const { agent: target, detached } = (0, import_nestjs_agent_core18.normalizeDelegation)(edge);
|
|
1952
2784
|
const targetDefinition = this.agents.get(target);
|
|
1953
2785
|
if (targetDefinition === void 0) {
|
|
1954
2786
|
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.`);
|
|
1955
2787
|
}
|
|
1956
|
-
const name = delegateToolName(
|
|
2788
|
+
const name = delegateToolName({
|
|
2789
|
+
target,
|
|
2790
|
+
detached
|
|
2791
|
+
});
|
|
1957
2792
|
if (this.registry.has(name)) {
|
|
1958
2793
|
continue;
|
|
1959
2794
|
}
|
|
1960
2795
|
const targetBlurb = typeof targetDefinition.systemPrompt === "string" ? ` It is: ${targetDefinition.systemPrompt}` : "";
|
|
2796
|
+
const description = detached ? `Start the "${target}" agent working on a task in the BACKGROUND. Returns immediately with a receipt, NOT an answer \u2014 the answer is delivered to this conversation as a separate message later. Use it for work the user does not need to sit and wait for.${targetBlurb}` : `Delegate a task to the "${target}" agent and get its answer.${targetBlurb}`;
|
|
1961
2797
|
this.registry.register(
|
|
1962
2798
|
{
|
|
1963
2799
|
name,
|
|
1964
2800
|
kind: "agent",
|
|
1965
2801
|
targetAgent: target,
|
|
1966
|
-
|
|
2802
|
+
...detached ? {
|
|
2803
|
+
detached: true
|
|
2804
|
+
} : {},
|
|
2805
|
+
description,
|
|
1967
2806
|
inputSchema: import_zod.z.object({
|
|
1968
2807
|
task: import_zod.z.string()
|
|
1969
2808
|
})
|
|
@@ -1991,13 +2830,13 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
|
|
|
1991
2830
|
return true;
|
|
1992
2831
|
}
|
|
1993
2832
|
};
|
|
1994
|
-
AiToolDiscoveryService =
|
|
1995
|
-
(0,
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2833
|
+
AiToolDiscoveryService = _ts_decorate17([
|
|
2834
|
+
(0, import_common17.Injectable)(),
|
|
2835
|
+
_ts_param15(1, (0, import_common17.Inject)(import_nestjs_agent_core18.AGENT_TOOL_REGISTRY)),
|
|
2836
|
+
_ts_param15(2, (0, import_common17.Inject)(import_nestjs_agent_core18.AGENT_REGISTRY)),
|
|
2837
|
+
_ts_param15(3, (0, import_common17.Inject)(import_nestjs_agent_core18.AGENT_OPTIONS)),
|
|
2838
|
+
_ts_metadata16("design:type", Function),
|
|
2839
|
+
_ts_metadata16("design:paramtypes", [
|
|
2001
2840
|
typeof import_core2.DiscoveryService === "undefined" ? Object : import_core2.DiscoveryService,
|
|
2002
2841
|
typeof ToolRegistry === "undefined" ? Object : ToolRegistry,
|
|
2003
2842
|
typeof AgentRegistry === "undefined" ? Object : AgentRegistry,
|
|
@@ -2005,6 +2844,95 @@ AiToolDiscoveryService = _ts_decorate15([
|
|
|
2005
2844
|
])
|
|
2006
2845
|
], AiToolDiscoveryService);
|
|
2007
2846
|
|
|
2847
|
+
// src/discovery/skill-discovery.service.ts
|
|
2848
|
+
var import_nestjs_agent_core20 = require("@dudousxd/nestjs-agent-core");
|
|
2849
|
+
var import_common18 = require("@nestjs/common");
|
|
2850
|
+
var import_core3 = require("@nestjs/core");
|
|
2851
|
+
|
|
2852
|
+
// src/decorator/skill.decorator.ts
|
|
2853
|
+
var import_reflect_metadata4 = require("reflect-metadata");
|
|
2854
|
+
var import_nestjs_agent_core19 = require("@dudousxd/nestjs-agent-core");
|
|
2855
|
+
var SKILL_METADATA = Symbol.for("@dudousxd/nestjs-agent:skill-metadata");
|
|
2856
|
+
function readSkillMetadata(target) {
|
|
2857
|
+
return Reflect.getMetadata(SKILL_METADATA, target);
|
|
2858
|
+
}
|
|
2859
|
+
__name(readSkillMetadata, "readSkillMetadata");
|
|
2860
|
+
function skillScope(options) {
|
|
2861
|
+
return options.scope ?? import_nestjs_agent_core19.GLOBAL_SCOPE;
|
|
2862
|
+
}
|
|
2863
|
+
__name(skillScope, "skillScope");
|
|
2864
|
+
|
|
2865
|
+
// src/discovery/skill-discovery.service.ts
|
|
2866
|
+
function _ts_decorate18(decorators, target, key, desc) {
|
|
2867
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2868
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2869
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2870
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2871
|
+
}
|
|
2872
|
+
__name(_ts_decorate18, "_ts_decorate");
|
|
2873
|
+
function _ts_metadata17(k, v) {
|
|
2874
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2875
|
+
}
|
|
2876
|
+
__name(_ts_metadata17, "_ts_metadata");
|
|
2877
|
+
function _ts_param16(paramIndex, decorator) {
|
|
2878
|
+
return function(target, key) {
|
|
2879
|
+
decorator(target, key, paramIndex);
|
|
2880
|
+
};
|
|
2881
|
+
}
|
|
2882
|
+
__name(_ts_param16, "_ts_param");
|
|
2883
|
+
var SkillDiscoveryService = class _SkillDiscoveryService {
|
|
2884
|
+
static {
|
|
2885
|
+
__name(this, "SkillDiscoveryService");
|
|
2886
|
+
}
|
|
2887
|
+
discovery;
|
|
2888
|
+
declared;
|
|
2889
|
+
logger = new import_common18.Logger(_SkillDiscoveryService.name);
|
|
2890
|
+
constructor(discovery, declared) {
|
|
2891
|
+
this.discovery = discovery;
|
|
2892
|
+
this.declared = declared;
|
|
2893
|
+
}
|
|
2894
|
+
onModuleInit() {
|
|
2895
|
+
for (const wrapper of this.discovery.getProviders()) {
|
|
2896
|
+
const instance = wrapper.instance;
|
|
2897
|
+
if (instance === null || typeof instance !== "object") {
|
|
2898
|
+
continue;
|
|
2899
|
+
}
|
|
2900
|
+
const meta = readSkillMetadata(instance.constructor);
|
|
2901
|
+
if (meta === void 0) {
|
|
2902
|
+
continue;
|
|
2903
|
+
}
|
|
2904
|
+
const body = this.bodyOf(instance, meta.body);
|
|
2905
|
+
if (body === void 0) {
|
|
2906
|
+
this.logger.warn(`Skill "${meta.name}" declares no body \u2014 add a \`body()\` method or \`@Skill({ body })\`. Skipped.`);
|
|
2907
|
+
continue;
|
|
2908
|
+
}
|
|
2909
|
+
this.declared.push({
|
|
2910
|
+
name: meta.name,
|
|
2911
|
+
description: meta.description,
|
|
2912
|
+
scope: skillScope(meta),
|
|
2913
|
+
body
|
|
2914
|
+
});
|
|
2915
|
+
}
|
|
2916
|
+
}
|
|
2917
|
+
/** The instance's `body()` method (bound), else the flat string, else nothing to offer. */
|
|
2918
|
+
bodyOf(instance, flat) {
|
|
2919
|
+
const candidate = instance.body;
|
|
2920
|
+
if (typeof candidate === "function") {
|
|
2921
|
+
return (ctx) => candidate.call(instance, ctx);
|
|
2922
|
+
}
|
|
2923
|
+
return flat === void 0 ? void 0 : () => flat;
|
|
2924
|
+
}
|
|
2925
|
+
};
|
|
2926
|
+
SkillDiscoveryService = _ts_decorate18([
|
|
2927
|
+
(0, import_common18.Injectable)(),
|
|
2928
|
+
_ts_param16(1, (0, import_common18.Inject)(import_nestjs_agent_core20.AGENT_SKILL_SOURCES)),
|
|
2929
|
+
_ts_metadata17("design:type", Function),
|
|
2930
|
+
_ts_metadata17("design:paramtypes", [
|
|
2931
|
+
typeof import_core3.DiscoveryService === "undefined" ? Object : import_core3.DiscoveryService,
|
|
2932
|
+
Array
|
|
2933
|
+
])
|
|
2934
|
+
], SkillDiscoveryService);
|
|
2935
|
+
|
|
2008
2936
|
// src/ledger-quota-store.ts
|
|
2009
2937
|
var LedgerQuotaStore = class {
|
|
2010
2938
|
static {
|
|
@@ -2024,38 +2952,44 @@ var LedgerQuotaStore = class {
|
|
|
2024
2952
|
withinLimit: usedTokens < this.limitTokens
|
|
2025
2953
|
};
|
|
2026
2954
|
}
|
|
2027
|
-
async bump() {
|
|
2955
|
+
async bump(_actorRef, _day, _tokens) {
|
|
2028
2956
|
}
|
|
2029
2957
|
};
|
|
2030
2958
|
|
|
2031
2959
|
// src/runner/inline-agent-runner.ts
|
|
2032
|
-
var
|
|
2033
|
-
var
|
|
2034
|
-
function
|
|
2960
|
+
var import_nestjs_agent_core21 = require("@dudousxd/nestjs-agent-core");
|
|
2961
|
+
var import_common19 = require("@nestjs/common");
|
|
2962
|
+
function _ts_decorate19(decorators, target, key, desc) {
|
|
2035
2963
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2036
2964
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2037
2965
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2038
2966
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2039
2967
|
}
|
|
2040
|
-
__name(
|
|
2041
|
-
function
|
|
2968
|
+
__name(_ts_decorate19, "_ts_decorate");
|
|
2969
|
+
function _ts_metadata18(k, v) {
|
|
2042
2970
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2043
2971
|
}
|
|
2044
|
-
__name(
|
|
2045
|
-
function
|
|
2972
|
+
__name(_ts_metadata18, "_ts_metadata");
|
|
2973
|
+
function _ts_param17(paramIndex, decorator) {
|
|
2046
2974
|
return function(target, key) {
|
|
2047
2975
|
decorator(target, key, paramIndex);
|
|
2048
2976
|
};
|
|
2049
2977
|
}
|
|
2050
|
-
__name(
|
|
2978
|
+
__name(_ts_param17, "_ts_param");
|
|
2051
2979
|
var InlineAgentRunner = class _InlineAgentRunner {
|
|
2052
2980
|
static {
|
|
2053
2981
|
__name(this, "InlineAgentRunner");
|
|
2054
2982
|
}
|
|
2055
2983
|
factory;
|
|
2056
2984
|
store;
|
|
2057
|
-
logger = new
|
|
2985
|
+
logger = new import_common19.Logger(_InlineAgentRunner.name);
|
|
2058
2986
|
pending = /* @__PURE__ */ new Map();
|
|
2987
|
+
/**
|
|
2988
|
+
* Runs someone has asked to stop. In-process, like `pending`, and for the same reason: this runner
|
|
2989
|
+
* is single-replica by construction, so the request is readable by the only loop that could be
|
|
2990
|
+
* running it. A cancelled id is dropped once the run settles, so the set tracks live runs only.
|
|
2991
|
+
*/
|
|
2992
|
+
cancelled = /* @__PURE__ */ new Set();
|
|
2059
2993
|
constructor(factory, store) {
|
|
2060
2994
|
this.factory = factory;
|
|
2061
2995
|
this.store = store;
|
|
@@ -2064,15 +2998,31 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
2064
2998
|
const runId = crypto.randomUUID();
|
|
2065
2999
|
const day = input.day ?? utcDay();
|
|
2066
3000
|
const deps = this.factory.forAgent(input.agentName);
|
|
2067
|
-
const hooks = this.topLevelHooks(
|
|
2068
|
-
|
|
3001
|
+
const hooks = this.topLevelHooks({
|
|
3002
|
+
runId,
|
|
3003
|
+
deps,
|
|
3004
|
+
actor: input.actor,
|
|
3005
|
+
day,
|
|
3006
|
+
threadId: input.threadId,
|
|
3007
|
+
chainBelow: [
|
|
3008
|
+
...input.delegationPath ?? [],
|
|
3009
|
+
...input.agentName !== void 0 ? [
|
|
3010
|
+
input.agentName
|
|
3011
|
+
] : []
|
|
3012
|
+
]
|
|
3013
|
+
});
|
|
3014
|
+
void (0, import_nestjs_agent_core21.runAgentLoop)({
|
|
2069
3015
|
...deps,
|
|
2070
3016
|
day
|
|
2071
3017
|
}, input, hooks).then(() => this.store.setActiveStream(input.threadId, null)).catch(async (error) => {
|
|
3018
|
+
if (error instanceof import_nestjs_agent_core21.RunCancelledError) {
|
|
3019
|
+
await this.settleCancelled(runId, input.threadId, deps);
|
|
3020
|
+
return;
|
|
3021
|
+
}
|
|
2072
3022
|
const message = error instanceof Error ? error.message : String(error);
|
|
2073
|
-
const code =
|
|
3023
|
+
const code = (0, import_nestjs_agent_core21.agentFailureCode)(error);
|
|
2074
3024
|
this.logger.error(`agent run ${runId} failed (${code}): ${message}`);
|
|
2075
|
-
(0,
|
|
3025
|
+
(0, import_nestjs_agent_core21.publishAgentRunFailed)({
|
|
2076
3026
|
runId,
|
|
2077
3027
|
code,
|
|
2078
3028
|
message
|
|
@@ -2089,33 +3039,216 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
2089
3039
|
code,
|
|
2090
3040
|
message
|
|
2091
3041
|
});
|
|
2092
|
-
});
|
|
3042
|
+
}).finally(() => this.cancelled.delete(runId));
|
|
2093
3043
|
return {
|
|
2094
3044
|
runId
|
|
2095
3045
|
};
|
|
2096
3046
|
}
|
|
2097
|
-
async signal(runId,
|
|
2098
|
-
const key = `${runId}:${
|
|
2099
|
-
const
|
|
2100
|
-
if (
|
|
3047
|
+
async signal(runId, toolCallId2, reply) {
|
|
3048
|
+
const key = `${runId}:${toolCallId2}`;
|
|
3049
|
+
const waiter = this.pending.get(key);
|
|
3050
|
+
if (waiter !== void 0) {
|
|
2101
3051
|
this.pending.delete(key);
|
|
2102
|
-
resolve(
|
|
3052
|
+
waiter.resolve(reply);
|
|
2103
3053
|
}
|
|
2104
3054
|
}
|
|
3055
|
+
/**
|
|
3056
|
+
* Ask a run to stop, and settle whatever it was parked on.
|
|
3057
|
+
*
|
|
3058
|
+
* The loop observes the request at its next safe point (between steps, before the turn's tools) and
|
|
3059
|
+
* unwinds from there — so a tool already executing is left to finish, and its result is recorded
|
|
3060
|
+
* exactly as it would have been. What this cannot wait for is a turn parked on a human: that wait
|
|
3061
|
+
* is a promise nobody is going to resolve, so it is REJECTED here with the same
|
|
3062
|
+
* {@link RunCancelledError} the loop would have thrown, and the run unwinds through the identical
|
|
3063
|
+
* path.
|
|
3064
|
+
*
|
|
3065
|
+
* Settlement — the run row, the thread's active stream, the stream's terminal — belongs to the
|
|
3066
|
+
* `RunCancelledError` catch in `start`, so a cancel and an ordinary failure settle in one place
|
|
3067
|
+
* each and can never both write.
|
|
3068
|
+
*/
|
|
2105
3069
|
async cancel(runId) {
|
|
2106
|
-
|
|
3070
|
+
this.cancelled.add(runId);
|
|
3071
|
+
for (const [key, waiter] of this.pending) {
|
|
3072
|
+
if (key.startsWith(`${runId}:`)) {
|
|
3073
|
+
this.pending.delete(key);
|
|
3074
|
+
waiter.reject(new import_nestjs_agent_core21.RunCancelledError());
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
await Promise.resolve();
|
|
3078
|
+
}
|
|
3079
|
+
/**
|
|
3080
|
+
* The single place a cancelled run's state is settled: recorded as its own terminal (never
|
|
3081
|
+
* `failed` — a user pressing Stop must not land in someone's error rate), the thread released, and
|
|
3082
|
+
* the stream ENDED after a `cancelled` frame rather than failed, so a client that retries failed
|
|
3083
|
+
* streams does not retry this one.
|
|
3084
|
+
*/
|
|
3085
|
+
async settleCancelled(runId, threadId, deps) {
|
|
3086
|
+
this.logger.log(`agent run ${runId} cancelled`);
|
|
3087
|
+
await this.store.setActiveStream(threadId, null);
|
|
2107
3088
|
const writer = await deps.sink.open(runId);
|
|
3089
|
+
await writer.write((0, import_nestjs_agent_core21.encodeStreamEvent)({
|
|
3090
|
+
kind: "cancelled"
|
|
3091
|
+
}));
|
|
2108
3092
|
await writer.end();
|
|
3093
|
+
await this.store.recordRunEnd?.({
|
|
3094
|
+
runId,
|
|
3095
|
+
status: "cancelled"
|
|
3096
|
+
});
|
|
3097
|
+
}
|
|
3098
|
+
/**
|
|
3099
|
+
* Park a run on a human, keyed by run + tool call. One map for approvals and for question-set
|
|
3100
|
+
* answers alike: both wait on the same key, and `signal` cannot tell (or need to tell) which
|
|
3101
|
+
* shape it is delivering — the loop asked for one and only ever gets what the caller sent. A
|
|
3102
|
+
* cancel settles the wait too, by rejecting it.
|
|
3103
|
+
*/
|
|
3104
|
+
park(runId, toolCallId2) {
|
|
3105
|
+
return new Promise((resolve, reject) => {
|
|
3106
|
+
this.pending.set(`${runId}:${toolCallId2}`, {
|
|
3107
|
+
resolve,
|
|
3108
|
+
reject
|
|
3109
|
+
});
|
|
3110
|
+
});
|
|
2109
3111
|
}
|
|
2110
|
-
topLevelHooks(
|
|
3112
|
+
topLevelHooks(args) {
|
|
3113
|
+
const { runId, deps, actor, day, threadId, chainBelow } = args;
|
|
2111
3114
|
return {
|
|
2112
3115
|
runId,
|
|
2113
3116
|
openSink: /* @__PURE__ */ __name(() => deps.sink.open(runId), "openSink"),
|
|
2114
|
-
awaitApproval: /* @__PURE__ */ __name((call) =>
|
|
2115
|
-
|
|
2116
|
-
|
|
3117
|
+
awaitApproval: /* @__PURE__ */ __name((call) => this.park(runId, call.id), "awaitApproval"),
|
|
3118
|
+
awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
|
|
3119
|
+
step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
|
|
3120
|
+
parallel: import_nestjs_agent_core21.settleAll,
|
|
3121
|
+
cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId), "cancelled"),
|
|
3122
|
+
runAgent: /* @__PURE__ */ __name((agentName, task) => this.runNested({
|
|
3123
|
+
agentName,
|
|
3124
|
+
task,
|
|
3125
|
+
actor,
|
|
3126
|
+
day,
|
|
3127
|
+
depth: 1,
|
|
3128
|
+
path: chainBelow,
|
|
3129
|
+
sinkRunId: runId,
|
|
3130
|
+
parentRunId: runId
|
|
3131
|
+
}), "runAgent"),
|
|
3132
|
+
startAgent: /* @__PURE__ */ __name(({ agentName, task, toolCallId: toolCallId2 }) => this.startDetached({
|
|
3133
|
+
agentName,
|
|
3134
|
+
task,
|
|
3135
|
+
actor,
|
|
3136
|
+
day,
|
|
3137
|
+
depth: 1,
|
|
3138
|
+
path: chainBelow,
|
|
3139
|
+
parentRunId: runId,
|
|
3140
|
+
deliverTo: {
|
|
3141
|
+
threadId,
|
|
3142
|
+
toolCallId: toolCallId2
|
|
3143
|
+
}
|
|
3144
|
+
}), "startAgent")
|
|
3145
|
+
};
|
|
3146
|
+
}
|
|
3147
|
+
/**
|
|
3148
|
+
* Delegate WITHOUT waiting: a nested loop nobody awaits, on its own thread and its own sink, which
|
|
3149
|
+
* posts its answer back into the delegating thread when it lands (`deliverTo`, settled by the
|
|
3150
|
+
* loop). The calling turn gets the run id straight back and finishes.
|
|
3151
|
+
*
|
|
3152
|
+
* No `sinkRunId`, unlike {@link runNested}: forwarding into the stream the human is watching would
|
|
3153
|
+
* write into a turn that has already ended. Its own approvals resolve through the shared pending
|
|
3154
|
+
* map keyed by its own runId — which is what the pending-approvals surface routes to.
|
|
3155
|
+
*/
|
|
3156
|
+
async startDetached(args) {
|
|
3157
|
+
const { agentName, task, actor, day, depth, path, parentRunId, deliverTo } = args;
|
|
3158
|
+
const subThread = await this.store.createThread({
|
|
3159
|
+
actor,
|
|
3160
|
+
transient: true
|
|
3161
|
+
});
|
|
3162
|
+
const runId = crypto.randomUUID();
|
|
3163
|
+
await this.store.setActiveStream(subThread.id, runId);
|
|
3164
|
+
const deps = this.factory.forAgent(agentName);
|
|
3165
|
+
const hooks = {
|
|
3166
|
+
runId,
|
|
3167
|
+
openSink: /* @__PURE__ */ __name(() => deps.sink.open(runId), "openSink"),
|
|
3168
|
+
awaitApproval: /* @__PURE__ */ __name((call) => this.park(runId, call.id), "awaitApproval"),
|
|
3169
|
+
awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
|
|
2117
3170
|
step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
|
|
2118
|
-
|
|
3171
|
+
parallel: import_nestjs_agent_core21.settleAll,
|
|
3172
|
+
cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId), "cancelled"),
|
|
3173
|
+
runAgent: /* @__PURE__ */ __name((childName, childTask) => this.runNested({
|
|
3174
|
+
agentName: childName,
|
|
3175
|
+
task: childTask,
|
|
3176
|
+
actor,
|
|
3177
|
+
day,
|
|
3178
|
+
depth: depth + 1,
|
|
3179
|
+
path: [
|
|
3180
|
+
...path,
|
|
3181
|
+
agentName
|
|
3182
|
+
],
|
|
3183
|
+
// A detached run owns a stream of its own, so ITS sub-agents forward into that one.
|
|
3184
|
+
sinkRunId: runId,
|
|
3185
|
+
parentRunId: runId
|
|
3186
|
+
}), "runAgent"),
|
|
3187
|
+
startAgent: /* @__PURE__ */ __name(({ agentName: childName, task: childTask, toolCallId: toolCallId2 }) => this.startDetached({
|
|
3188
|
+
agentName: childName,
|
|
3189
|
+
task: childTask,
|
|
3190
|
+
actor,
|
|
3191
|
+
day,
|
|
3192
|
+
depth: depth + 1,
|
|
3193
|
+
path: [
|
|
3194
|
+
...path,
|
|
3195
|
+
agentName
|
|
3196
|
+
],
|
|
3197
|
+
parentRunId: runId,
|
|
3198
|
+
deliverTo: {
|
|
3199
|
+
threadId: subThread.id,
|
|
3200
|
+
toolCallId: toolCallId2
|
|
3201
|
+
}
|
|
3202
|
+
}), "startAgent")
|
|
3203
|
+
};
|
|
3204
|
+
void (0, import_nestjs_agent_core21.runAgentLoop)({
|
|
3205
|
+
...deps,
|
|
3206
|
+
day
|
|
3207
|
+
}, {
|
|
3208
|
+
threadId: subThread.id,
|
|
3209
|
+
actor,
|
|
3210
|
+
userText: task,
|
|
3211
|
+
agentName,
|
|
3212
|
+
day,
|
|
3213
|
+
delegationDepth: depth,
|
|
3214
|
+
delegationPath: path,
|
|
3215
|
+
parentRunId,
|
|
3216
|
+
deliverTo
|
|
3217
|
+
}, hooks).catch(async (error) => {
|
|
3218
|
+
const cancelled = error instanceof import_nestjs_agent_core21.RunCancelledError;
|
|
3219
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3220
|
+
if (!cancelled) {
|
|
3221
|
+
this.logger.error(`detached agent run ${runId} failed: ${message}`);
|
|
3222
|
+
(0, import_nestjs_agent_core21.publishAgentRunFailed)({
|
|
3223
|
+
runId,
|
|
3224
|
+
code: (0, import_nestjs_agent_core21.agentFailureCode)(error),
|
|
3225
|
+
message
|
|
3226
|
+
});
|
|
3227
|
+
}
|
|
3228
|
+
await this.store.recordRunEnd?.({
|
|
3229
|
+
runId,
|
|
3230
|
+
status: cancelled ? "cancelled" : "failed",
|
|
3231
|
+
...cancelled ? {} : {
|
|
3232
|
+
errorCode: (0, import_nestjs_agent_core21.agentFailureCode)(error),
|
|
3233
|
+
errorMessage: message
|
|
3234
|
+
}
|
|
3235
|
+
});
|
|
3236
|
+
await (0, import_nestjs_agent_core21.settleUnsettledDelegation)({
|
|
3237
|
+
store: this.store,
|
|
3238
|
+
delivery: deliverTo,
|
|
3239
|
+
agent: agentName,
|
|
3240
|
+
runId,
|
|
3241
|
+
status: cancelled ? "cancelled" : "failed",
|
|
3242
|
+
...cancelled ? {} : {
|
|
3243
|
+
error: message
|
|
3244
|
+
}
|
|
3245
|
+
});
|
|
3246
|
+
}).finally(async () => {
|
|
3247
|
+
this.cancelled.delete(runId);
|
|
3248
|
+
await this.store.setActiveStream(subThread.id, null);
|
|
3249
|
+
});
|
|
3250
|
+
return {
|
|
3251
|
+
runId
|
|
2119
3252
|
};
|
|
2120
3253
|
}
|
|
2121
3254
|
/**
|
|
@@ -2123,7 +3256,8 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
2123
3256
|
* (the top-level run the human is watching) so its output and any pending action tool are visible,
|
|
2124
3257
|
* and its own approvals resolve through the shared pending map keyed by its own runId.
|
|
2125
3258
|
*/
|
|
2126
|
-
async runNested(
|
|
3259
|
+
async runNested(args) {
|
|
3260
|
+
const { agentName, task, actor, day, depth, path, sinkRunId, parentRunId } = args;
|
|
2127
3261
|
const subThread = await this.store.createThread({
|
|
2128
3262
|
actor,
|
|
2129
3263
|
transient: true
|
|
@@ -2135,14 +3269,45 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
2135
3269
|
runId,
|
|
2136
3270
|
// Forward into the top-level stream; the top-level run owns end/fail on that shared sink.
|
|
2137
3271
|
openSink: /* @__PURE__ */ __name(async () => childSinkWriter(await deps.sink.open(sinkRunId)), "openSink"),
|
|
2138
|
-
awaitApproval: /* @__PURE__ */ __name((call) =>
|
|
2139
|
-
|
|
2140
|
-
}), "awaitApproval"),
|
|
3272
|
+
awaitApproval: /* @__PURE__ */ __name((call) => this.park(runId, call.id), "awaitApproval"),
|
|
3273
|
+
awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
|
|
2141
3274
|
step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
|
|
2142
|
-
|
|
3275
|
+
parallel: import_nestjs_agent_core21.settleAll,
|
|
3276
|
+
// A child stops when it is cancelled OR when the run a human is actually watching is: the
|
|
3277
|
+
// canceller names the top-level run, which is the only id that ever left the server.
|
|
3278
|
+
cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId) || this.cancelled.has(sinkRunId), "cancelled"),
|
|
3279
|
+
runAgent: /* @__PURE__ */ __name((childName, childTask) => this.runNested({
|
|
3280
|
+
agentName: childName,
|
|
3281
|
+
task: childTask,
|
|
3282
|
+
actor,
|
|
3283
|
+
day,
|
|
3284
|
+
depth: depth + 1,
|
|
3285
|
+
path: [
|
|
3286
|
+
...path,
|
|
3287
|
+
agentName
|
|
3288
|
+
],
|
|
3289
|
+
sinkRunId,
|
|
3290
|
+
parentRunId: runId
|
|
3291
|
+
}), "runAgent"),
|
|
3292
|
+
startAgent: /* @__PURE__ */ __name(({ agentName: childName, task: childTask, toolCallId: toolCallId2 }) => this.startDetached({
|
|
3293
|
+
agentName: childName,
|
|
3294
|
+
task: childTask,
|
|
3295
|
+
actor,
|
|
3296
|
+
day,
|
|
3297
|
+
depth: depth + 1,
|
|
3298
|
+
path: [
|
|
3299
|
+
...path,
|
|
3300
|
+
agentName
|
|
3301
|
+
],
|
|
3302
|
+
parentRunId: runId,
|
|
3303
|
+
deliverTo: {
|
|
3304
|
+
threadId: subThread.id,
|
|
3305
|
+
toolCallId: toolCallId2
|
|
3306
|
+
}
|
|
3307
|
+
}), "startAgent")
|
|
2143
3308
|
};
|
|
2144
3309
|
try {
|
|
2145
|
-
return await (0,
|
|
3310
|
+
return await (0, import_nestjs_agent_core21.runAgentLoop)({
|
|
2146
3311
|
...deps,
|
|
2147
3312
|
day
|
|
2148
3313
|
}, {
|
|
@@ -2152,6 +3317,8 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
2152
3317
|
agentName,
|
|
2153
3318
|
day,
|
|
2154
3319
|
delegationDepth: depth,
|
|
3320
|
+
delegationPath: path,
|
|
3321
|
+
parentRunId,
|
|
2155
3322
|
sinkRunId
|
|
2156
3323
|
}, hooks);
|
|
2157
3324
|
} finally {
|
|
@@ -2159,112 +3326,177 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
2159
3326
|
}
|
|
2160
3327
|
}
|
|
2161
3328
|
};
|
|
2162
|
-
InlineAgentRunner =
|
|
2163
|
-
(0,
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
3329
|
+
InlineAgentRunner = _ts_decorate19([
|
|
3330
|
+
(0, import_common19.Injectable)(),
|
|
3331
|
+
_ts_param17(0, (0, import_common19.Inject)(import_nestjs_agent_core21.AGENT_DEPS_FACTORY)),
|
|
3332
|
+
_ts_param17(1, (0, import_common19.Inject)(import_nestjs_agent_core21.AGENT_STORE)),
|
|
3333
|
+
_ts_metadata18("design:type", Function),
|
|
3334
|
+
_ts_metadata18("design:paramtypes", [
|
|
2168
3335
|
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
|
|
2169
3336
|
typeof AgentStore === "undefined" ? Object : AgentStore
|
|
2170
3337
|
])
|
|
2171
3338
|
], InlineAgentRunner);
|
|
2172
3339
|
|
|
3340
|
+
// src/skills-config.ts
|
|
3341
|
+
var import_nestjs_agent_core22 = require("@dudousxd/nestjs-agent-core");
|
|
3342
|
+
function declaredSkillProvider(declared) {
|
|
3343
|
+
return {
|
|
3344
|
+
list: /* @__PURE__ */ __name(({ scopes }) => declared.filter((skill) => scopes.includes(skill.scope)).map(({ name, description, scope }) => ({
|
|
3345
|
+
name,
|
|
3346
|
+
description,
|
|
3347
|
+
scope
|
|
3348
|
+
})), "list"),
|
|
3349
|
+
load: /* @__PURE__ */ __name(async ({ name, scope, ctx }) => {
|
|
3350
|
+
const match = declared.find((skill) => skill.name === name && skill.scope === scope);
|
|
3351
|
+
return match === void 0 ? null : await match.body(ctx);
|
|
3352
|
+
}, "load")
|
|
3353
|
+
};
|
|
3354
|
+
}
|
|
3355
|
+
__name(declaredSkillProvider, "declaredSkillProvider");
|
|
3356
|
+
function resolveSkillsConfig(options, declared) {
|
|
3357
|
+
if (options === void 0) {
|
|
3358
|
+
return void 0;
|
|
3359
|
+
}
|
|
3360
|
+
const providers = options.provider === void 0 ? [
|
|
3361
|
+
declaredSkillProvider(declared)
|
|
3362
|
+
] : [
|
|
3363
|
+
options.provider,
|
|
3364
|
+
declaredSkillProvider(declared)
|
|
3365
|
+
];
|
|
3366
|
+
return {
|
|
3367
|
+
provider: providers.length === 1 ? providers[0] : (0, import_nestjs_agent_core22.compositeSkillProvider)(providers),
|
|
3368
|
+
...options.scopes !== void 0 ? {
|
|
3369
|
+
scopes: options.scopes
|
|
3370
|
+
} : {},
|
|
3371
|
+
...options.maxSkills !== void 0 ? {
|
|
3372
|
+
maxSkills: options.maxSkills
|
|
3373
|
+
} : {}
|
|
3374
|
+
};
|
|
3375
|
+
}
|
|
3376
|
+
__name(resolveSkillsConfig, "resolveSkillsConfig");
|
|
3377
|
+
|
|
2173
3378
|
// src/agent.module.ts
|
|
2174
|
-
function
|
|
3379
|
+
function _ts_decorate20(decorators, target, key, desc) {
|
|
2175
3380
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2176
3381
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2177
3382
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2178
3383
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2179
3384
|
}
|
|
2180
|
-
__name(
|
|
3385
|
+
__name(_ts_decorate20, "_ts_decorate");
|
|
2181
3386
|
var DEFAULT_PATH = "agent";
|
|
2182
3387
|
function sharedProviders(durable, includeStore) {
|
|
2183
3388
|
const providers = [
|
|
2184
3389
|
{
|
|
2185
|
-
provide:
|
|
2186
|
-
useFactory: /* @__PURE__ */ __name(() => new
|
|
3390
|
+
provide: import_nestjs_agent_core23.AGENT_TOOL_REGISTRY,
|
|
3391
|
+
useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core23.ToolRegistry(), "useFactory")
|
|
2187
3392
|
},
|
|
2188
3393
|
// Starts empty; AgentDiscoveryService populates it from `@Agent`-decorated providers at boot.
|
|
2189
3394
|
{
|
|
2190
|
-
provide:
|
|
2191
|
-
useFactory: /* @__PURE__ */ __name(() => new
|
|
3395
|
+
provide: import_nestjs_agent_core23.AGENT_REGISTRY,
|
|
3396
|
+
useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core23.AgentRegistry(), "useFactory")
|
|
2192
3397
|
},
|
|
2193
3398
|
// A shared, mutable list AgentDiscoveryService fills with `@SystemPromptContributor()` methods.
|
|
2194
3399
|
{
|
|
2195
|
-
provide:
|
|
3400
|
+
provide: import_nestjs_agent_core23.AGENT_PROMPT_CONTRIBUTORS,
|
|
3401
|
+
useFactory: /* @__PURE__ */ __name(() => [], "useFactory")
|
|
3402
|
+
},
|
|
3403
|
+
// Likewise for `@Skill`-decorated providers — filled by SkillDiscoveryService at onModuleInit,
|
|
3404
|
+
// read lazily by the AGENT_SKILLS provider below (which DI builds before discovery has run).
|
|
3405
|
+
{
|
|
3406
|
+
provide: import_nestjs_agent_core23.AGENT_SKILL_SOURCES,
|
|
2196
3407
|
useFactory: /* @__PURE__ */ __name(() => [], "useFactory")
|
|
2197
3408
|
},
|
|
2198
3409
|
{
|
|
2199
|
-
|
|
3410
|
+
// One resolution, shared by the loop's deps and the listing endpoint: a second one would
|
|
3411
|
+
// drift, and a user would be offered a skill the agent cannot reach. `undefined` when the
|
|
3412
|
+
// host configured none — which is what keeps the turn's checkpoint sequence unchanged.
|
|
3413
|
+
provide: import_nestjs_agent_core23.AGENT_SKILLS,
|
|
3414
|
+
useFactory: /* @__PURE__ */ __name((options, declared) => resolveSkillsConfig(options.skills, declared), "useFactory"),
|
|
3415
|
+
inject: [
|
|
3416
|
+
import_nestjs_agent_core23.AGENT_OPTIONS,
|
|
3417
|
+
import_nestjs_agent_core23.AGENT_SKILL_SOURCES
|
|
3418
|
+
]
|
|
3419
|
+
},
|
|
3420
|
+
{
|
|
3421
|
+
// One resolution, shared by the loop's deps and the read-back endpoint: a person has to be
|
|
3422
|
+
// shown what the model was shown, and two resolutions would eventually disagree about that.
|
|
3423
|
+
provide: import_nestjs_agent_core23.AGENT_MEMORY,
|
|
3424
|
+
useFactory: /* @__PURE__ */ __name((options) => options.memory, "useFactory"),
|
|
3425
|
+
inject: [
|
|
3426
|
+
import_nestjs_agent_core23.AGENT_OPTIONS
|
|
3427
|
+
]
|
|
3428
|
+
},
|
|
3429
|
+
{
|
|
3430
|
+
provide: import_nestjs_agent_core23.AGENT_SINK,
|
|
2200
3431
|
useFactory: /* @__PURE__ */ __name((options) => options.sink ?? new InProcessTokenStreamSink(), "useFactory"),
|
|
2201
3432
|
inject: [
|
|
2202
|
-
|
|
3433
|
+
import_nestjs_agent_core23.AGENT_OPTIONS
|
|
2203
3434
|
]
|
|
2204
3435
|
},
|
|
2205
3436
|
{
|
|
2206
|
-
provide:
|
|
2207
|
-
useFactory: /* @__PURE__ */ __name((options) => options.rolesPolicy ?? new
|
|
3437
|
+
provide: import_nestjs_agent_core23.AGENT_ROLES_POLICY,
|
|
3438
|
+
useFactory: /* @__PURE__ */ __name((options) => options.rolesPolicy ?? new import_nestjs_agent_core23.DefaultRolesPolicy(options.defaultRoles), "useFactory"),
|
|
2208
3439
|
inject: [
|
|
2209
|
-
|
|
3440
|
+
import_nestjs_agent_core23.AGENT_OPTIONS
|
|
2210
3441
|
]
|
|
2211
3442
|
},
|
|
2212
3443
|
{
|
|
2213
|
-
provide:
|
|
3444
|
+
provide: import_nestjs_agent_core23.AGENT_ACTOR_RESOLVER,
|
|
2214
3445
|
useFactory: /* @__PURE__ */ __name((options) => options.actorResolver, "useFactory"),
|
|
2215
3446
|
inject: [
|
|
2216
|
-
|
|
3447
|
+
import_nestjs_agent_core23.AGENT_OPTIONS
|
|
2217
3448
|
]
|
|
2218
3449
|
},
|
|
2219
3450
|
{
|
|
2220
|
-
provide:
|
|
3451
|
+
provide: import_nestjs_agent_core23.AGENT_MODEL,
|
|
2221
3452
|
useFactory: /* @__PURE__ */ __name((o) => o.model, "useFactory"),
|
|
2222
3453
|
inject: [
|
|
2223
|
-
|
|
3454
|
+
import_nestjs_agent_core23.AGENT_OPTIONS
|
|
2224
3455
|
]
|
|
2225
3456
|
},
|
|
2226
3457
|
{
|
|
2227
3458
|
// An explicit `quota` wins; otherwise `quotaLimitTokens` binds the built-in ledger-backed
|
|
2228
3459
|
// store; otherwise quotas are off (undefined). The ledger store reads the same usage rows
|
|
2229
3460
|
// the loop already writes, so enforcement needs no extra shared state across replicas.
|
|
2230
|
-
provide:
|
|
3461
|
+
provide: import_nestjs_agent_core23.AGENT_QUOTA_STORE,
|
|
2231
3462
|
useFactory: /* @__PURE__ */ __name((o, store) => o.quota ?? (o.quotaLimitTokens !== void 0 ? new LedgerQuotaStore(store, o.quotaLimitTokens) : void 0), "useFactory"),
|
|
2232
3463
|
inject: [
|
|
2233
|
-
|
|
2234
|
-
|
|
3464
|
+
import_nestjs_agent_core23.AGENT_OPTIONS,
|
|
3465
|
+
import_nestjs_agent_core23.AGENT_STORE
|
|
2235
3466
|
]
|
|
2236
3467
|
},
|
|
2237
3468
|
AgentDepsFactory2,
|
|
2238
3469
|
{
|
|
2239
|
-
provide:
|
|
3470
|
+
provide: import_nestjs_agent_core23.AGENT_DEPS_FACTORY,
|
|
2240
3471
|
useExisting: AgentDepsFactory2
|
|
2241
3472
|
},
|
|
2242
3473
|
// Populates the registry + contributors (onModuleInit) BEFORE AiToolDiscoveryService synthesizes
|
|
2243
3474
|
// handoff tools (onApplicationBootstrap) reads the registry.
|
|
2244
3475
|
AgentDiscoveryService,
|
|
2245
3476
|
AiToolDiscoveryService,
|
|
3477
|
+
SkillDiscoveryService,
|
|
2246
3478
|
InlineAgentRunner,
|
|
2247
3479
|
AgentService,
|
|
2248
3480
|
// Bound ALWAYS (durable or inline) — the console's cross-thread approvals inbox routes decisions
|
|
2249
3481
|
// through AgentService.signalToolCall, which reaches whichever AGENT_RUNNER is bound above.
|
|
2250
3482
|
AgentApprovalPortAdapter,
|
|
2251
3483
|
{
|
|
2252
|
-
provide:
|
|
3484
|
+
provide: import_nestjs_agent_core23.AGENT_APPROVAL_PORT,
|
|
2253
3485
|
useExisting: AgentApprovalPortAdapter
|
|
2254
3486
|
}
|
|
2255
3487
|
];
|
|
2256
3488
|
if (includeStore) {
|
|
2257
3489
|
providers.push({
|
|
2258
|
-
provide:
|
|
3490
|
+
provide: import_nestjs_agent_core23.AGENT_STORE,
|
|
2259
3491
|
useFactory: /* @__PURE__ */ __name((o) => o.store, "useFactory"),
|
|
2260
3492
|
inject: [
|
|
2261
|
-
|
|
3493
|
+
import_nestjs_agent_core23.AGENT_OPTIONS
|
|
2262
3494
|
]
|
|
2263
3495
|
});
|
|
2264
3496
|
}
|
|
2265
3497
|
if (durable) {
|
|
2266
3498
|
providers.push({
|
|
2267
|
-
provide:
|
|
3499
|
+
provide: import_nestjs_agent_core23.AGENT_RUNNER,
|
|
2268
3500
|
useFactory: /* @__PURE__ */ __name((durableRunner) => {
|
|
2269
3501
|
if (durableRunner === void 0) {
|
|
2270
3502
|
throw new Error("AgentModule.forRoot({ durable: true }) requires importing AgentDurableModule from '@dudousxd/nestjs-agent/durable' (alongside a configured DurableModule). It was not found.");
|
|
@@ -2273,14 +3505,14 @@ function sharedProviders(durable, includeStore) {
|
|
|
2273
3505
|
}, "useFactory"),
|
|
2274
3506
|
inject: [
|
|
2275
3507
|
{
|
|
2276
|
-
token:
|
|
3508
|
+
token: import_nestjs_agent_core23.AGENT_DURABLE_RUNNER,
|
|
2277
3509
|
optional: true
|
|
2278
3510
|
}
|
|
2279
3511
|
]
|
|
2280
3512
|
});
|
|
2281
3513
|
} else {
|
|
2282
3514
|
providers.push({
|
|
2283
|
-
provide:
|
|
3515
|
+
provide: import_nestjs_agent_core23.AGENT_RUNNER,
|
|
2284
3516
|
useExisting: InlineAgentRunner
|
|
2285
3517
|
});
|
|
2286
3518
|
}
|
|
@@ -2289,23 +3521,25 @@ function sharedProviders(durable, includeStore) {
|
|
|
2289
3521
|
__name(sharedProviders, "sharedProviders");
|
|
2290
3522
|
function exportsFor(includeStore) {
|
|
2291
3523
|
return [
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
3524
|
+
import_nestjs_agent_core23.AGENT_OPTIONS,
|
|
3525
|
+
import_nestjs_agent_core23.AGENT_TOOL_REGISTRY,
|
|
3526
|
+
import_nestjs_agent_core23.AGENT_REGISTRY,
|
|
3527
|
+
import_nestjs_agent_core23.AGENT_SINK,
|
|
3528
|
+
import_nestjs_agent_core23.AGENT_ROLES_POLICY,
|
|
3529
|
+
import_nestjs_agent_core23.AGENT_ACTOR_RESOLVER,
|
|
3530
|
+
import_nestjs_agent_core23.AGENT_MODEL,
|
|
2299
3531
|
...includeStore ? [
|
|
2300
|
-
|
|
3532
|
+
import_nestjs_agent_core23.AGENT_STORE
|
|
2301
3533
|
] : [],
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
3534
|
+
import_nestjs_agent_core23.AGENT_QUOTA_STORE,
|
|
3535
|
+
import_nestjs_agent_core23.AGENT_PROMPT_CONTRIBUTORS,
|
|
3536
|
+
import_nestjs_agent_core23.AGENT_SKILLS,
|
|
3537
|
+
import_nestjs_agent_core23.AGENT_MEMORY,
|
|
3538
|
+
import_nestjs_agent_core23.AGENT_DEPS_FACTORY,
|
|
2305
3539
|
AgentDepsFactory2,
|
|
2306
3540
|
AgentService,
|
|
2307
3541
|
InlineAgentRunner,
|
|
2308
|
-
|
|
3542
|
+
import_nestjs_agent_core23.AGENT_APPROVAL_PORT
|
|
2309
3543
|
];
|
|
2310
3544
|
}
|
|
2311
3545
|
__name(exportsFor, "exportsFor");
|
|
@@ -2314,7 +3548,9 @@ var BASE_CONTROLLERS = [
|
|
|
2314
3548
|
ThreadsController,
|
|
2315
3549
|
ToolCallController,
|
|
2316
3550
|
QuotaController,
|
|
2317
|
-
AgentsController
|
|
3551
|
+
AgentsController,
|
|
3552
|
+
SkillsController,
|
|
3553
|
+
MemoriesController
|
|
2318
3554
|
];
|
|
2319
3555
|
var GUARDABLE_CONTROLLERS = [
|
|
2320
3556
|
...BASE_CONTROLLERS,
|
|
@@ -2346,7 +3582,7 @@ function guardProviders(guards) {
|
|
|
2346
3582
|
}
|
|
2347
3583
|
__name(guardProviders, "guardProviders");
|
|
2348
3584
|
function routerFor(path) {
|
|
2349
|
-
return
|
|
3585
|
+
return import_core4.RouterModule.register([
|
|
2350
3586
|
{
|
|
2351
3587
|
path,
|
|
2352
3588
|
module: AgentModule
|
|
@@ -2373,13 +3609,13 @@ var AgentModule = class _AgentModule {
|
|
|
2373
3609
|
module: _AgentModule,
|
|
2374
3610
|
global: true,
|
|
2375
3611
|
imports: [
|
|
2376
|
-
|
|
3612
|
+
import_core4.DiscoveryModule,
|
|
2377
3613
|
routerFor(path)
|
|
2378
3614
|
],
|
|
2379
3615
|
controllers: controllersForSurface(options.surface, options.attachments?.upload === true),
|
|
2380
3616
|
providers: [
|
|
2381
3617
|
{
|
|
2382
|
-
provide:
|
|
3618
|
+
provide: import_nestjs_agent_core23.AGENT_OPTIONS,
|
|
2383
3619
|
useValue: options
|
|
2384
3620
|
},
|
|
2385
3621
|
...sharedProviders(options.durable ?? false, includeStore),
|
|
@@ -2397,14 +3633,14 @@ var AgentModule = class _AgentModule {
|
|
|
2397
3633
|
module: _AgentModule,
|
|
2398
3634
|
global: true,
|
|
2399
3635
|
imports: [
|
|
2400
|
-
|
|
3636
|
+
import_core4.DiscoveryModule,
|
|
2401
3637
|
routerFor(path),
|
|
2402
3638
|
...options.imports ?? []
|
|
2403
3639
|
],
|
|
2404
3640
|
controllers: controllersForSurface(options.surface, options.attachmentsUpload === true),
|
|
2405
3641
|
providers: [
|
|
2406
3642
|
{
|
|
2407
|
-
provide:
|
|
3643
|
+
provide: import_nestjs_agent_core23.AGENT_OPTIONS,
|
|
2408
3644
|
// Stamp the STATIC wiring flags onto the factory result: `durable`/`dispatchedSteps`/
|
|
2409
3645
|
// `surface` are authoritative on the async config object (they decided the actual wiring
|
|
2410
3646
|
// above), and `AgentDurableModule` derives the effective dispatched-steps value from
|
|
@@ -2429,9 +3665,9 @@ var AgentModule = class _AgentModule {
|
|
|
2429
3665
|
};
|
|
2430
3666
|
}
|
|
2431
3667
|
};
|
|
2432
|
-
AgentModule =
|
|
2433
|
-
(0,
|
|
2434
|
-
(0,
|
|
3668
|
+
AgentModule = _ts_decorate20([
|
|
3669
|
+
(0, import_common20.Global)(),
|
|
3670
|
+
(0, import_common20.Module)({})
|
|
2435
3671
|
], AgentModule);
|
|
2436
3672
|
|
|
2437
3673
|
// src/durable/agent-durable.ts
|