@dudousxd/nestjs-agent 0.11.1 → 0.13.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-y2hvoQ6U.d.cts} +200 -16
- package/dist/{agent-deps.factory-D7GdhqdK.d.ts → agent-deps.factory-y2hvoQ6U.d.ts} +200 -16
- package/dist/durable/index.cjs +1735 -499
- package/dist/durable/index.cjs.map +1 -1
- package/dist/durable/index.d.cts +84 -38
- package/dist/durable/index.d.ts +84 -38
- package/dist/durable/index.js +1675 -439
- 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.js
CHANGED
|
@@ -2,10 +2,10 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
4
|
// src/durable/agent-run.workflow.ts
|
|
5
|
-
import { AGENT_DEPS_FACTORY, AGENT_STORE,
|
|
6
|
-
import { Workflow } from "@dudousxd/nestjs-durable";
|
|
5
|
+
import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY2, AGENT_STORE, RunCancelledError, agentFailureCode, isReplayIntegrityError, publishAgentRunFailed, runAgentLoop, settleAll, settleUnsettledDelegation } from "@dudousxd/nestjs-agent-core";
|
|
6
|
+
import { RUN_GATEWAY, Workflow } from "@dudousxd/nestjs-durable";
|
|
7
7
|
import { isWorkflowControlFlowSignal } from "@dudousxd/nestjs-durable-core";
|
|
8
|
-
import { Inject, Injectable, Optional } from "@nestjs/common";
|
|
8
|
+
import { Inject as Inject2, Injectable as Injectable2, Optional } from "@nestjs/common";
|
|
9
9
|
|
|
10
10
|
// src/agent-deps.ts
|
|
11
11
|
function utcDay(date = /* @__PURE__ */ new Date()) {
|
|
@@ -23,10 +23,10 @@ function childSinkWriter(writer) {
|
|
|
23
23
|
}
|
|
24
24
|
__name(childSinkWriter, "childSinkWriter");
|
|
25
25
|
|
|
26
|
-
// src/durable/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
// src/durable/agent-run.steps.ts
|
|
27
|
+
import { AGENT_DEPS_FACTORY, createFrameBuffer, invokeWithTransientRetry, publishAgentToolRetry, traceLlmTurn, traceToolExecution, withAskTool, withMemoryTool, withSkillTool, withToolTimeout } from "@dudousxd/nestjs-agent-core";
|
|
28
|
+
import { Step } from "@dudousxd/nestjs-durable";
|
|
29
|
+
import { Inject, Injectable } from "@nestjs/common";
|
|
30
30
|
function _ts_decorate(decorators, target, key, desc) {
|
|
31
31
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
32
32
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -44,34 +44,236 @@ function _ts_param(paramIndex, decorator) {
|
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
__name(_ts_param, "_ts_param");
|
|
47
|
+
var AgentRunSteps = class {
|
|
48
|
+
static {
|
|
49
|
+
__name(this, "AgentRunSteps");
|
|
50
|
+
}
|
|
51
|
+
factory;
|
|
52
|
+
constructor(factory) {
|
|
53
|
+
this.factory = factory;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Retryable: every side effect (persist/quota/stream markers) happens loop-side under
|
|
57
|
+
* `hooks.step`, so a durable retry only re-runs the model call and re-streams its tokens — never
|
|
58
|
+
* double-writes. NEVER call `writer.end()`/`fail()` here: the workflow owns the stream's lifecycle,
|
|
59
|
+
* across however many turns/retries it takes.
|
|
60
|
+
*/
|
|
61
|
+
async llm(input) {
|
|
62
|
+
const deps = this.factory.forAgent(input.agentName);
|
|
63
|
+
const tools = withMemoryTool({
|
|
64
|
+
tools: withSkillTool({
|
|
65
|
+
tools: withAskTool({
|
|
66
|
+
tools: await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList),
|
|
67
|
+
ask: deps.ask
|
|
68
|
+
}),
|
|
69
|
+
enabled: deps.skills !== void 0
|
|
70
|
+
}),
|
|
71
|
+
enabled: deps.memory?.provider.write !== void 0
|
|
72
|
+
});
|
|
73
|
+
const buffer = input.bufferOutput === true ? createFrameBuffer() : void 0;
|
|
74
|
+
let writer;
|
|
75
|
+
if (buffer !== void 0) {
|
|
76
|
+
writer = buffer.writer;
|
|
77
|
+
} else {
|
|
78
|
+
const opened = await deps.sink.open(input.sinkRunId);
|
|
79
|
+
writer = input.childSink ? childSinkWriter(opened) : opened;
|
|
80
|
+
}
|
|
81
|
+
const turn = await traceLlmTurn(input.runId, input.step, () => deps.model.runTurn({
|
|
82
|
+
system: input.system,
|
|
83
|
+
messages: input.messages,
|
|
84
|
+
tools,
|
|
85
|
+
sink: writer
|
|
86
|
+
}));
|
|
87
|
+
return buffer === void 0 ? turn : {
|
|
88
|
+
...turn,
|
|
89
|
+
bufferedFrames: buffer.frames()
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* NO DURABLE retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm`
|
|
94
|
+
* above). What it does retry, in place, is a CLASSIFIED-TRANSIENT error from the tool's own
|
|
95
|
+
* invocation (a DB deadlock, a lock-wait timeout — see `isTransientToolError`): the server rolled
|
|
96
|
+
* that work back, so re-invoking it is safe, and doing it here (inside this one step, never a new
|
|
97
|
+
* checkpoint) is exactly how the non-dispatched loop path handles it too. The timeout is applied
|
|
98
|
+
* HERE, handler-side, via `withToolTimeout` — never as a durable dispatch `timeoutMs`, which
|
|
99
|
+
* bounds engine liveness (retryable) rather than the tool's own business outcome — and per
|
|
100
|
+
* ATTEMPT, so a retried invocation gets its own fresh timeout window.
|
|
101
|
+
*/
|
|
102
|
+
async tool(input) {
|
|
103
|
+
const deps = this.factory.forAgent(input.ctx.agentName);
|
|
104
|
+
if (deps.registry.spec(input.toolName)?.kind === "action" && input.toolType !== "action") {
|
|
105
|
+
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`);
|
|
106
|
+
}
|
|
107
|
+
const ctx = {
|
|
108
|
+
...input.ctx
|
|
109
|
+
};
|
|
110
|
+
const localClassify = deps.toolTransientRetry !== false ? deps.toolTransientRetry?.classify : void 0;
|
|
111
|
+
const transientRetry = input.transientRetry === false ? false : {
|
|
112
|
+
attempts: input.transientRetry.attempts,
|
|
113
|
+
backoffMs: input.transientRetry.backoffMs,
|
|
114
|
+
...localClassify !== void 0 ? {
|
|
115
|
+
classify: localClassify
|
|
116
|
+
} : {}
|
|
117
|
+
};
|
|
118
|
+
return traceToolExecution(input.ctx.runId, {
|
|
119
|
+
toolCallId: input.toolCallId,
|
|
120
|
+
toolName: input.toolName,
|
|
121
|
+
toolType: input.toolType
|
|
122
|
+
}, () => invokeWithTransientRetry(() => {
|
|
123
|
+
const invocation = deps.registry.invoke(input.toolName, input.input, ctx, deps.rolesPolicy);
|
|
124
|
+
return input.timeoutMs !== void 0 ? withToolTimeout(invocation, input.timeoutMs, input.toolName) : invocation;
|
|
125
|
+
}, transientRetry, {
|
|
126
|
+
onRetry: /* @__PURE__ */ __name((attempt, error) => {
|
|
127
|
+
publishAgentToolRetry({
|
|
128
|
+
toolName: input.toolName,
|
|
129
|
+
toolCallId: input.toolCallId,
|
|
130
|
+
attempt,
|
|
131
|
+
message: error instanceof Error ? error.message : String(error)
|
|
132
|
+
});
|
|
133
|
+
}, "onRetry")
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
_ts_decorate([
|
|
138
|
+
Step({
|
|
139
|
+
retries: 3
|
|
140
|
+
}),
|
|
141
|
+
_ts_metadata("design:type", Function),
|
|
142
|
+
_ts_metadata("design:paramtypes", [
|
|
143
|
+
typeof DispatchedLlmInput === "undefined" ? Object : DispatchedLlmInput
|
|
144
|
+
]),
|
|
145
|
+
_ts_metadata("design:returntype", Promise)
|
|
146
|
+
], AgentRunSteps.prototype, "llm", null);
|
|
147
|
+
_ts_decorate([
|
|
148
|
+
Step(),
|
|
149
|
+
_ts_metadata("design:type", Function),
|
|
150
|
+
_ts_metadata("design:paramtypes", [
|
|
151
|
+
typeof DispatchedToolInput === "undefined" ? Object : DispatchedToolInput
|
|
152
|
+
]),
|
|
153
|
+
_ts_metadata("design:returntype", Promise)
|
|
154
|
+
], AgentRunSteps.prototype, "tool", null);
|
|
155
|
+
AgentRunSteps = _ts_decorate([
|
|
156
|
+
Injectable(),
|
|
157
|
+
_ts_param(0, Inject(AGENT_DEPS_FACTORY)),
|
|
158
|
+
_ts_metadata("design:type", Function),
|
|
159
|
+
_ts_metadata("design:paramtypes", [
|
|
160
|
+
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
|
|
161
|
+
])
|
|
162
|
+
], AgentRunSteps);
|
|
163
|
+
|
|
164
|
+
// src/durable/dispatched-steps.token.ts
|
|
165
|
+
var AGENT_DISPATCHED_STEPS = Symbol.for("@dudousxd/nestjs-agent:dispatched-steps");
|
|
166
|
+
|
|
167
|
+
// src/durable/agent-run.workflow.ts
|
|
168
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
169
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
170
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
171
|
+
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;
|
|
172
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
173
|
+
}
|
|
174
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
175
|
+
function _ts_metadata2(k, v) {
|
|
176
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
177
|
+
}
|
|
178
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
179
|
+
function _ts_param2(paramIndex, decorator) {
|
|
180
|
+
return function(target, key) {
|
|
181
|
+
decorator(target, key, paramIndex);
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
__name(_ts_param2, "_ts_param");
|
|
47
185
|
var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
48
186
|
static {
|
|
49
187
|
__name(this, "AgentRunWorkflow");
|
|
50
188
|
}
|
|
51
189
|
factory;
|
|
52
190
|
store;
|
|
53
|
-
steps;
|
|
54
191
|
dispatchedSteps;
|
|
55
|
-
|
|
192
|
+
runs;
|
|
193
|
+
constructor(factory, store, dispatchedSteps, runs) {
|
|
56
194
|
this.factory = factory;
|
|
57
195
|
this.store = store;
|
|
58
|
-
this.steps = steps;
|
|
59
196
|
this.dispatchedSteps = dispatchedSteps;
|
|
197
|
+
this.runs = runs;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Has someone asked this run to stop? Read from the runtime's own run status, which is where
|
|
201
|
+
* `DurableAgentRunner.cancel` puts it — `cancelling` while a compensating cancel is in flight,
|
|
202
|
+
* `cancelled` once it has settled.
|
|
203
|
+
*
|
|
204
|
+
* Costs a run read at each of the loop's observation points (two per step). That is a row the
|
|
205
|
+
* control plane already has, against a turn that is otherwise making model calls, and it buys the
|
|
206
|
+
* property that matters: the answer comes from a place BOTH the canceller and every pod that might
|
|
207
|
+
* replay this run can see.
|
|
208
|
+
*
|
|
209
|
+
* Failing to ask is not a cancel. A tenant with no gateway wired, or an operator briefly
|
|
210
|
+
* unreachable, answers "no" and the run carries on — the alternative is failing healthy runs
|
|
211
|
+
* because a status read timed out. The loop journals that answer like any other, so two processes
|
|
212
|
+
* can never disagree about what was seen here.
|
|
213
|
+
*/
|
|
214
|
+
async isCancelled(runId) {
|
|
215
|
+
try {
|
|
216
|
+
const status = (await this.runs?.getRunDetail(runId))?.run.status;
|
|
217
|
+
return status === "cancelled" || status === "cancelling";
|
|
218
|
+
} catch {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Settle the delegation a DETACHED run was started for, when that run ends without an answer.
|
|
224
|
+
*
|
|
225
|
+
* The loop delivers its own success (`deliver:detached`) but cannot catch its own crash, and the
|
|
226
|
+
* runtime settles the run row without knowing anything delegated it. Left alone, the card in the
|
|
227
|
+
* calling conversation says "started" for ever — the one state a reader can neither wait on nor
|
|
228
|
+
* act on. A no-op for every other run: only a detached one carries a delivery address.
|
|
229
|
+
*/
|
|
230
|
+
async settleDetachedParent(ctx, input, outcome) {
|
|
231
|
+
const delivery = input.deliverTo;
|
|
232
|
+
if (delivery === void 0) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
await ctx.localStep("deliver:detached:unsettled", () => settleUnsettledDelegation({
|
|
236
|
+
store: this.store,
|
|
237
|
+
delivery,
|
|
238
|
+
agent: input.agentName ?? "default",
|
|
239
|
+
runId: ctx.runId,
|
|
240
|
+
status: outcome.status,
|
|
241
|
+
...outcome.error !== void 0 ? {
|
|
242
|
+
error: outcome.error
|
|
243
|
+
} : {}
|
|
244
|
+
}));
|
|
60
245
|
}
|
|
61
246
|
async run(ctx, input) {
|
|
62
247
|
const day = input.day ?? utcDay();
|
|
63
248
|
const deps = this.factory.forAgent(input.agentName);
|
|
64
|
-
const dispatchSteps = this.dispatchedSteps
|
|
65
|
-
if (input.sinkRunId !== void 0) {
|
|
249
|
+
const dispatchSteps = this.dispatchedSteps && await ctx.patched("agent:dispatched-steps");
|
|
250
|
+
if (input.sinkRunId !== void 0 || input.deliverTo !== void 0) {
|
|
66
251
|
await ctx.localStep("activate", () => this.store.setActiveStream(input.threadId, ctx.runId));
|
|
67
252
|
}
|
|
68
253
|
const sinkRunId = input.sinkRunId ?? ctx.runId;
|
|
254
|
+
const chainBelow = [
|
|
255
|
+
...input.delegationPath ?? [],
|
|
256
|
+
...input.agentName !== void 0 ? [
|
|
257
|
+
input.agentName
|
|
258
|
+
] : []
|
|
259
|
+
];
|
|
69
260
|
const hooks = {
|
|
70
261
|
runId: ctx.runId,
|
|
71
262
|
// A child forwards into the top-level sink but must not end/fail it (the top-level run owns it).
|
|
72
263
|
openSink: /* @__PURE__ */ __name(async () => input.sinkRunId !== void 0 ? childSinkWriter(await deps.sink.open(sinkRunId)) : deps.sink.open(ctx.runId), "openSink"),
|
|
73
264
|
awaitApproval: /* @__PURE__ */ __name((call) => ctx.waitForSignal(`tool:${ctx.runId}:${call.id}`), "awaitApproval"),
|
|
265
|
+
// The same wait, on the same signal key, carrying a typed answer instead of a yes/no — so a
|
|
266
|
+
// question set and an approval reach a parked run through one path, and the HTTP surface that
|
|
267
|
+
// settles either one is the same `POST /agent/tool-call/*` family.
|
|
268
|
+
awaitAnswers: /* @__PURE__ */ __name((request) => ctx.waitForSignal(`tool:${ctx.runId}:${request.id}`), "awaitAnswers"),
|
|
74
269
|
step: /* @__PURE__ */ __name((name, fn) => ctx.localStep(name, fn), "step"),
|
|
270
|
+
// Both durable step primitives take their checkpoint position on the CALL, before their first
|
|
271
|
+
// await, so launching a batch in one tick — what `settleAll` does — fixes the block of
|
|
272
|
+
// positions in call order however the tools then settle. `ctx.patched` keeps a run that
|
|
273
|
+
// recorded the one-call-at-a-time shape replaying against that shape.
|
|
274
|
+
parallel: settleAll,
|
|
275
|
+
cancelled: /* @__PURE__ */ __name(() => this.isCancelled(ctx.runId), "cancelled"),
|
|
276
|
+
patched: /* @__PURE__ */ __name((id) => ctx.patched(id), "patched"),
|
|
75
277
|
// Dispatched-step suspends must escape the loop's tool catch — control flow, not a tool
|
|
76
278
|
// failure. Marker-based predicate, NOT instanceof: the signal's CLASS differs by runtime
|
|
77
279
|
// (engine in-process throws durable-core's WorkflowSuspended/ContinueAsNew; the BullMQ thin
|
|
@@ -92,15 +294,54 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
92
294
|
userText: task,
|
|
93
295
|
day,
|
|
94
296
|
delegationDepth: (input.delegationDepth ?? 0) + 1,
|
|
297
|
+
delegationPath: chainBelow,
|
|
298
|
+
parentRunId: ctx.runId,
|
|
95
299
|
sinkRunId
|
|
96
300
|
});
|
|
97
301
|
}, "runAgent"),
|
|
302
|
+
// The same delegation, not awaited: `ctx.startChild` records a `spawn:<childRunId>` at this
|
|
303
|
+
// position and returns, so THIS turn ends while the child is still working. Two things the
|
|
304
|
+
// awaited form does are deliberately left off:
|
|
305
|
+
// - no `sinkRunId`. A detached run owns its own stream. Forwarding it into the turn that
|
|
306
|
+
// started it would write tokens, and a pending action-tool frame, into a stream whose
|
|
307
|
+
// reader has already seen `done` — and would put the child's approval card in whatever
|
|
308
|
+
// turn happened to be open. Its approval goes to the pending-approvals surface instead,
|
|
309
|
+
// which it reaches for free: the call is persisted `pending_approval` against the child's
|
|
310
|
+
// OWN runId, and that is what `runForToolCall` answers with.
|
|
311
|
+
// - `deliverTo` instead. The parent's tool result is a receipt, so the answer needs an
|
|
312
|
+
// address of its own, and by the time it exists nobody is holding one.
|
|
313
|
+
startAgent: /* @__PURE__ */ __name(async ({ agentName, task, toolCallId: toolCallId2 }) => {
|
|
314
|
+
const subThreadId = await ctx.localStep(`subthread:${agentName}`, async () => {
|
|
315
|
+
const thread = await this.store.createThread({
|
|
316
|
+
actor: input.actor,
|
|
317
|
+
transient: true
|
|
318
|
+
});
|
|
319
|
+
return thread.id;
|
|
320
|
+
});
|
|
321
|
+
const childRunId = await ctx.startChild(_AgentRunWorkflow, {
|
|
322
|
+
agentName,
|
|
323
|
+
threadId: subThreadId,
|
|
324
|
+
actor: input.actor,
|
|
325
|
+
userText: task,
|
|
326
|
+
day,
|
|
327
|
+
delegationDepth: (input.delegationDepth ?? 0) + 1,
|
|
328
|
+
delegationPath: chainBelow,
|
|
329
|
+
parentRunId: ctx.runId,
|
|
330
|
+
deliverTo: {
|
|
331
|
+
threadId: input.threadId,
|
|
332
|
+
toolCallId: toolCallId2
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
return {
|
|
336
|
+
runId: childRunId
|
|
337
|
+
};
|
|
338
|
+
}, "startAgent"),
|
|
98
339
|
// Routes the two long steps through AgentRunSteps as engine-dispatched `ctx.step`s instead of
|
|
99
340
|
// `ctx.localStep`s, so a turn isn't pinned to this workflow worker for the model call or a tool
|
|
100
341
|
// execution. `sinkRunId`/`childSink` are sink routing this workflow already resolved above —
|
|
101
342
|
// core's dispatchLlm signature stays sink-topology-agnostic, so we add them here, not in core.
|
|
102
|
-
...dispatchSteps
|
|
103
|
-
dispatchLlm: /* @__PURE__ */ __name((index, envelope) => ctx.step(
|
|
343
|
+
...dispatchSteps ? {
|
|
344
|
+
dispatchLlm: /* @__PURE__ */ __name((index, envelope) => ctx.step(AgentRunSteps.prototype.llm, {
|
|
104
345
|
...envelope,
|
|
105
346
|
runId: ctx.runId,
|
|
106
347
|
step: index,
|
|
@@ -112,7 +353,7 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
112
353
|
// ('agent'-kind delegations branch to runAgent earlier in the loop), so anything that
|
|
113
354
|
// isn't 'action' is defensively 'read' — the same posture core takes for an
|
|
114
355
|
// unresolvable `kind`.
|
|
115
|
-
dispatchTool: /* @__PURE__ */ __name((call, envelope) => ctx.step(
|
|
356
|
+
dispatchTool: /* @__PURE__ */ __name((call, envelope) => ctx.step(AgentRunSteps.prototype.tool, {
|
|
116
357
|
...envelope,
|
|
117
358
|
toolCallId: call.id,
|
|
118
359
|
toolType: call.kind === "action" ? "action" : "read"
|
|
@@ -130,8 +371,27 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
130
371
|
if (isWorkflowControlFlowSignal(error)) {
|
|
131
372
|
throw error;
|
|
132
373
|
}
|
|
374
|
+
if (error instanceof RunCancelledError) {
|
|
375
|
+
await ctx.localStep("deactivate", () => this.store.setActiveStream(input.threadId, null));
|
|
376
|
+
await this.settleDetachedParent(ctx, input, {
|
|
377
|
+
status: "cancelled"
|
|
378
|
+
});
|
|
379
|
+
throw error;
|
|
380
|
+
}
|
|
381
|
+
if (isReplayIntegrityError(error)) {
|
|
382
|
+
const failure = {
|
|
383
|
+
code: "run_failed",
|
|
384
|
+
message: error.message
|
|
385
|
+
};
|
|
386
|
+
publishAgentRunFailed({
|
|
387
|
+
runId: ctx.runId,
|
|
388
|
+
...failure
|
|
389
|
+
});
|
|
390
|
+
await (await hooks.openSink()).fail(failure);
|
|
391
|
+
throw error;
|
|
392
|
+
}
|
|
133
393
|
const message = error instanceof Error ? error.message : String(error);
|
|
134
|
-
const code = error
|
|
394
|
+
const code = agentFailureCode(error);
|
|
135
395
|
publishAgentRunFailed({
|
|
136
396
|
runId: ctx.runId,
|
|
137
397
|
code,
|
|
@@ -144,6 +404,10 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
144
404
|
errorMessage: message
|
|
145
405
|
}) ?? Promise.resolve());
|
|
146
406
|
await ctx.localStep("deactivate", () => this.store.setActiveStream(input.threadId, null));
|
|
407
|
+
await this.settleDetachedParent(ctx, input, {
|
|
408
|
+
status: "failed",
|
|
409
|
+
error: message
|
|
410
|
+
});
|
|
147
411
|
const writer = await hooks.openSink();
|
|
148
412
|
await writer.fail({
|
|
149
413
|
code,
|
|
@@ -153,146 +417,32 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
|
|
|
153
417
|
}
|
|
154
418
|
}
|
|
155
419
|
};
|
|
156
|
-
AgentRunWorkflow =
|
|
157
|
-
|
|
420
|
+
AgentRunWorkflow = _ts_decorate2([
|
|
421
|
+
Injectable2(),
|
|
158
422
|
Workflow({
|
|
159
423
|
name: "agent.run",
|
|
160
424
|
version: "1"
|
|
161
425
|
}),
|
|
162
|
-
_ts_param(0, Inject(AGENT_DEPS_FACTORY)),
|
|
163
|
-
_ts_param(1, Inject(AGENT_STORE)),
|
|
164
|
-
_ts_param(2, Optional()),
|
|
165
|
-
_ts_param(3, Inject(AGENT_DISPATCHED_STEPS)),
|
|
166
|
-
_ts_metadata("design:type", Function),
|
|
167
|
-
_ts_metadata("design:paramtypes", [
|
|
168
|
-
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
|
|
169
|
-
typeof AgentStore === "undefined" ? Object : AgentStore,
|
|
170
|
-
Object,
|
|
171
|
-
Boolean
|
|
172
|
-
])
|
|
173
|
-
], AgentRunWorkflow);
|
|
174
|
-
|
|
175
|
-
// src/durable/agent-run.steps.ts
|
|
176
|
-
import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY2, invokeWithTransientRetry, publishAgentToolRetry, traceLlmTurn, traceToolExecution, withToolTimeout } from "@dudousxd/nestjs-agent-core";
|
|
177
|
-
import { Step } from "@dudousxd/nestjs-durable";
|
|
178
|
-
import { Inject as Inject2, Injectable as Injectable2 } from "@nestjs/common";
|
|
179
|
-
function _ts_decorate2(decorators, target, key, desc) {
|
|
180
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
181
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
182
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
183
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
184
|
-
}
|
|
185
|
-
__name(_ts_decorate2, "_ts_decorate");
|
|
186
|
-
function _ts_metadata2(k, v) {
|
|
187
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
188
|
-
}
|
|
189
|
-
__name(_ts_metadata2, "_ts_metadata");
|
|
190
|
-
function _ts_param2(paramIndex, decorator) {
|
|
191
|
-
return function(target, key) {
|
|
192
|
-
decorator(target, key, paramIndex);
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
__name(_ts_param2, "_ts_param");
|
|
196
|
-
var AgentRunSteps = class {
|
|
197
|
-
static {
|
|
198
|
-
__name(this, "AgentRunSteps");
|
|
199
|
-
}
|
|
200
|
-
factory;
|
|
201
|
-
constructor(factory) {
|
|
202
|
-
this.factory = factory;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Retryable: every side effect (persist/quota/stream markers) happens loop-side under
|
|
206
|
-
* `hooks.step`, so a durable retry only re-runs the model call and re-streams its tokens — never
|
|
207
|
-
* double-writes. NEVER call `writer.end()`/`fail()` here: the workflow owns the stream's lifecycle,
|
|
208
|
-
* across however many turns/retries it takes.
|
|
209
|
-
*/
|
|
210
|
-
async llm(input) {
|
|
211
|
-
const deps = this.factory.forAgent(input.agentName);
|
|
212
|
-
const tools = await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList);
|
|
213
|
-
const opened = await deps.sink.open(input.sinkRunId);
|
|
214
|
-
const writer = input.childSink ? childSinkWriter(opened) : opened;
|
|
215
|
-
return traceLlmTurn(input.runId, input.step, () => deps.model.runTurn({
|
|
216
|
-
system: input.system,
|
|
217
|
-
messages: input.messages,
|
|
218
|
-
tools,
|
|
219
|
-
sink: writer
|
|
220
|
-
}));
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* NO DURABLE retries — a tool may not be idempotent (a bare `@Step()` carries none, unlike `llm`
|
|
224
|
-
* above). What it does retry, in place, is a CLASSIFIED-TRANSIENT error from the tool's own
|
|
225
|
-
* invocation (a DB deadlock, a lock-wait timeout — see `isTransientToolError`): the server rolled
|
|
226
|
-
* that work back, so re-invoking it is safe, and doing it here (inside this one step, never a new
|
|
227
|
-
* checkpoint) is exactly how the non-dispatched loop path handles it too. The timeout is applied
|
|
228
|
-
* HERE, handler-side, via `withToolTimeout` — never as a durable dispatch `timeoutMs`, which
|
|
229
|
-
* bounds engine liveness (retryable) rather than the tool's own business outcome — and per
|
|
230
|
-
* ATTEMPT, so a retried invocation gets its own fresh timeout window.
|
|
231
|
-
*/
|
|
232
|
-
async tool(input) {
|
|
233
|
-
const deps = this.factory.forAgent(input.ctx.agentName);
|
|
234
|
-
const ctx = {
|
|
235
|
-
...input.ctx
|
|
236
|
-
};
|
|
237
|
-
const localClassify = deps.toolTransientRetry !== false ? deps.toolTransientRetry?.classify : void 0;
|
|
238
|
-
const transientRetry = input.transientRetry === false ? false : {
|
|
239
|
-
attempts: input.transientRetry.attempts,
|
|
240
|
-
backoffMs: input.transientRetry.backoffMs,
|
|
241
|
-
...localClassify !== void 0 ? {
|
|
242
|
-
classify: localClassify
|
|
243
|
-
} : {}
|
|
244
|
-
};
|
|
245
|
-
return traceToolExecution(input.ctx.runId, {
|
|
246
|
-
toolCallId: input.toolCallId,
|
|
247
|
-
toolName: input.toolName,
|
|
248
|
-
toolType: input.toolType
|
|
249
|
-
}, () => invokeWithTransientRetry(() => {
|
|
250
|
-
const invocation = deps.registry.invoke(input.toolName, input.input, ctx, deps.rolesPolicy);
|
|
251
|
-
return input.timeoutMs !== void 0 ? withToolTimeout(invocation, input.timeoutMs, input.toolName) : invocation;
|
|
252
|
-
}, transientRetry, {
|
|
253
|
-
onRetry: /* @__PURE__ */ __name((attempt, error) => {
|
|
254
|
-
publishAgentToolRetry({
|
|
255
|
-
toolName: input.toolName,
|
|
256
|
-
toolCallId: input.toolCallId,
|
|
257
|
-
attempt,
|
|
258
|
-
message: error instanceof Error ? error.message : String(error)
|
|
259
|
-
});
|
|
260
|
-
}, "onRetry")
|
|
261
|
-
}));
|
|
262
|
-
}
|
|
263
|
-
};
|
|
264
|
-
_ts_decorate2([
|
|
265
|
-
Step({
|
|
266
|
-
retries: 3
|
|
267
|
-
}),
|
|
268
|
-
_ts_metadata2("design:type", Function),
|
|
269
|
-
_ts_metadata2("design:paramtypes", [
|
|
270
|
-
typeof DispatchedLlmInput === "undefined" ? Object : DispatchedLlmInput
|
|
271
|
-
]),
|
|
272
|
-
_ts_metadata2("design:returntype", Promise)
|
|
273
|
-
], AgentRunSteps.prototype, "llm", null);
|
|
274
|
-
_ts_decorate2([
|
|
275
|
-
Step(),
|
|
276
|
-
_ts_metadata2("design:type", Function),
|
|
277
|
-
_ts_metadata2("design:paramtypes", [
|
|
278
|
-
typeof DispatchedToolInput === "undefined" ? Object : DispatchedToolInput
|
|
279
|
-
]),
|
|
280
|
-
_ts_metadata2("design:returntype", Promise)
|
|
281
|
-
], AgentRunSteps.prototype, "tool", null);
|
|
282
|
-
AgentRunSteps = _ts_decorate2([
|
|
283
|
-
Injectable2(),
|
|
284
426
|
_ts_param2(0, Inject2(AGENT_DEPS_FACTORY2)),
|
|
427
|
+
_ts_param2(1, Inject2(AGENT_STORE)),
|
|
428
|
+
_ts_param2(2, Inject2(AGENT_DISPATCHED_STEPS)),
|
|
429
|
+
_ts_param2(3, Optional()),
|
|
430
|
+
_ts_param2(3, Inject2(RUN_GATEWAY)),
|
|
285
431
|
_ts_metadata2("design:type", Function),
|
|
286
432
|
_ts_metadata2("design:paramtypes", [
|
|
287
|
-
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
|
|
433
|
+
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
|
|
434
|
+
typeof AgentStore === "undefined" ? Object : AgentStore,
|
|
435
|
+
Boolean,
|
|
436
|
+
typeof RunGateway === "undefined" ? Object : RunGateway
|
|
288
437
|
])
|
|
289
|
-
],
|
|
438
|
+
], AgentRunWorkflow);
|
|
290
439
|
|
|
291
440
|
// src/durable/durable-agent-runner.ts
|
|
292
441
|
import { randomUUID } from "node:crypto";
|
|
293
|
-
import {
|
|
442
|
+
import { AGENT_SINK, AGENT_STORE as AGENT_STORE2, encodeStreamEvent } from "@dudousxd/nestjs-agent-core";
|
|
443
|
+
import { RUN_GATEWAY as RUN_GATEWAY2, WorkflowService } from "@dudousxd/nestjs-durable";
|
|
294
444
|
import { isWorkflowControlFlowSignal as isWorkflowControlFlowSignal2 } from "@dudousxd/nestjs-durable-core";
|
|
295
|
-
import { Injectable as Injectable3 } from "@nestjs/common";
|
|
445
|
+
import { Inject as Inject3, Injectable as Injectable3, Logger } from "@nestjs/common";
|
|
296
446
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
297
447
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
298
448
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -304,13 +454,26 @@ function _ts_metadata3(k, v) {
|
|
|
304
454
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
305
455
|
}
|
|
306
456
|
__name(_ts_metadata3, "_ts_metadata");
|
|
307
|
-
|
|
457
|
+
function _ts_param3(paramIndex, decorator) {
|
|
458
|
+
return function(target, key) {
|
|
459
|
+
decorator(target, key, paramIndex);
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
__name(_ts_param3, "_ts_param");
|
|
463
|
+
var DurableAgentRunner = class _DurableAgentRunner {
|
|
308
464
|
static {
|
|
309
465
|
__name(this, "DurableAgentRunner");
|
|
310
466
|
}
|
|
311
467
|
workflows;
|
|
312
|
-
|
|
468
|
+
runs;
|
|
469
|
+
store;
|
|
470
|
+
sink;
|
|
471
|
+
logger = new Logger(_DurableAgentRunner.name);
|
|
472
|
+
constructor(workflows, runs, store, sink) {
|
|
313
473
|
this.workflows = workflows;
|
|
474
|
+
this.runs = runs;
|
|
475
|
+
this.store = store;
|
|
476
|
+
this.sink = sink;
|
|
314
477
|
}
|
|
315
478
|
async start(input) {
|
|
316
479
|
const stamped = {
|
|
@@ -329,24 +492,59 @@ var DurableAgentRunner = class {
|
|
|
329
492
|
runId
|
|
330
493
|
};
|
|
331
494
|
}
|
|
332
|
-
async signal(runId,
|
|
333
|
-
await this.workflows.signal(`tool:${runId}:${
|
|
495
|
+
async signal(runId, toolCallId2, reply) {
|
|
496
|
+
await this.workflows.signal(`tool:${runId}:${toolCallId2}`, reply);
|
|
334
497
|
}
|
|
335
|
-
|
|
336
|
-
|
|
498
|
+
/**
|
|
499
|
+
* Stop a run, and settle what the durable runtime knows nothing about.
|
|
500
|
+
*
|
|
501
|
+
* `compensate: true` is the form that gives the BODY a chance: it moves the run to `cancelling`
|
|
502
|
+
* (which is what the workflow's own cancel observation reads) and then re-drives it, so a turn
|
|
503
|
+
* running in-process unwinds at its next safe point instead of finishing. It also guarantees the
|
|
504
|
+
* outcome for the turn that CANNOT observe anything — one parked on `waitForSignal`, suspended
|
|
505
|
+
* inside a position its journal already holds — because that re-drive re-suspends and the runtime
|
|
506
|
+
* settles the run `cancelled` regardless. The cascade to child runs comes with it.
|
|
507
|
+
*
|
|
508
|
+
* Neither of those settles the agent's own state, so this does: the run row gets its own terminal,
|
|
509
|
+
* and the subscriber gets a `cancelled` frame followed by a normal end. Both are keyed by runId
|
|
510
|
+
* alone, which is why they belong here rather than in the body — the body is the only place that
|
|
511
|
+
* knows which THREAD was streaming, so releasing that stays there (see `AgentRunWorkflow`).
|
|
512
|
+
*
|
|
513
|
+
* A tool already executing is not interrupted, here or anywhere: see `haltIfCancelled` in core.
|
|
514
|
+
*/
|
|
515
|
+
async cancel(runId) {
|
|
516
|
+
this.logger.log(`cancelling agent run ${runId}`);
|
|
517
|
+
await this.runs.cancel(runId, {
|
|
518
|
+
compensate: true
|
|
519
|
+
});
|
|
520
|
+
const writer = await this.sink.open(runId);
|
|
521
|
+
await writer.write(encodeStreamEvent({
|
|
522
|
+
kind: "cancelled"
|
|
523
|
+
}));
|
|
524
|
+
await writer.end();
|
|
525
|
+
await this.store.recordRunEnd?.({
|
|
526
|
+
runId,
|
|
527
|
+
status: "cancelled"
|
|
528
|
+
});
|
|
337
529
|
}
|
|
338
530
|
};
|
|
339
531
|
DurableAgentRunner = _ts_decorate3([
|
|
340
532
|
Injectable3(),
|
|
533
|
+
_ts_param3(1, Inject3(RUN_GATEWAY2)),
|
|
534
|
+
_ts_param3(2, Inject3(AGENT_STORE2)),
|
|
535
|
+
_ts_param3(3, Inject3(AGENT_SINK)),
|
|
341
536
|
_ts_metadata3("design:type", Function),
|
|
342
537
|
_ts_metadata3("design:paramtypes", [
|
|
343
|
-
typeof WorkflowService === "undefined" ? Object : WorkflowService
|
|
538
|
+
typeof WorkflowService === "undefined" ? Object : WorkflowService,
|
|
539
|
+
typeof RunGateway === "undefined" ? Object : RunGateway,
|
|
540
|
+
typeof AgentStore === "undefined" ? Object : AgentStore,
|
|
541
|
+
typeof TokenStreamSink === "undefined" ? Object : TokenStreamSink
|
|
344
542
|
])
|
|
345
543
|
], DurableAgentRunner);
|
|
346
544
|
|
|
347
545
|
// src/durable/agent-durable.module.ts
|
|
348
|
-
import { AGENT_DURABLE_RUNNER, AGENT_OPTIONS, AGENT_SINK } from "@dudousxd/nestjs-agent-core";
|
|
349
|
-
import { Global, Logger, Module } from "@nestjs/common";
|
|
546
|
+
import { AGENT_DURABLE_RUNNER, AGENT_OPTIONS, AGENT_SINK as AGENT_SINK2 } from "@dudousxd/nestjs-agent-core";
|
|
547
|
+
import { Global, Logger as Logger2, Module } from "@nestjs/common";
|
|
350
548
|
|
|
351
549
|
// src/in-process-sink.ts
|
|
352
550
|
import { AgentStreamError } from "@dudousxd/nestjs-agent-core";
|
|
@@ -424,7 +622,7 @@ function _ts_decorate4(decorators, target, key, desc) {
|
|
|
424
622
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
425
623
|
}
|
|
426
624
|
__name(_ts_decorate4, "_ts_decorate");
|
|
427
|
-
var logger = new
|
|
625
|
+
var logger = new Logger2("AgentDurableModule");
|
|
428
626
|
function runnerProviders() {
|
|
429
627
|
return [
|
|
430
628
|
DurableAgentRunner,
|
|
@@ -435,15 +633,15 @@ function runnerProviders() {
|
|
|
435
633
|
{
|
|
436
634
|
provide: AGENT_DISPATCHED_STEPS,
|
|
437
635
|
useFactory: /* @__PURE__ */ __name((options, sink) => {
|
|
438
|
-
const enabled = options.durable === true && options.dispatchedSteps
|
|
636
|
+
const enabled = options.durable === true && options.dispatchedSteps === true;
|
|
439
637
|
if (enabled && sink instanceof InProcessTokenStreamSink) {
|
|
440
|
-
logger.warn("
|
|
638
|
+
logger.warn("dispatchedSteps: true with the default InProcessTokenStreamSink, which only buffers tokens in-process. A dispatched `llm` step served by a different worker cannot stream into this buffer. Wire a cross-process TokenStreamSink (e.g. a Redis pub/sub sink) via AgentModule.forRoot({ sink }) before running multi-pod, or drop dispatchedSteps to keep the turn in-process localSteps.");
|
|
441
639
|
}
|
|
442
640
|
return enabled;
|
|
443
641
|
}, "useFactory"),
|
|
444
642
|
inject: [
|
|
445
643
|
AGENT_OPTIONS,
|
|
446
|
-
|
|
644
|
+
AGENT_SINK2
|
|
447
645
|
]
|
|
448
646
|
}
|
|
449
647
|
];
|
|
@@ -511,14 +709,14 @@ AgentDurableModule = _ts_decorate4([
|
|
|
511
709
|
], AgentDurableModule);
|
|
512
710
|
|
|
513
711
|
// src/agent.module.ts
|
|
514
|
-
import { AGENT_ACTOR_RESOLVER as
|
|
712
|
+
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER8, AGENT_APPROVAL_PORT, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY6, AGENT_DURABLE_RUNNER as AGENT_DURABLE_RUNNER2, AGENT_MEMORY as AGENT_MEMORY3, AGENT_MODEL as AGENT_MODEL2, AGENT_OPTIONS as AGENT_OPTIONS5, AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS3, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE3, AGENT_REGISTRY as AGENT_REGISTRY5, AGENT_ROLES_POLICY as AGENT_ROLES_POLICY2, AGENT_RUNNER as AGENT_RUNNER2, AGENT_SINK as AGENT_SINK4, AGENT_SKILLS as AGENT_SKILLS3, AGENT_SKILL_SOURCES as AGENT_SKILL_SOURCES2, AGENT_STORE as AGENT_STORE6, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY3, AgentRegistry as AgentRegistry5, DefaultRolesPolicy, ToolRegistry as ToolRegistry3 } from "@dudousxd/nestjs-agent-core";
|
|
515
713
|
import { Global as Global2, Module as Module2 } from "@nestjs/common";
|
|
516
714
|
import { DiscoveryModule, RouterModule } from "@nestjs/core";
|
|
517
715
|
|
|
518
716
|
// src/agent-deps.factory.ts
|
|
519
|
-
import { AGENT_MODEL, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_ROLES_POLICY, AGENT_SINK as
|
|
717
|
+
import { AGENT_MEMORY, AGENT_MODEL, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_ROLES_POLICY, AGENT_SINK as AGENT_SINK3, AGENT_SKILLS, AGENT_STORE as AGENT_STORE3, AGENT_TOOL_REGISTRY, AgentRegistry as AgentRegistry2, ToolRegistry as ToolRegistry2, normalizeDelegation, summarizeWithModel, windowHistory } from "@dudousxd/nestjs-agent-core";
|
|
520
718
|
import { AGENT_OPTIONS as AGENT_OPTIONS2 } from "@dudousxd/nestjs-agent-core";
|
|
521
|
-
import { Inject as
|
|
719
|
+
import { Inject as Inject4, Injectable as Injectable4, Optional as Optional2 } from "@nestjs/common";
|
|
522
720
|
function _ts_decorate5(decorators, target, key, desc) {
|
|
523
721
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
524
722
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -530,14 +728,15 @@ function _ts_metadata4(k, v) {
|
|
|
530
728
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
531
729
|
}
|
|
532
730
|
__name(_ts_metadata4, "_ts_metadata");
|
|
533
|
-
function
|
|
731
|
+
function _ts_param4(paramIndex, decorator) {
|
|
534
732
|
return function(target, key) {
|
|
535
733
|
decorator(target, key, paramIndex);
|
|
536
734
|
};
|
|
537
735
|
}
|
|
538
|
-
__name(
|
|
539
|
-
function delegateToolName(
|
|
540
|
-
|
|
736
|
+
__name(_ts_param4, "_ts_param");
|
|
737
|
+
function delegateToolName(args) {
|
|
738
|
+
const slug = args.target.replace(/[^a-zA-Z0-9]+/g, "_");
|
|
739
|
+
return args.detached === true ? `start_${slug}` : `ask_${slug}`;
|
|
541
740
|
}
|
|
542
741
|
__name(delegateToolName, "delegateToolName");
|
|
543
742
|
var AgentDepsFactory2 = class {
|
|
@@ -554,7 +753,9 @@ var AgentDepsFactory2 = class {
|
|
|
554
753
|
promptContributors;
|
|
555
754
|
quota;
|
|
556
755
|
pricingStore;
|
|
557
|
-
|
|
756
|
+
skills;
|
|
757
|
+
memory;
|
|
758
|
+
constructor(options, model, store, sink, rolesPolicy, registry, agents, promptContributors, quota, pricingStore, skills, memory) {
|
|
558
759
|
this.options = options;
|
|
559
760
|
this.model = model;
|
|
560
761
|
this.store = store;
|
|
@@ -565,6 +766,16 @@ var AgentDepsFactory2 = class {
|
|
|
565
766
|
this.promptContributors = promptContributors;
|
|
566
767
|
this.quota = quota;
|
|
567
768
|
this.pricingStore = pricingStore;
|
|
769
|
+
this.skills = skills;
|
|
770
|
+
this.memory = memory;
|
|
771
|
+
}
|
|
772
|
+
/** The turn's memory seam, shared with the read-back endpoint. Undefined → memory is not configured. */
|
|
773
|
+
memoryConfig() {
|
|
774
|
+
return this.memory;
|
|
775
|
+
}
|
|
776
|
+
/** The turn's skills seam, shared with the listing endpoint. Undefined → skills are not configured. */
|
|
777
|
+
skillsConfig() {
|
|
778
|
+
return this.skills;
|
|
568
779
|
}
|
|
569
780
|
/**
|
|
570
781
|
* The agent a turn uses when the caller names none: the explicit `defaultAgent` option, else the
|
|
@@ -581,7 +792,13 @@ var AgentDepsFactory2 = class {
|
|
|
581
792
|
if (definition === void 0) {
|
|
582
793
|
return void 0;
|
|
583
794
|
}
|
|
584
|
-
const delegated = (definition.delegatesTo ?? []).map(
|
|
795
|
+
const delegated = (definition.delegatesTo ?? []).map((edge) => {
|
|
796
|
+
const { agent, detached } = normalizeDelegation(edge);
|
|
797
|
+
return delegateToolName({
|
|
798
|
+
target: agent,
|
|
799
|
+
detached
|
|
800
|
+
});
|
|
801
|
+
});
|
|
585
802
|
if (definition.tools === void 0 && delegated.length === 0) {
|
|
586
803
|
return void 0;
|
|
587
804
|
}
|
|
@@ -596,6 +813,8 @@ var AgentDepsFactory2 = class {
|
|
|
596
813
|
const toolAllowList = this.effectiveTools(definition);
|
|
597
814
|
const followUpsCount = this.followUpsCount();
|
|
598
815
|
const retrieval = this.options.retrieval;
|
|
816
|
+
const historyPolicy = this.historyPolicy(definition);
|
|
817
|
+
const ask = definition?.ask ?? this.options.ask;
|
|
599
818
|
return {
|
|
600
819
|
model: this.model,
|
|
601
820
|
store: this.store,
|
|
@@ -605,6 +824,12 @@ var AgentDepsFactory2 = class {
|
|
|
605
824
|
promptContributors: this.promptContributors,
|
|
606
825
|
systemPrompt: definition?.systemPrompt ?? "You are a helpful assistant.",
|
|
607
826
|
maxSteps: definition?.maxSteps ?? 8,
|
|
827
|
+
...definition?.maxDelegationDepth !== void 0 ? {
|
|
828
|
+
maxDelegationDepth: definition.maxDelegationDepth
|
|
829
|
+
} : {},
|
|
830
|
+
...definition?.maxAgentAppearances !== void 0 ? {
|
|
831
|
+
maxAgentAppearances: definition.maxAgentAppearances
|
|
832
|
+
} : {},
|
|
608
833
|
...definition?.modelId !== void 0 ? {
|
|
609
834
|
modelId: definition.modelId
|
|
610
835
|
} : {},
|
|
@@ -614,6 +839,37 @@ var AgentDepsFactory2 = class {
|
|
|
614
839
|
...this.pricingStore !== void 0 ? {
|
|
615
840
|
pricingStore: this.pricingStore
|
|
616
841
|
} : {},
|
|
842
|
+
...historyPolicy !== void 0 ? {
|
|
843
|
+
historyPolicy
|
|
844
|
+
} : {},
|
|
845
|
+
inputProcessors: this.options.inputProcessors ?? [],
|
|
846
|
+
outputProcessors: this.options.outputProcessors ?? [],
|
|
847
|
+
...definition?.outputSchema !== void 0 ? {
|
|
848
|
+
outputSchema: definition.outputSchema
|
|
849
|
+
} : {},
|
|
850
|
+
...definition?.outputRepairAttempts !== void 0 ? {
|
|
851
|
+
outputRepairAttempts: definition.outputRepairAttempts
|
|
852
|
+
} : {},
|
|
853
|
+
...definition?.intake !== void 0 ? {
|
|
854
|
+
intake: definition.intake
|
|
855
|
+
} : {},
|
|
856
|
+
// Most specific wins, exactly as `historyPolicy` resolves: the agent's own `@Agent({ ask })`,
|
|
857
|
+
// else the module-wide flag. Both are module config, so every process of a deployment agrees.
|
|
858
|
+
...ask === true ? {
|
|
859
|
+
ask: true
|
|
860
|
+
} : {},
|
|
861
|
+
// Module-wide, never per-agent: a skill is a procedure, not a persona, and an agent that could
|
|
862
|
+
// opt out of one would make the catalog depend on which agent a turn happened to select — a
|
|
863
|
+
// per-turn fact the worker re-deriving the tool list cannot see.
|
|
864
|
+
...this.skills !== void 0 ? {
|
|
865
|
+
skills: this.skills
|
|
866
|
+
} : {},
|
|
867
|
+
// Module-wide, never per-agent, for the same reason skills are: which memories a turn carries
|
|
868
|
+
// cannot depend on which persona answered it, or the worker re-deriving a dispatched turn's
|
|
869
|
+
// tool list would disagree with the loop about whether `remember` was offered.
|
|
870
|
+
...this.memory !== void 0 ? {
|
|
871
|
+
memory: this.memory
|
|
872
|
+
} : {},
|
|
617
873
|
...toolAllowList !== void 0 ? {
|
|
618
874
|
toolAllowList
|
|
619
875
|
} : {},
|
|
@@ -634,6 +890,36 @@ var AgentDepsFactory2 = class {
|
|
|
634
890
|
} : {}
|
|
635
891
|
};
|
|
636
892
|
}
|
|
893
|
+
/**
|
|
894
|
+
* The ceiling on how much of a thread this agent's turns carry, most specific wins: the agent's
|
|
895
|
+
* own `@Agent({ history })`, else a module-wide custom `historyPolicy`, else the module-wide
|
|
896
|
+
* `history` window. Undefined → unbounded, the behaviour of a module that configures none.
|
|
897
|
+
*/
|
|
898
|
+
historyPolicy(definition) {
|
|
899
|
+
if (definition?.history !== void 0) {
|
|
900
|
+
return this.window(definition.history);
|
|
901
|
+
}
|
|
902
|
+
if (this.options.historyPolicy !== void 0) {
|
|
903
|
+
return this.options.historyPolicy;
|
|
904
|
+
}
|
|
905
|
+
return this.options.history === void 0 ? void 0 : this.window(this.options.history);
|
|
906
|
+
}
|
|
907
|
+
/** Build the built-in window policy from the declarative `{ maxMessages, maxTokens, summarize }`. */
|
|
908
|
+
window(config) {
|
|
909
|
+
return windowHistory({
|
|
910
|
+
...config.maxMessages !== void 0 ? {
|
|
911
|
+
maxMessages: config.maxMessages
|
|
912
|
+
} : {},
|
|
913
|
+
...config.maxTokens !== void 0 ? {
|
|
914
|
+
maxTokens: config.maxTokens
|
|
915
|
+
} : {},
|
|
916
|
+
// The shared module model, not a per-agent one: an agent's `modelId` is an accounting label,
|
|
917
|
+
// and only one provider is ever bound.
|
|
918
|
+
...config.summarize === true ? {
|
|
919
|
+
summarize: summarizeWithModel(this.model)
|
|
920
|
+
} : {}
|
|
921
|
+
});
|
|
922
|
+
}
|
|
637
923
|
/** Normalize the `followUps` option (`true` → 3, `{ count }` → count) to a number, or undefined. */
|
|
638
924
|
followUpsCount() {
|
|
639
925
|
const followUps = this.options.followUps;
|
|
@@ -648,17 +934,21 @@ var AgentDepsFactory2 = class {
|
|
|
648
934
|
};
|
|
649
935
|
AgentDepsFactory2 = _ts_decorate5([
|
|
650
936
|
Injectable4(),
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
937
|
+
_ts_param4(0, Inject4(AGENT_OPTIONS2)),
|
|
938
|
+
_ts_param4(1, Inject4(AGENT_MODEL)),
|
|
939
|
+
_ts_param4(2, Inject4(AGENT_STORE3)),
|
|
940
|
+
_ts_param4(3, Inject4(AGENT_SINK3)),
|
|
941
|
+
_ts_param4(4, Inject4(AGENT_ROLES_POLICY)),
|
|
942
|
+
_ts_param4(5, Inject4(AGENT_TOOL_REGISTRY)),
|
|
943
|
+
_ts_param4(6, Inject4(AGENT_REGISTRY)),
|
|
944
|
+
_ts_param4(7, Inject4(AGENT_PROMPT_CONTRIBUTORS)),
|
|
945
|
+
_ts_param4(8, Inject4(AGENT_QUOTA_STORE)),
|
|
946
|
+
_ts_param4(9, Optional2()),
|
|
947
|
+
_ts_param4(9, Inject4(AGENT_PRICING_STORE)),
|
|
948
|
+
_ts_param4(10, Optional2()),
|
|
949
|
+
_ts_param4(10, Inject4(AGENT_SKILLS)),
|
|
950
|
+
_ts_param4(11, Optional2()),
|
|
951
|
+
_ts_param4(11, Inject4(AGENT_MEMORY)),
|
|
662
952
|
_ts_metadata4("design:type", Function),
|
|
663
953
|
_ts_metadata4("design:paramtypes", [
|
|
664
954
|
typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
|
|
@@ -670,13 +960,15 @@ AgentDepsFactory2 = _ts_decorate5([
|
|
|
670
960
|
typeof AgentRegistry2 === "undefined" ? Object : AgentRegistry2,
|
|
671
961
|
Array,
|
|
672
962
|
Object,
|
|
963
|
+
Object,
|
|
964
|
+
Object,
|
|
673
965
|
Object
|
|
674
966
|
])
|
|
675
967
|
], AgentDepsFactory2);
|
|
676
968
|
|
|
677
969
|
// src/agent.service.ts
|
|
678
|
-
import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY3, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE2, AGENT_RUNNER, AGENT_STORE as
|
|
679
|
-
import { BadRequestException, ForbiddenException, Inject as
|
|
970
|
+
import { AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY3, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE4 } from "@dudousxd/nestjs-agent-core";
|
|
971
|
+
import { BadRequestException, ForbiddenException, Inject as Inject5, Injectable as Injectable5, NotFoundException, NotImplementedException, Optional as Optional3 } from "@nestjs/common";
|
|
680
972
|
function _ts_decorate6(decorators, target, key, desc) {
|
|
681
973
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
682
974
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -688,12 +980,12 @@ function _ts_metadata5(k, v) {
|
|
|
688
980
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
689
981
|
}
|
|
690
982
|
__name(_ts_metadata5, "_ts_metadata");
|
|
691
|
-
function
|
|
983
|
+
function _ts_param5(paramIndex, decorator) {
|
|
692
984
|
return function(target, key) {
|
|
693
985
|
decorator(target, key, paramIndex);
|
|
694
986
|
};
|
|
695
987
|
}
|
|
696
|
-
__name(
|
|
988
|
+
__name(_ts_param5, "_ts_param");
|
|
697
989
|
var AgentService = class {
|
|
698
990
|
static {
|
|
699
991
|
__name(this, "AgentService");
|
|
@@ -702,14 +994,17 @@ var AgentService = class {
|
|
|
702
994
|
store;
|
|
703
995
|
deps;
|
|
704
996
|
quota;
|
|
705
|
-
|
|
997
|
+
staging;
|
|
998
|
+
constructor(runner, store, deps, quota, staging) {
|
|
706
999
|
this.runner = runner;
|
|
707
1000
|
this.store = store;
|
|
708
1001
|
this.deps = deps;
|
|
709
1002
|
this.quota = quota;
|
|
1003
|
+
this.staging = staging;
|
|
710
1004
|
}
|
|
711
1005
|
async chat(params) {
|
|
712
1006
|
const agentName = await this.resolveAgentName(params.agentName, params.threadId);
|
|
1007
|
+
const attachments = await this.resolveAttachments(params.actor, params.attachments ?? []);
|
|
713
1008
|
let threadId = params.threadId;
|
|
714
1009
|
if (threadId === void 0) {
|
|
715
1010
|
if (params.regenerate === true) {
|
|
@@ -734,8 +1029,8 @@ var AgentService = class {
|
|
|
734
1029
|
...params.regenerate === true ? {
|
|
735
1030
|
regenerate: true
|
|
736
1031
|
} : {},
|
|
737
|
-
...
|
|
738
|
-
attachments
|
|
1032
|
+
...attachments.length > 0 ? {
|
|
1033
|
+
attachments
|
|
739
1034
|
} : {},
|
|
740
1035
|
...params.pageContext !== void 0 ? {
|
|
741
1036
|
pageContext: params.pageContext
|
|
@@ -748,18 +1043,66 @@ var AgentService = class {
|
|
|
748
1043
|
threadId
|
|
749
1044
|
};
|
|
750
1045
|
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Rebuild this turn's attachments from the staging store, keyed by the ids the caller claimed.
|
|
1048
|
+
* The model provider fetches {@link MessageAttachment.url} verbatim, so that url is only ever
|
|
1049
|
+
* allowed to come from the host's own store — a caller that could name it could point the server
|
|
1050
|
+
* at anything it can reach (cloud metadata, internal services) and read the response back out of
|
|
1051
|
+
* the model's answer.
|
|
1052
|
+
*
|
|
1053
|
+
* No store bound means no way to tell an id the actor owns from one they don't, so a turn simply
|
|
1054
|
+
* cannot carry attachments: 501 rather than trusting the request.
|
|
1055
|
+
*/
|
|
1056
|
+
async resolveAttachments(actor, refs) {
|
|
1057
|
+
if (refs.length === 0) {
|
|
1058
|
+
return [];
|
|
1059
|
+
}
|
|
1060
|
+
const staging = this.staging;
|
|
1061
|
+
if (staging === void 0 || typeof staging.resolve !== "function") {
|
|
1062
|
+
throw new NotImplementedException("Message attachments require an AGENT_ATTACHMENT_STAGING provider implementing resolve(); attachment urls are never taken from the request.");
|
|
1063
|
+
}
|
|
1064
|
+
const resolved = [];
|
|
1065
|
+
for (const ref of refs) {
|
|
1066
|
+
const attachment = await staging.resolve({
|
|
1067
|
+
mediaId: ref.mediaId,
|
|
1068
|
+
actor
|
|
1069
|
+
});
|
|
1070
|
+
if (attachment === null) {
|
|
1071
|
+
throw new ForbiddenException(`attachment ${ref.mediaId} is not available to this actor`);
|
|
1072
|
+
}
|
|
1073
|
+
resolved.push(attachment);
|
|
1074
|
+
}
|
|
1075
|
+
return resolved;
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* The run's live token stream, WITHOUT an ownership check — for in-process callers that are
|
|
1079
|
+
* already authorized (the MCP bridge, a host's own job code), the same split as
|
|
1080
|
+
* {@link signalToolCall} vs {@link approve}. Anything reachable from a request must go through
|
|
1081
|
+
* {@link subscribeAs} instead: a runId is the only thing standing between a caller and another
|
|
1082
|
+
* actor's answer, tool arguments and tool results.
|
|
1083
|
+
*/
|
|
751
1084
|
subscribe(runId) {
|
|
752
1085
|
return this.deps.forAgent().sink.subscribe(runId);
|
|
753
1086
|
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
1087
|
+
/**
|
|
1088
|
+
* {@link subscribe}, gated the way {@link cancel} is: only the actor whose thread is currently
|
|
1089
|
+
* streaming this run may read it. A run that has already finished is reported missing rather than
|
|
1090
|
+
* replayed — the runner clears the thread's active stream as the run ends, and that field is what
|
|
1091
|
+
* ownership is derived from.
|
|
1092
|
+
*/
|
|
1093
|
+
async subscribeAs(actor, runId) {
|
|
1094
|
+
await this.assertOwnsActiveStream(actor, runId);
|
|
1095
|
+
return this.subscribe(runId);
|
|
1096
|
+
}
|
|
1097
|
+
async approve(actor, toolCallId2) {
|
|
1098
|
+
await this.assertOwnsToolCall(actor, toolCallId2);
|
|
1099
|
+
return this.signalToolCall(toolCallId2, {
|
|
757
1100
|
approved: true
|
|
758
1101
|
});
|
|
759
1102
|
}
|
|
760
|
-
async reject(actor,
|
|
761
|
-
await this.assertOwnsToolCall(actor,
|
|
762
|
-
return this.signalToolCall(
|
|
1103
|
+
async reject(actor, toolCallId2, reason) {
|
|
1104
|
+
await this.assertOwnsToolCall(actor, toolCallId2);
|
|
1105
|
+
return this.signalToolCall(toolCallId2, {
|
|
763
1106
|
approved: false,
|
|
764
1107
|
...reason !== void 0 ? {
|
|
765
1108
|
reason
|
|
@@ -767,6 +1110,34 @@ var AgentService = class {
|
|
|
767
1110
|
});
|
|
768
1111
|
}
|
|
769
1112
|
/**
|
|
1113
|
+
* Answer a parked question set. An omitted question takes the request's own pre-picked default —
|
|
1114
|
+
* resolved by the LOOP against the request it already holds, so "the user just submitted" and
|
|
1115
|
+
* "the user picked exactly the defaults" persist as the same answers, and no client has to
|
|
1116
|
+
* re-send what it was shown.
|
|
1117
|
+
*/
|
|
1118
|
+
async answer(actor, toolCallId2, answers2 = {}) {
|
|
1119
|
+
await this.assertOwnsToolCall(actor, toolCallId2);
|
|
1120
|
+
const reply = {
|
|
1121
|
+
answers: answers2,
|
|
1122
|
+
answeredByRef: actor.id
|
|
1123
|
+
};
|
|
1124
|
+
return this.signalToolCall(toolCallId2, reply);
|
|
1125
|
+
}
|
|
1126
|
+
/**
|
|
1127
|
+
* Decline to answer and let the agent proceed on its own assumptions. NOT the same as confirming
|
|
1128
|
+
* them: the run records this as a rejection, so a reader auditing what the agent was told can
|
|
1129
|
+
* tell a choice the user made from one they refused to make.
|
|
1130
|
+
*/
|
|
1131
|
+
async skip(actor, toolCallId2) {
|
|
1132
|
+
await this.assertOwnsToolCall(actor, toolCallId2);
|
|
1133
|
+
const reply = {
|
|
1134
|
+
answers: {},
|
|
1135
|
+
skipped: true,
|
|
1136
|
+
answeredByRef: actor.id
|
|
1137
|
+
};
|
|
1138
|
+
return this.signalToolCall(toolCallId2, reply);
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
770
1141
|
* The decision core behind approve/reject, WITHOUT an ownership check: resolves the run
|
|
771
1142
|
* currently awaiting `toolCallId` and signals it. `approve`/`reject` above call this after their
|
|
772
1143
|
* own `assertOwnsToolCall` gate; the console `AgentApprovalPort` adapter (bound by `AgentModule`)
|
|
@@ -774,9 +1145,9 @@ var AgentService = class {
|
|
|
774
1145
|
* re-deriving thread ownership here would reject a legitimate operator decision (an operator is
|
|
775
1146
|
* not the thread's own actor).
|
|
776
1147
|
*/
|
|
777
|
-
async signalToolCall(
|
|
778
|
-
const runId = await this.resolveRunForToolCall(
|
|
779
|
-
return this.runner.signal(runId,
|
|
1148
|
+
async signalToolCall(toolCallId2, reply) {
|
|
1149
|
+
const runId = await this.resolveRunForToolCall(toolCallId2);
|
|
1150
|
+
return this.runner.signal(runId, toolCallId2, reply);
|
|
780
1151
|
}
|
|
781
1152
|
async cancel(actor, runId) {
|
|
782
1153
|
await this.assertOwnsActiveStream(actor, runId);
|
|
@@ -843,20 +1214,33 @@ var AgentService = class {
|
|
|
843
1214
|
/**
|
|
844
1215
|
* Agent-selection precedence for a `chat()` call with no explicit `agentName`: the thread's own
|
|
845
1216
|
* `defaultAgent` (if the thread exists and one is set) wins over the module's configured default.
|
|
846
|
-
* Skips the
|
|
1217
|
+
* Skips the store entirely when the caller already named an agent or there's no thread yet.
|
|
1218
|
+
*
|
|
1219
|
+
* What this needs is one nullable scalar, so it asks for one. `getThread` returns the entire
|
|
1220
|
+
* transcript — every message, every persisted tool output — and this discards all of it; on a
|
|
1221
|
+
* long thread with large tool results that is hundreds of kilobytes read per turn, outside the
|
|
1222
|
+
* workflow, for a string. A store predating {@link ThreadDefaultAgentReader} still answers, via
|
|
1223
|
+
* the full read.
|
|
847
1224
|
*/
|
|
848
1225
|
async resolveAgentName(agentName, threadId) {
|
|
849
1226
|
if (agentName !== void 0) {
|
|
850
1227
|
return agentName;
|
|
851
1228
|
}
|
|
852
1229
|
if (threadId !== void 0) {
|
|
853
|
-
const
|
|
854
|
-
if (
|
|
855
|
-
return
|
|
1230
|
+
const threadDefault = await this.threadDefaultAgent(threadId);
|
|
1231
|
+
if (threadDefault !== null) {
|
|
1232
|
+
return threadDefault;
|
|
856
1233
|
}
|
|
857
1234
|
}
|
|
858
1235
|
return this.deps.defaultAgentName();
|
|
859
1236
|
}
|
|
1237
|
+
async threadDefaultAgent(threadId) {
|
|
1238
|
+
const projecting = this.store;
|
|
1239
|
+
if (typeof projecting.defaultAgentForThread === "function") {
|
|
1240
|
+
return projecting.defaultAgentForThread(threadId);
|
|
1241
|
+
}
|
|
1242
|
+
return (await this.store.getThread(threadId))?.defaultAgent ?? null;
|
|
1243
|
+
}
|
|
860
1244
|
async toSummaryView(thread) {
|
|
861
1245
|
return {
|
|
862
1246
|
...thread,
|
|
@@ -888,6 +1272,67 @@ var AgentService = class {
|
|
|
888
1272
|
return this.store.truncateFrom(threadId, messageId);
|
|
889
1273
|
}
|
|
890
1274
|
/**
|
|
1275
|
+
* Every file this actor has staged, newest first — across threads, including uploads that were
|
|
1276
|
+
* never sent, which nothing else on this surface can see.
|
|
1277
|
+
*
|
|
1278
|
+
* Metadata only. A url is minted per turn by `resolve` so it can be short-lived, and handing one
|
|
1279
|
+
* back per entry would undo that for the price of rendering a list.
|
|
1280
|
+
*/
|
|
1281
|
+
async listAttachments(actor, options = {}) {
|
|
1282
|
+
const list = this.attachmentInventory();
|
|
1283
|
+
return list({
|
|
1284
|
+
actor,
|
|
1285
|
+
...options.limit !== void 0 ? {
|
|
1286
|
+
limit: options.limit
|
|
1287
|
+
} : {}
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* This actor's staged media that no live message references and that is old enough not to be an
|
|
1292
|
+
* upload in flight — the candidate set for a sweep. Returns them; never deletes them. The bytes
|
|
1293
|
+
* are the host's, and so is the decision.
|
|
1294
|
+
*
|
|
1295
|
+
* `olderThan` is required and has no default. How long a composer may sit open with a file
|
|
1296
|
+
* attached is the host's knowledge, and a library-chosen grace period would eventually delete a
|
|
1297
|
+
* file someone was about to send. The staging store is asked to apply it, and the result is
|
|
1298
|
+
* filtered again here: a store that ignores the hint would otherwise turn this into exactly that
|
|
1299
|
+
* bug, silently.
|
|
1300
|
+
*
|
|
1301
|
+
* Both halves must be answerable or this refuses. An unanswerable reference query means "cannot
|
|
1302
|
+
* tell", and treating it as "nothing is referenced" would hand back every attachment the actor
|
|
1303
|
+
* ever sent, marked safe to delete.
|
|
1304
|
+
*/
|
|
1305
|
+
async collectableAttachments(actor, options) {
|
|
1306
|
+
const list = this.attachmentInventory();
|
|
1307
|
+
const referencedMediaIds = this.store.referencedMediaIds?.bind(this.store);
|
|
1308
|
+
if (referencedMediaIds === void 0) {
|
|
1309
|
+
throw new 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.");
|
|
1310
|
+
}
|
|
1311
|
+
const stagedBefore = options.olderThan.toISOString();
|
|
1312
|
+
const inventory = await list({
|
|
1313
|
+
actor,
|
|
1314
|
+
stagedBefore,
|
|
1315
|
+
...options.limit !== void 0 ? {
|
|
1316
|
+
limit: options.limit
|
|
1317
|
+
} : {}
|
|
1318
|
+
});
|
|
1319
|
+
const aged = inventory.filter((entry) => entry.createdAt < stagedBefore);
|
|
1320
|
+
const referenced = new Set(await referencedMediaIds(actor.id, aged.map((entry) => entry.mediaId)));
|
|
1321
|
+
return aged.filter((entry) => !referenced.has(entry.mediaId));
|
|
1322
|
+
}
|
|
1323
|
+
/**
|
|
1324
|
+
* The bound staging store's `list`, or a refusal. Absence is never answered with an empty list:
|
|
1325
|
+
* "this host keeps no inventory" and "this actor has no files" are opposite facts that would
|
|
1326
|
+
* otherwise render identically — as a clean file list, and as a sweep that collects nothing.
|
|
1327
|
+
*/
|
|
1328
|
+
attachmentInventory() {
|
|
1329
|
+
const list = this.staging?.list?.bind(this.staging);
|
|
1330
|
+
if (list === void 0) {
|
|
1331
|
+
throw new NotImplementedException("Listing attachments requires an AGENT_ATTACHMENT_STAGING provider implementing list(); the host owns the staged bytes, so only it can enumerate them.");
|
|
1332
|
+
}
|
|
1333
|
+
return list;
|
|
1334
|
+
}
|
|
1335
|
+
/**
|
|
891
1336
|
* The day's usage for the badge: tokens + summed USD cost from the store, and the configured
|
|
892
1337
|
* limit from the quota store (null → unlimited). `withinLimit` comes from the quota store so it
|
|
893
1338
|
* can never drift from what enforcement uses.
|
|
@@ -929,24 +1374,26 @@ var AgentService = class {
|
|
|
929
1374
|
* out from run resolution (see {@link resolveRunForToolCall}) so the console `AgentApprovalPort`
|
|
930
1375
|
* adapter can resolve+signal a decision WITHOUT this check — it is authorized upstream instead.
|
|
931
1376
|
*/
|
|
932
|
-
async assertOwnsToolCall(actor,
|
|
933
|
-
const owner = await this.store.ownerOfToolCall(
|
|
1377
|
+
async assertOwnsToolCall(actor, toolCallId2) {
|
|
1378
|
+
const owner = await this.store.ownerOfToolCall(toolCallId2);
|
|
934
1379
|
if (owner === null) {
|
|
935
|
-
throw new NotFoundException(`tool call ${
|
|
1380
|
+
throw new NotFoundException(`tool call ${toolCallId2} not found`);
|
|
936
1381
|
}
|
|
937
1382
|
if (owner !== actor.id) {
|
|
938
1383
|
throw new ForbiddenException("tool call belongs to another actor");
|
|
939
1384
|
}
|
|
940
1385
|
}
|
|
941
1386
|
/**
|
|
942
|
-
* Resolve the run
|
|
943
|
-
* sub-agent's own child run when the pending
|
|
944
|
-
*
|
|
1387
|
+
* Resolve the run awaiting `toolCallId`. Derived server-side from the tool call alone — the client
|
|
1388
|
+
* never knows or supplies a runId, and that run is the sub-agent's own child run when the pending
|
|
1389
|
+
* call belongs to a delegated agent. The store answers from the CALL'S OWN `runId` where it has
|
|
1390
|
+
* one; see `AgentStore.runForToolCall` for why that matters once a thread can hold more than one
|
|
1391
|
+
* live run.
|
|
945
1392
|
*/
|
|
946
|
-
async resolveRunForToolCall(
|
|
947
|
-
const runId = await this.store.runForToolCall(
|
|
1393
|
+
async resolveRunForToolCall(toolCallId2) {
|
|
1394
|
+
const runId = await this.store.runForToolCall(toolCallId2);
|
|
948
1395
|
if (runId === null) {
|
|
949
|
-
throw new NotFoundException(`tool call ${
|
|
1396
|
+
throw new NotFoundException(`tool call ${toolCallId2} has no active run to signal`);
|
|
950
1397
|
}
|
|
951
1398
|
return runId;
|
|
952
1399
|
}
|
|
@@ -963,16 +1410,19 @@ var AgentService = class {
|
|
|
963
1410
|
};
|
|
964
1411
|
AgentService = _ts_decorate6([
|
|
965
1412
|
Injectable5(),
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1413
|
+
_ts_param5(0, Inject5(AGENT_RUNNER)),
|
|
1414
|
+
_ts_param5(1, Inject5(AGENT_STORE4)),
|
|
1415
|
+
_ts_param5(2, Inject5(AGENT_DEPS_FACTORY3)),
|
|
1416
|
+
_ts_param5(3, Inject5(AGENT_QUOTA_STORE2)),
|
|
1417
|
+
_ts_param5(4, Optional3()),
|
|
1418
|
+
_ts_param5(4, Inject5(AGENT_ATTACHMENT_STAGING)),
|
|
970
1419
|
_ts_metadata5("design:type", Function),
|
|
971
1420
|
_ts_metadata5("design:paramtypes", [
|
|
972
1421
|
typeof AgentRunner === "undefined" ? Object : AgentRunner,
|
|
973
1422
|
typeof AgentStore === "undefined" ? Object : AgentStore,
|
|
974
1423
|
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
|
|
975
|
-
Object
|
|
1424
|
+
Object,
|
|
1425
|
+
typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore
|
|
976
1426
|
])
|
|
977
1427
|
], AgentService);
|
|
978
1428
|
|
|
@@ -997,16 +1447,16 @@ var AgentApprovalPortAdapter = class {
|
|
|
997
1447
|
constructor(agent) {
|
|
998
1448
|
this.agent = agent;
|
|
999
1449
|
}
|
|
1000
|
-
async approve(
|
|
1001
|
-
await this.agent.signalToolCall(
|
|
1450
|
+
async approve(toolCallId2, opts) {
|
|
1451
|
+
await this.agent.signalToolCall(toolCallId2, {
|
|
1002
1452
|
approved: true,
|
|
1003
1453
|
...opts?.executedByRef !== void 0 ? {
|
|
1004
1454
|
executedByRef: opts.executedByRef
|
|
1005
1455
|
} : {}
|
|
1006
1456
|
});
|
|
1007
1457
|
}
|
|
1008
|
-
async reject(
|
|
1009
|
-
await this.agent.signalToolCall(
|
|
1458
|
+
async reject(toolCallId2, opts) {
|
|
1459
|
+
await this.agent.signalToolCall(toolCallId2, {
|
|
1010
1460
|
approved: false,
|
|
1011
1461
|
...opts?.executedByRef !== void 0 ? {
|
|
1012
1462
|
executedByRef: opts.executedByRef
|
|
@@ -1027,7 +1477,7 @@ AgentApprovalPortAdapter = _ts_decorate7([
|
|
|
1027
1477
|
|
|
1028
1478
|
// src/controller/agents.controller.ts
|
|
1029
1479
|
import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY4, AGENT_REGISTRY as AGENT_REGISTRY2, AgentRegistry as AgentRegistry3 } from "@dudousxd/nestjs-agent-core";
|
|
1030
|
-
import { Controller, Get, Inject as
|
|
1480
|
+
import { Controller, Get, Inject as Inject6 } from "@nestjs/common";
|
|
1031
1481
|
function _ts_decorate8(decorators, target, key, desc) {
|
|
1032
1482
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1033
1483
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1039,12 +1489,12 @@ function _ts_metadata7(k, v) {
|
|
|
1039
1489
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1040
1490
|
}
|
|
1041
1491
|
__name(_ts_metadata7, "_ts_metadata");
|
|
1042
|
-
function
|
|
1492
|
+
function _ts_param6(paramIndex, decorator) {
|
|
1043
1493
|
return function(target, key) {
|
|
1044
1494
|
decorator(target, key, paramIndex);
|
|
1045
1495
|
};
|
|
1046
1496
|
}
|
|
1047
|
-
__name(
|
|
1497
|
+
__name(_ts_param6, "_ts_param");
|
|
1048
1498
|
var AgentsController = class {
|
|
1049
1499
|
static {
|
|
1050
1500
|
__name(this, "AgentsController");
|
|
@@ -1074,8 +1524,8 @@ _ts_decorate8([
|
|
|
1074
1524
|
], AgentsController.prototype, "list", null);
|
|
1075
1525
|
AgentsController = _ts_decorate8([
|
|
1076
1526
|
Controller("agents"),
|
|
1077
|
-
|
|
1078
|
-
|
|
1527
|
+
_ts_param6(0, Inject6(AGENT_REGISTRY2)),
|
|
1528
|
+
_ts_param6(1, Inject6(AGENT_DEPS_FACTORY4)),
|
|
1079
1529
|
_ts_metadata7("design:type", Function),
|
|
1080
1530
|
_ts_metadata7("design:paramtypes", [
|
|
1081
1531
|
typeof AgentRegistry3 === "undefined" ? Object : AgentRegistry3,
|
|
@@ -1084,8 +1534,8 @@ AgentsController = _ts_decorate8([
|
|
|
1084
1534
|
], AgentsController);
|
|
1085
1535
|
|
|
1086
1536
|
// src/controller/attachments.controller.ts
|
|
1087
|
-
import { AGENT_ACTOR_RESOLVER, AGENT_ATTACHMENT_STAGING, AGENT_OPTIONS as AGENT_OPTIONS3 } from "@dudousxd/nestjs-agent-core";
|
|
1088
|
-
import { BadRequestException as BadRequestException2, Controller as Controller2, Inject as
|
|
1537
|
+
import { AGENT_ACTOR_RESOLVER, AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING2, AGENT_OPTIONS as AGENT_OPTIONS3 } from "@dudousxd/nestjs-agent-core";
|
|
1538
|
+
import { BadRequestException as BadRequestException2, Controller as Controller2, Get as Get2, Inject as Inject7, NotImplementedException as NotImplementedException2, Optional as Optional4, PayloadTooLargeException, Post, Req, UnsupportedMediaTypeException, UploadedFile, UseInterceptors } from "@nestjs/common";
|
|
1089
1539
|
import { FileInterceptor } from "@nestjs/platform-express";
|
|
1090
1540
|
function _ts_decorate9(decorators, target, key, desc) {
|
|
1091
1541
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -1098,13 +1548,15 @@ function _ts_metadata8(k, v) {
|
|
|
1098
1548
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1099
1549
|
}
|
|
1100
1550
|
__name(_ts_metadata8, "_ts_metadata");
|
|
1101
|
-
function
|
|
1551
|
+
function _ts_param7(paramIndex, decorator) {
|
|
1102
1552
|
return function(target, key) {
|
|
1103
1553
|
decorator(target, key, paramIndex);
|
|
1104
1554
|
};
|
|
1105
1555
|
}
|
|
1106
|
-
__name(
|
|
1556
|
+
__name(_ts_param7, "_ts_param");
|
|
1107
1557
|
var DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
1558
|
+
var HARD_MAX_ATTACHMENT_BYTES = 32 * 1024 * 1024;
|
|
1559
|
+
var ATTACHMENT_PAGE_SIZE = 50;
|
|
1108
1560
|
var DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES = [
|
|
1109
1561
|
"image/png",
|
|
1110
1562
|
"image/jpeg",
|
|
@@ -1120,10 +1572,12 @@ var AttachmentsController = class {
|
|
|
1120
1572
|
}
|
|
1121
1573
|
options;
|
|
1122
1574
|
actorResolver;
|
|
1575
|
+
agents;
|
|
1123
1576
|
staging;
|
|
1124
|
-
constructor(options, actorResolver, staging) {
|
|
1577
|
+
constructor(options, actorResolver, agents, staging) {
|
|
1125
1578
|
this.options = options;
|
|
1126
1579
|
this.actorResolver = actorResolver;
|
|
1580
|
+
this.agents = agents;
|
|
1127
1581
|
this.staging = staging;
|
|
1128
1582
|
}
|
|
1129
1583
|
/**
|
|
@@ -1137,6 +1591,21 @@ var AttachmentsController = class {
|
|
|
1137
1591
|
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.");
|
|
1138
1592
|
}
|
|
1139
1593
|
}
|
|
1594
|
+
/**
|
|
1595
|
+
* The caller's own staged files, newest first — the one question `GET /agent/threads/:id` cannot
|
|
1596
|
+
* answer, since an upload that was never sent belongs to no thread.
|
|
1597
|
+
*
|
|
1598
|
+
* Scoped by the RESOLVED actor and nothing else. There is deliberately no `threadId` filter: a
|
|
1599
|
+
* thread's attachments already ride on its messages in the thread payload, and re-serving them
|
|
1600
|
+
* from here would add a second ownership path to get wrong for information the client already
|
|
1601
|
+
* holds. Metadata only — see {@link StagedAttachment}.
|
|
1602
|
+
*/
|
|
1603
|
+
async list(req) {
|
|
1604
|
+
const actor = await this.actorResolver.resolve(req);
|
|
1605
|
+
return this.agents.listAttachments(actor, {
|
|
1606
|
+
limit: ATTACHMENT_PAGE_SIZE
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1140
1609
|
async upload(req, file) {
|
|
1141
1610
|
if (this.staging === void 0) {
|
|
1142
1611
|
throw new NotImplementedException2("Attachment upload is not configured on this server.");
|
|
@@ -1162,11 +1631,24 @@ var AttachmentsController = class {
|
|
|
1162
1631
|
});
|
|
1163
1632
|
}
|
|
1164
1633
|
};
|
|
1634
|
+
_ts_decorate9([
|
|
1635
|
+
Get2(),
|
|
1636
|
+
_ts_param7(0, Req()),
|
|
1637
|
+
_ts_metadata8("design:type", Function),
|
|
1638
|
+
_ts_metadata8("design:paramtypes", [
|
|
1639
|
+
typeof Request === "undefined" ? Object : Request
|
|
1640
|
+
]),
|
|
1641
|
+
_ts_metadata8("design:returntype", Promise)
|
|
1642
|
+
], AttachmentsController.prototype, "list", null);
|
|
1165
1643
|
_ts_decorate9([
|
|
1166
1644
|
Post(),
|
|
1167
|
-
UseInterceptors(FileInterceptor("file"
|
|
1168
|
-
|
|
1169
|
-
|
|
1645
|
+
UseInterceptors(FileInterceptor("file", {
|
|
1646
|
+
limits: {
|
|
1647
|
+
fileSize: HARD_MAX_ATTACHMENT_BYTES
|
|
1648
|
+
}
|
|
1649
|
+
})),
|
|
1650
|
+
_ts_param7(0, Req()),
|
|
1651
|
+
_ts_param7(1, UploadedFile()),
|
|
1170
1652
|
_ts_metadata8("design:type", Function),
|
|
1171
1653
|
_ts_metadata8("design:paramtypes", [
|
|
1172
1654
|
typeof Request === "undefined" ? Object : Request,
|
|
@@ -1176,21 +1658,22 @@ _ts_decorate9([
|
|
|
1176
1658
|
], AttachmentsController.prototype, "upload", null);
|
|
1177
1659
|
AttachmentsController = _ts_decorate9([
|
|
1178
1660
|
Controller2("attachments"),
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1661
|
+
_ts_param7(0, Inject7(AGENT_OPTIONS3)),
|
|
1662
|
+
_ts_param7(1, Inject7(AGENT_ACTOR_RESOLVER)),
|
|
1663
|
+
_ts_param7(3, Optional4()),
|
|
1664
|
+
_ts_param7(3, Inject7(AGENT_ATTACHMENT_STAGING2)),
|
|
1183
1665
|
_ts_metadata8("design:type", Function),
|
|
1184
1666
|
_ts_metadata8("design:paramtypes", [
|
|
1185
1667
|
typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
|
|
1186
1668
|
typeof ActorResolver === "undefined" ? Object : ActorResolver,
|
|
1669
|
+
typeof AgentService === "undefined" ? Object : AgentService,
|
|
1187
1670
|
Object
|
|
1188
1671
|
])
|
|
1189
1672
|
], AttachmentsController);
|
|
1190
1673
|
|
|
1191
1674
|
// src/controller/chat.controller.ts
|
|
1192
1675
|
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER2, AgentStreamError as AgentStreamError2 } from "@dudousxd/nestjs-agent-core";
|
|
1193
|
-
import { Body, Controller as Controller3, Get as
|
|
1676
|
+
import { BadRequestException as BadRequestException3, Body, Controller as Controller3, Get as Get3, Inject as Inject8, Param, Post as Post2, Req as Req2, Res } from "@nestjs/common";
|
|
1194
1677
|
function _ts_decorate10(decorators, target, key, desc) {
|
|
1195
1678
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1196
1679
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1202,12 +1685,37 @@ function _ts_metadata9(k, v) {
|
|
|
1202
1685
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1203
1686
|
}
|
|
1204
1687
|
__name(_ts_metadata9, "_ts_metadata");
|
|
1205
|
-
function
|
|
1688
|
+
function _ts_param8(paramIndex, decorator) {
|
|
1206
1689
|
return function(target, key) {
|
|
1207
1690
|
decorator(target, key, paramIndex);
|
|
1208
1691
|
};
|
|
1209
1692
|
}
|
|
1210
|
-
__name(
|
|
1693
|
+
__name(_ts_param8, "_ts_param");
|
|
1694
|
+
var MAX_ATTACHMENTS_PER_MESSAGE = 10;
|
|
1695
|
+
function attachmentRefs(claimed) {
|
|
1696
|
+
if (claimed === void 0) {
|
|
1697
|
+
return [];
|
|
1698
|
+
}
|
|
1699
|
+
if (!Array.isArray(claimed)) {
|
|
1700
|
+
throw new BadRequestException3("attachments must be an array of { mediaId }");
|
|
1701
|
+
}
|
|
1702
|
+
if (claimed.length > MAX_ATTACHMENTS_PER_MESSAGE) {
|
|
1703
|
+
throw new BadRequestException3(`a message may carry at most ${MAX_ATTACHMENTS_PER_MESSAGE} attachments`);
|
|
1704
|
+
}
|
|
1705
|
+
return claimed.map((entry) => {
|
|
1706
|
+
if (typeof entry !== "object" || entry === null || !("mediaId" in entry)) {
|
|
1707
|
+
throw new BadRequestException3("each attachment must be an object with a mediaId");
|
|
1708
|
+
}
|
|
1709
|
+
const { mediaId } = entry;
|
|
1710
|
+
if (typeof mediaId !== "string" || mediaId.length === 0) {
|
|
1711
|
+
throw new BadRequestException3("each attachment must carry a non-empty string mediaId");
|
|
1712
|
+
}
|
|
1713
|
+
return {
|
|
1714
|
+
mediaId
|
|
1715
|
+
};
|
|
1716
|
+
});
|
|
1717
|
+
}
|
|
1718
|
+
__name(attachmentRefs, "attachmentRefs");
|
|
1211
1719
|
var ChatController = class {
|
|
1212
1720
|
static {
|
|
1213
1721
|
__name(this, "ChatController");
|
|
@@ -1220,6 +1728,7 @@ var ChatController = class {
|
|
|
1220
1728
|
}
|
|
1221
1729
|
async chat(req, res, body) {
|
|
1222
1730
|
const actor = await this.actorResolver.resolve(req);
|
|
1731
|
+
const attachments = attachmentRefs(body.attachments);
|
|
1223
1732
|
const { runId, threadId } = await this.agent.chat({
|
|
1224
1733
|
actor,
|
|
1225
1734
|
message: body.message,
|
|
@@ -1229,8 +1738,8 @@ var ChatController = class {
|
|
|
1229
1738
|
...body.agent !== void 0 ? {
|
|
1230
1739
|
agentName: body.agent
|
|
1231
1740
|
} : {},
|
|
1232
|
-
...
|
|
1233
|
-
attachments
|
|
1741
|
+
...attachments.length > 0 ? {
|
|
1742
|
+
attachments
|
|
1234
1743
|
} : {},
|
|
1235
1744
|
...body.pageContext !== void 0 ? {
|
|
1236
1745
|
pageContext: body.pageContext
|
|
@@ -1242,10 +1751,11 @@ var ChatController = class {
|
|
|
1242
1751
|
transient: true
|
|
1243
1752
|
} : {}
|
|
1244
1753
|
});
|
|
1245
|
-
await this.pipe(res, runId, threadId);
|
|
1754
|
+
await this.pipe(res, runId, this.agent.subscribe(runId), threadId);
|
|
1246
1755
|
}
|
|
1247
|
-
async stream(runId, res) {
|
|
1248
|
-
await this.
|
|
1756
|
+
async stream(req, runId, res) {
|
|
1757
|
+
const actor = await this.actorResolver.resolve(req);
|
|
1758
|
+
await this.pipe(res, runId, await this.agent.subscribeAs(actor, runId));
|
|
1249
1759
|
}
|
|
1250
1760
|
async cancel(req, runId) {
|
|
1251
1761
|
const actor = await this.actorResolver.resolve(req);
|
|
@@ -1254,7 +1764,7 @@ var ChatController = class {
|
|
|
1254
1764
|
aborted: true
|
|
1255
1765
|
};
|
|
1256
1766
|
}
|
|
1257
|
-
async pipe(res, runId, threadId) {
|
|
1767
|
+
async pipe(res, runId, events, threadId) {
|
|
1258
1768
|
res.setHeader("Content-Type", "text/event-stream");
|
|
1259
1769
|
res.setHeader("Cache-Control", "no-cache");
|
|
1260
1770
|
res.setHeader("Connection", "keep-alive");
|
|
@@ -1272,7 +1782,7 @@ data: ${JSON.stringify({
|
|
|
1272
1782
|
const decoder = new TextDecoder();
|
|
1273
1783
|
let buffer = "";
|
|
1274
1784
|
try {
|
|
1275
|
-
for await (const chunk of
|
|
1785
|
+
for await (const chunk of events) {
|
|
1276
1786
|
buffer += decoder.decode(chunk, {
|
|
1277
1787
|
stream: true
|
|
1278
1788
|
});
|
|
@@ -1312,9 +1822,9 @@ data: ${JSON.stringify(payload)}
|
|
|
1312
1822
|
};
|
|
1313
1823
|
_ts_decorate10([
|
|
1314
1824
|
Post2("chat"),
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1825
|
+
_ts_param8(0, Req2()),
|
|
1826
|
+
_ts_param8(1, Res()),
|
|
1827
|
+
_ts_param8(2, Body()),
|
|
1318
1828
|
_ts_metadata9("design:type", Function),
|
|
1319
1829
|
_ts_metadata9("design:paramtypes", [
|
|
1320
1830
|
typeof Request === "undefined" ? Object : Request,
|
|
@@ -1324,11 +1834,13 @@ _ts_decorate10([
|
|
|
1324
1834
|
_ts_metadata9("design:returntype", Promise)
|
|
1325
1835
|
], ChatController.prototype, "chat", null);
|
|
1326
1836
|
_ts_decorate10([
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1837
|
+
Get3("chat/:runId/stream"),
|
|
1838
|
+
_ts_param8(0, Req2()),
|
|
1839
|
+
_ts_param8(1, Param("runId")),
|
|
1840
|
+
_ts_param8(2, Res()),
|
|
1330
1841
|
_ts_metadata9("design:type", Function),
|
|
1331
1842
|
_ts_metadata9("design:paramtypes", [
|
|
1843
|
+
typeof Request === "undefined" ? Object : Request,
|
|
1332
1844
|
String,
|
|
1333
1845
|
typeof Response === "undefined" ? Object : Response
|
|
1334
1846
|
]),
|
|
@@ -1336,8 +1848,8 @@ _ts_decorate10([
|
|
|
1336
1848
|
], ChatController.prototype, "stream", null);
|
|
1337
1849
|
_ts_decorate10([
|
|
1338
1850
|
Post2("chat/:runId/cancel"),
|
|
1339
|
-
|
|
1340
|
-
|
|
1851
|
+
_ts_param8(0, Req2()),
|
|
1852
|
+
_ts_param8(1, Param("runId")),
|
|
1341
1853
|
_ts_metadata9("design:type", Function),
|
|
1342
1854
|
_ts_metadata9("design:paramtypes", [
|
|
1343
1855
|
typeof Request === "undefined" ? Object : Request,
|
|
@@ -1347,7 +1859,7 @@ _ts_decorate10([
|
|
|
1347
1859
|
], ChatController.prototype, "cancel", null);
|
|
1348
1860
|
ChatController = _ts_decorate10([
|
|
1349
1861
|
Controller3(),
|
|
1350
|
-
|
|
1862
|
+
_ts_param8(1, Inject8(AGENT_ACTOR_RESOLVER2)),
|
|
1351
1863
|
_ts_metadata9("design:type", Function),
|
|
1352
1864
|
_ts_metadata9("design:paramtypes", [
|
|
1353
1865
|
typeof AgentService === "undefined" ? Object : AgentService,
|
|
@@ -1355,9 +1867,9 @@ ChatController = _ts_decorate10([
|
|
|
1355
1867
|
])
|
|
1356
1868
|
], ChatController);
|
|
1357
1869
|
|
|
1358
|
-
// src/controller/
|
|
1359
|
-
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER3 } from "@dudousxd/nestjs-agent-core";
|
|
1360
|
-
import { Controller as Controller4, Get as
|
|
1870
|
+
// src/controller/memories.controller.ts
|
|
1871
|
+
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER3, AGENT_MEMORY as AGENT_MEMORY2, memoryForgetVerdict, offerMemories } from "@dudousxd/nestjs-agent-core";
|
|
1872
|
+
import { Controller as Controller4, Delete, ForbiddenException as ForbiddenException2, Get as Get4, Inject as Inject9, NotFoundException as NotFoundException2, Optional as Optional5, Param as Param2, Query, Req as Req3 } from "@nestjs/common";
|
|
1361
1873
|
function _ts_decorate11(decorators, target, key, desc) {
|
|
1362
1874
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1363
1875
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1369,12 +1881,138 @@ function _ts_metadata10(k, v) {
|
|
|
1369
1881
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1370
1882
|
}
|
|
1371
1883
|
__name(_ts_metadata10, "_ts_metadata");
|
|
1372
|
-
function
|
|
1884
|
+
function _ts_param9(paramIndex, decorator) {
|
|
1373
1885
|
return function(target, key) {
|
|
1374
1886
|
decorator(target, key, paramIndex);
|
|
1375
1887
|
};
|
|
1376
1888
|
}
|
|
1377
|
-
__name(
|
|
1889
|
+
__name(_ts_param9, "_ts_param");
|
|
1890
|
+
var MemoriesController = class {
|
|
1891
|
+
static {
|
|
1892
|
+
__name(this, "MemoriesController");
|
|
1893
|
+
}
|
|
1894
|
+
actorResolver;
|
|
1895
|
+
memory;
|
|
1896
|
+
constructor(actorResolver, memory) {
|
|
1897
|
+
this.actorResolver = actorResolver;
|
|
1898
|
+
this.memory = memory;
|
|
1899
|
+
}
|
|
1900
|
+
/**
|
|
1901
|
+
* Every memory this actor can reach, most specific first, each carrying its origin and whatever
|
|
1902
|
+
* wider value it outranks.
|
|
1903
|
+
*
|
|
1904
|
+
* DELIBERATELY IGNORES `maxMemories`. That ceiling is a budget on what one TURN carries; applying
|
|
1905
|
+
* it here would mean a person could not see — and so could not delete — a belief the assistant is
|
|
1906
|
+
* one write away from acting on again. Showing someone more than the model sees is harmless;
|
|
1907
|
+
* showing them less is the failure this endpoint exists to prevent.
|
|
1908
|
+
*/
|
|
1909
|
+
async list(req, threadId) {
|
|
1910
|
+
if (this.memory === void 0) {
|
|
1911
|
+
return [];
|
|
1912
|
+
}
|
|
1913
|
+
const actor = await this.actorResolver.resolve(req);
|
|
1914
|
+
return (await this.unbounded(threadId ?? "", actor)).entries;
|
|
1915
|
+
}
|
|
1916
|
+
/**
|
|
1917
|
+
* Forget one. Authorized against the actor's OWN resolved list, the same way a `skill` load is
|
|
1918
|
+
* authorized against the turn's catalog: an id this actor cannot see is answered as missing rather
|
|
1919
|
+
* than refused, so the endpoint cannot be used to find out which memories exist about other people.
|
|
1920
|
+
*/
|
|
1921
|
+
async forget(req, id) {
|
|
1922
|
+
if (this.memory === void 0) {
|
|
1923
|
+
throw new NotFoundException2("No memory is configured in this deployment.");
|
|
1924
|
+
}
|
|
1925
|
+
const actor = await this.actorResolver.resolve(req);
|
|
1926
|
+
const digest = await this.unbounded("", actor);
|
|
1927
|
+
const entry = digest.entries.find((candidate) => candidate.id === id);
|
|
1928
|
+
if (entry === void 0) {
|
|
1929
|
+
throw new NotFoundException2(`No memory with id "${id}".`);
|
|
1930
|
+
}
|
|
1931
|
+
const verdict = memoryForgetVerdict({
|
|
1932
|
+
record: entry,
|
|
1933
|
+
actor
|
|
1934
|
+
});
|
|
1935
|
+
if (!verdict.allowed) {
|
|
1936
|
+
throw new ForbiddenException2(verdict.reason);
|
|
1937
|
+
}
|
|
1938
|
+
return {
|
|
1939
|
+
forgotten: await this.memory.provider.forget({
|
|
1940
|
+
id: entry.id,
|
|
1941
|
+
ctx: {
|
|
1942
|
+
actor,
|
|
1943
|
+
threadId: ""
|
|
1944
|
+
}
|
|
1945
|
+
})
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
async unbounded(threadId, actor) {
|
|
1949
|
+
const config = this.memory;
|
|
1950
|
+
return await offerMemories({
|
|
1951
|
+
config: {
|
|
1952
|
+
...config,
|
|
1953
|
+
maxMemories: Number.POSITIVE_INFINITY
|
|
1954
|
+
},
|
|
1955
|
+
ctx: {
|
|
1956
|
+
actor,
|
|
1957
|
+
threadId
|
|
1958
|
+
}
|
|
1959
|
+
});
|
|
1960
|
+
}
|
|
1961
|
+
};
|
|
1962
|
+
_ts_decorate11([
|
|
1963
|
+
Get4(),
|
|
1964
|
+
_ts_param9(0, Req3()),
|
|
1965
|
+
_ts_param9(1, Query("threadId")),
|
|
1966
|
+
_ts_metadata10("design:type", Function),
|
|
1967
|
+
_ts_metadata10("design:paramtypes", [
|
|
1968
|
+
typeof Request === "undefined" ? Object : Request,
|
|
1969
|
+
String
|
|
1970
|
+
]),
|
|
1971
|
+
_ts_metadata10("design:returntype", Promise)
|
|
1972
|
+
], MemoriesController.prototype, "list", null);
|
|
1973
|
+
_ts_decorate11([
|
|
1974
|
+
Delete(":id"),
|
|
1975
|
+
_ts_param9(0, Req3()),
|
|
1976
|
+
_ts_param9(1, Param2("id")),
|
|
1977
|
+
_ts_metadata10("design:type", Function),
|
|
1978
|
+
_ts_metadata10("design:paramtypes", [
|
|
1979
|
+
typeof Request === "undefined" ? Object : Request,
|
|
1980
|
+
String
|
|
1981
|
+
]),
|
|
1982
|
+
_ts_metadata10("design:returntype", Promise)
|
|
1983
|
+
], MemoriesController.prototype, "forget", null);
|
|
1984
|
+
MemoriesController = _ts_decorate11([
|
|
1985
|
+
Controller4("memories"),
|
|
1986
|
+
_ts_param9(0, Inject9(AGENT_ACTOR_RESOLVER3)),
|
|
1987
|
+
_ts_param9(1, Optional5()),
|
|
1988
|
+
_ts_param9(1, Inject9(AGENT_MEMORY2)),
|
|
1989
|
+
_ts_metadata10("design:type", Function),
|
|
1990
|
+
_ts_metadata10("design:paramtypes", [
|
|
1991
|
+
typeof ActorResolver === "undefined" ? Object : ActorResolver,
|
|
1992
|
+
Object
|
|
1993
|
+
])
|
|
1994
|
+
], MemoriesController);
|
|
1995
|
+
|
|
1996
|
+
// src/controller/quota.controller.ts
|
|
1997
|
+
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER4 } from "@dudousxd/nestjs-agent-core";
|
|
1998
|
+
import { Controller as Controller5, Get as Get5, Inject as Inject10, Req as Req4 } from "@nestjs/common";
|
|
1999
|
+
function _ts_decorate12(decorators, target, key, desc) {
|
|
2000
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2001
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2002
|
+
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;
|
|
2003
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2004
|
+
}
|
|
2005
|
+
__name(_ts_decorate12, "_ts_decorate");
|
|
2006
|
+
function _ts_metadata11(k, v) {
|
|
2007
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2008
|
+
}
|
|
2009
|
+
__name(_ts_metadata11, "_ts_metadata");
|
|
2010
|
+
function _ts_param10(paramIndex, decorator) {
|
|
2011
|
+
return function(target, key) {
|
|
2012
|
+
decorator(target, key, paramIndex);
|
|
2013
|
+
};
|
|
2014
|
+
}
|
|
2015
|
+
__name(_ts_param10, "_ts_param");
|
|
1378
2016
|
var QuotaController = class {
|
|
1379
2017
|
static {
|
|
1380
2018
|
__name(this, "QuotaController");
|
|
@@ -1390,45 +2028,110 @@ var QuotaController = class {
|
|
|
1390
2028
|
return this.agent.quotaToday(actor.id);
|
|
1391
2029
|
}
|
|
1392
2030
|
};
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
2031
|
+
_ts_decorate12([
|
|
2032
|
+
Get5("today"),
|
|
2033
|
+
_ts_param10(0, Req4()),
|
|
2034
|
+
_ts_metadata11("design:type", Function),
|
|
2035
|
+
_ts_metadata11("design:paramtypes", [
|
|
1398
2036
|
typeof Request === "undefined" ? Object : Request
|
|
1399
2037
|
]),
|
|
1400
|
-
|
|
2038
|
+
_ts_metadata11("design:returntype", Promise)
|
|
1401
2039
|
], QuotaController.prototype, "today", null);
|
|
1402
|
-
QuotaController =
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
2040
|
+
QuotaController = _ts_decorate12([
|
|
2041
|
+
Controller5("quota"),
|
|
2042
|
+
_ts_param10(1, Inject10(AGENT_ACTOR_RESOLVER4)),
|
|
2043
|
+
_ts_metadata11("design:type", Function),
|
|
2044
|
+
_ts_metadata11("design:paramtypes", [
|
|
1407
2045
|
typeof AgentService === "undefined" ? Object : AgentService,
|
|
1408
2046
|
typeof ActorResolver === "undefined" ? Object : ActorResolver
|
|
1409
2047
|
])
|
|
1410
2048
|
], QuotaController);
|
|
1411
2049
|
|
|
2050
|
+
// src/controller/skills.controller.ts
|
|
2051
|
+
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER5, AGENT_SKILLS as AGENT_SKILLS2, offerSkills } from "@dudousxd/nestjs-agent-core";
|
|
2052
|
+
import { Controller as Controller6, Get as Get6, Inject as Inject11, Optional as Optional6, Query as Query2, Req as Req5 } from "@nestjs/common";
|
|
2053
|
+
function _ts_decorate13(decorators, target, key, desc) {
|
|
2054
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2055
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2056
|
+
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;
|
|
2057
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2058
|
+
}
|
|
2059
|
+
__name(_ts_decorate13, "_ts_decorate");
|
|
2060
|
+
function _ts_metadata12(k, v) {
|
|
2061
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2062
|
+
}
|
|
2063
|
+
__name(_ts_metadata12, "_ts_metadata");
|
|
2064
|
+
function _ts_param11(paramIndex, decorator) {
|
|
2065
|
+
return function(target, key) {
|
|
2066
|
+
decorator(target, key, paramIndex);
|
|
2067
|
+
};
|
|
2068
|
+
}
|
|
2069
|
+
__name(_ts_param11, "_ts_param");
|
|
2070
|
+
var SkillsController = class {
|
|
2071
|
+
static {
|
|
2072
|
+
__name(this, "SkillsController");
|
|
2073
|
+
}
|
|
2074
|
+
actorResolver;
|
|
2075
|
+
skills;
|
|
2076
|
+
constructor(actorResolver, skills) {
|
|
2077
|
+
this.actorResolver = actorResolver;
|
|
2078
|
+
this.skills = skills;
|
|
2079
|
+
}
|
|
2080
|
+
async list(req, threadId) {
|
|
2081
|
+
if (this.skills === void 0) {
|
|
2082
|
+
return [];
|
|
2083
|
+
}
|
|
2084
|
+
const actor = await this.actorResolver.resolve(req);
|
|
2085
|
+
const offer = await offerSkills(this.skills, {
|
|
2086
|
+
actor,
|
|
2087
|
+
threadId: threadId ?? ""
|
|
2088
|
+
});
|
|
2089
|
+
return offer.entries;
|
|
2090
|
+
}
|
|
2091
|
+
};
|
|
2092
|
+
_ts_decorate13([
|
|
2093
|
+
Get6(),
|
|
2094
|
+
_ts_param11(0, Req5()),
|
|
2095
|
+
_ts_param11(1, Query2("threadId")),
|
|
2096
|
+
_ts_metadata12("design:type", Function),
|
|
2097
|
+
_ts_metadata12("design:paramtypes", [
|
|
2098
|
+
typeof Request === "undefined" ? Object : Request,
|
|
2099
|
+
String
|
|
2100
|
+
]),
|
|
2101
|
+
_ts_metadata12("design:returntype", Promise)
|
|
2102
|
+
], SkillsController.prototype, "list", null);
|
|
2103
|
+
SkillsController = _ts_decorate13([
|
|
2104
|
+
Controller6("skills"),
|
|
2105
|
+
_ts_param11(0, Inject11(AGENT_ACTOR_RESOLVER5)),
|
|
2106
|
+
_ts_param11(1, Optional6()),
|
|
2107
|
+
_ts_param11(1, Inject11(AGENT_SKILLS2)),
|
|
2108
|
+
_ts_metadata12("design:type", Function),
|
|
2109
|
+
_ts_metadata12("design:paramtypes", [
|
|
2110
|
+
typeof ActorResolver === "undefined" ? Object : ActorResolver,
|
|
2111
|
+
Object
|
|
2112
|
+
])
|
|
2113
|
+
], SkillsController);
|
|
2114
|
+
|
|
1412
2115
|
// src/controller/threads.controller.ts
|
|
1413
|
-
import { AGENT_ACTOR_RESOLVER as
|
|
1414
|
-
import { Body as Body2, Controller as
|
|
1415
|
-
function
|
|
2116
|
+
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER6 } from "@dudousxd/nestjs-agent-core";
|
|
2117
|
+
import { Body as Body2, Controller as Controller7, Delete as Delete2, Get as Get7, Inject as Inject12, Param as Param3, Patch, Post as Post3, Req as Req6 } from "@nestjs/common";
|
|
2118
|
+
function _ts_decorate14(decorators, target, key, desc) {
|
|
1416
2119
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1417
2120
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1418
2121
|
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;
|
|
1419
2122
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1420
2123
|
}
|
|
1421
|
-
__name(
|
|
1422
|
-
function
|
|
2124
|
+
__name(_ts_decorate14, "_ts_decorate");
|
|
2125
|
+
function _ts_metadata13(k, v) {
|
|
1423
2126
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1424
2127
|
}
|
|
1425
|
-
__name(
|
|
1426
|
-
function
|
|
2128
|
+
__name(_ts_metadata13, "_ts_metadata");
|
|
2129
|
+
function _ts_param12(paramIndex, decorator) {
|
|
1427
2130
|
return function(target, key) {
|
|
1428
2131
|
decorator(target, key, paramIndex);
|
|
1429
2132
|
};
|
|
1430
2133
|
}
|
|
1431
|
-
__name(
|
|
2134
|
+
__name(_ts_param12, "_ts_param");
|
|
1432
2135
|
var ThreadsController = class {
|
|
1433
2136
|
static {
|
|
1434
2137
|
__name(this, "ThreadsController");
|
|
@@ -1492,117 +2195,173 @@ var ThreadsController = class {
|
|
|
1492
2195
|
};
|
|
1493
2196
|
}
|
|
1494
2197
|
};
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
2198
|
+
_ts_decorate14([
|
|
2199
|
+
Get7(),
|
|
2200
|
+
_ts_param12(0, Req6()),
|
|
2201
|
+
_ts_metadata13("design:type", Function),
|
|
2202
|
+
_ts_metadata13("design:paramtypes", [
|
|
1500
2203
|
typeof Request === "undefined" ? Object : Request
|
|
1501
2204
|
]),
|
|
1502
|
-
|
|
2205
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1503
2206
|
], ThreadsController.prototype, "list", null);
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
2207
|
+
_ts_decorate14([
|
|
2208
|
+
Get7(":id"),
|
|
2209
|
+
_ts_param12(0, Req6()),
|
|
2210
|
+
_ts_param12(1, Param3("id")),
|
|
2211
|
+
_ts_metadata13("design:type", Function),
|
|
2212
|
+
_ts_metadata13("design:paramtypes", [
|
|
1510
2213
|
typeof Request === "undefined" ? Object : Request,
|
|
1511
2214
|
String
|
|
1512
2215
|
]),
|
|
1513
|
-
|
|
2216
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1514
2217
|
], ThreadsController.prototype, "detail", null);
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
2218
|
+
_ts_decorate14([
|
|
2219
|
+
Delete2(":id"),
|
|
2220
|
+
_ts_param12(0, Req6()),
|
|
2221
|
+
_ts_param12(1, Param3("id")),
|
|
2222
|
+
_ts_metadata13("design:type", Function),
|
|
2223
|
+
_ts_metadata13("design:paramtypes", [
|
|
1521
2224
|
typeof Request === "undefined" ? Object : Request,
|
|
1522
2225
|
String
|
|
1523
2226
|
]),
|
|
1524
|
-
|
|
2227
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1525
2228
|
], ThreadsController.prototype, "remove", null);
|
|
1526
|
-
|
|
2229
|
+
_ts_decorate14([
|
|
1527
2230
|
Post3(":id/fork-from/:messageId"),
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
2231
|
+
_ts_param12(0, Req6()),
|
|
2232
|
+
_ts_param12(1, Param3("id")),
|
|
2233
|
+
_ts_param12(2, Param3("messageId")),
|
|
2234
|
+
_ts_metadata13("design:type", Function),
|
|
2235
|
+
_ts_metadata13("design:paramtypes", [
|
|
1533
2236
|
typeof Request === "undefined" ? Object : Request,
|
|
1534
2237
|
String,
|
|
1535
2238
|
String
|
|
1536
2239
|
]),
|
|
1537
|
-
|
|
2240
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1538
2241
|
], ThreadsController.prototype, "fork", null);
|
|
1539
|
-
|
|
2242
|
+
_ts_decorate14([
|
|
1540
2243
|
Patch(":id"),
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
2244
|
+
_ts_param12(0, Req6()),
|
|
2245
|
+
_ts_param12(1, Param3("id")),
|
|
2246
|
+
_ts_param12(2, Body2()),
|
|
2247
|
+
_ts_metadata13("design:type", Function),
|
|
2248
|
+
_ts_metadata13("design:paramtypes", [
|
|
1546
2249
|
typeof Request === "undefined" ? Object : Request,
|
|
1547
2250
|
String,
|
|
1548
2251
|
typeof UpdateThreadBody === "undefined" ? Object : UpdateThreadBody
|
|
1549
2252
|
]),
|
|
1550
|
-
|
|
2253
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1551
2254
|
], ThreadsController.prototype, "update", null);
|
|
1552
|
-
|
|
2255
|
+
_ts_decorate14([
|
|
1553
2256
|
Post3(":id/promote"),
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
2257
|
+
_ts_param12(0, Req6()),
|
|
2258
|
+
_ts_param12(1, Param3("id")),
|
|
2259
|
+
_ts_metadata13("design:type", Function),
|
|
2260
|
+
_ts_metadata13("design:paramtypes", [
|
|
1558
2261
|
typeof Request === "undefined" ? Object : Request,
|
|
1559
2262
|
String
|
|
1560
2263
|
]),
|
|
1561
|
-
|
|
2264
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1562
2265
|
], ThreadsController.prototype, "promote", null);
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
2266
|
+
_ts_decorate14([
|
|
2267
|
+
Delete2(":id/from/:messageId"),
|
|
2268
|
+
_ts_param12(0, Req6()),
|
|
2269
|
+
_ts_param12(1, Param3("id")),
|
|
2270
|
+
_ts_param12(2, Param3("messageId")),
|
|
2271
|
+
_ts_metadata13("design:type", Function),
|
|
2272
|
+
_ts_metadata13("design:paramtypes", [
|
|
1570
2273
|
typeof Request === "undefined" ? Object : Request,
|
|
1571
2274
|
String,
|
|
1572
2275
|
String
|
|
1573
2276
|
]),
|
|
1574
|
-
|
|
2277
|
+
_ts_metadata13("design:returntype", Promise)
|
|
1575
2278
|
], ThreadsController.prototype, "truncateFrom", null);
|
|
1576
|
-
ThreadsController =
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
2279
|
+
ThreadsController = _ts_decorate14([
|
|
2280
|
+
Controller7("threads"),
|
|
2281
|
+
_ts_param12(1, Inject12(AGENT_ACTOR_RESOLVER6)),
|
|
2282
|
+
_ts_metadata13("design:type", Function),
|
|
2283
|
+
_ts_metadata13("design:paramtypes", [
|
|
1581
2284
|
typeof AgentService === "undefined" ? Object : AgentService,
|
|
1582
2285
|
typeof ActorResolver === "undefined" ? Object : ActorResolver
|
|
1583
2286
|
])
|
|
1584
2287
|
], ThreadsController);
|
|
1585
2288
|
|
|
1586
2289
|
// src/controller/tool-call.controller.ts
|
|
1587
|
-
import { AGENT_ACTOR_RESOLVER as
|
|
1588
|
-
import { Body as Body3, Controller as
|
|
1589
|
-
function
|
|
2290
|
+
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER7 } from "@dudousxd/nestjs-agent-core";
|
|
2291
|
+
import { BadRequestException as BadRequestException4, Body as Body3, Controller as Controller8, Inject as Inject13, Post as Post4, Req as Req7 } from "@nestjs/common";
|
|
2292
|
+
function _ts_decorate15(decorators, target, key, desc) {
|
|
1590
2293
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1591
2294
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1592
2295
|
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;
|
|
1593
2296
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1594
2297
|
}
|
|
1595
|
-
__name(
|
|
1596
|
-
function
|
|
2298
|
+
__name(_ts_decorate15, "_ts_decorate");
|
|
2299
|
+
function _ts_metadata14(k, v) {
|
|
1597
2300
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1598
2301
|
}
|
|
1599
|
-
__name(
|
|
1600
|
-
function
|
|
2302
|
+
__name(_ts_metadata14, "_ts_metadata");
|
|
2303
|
+
function _ts_param13(paramIndex, decorator) {
|
|
1601
2304
|
return function(target, key) {
|
|
1602
2305
|
decorator(target, key, paramIndex);
|
|
1603
2306
|
};
|
|
1604
2307
|
}
|
|
1605
|
-
__name(
|
|
2308
|
+
__name(_ts_param13, "_ts_param");
|
|
2309
|
+
var MAX_ANSWERED_QUESTIONS = 100;
|
|
2310
|
+
var MAX_VALUES_PER_QUESTION = 100;
|
|
2311
|
+
var MAX_ANSWER_VALUE_LENGTH = 4096;
|
|
2312
|
+
var MAX_REJECT_REASON_LENGTH = 4096;
|
|
2313
|
+
function toolCallId(claimed) {
|
|
2314
|
+
if (typeof claimed !== "string" || claimed.length === 0) {
|
|
2315
|
+
throw new BadRequestException4("toolCallId must be a non-empty string");
|
|
2316
|
+
}
|
|
2317
|
+
return claimed;
|
|
2318
|
+
}
|
|
2319
|
+
__name(toolCallId, "toolCallId");
|
|
2320
|
+
function rejectReason(claimed) {
|
|
2321
|
+
if (claimed === void 0) {
|
|
2322
|
+
return void 0;
|
|
2323
|
+
}
|
|
2324
|
+
if (typeof claimed !== "string") {
|
|
2325
|
+
throw new BadRequestException4("reason must be a string");
|
|
2326
|
+
}
|
|
2327
|
+
if (claimed.length > MAX_REJECT_REASON_LENGTH) {
|
|
2328
|
+
throw new BadRequestException4(`reason must be at most ${MAX_REJECT_REASON_LENGTH} characters`);
|
|
2329
|
+
}
|
|
2330
|
+
return claimed;
|
|
2331
|
+
}
|
|
2332
|
+
__name(rejectReason, "rejectReason");
|
|
2333
|
+
function answers(claimed) {
|
|
2334
|
+
if (claimed === void 0) {
|
|
2335
|
+
return void 0;
|
|
2336
|
+
}
|
|
2337
|
+
if (typeof claimed !== "object" || claimed === null || Array.isArray(claimed)) {
|
|
2338
|
+
throw new BadRequestException4("answers must be an object of questionId \u2192 chosen values");
|
|
2339
|
+
}
|
|
2340
|
+
const entries = Object.entries(claimed);
|
|
2341
|
+
if (entries.length > MAX_ANSWERED_QUESTIONS) {
|
|
2342
|
+
throw new BadRequestException4(`answers may cover at most ${MAX_ANSWERED_QUESTIONS} questions`);
|
|
2343
|
+
}
|
|
2344
|
+
const validated = /* @__PURE__ */ Object.create(null);
|
|
2345
|
+
for (const [questionId, values] of entries) {
|
|
2346
|
+
if (!Array.isArray(values)) {
|
|
2347
|
+
throw new BadRequestException4(`answers["${questionId}"] must be an array of chosen values`);
|
|
2348
|
+
}
|
|
2349
|
+
if (values.length > MAX_VALUES_PER_QUESTION) {
|
|
2350
|
+
throw new BadRequestException4(`answers["${questionId}"] may carry at most ${MAX_VALUES_PER_QUESTION} values`);
|
|
2351
|
+
}
|
|
2352
|
+
for (const value of values) {
|
|
2353
|
+
if (typeof value !== "string") {
|
|
2354
|
+
throw new BadRequestException4(`answers["${questionId}"] must contain only strings`);
|
|
2355
|
+
}
|
|
2356
|
+
if (value.length > MAX_ANSWER_VALUE_LENGTH) {
|
|
2357
|
+
throw new BadRequestException4(`answers["${questionId}"] values must be at most ${MAX_ANSWER_VALUE_LENGTH} characters`);
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
validated[questionId] = values;
|
|
2361
|
+
}
|
|
2362
|
+
return validated;
|
|
2363
|
+
}
|
|
2364
|
+
__name(answers, "answers");
|
|
1606
2365
|
var ToolCallController = class {
|
|
1607
2366
|
static {
|
|
1608
2367
|
__name(this, "ToolCallController");
|
|
@@ -1615,46 +2374,88 @@ var ToolCallController = class {
|
|
|
1615
2374
|
}
|
|
1616
2375
|
async approve(req, body) {
|
|
1617
2376
|
const actor = await this.actorResolver.resolve(req);
|
|
1618
|
-
await this.agent.approve(actor, body.toolCallId);
|
|
2377
|
+
await this.agent.approve(actor, toolCallId(body.toolCallId));
|
|
1619
2378
|
return {
|
|
1620
2379
|
ok: true
|
|
1621
2380
|
};
|
|
1622
2381
|
}
|
|
1623
2382
|
async reject(req, body) {
|
|
1624
2383
|
const actor = await this.actorResolver.resolve(req);
|
|
1625
|
-
await this.agent.reject(actor, body.toolCallId, body.reason);
|
|
2384
|
+
await this.agent.reject(actor, toolCallId(body.toolCallId), rejectReason(body.reason));
|
|
2385
|
+
return {
|
|
2386
|
+
ok: true
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2389
|
+
/**
|
|
2390
|
+
* Settle a parked question set. Alongside `approve`/`reject` rather than under a surface of its
|
|
2391
|
+
* own: an elicitation IS a parked tool call, gated by the same ownership check and delivered
|
|
2392
|
+
* through the same signal.
|
|
2393
|
+
*/
|
|
2394
|
+
async answer(req, body) {
|
|
2395
|
+
const actor = await this.actorResolver.resolve(req);
|
|
2396
|
+
await this.agent.answer(actor, toolCallId(body.toolCallId), answers(body.answers));
|
|
2397
|
+
return {
|
|
2398
|
+
ok: true
|
|
2399
|
+
};
|
|
2400
|
+
}
|
|
2401
|
+
/** Decline to answer and let the agent proceed on the answers it pre-picked. */
|
|
2402
|
+
async skip(req, body) {
|
|
2403
|
+
const actor = await this.actorResolver.resolve(req);
|
|
2404
|
+
await this.agent.skip(actor, toolCallId(body.toolCallId));
|
|
1626
2405
|
return {
|
|
1627
2406
|
ok: true
|
|
1628
2407
|
};
|
|
1629
2408
|
}
|
|
1630
2409
|
};
|
|
1631
|
-
|
|
2410
|
+
_ts_decorate15([
|
|
1632
2411
|
Post4("approve"),
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
2412
|
+
_ts_param13(0, Req7()),
|
|
2413
|
+
_ts_param13(1, Body3()),
|
|
2414
|
+
_ts_metadata14("design:type", Function),
|
|
2415
|
+
_ts_metadata14("design:paramtypes", [
|
|
1637
2416
|
typeof Request === "undefined" ? Object : Request,
|
|
1638
2417
|
typeof ApproveBody === "undefined" ? Object : ApproveBody
|
|
1639
2418
|
]),
|
|
1640
|
-
|
|
2419
|
+
_ts_metadata14("design:returntype", Promise)
|
|
1641
2420
|
], ToolCallController.prototype, "approve", null);
|
|
1642
|
-
|
|
2421
|
+
_ts_decorate15([
|
|
1643
2422
|
Post4("reject"),
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
2423
|
+
_ts_param13(0, Req7()),
|
|
2424
|
+
_ts_param13(1, Body3()),
|
|
2425
|
+
_ts_metadata14("design:type", Function),
|
|
2426
|
+
_ts_metadata14("design:paramtypes", [
|
|
1648
2427
|
typeof Request === "undefined" ? Object : Request,
|
|
1649
2428
|
typeof RejectBody === "undefined" ? Object : RejectBody
|
|
1650
2429
|
]),
|
|
1651
|
-
|
|
2430
|
+
_ts_metadata14("design:returntype", Promise)
|
|
1652
2431
|
], ToolCallController.prototype, "reject", null);
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
2432
|
+
_ts_decorate15([
|
|
2433
|
+
Post4("answer"),
|
|
2434
|
+
_ts_param13(0, Req7()),
|
|
2435
|
+
_ts_param13(1, Body3()),
|
|
2436
|
+
_ts_metadata14("design:type", Function),
|
|
2437
|
+
_ts_metadata14("design:paramtypes", [
|
|
2438
|
+
typeof Request === "undefined" ? Object : Request,
|
|
2439
|
+
typeof AnswerBody === "undefined" ? Object : AnswerBody
|
|
2440
|
+
]),
|
|
2441
|
+
_ts_metadata14("design:returntype", Promise)
|
|
2442
|
+
], ToolCallController.prototype, "answer", null);
|
|
2443
|
+
_ts_decorate15([
|
|
2444
|
+
Post4("skip"),
|
|
2445
|
+
_ts_param13(0, Req7()),
|
|
2446
|
+
_ts_param13(1, Body3()),
|
|
2447
|
+
_ts_metadata14("design:type", Function),
|
|
2448
|
+
_ts_metadata14("design:paramtypes", [
|
|
2449
|
+
typeof Request === "undefined" ? Object : Request,
|
|
2450
|
+
typeof ApproveBody === "undefined" ? Object : ApproveBody
|
|
2451
|
+
]),
|
|
2452
|
+
_ts_metadata14("design:returntype", Promise)
|
|
2453
|
+
], ToolCallController.prototype, "skip", null);
|
|
2454
|
+
ToolCallController = _ts_decorate15([
|
|
2455
|
+
Controller8("tool-call"),
|
|
2456
|
+
_ts_param13(1, Inject13(AGENT_ACTOR_RESOLVER7)),
|
|
2457
|
+
_ts_metadata14("design:type", Function),
|
|
2458
|
+
_ts_metadata14("design:paramtypes", [
|
|
1658
2459
|
typeof AgentService === "undefined" ? Object : AgentService,
|
|
1659
2460
|
typeof ActorResolver === "undefined" ? Object : ActorResolver
|
|
1660
2461
|
])
|
|
@@ -1662,7 +2463,7 @@ ToolCallController = _ts_decorate13([
|
|
|
1662
2463
|
|
|
1663
2464
|
// src/discovery/agent-discovery.service.ts
|
|
1664
2465
|
import { AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS2, AGENT_REGISTRY as AGENT_REGISTRY3, AgentRegistry as AgentRegistry4 } from "@dudousxd/nestjs-agent-core";
|
|
1665
|
-
import { Inject as
|
|
2466
|
+
import { Inject as Inject14, Injectable as Injectable7, Logger as Logger3 } from "@nestjs/common";
|
|
1666
2467
|
import { DiscoveryService, MetadataScanner } from "@nestjs/core";
|
|
1667
2468
|
|
|
1668
2469
|
// src/decorator/agent.decorator.ts
|
|
@@ -1679,23 +2480,23 @@ var SYSTEM_PROMPT_METADATA = Symbol.for("@dudousxd/nestjs-agent:system-prompt");
|
|
|
1679
2480
|
var SYSTEM_PROMPT_CONTRIBUTOR_METADATA = Symbol.for("@dudousxd/nestjs-agent:system-prompt-contributor");
|
|
1680
2481
|
|
|
1681
2482
|
// src/discovery/agent-discovery.service.ts
|
|
1682
|
-
function
|
|
2483
|
+
function _ts_decorate16(decorators, target, key, desc) {
|
|
1683
2484
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1684
2485
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1685
2486
|
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;
|
|
1686
2487
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1687
2488
|
}
|
|
1688
|
-
__name(
|
|
1689
|
-
function
|
|
2489
|
+
__name(_ts_decorate16, "_ts_decorate");
|
|
2490
|
+
function _ts_metadata15(k, v) {
|
|
1690
2491
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1691
2492
|
}
|
|
1692
|
-
__name(
|
|
1693
|
-
function
|
|
2493
|
+
__name(_ts_metadata15, "_ts_metadata");
|
|
2494
|
+
function _ts_param14(paramIndex, decorator) {
|
|
1694
2495
|
return function(target, key) {
|
|
1695
2496
|
decorator(target, key, paramIndex);
|
|
1696
2497
|
};
|
|
1697
2498
|
}
|
|
1698
|
-
__name(
|
|
2499
|
+
__name(_ts_param14, "_ts_param");
|
|
1699
2500
|
var AgentDiscoveryService = class _AgentDiscoveryService {
|
|
1700
2501
|
static {
|
|
1701
2502
|
__name(this, "AgentDiscoveryService");
|
|
@@ -1704,7 +2505,7 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
|
|
|
1704
2505
|
scanner;
|
|
1705
2506
|
registry;
|
|
1706
2507
|
contributors;
|
|
1707
|
-
logger = new
|
|
2508
|
+
logger = new Logger3(_AgentDiscoveryService.name);
|
|
1708
2509
|
constructor(discovery, scanner, registry, contributors) {
|
|
1709
2510
|
this.discovery = discovery;
|
|
1710
2511
|
this.scanner = scanner;
|
|
@@ -1743,23 +2544,53 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
|
|
|
1743
2544
|
...meta.maxSteps !== void 0 ? {
|
|
1744
2545
|
maxSteps: meta.maxSteps
|
|
1745
2546
|
} : {},
|
|
2547
|
+
...meta.maxDelegationDepth !== void 0 ? {
|
|
2548
|
+
maxDelegationDepth: meta.maxDelegationDepth
|
|
2549
|
+
} : {},
|
|
2550
|
+
...meta.maxAgentAppearances !== void 0 ? {
|
|
2551
|
+
maxAgentAppearances: meta.maxAgentAppearances
|
|
2552
|
+
} : {},
|
|
2553
|
+
...meta.history !== void 0 ? {
|
|
2554
|
+
history: meta.history
|
|
2555
|
+
} : {},
|
|
2556
|
+
...meta.outputSchema !== void 0 ? {
|
|
2557
|
+
outputSchema: meta.outputSchema
|
|
2558
|
+
} : {},
|
|
2559
|
+
...meta.intake !== void 0 ? {
|
|
2560
|
+
intake: meta.intake
|
|
2561
|
+
} : {},
|
|
2562
|
+
...meta.ask !== void 0 ? {
|
|
2563
|
+
ask: meta.ask
|
|
2564
|
+
} : {},
|
|
2565
|
+
...meta.outputRepairAttempts !== void 0 ? {
|
|
2566
|
+
outputRepairAttempts: meta.outputRepairAttempts
|
|
2567
|
+
} : {},
|
|
1746
2568
|
...meta.handoff !== void 0 ? {
|
|
1747
|
-
delegatesTo: this.
|
|
2569
|
+
delegatesTo: this.handoffEdges(meta)
|
|
1748
2570
|
} : {}
|
|
1749
2571
|
};
|
|
1750
2572
|
}
|
|
1751
|
-
/**
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
2573
|
+
/**
|
|
2574
|
+
* Resolve each handoff entry to an {@link AgentDelegation} — its target's registered name, plus
|
|
2575
|
+
* whether that edge detaches (skipping non-agent classes). A bare name is kept for a plain edge
|
|
2576
|
+
* rather than an always-object form, so a definition an older host built by hand still reads.
|
|
2577
|
+
*/
|
|
2578
|
+
handoffEdges(meta) {
|
|
2579
|
+
const edges = [];
|
|
2580
|
+
for (const entry of meta.handoff ?? []) {
|
|
2581
|
+
const target = typeof entry === "function" ? entry : entry.agent;
|
|
2582
|
+
const detached = typeof entry === "function" ? false : entry.detached === true;
|
|
1755
2583
|
const targetMeta = readAgentMetadata(target);
|
|
1756
2584
|
if (targetMeta === void 0) {
|
|
1757
2585
|
this.logger.warn(`Agent "${meta.name}" hands off to ${target.name}, which is not an @Agent \u2014 skipped.`);
|
|
1758
2586
|
continue;
|
|
1759
2587
|
}
|
|
1760
|
-
|
|
2588
|
+
edges.push(detached ? {
|
|
2589
|
+
agent: targetMeta.name,
|
|
2590
|
+
detached: true
|
|
2591
|
+
} : targetMeta.name);
|
|
1761
2592
|
}
|
|
1762
|
-
return
|
|
2593
|
+
return edges;
|
|
1763
2594
|
}
|
|
1764
2595
|
/** Push every `@SystemPromptContributor()` method on `instance` (bound) into the contributor list. */
|
|
1765
2596
|
collectContributors(instance) {
|
|
@@ -1792,12 +2623,12 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
|
|
|
1792
2623
|
return (ctx) => candidate.call(instance, ctx);
|
|
1793
2624
|
}
|
|
1794
2625
|
};
|
|
1795
|
-
AgentDiscoveryService =
|
|
2626
|
+
AgentDiscoveryService = _ts_decorate16([
|
|
1796
2627
|
Injectable7(),
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
2628
|
+
_ts_param14(2, Inject14(AGENT_REGISTRY3)),
|
|
2629
|
+
_ts_param14(3, Inject14(AGENT_PROMPT_CONTRIBUTORS2)),
|
|
2630
|
+
_ts_metadata15("design:type", Function),
|
|
2631
|
+
_ts_metadata15("design:paramtypes", [
|
|
1801
2632
|
typeof DiscoveryService === "undefined" ? Object : DiscoveryService,
|
|
1802
2633
|
typeof MetadataScanner === "undefined" ? Object : MetadataScanner,
|
|
1803
2634
|
typeof AgentRegistry4 === "undefined" ? Object : AgentRegistry4,
|
|
@@ -1806,8 +2637,8 @@ AgentDiscoveryService = _ts_decorate14([
|
|
|
1806
2637
|
], AgentDiscoveryService);
|
|
1807
2638
|
|
|
1808
2639
|
// src/discovery/ai-tool-discovery.service.ts
|
|
1809
|
-
import { AGENT_OPTIONS as AGENT_OPTIONS4, AGENT_REGISTRY as AGENT_REGISTRY4, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY2 } from "@dudousxd/nestjs-agent-core";
|
|
1810
|
-
import { Inject as
|
|
2640
|
+
import { AGENT_OPTIONS as AGENT_OPTIONS4, AGENT_REGISTRY as AGENT_REGISTRY4, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY2, normalizeDelegation as normalizeDelegation2 } from "@dudousxd/nestjs-agent-core";
|
|
2641
|
+
import { Inject as Inject15, Injectable as Injectable8, Logger as Logger4 } from "@nestjs/common";
|
|
1811
2642
|
import { DiscoveryService as DiscoveryService2 } from "@nestjs/core";
|
|
1812
2643
|
import { z } from "zod";
|
|
1813
2644
|
|
|
@@ -1827,23 +2658,23 @@ function isBrandedFunctionalTool(value) {
|
|
|
1827
2658
|
__name(isBrandedFunctionalTool, "isBrandedFunctionalTool");
|
|
1828
2659
|
|
|
1829
2660
|
// src/discovery/ai-tool-discovery.service.ts
|
|
1830
|
-
function
|
|
2661
|
+
function _ts_decorate17(decorators, target, key, desc) {
|
|
1831
2662
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1832
2663
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1833
2664
|
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;
|
|
1834
2665
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1835
2666
|
}
|
|
1836
|
-
__name(
|
|
1837
|
-
function
|
|
2667
|
+
__name(_ts_decorate17, "_ts_decorate");
|
|
2668
|
+
function _ts_metadata16(k, v) {
|
|
1838
2669
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1839
2670
|
}
|
|
1840
|
-
__name(
|
|
1841
|
-
function
|
|
2671
|
+
__name(_ts_metadata16, "_ts_metadata");
|
|
2672
|
+
function _ts_param15(paramIndex, decorator) {
|
|
1842
2673
|
return function(target, key) {
|
|
1843
2674
|
decorator(target, key, paramIndex);
|
|
1844
2675
|
};
|
|
1845
2676
|
}
|
|
1846
|
-
__name(
|
|
2677
|
+
__name(_ts_param15, "_ts_param");
|
|
1847
2678
|
var AiToolDiscoveryService = class _AiToolDiscoveryService {
|
|
1848
2679
|
static {
|
|
1849
2680
|
__name(this, "AiToolDiscoveryService");
|
|
@@ -1852,7 +2683,7 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
|
|
|
1852
2683
|
registry;
|
|
1853
2684
|
agents;
|
|
1854
2685
|
options;
|
|
1855
|
-
logger = new
|
|
2686
|
+
logger = new Logger4(_AiToolDiscoveryService.name);
|
|
1856
2687
|
constructor(discovery, registry, agents, options) {
|
|
1857
2688
|
this.discovery = discovery;
|
|
1858
2689
|
this.registry = registry;
|
|
@@ -1919,22 +2750,30 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
|
|
|
1919
2750
|
}
|
|
1920
2751
|
let delegates = 0;
|
|
1921
2752
|
for (const definition of this.agents.list()) {
|
|
1922
|
-
for (const
|
|
2753
|
+
for (const edge of definition.delegatesTo ?? []) {
|
|
2754
|
+
const { agent: target, detached } = normalizeDelegation2(edge);
|
|
1923
2755
|
const targetDefinition = this.agents.get(target);
|
|
1924
2756
|
if (targetDefinition === void 0) {
|
|
1925
2757
|
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.`);
|
|
1926
2758
|
}
|
|
1927
|
-
const name = delegateToolName(
|
|
2759
|
+
const name = delegateToolName({
|
|
2760
|
+
target,
|
|
2761
|
+
detached
|
|
2762
|
+
});
|
|
1928
2763
|
if (this.registry.has(name)) {
|
|
1929
2764
|
continue;
|
|
1930
2765
|
}
|
|
1931
2766
|
const targetBlurb = typeof targetDefinition.systemPrompt === "string" ? ` It is: ${targetDefinition.systemPrompt}` : "";
|
|
2767
|
+
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}`;
|
|
1932
2768
|
this.registry.register(
|
|
1933
2769
|
{
|
|
1934
2770
|
name,
|
|
1935
2771
|
kind: "agent",
|
|
1936
2772
|
targetAgent: target,
|
|
1937
|
-
|
|
2773
|
+
...detached ? {
|
|
2774
|
+
detached: true
|
|
2775
|
+
} : {},
|
|
2776
|
+
description,
|
|
1938
2777
|
inputSchema: z.object({
|
|
1939
2778
|
task: z.string()
|
|
1940
2779
|
})
|
|
@@ -1962,13 +2801,13 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
|
|
|
1962
2801
|
return true;
|
|
1963
2802
|
}
|
|
1964
2803
|
};
|
|
1965
|
-
AiToolDiscoveryService =
|
|
2804
|
+
AiToolDiscoveryService = _ts_decorate17([
|
|
1966
2805
|
Injectable8(),
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
2806
|
+
_ts_param15(1, Inject15(AGENT_TOOL_REGISTRY2)),
|
|
2807
|
+
_ts_param15(2, Inject15(AGENT_REGISTRY4)),
|
|
2808
|
+
_ts_param15(3, Inject15(AGENT_OPTIONS4)),
|
|
2809
|
+
_ts_metadata16("design:type", Function),
|
|
2810
|
+
_ts_metadata16("design:paramtypes", [
|
|
1972
2811
|
typeof DiscoveryService2 === "undefined" ? Object : DiscoveryService2,
|
|
1973
2812
|
typeof ToolRegistry === "undefined" ? Object : ToolRegistry,
|
|
1974
2813
|
typeof AgentRegistry === "undefined" ? Object : AgentRegistry,
|
|
@@ -1976,6 +2815,95 @@ AiToolDiscoveryService = _ts_decorate15([
|
|
|
1976
2815
|
])
|
|
1977
2816
|
], AiToolDiscoveryService);
|
|
1978
2817
|
|
|
2818
|
+
// src/discovery/skill-discovery.service.ts
|
|
2819
|
+
import { AGENT_SKILL_SOURCES } from "@dudousxd/nestjs-agent-core";
|
|
2820
|
+
import { Inject as Inject16, Injectable as Injectable9, Logger as Logger5 } from "@nestjs/common";
|
|
2821
|
+
import { DiscoveryService as DiscoveryService3 } from "@nestjs/core";
|
|
2822
|
+
|
|
2823
|
+
// src/decorator/skill.decorator.ts
|
|
2824
|
+
import "reflect-metadata";
|
|
2825
|
+
import { GLOBAL_SCOPE } from "@dudousxd/nestjs-agent-core";
|
|
2826
|
+
var SKILL_METADATA = Symbol.for("@dudousxd/nestjs-agent:skill-metadata");
|
|
2827
|
+
function readSkillMetadata(target) {
|
|
2828
|
+
return Reflect.getMetadata(SKILL_METADATA, target);
|
|
2829
|
+
}
|
|
2830
|
+
__name(readSkillMetadata, "readSkillMetadata");
|
|
2831
|
+
function skillScope(options) {
|
|
2832
|
+
return options.scope ?? GLOBAL_SCOPE;
|
|
2833
|
+
}
|
|
2834
|
+
__name(skillScope, "skillScope");
|
|
2835
|
+
|
|
2836
|
+
// src/discovery/skill-discovery.service.ts
|
|
2837
|
+
function _ts_decorate18(decorators, target, key, desc) {
|
|
2838
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2839
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2840
|
+
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;
|
|
2841
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2842
|
+
}
|
|
2843
|
+
__name(_ts_decorate18, "_ts_decorate");
|
|
2844
|
+
function _ts_metadata17(k, v) {
|
|
2845
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2846
|
+
}
|
|
2847
|
+
__name(_ts_metadata17, "_ts_metadata");
|
|
2848
|
+
function _ts_param16(paramIndex, decorator) {
|
|
2849
|
+
return function(target, key) {
|
|
2850
|
+
decorator(target, key, paramIndex);
|
|
2851
|
+
};
|
|
2852
|
+
}
|
|
2853
|
+
__name(_ts_param16, "_ts_param");
|
|
2854
|
+
var SkillDiscoveryService = class _SkillDiscoveryService {
|
|
2855
|
+
static {
|
|
2856
|
+
__name(this, "SkillDiscoveryService");
|
|
2857
|
+
}
|
|
2858
|
+
discovery;
|
|
2859
|
+
declared;
|
|
2860
|
+
logger = new Logger5(_SkillDiscoveryService.name);
|
|
2861
|
+
constructor(discovery, declared) {
|
|
2862
|
+
this.discovery = discovery;
|
|
2863
|
+
this.declared = declared;
|
|
2864
|
+
}
|
|
2865
|
+
onModuleInit() {
|
|
2866
|
+
for (const wrapper of this.discovery.getProviders()) {
|
|
2867
|
+
const instance = wrapper.instance;
|
|
2868
|
+
if (instance === null || typeof instance !== "object") {
|
|
2869
|
+
continue;
|
|
2870
|
+
}
|
|
2871
|
+
const meta = readSkillMetadata(instance.constructor);
|
|
2872
|
+
if (meta === void 0) {
|
|
2873
|
+
continue;
|
|
2874
|
+
}
|
|
2875
|
+
const body = this.bodyOf(instance, meta.body);
|
|
2876
|
+
if (body === void 0) {
|
|
2877
|
+
this.logger.warn(`Skill "${meta.name}" declares no body \u2014 add a \`body()\` method or \`@Skill({ body })\`. Skipped.`);
|
|
2878
|
+
continue;
|
|
2879
|
+
}
|
|
2880
|
+
this.declared.push({
|
|
2881
|
+
name: meta.name,
|
|
2882
|
+
description: meta.description,
|
|
2883
|
+
scope: skillScope(meta),
|
|
2884
|
+
body
|
|
2885
|
+
});
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
/** The instance's `body()` method (bound), else the flat string, else nothing to offer. */
|
|
2889
|
+
bodyOf(instance, flat) {
|
|
2890
|
+
const candidate = instance.body;
|
|
2891
|
+
if (typeof candidate === "function") {
|
|
2892
|
+
return (ctx) => candidate.call(instance, ctx);
|
|
2893
|
+
}
|
|
2894
|
+
return flat === void 0 ? void 0 : () => flat;
|
|
2895
|
+
}
|
|
2896
|
+
};
|
|
2897
|
+
SkillDiscoveryService = _ts_decorate18([
|
|
2898
|
+
Injectable9(),
|
|
2899
|
+
_ts_param16(1, Inject16(AGENT_SKILL_SOURCES)),
|
|
2900
|
+
_ts_metadata17("design:type", Function),
|
|
2901
|
+
_ts_metadata17("design:paramtypes", [
|
|
2902
|
+
typeof DiscoveryService3 === "undefined" ? Object : DiscoveryService3,
|
|
2903
|
+
Array
|
|
2904
|
+
])
|
|
2905
|
+
], SkillDiscoveryService);
|
|
2906
|
+
|
|
1979
2907
|
// src/ledger-quota-store.ts
|
|
1980
2908
|
var LedgerQuotaStore = class {
|
|
1981
2909
|
static {
|
|
@@ -1995,38 +2923,44 @@ var LedgerQuotaStore = class {
|
|
|
1995
2923
|
withinLimit: usedTokens < this.limitTokens
|
|
1996
2924
|
};
|
|
1997
2925
|
}
|
|
1998
|
-
async bump() {
|
|
2926
|
+
async bump(_actorRef, _day, _tokens) {
|
|
1999
2927
|
}
|
|
2000
2928
|
};
|
|
2001
2929
|
|
|
2002
2930
|
// src/runner/inline-agent-runner.ts
|
|
2003
|
-
import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY5, AGENT_STORE as
|
|
2004
|
-
import { Inject as
|
|
2005
|
-
function
|
|
2931
|
+
import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY5, AGENT_STORE as AGENT_STORE5, RunCancelledError as RunCancelledError2, agentFailureCode as agentFailureCode2, encodeStreamEvent as encodeStreamEvent2, publishAgentRunFailed as publishAgentRunFailed2, runAgentLoop as runAgentLoop2, settleAll as settleAll2, settleUnsettledDelegation as settleUnsettledDelegation2 } from "@dudousxd/nestjs-agent-core";
|
|
2932
|
+
import { Inject as Inject17, Injectable as Injectable10, Logger as Logger6 } from "@nestjs/common";
|
|
2933
|
+
function _ts_decorate19(decorators, target, key, desc) {
|
|
2006
2934
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2007
2935
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2008
2936
|
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;
|
|
2009
2937
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2010
2938
|
}
|
|
2011
|
-
__name(
|
|
2012
|
-
function
|
|
2939
|
+
__name(_ts_decorate19, "_ts_decorate");
|
|
2940
|
+
function _ts_metadata18(k, v) {
|
|
2013
2941
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
2014
2942
|
}
|
|
2015
|
-
__name(
|
|
2016
|
-
function
|
|
2943
|
+
__name(_ts_metadata18, "_ts_metadata");
|
|
2944
|
+
function _ts_param17(paramIndex, decorator) {
|
|
2017
2945
|
return function(target, key) {
|
|
2018
2946
|
decorator(target, key, paramIndex);
|
|
2019
2947
|
};
|
|
2020
2948
|
}
|
|
2021
|
-
__name(
|
|
2949
|
+
__name(_ts_param17, "_ts_param");
|
|
2022
2950
|
var InlineAgentRunner = class _InlineAgentRunner {
|
|
2023
2951
|
static {
|
|
2024
2952
|
__name(this, "InlineAgentRunner");
|
|
2025
2953
|
}
|
|
2026
2954
|
factory;
|
|
2027
2955
|
store;
|
|
2028
|
-
logger = new
|
|
2956
|
+
logger = new Logger6(_InlineAgentRunner.name);
|
|
2029
2957
|
pending = /* @__PURE__ */ new Map();
|
|
2958
|
+
/**
|
|
2959
|
+
* Runs someone has asked to stop. In-process, like `pending`, and for the same reason: this runner
|
|
2960
|
+
* is single-replica by construction, so the request is readable by the only loop that could be
|
|
2961
|
+
* running it. A cancelled id is dropped once the run settles, so the set tracks live runs only.
|
|
2962
|
+
*/
|
|
2963
|
+
cancelled = /* @__PURE__ */ new Set();
|
|
2030
2964
|
constructor(factory, store) {
|
|
2031
2965
|
this.factory = factory;
|
|
2032
2966
|
this.store = store;
|
|
@@ -2035,13 +2969,29 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
2035
2969
|
const runId = crypto.randomUUID();
|
|
2036
2970
|
const day = input.day ?? utcDay();
|
|
2037
2971
|
const deps = this.factory.forAgent(input.agentName);
|
|
2038
|
-
const hooks = this.topLevelHooks(
|
|
2972
|
+
const hooks = this.topLevelHooks({
|
|
2973
|
+
runId,
|
|
2974
|
+
deps,
|
|
2975
|
+
actor: input.actor,
|
|
2976
|
+
day,
|
|
2977
|
+
threadId: input.threadId,
|
|
2978
|
+
chainBelow: [
|
|
2979
|
+
...input.delegationPath ?? [],
|
|
2980
|
+
...input.agentName !== void 0 ? [
|
|
2981
|
+
input.agentName
|
|
2982
|
+
] : []
|
|
2983
|
+
]
|
|
2984
|
+
});
|
|
2039
2985
|
void runAgentLoop2({
|
|
2040
2986
|
...deps,
|
|
2041
2987
|
day
|
|
2042
2988
|
}, input, hooks).then(() => this.store.setActiveStream(input.threadId, null)).catch(async (error) => {
|
|
2989
|
+
if (error instanceof RunCancelledError2) {
|
|
2990
|
+
await this.settleCancelled(runId, input.threadId, deps);
|
|
2991
|
+
return;
|
|
2992
|
+
}
|
|
2043
2993
|
const message = error instanceof Error ? error.message : String(error);
|
|
2044
|
-
const code = error
|
|
2994
|
+
const code = agentFailureCode2(error);
|
|
2045
2995
|
this.logger.error(`agent run ${runId} failed (${code}): ${message}`);
|
|
2046
2996
|
publishAgentRunFailed2({
|
|
2047
2997
|
runId,
|
|
@@ -2060,33 +3010,216 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
2060
3010
|
code,
|
|
2061
3011
|
message
|
|
2062
3012
|
});
|
|
2063
|
-
});
|
|
3013
|
+
}).finally(() => this.cancelled.delete(runId));
|
|
2064
3014
|
return {
|
|
2065
3015
|
runId
|
|
2066
3016
|
};
|
|
2067
3017
|
}
|
|
2068
|
-
async signal(runId,
|
|
2069
|
-
const key = `${runId}:${
|
|
2070
|
-
const
|
|
2071
|
-
if (
|
|
3018
|
+
async signal(runId, toolCallId2, reply) {
|
|
3019
|
+
const key = `${runId}:${toolCallId2}`;
|
|
3020
|
+
const waiter = this.pending.get(key);
|
|
3021
|
+
if (waiter !== void 0) {
|
|
2072
3022
|
this.pending.delete(key);
|
|
2073
|
-
resolve(
|
|
3023
|
+
waiter.resolve(reply);
|
|
2074
3024
|
}
|
|
2075
3025
|
}
|
|
3026
|
+
/**
|
|
3027
|
+
* Ask a run to stop, and settle whatever it was parked on.
|
|
3028
|
+
*
|
|
3029
|
+
* The loop observes the request at its next safe point (between steps, before the turn's tools) and
|
|
3030
|
+
* unwinds from there — so a tool already executing is left to finish, and its result is recorded
|
|
3031
|
+
* exactly as it would have been. What this cannot wait for is a turn parked on a human: that wait
|
|
3032
|
+
* is a promise nobody is going to resolve, so it is REJECTED here with the same
|
|
3033
|
+
* {@link RunCancelledError} the loop would have thrown, and the run unwinds through the identical
|
|
3034
|
+
* path.
|
|
3035
|
+
*
|
|
3036
|
+
* Settlement — the run row, the thread's active stream, the stream's terminal — belongs to the
|
|
3037
|
+
* `RunCancelledError` catch in `start`, so a cancel and an ordinary failure settle in one place
|
|
3038
|
+
* each and can never both write.
|
|
3039
|
+
*/
|
|
2076
3040
|
async cancel(runId) {
|
|
2077
|
-
|
|
3041
|
+
this.cancelled.add(runId);
|
|
3042
|
+
for (const [key, waiter] of this.pending) {
|
|
3043
|
+
if (key.startsWith(`${runId}:`)) {
|
|
3044
|
+
this.pending.delete(key);
|
|
3045
|
+
waiter.reject(new RunCancelledError2());
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
3048
|
+
await Promise.resolve();
|
|
3049
|
+
}
|
|
3050
|
+
/**
|
|
3051
|
+
* The single place a cancelled run's state is settled: recorded as its own terminal (never
|
|
3052
|
+
* `failed` — a user pressing Stop must not land in someone's error rate), the thread released, and
|
|
3053
|
+
* the stream ENDED after a `cancelled` frame rather than failed, so a client that retries failed
|
|
3054
|
+
* streams does not retry this one.
|
|
3055
|
+
*/
|
|
3056
|
+
async settleCancelled(runId, threadId, deps) {
|
|
3057
|
+
this.logger.log(`agent run ${runId} cancelled`);
|
|
3058
|
+
await this.store.setActiveStream(threadId, null);
|
|
2078
3059
|
const writer = await deps.sink.open(runId);
|
|
3060
|
+
await writer.write(encodeStreamEvent2({
|
|
3061
|
+
kind: "cancelled"
|
|
3062
|
+
}));
|
|
2079
3063
|
await writer.end();
|
|
3064
|
+
await this.store.recordRunEnd?.({
|
|
3065
|
+
runId,
|
|
3066
|
+
status: "cancelled"
|
|
3067
|
+
});
|
|
3068
|
+
}
|
|
3069
|
+
/**
|
|
3070
|
+
* Park a run on a human, keyed by run + tool call. One map for approvals and for question-set
|
|
3071
|
+
* answers alike: both wait on the same key, and `signal` cannot tell (or need to tell) which
|
|
3072
|
+
* shape it is delivering — the loop asked for one and only ever gets what the caller sent. A
|
|
3073
|
+
* cancel settles the wait too, by rejecting it.
|
|
3074
|
+
*/
|
|
3075
|
+
park(runId, toolCallId2) {
|
|
3076
|
+
return new Promise((resolve, reject) => {
|
|
3077
|
+
this.pending.set(`${runId}:${toolCallId2}`, {
|
|
3078
|
+
resolve,
|
|
3079
|
+
reject
|
|
3080
|
+
});
|
|
3081
|
+
});
|
|
2080
3082
|
}
|
|
2081
|
-
topLevelHooks(
|
|
3083
|
+
topLevelHooks(args) {
|
|
3084
|
+
const { runId, deps, actor, day, threadId, chainBelow } = args;
|
|
2082
3085
|
return {
|
|
2083
3086
|
runId,
|
|
2084
3087
|
openSink: /* @__PURE__ */ __name(() => deps.sink.open(runId), "openSink"),
|
|
2085
|
-
awaitApproval: /* @__PURE__ */ __name((call) =>
|
|
2086
|
-
|
|
2087
|
-
|
|
3088
|
+
awaitApproval: /* @__PURE__ */ __name((call) => this.park(runId, call.id), "awaitApproval"),
|
|
3089
|
+
awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
|
|
3090
|
+
step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
|
|
3091
|
+
parallel: settleAll2,
|
|
3092
|
+
cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId), "cancelled"),
|
|
3093
|
+
runAgent: /* @__PURE__ */ __name((agentName, task) => this.runNested({
|
|
3094
|
+
agentName,
|
|
3095
|
+
task,
|
|
3096
|
+
actor,
|
|
3097
|
+
day,
|
|
3098
|
+
depth: 1,
|
|
3099
|
+
path: chainBelow,
|
|
3100
|
+
sinkRunId: runId,
|
|
3101
|
+
parentRunId: runId
|
|
3102
|
+
}), "runAgent"),
|
|
3103
|
+
startAgent: /* @__PURE__ */ __name(({ agentName, task, toolCallId: toolCallId2 }) => this.startDetached({
|
|
3104
|
+
agentName,
|
|
3105
|
+
task,
|
|
3106
|
+
actor,
|
|
3107
|
+
day,
|
|
3108
|
+
depth: 1,
|
|
3109
|
+
path: chainBelow,
|
|
3110
|
+
parentRunId: runId,
|
|
3111
|
+
deliverTo: {
|
|
3112
|
+
threadId,
|
|
3113
|
+
toolCallId: toolCallId2
|
|
3114
|
+
}
|
|
3115
|
+
}), "startAgent")
|
|
3116
|
+
};
|
|
3117
|
+
}
|
|
3118
|
+
/**
|
|
3119
|
+
* Delegate WITHOUT waiting: a nested loop nobody awaits, on its own thread and its own sink, which
|
|
3120
|
+
* posts its answer back into the delegating thread when it lands (`deliverTo`, settled by the
|
|
3121
|
+
* loop). The calling turn gets the run id straight back and finishes.
|
|
3122
|
+
*
|
|
3123
|
+
* No `sinkRunId`, unlike {@link runNested}: forwarding into the stream the human is watching would
|
|
3124
|
+
* write into a turn that has already ended. Its own approvals resolve through the shared pending
|
|
3125
|
+
* map keyed by its own runId — which is what the pending-approvals surface routes to.
|
|
3126
|
+
*/
|
|
3127
|
+
async startDetached(args) {
|
|
3128
|
+
const { agentName, task, actor, day, depth, path, parentRunId, deliverTo } = args;
|
|
3129
|
+
const subThread = await this.store.createThread({
|
|
3130
|
+
actor,
|
|
3131
|
+
transient: true
|
|
3132
|
+
});
|
|
3133
|
+
const runId = crypto.randomUUID();
|
|
3134
|
+
await this.store.setActiveStream(subThread.id, runId);
|
|
3135
|
+
const deps = this.factory.forAgent(agentName);
|
|
3136
|
+
const hooks = {
|
|
3137
|
+
runId,
|
|
3138
|
+
openSink: /* @__PURE__ */ __name(() => deps.sink.open(runId), "openSink"),
|
|
3139
|
+
awaitApproval: /* @__PURE__ */ __name((call) => this.park(runId, call.id), "awaitApproval"),
|
|
3140
|
+
awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
|
|
2088
3141
|
step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
|
|
2089
|
-
|
|
3142
|
+
parallel: settleAll2,
|
|
3143
|
+
cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId), "cancelled"),
|
|
3144
|
+
runAgent: /* @__PURE__ */ __name((childName, childTask) => this.runNested({
|
|
3145
|
+
agentName: childName,
|
|
3146
|
+
task: childTask,
|
|
3147
|
+
actor,
|
|
3148
|
+
day,
|
|
3149
|
+
depth: depth + 1,
|
|
3150
|
+
path: [
|
|
3151
|
+
...path,
|
|
3152
|
+
agentName
|
|
3153
|
+
],
|
|
3154
|
+
// A detached run owns a stream of its own, so ITS sub-agents forward into that one.
|
|
3155
|
+
sinkRunId: runId,
|
|
3156
|
+
parentRunId: runId
|
|
3157
|
+
}), "runAgent"),
|
|
3158
|
+
startAgent: /* @__PURE__ */ __name(({ agentName: childName, task: childTask, toolCallId: toolCallId2 }) => this.startDetached({
|
|
3159
|
+
agentName: childName,
|
|
3160
|
+
task: childTask,
|
|
3161
|
+
actor,
|
|
3162
|
+
day,
|
|
3163
|
+
depth: depth + 1,
|
|
3164
|
+
path: [
|
|
3165
|
+
...path,
|
|
3166
|
+
agentName
|
|
3167
|
+
],
|
|
3168
|
+
parentRunId: runId,
|
|
3169
|
+
deliverTo: {
|
|
3170
|
+
threadId: subThread.id,
|
|
3171
|
+
toolCallId: toolCallId2
|
|
3172
|
+
}
|
|
3173
|
+
}), "startAgent")
|
|
3174
|
+
};
|
|
3175
|
+
void runAgentLoop2({
|
|
3176
|
+
...deps,
|
|
3177
|
+
day
|
|
3178
|
+
}, {
|
|
3179
|
+
threadId: subThread.id,
|
|
3180
|
+
actor,
|
|
3181
|
+
userText: task,
|
|
3182
|
+
agentName,
|
|
3183
|
+
day,
|
|
3184
|
+
delegationDepth: depth,
|
|
3185
|
+
delegationPath: path,
|
|
3186
|
+
parentRunId,
|
|
3187
|
+
deliverTo
|
|
3188
|
+
}, hooks).catch(async (error) => {
|
|
3189
|
+
const cancelled = error instanceof RunCancelledError2;
|
|
3190
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3191
|
+
if (!cancelled) {
|
|
3192
|
+
this.logger.error(`detached agent run ${runId} failed: ${message}`);
|
|
3193
|
+
publishAgentRunFailed2({
|
|
3194
|
+
runId,
|
|
3195
|
+
code: agentFailureCode2(error),
|
|
3196
|
+
message
|
|
3197
|
+
});
|
|
3198
|
+
}
|
|
3199
|
+
await this.store.recordRunEnd?.({
|
|
3200
|
+
runId,
|
|
3201
|
+
status: cancelled ? "cancelled" : "failed",
|
|
3202
|
+
...cancelled ? {} : {
|
|
3203
|
+
errorCode: agentFailureCode2(error),
|
|
3204
|
+
errorMessage: message
|
|
3205
|
+
}
|
|
3206
|
+
});
|
|
3207
|
+
await settleUnsettledDelegation2({
|
|
3208
|
+
store: this.store,
|
|
3209
|
+
delivery: deliverTo,
|
|
3210
|
+
agent: agentName,
|
|
3211
|
+
runId,
|
|
3212
|
+
status: cancelled ? "cancelled" : "failed",
|
|
3213
|
+
...cancelled ? {} : {
|
|
3214
|
+
error: message
|
|
3215
|
+
}
|
|
3216
|
+
});
|
|
3217
|
+
}).finally(async () => {
|
|
3218
|
+
this.cancelled.delete(runId);
|
|
3219
|
+
await this.store.setActiveStream(subThread.id, null);
|
|
3220
|
+
});
|
|
3221
|
+
return {
|
|
3222
|
+
runId
|
|
2090
3223
|
};
|
|
2091
3224
|
}
|
|
2092
3225
|
/**
|
|
@@ -2094,7 +3227,8 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
2094
3227
|
* (the top-level run the human is watching) so its output and any pending action tool are visible,
|
|
2095
3228
|
* and its own approvals resolve through the shared pending map keyed by its own runId.
|
|
2096
3229
|
*/
|
|
2097
|
-
async runNested(
|
|
3230
|
+
async runNested(args) {
|
|
3231
|
+
const { agentName, task, actor, day, depth, path, sinkRunId, parentRunId } = args;
|
|
2098
3232
|
const subThread = await this.store.createThread({
|
|
2099
3233
|
actor,
|
|
2100
3234
|
transient: true
|
|
@@ -2106,11 +3240,42 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
2106
3240
|
runId,
|
|
2107
3241
|
// Forward into the top-level stream; the top-level run owns end/fail on that shared sink.
|
|
2108
3242
|
openSink: /* @__PURE__ */ __name(async () => childSinkWriter(await deps.sink.open(sinkRunId)), "openSink"),
|
|
2109
|
-
awaitApproval: /* @__PURE__ */ __name((call) =>
|
|
2110
|
-
|
|
2111
|
-
}), "awaitApproval"),
|
|
3243
|
+
awaitApproval: /* @__PURE__ */ __name((call) => this.park(runId, call.id), "awaitApproval"),
|
|
3244
|
+
awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
|
|
2112
3245
|
step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
|
|
2113
|
-
|
|
3246
|
+
parallel: settleAll2,
|
|
3247
|
+
// A child stops when it is cancelled OR when the run a human is actually watching is: the
|
|
3248
|
+
// canceller names the top-level run, which is the only id that ever left the server.
|
|
3249
|
+
cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId) || this.cancelled.has(sinkRunId), "cancelled"),
|
|
3250
|
+
runAgent: /* @__PURE__ */ __name((childName, childTask) => this.runNested({
|
|
3251
|
+
agentName: childName,
|
|
3252
|
+
task: childTask,
|
|
3253
|
+
actor,
|
|
3254
|
+
day,
|
|
3255
|
+
depth: depth + 1,
|
|
3256
|
+
path: [
|
|
3257
|
+
...path,
|
|
3258
|
+
agentName
|
|
3259
|
+
],
|
|
3260
|
+
sinkRunId,
|
|
3261
|
+
parentRunId: runId
|
|
3262
|
+
}), "runAgent"),
|
|
3263
|
+
startAgent: /* @__PURE__ */ __name(({ agentName: childName, task: childTask, toolCallId: toolCallId2 }) => this.startDetached({
|
|
3264
|
+
agentName: childName,
|
|
3265
|
+
task: childTask,
|
|
3266
|
+
actor,
|
|
3267
|
+
day,
|
|
3268
|
+
depth: depth + 1,
|
|
3269
|
+
path: [
|
|
3270
|
+
...path,
|
|
3271
|
+
agentName
|
|
3272
|
+
],
|
|
3273
|
+
parentRunId: runId,
|
|
3274
|
+
deliverTo: {
|
|
3275
|
+
threadId: subThread.id,
|
|
3276
|
+
toolCallId: toolCallId2
|
|
3277
|
+
}
|
|
3278
|
+
}), "startAgent")
|
|
2114
3279
|
};
|
|
2115
3280
|
try {
|
|
2116
3281
|
return await runAgentLoop2({
|
|
@@ -2123,6 +3288,8 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
2123
3288
|
agentName,
|
|
2124
3289
|
day,
|
|
2125
3290
|
delegationDepth: depth,
|
|
3291
|
+
delegationPath: path,
|
|
3292
|
+
parentRunId,
|
|
2126
3293
|
sinkRunId
|
|
2127
3294
|
}, hooks);
|
|
2128
3295
|
} finally {
|
|
@@ -2130,25 +3297,63 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
2130
3297
|
}
|
|
2131
3298
|
}
|
|
2132
3299
|
};
|
|
2133
|
-
InlineAgentRunner =
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
3300
|
+
InlineAgentRunner = _ts_decorate19([
|
|
3301
|
+
Injectable10(),
|
|
3302
|
+
_ts_param17(0, Inject17(AGENT_DEPS_FACTORY5)),
|
|
3303
|
+
_ts_param17(1, Inject17(AGENT_STORE5)),
|
|
3304
|
+
_ts_metadata18("design:type", Function),
|
|
3305
|
+
_ts_metadata18("design:paramtypes", [
|
|
2139
3306
|
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
|
|
2140
3307
|
typeof AgentStore === "undefined" ? Object : AgentStore
|
|
2141
3308
|
])
|
|
2142
3309
|
], InlineAgentRunner);
|
|
2143
3310
|
|
|
3311
|
+
// src/skills-config.ts
|
|
3312
|
+
import { compositeSkillProvider } from "@dudousxd/nestjs-agent-core";
|
|
3313
|
+
function declaredSkillProvider(declared) {
|
|
3314
|
+
return {
|
|
3315
|
+
list: /* @__PURE__ */ __name(({ scopes }) => declared.filter((skill) => scopes.includes(skill.scope)).map(({ name, description, scope }) => ({
|
|
3316
|
+
name,
|
|
3317
|
+
description,
|
|
3318
|
+
scope
|
|
3319
|
+
})), "list"),
|
|
3320
|
+
load: /* @__PURE__ */ __name(async ({ name, scope, ctx }) => {
|
|
3321
|
+
const match = declared.find((skill) => skill.name === name && skill.scope === scope);
|
|
3322
|
+
return match === void 0 ? null : await match.body(ctx);
|
|
3323
|
+
}, "load")
|
|
3324
|
+
};
|
|
3325
|
+
}
|
|
3326
|
+
__name(declaredSkillProvider, "declaredSkillProvider");
|
|
3327
|
+
function resolveSkillsConfig(options, declared) {
|
|
3328
|
+
if (options === void 0) {
|
|
3329
|
+
return void 0;
|
|
3330
|
+
}
|
|
3331
|
+
const providers = options.provider === void 0 ? [
|
|
3332
|
+
declaredSkillProvider(declared)
|
|
3333
|
+
] : [
|
|
3334
|
+
options.provider,
|
|
3335
|
+
declaredSkillProvider(declared)
|
|
3336
|
+
];
|
|
3337
|
+
return {
|
|
3338
|
+
provider: providers.length === 1 ? providers[0] : compositeSkillProvider(providers),
|
|
3339
|
+
...options.scopes !== void 0 ? {
|
|
3340
|
+
scopes: options.scopes
|
|
3341
|
+
} : {},
|
|
3342
|
+
...options.maxSkills !== void 0 ? {
|
|
3343
|
+
maxSkills: options.maxSkills
|
|
3344
|
+
} : {}
|
|
3345
|
+
};
|
|
3346
|
+
}
|
|
3347
|
+
__name(resolveSkillsConfig, "resolveSkillsConfig");
|
|
3348
|
+
|
|
2144
3349
|
// src/agent.module.ts
|
|
2145
|
-
function
|
|
3350
|
+
function _ts_decorate20(decorators, target, key, desc) {
|
|
2146
3351
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2147
3352
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2148
3353
|
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;
|
|
2149
3354
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2150
3355
|
}
|
|
2151
|
-
__name(
|
|
3356
|
+
__name(_ts_decorate20, "_ts_decorate");
|
|
2152
3357
|
var DEFAULT_PATH = "agent";
|
|
2153
3358
|
function sharedProviders(durable, includeStore) {
|
|
2154
3359
|
const providers = [
|
|
@@ -2166,8 +3371,34 @@ function sharedProviders(durable, includeStore) {
|
|
|
2166
3371
|
provide: AGENT_PROMPT_CONTRIBUTORS3,
|
|
2167
3372
|
useFactory: /* @__PURE__ */ __name(() => [], "useFactory")
|
|
2168
3373
|
},
|
|
3374
|
+
// Likewise for `@Skill`-decorated providers — filled by SkillDiscoveryService at onModuleInit,
|
|
3375
|
+
// read lazily by the AGENT_SKILLS provider below (which DI builds before discovery has run).
|
|
3376
|
+
{
|
|
3377
|
+
provide: AGENT_SKILL_SOURCES2,
|
|
3378
|
+
useFactory: /* @__PURE__ */ __name(() => [], "useFactory")
|
|
3379
|
+
},
|
|
3380
|
+
{
|
|
3381
|
+
// One resolution, shared by the loop's deps and the listing endpoint: a second one would
|
|
3382
|
+
// drift, and a user would be offered a skill the agent cannot reach. `undefined` when the
|
|
3383
|
+
// host configured none — which is what keeps the turn's checkpoint sequence unchanged.
|
|
3384
|
+
provide: AGENT_SKILLS3,
|
|
3385
|
+
useFactory: /* @__PURE__ */ __name((options, declared) => resolveSkillsConfig(options.skills, declared), "useFactory"),
|
|
3386
|
+
inject: [
|
|
3387
|
+
AGENT_OPTIONS5,
|
|
3388
|
+
AGENT_SKILL_SOURCES2
|
|
3389
|
+
]
|
|
3390
|
+
},
|
|
3391
|
+
{
|
|
3392
|
+
// One resolution, shared by the loop's deps and the read-back endpoint: a person has to be
|
|
3393
|
+
// shown what the model was shown, and two resolutions would eventually disagree about that.
|
|
3394
|
+
provide: AGENT_MEMORY3,
|
|
3395
|
+
useFactory: /* @__PURE__ */ __name((options) => options.memory, "useFactory"),
|
|
3396
|
+
inject: [
|
|
3397
|
+
AGENT_OPTIONS5
|
|
3398
|
+
]
|
|
3399
|
+
},
|
|
2169
3400
|
{
|
|
2170
|
-
provide:
|
|
3401
|
+
provide: AGENT_SINK4,
|
|
2171
3402
|
useFactory: /* @__PURE__ */ __name((options) => options.sink ?? new InProcessTokenStreamSink(), "useFactory"),
|
|
2172
3403
|
inject: [
|
|
2173
3404
|
AGENT_OPTIONS5
|
|
@@ -2181,7 +3412,7 @@ function sharedProviders(durable, includeStore) {
|
|
|
2181
3412
|
]
|
|
2182
3413
|
},
|
|
2183
3414
|
{
|
|
2184
|
-
provide:
|
|
3415
|
+
provide: AGENT_ACTOR_RESOLVER8,
|
|
2185
3416
|
useFactory: /* @__PURE__ */ __name((options) => options.actorResolver, "useFactory"),
|
|
2186
3417
|
inject: [
|
|
2187
3418
|
AGENT_OPTIONS5
|
|
@@ -2202,7 +3433,7 @@ function sharedProviders(durable, includeStore) {
|
|
|
2202
3433
|
useFactory: /* @__PURE__ */ __name((o, store) => o.quota ?? (o.quotaLimitTokens !== void 0 ? new LedgerQuotaStore(store, o.quotaLimitTokens) : void 0), "useFactory"),
|
|
2203
3434
|
inject: [
|
|
2204
3435
|
AGENT_OPTIONS5,
|
|
2205
|
-
|
|
3436
|
+
AGENT_STORE6
|
|
2206
3437
|
]
|
|
2207
3438
|
},
|
|
2208
3439
|
AgentDepsFactory2,
|
|
@@ -2214,6 +3445,7 @@ function sharedProviders(durable, includeStore) {
|
|
|
2214
3445
|
// handoff tools (onApplicationBootstrap) reads the registry.
|
|
2215
3446
|
AgentDiscoveryService,
|
|
2216
3447
|
AiToolDiscoveryService,
|
|
3448
|
+
SkillDiscoveryService,
|
|
2217
3449
|
InlineAgentRunner,
|
|
2218
3450
|
AgentService,
|
|
2219
3451
|
// Bound ALWAYS (durable or inline) — the console's cross-thread approvals inbox routes decisions
|
|
@@ -2226,7 +3458,7 @@ function sharedProviders(durable, includeStore) {
|
|
|
2226
3458
|
];
|
|
2227
3459
|
if (includeStore) {
|
|
2228
3460
|
providers.push({
|
|
2229
|
-
provide:
|
|
3461
|
+
provide: AGENT_STORE6,
|
|
2230
3462
|
useFactory: /* @__PURE__ */ __name((o) => o.store, "useFactory"),
|
|
2231
3463
|
inject: [
|
|
2232
3464
|
AGENT_OPTIONS5
|
|
@@ -2263,15 +3495,17 @@ function exportsFor(includeStore) {
|
|
|
2263
3495
|
AGENT_OPTIONS5,
|
|
2264
3496
|
AGENT_TOOL_REGISTRY3,
|
|
2265
3497
|
AGENT_REGISTRY5,
|
|
2266
|
-
|
|
3498
|
+
AGENT_SINK4,
|
|
2267
3499
|
AGENT_ROLES_POLICY2,
|
|
2268
|
-
|
|
3500
|
+
AGENT_ACTOR_RESOLVER8,
|
|
2269
3501
|
AGENT_MODEL2,
|
|
2270
3502
|
...includeStore ? [
|
|
2271
|
-
|
|
3503
|
+
AGENT_STORE6
|
|
2272
3504
|
] : [],
|
|
2273
3505
|
AGENT_QUOTA_STORE3,
|
|
2274
3506
|
AGENT_PROMPT_CONTRIBUTORS3,
|
|
3507
|
+
AGENT_SKILLS3,
|
|
3508
|
+
AGENT_MEMORY3,
|
|
2275
3509
|
AGENT_DEPS_FACTORY6,
|
|
2276
3510
|
AgentDepsFactory2,
|
|
2277
3511
|
AgentService,
|
|
@@ -2285,7 +3519,9 @@ var BASE_CONTROLLERS = [
|
|
|
2285
3519
|
ThreadsController,
|
|
2286
3520
|
ToolCallController,
|
|
2287
3521
|
QuotaController,
|
|
2288
|
-
AgentsController
|
|
3522
|
+
AgentsController,
|
|
3523
|
+
SkillsController,
|
|
3524
|
+
MemoriesController
|
|
2289
3525
|
];
|
|
2290
3526
|
var GUARDABLE_CONTROLLERS = [
|
|
2291
3527
|
...BASE_CONTROLLERS,
|
|
@@ -2400,7 +3636,7 @@ var AgentModule = class _AgentModule {
|
|
|
2400
3636
|
};
|
|
2401
3637
|
}
|
|
2402
3638
|
};
|
|
2403
|
-
AgentModule =
|
|
3639
|
+
AgentModule = _ts_decorate20([
|
|
2404
3640
|
Global2(),
|
|
2405
3641
|
Module2({})
|
|
2406
3642
|
], AgentModule);
|