@dudousxd/nestjs-agent 1.19.3 → 1.20.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/dist/{chat-queue.service-CKZkjlMK.d.cts → chat-queue.service-C0hr7dqx.d.cts} +41 -2
- package/dist/{chat-queue.service-CKZkjlMK.d.ts → chat-queue.service-C0hr7dqx.d.ts} +41 -2
- package/dist/durable/index.cjs +287 -23
- package/dist/durable/index.cjs.map +1 -1
- package/dist/durable/index.d.cts +1 -1
- package/dist/durable/index.d.ts +1 -1
- package/dist/durable/index.js +340 -76
- package/dist/durable/index.js.map +1 -1
- package/dist/index.cjs +274 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -4
- package/dist/index.d.ts +50 -4
- package/dist/index.js +327 -68
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/durable/index.js
CHANGED
|
@@ -33,7 +33,7 @@ __name(childSinkWriter, "childSinkWriter");
|
|
|
33
33
|
var AGENT_CHAT_QUEUE = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:chat-queue");
|
|
34
34
|
|
|
35
35
|
// src/durable/agent-run.steps.ts
|
|
36
|
-
import { AGENT_DEPS_FACTORY, createFrameBuffer, createUiCollector, encodeStreamEvent, invokeWithTransientRetry, observeTurnFrames, publishAgentToolRetry, stampToolKinds, toolCallContext, traceLlmTurn, traceToolExecution, withAskTool, withMemoryTool, withSkillTool, withToolTimeout, withTurnFrames, wrapToolStepOutput } from "@dudousxd/nestjs-agent-core";
|
|
36
|
+
import { AGENT_DEPS_FACTORY, createFrameBuffer, createUiCollector, encodeStreamEvent, intersectAllowLists, invokeWithTransientRetry, observeTurnFrames, publishAgentToolRetry, stampToolKinds, toolCallContext, traceLlmTurn, traceToolExecution, withAskTool, withMemoryTool, withSkillTool, withToolTimeout, withTurnFrames, wrapToolStepOutput } from "@dudousxd/nestjs-agent-core";
|
|
37
37
|
import { Step } from "@dudousxd/nestjs-durable";
|
|
38
38
|
import { Inject, Injectable } from "@nestjs/common";
|
|
39
39
|
|
|
@@ -97,14 +97,21 @@ var AgentRunSteps = class {
|
|
|
97
97
|
const tools = withMemoryTool({
|
|
98
98
|
tools: withSkillTool({
|
|
99
99
|
tools: withAskTool({
|
|
100
|
-
tools: await deps.registry.definitionsFor(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
100
|
+
tools: await deps.registry.definitionsFor(
|
|
101
|
+
input.actor,
|
|
102
|
+
deps.rolesPolicy,
|
|
103
|
+
// The persona narrowing the loop journaled in `persona:resolve` rides the envelope:
|
|
104
|
+
// this worker's own persona config may already say something else.
|
|
105
|
+
intersectAllowLists(deps.toolAllowList, input.personaAllowedTools),
|
|
106
|
+
{
|
|
107
|
+
...input.threadId !== void 0 ? {
|
|
108
|
+
threadId: input.threadId
|
|
109
|
+
} : {},
|
|
110
|
+
...input.agentName !== void 0 ? {
|
|
111
|
+
agentName: input.agentName
|
|
112
|
+
} : {}
|
|
113
|
+
}
|
|
114
|
+
),
|
|
108
115
|
ask: deps.ask
|
|
109
116
|
}),
|
|
110
117
|
enabled: deps.skills !== void 0
|
|
@@ -177,7 +184,9 @@ var AgentRunSteps = class {
|
|
|
177
184
|
toolType: input.toolType
|
|
178
185
|
}, () => invokeWithTransientRetry(() => {
|
|
179
186
|
ui.restart();
|
|
180
|
-
const invocation = deps.registry.invoke(input.toolName, input.input, ctx, deps.rolesPolicy
|
|
187
|
+
const invocation = deps.registry.invoke(input.toolName, input.input, ctx, deps.rolesPolicy, input.allowedTools !== void 0 ? {
|
|
188
|
+
allowedTools: input.allowedTools
|
|
189
|
+
} : {});
|
|
181
190
|
return input.timeoutMs !== void 0 ? withToolTimeout(invocation, input.timeoutMs, input.toolName) : invocation;
|
|
182
191
|
}, transientRetry, {
|
|
183
192
|
onRetry: /* @__PURE__ */ __name((attempt, error) => {
|
|
@@ -1085,14 +1094,14 @@ AgentDurableModule = _ts_decorate4([
|
|
|
1085
1094
|
], AgentDurableModule);
|
|
1086
1095
|
|
|
1087
1096
|
// src/agent.module.ts
|
|
1088
|
-
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER13, AGENT_APPROVAL_PORT, AGENT_DEPS_FACTORY as
|
|
1097
|
+
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER13, AGENT_APPROVAL_PORT, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY8, AGENT_DURABLE_RUNNER as AGENT_DURABLE_RUNNER2, AGENT_MEMORY as AGENT_MEMORY3, AGENT_MODEL as AGENT_MODEL2, AGENT_MODEL_CATALOG as AGENT_MODEL_CATALOG3, AGENT_OPTIONS as AGENT_OPTIONS7, AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS3, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER3, AGENT_REGISTRY as AGENT_REGISTRY6, 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_STORE7, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY3, AgentRegistry as AgentRegistry6, ClosedRolesPolicy, DefaultRolesPolicy, InMemoryAgentStore, ToolRegistry as ToolRegistry3 } from "@dudousxd/nestjs-agent-core";
|
|
1089
1098
|
import { Global as Global2, Logger as Logger8, Module as Module2 } from "@nestjs/common";
|
|
1090
1099
|
import { DiscoveryModule, ModulesContainer, RouterModule } from "@nestjs/core";
|
|
1091
1100
|
|
|
1092
1101
|
// src/agent-deps.factory.ts
|
|
1093
|
-
import { AGENT_MEMORY, AGENT_MODEL, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_REGISTRY, AGENT_ROLES_POLICY, AGENT_SINK as AGENT_SINK2, AGENT_SKILLS, AGENT_STORE as AGENT_STORE3, AGENT_TOOL_REGISTRY, AgentRegistry as AgentRegistry2, ToolRegistry as ToolRegistry2, normalizeDelegation, summarizeWithModel, windowHistory } from "@dudousxd/nestjs-agent-core";
|
|
1102
|
+
import { AGENT_MEMORY, AGENT_MODEL, AGENT_PRICING_STORE, AGENT_PROMPT_CONTRIBUTORS, AGENT_REGISTRY, AGENT_ROLES_POLICY, AGENT_SINK as AGENT_SINK2, AGENT_SKILLS, AGENT_STORE as AGENT_STORE3, AGENT_TOOL_REGISTRY, AgentRegistry as AgentRegistry2, ToolRegistry as ToolRegistry2, findPersona, intersectAllowLists as intersectAllowLists2, normalizeDelegation, personaCatalogEntry, resolvePersonaAlias, summarizeWithModel, windowHistory } from "@dudousxd/nestjs-agent-core";
|
|
1094
1103
|
import { AGENT_OPTIONS } from "@dudousxd/nestjs-agent-core";
|
|
1095
|
-
import { Inject as Inject4, Injectable as Injectable4, Optional as Optional3 } from "@nestjs/common";
|
|
1104
|
+
import { BadRequestException, Inject as Inject4, Injectable as Injectable4, Optional as Optional3 } from "@nestjs/common";
|
|
1096
1105
|
function _ts_decorate5(decorators, target, key, desc) {
|
|
1097
1106
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1098
1107
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -1190,8 +1199,64 @@ var AgentDepsFactory2 = class {
|
|
|
1190
1199
|
...delegated
|
|
1191
1200
|
];
|
|
1192
1201
|
}
|
|
1202
|
+
/**
|
|
1203
|
+
* The agent a name stands for: itself when it is a registered agent (or unknown — the bare
|
|
1204
|
+
* assistant), else the agent whose persona took the name over (`Persona.aliases`) and that persona.
|
|
1205
|
+
*/
|
|
1206
|
+
resolveAgent(name) {
|
|
1207
|
+
if (this.agents.has(name)) {
|
|
1208
|
+
return {
|
|
1209
|
+
agentName: name
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
const alias = resolvePersonaAlias(this.agents.list(), name);
|
|
1213
|
+
return alias === void 0 ? {
|
|
1214
|
+
agentName: name
|
|
1215
|
+
} : {
|
|
1216
|
+
agentName: alias.agent,
|
|
1217
|
+
persona: alias.persona
|
|
1218
|
+
};
|
|
1219
|
+
}
|
|
1220
|
+
/** `agentName`'s personas as a picker reads them. Empty when it declares none. */
|
|
1221
|
+
personaCatalog(agentName) {
|
|
1222
|
+
return (this.agents.get(agentName)?.personas ?? []).map(personaCatalogEntry);
|
|
1223
|
+
}
|
|
1224
|
+
/** The persona `agentName` runs under when nothing names one. Undefined → none. */
|
|
1225
|
+
defaultPersona(agentName) {
|
|
1226
|
+
return this.agents.get(agentName)?.defaultPersona;
|
|
1227
|
+
}
|
|
1228
|
+
/**
|
|
1229
|
+
* The persona a turn of `agentName` runs under, most specific first: the one the send names
|
|
1230
|
+
* (refused with `400 persona_not_found` when the agent does not declare it), else the thread's
|
|
1231
|
+
* pinned one when this agent declares it, else the agent's default. Undefined → none.
|
|
1232
|
+
*/
|
|
1233
|
+
resolvePersona(args) {
|
|
1234
|
+
const definition = this.agents.get(args.agentName);
|
|
1235
|
+
if (args.requested !== void 0) {
|
|
1236
|
+
if (findPersona(definition, args.requested) === void 0) {
|
|
1237
|
+
throw new BadRequestException({
|
|
1238
|
+
statusCode: 400,
|
|
1239
|
+
code: "persona_not_found",
|
|
1240
|
+
message: `agent "${args.agentName}" has no persona "${args.requested}"`
|
|
1241
|
+
});
|
|
1242
|
+
}
|
|
1243
|
+
return args.requested;
|
|
1244
|
+
}
|
|
1245
|
+
const pinned = args.threadPersona ?? void 0;
|
|
1246
|
+
if (pinned !== void 0 && findPersona(definition, pinned) !== void 0) {
|
|
1247
|
+
return pinned;
|
|
1248
|
+
}
|
|
1249
|
+
return definition?.defaultPersona;
|
|
1250
|
+
}
|
|
1193
1251
|
forAgent(agentName) {
|
|
1194
1252
|
const name = agentName ?? this.defaultAgentName();
|
|
1253
|
+
if (agentName !== void 0 && !this.agents.has(agentName)) {
|
|
1254
|
+
const alias = resolvePersonaAlias(this.agents.list(), agentName);
|
|
1255
|
+
const persona = alias === void 0 ? void 0 : findPersona(this.agents.get(alias.agent), alias.persona);
|
|
1256
|
+
if (alias !== void 0 && persona !== void 0) {
|
|
1257
|
+
return this.withPersona(this.forAgent(alias.agent), persona);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1195
1260
|
const definition = this.agents.get(name);
|
|
1196
1261
|
const toolAllowList = this.effectiveTools(definition);
|
|
1197
1262
|
const followUpsCount = this.followUpsCount();
|
|
@@ -1256,6 +1321,9 @@ var AgentDepsFactory2 = class {
|
|
|
1256
1321
|
...toolAllowList !== void 0 ? {
|
|
1257
1322
|
toolAllowList
|
|
1258
1323
|
} : {},
|
|
1324
|
+
...definition?.personas !== void 0 ? {
|
|
1325
|
+
personas: definition.personas
|
|
1326
|
+
} : {},
|
|
1259
1327
|
...this.options.toolTimeoutMs !== void 0 ? {
|
|
1260
1328
|
toolTimeoutMs: this.options.toolTimeoutMs
|
|
1261
1329
|
} : {},
|
|
@@ -1274,6 +1342,45 @@ var AgentDepsFactory2 = class {
|
|
|
1274
1342
|
};
|
|
1275
1343
|
}
|
|
1276
1344
|
/**
|
|
1345
|
+
* A persona baked into an agent's deps — how a run journaled under an agent name that a persona
|
|
1346
|
+
* has since taken over (`Persona.aliases`) is served. That run names no persona of its own (it
|
|
1347
|
+
* predates them, and its input cannot change), so the persona applies the way the old agent's own
|
|
1348
|
+
* config did: as config, re-read on every replay, with no checkpoint of its own.
|
|
1349
|
+
*/
|
|
1350
|
+
withPersona(deps, persona) {
|
|
1351
|
+
const base = deps.systemPrompt;
|
|
1352
|
+
const ref = {
|
|
1353
|
+
id: persona.id,
|
|
1354
|
+
label: persona.label
|
|
1355
|
+
};
|
|
1356
|
+
const resolve = /* @__PURE__ */ __name(async (prompt, ctx) => typeof prompt === "function" ? prompt(ctx) : prompt, "resolve");
|
|
1357
|
+
const own = persona.systemPrompt;
|
|
1358
|
+
const systemPrompt = /* @__PURE__ */ __name(async (ctx) => {
|
|
1359
|
+
const scoped = {
|
|
1360
|
+
...ctx,
|
|
1361
|
+
persona: ref
|
|
1362
|
+
};
|
|
1363
|
+
if (own === void 0) {
|
|
1364
|
+
return resolve(base, scoped);
|
|
1365
|
+
}
|
|
1366
|
+
const basePrompt = typeof own === "function" ? await resolve(base, scoped) : void 0;
|
|
1367
|
+
return resolve(own, {
|
|
1368
|
+
...scoped,
|
|
1369
|
+
...basePrompt !== void 0 ? {
|
|
1370
|
+
basePrompt
|
|
1371
|
+
} : {}
|
|
1372
|
+
});
|
|
1373
|
+
}, "systemPrompt");
|
|
1374
|
+
const toolAllowList = intersectAllowLists2(deps.toolAllowList, persona.allowedTools);
|
|
1375
|
+
return {
|
|
1376
|
+
...deps,
|
|
1377
|
+
systemPrompt,
|
|
1378
|
+
...toolAllowList !== void 0 ? {
|
|
1379
|
+
toolAllowList
|
|
1380
|
+
} : {}
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1277
1384
|
* The ceiling on how much of a thread this agent's turns carry, most specific wins: the agent's
|
|
1278
1385
|
* own `@Agent({ history })`, else a module-wide custom `historyPolicy`, else the module-wide
|
|
1279
1386
|
* `history` window. Undefined → unbounded, the behaviour of a module that configures none.
|
|
@@ -1348,12 +1455,24 @@ AgentDepsFactory2 = _ts_decorate5([
|
|
|
1348
1455
|
], AgentDepsFactory2);
|
|
1349
1456
|
|
|
1350
1457
|
// src/agent.service.ts
|
|
1351
|
-
import { AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING2, AGENT_DEPS_FACTORY as
|
|
1352
|
-
import { BadRequestException, ConflictException as ConflictException2, ForbiddenException, GoneException, HttpException, HttpStatus, Inject as Inject6, Injectable as Injectable6, NotFoundException, NotImplementedException as NotImplementedException2, Optional as Optional5 } from "@nestjs/common";
|
|
1458
|
+
import { AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING2, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY4, AGENT_MODEL_CATALOG, AGENT_OPTIONS as AGENT_OPTIONS3, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE5, REQUESTER_APPROVER, findCatalogModel, mayDecideApproval, readElicitationQuestions, settleDeadRun as settleDeadRun2, validateElicitationAnswer } from "@dudousxd/nestjs-agent-core";
|
|
1459
|
+
import { BadRequestException as BadRequestException2, ConflictException as ConflictException2, ForbiddenException, GoneException, HttpException, HttpStatus, Inject as Inject6, Injectable as Injectable6, NotFoundException, NotImplementedException as NotImplementedException2, Optional as Optional5 } from "@nestjs/common";
|
|
1353
1460
|
|
|
1354
1461
|
// src/queue/chat-queue.service.ts
|
|
1355
|
-
import { AGENT_ATTACHMENT_STAGING, AGENT_OPTIONS as AGENT_OPTIONS2, AGENT_QUOTA_PROVIDER, AGENT_SINK as AGENT_SINK3, AGENT_STORE as AGENT_STORE4, encodeStreamEvent as encodeStreamEvent4, isChatQueueStore, queuedMessageView } from "@dudousxd/nestjs-agent-core";
|
|
1462
|
+
import { AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY3, AGENT_OPTIONS as AGENT_OPTIONS2, AGENT_QUOTA_PROVIDER, AGENT_SINK as AGENT_SINK3, AGENT_STORE as AGENT_STORE4, encodeStreamEvent as encodeStreamEvent4, isChatQueueStore, queuedMessageView } from "@dudousxd/nestjs-agent-core";
|
|
1356
1463
|
import { Inject as Inject5, Injectable as Injectable5, Logger as Logger3, NotImplementedException, Optional as Optional4 } from "@nestjs/common";
|
|
1464
|
+
|
|
1465
|
+
// src/thread-persona.ts
|
|
1466
|
+
async function threadPersona(store, threadId) {
|
|
1467
|
+
const projecting = store;
|
|
1468
|
+
if (typeof projecting.personaForThread === "function") {
|
|
1469
|
+
return projecting.personaForThread(threadId);
|
|
1470
|
+
}
|
|
1471
|
+
return (await store.getThread(threadId))?.persona ?? null;
|
|
1472
|
+
}
|
|
1473
|
+
__name(threadPersona, "threadPersona");
|
|
1474
|
+
|
|
1475
|
+
// src/queue/chat-queue.service.ts
|
|
1357
1476
|
function _ts_decorate6(decorators, target, key, desc) {
|
|
1358
1477
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1359
1478
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -1390,18 +1509,20 @@ var ChatQueueService2 = class _ChatQueueService {
|
|
|
1390
1509
|
quotaProvider;
|
|
1391
1510
|
options;
|
|
1392
1511
|
staging;
|
|
1512
|
+
deps;
|
|
1393
1513
|
logger = new Logger3(_ChatQueueService.name);
|
|
1394
1514
|
/**
|
|
1395
1515
|
* Runs this process claimed a thread for and has not handed to a runner yet. A holder in here is
|
|
1396
1516
|
* alive whatever the runner says — it simply has not registered the run yet.
|
|
1397
1517
|
*/
|
|
1398
1518
|
starting = /* @__PURE__ */ new Set();
|
|
1399
|
-
constructor(store, sink, quotaProvider, options, staging) {
|
|
1519
|
+
constructor(store, sink, quotaProvider, options, staging, deps) {
|
|
1400
1520
|
this.store = store;
|
|
1401
1521
|
this.sink = sink;
|
|
1402
1522
|
this.quotaProvider = quotaProvider;
|
|
1403
1523
|
this.options = options;
|
|
1404
1524
|
this.staging = staging;
|
|
1525
|
+
this.deps = deps;
|
|
1405
1526
|
}
|
|
1406
1527
|
/** Whether the bound store can hold a queue. Without one, a busy thread is not queued. */
|
|
1407
1528
|
get supported() {
|
|
@@ -1699,13 +1820,17 @@ var ChatQueueService2 = class _ChatQueueService {
|
|
|
1699
1820
|
*/
|
|
1700
1821
|
async inputFor(message) {
|
|
1701
1822
|
const attachments = await this.freshAttachments(message.actor, message.attachments ?? []);
|
|
1823
|
+
const { agentName, persona } = await this.targetFor(message);
|
|
1702
1824
|
return {
|
|
1703
1825
|
threadId: message.threadId,
|
|
1704
1826
|
actor: message.actor,
|
|
1705
1827
|
userText: message.content,
|
|
1706
1828
|
day: utcDay(),
|
|
1707
|
-
...
|
|
1708
|
-
agentName
|
|
1829
|
+
...agentName !== void 0 ? {
|
|
1830
|
+
agentName
|
|
1831
|
+
} : {},
|
|
1832
|
+
...persona !== void 0 ? {
|
|
1833
|
+
persona
|
|
1709
1834
|
} : {},
|
|
1710
1835
|
...attachments.length > 0 ? {
|
|
1711
1836
|
attachments
|
|
@@ -1718,6 +1843,37 @@ var ChatQueueService2 = class _ChatQueueService {
|
|
|
1718
1843
|
} : {}
|
|
1719
1844
|
};
|
|
1720
1845
|
}
|
|
1846
|
+
/**
|
|
1847
|
+
* The agent and persona a queued message starts as. A message carries the persona its send
|
|
1848
|
+
* resolved; one that carries none — queued before personas existed, or by a host that sets none —
|
|
1849
|
+
* resolves it now, exactly as a send would: an agent name a persona took over, then the thread's
|
|
1850
|
+
* pinned persona, then the agent's default. Never refused here: nobody is waiting on a 400.
|
|
1851
|
+
*/
|
|
1852
|
+
async targetFor(message) {
|
|
1853
|
+
const deps = this.deps;
|
|
1854
|
+
if (message.persona !== void 0 || deps === void 0 || message.agentName === void 0) {
|
|
1855
|
+
return {
|
|
1856
|
+
...message.agentName !== void 0 ? {
|
|
1857
|
+
agentName: message.agentName
|
|
1858
|
+
} : {},
|
|
1859
|
+
...message.persona !== void 0 ? {
|
|
1860
|
+
persona: message.persona
|
|
1861
|
+
} : {}
|
|
1862
|
+
};
|
|
1863
|
+
}
|
|
1864
|
+
const target = deps.resolveAgent(message.agentName);
|
|
1865
|
+
const hasPersonas = deps.personaCatalog(target.agentName).length > 0;
|
|
1866
|
+
const persona = target.persona ?? (hasPersonas ? deps.resolvePersona({
|
|
1867
|
+
agentName: target.agentName,
|
|
1868
|
+
threadPersona: await threadPersona(this.store, message.threadId)
|
|
1869
|
+
}) : void 0);
|
|
1870
|
+
return {
|
|
1871
|
+
agentName: target.agentName,
|
|
1872
|
+
...persona !== void 0 ? {
|
|
1873
|
+
persona
|
|
1874
|
+
} : {}
|
|
1875
|
+
};
|
|
1876
|
+
}
|
|
1721
1877
|
async freshAttachments(actor, attachments) {
|
|
1722
1878
|
const staging = this.staging;
|
|
1723
1879
|
if (attachments.length === 0 || staging === void 0 || typeof staging.resolve !== "function") {
|
|
@@ -1745,13 +1901,16 @@ ChatQueueService2 = _ts_decorate6([
|
|
|
1745
1901
|
_ts_param5(3, Inject5(AGENT_OPTIONS2)),
|
|
1746
1902
|
_ts_param5(4, Optional4()),
|
|
1747
1903
|
_ts_param5(4, Inject5(AGENT_ATTACHMENT_STAGING)),
|
|
1904
|
+
_ts_param5(5, Optional4()),
|
|
1905
|
+
_ts_param5(5, Inject5(AGENT_DEPS_FACTORY3)),
|
|
1748
1906
|
_ts_metadata5("design:type", Function),
|
|
1749
1907
|
_ts_metadata5("design:paramtypes", [
|
|
1750
1908
|
typeof AgentStore === "undefined" ? Object : AgentStore,
|
|
1751
1909
|
typeof TokenStreamSink === "undefined" ? Object : TokenStreamSink,
|
|
1752
1910
|
typeof QuotaProvider === "undefined" ? Object : QuotaProvider,
|
|
1753
1911
|
typeof Pick === "undefined" ? Object : Pick,
|
|
1754
|
-
typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore
|
|
1912
|
+
typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore,
|
|
1913
|
+
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
|
|
1755
1914
|
])
|
|
1756
1915
|
], ChatQueueService2);
|
|
1757
1916
|
function pauseReasonFor(outcome, head) {
|
|
@@ -1923,17 +2082,17 @@ var AgentService = class {
|
|
|
1923
2082
|
*/
|
|
1924
2083
|
async assertModelAllowed(actor, agent, model) {
|
|
1925
2084
|
if (this.models === void 0) {
|
|
1926
|
-
throw new
|
|
2085
|
+
throw new BadRequestException2(`model "${model}" cannot be selected: no ModelCatalog is configured (AgentModule.forRoot({ models }))`);
|
|
1927
2086
|
}
|
|
1928
2087
|
const entry = findCatalogModel(await this.models.list({
|
|
1929
2088
|
actor,
|
|
1930
2089
|
agent
|
|
1931
2090
|
}), model);
|
|
1932
2091
|
if (entry === void 0) {
|
|
1933
|
-
throw new
|
|
2092
|
+
throw new BadRequestException2(`model "${model}" is not offered`);
|
|
1934
2093
|
}
|
|
1935
2094
|
if (!entry.available) {
|
|
1936
|
-
throw new
|
|
2095
|
+
throw new BadRequestException2(`model "${model}" is not available${entry.unavailableReason ? `: ${entry.unavailableReason}` : ""}`);
|
|
1937
2096
|
}
|
|
1938
2097
|
return entry.id;
|
|
1939
2098
|
}
|
|
@@ -1949,7 +2108,7 @@ var AgentService = class {
|
|
|
1949
2108
|
})).locked : void 0;
|
|
1950
2109
|
if (locked !== void 0) {
|
|
1951
2110
|
if (requested !== void 0 && requested !== locked.model) {
|
|
1952
|
-
throw new
|
|
2111
|
+
throw new BadRequestException2(`model "${requested}" cannot be selected: ${locked.reason ?? `this agent always uses "${locked.model}"`}`);
|
|
1953
2112
|
}
|
|
1954
2113
|
return locked.model;
|
|
1955
2114
|
}
|
|
@@ -2005,13 +2164,15 @@ var AgentService = class {
|
|
|
2005
2164
|
*/
|
|
2006
2165
|
async send(params) {
|
|
2007
2166
|
await this.assertWithinQuota(params.actor);
|
|
2008
|
-
const
|
|
2167
|
+
const target = this.deps.resolveAgent(await this.resolveAgentName(params.agentName, params.threadId));
|
|
2168
|
+
const agentName = target.agentName;
|
|
2169
|
+
const persona = await this.resolvePersona(agentName, params.personaId ?? target.persona, params.threadId);
|
|
2009
2170
|
const model = await this.resolveModel(params.actor, agentName, params.model, params.threadId);
|
|
2010
2171
|
const attachments = await this.resolveAttachments(params.actor, params.attachments ?? []);
|
|
2011
2172
|
let threadId = params.threadId;
|
|
2012
2173
|
if (threadId === void 0) {
|
|
2013
2174
|
if (params.regenerate === true) {
|
|
2014
|
-
throw new
|
|
2175
|
+
throw new BadRequestException2("regenerate requires an existing threadId");
|
|
2015
2176
|
}
|
|
2016
2177
|
const created = await this.store.createThread({
|
|
2017
2178
|
actor: params.actor,
|
|
@@ -2020,11 +2181,17 @@ var AgentService = class {
|
|
|
2020
2181
|
} : {},
|
|
2021
2182
|
...params.newThreadId !== void 0 ? {
|
|
2022
2183
|
id: params.newThreadId
|
|
2184
|
+
} : {},
|
|
2185
|
+
...params.personaId !== void 0 ? {
|
|
2186
|
+
persona: params.personaId
|
|
2023
2187
|
} : {}
|
|
2024
2188
|
});
|
|
2025
2189
|
threadId = created.id;
|
|
2026
2190
|
} else {
|
|
2027
2191
|
await this.assertOwnsThread(params.actor, threadId);
|
|
2192
|
+
if (params.personaId !== void 0) {
|
|
2193
|
+
await this.pinThreadPersona(threadId, params.personaId);
|
|
2194
|
+
}
|
|
2028
2195
|
}
|
|
2029
2196
|
const input = {
|
|
2030
2197
|
threadId,
|
|
@@ -2032,6 +2199,9 @@ var AgentService = class {
|
|
|
2032
2199
|
userText: params.message,
|
|
2033
2200
|
day: utcDay(),
|
|
2034
2201
|
agentName,
|
|
2202
|
+
...persona !== void 0 ? {
|
|
2203
|
+
persona
|
|
2204
|
+
} : {},
|
|
2035
2205
|
...params.regenerate === true ? {
|
|
2036
2206
|
regenerate: true
|
|
2037
2207
|
} : {},
|
|
@@ -2118,6 +2288,9 @@ var AgentService = class {
|
|
|
2118
2288
|
...input.agentName !== void 0 ? {
|
|
2119
2289
|
agentName: input.agentName
|
|
2120
2290
|
} : {},
|
|
2291
|
+
...input.persona !== void 0 ? {
|
|
2292
|
+
persona: input.persona
|
|
2293
|
+
} : {},
|
|
2121
2294
|
...input.model !== void 0 ? {
|
|
2122
2295
|
model: input.model
|
|
2123
2296
|
} : {},
|
|
@@ -2170,7 +2343,7 @@ var AgentService = class {
|
|
|
2170
2343
|
const store = queue.queueStore();
|
|
2171
2344
|
const threadId = await this.assertOwnsQueuedMessage(actor, messageId);
|
|
2172
2345
|
if (patch.message !== void 0 && patch.message.trim().length === 0) {
|
|
2173
|
-
throw new
|
|
2346
|
+
throw new BadRequestException2("message must not be empty");
|
|
2174
2347
|
}
|
|
2175
2348
|
const attachments = patch.attachments === void 0 || patch.attachments === null ? patch.attachments : await this.resolveAttachments(actor, patch.attachments);
|
|
2176
2349
|
if (patch.message !== void 0 || attachments !== void 0) {
|
|
@@ -2188,7 +2361,7 @@ var AgentService = class {
|
|
|
2188
2361
|
}
|
|
2189
2362
|
if (patch.position !== void 0) {
|
|
2190
2363
|
if (!Number.isInteger(patch.position) || patch.position < 0) {
|
|
2191
|
-
throw new
|
|
2364
|
+
throw new BadRequestException2("position must be a non-negative integer");
|
|
2192
2365
|
}
|
|
2193
2366
|
if (!await store.moveQueuedMessage(messageId, patch.position)) {
|
|
2194
2367
|
throw new GoneException(`queued message ${messageId} already started or was removed`);
|
|
@@ -2512,16 +2685,22 @@ var AgentService = class {
|
|
|
2512
2685
|
async updateThread(actor, threadId, patch) {
|
|
2513
2686
|
const title = patch.title !== void 0 ? this.validateTitle(patch.title) : void 0;
|
|
2514
2687
|
await this.assertOwnsThread(actor, threadId);
|
|
2515
|
-
if (patch.defaultAgent === void 0 && patch.model === void 0) {
|
|
2688
|
+
if (patch.defaultAgent === void 0 && patch.model === void 0 && patch.persona === void 0) {
|
|
2516
2689
|
if (title !== void 0) {
|
|
2517
2690
|
await this.store.setTitle(threadId, title);
|
|
2518
2691
|
}
|
|
2519
2692
|
return;
|
|
2520
2693
|
}
|
|
2521
2694
|
if (this.store.updateThread === void 0) {
|
|
2522
|
-
throw new NotImplementedException2("Setting a thread's defaultAgent or
|
|
2695
|
+
throw new NotImplementedException2("Setting a thread's defaultAgent, model or persona requires an AgentStore that implements updateThread(); the bound store does not support it.");
|
|
2523
2696
|
}
|
|
2524
2697
|
const model = patch.model === void 0 || patch.model === null ? patch.model : await this.assertModelAllowed(actor, patch.defaultAgent ?? await this.resolveAgentName(void 0, threadId), patch.model);
|
|
2698
|
+
if (patch.persona !== void 0 && patch.persona !== null) {
|
|
2699
|
+
this.deps.resolvePersona({
|
|
2700
|
+
agentName: this.deps.resolveAgent(patch.defaultAgent ?? await this.resolveAgentName(void 0, threadId)).agentName,
|
|
2701
|
+
requested: patch.persona
|
|
2702
|
+
});
|
|
2703
|
+
}
|
|
2525
2704
|
await this.store.updateThread(threadId, {
|
|
2526
2705
|
...title !== void 0 ? {
|
|
2527
2706
|
title
|
|
@@ -2531,16 +2710,46 @@ var AgentService = class {
|
|
|
2531
2710
|
} : {},
|
|
2532
2711
|
...model !== void 0 ? {
|
|
2533
2712
|
model
|
|
2713
|
+
} : {},
|
|
2714
|
+
...patch.persona !== void 0 ? {
|
|
2715
|
+
persona: patch.persona
|
|
2716
|
+
} : {}
|
|
2717
|
+
});
|
|
2718
|
+
}
|
|
2719
|
+
/**
|
|
2720
|
+
* The persona this send runs under — see {@link AgentDepsFactory.resolvePersona}. The thread's
|
|
2721
|
+
* pinned persona is read only when the send names none AND the agent has personas to pick from.
|
|
2722
|
+
*/
|
|
2723
|
+
async resolvePersona(agentName, requested, threadId) {
|
|
2724
|
+
const needsThread = requested === void 0 && threadId !== void 0 && this.deps.personaCatalog(agentName).length > 0;
|
|
2725
|
+
return this.deps.resolvePersona({
|
|
2726
|
+
agentName,
|
|
2727
|
+
...requested !== void 0 ? {
|
|
2728
|
+
requested
|
|
2729
|
+
} : {},
|
|
2730
|
+
...needsThread ? {
|
|
2731
|
+
threadPersona: await threadPersona(this.store, threadId)
|
|
2534
2732
|
} : {}
|
|
2535
2733
|
});
|
|
2536
2734
|
}
|
|
2735
|
+
/** Pin `persona` on the thread when it is not already — a no-op on a store that cannot. */
|
|
2736
|
+
async pinThreadPersona(threadId, persona) {
|
|
2737
|
+
if (this.store.updateThread === void 0) {
|
|
2738
|
+
return;
|
|
2739
|
+
}
|
|
2740
|
+
if (await threadPersona(this.store, threadId) !== persona) {
|
|
2741
|
+
await this.store.updateThread(threadId, {
|
|
2742
|
+
persona
|
|
2743
|
+
});
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2537
2746
|
validateTitle(title) {
|
|
2538
2747
|
const trimmed = title.trim();
|
|
2539
2748
|
if (trimmed.length === 0) {
|
|
2540
|
-
throw new
|
|
2749
|
+
throw new BadRequestException2("title must not be empty");
|
|
2541
2750
|
}
|
|
2542
2751
|
if (trimmed.length > 200) {
|
|
2543
|
-
throw new
|
|
2752
|
+
throw new BadRequestException2("title must be at most 200 characters");
|
|
2544
2753
|
}
|
|
2545
2754
|
return trimmed;
|
|
2546
2755
|
}
|
|
@@ -2579,6 +2788,7 @@ var AgentService = class {
|
|
|
2579
2788
|
...thread,
|
|
2580
2789
|
defaultAgent: thread.defaultAgent ?? null,
|
|
2581
2790
|
model: thread.model ?? null,
|
|
2791
|
+
persona: thread.persona ?? null,
|
|
2582
2792
|
activeRunId: await this.store.activeRunForThread?.(thread.id) ?? thread.activeRunId ?? null
|
|
2583
2793
|
};
|
|
2584
2794
|
}
|
|
@@ -2643,14 +2853,14 @@ var AgentService = class {
|
|
|
2643
2853
|
*/
|
|
2644
2854
|
async setMessageFeedback(actor, messageId, input) {
|
|
2645
2855
|
if (input.value !== null && input.value !== "up" && input.value !== "down") {
|
|
2646
|
-
throw new
|
|
2856
|
+
throw new BadRequestException2("value must be 'up', 'down' or null");
|
|
2647
2857
|
}
|
|
2648
2858
|
if (input.comment !== void 0 && typeof input.comment !== "string") {
|
|
2649
|
-
throw new
|
|
2859
|
+
throw new BadRequestException2("comment must be a string");
|
|
2650
2860
|
}
|
|
2651
2861
|
const comment = input.comment?.trim();
|
|
2652
2862
|
if (comment !== void 0 && comment.length > 2e3) {
|
|
2653
|
-
throw new
|
|
2863
|
+
throw new BadRequestException2("comment must be at most 2000 characters");
|
|
2654
2864
|
}
|
|
2655
2865
|
if (this.store.threadOfMessage === void 0 || this.store.setMessageFeedback === void 0) {
|
|
2656
2866
|
throw new NotImplementedException2("Message feedback requires an AgentStore that implements threadOfMessage() and setMessageFeedback(); the bound store does not support it.");
|
|
@@ -2775,7 +2985,7 @@ var AgentService = class {
|
|
|
2775
2985
|
const submitted = Object.hasOwn(answers2, question.id) ? answers2[question.id] : void 0;
|
|
2776
2986
|
const problem = validateElicitationAnswer(question, submitted ?? question.defaults ?? []);
|
|
2777
2987
|
if (problem !== null) {
|
|
2778
|
-
throw new
|
|
2988
|
+
throw new BadRequestException2(`answers["${question.id}"] ${problem}`);
|
|
2779
2989
|
}
|
|
2780
2990
|
}
|
|
2781
2991
|
}
|
|
@@ -2849,7 +3059,7 @@ AgentService = _ts_decorate7([
|
|
|
2849
3059
|
Injectable6(),
|
|
2850
3060
|
_ts_param6(0, Inject6(AGENT_RUNNER)),
|
|
2851
3061
|
_ts_param6(1, Inject6(AGENT_STORE5)),
|
|
2852
|
-
_ts_param6(2, Inject6(
|
|
3062
|
+
_ts_param6(2, Inject6(AGENT_DEPS_FACTORY4)),
|
|
2853
3063
|
_ts_param6(3, Optional5()),
|
|
2854
3064
|
_ts_param6(3, Inject6(AGENT_ATTACHMENT_STAGING2)),
|
|
2855
3065
|
_ts_param6(4, Optional5()),
|
|
@@ -2940,7 +3150,7 @@ AgentApprovalPortAdapter = _ts_decorate8([
|
|
|
2940
3150
|
], AgentApprovalPortAdapter);
|
|
2941
3151
|
|
|
2942
3152
|
// src/controller/agents.controller.ts
|
|
2943
|
-
import { AGENT_DEPS_FACTORY as
|
|
3153
|
+
import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY5, AGENT_REGISTRY as AGENT_REGISTRY2, AgentRegistry as AgentRegistry3 } from "@dudousxd/nestjs-agent-core";
|
|
2944
3154
|
import { Controller, Get, Inject as Inject7 } from "@nestjs/common";
|
|
2945
3155
|
function _ts_decorate9(decorators, target, key, desc) {
|
|
2946
3156
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -2980,13 +3190,22 @@ var AgentsController = class {
|
|
|
2980
3190
|
}
|
|
2981
3191
|
list() {
|
|
2982
3192
|
const defaultAgentName = this.depsFactory.defaultAgentName();
|
|
2983
|
-
return this.agents.list().map((definition) =>
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
3193
|
+
return this.agents.list().map((definition) => {
|
|
3194
|
+
const personas = this.depsFactory.personaCatalog(definition.name);
|
|
3195
|
+
return {
|
|
3196
|
+
name: definition.name,
|
|
3197
|
+
description: definition.description ?? "",
|
|
3198
|
+
...definition.name === defaultAgentName ? {
|
|
3199
|
+
isDefault: true
|
|
3200
|
+
} : {},
|
|
3201
|
+
...personas.length > 0 ? {
|
|
3202
|
+
personas
|
|
3203
|
+
} : {},
|
|
3204
|
+
...definition.defaultPersona !== void 0 ? {
|
|
3205
|
+
defaultPersona: definition.defaultPersona
|
|
3206
|
+
} : {}
|
|
3207
|
+
};
|
|
3208
|
+
});
|
|
2990
3209
|
}
|
|
2991
3210
|
};
|
|
2992
3211
|
_ts_decorate9([
|
|
@@ -2998,7 +3217,7 @@ _ts_decorate9([
|
|
|
2998
3217
|
AgentsController = _ts_decorate9([
|
|
2999
3218
|
Controller("agents"),
|
|
3000
3219
|
_ts_param7(0, Inject7(AGENT_REGISTRY2)),
|
|
3001
|
-
_ts_param7(1, Inject7(
|
|
3220
|
+
_ts_param7(1, Inject7(AGENT_DEPS_FACTORY5)),
|
|
3002
3221
|
_ts_metadata8("design:type", Function),
|
|
3003
3222
|
_ts_metadata8("design:paramtypes", [
|
|
3004
3223
|
typeof AgentRegistry3 === "undefined" ? Object : AgentRegistry3,
|
|
@@ -3008,7 +3227,7 @@ AgentsController = _ts_decorate9([
|
|
|
3008
3227
|
|
|
3009
3228
|
// src/controller/attachments.controller.ts
|
|
3010
3229
|
import { AGENT_ACTOR_RESOLVER, AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING3, AGENT_OPTIONS as AGENT_OPTIONS4 } from "@dudousxd/nestjs-agent-core";
|
|
3011
|
-
import { BadRequestException as
|
|
3230
|
+
import { BadRequestException as BadRequestException3, Controller as Controller2, Get as Get2, Inject as Inject8, NotImplementedException as NotImplementedException3, Optional as Optional6, PayloadTooLargeException, Post, Req, UnsupportedMediaTypeException, UploadedFile, UseInterceptors } from "@nestjs/common";
|
|
3012
3231
|
import { FileInterceptor } from "@nestjs/platform-express";
|
|
3013
3232
|
|
|
3014
3233
|
// src/attachment-limits.ts
|
|
@@ -3099,7 +3318,7 @@ var AttachmentsController = class {
|
|
|
3099
3318
|
throw new NotImplementedException3("Attachment upload is not configured on this server: bind AGENT_ATTACHMENT_STAGING (e.g. import AgentMediaAttachmentsModule).");
|
|
3100
3319
|
}
|
|
3101
3320
|
if (file === void 0) {
|
|
3102
|
-
throw new
|
|
3321
|
+
throw new BadRequestException3('multipart field "file" is required');
|
|
3103
3322
|
}
|
|
3104
3323
|
const { allowedContentTypes, maxBytes } = attachmentLimits(this.options, this.staging);
|
|
3105
3324
|
if (!allowedContentTypes.includes(file.mimetype)) {
|
|
@@ -3160,7 +3379,7 @@ AttachmentsController = _ts_decorate10([
|
|
|
3160
3379
|
|
|
3161
3380
|
// src/controller/chat.controller.ts
|
|
3162
3381
|
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER2, AgentStreamError as AgentStreamError2, streamFailure as streamFailure2 } from "@dudousxd/nestjs-agent-core";
|
|
3163
|
-
import { BadRequestException as
|
|
3382
|
+
import { BadRequestException as BadRequestException4, Body, Controller as Controller3, Get as Get3, Inject as Inject9, Param, Post as Post2, Query, Req as Req2, Res } from "@nestjs/common";
|
|
3164
3383
|
function _ts_decorate11(decorators, target, key, desc) {
|
|
3165
3384
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3166
3385
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -3197,7 +3416,7 @@ function sendMode(body) {
|
|
|
3197
3416
|
if (body.mode === "auto" || body.mode === "queue" || body.mode === "interrupt") {
|
|
3198
3417
|
return body.mode;
|
|
3199
3418
|
}
|
|
3200
|
-
throw new
|
|
3419
|
+
throw new BadRequestException4("mode must be 'auto', 'queue' or 'interrupt'");
|
|
3201
3420
|
}
|
|
3202
3421
|
__name(sendMode, "sendMode");
|
|
3203
3422
|
function attachmentRefs(claimed) {
|
|
@@ -3205,21 +3424,21 @@ function attachmentRefs(claimed) {
|
|
|
3205
3424
|
return [];
|
|
3206
3425
|
}
|
|
3207
3426
|
if (!Array.isArray(claimed)) {
|
|
3208
|
-
throw new
|
|
3427
|
+
throw new BadRequestException4("attachments must be an array of { mediaId }");
|
|
3209
3428
|
}
|
|
3210
3429
|
if (claimed.length > MAX_ATTACHMENTS_PER_MESSAGE) {
|
|
3211
|
-
throw new
|
|
3430
|
+
throw new BadRequestException4(`a message may carry at most ${MAX_ATTACHMENTS_PER_MESSAGE} attachments`);
|
|
3212
3431
|
}
|
|
3213
3432
|
return claimed.map((entry) => {
|
|
3214
3433
|
if (typeof entry !== "object" || entry === null || !("mediaId" in entry)) {
|
|
3215
|
-
throw new
|
|
3434
|
+
throw new BadRequestException4("each attachment must be an object with a mediaId");
|
|
3216
3435
|
}
|
|
3217
3436
|
if (Object.keys(entry).some((key) => key !== "mediaId")) {
|
|
3218
|
-
throw new
|
|
3437
|
+
throw new BadRequestException4("attachments are { mediaId } refs \u2014 send nothing but the id");
|
|
3219
3438
|
}
|
|
3220
3439
|
const { mediaId } = entry;
|
|
3221
3440
|
if (typeof mediaId !== "string" || mediaId.length === 0) {
|
|
3222
|
-
throw new
|
|
3441
|
+
throw new BadRequestException4("each attachment must carry a non-empty string mediaId");
|
|
3223
3442
|
}
|
|
3224
3443
|
return {
|
|
3225
3444
|
mediaId
|
|
@@ -3256,6 +3475,9 @@ var ChatController = class {
|
|
|
3256
3475
|
...body.agent !== void 0 ? {
|
|
3257
3476
|
agentName: body.agent
|
|
3258
3477
|
} : {},
|
|
3478
|
+
...typeof body.persona === "string" && body.persona.length > 0 ? {
|
|
3479
|
+
personaId: body.persona
|
|
3480
|
+
} : {},
|
|
3259
3481
|
...attachments.length > 0 ? {
|
|
3260
3482
|
attachments
|
|
3261
3483
|
} : {},
|
|
@@ -3882,7 +4104,7 @@ ModelsController = _ts_decorate15([
|
|
|
3882
4104
|
|
|
3883
4105
|
// src/controller/queue.controller.ts
|
|
3884
4106
|
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER7 } from "@dudousxd/nestjs-agent-core";
|
|
3885
|
-
import { BadRequestException as
|
|
4107
|
+
import { BadRequestException as BadRequestException5, Body as Body3, Controller as Controller8, Delete as Delete2, Get as Get7, Inject as Inject14, Param as Param4, Patch, Post as Post4, Req as Req7 } from "@nestjs/common";
|
|
3886
4108
|
function _ts_decorate16(decorators, target, key, desc) {
|
|
3887
4109
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3888
4110
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -3932,10 +4154,10 @@ var QueueController = class {
|
|
|
3932
4154
|
async update(req, messageId, body) {
|
|
3933
4155
|
const actor = await this.actorResolver.resolve(req);
|
|
3934
4156
|
if (body.message !== void 0 && typeof body.message !== "string") {
|
|
3935
|
-
throw new
|
|
4157
|
+
throw new BadRequestException5("message must be a string");
|
|
3936
4158
|
}
|
|
3937
4159
|
if (body.position !== void 0 && typeof body.position !== "number") {
|
|
3938
|
-
throw new
|
|
4160
|
+
throw new BadRequestException5("position must be a number");
|
|
3939
4161
|
}
|
|
3940
4162
|
const attachments = body.attachments === void 0 ? void 0 : body.attachments === null ? null : attachmentRefs(body.attachments);
|
|
3941
4163
|
return this.agent.updateQueuedMessage(actor, messageId, {
|
|
@@ -4255,6 +4477,9 @@ var ThreadsController = class {
|
|
|
4255
4477
|
} : {},
|
|
4256
4478
|
..."model" in body ? {
|
|
4257
4479
|
model: body.model ?? null
|
|
4480
|
+
} : {},
|
|
4481
|
+
..."persona" in body ? {
|
|
4482
|
+
persona: body.persona ?? null
|
|
4258
4483
|
} : {}
|
|
4259
4484
|
});
|
|
4260
4485
|
return {
|
|
@@ -4369,7 +4594,7 @@ ThreadsController = _ts_decorate19([
|
|
|
4369
4594
|
|
|
4370
4595
|
// src/controller/tool-call.controller.ts
|
|
4371
4596
|
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER11 } from "@dudousxd/nestjs-agent-core";
|
|
4372
|
-
import { BadRequestException as
|
|
4597
|
+
import { BadRequestException as BadRequestException6, Body as Body5, Controller as Controller12, Inject as Inject18, Post as Post6, Req as Req11 } from "@nestjs/common";
|
|
4373
4598
|
function _ts_decorate20(decorators, target, key, desc) {
|
|
4374
4599
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4375
4600
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -4404,7 +4629,7 @@ var MAX_VIA_LENGTH = 64;
|
|
|
4404
4629
|
var DEFAULT_VIA = "web";
|
|
4405
4630
|
function toolCallId(claimed) {
|
|
4406
4631
|
if (typeof claimed !== "string" || claimed.length === 0) {
|
|
4407
|
-
throw new
|
|
4632
|
+
throw new BadRequestException6("toolCallId must be a non-empty string");
|
|
4408
4633
|
}
|
|
4409
4634
|
return claimed;
|
|
4410
4635
|
}
|
|
@@ -4414,10 +4639,10 @@ function rejectReason(claimed) {
|
|
|
4414
4639
|
return void 0;
|
|
4415
4640
|
}
|
|
4416
4641
|
if (typeof claimed !== "string") {
|
|
4417
|
-
throw new
|
|
4642
|
+
throw new BadRequestException6("reason must be a string");
|
|
4418
4643
|
}
|
|
4419
4644
|
if (claimed.length > MAX_REJECT_REASON_LENGTH) {
|
|
4420
|
-
throw new
|
|
4645
|
+
throw new BadRequestException6(`reason must be at most ${MAX_REJECT_REASON_LENGTH} characters`);
|
|
4421
4646
|
}
|
|
4422
4647
|
return claimed;
|
|
4423
4648
|
}
|
|
@@ -4427,7 +4652,7 @@ function remember(claimed) {
|
|
|
4427
4652
|
return false;
|
|
4428
4653
|
}
|
|
4429
4654
|
if (typeof claimed !== "boolean") {
|
|
4430
|
-
throw new
|
|
4655
|
+
throw new BadRequestException6("remember must be a boolean");
|
|
4431
4656
|
}
|
|
4432
4657
|
return claimed;
|
|
4433
4658
|
}
|
|
@@ -4437,7 +4662,7 @@ function via(claimed) {
|
|
|
4437
4662
|
return DEFAULT_VIA;
|
|
4438
4663
|
}
|
|
4439
4664
|
if (typeof claimed !== "string" || claimed.length === 0 || claimed.length > MAX_VIA_LENGTH) {
|
|
4440
|
-
throw new
|
|
4665
|
+
throw new BadRequestException6(`via must be a string of 1-${MAX_VIA_LENGTH} characters`);
|
|
4441
4666
|
}
|
|
4442
4667
|
return claimed;
|
|
4443
4668
|
}
|
|
@@ -4447,26 +4672,26 @@ function answers(claimed) {
|
|
|
4447
4672
|
return void 0;
|
|
4448
4673
|
}
|
|
4449
4674
|
if (typeof claimed !== "object" || claimed === null || Array.isArray(claimed)) {
|
|
4450
|
-
throw new
|
|
4675
|
+
throw new BadRequestException6("answers must be an object of questionId \u2192 chosen values");
|
|
4451
4676
|
}
|
|
4452
4677
|
const entries = Object.entries(claimed);
|
|
4453
4678
|
if (entries.length > MAX_ANSWERED_QUESTIONS) {
|
|
4454
|
-
throw new
|
|
4679
|
+
throw new BadRequestException6(`answers may cover at most ${MAX_ANSWERED_QUESTIONS} questions`);
|
|
4455
4680
|
}
|
|
4456
4681
|
const validated = /* @__PURE__ */ Object.create(null);
|
|
4457
4682
|
for (const [questionId, values] of entries) {
|
|
4458
4683
|
if (!Array.isArray(values)) {
|
|
4459
|
-
throw new
|
|
4684
|
+
throw new BadRequestException6(`answers["${questionId}"] must be an array of chosen values`);
|
|
4460
4685
|
}
|
|
4461
4686
|
if (values.length > MAX_VALUES_PER_QUESTION) {
|
|
4462
|
-
throw new
|
|
4687
|
+
throw new BadRequestException6(`answers["${questionId}"] may carry at most ${MAX_VALUES_PER_QUESTION} values`);
|
|
4463
4688
|
}
|
|
4464
4689
|
for (const value of values) {
|
|
4465
4690
|
if (typeof value !== "string") {
|
|
4466
|
-
throw new
|
|
4691
|
+
throw new BadRequestException6(`answers["${questionId}"] must contain only strings`);
|
|
4467
4692
|
}
|
|
4468
4693
|
if (value.length > MAX_ANSWER_VALUE_LENGTH) {
|
|
4469
|
-
throw new
|
|
4694
|
+
throw new BadRequestException6(`answers["${questionId}"] values must be at most ${MAX_ANSWER_VALUE_LENGTH} characters`);
|
|
4470
4695
|
}
|
|
4471
4696
|
}
|
|
4472
4697
|
validated[questionId] = values;
|
|
@@ -4583,7 +4808,7 @@ ToolCallController = _ts_decorate20([
|
|
|
4583
4808
|
], ToolCallController);
|
|
4584
4809
|
|
|
4585
4810
|
// src/controller/tools.controller.ts
|
|
4586
|
-
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER12, AGENT_DEPS_FACTORY as
|
|
4811
|
+
import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER12, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY6, AGENT_REGISTRY as AGENT_REGISTRY3, ALL_AGENTS, AgentRegistry as AgentRegistry4 } from "@dudousxd/nestjs-agent-core";
|
|
4587
4812
|
import { Controller as Controller13, Get as Get11, Inject as Inject19, NotFoundException as NotFoundException3, Query as Query5, Req as Req12 } from "@nestjs/common";
|
|
4588
4813
|
function _ts_decorate21(decorators, target, key, desc) {
|
|
4589
4814
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -4668,7 +4893,7 @@ _ts_decorate21([
|
|
|
4668
4893
|
ToolsController = _ts_decorate21([
|
|
4669
4894
|
Controller13("tools"),
|
|
4670
4895
|
_ts_param19(0, Inject19(AGENT_ACTOR_RESOLVER12)),
|
|
4671
|
-
_ts_param19(1, Inject19(
|
|
4896
|
+
_ts_param19(1, Inject19(AGENT_DEPS_FACTORY6)),
|
|
4672
4897
|
_ts_param19(2, Inject19(AGENT_REGISTRY3)),
|
|
4673
4898
|
_ts_metadata20("design:type", Function),
|
|
4674
4899
|
_ts_metadata20("design:paramtypes", [
|
|
@@ -4750,6 +4975,7 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
|
|
|
4750
4975
|
}
|
|
4751
4976
|
this.collectContributors(instance);
|
|
4752
4977
|
}
|
|
4978
|
+
this.assertPersonas(this.registry.list());
|
|
4753
4979
|
}
|
|
4754
4980
|
/** Build the internal {@link AgentDefinition} from an `@Agent` instance and its options. */
|
|
4755
4981
|
definitionFrom(instance, meta) {
|
|
@@ -4793,10 +5019,48 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
|
|
|
4793
5019
|
} : {},
|
|
4794
5020
|
...meta.handoff !== void 0 ? {
|
|
4795
5021
|
delegatesTo: this.handoffEdges(meta)
|
|
5022
|
+
} : {},
|
|
5023
|
+
...meta.personas !== void 0 ? {
|
|
5024
|
+
personas: meta.personas
|
|
5025
|
+
} : {},
|
|
5026
|
+
...meta.defaultPersona !== void 0 ? {
|
|
5027
|
+
defaultPersona: meta.defaultPersona
|
|
4796
5028
|
} : {}
|
|
4797
5029
|
};
|
|
4798
5030
|
}
|
|
4799
5031
|
/**
|
|
5032
|
+
* Refuse to boot on a persona declaration that could only fail later, per request: a default that
|
|
5033
|
+
* names no persona, an id declared twice, an alias two personas claim, or an alias that is a real
|
|
5034
|
+
* agent's name (which would never be reached — a registered agent always wins).
|
|
5035
|
+
*/
|
|
5036
|
+
assertPersonas(definitions) {
|
|
5037
|
+
const agentNames = new Set(definitions.map((definition) => definition.name));
|
|
5038
|
+
const aliasOwner = /* @__PURE__ */ new Map();
|
|
5039
|
+
for (const definition of definitions) {
|
|
5040
|
+
const ids = /* @__PURE__ */ new Set();
|
|
5041
|
+
for (const persona of definition.personas ?? []) {
|
|
5042
|
+
if (ids.has(persona.id)) {
|
|
5043
|
+
throw new Error(`Agent "${definition.name}" declares persona "${persona.id}" twice.`);
|
|
5044
|
+
}
|
|
5045
|
+
ids.add(persona.id);
|
|
5046
|
+
for (const alias of persona.aliases ?? []) {
|
|
5047
|
+
const owner = `${definition.name}/${persona.id}`;
|
|
5048
|
+
if (agentNames.has(alias)) {
|
|
5049
|
+
throw new Error(`Persona ${owner} claims the alias "${alias}", which is a registered agent's name.`);
|
|
5050
|
+
}
|
|
5051
|
+
const previous = aliasOwner.get(alias);
|
|
5052
|
+
if (previous !== void 0) {
|
|
5053
|
+
throw new Error(`Personas ${previous} and ${owner} both claim the alias "${alias}".`);
|
|
5054
|
+
}
|
|
5055
|
+
aliasOwner.set(alias, owner);
|
|
5056
|
+
}
|
|
5057
|
+
}
|
|
5058
|
+
if (definition.defaultPersona !== void 0 && !ids.has(definition.defaultPersona)) {
|
|
5059
|
+
throw new Error(`Agent "${definition.name}" names "${definition.defaultPersona}" as its default persona, but declares no persona with that id.`);
|
|
5060
|
+
}
|
|
5061
|
+
}
|
|
5062
|
+
}
|
|
5063
|
+
/**
|
|
4800
5064
|
* Resolve each handoff entry to an {@link AgentDelegation} — its target's registered name, plus
|
|
4801
5065
|
* whether that edge detaches (skipping non-agent classes). A bare name is kept for a plain edge
|
|
4802
5066
|
* rather than an always-object form, so a definition an older host built by hand still reads.
|
|
@@ -5228,7 +5492,7 @@ var LedgerQuotaProvider = class {
|
|
|
5228
5492
|
};
|
|
5229
5493
|
|
|
5230
5494
|
// src/runner/inline-agent-runner.ts
|
|
5231
|
-
import { AGENT_DEPS_FACTORY as
|
|
5495
|
+
import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY7, AGENT_STORE as AGENT_STORE6, RUN_ENDED_BEFORE_TOOL_CALL as RUN_ENDED_BEFORE_TOOL_CALL2, RunCancelledError as RunCancelledError2, agentFailureCode as agentFailureCode2, encodeStreamEvent as encodeStreamEvent5, publishAgentRunFailed as publishAgentRunFailed2, releaseThreadRun as releaseThreadRun3, runAgentLoop as runAgentLoop2, settleAll as settleAll2, settleUnsettledDelegation as settleUnsettledDelegation3, streamFailure as streamFailure3 } from "@dudousxd/nestjs-agent-core";
|
|
5232
5496
|
import { Inject as Inject23, Injectable as Injectable11, Logger as Logger7, Optional as Optional10 } from "@nestjs/common";
|
|
5233
5497
|
function _ts_decorate25(decorators, target, key, desc) {
|
|
5234
5498
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -5708,7 +5972,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
|
|
|
5708
5972
|
};
|
|
5709
5973
|
InlineAgentRunner = _ts_decorate25([
|
|
5710
5974
|
Injectable11(),
|
|
5711
|
-
_ts_param23(0, Inject23(
|
|
5975
|
+
_ts_param23(0, Inject23(AGENT_DEPS_FACTORY7)),
|
|
5712
5976
|
_ts_param23(1, Inject23(AGENT_STORE6)),
|
|
5713
5977
|
_ts_param23(2, Optional10()),
|
|
5714
5978
|
_ts_metadata24("design:type", Function),
|
|
@@ -5920,7 +6184,7 @@ function sharedProviders(durable) {
|
|
|
5920
6184
|
},
|
|
5921
6185
|
AgentDepsFactory2,
|
|
5922
6186
|
{
|
|
5923
|
-
provide:
|
|
6187
|
+
provide: AGENT_DEPS_FACTORY8,
|
|
5924
6188
|
useExisting: AgentDepsFactory2
|
|
5925
6189
|
},
|
|
5926
6190
|
// Populates the registry + contributors (onModuleInit) BEFORE AiToolDiscoveryService synthesizes
|
|
@@ -5993,7 +6257,7 @@ function exportsFor() {
|
|
|
5993
6257
|
AGENT_PROMPT_CONTRIBUTORS3,
|
|
5994
6258
|
AGENT_SKILLS3,
|
|
5995
6259
|
AGENT_MEMORY3,
|
|
5996
|
-
|
|
6260
|
+
AGENT_DEPS_FACTORY8,
|
|
5997
6261
|
AgentDepsFactory2,
|
|
5998
6262
|
AgentService,
|
|
5999
6263
|
ChatQueueService2,
|