@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/index.cjs
CHANGED
|
@@ -74,6 +74,7 @@ __export(index_exports, {
|
|
|
74
74
|
requestUserActorResolver: () => requestUserActorResolver,
|
|
75
75
|
resolveSkillsConfig: () => resolveSkillsConfig,
|
|
76
76
|
skillScope: () => skillScope,
|
|
77
|
+
threadPersona: () => threadPersona,
|
|
77
78
|
toolNameFromClass: () => toolNameFromClass,
|
|
78
79
|
utcDay: () => utcDay
|
|
79
80
|
});
|
|
@@ -185,8 +186,64 @@ var AgentDepsFactory2 = class {
|
|
|
185
186
|
...delegated
|
|
186
187
|
];
|
|
187
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* The agent a name stands for: itself when it is a registered agent (or unknown — the bare
|
|
191
|
+
* assistant), else the agent whose persona took the name over (`Persona.aliases`) and that persona.
|
|
192
|
+
*/
|
|
193
|
+
resolveAgent(name) {
|
|
194
|
+
if (this.agents.has(name)) {
|
|
195
|
+
return {
|
|
196
|
+
agentName: name
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const alias = (0, import_nestjs_agent_core.resolvePersonaAlias)(this.agents.list(), name);
|
|
200
|
+
return alias === void 0 ? {
|
|
201
|
+
agentName: name
|
|
202
|
+
} : {
|
|
203
|
+
agentName: alias.agent,
|
|
204
|
+
persona: alias.persona
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/** `agentName`'s personas as a picker reads them. Empty when it declares none. */
|
|
208
|
+
personaCatalog(agentName) {
|
|
209
|
+
return (this.agents.get(agentName)?.personas ?? []).map(import_nestjs_agent_core.personaCatalogEntry);
|
|
210
|
+
}
|
|
211
|
+
/** The persona `agentName` runs under when nothing names one. Undefined → none. */
|
|
212
|
+
defaultPersona(agentName) {
|
|
213
|
+
return this.agents.get(agentName)?.defaultPersona;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* The persona a turn of `agentName` runs under, most specific first: the one the send names
|
|
217
|
+
* (refused with `400 persona_not_found` when the agent does not declare it), else the thread's
|
|
218
|
+
* pinned one when this agent declares it, else the agent's default. Undefined → none.
|
|
219
|
+
*/
|
|
220
|
+
resolvePersona(args) {
|
|
221
|
+
const definition = this.agents.get(args.agentName);
|
|
222
|
+
if (args.requested !== void 0) {
|
|
223
|
+
if ((0, import_nestjs_agent_core.findPersona)(definition, args.requested) === void 0) {
|
|
224
|
+
throw new import_common.BadRequestException({
|
|
225
|
+
statusCode: 400,
|
|
226
|
+
code: "persona_not_found",
|
|
227
|
+
message: `agent "${args.agentName}" has no persona "${args.requested}"`
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
return args.requested;
|
|
231
|
+
}
|
|
232
|
+
const pinned = args.threadPersona ?? void 0;
|
|
233
|
+
if (pinned !== void 0 && (0, import_nestjs_agent_core.findPersona)(definition, pinned) !== void 0) {
|
|
234
|
+
return pinned;
|
|
235
|
+
}
|
|
236
|
+
return definition?.defaultPersona;
|
|
237
|
+
}
|
|
188
238
|
forAgent(agentName) {
|
|
189
239
|
const name = agentName ?? this.defaultAgentName();
|
|
240
|
+
if (agentName !== void 0 && !this.agents.has(agentName)) {
|
|
241
|
+
const alias = (0, import_nestjs_agent_core.resolvePersonaAlias)(this.agents.list(), agentName);
|
|
242
|
+
const persona = alias === void 0 ? void 0 : (0, import_nestjs_agent_core.findPersona)(this.agents.get(alias.agent), alias.persona);
|
|
243
|
+
if (alias !== void 0 && persona !== void 0) {
|
|
244
|
+
return this.withPersona(this.forAgent(alias.agent), persona);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
190
247
|
const definition = this.agents.get(name);
|
|
191
248
|
const toolAllowList = this.effectiveTools(definition);
|
|
192
249
|
const followUpsCount = this.followUpsCount();
|
|
@@ -251,6 +308,9 @@ var AgentDepsFactory2 = class {
|
|
|
251
308
|
...toolAllowList !== void 0 ? {
|
|
252
309
|
toolAllowList
|
|
253
310
|
} : {},
|
|
311
|
+
...definition?.personas !== void 0 ? {
|
|
312
|
+
personas: definition.personas
|
|
313
|
+
} : {},
|
|
254
314
|
...this.options.toolTimeoutMs !== void 0 ? {
|
|
255
315
|
toolTimeoutMs: this.options.toolTimeoutMs
|
|
256
316
|
} : {},
|
|
@@ -269,6 +329,45 @@ var AgentDepsFactory2 = class {
|
|
|
269
329
|
};
|
|
270
330
|
}
|
|
271
331
|
/**
|
|
332
|
+
* A persona baked into an agent's deps — how a run journaled under an agent name that a persona
|
|
333
|
+
* has since taken over (`Persona.aliases`) is served. That run names no persona of its own (it
|
|
334
|
+
* predates them, and its input cannot change), so the persona applies the way the old agent's own
|
|
335
|
+
* config did: as config, re-read on every replay, with no checkpoint of its own.
|
|
336
|
+
*/
|
|
337
|
+
withPersona(deps, persona) {
|
|
338
|
+
const base = deps.systemPrompt;
|
|
339
|
+
const ref = {
|
|
340
|
+
id: persona.id,
|
|
341
|
+
label: persona.label
|
|
342
|
+
};
|
|
343
|
+
const resolve = /* @__PURE__ */ __name(async (prompt, ctx) => typeof prompt === "function" ? prompt(ctx) : prompt, "resolve");
|
|
344
|
+
const own = persona.systemPrompt;
|
|
345
|
+
const systemPrompt = /* @__PURE__ */ __name(async (ctx) => {
|
|
346
|
+
const scoped = {
|
|
347
|
+
...ctx,
|
|
348
|
+
persona: ref
|
|
349
|
+
};
|
|
350
|
+
if (own === void 0) {
|
|
351
|
+
return resolve(base, scoped);
|
|
352
|
+
}
|
|
353
|
+
const basePrompt = typeof own === "function" ? await resolve(base, scoped) : void 0;
|
|
354
|
+
return resolve(own, {
|
|
355
|
+
...scoped,
|
|
356
|
+
...basePrompt !== void 0 ? {
|
|
357
|
+
basePrompt
|
|
358
|
+
} : {}
|
|
359
|
+
});
|
|
360
|
+
}, "systemPrompt");
|
|
361
|
+
const toolAllowList = (0, import_nestjs_agent_core.intersectAllowLists)(deps.toolAllowList, persona.allowedTools);
|
|
362
|
+
return {
|
|
363
|
+
...deps,
|
|
364
|
+
systemPrompt,
|
|
365
|
+
...toolAllowList !== void 0 ? {
|
|
366
|
+
toolAllowList
|
|
367
|
+
} : {}
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
272
371
|
* The ceiling on how much of a thread this agent's turns carry, most specific wins: the agent's
|
|
273
372
|
* own `@Agent({ history })`, else a module-wide custom `historyPolicy`, else the module-wide
|
|
274
373
|
* `history` window. Undefined → unbounded, the behaviour of a module that configures none.
|
|
@@ -371,6 +470,18 @@ __name(childSinkWriter, "childSinkWriter");
|
|
|
371
470
|
// src/queue/chat-queue.service.ts
|
|
372
471
|
var import_nestjs_agent_core3 = require("@dudousxd/nestjs-agent-core");
|
|
373
472
|
var import_common2 = require("@nestjs/common");
|
|
473
|
+
|
|
474
|
+
// src/thread-persona.ts
|
|
475
|
+
async function threadPersona(store, threadId) {
|
|
476
|
+
const projecting = store;
|
|
477
|
+
if (typeof projecting.personaForThread === "function") {
|
|
478
|
+
return projecting.personaForThread(threadId);
|
|
479
|
+
}
|
|
480
|
+
return (await store.getThread(threadId))?.persona ?? null;
|
|
481
|
+
}
|
|
482
|
+
__name(threadPersona, "threadPersona");
|
|
483
|
+
|
|
484
|
+
// src/queue/chat-queue.service.ts
|
|
374
485
|
function _ts_decorate2(decorators, target, key, desc) {
|
|
375
486
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
376
487
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -407,18 +518,20 @@ var ChatQueueService = class _ChatQueueService {
|
|
|
407
518
|
quotaProvider;
|
|
408
519
|
options;
|
|
409
520
|
staging;
|
|
521
|
+
deps;
|
|
410
522
|
logger = new import_common2.Logger(_ChatQueueService.name);
|
|
411
523
|
/**
|
|
412
524
|
* Runs this process claimed a thread for and has not handed to a runner yet. A holder in here is
|
|
413
525
|
* alive whatever the runner says — it simply has not registered the run yet.
|
|
414
526
|
*/
|
|
415
527
|
starting = /* @__PURE__ */ new Set();
|
|
416
|
-
constructor(store, sink, quotaProvider, options, staging) {
|
|
528
|
+
constructor(store, sink, quotaProvider, options, staging, deps) {
|
|
417
529
|
this.store = store;
|
|
418
530
|
this.sink = sink;
|
|
419
531
|
this.quotaProvider = quotaProvider;
|
|
420
532
|
this.options = options;
|
|
421
533
|
this.staging = staging;
|
|
534
|
+
this.deps = deps;
|
|
422
535
|
}
|
|
423
536
|
/** Whether the bound store can hold a queue. Without one, a busy thread is not queued. */
|
|
424
537
|
get supported() {
|
|
@@ -716,13 +829,17 @@ var ChatQueueService = class _ChatQueueService {
|
|
|
716
829
|
*/
|
|
717
830
|
async inputFor(message) {
|
|
718
831
|
const attachments = await this.freshAttachments(message.actor, message.attachments ?? []);
|
|
832
|
+
const { agentName, persona } = await this.targetFor(message);
|
|
719
833
|
return {
|
|
720
834
|
threadId: message.threadId,
|
|
721
835
|
actor: message.actor,
|
|
722
836
|
userText: message.content,
|
|
723
837
|
day: utcDay(),
|
|
724
|
-
...
|
|
725
|
-
agentName
|
|
838
|
+
...agentName !== void 0 ? {
|
|
839
|
+
agentName
|
|
840
|
+
} : {},
|
|
841
|
+
...persona !== void 0 ? {
|
|
842
|
+
persona
|
|
726
843
|
} : {},
|
|
727
844
|
...attachments.length > 0 ? {
|
|
728
845
|
attachments
|
|
@@ -735,6 +852,37 @@ var ChatQueueService = class _ChatQueueService {
|
|
|
735
852
|
} : {}
|
|
736
853
|
};
|
|
737
854
|
}
|
|
855
|
+
/**
|
|
856
|
+
* The agent and persona a queued message starts as. A message carries the persona its send
|
|
857
|
+
* resolved; one that carries none — queued before personas existed, or by a host that sets none —
|
|
858
|
+
* resolves it now, exactly as a send would: an agent name a persona took over, then the thread's
|
|
859
|
+
* pinned persona, then the agent's default. Never refused here: nobody is waiting on a 400.
|
|
860
|
+
*/
|
|
861
|
+
async targetFor(message) {
|
|
862
|
+
const deps = this.deps;
|
|
863
|
+
if (message.persona !== void 0 || deps === void 0 || message.agentName === void 0) {
|
|
864
|
+
return {
|
|
865
|
+
...message.agentName !== void 0 ? {
|
|
866
|
+
agentName: message.agentName
|
|
867
|
+
} : {},
|
|
868
|
+
...message.persona !== void 0 ? {
|
|
869
|
+
persona: message.persona
|
|
870
|
+
} : {}
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
const target = deps.resolveAgent(message.agentName);
|
|
874
|
+
const hasPersonas = deps.personaCatalog(target.agentName).length > 0;
|
|
875
|
+
const persona = target.persona ?? (hasPersonas ? deps.resolvePersona({
|
|
876
|
+
agentName: target.agentName,
|
|
877
|
+
threadPersona: await threadPersona(this.store, message.threadId)
|
|
878
|
+
}) : void 0);
|
|
879
|
+
return {
|
|
880
|
+
agentName: target.agentName,
|
|
881
|
+
...persona !== void 0 ? {
|
|
882
|
+
persona
|
|
883
|
+
} : {}
|
|
884
|
+
};
|
|
885
|
+
}
|
|
738
886
|
async freshAttachments(actor, attachments) {
|
|
739
887
|
const staging = this.staging;
|
|
740
888
|
if (attachments.length === 0 || staging === void 0 || typeof staging.resolve !== "function") {
|
|
@@ -762,13 +910,16 @@ ChatQueueService = _ts_decorate2([
|
|
|
762
910
|
_ts_param2(3, (0, import_common2.Inject)(import_nestjs_agent_core3.AGENT_OPTIONS)),
|
|
763
911
|
_ts_param2(4, (0, import_common2.Optional)()),
|
|
764
912
|
_ts_param2(4, (0, import_common2.Inject)(import_nestjs_agent_core3.AGENT_ATTACHMENT_STAGING)),
|
|
913
|
+
_ts_param2(5, (0, import_common2.Optional)()),
|
|
914
|
+
_ts_param2(5, (0, import_common2.Inject)(import_nestjs_agent_core3.AGENT_DEPS_FACTORY)),
|
|
765
915
|
_ts_metadata2("design:type", Function),
|
|
766
916
|
_ts_metadata2("design:paramtypes", [
|
|
767
917
|
typeof AgentStore === "undefined" ? Object : AgentStore,
|
|
768
918
|
typeof TokenStreamSink === "undefined" ? Object : TokenStreamSink,
|
|
769
919
|
typeof QuotaProvider === "undefined" ? Object : QuotaProvider,
|
|
770
920
|
typeof Pick === "undefined" ? Object : Pick,
|
|
771
|
-
typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore
|
|
921
|
+
typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore,
|
|
922
|
+
typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
|
|
772
923
|
])
|
|
773
924
|
], ChatQueueService);
|
|
774
925
|
function pauseReasonFor(outcome, head) {
|
|
@@ -1022,7 +1173,9 @@ var AgentService = class {
|
|
|
1022
1173
|
*/
|
|
1023
1174
|
async send(params) {
|
|
1024
1175
|
await this.assertWithinQuota(params.actor);
|
|
1025
|
-
const
|
|
1176
|
+
const target = this.deps.resolveAgent(await this.resolveAgentName(params.agentName, params.threadId));
|
|
1177
|
+
const agentName = target.agentName;
|
|
1178
|
+
const persona = await this.resolvePersona(agentName, params.personaId ?? target.persona, params.threadId);
|
|
1026
1179
|
const model = await this.resolveModel(params.actor, agentName, params.model, params.threadId);
|
|
1027
1180
|
const attachments = await this.resolveAttachments(params.actor, params.attachments ?? []);
|
|
1028
1181
|
let threadId = params.threadId;
|
|
@@ -1037,11 +1190,17 @@ var AgentService = class {
|
|
|
1037
1190
|
} : {},
|
|
1038
1191
|
...params.newThreadId !== void 0 ? {
|
|
1039
1192
|
id: params.newThreadId
|
|
1193
|
+
} : {},
|
|
1194
|
+
...params.personaId !== void 0 ? {
|
|
1195
|
+
persona: params.personaId
|
|
1040
1196
|
} : {}
|
|
1041
1197
|
});
|
|
1042
1198
|
threadId = created.id;
|
|
1043
1199
|
} else {
|
|
1044
1200
|
await this.assertOwnsThread(params.actor, threadId);
|
|
1201
|
+
if (params.personaId !== void 0) {
|
|
1202
|
+
await this.pinThreadPersona(threadId, params.personaId);
|
|
1203
|
+
}
|
|
1045
1204
|
}
|
|
1046
1205
|
const input = {
|
|
1047
1206
|
threadId,
|
|
@@ -1049,6 +1208,9 @@ var AgentService = class {
|
|
|
1049
1208
|
userText: params.message,
|
|
1050
1209
|
day: utcDay(),
|
|
1051
1210
|
agentName,
|
|
1211
|
+
...persona !== void 0 ? {
|
|
1212
|
+
persona
|
|
1213
|
+
} : {},
|
|
1052
1214
|
...params.regenerate === true ? {
|
|
1053
1215
|
regenerate: true
|
|
1054
1216
|
} : {},
|
|
@@ -1135,6 +1297,9 @@ var AgentService = class {
|
|
|
1135
1297
|
...input.agentName !== void 0 ? {
|
|
1136
1298
|
agentName: input.agentName
|
|
1137
1299
|
} : {},
|
|
1300
|
+
...input.persona !== void 0 ? {
|
|
1301
|
+
persona: input.persona
|
|
1302
|
+
} : {},
|
|
1138
1303
|
...input.model !== void 0 ? {
|
|
1139
1304
|
model: input.model
|
|
1140
1305
|
} : {},
|
|
@@ -1529,16 +1694,22 @@ var AgentService = class {
|
|
|
1529
1694
|
async updateThread(actor, threadId, patch) {
|
|
1530
1695
|
const title = patch.title !== void 0 ? this.validateTitle(patch.title) : void 0;
|
|
1531
1696
|
await this.assertOwnsThread(actor, threadId);
|
|
1532
|
-
if (patch.defaultAgent === void 0 && patch.model === void 0) {
|
|
1697
|
+
if (patch.defaultAgent === void 0 && patch.model === void 0 && patch.persona === void 0) {
|
|
1533
1698
|
if (title !== void 0) {
|
|
1534
1699
|
await this.store.setTitle(threadId, title);
|
|
1535
1700
|
}
|
|
1536
1701
|
return;
|
|
1537
1702
|
}
|
|
1538
1703
|
if (this.store.updateThread === void 0) {
|
|
1539
|
-
throw new import_common4.NotImplementedException("Setting a thread's defaultAgent or
|
|
1704
|
+
throw new import_common4.NotImplementedException("Setting a thread's defaultAgent, model or persona requires an AgentStore that implements updateThread(); the bound store does not support it.");
|
|
1540
1705
|
}
|
|
1541
1706
|
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);
|
|
1707
|
+
if (patch.persona !== void 0 && patch.persona !== null) {
|
|
1708
|
+
this.deps.resolvePersona({
|
|
1709
|
+
agentName: this.deps.resolveAgent(patch.defaultAgent ?? await this.resolveAgentName(void 0, threadId)).agentName,
|
|
1710
|
+
requested: patch.persona
|
|
1711
|
+
});
|
|
1712
|
+
}
|
|
1542
1713
|
await this.store.updateThread(threadId, {
|
|
1543
1714
|
...title !== void 0 ? {
|
|
1544
1715
|
title
|
|
@@ -1548,9 +1719,39 @@ var AgentService = class {
|
|
|
1548
1719
|
} : {},
|
|
1549
1720
|
...model !== void 0 ? {
|
|
1550
1721
|
model
|
|
1722
|
+
} : {},
|
|
1723
|
+
...patch.persona !== void 0 ? {
|
|
1724
|
+
persona: patch.persona
|
|
1551
1725
|
} : {}
|
|
1552
1726
|
});
|
|
1553
1727
|
}
|
|
1728
|
+
/**
|
|
1729
|
+
* The persona this send runs under — see {@link AgentDepsFactory.resolvePersona}. The thread's
|
|
1730
|
+
* pinned persona is read only when the send names none AND the agent has personas to pick from.
|
|
1731
|
+
*/
|
|
1732
|
+
async resolvePersona(agentName, requested, threadId) {
|
|
1733
|
+
const needsThread = requested === void 0 && threadId !== void 0 && this.deps.personaCatalog(agentName).length > 0;
|
|
1734
|
+
return this.deps.resolvePersona({
|
|
1735
|
+
agentName,
|
|
1736
|
+
...requested !== void 0 ? {
|
|
1737
|
+
requested
|
|
1738
|
+
} : {},
|
|
1739
|
+
...needsThread ? {
|
|
1740
|
+
threadPersona: await threadPersona(this.store, threadId)
|
|
1741
|
+
} : {}
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
/** Pin `persona` on the thread when it is not already — a no-op on a store that cannot. */
|
|
1745
|
+
async pinThreadPersona(threadId, persona) {
|
|
1746
|
+
if (this.store.updateThread === void 0) {
|
|
1747
|
+
return;
|
|
1748
|
+
}
|
|
1749
|
+
if (await threadPersona(this.store, threadId) !== persona) {
|
|
1750
|
+
await this.store.updateThread(threadId, {
|
|
1751
|
+
persona
|
|
1752
|
+
});
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1554
1755
|
validateTitle(title) {
|
|
1555
1756
|
const trimmed = title.trim();
|
|
1556
1757
|
if (trimmed.length === 0) {
|
|
@@ -1596,6 +1797,7 @@ var AgentService = class {
|
|
|
1596
1797
|
...thread,
|
|
1597
1798
|
defaultAgent: thread.defaultAgent ?? null,
|
|
1598
1799
|
model: thread.model ?? null,
|
|
1800
|
+
persona: thread.persona ?? null,
|
|
1599
1801
|
activeRunId: await this.store.activeRunForThread?.(thread.id) ?? thread.activeRunId ?? null
|
|
1600
1802
|
};
|
|
1601
1803
|
}
|
|
@@ -1997,13 +2199,22 @@ var AgentsController = class {
|
|
|
1997
2199
|
}
|
|
1998
2200
|
list() {
|
|
1999
2201
|
const defaultAgentName = this.depsFactory.defaultAgentName();
|
|
2000
|
-
return this.agents.list().map((definition) =>
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2202
|
+
return this.agents.list().map((definition) => {
|
|
2203
|
+
const personas = this.depsFactory.personaCatalog(definition.name);
|
|
2204
|
+
return {
|
|
2205
|
+
name: definition.name,
|
|
2206
|
+
description: definition.description ?? "",
|
|
2207
|
+
...definition.name === defaultAgentName ? {
|
|
2208
|
+
isDefault: true
|
|
2209
|
+
} : {},
|
|
2210
|
+
...personas.length > 0 ? {
|
|
2211
|
+
personas
|
|
2212
|
+
} : {},
|
|
2213
|
+
...definition.defaultPersona !== void 0 ? {
|
|
2214
|
+
defaultPersona: definition.defaultPersona
|
|
2215
|
+
} : {}
|
|
2216
|
+
};
|
|
2217
|
+
});
|
|
2007
2218
|
}
|
|
2008
2219
|
};
|
|
2009
2220
|
_ts_decorate5([
|
|
@@ -2273,6 +2484,9 @@ var ChatController = class {
|
|
|
2273
2484
|
...body.agent !== void 0 ? {
|
|
2274
2485
|
agentName: body.agent
|
|
2275
2486
|
} : {},
|
|
2487
|
+
...typeof body.persona === "string" && body.persona.length > 0 ? {
|
|
2488
|
+
personaId: body.persona
|
|
2489
|
+
} : {},
|
|
2276
2490
|
...attachments.length > 0 ? {
|
|
2277
2491
|
attachments
|
|
2278
2492
|
} : {},
|
|
@@ -3272,6 +3486,9 @@ var ThreadsController = class {
|
|
|
3272
3486
|
} : {},
|
|
3273
3487
|
..."model" in body ? {
|
|
3274
3488
|
model: body.model ?? null
|
|
3489
|
+
} : {},
|
|
3490
|
+
..."persona" in body ? {
|
|
3491
|
+
persona: body.persona ?? null
|
|
3275
3492
|
} : {}
|
|
3276
3493
|
});
|
|
3277
3494
|
return {
|
|
@@ -3785,6 +4002,7 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
|
|
|
3785
4002
|
}
|
|
3786
4003
|
this.collectContributors(instance);
|
|
3787
4004
|
}
|
|
4005
|
+
this.assertPersonas(this.registry.list());
|
|
3788
4006
|
}
|
|
3789
4007
|
/** Build the internal {@link AgentDefinition} from an `@Agent` instance and its options. */
|
|
3790
4008
|
definitionFrom(instance, meta) {
|
|
@@ -3828,10 +4046,48 @@ var AgentDiscoveryService = class _AgentDiscoveryService {
|
|
|
3828
4046
|
} : {},
|
|
3829
4047
|
...meta.handoff !== void 0 ? {
|
|
3830
4048
|
delegatesTo: this.handoffEdges(meta)
|
|
4049
|
+
} : {},
|
|
4050
|
+
...meta.personas !== void 0 ? {
|
|
4051
|
+
personas: meta.personas
|
|
4052
|
+
} : {},
|
|
4053
|
+
...meta.defaultPersona !== void 0 ? {
|
|
4054
|
+
defaultPersona: meta.defaultPersona
|
|
3831
4055
|
} : {}
|
|
3832
4056
|
};
|
|
3833
4057
|
}
|
|
3834
4058
|
/**
|
|
4059
|
+
* Refuse to boot on a persona declaration that could only fail later, per request: a default that
|
|
4060
|
+
* names no persona, an id declared twice, an alias two personas claim, or an alias that is a real
|
|
4061
|
+
* agent's name (which would never be reached — a registered agent always wins).
|
|
4062
|
+
*/
|
|
4063
|
+
assertPersonas(definitions) {
|
|
4064
|
+
const agentNames = new Set(definitions.map((definition) => definition.name));
|
|
4065
|
+
const aliasOwner = /* @__PURE__ */ new Map();
|
|
4066
|
+
for (const definition of definitions) {
|
|
4067
|
+
const ids = /* @__PURE__ */ new Set();
|
|
4068
|
+
for (const persona of definition.personas ?? []) {
|
|
4069
|
+
if (ids.has(persona.id)) {
|
|
4070
|
+
throw new Error(`Agent "${definition.name}" declares persona "${persona.id}" twice.`);
|
|
4071
|
+
}
|
|
4072
|
+
ids.add(persona.id);
|
|
4073
|
+
for (const alias of persona.aliases ?? []) {
|
|
4074
|
+
const owner = `${definition.name}/${persona.id}`;
|
|
4075
|
+
if (agentNames.has(alias)) {
|
|
4076
|
+
throw new Error(`Persona ${owner} claims the alias "${alias}", which is a registered agent's name.`);
|
|
4077
|
+
}
|
|
4078
|
+
const previous = aliasOwner.get(alias);
|
|
4079
|
+
if (previous !== void 0) {
|
|
4080
|
+
throw new Error(`Personas ${previous} and ${owner} both claim the alias "${alias}".`);
|
|
4081
|
+
}
|
|
4082
|
+
aliasOwner.set(alias, owner);
|
|
4083
|
+
}
|
|
4084
|
+
}
|
|
4085
|
+
if (definition.defaultPersona !== void 0 && !ids.has(definition.defaultPersona)) {
|
|
4086
|
+
throw new Error(`Agent "${definition.name}" names "${definition.defaultPersona}" as its default persona, but declares no persona with that id.`);
|
|
4087
|
+
}
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
4090
|
+
/**
|
|
3835
4091
|
* Resolve each handoff entry to an {@link AgentDelegation} — its target's registered name, plus
|
|
3836
4092
|
* whether that edge detaches (skipping non-agent classes). A bare name is kept for a plain edge
|
|
3837
4093
|
* rather than an always-object form, so a definition an older host built by hand still reads.
|
|
@@ -5425,6 +5681,9 @@ var AgUiRunHandler = class {
|
|
|
5425
5681
|
...forwarded.agent !== void 0 ? {
|
|
5426
5682
|
agentName: forwarded.agent
|
|
5427
5683
|
} : {},
|
|
5684
|
+
...forwarded.persona !== void 0 ? {
|
|
5685
|
+
personaId: forwarded.persona
|
|
5686
|
+
} : {},
|
|
5428
5687
|
...forwarded.model !== void 0 ? {
|
|
5429
5688
|
model: forwarded.model
|
|
5430
5689
|
} : {},
|
|
@@ -5740,6 +5999,7 @@ __reExport(index_exports, require("@dudousxd/nestjs-agent-core"), module.exports
|
|
|
5740
5999
|
requestUserActorResolver,
|
|
5741
6000
|
resolveSkillsConfig,
|
|
5742
6001
|
skillScope,
|
|
6002
|
+
threadPersona,
|
|
5743
6003
|
toolNameFromClass,
|
|
5744
6004
|
utcDay,
|
|
5745
6005
|
...require("@dudousxd/nestjs-agent-core")
|