@dudousxd/nestjs-agent 0.1.0 → 0.3.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.
@@ -68,7 +68,6 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
68
68
  const subThreadId = await ctx.step(`subthread:${agentName}`, async () => {
69
69
  const thread = await this.store.createThread({
70
70
  actor: input.actor,
71
- persona: "default",
72
71
  transient: true
73
72
  });
74
73
  return thread.id;
@@ -216,12 +215,12 @@ AgentDurableModule = _ts_decorate3([
216
215
  ], AgentDurableModule);
217
216
 
218
217
  // src/agent.module.ts
219
- import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER5, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY4, AGENT_DURABLE_RUNNER as AGENT_DURABLE_RUNNER2, AGENT_MODEL as AGENT_MODEL2, AGENT_OPTIONS as AGENT_OPTIONS3, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE2, AGENT_REGISTRY as AGENT_REGISTRY3, AGENT_ROLES_POLICY as AGENT_ROLES_POLICY2, AGENT_RUNNER as AGENT_RUNNER2, AGENT_SINK as AGENT_SINK2, AGENT_STORE as AGENT_STORE5, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY3, AgentRegistry as AgentRegistry3, DefaultRolesPolicy, ToolRegistry as ToolRegistry3 } from "@dudousxd/nestjs-agent-core";
218
+ import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER5, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY4, AGENT_DURABLE_RUNNER as AGENT_DURABLE_RUNNER2, AGENT_MODEL as AGENT_MODEL2, AGENT_OPTIONS as AGENT_OPTIONS3, AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS3, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE3, AGENT_REGISTRY as AGENT_REGISTRY4, AGENT_ROLES_POLICY as AGENT_ROLES_POLICY2, AGENT_RUNNER as AGENT_RUNNER2, AGENT_SINK as AGENT_SINK2, AGENT_STORE as AGENT_STORE5, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY3, AgentRegistry as AgentRegistry4, DefaultRolesPolicy, ToolRegistry as ToolRegistry3 } from "@dudousxd/nestjs-agent-core";
220
219
  import { Global as Global2, Module as Module2 } from "@nestjs/common";
221
220
  import { DiscoveryModule, RouterModule } from "@nestjs/core";
222
221
 
223
222
  // src/agent-deps.factory.ts
224
- import { AGENT_MODEL, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_ROLES_POLICY, AGENT_SINK, AGENT_STORE as AGENT_STORE2, AGENT_TOOL_REGISTRY, AgentRegistry as AgentRegistry2, ToolRegistry as ToolRegistry2 } from "@dudousxd/nestjs-agent-core";
223
+ import { AGENT_MODEL, AGENT_PROMPT_CONTRIBUTORS, AGENT_QUOTA_STORE, AGENT_REGISTRY, AGENT_ROLES_POLICY, AGENT_SINK, AGENT_STORE as AGENT_STORE2, AGENT_TOOL_REGISTRY, AgentRegistry as AgentRegistry2, ToolRegistry as ToolRegistry2 } from "@dudousxd/nestjs-agent-core";
225
224
  import { AGENT_OPTIONS } from "@dudousxd/nestjs-agent-core";
226
225
  import { Inject as Inject2, Injectable as Injectable3 } from "@nestjs/common";
227
226
  function _ts_decorate4(decorators, target, key, desc) {
@@ -256,8 +255,9 @@ var AgentDepsFactory2 = class {
256
255
  rolesPolicy;
257
256
  registry;
258
257
  agents;
258
+ promptContributors;
259
259
  quota;
260
- constructor(options, model, store, sink, rolesPolicy, registry, agents, quota) {
260
+ constructor(options, model, store, sink, rolesPolicy, registry, agents, promptContributors, quota) {
261
261
  this.options = options;
262
262
  this.model = model;
263
263
  this.store = store;
@@ -265,10 +265,19 @@ var AgentDepsFactory2 = class {
265
265
  this.rolesPolicy = rolesPolicy;
266
266
  this.registry = registry;
267
267
  this.agents = agents;
268
+ this.promptContributors = promptContributors;
268
269
  this.quota = quota;
269
270
  }
271
+ /**
272
+ * The agent a turn uses when the caller names none: the explicit `defaultAgent` option, else the
273
+ * sole registered `@Agent` when there is exactly one, else `'default'` (a bare assistant).
274
+ */
270
275
  defaultAgentName() {
271
- return this.options.defaultAgent?.name ?? "default";
276
+ if (this.options.defaultAgent !== void 0) {
277
+ return this.options.defaultAgent;
278
+ }
279
+ const registered = this.agents.list();
280
+ return registered.length === 1 ? registered[0]?.name ?? "default" : "default";
272
281
  }
273
282
  effectiveTools(definition) {
274
283
  if (definition === void 0) {
@@ -286,10 +295,6 @@ var AgentDepsFactory2 = class {
286
295
  forAgent(agentName) {
287
296
  const name = agentName ?? this.defaultAgentName();
288
297
  const definition = this.agents.get(name);
289
- const personas = /* @__PURE__ */ new Map();
290
- for (const persona of definition?.personas ?? []) {
291
- personas.set(persona.id, persona);
292
- }
293
298
  const toolAllowList = this.effectiveTools(definition);
294
299
  const followUpsCount = this.followUpsCount();
295
300
  const retrieval = this.options.retrieval;
@@ -299,10 +304,9 @@ var AgentDepsFactory2 = class {
299
304
  sink: this.sink,
300
305
  rolesPolicy: this.rolesPolicy,
301
306
  registry: this.registry,
307
+ promptContributors: this.promptContributors,
302
308
  systemPrompt: definition?.systemPrompt ?? "You are a helpful assistant.",
303
309
  maxSteps: definition?.maxSteps ?? 8,
304
- personas,
305
- defaultPersona: definition?.defaultPersona ?? "default",
306
310
  ...definition?.modelId !== void 0 ? {
307
311
  modelId: definition.modelId
308
312
  } : {},
@@ -347,7 +351,8 @@ AgentDepsFactory2 = _ts_decorate4([
347
351
  _ts_param2(4, Inject2(AGENT_ROLES_POLICY)),
348
352
  _ts_param2(5, Inject2(AGENT_TOOL_REGISTRY)),
349
353
  _ts_param2(6, Inject2(AGENT_REGISTRY)),
350
- _ts_param2(7, Inject2(AGENT_QUOTA_STORE)),
354
+ _ts_param2(7, Inject2(AGENT_PROMPT_CONTRIBUTORS)),
355
+ _ts_param2(8, Inject2(AGENT_QUOTA_STORE)),
351
356
  _ts_metadata3("design:type", Function),
352
357
  _ts_metadata3("design:paramtypes", [
353
358
  typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions,
@@ -357,12 +362,13 @@ AgentDepsFactory2 = _ts_decorate4([
357
362
  typeof RolesPolicy === "undefined" ? Object : RolesPolicy,
358
363
  typeof ToolRegistry2 === "undefined" ? Object : ToolRegistry2,
359
364
  typeof AgentRegistry2 === "undefined" ? Object : AgentRegistry2,
365
+ Array,
360
366
  Object
361
367
  ])
362
368
  ], AgentDepsFactory2);
363
369
 
364
370
  // src/agent.service.ts
365
- import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE3 } from "@dudousxd/nestjs-agent-core";
371
+ import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY2, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE3 } from "@dudousxd/nestjs-agent-core";
366
372
  import { BadRequestException, ForbiddenException, Inject as Inject3, Injectable as Injectable4, NotFoundException } from "@nestjs/common";
367
373
  function _ts_decorate5(decorators, target, key, desc) {
368
374
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -388,10 +394,12 @@ var AgentService = class {
388
394
  runner;
389
395
  store;
390
396
  deps;
391
- constructor(runner, store, deps) {
397
+ quota;
398
+ constructor(runner, store, deps, quota) {
392
399
  this.runner = runner;
393
400
  this.store = store;
394
401
  this.deps = deps;
402
+ this.quota = quota;
395
403
  }
396
404
  async chat(params) {
397
405
  const agentName = params.agentName ?? this.deps.defaultAgentName();
@@ -402,13 +410,14 @@ var AgentService = class {
402
410
  }
403
411
  const created = await this.store.createThread({
404
412
  actor: params.actor,
405
- persona: params.personaId ?? this.deps.forAgent(agentName).defaultPersona
413
+ ...params.transient === true ? {
414
+ transient: true
415
+ } : {}
406
416
  });
407
417
  threadId = created.id;
408
418
  } else if (params.regenerate === true) {
409
419
  await this.assertOwnsThread(params.actor, threadId);
410
420
  }
411
- const persona = this.resolvePersona(agentName, params.personaId);
412
421
  const input = {
413
422
  threadId,
414
423
  actor: params.actor,
@@ -418,9 +427,6 @@ var AgentService = class {
418
427
  ...params.regenerate === true ? {
419
428
  regenerate: true
420
429
  } : {},
421
- ...persona !== void 0 ? {
422
- persona
423
- } : {},
424
430
  ...params.pageContext !== void 0 ? {
425
431
  pageContext: params.pageContext
426
432
  } : {}
@@ -454,18 +460,6 @@ var AgentService = class {
454
460
  await this.assertOwnsActiveStream(actor, runId);
455
461
  return this.runner.cancel(runId);
456
462
  }
457
- resolvePersona(agentName, id) {
458
- const deps = this.deps.forAgent(agentName);
459
- return deps.personas.get(id ?? deps.defaultPersona);
460
- }
461
- personaCatalog(agentName) {
462
- return [
463
- ...this.deps.forAgent(agentName).personas.values()
464
- ].map((persona) => ({
465
- id: persona.id,
466
- label: persona.label
467
- }));
468
- }
469
463
  listThreads(actorRef) {
470
464
  return this.store.listThreads(actorRef);
471
465
  }
@@ -481,8 +475,53 @@ var AgentService = class {
481
475
  await this.assertOwnsThread(actor, threadId);
482
476
  return this.store.forkThread(threadId, fromMessageId);
483
477
  }
478
+ async renameThread(actor, threadId, title) {
479
+ const trimmed = title.trim();
480
+ if (trimmed.length === 0) {
481
+ throw new BadRequestException("title must not be empty");
482
+ }
483
+ if (trimmed.length > 200) {
484
+ throw new BadRequestException("title must be at most 200 characters");
485
+ }
486
+ await this.assertOwnsThread(actor, threadId);
487
+ return this.store.setTitle(threadId, trimmed);
488
+ }
489
+ async promoteThread(actor, threadId) {
490
+ await this.assertOwnsThread(actor, threadId);
491
+ return this.store.promoteThread(threadId);
492
+ }
493
+ /**
494
+ * Drop a message and everything after it — the "edit and resend" / "delete from here" primitive.
495
+ * The client then sends a fresh turn on the truncated thread. Ownership-gated like the other
496
+ * thread-scoped mutations.
497
+ */
498
+ async truncateThreadFrom(actor, threadId, messageId) {
499
+ await this.assertOwnsThread(actor, threadId);
500
+ return this.store.truncateFrom(threadId, messageId);
501
+ }
502
+ /**
503
+ * The day's usage for the badge: tokens + summed USD cost from the store, and the configured
504
+ * limit from the quota store (null → unlimited). `withinLimit` comes from the quota store so it
505
+ * can never drift from what enforcement uses.
506
+ */
484
507
  async quotaToday(actorRef) {
485
- return this.store.quotaToday(actorRef, utcDay());
508
+ const day = utcDay();
509
+ const { usedTokens, costUsd } = await this.store.quotaToday(actorRef, day);
510
+ if (this.quota === void 0) {
511
+ return {
512
+ usedTokens,
513
+ costUsd,
514
+ limitTokens: null,
515
+ withinLimit: true
516
+ };
517
+ }
518
+ const state = await this.quota.check(actorRef, day);
519
+ return {
520
+ usedTokens: state.usedTokens,
521
+ costUsd,
522
+ limitTokens: state.limitTokens,
523
+ withinLimit: state.withinLimit
524
+ };
486
525
  }
487
526
  /**
488
527
  * Authorization seam for thread-scoped endpoints: the caller must own the thread. A missing
@@ -533,11 +572,13 @@ AgentService = _ts_decorate5([
533
572
  _ts_param3(0, Inject3(AGENT_RUNNER)),
534
573
  _ts_param3(1, Inject3(AGENT_STORE3)),
535
574
  _ts_param3(2, Inject3(AGENT_DEPS_FACTORY2)),
575
+ _ts_param3(3, Inject3(AGENT_QUOTA_STORE2)),
536
576
  _ts_metadata4("design:type", Function),
537
577
  _ts_metadata4("design:paramtypes", [
538
578
  typeof AgentRunner === "undefined" ? Object : AgentRunner,
539
579
  typeof AgentStore === "undefined" ? Object : AgentStore,
540
- typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory
580
+ typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
581
+ Object
541
582
  ])
542
583
  ], AgentService);
543
584
 
@@ -582,14 +623,14 @@ var ChatController = class {
582
623
  ...body.agent !== void 0 ? {
583
624
  agentName: body.agent
584
625
  } : {},
585
- ...body.persona !== void 0 ? {
586
- personaId: body.persona
587
- } : {},
588
626
  ...body.pageContext !== void 0 ? {
589
627
  pageContext: body.pageContext
590
628
  } : {},
591
629
  ...body.regenerate === true ? {
592
630
  regenerate: true
631
+ } : {},
632
+ ...body.transient === true ? {
633
+ transient: true
593
634
  } : {}
594
635
  });
595
636
  await this.pipe(res, runId, threadId);
@@ -746,7 +787,7 @@ QuotaController = _ts_decorate7([
746
787
 
747
788
  // src/controller/threads.controller.ts
748
789
  import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER3 } from "@dudousxd/nestjs-agent-core";
749
- import { Controller as Controller3, Delete, Get as Get3, Inject as Inject6, Param as Param2, Post as Post2, Req as Req3 } from "@nestjs/common";
790
+ import { Body as Body2, Controller as Controller3, Delete, Get as Get3, Inject as Inject6, Param as Param2, Patch, Post as Post2, Req as Req3 } from "@nestjs/common";
750
791
  function _ts_decorate8(decorators, target, key, desc) {
751
792
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
752
793
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -778,9 +819,6 @@ var ThreadsController = class {
778
819
  const actor = await this.actorResolver.resolve(req);
779
820
  return this.agent.listThreads(actor.id);
780
821
  }
781
- personas() {
782
- return this.agent.personaCatalog();
783
- }
784
822
  async detail(req, id) {
785
823
  const actor = await this.actorResolver.resolve(req);
786
824
  return this.agent.getThread(actor, id);
@@ -796,6 +834,27 @@ var ThreadsController = class {
796
834
  const actor = await this.actorResolver.resolve(req);
797
835
  return this.agent.forkThread(actor, id, messageId);
798
836
  }
837
+ async rename(req, id, body) {
838
+ const actor = await this.actorResolver.resolve(req);
839
+ await this.agent.renameThread(actor, id, body.title);
840
+ return {
841
+ ok: true
842
+ };
843
+ }
844
+ async promote(req, id) {
845
+ const actor = await this.actorResolver.resolve(req);
846
+ await this.agent.promoteThread(actor, id);
847
+ return {
848
+ ok: true
849
+ };
850
+ }
851
+ async truncateFrom(req, id, messageId) {
852
+ const actor = await this.actorResolver.resolve(req);
853
+ await this.agent.truncateThreadFrom(actor, id, messageId);
854
+ return {
855
+ ok: true
856
+ };
857
+ }
799
858
  };
800
859
  _ts_decorate8([
801
860
  Get3(),
@@ -806,12 +865,6 @@ _ts_decorate8([
806
865
  ]),
807
866
  _ts_metadata7("design:returntype", Promise)
808
867
  ], ThreadsController.prototype, "list", null);
809
- _ts_decorate8([
810
- Get3("personas/catalog"),
811
- _ts_metadata7("design:type", Function),
812
- _ts_metadata7("design:paramtypes", []),
813
- _ts_metadata7("design:returntype", void 0)
814
- ], ThreadsController.prototype, "personas", null);
815
868
  _ts_decorate8([
816
869
  Get3(":id"),
817
870
  _ts_param6(0, Req3()),
@@ -847,6 +900,43 @@ _ts_decorate8([
847
900
  ]),
848
901
  _ts_metadata7("design:returntype", Promise)
849
902
  ], ThreadsController.prototype, "fork", null);
903
+ _ts_decorate8([
904
+ Patch(":id"),
905
+ _ts_param6(0, Req3()),
906
+ _ts_param6(1, Param2("id")),
907
+ _ts_param6(2, Body2()),
908
+ _ts_metadata7("design:type", Function),
909
+ _ts_metadata7("design:paramtypes", [
910
+ typeof Request === "undefined" ? Object : Request,
911
+ String,
912
+ typeof RenameThreadBody === "undefined" ? Object : RenameThreadBody
913
+ ]),
914
+ _ts_metadata7("design:returntype", Promise)
915
+ ], ThreadsController.prototype, "rename", null);
916
+ _ts_decorate8([
917
+ Post2(":id/promote"),
918
+ _ts_param6(0, Req3()),
919
+ _ts_param6(1, Param2("id")),
920
+ _ts_metadata7("design:type", Function),
921
+ _ts_metadata7("design:paramtypes", [
922
+ typeof Request === "undefined" ? Object : Request,
923
+ String
924
+ ]),
925
+ _ts_metadata7("design:returntype", Promise)
926
+ ], ThreadsController.prototype, "promote", null);
927
+ _ts_decorate8([
928
+ Delete(":id/from/:messageId"),
929
+ _ts_param6(0, Req3()),
930
+ _ts_param6(1, Param2("id")),
931
+ _ts_param6(2, Param2("messageId")),
932
+ _ts_metadata7("design:type", Function),
933
+ _ts_metadata7("design:paramtypes", [
934
+ typeof Request === "undefined" ? Object : Request,
935
+ String,
936
+ String
937
+ ]),
938
+ _ts_metadata7("design:returntype", Promise)
939
+ ], ThreadsController.prototype, "truncateFrom", null);
850
940
  ThreadsController = _ts_decorate8([
851
941
  Controller3("threads"),
852
942
  _ts_param6(1, Inject6(AGENT_ACTOR_RESOLVER3)),
@@ -859,7 +949,7 @@ ThreadsController = _ts_decorate8([
859
949
 
860
950
  // src/controller/tool-call.controller.ts
861
951
  import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER4 } from "@dudousxd/nestjs-agent-core";
862
- import { Body as Body2, Controller as Controller4, Inject as Inject7, Post as Post3, Req as Req4 } from "@nestjs/common";
952
+ import { Body as Body3, Controller as Controller4, Inject as Inject7, Post as Post3, Req as Req4 } from "@nestjs/common";
863
953
  function _ts_decorate9(decorators, target, key, desc) {
864
954
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
865
955
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -905,7 +995,7 @@ var ToolCallController = class {
905
995
  _ts_decorate9([
906
996
  Post3("approve"),
907
997
  _ts_param7(0, Req4()),
908
- _ts_param7(1, Body2()),
998
+ _ts_param7(1, Body3()),
909
999
  _ts_metadata8("design:type", Function),
910
1000
  _ts_metadata8("design:paramtypes", [
911
1001
  typeof Request === "undefined" ? Object : Request,
@@ -916,7 +1006,7 @@ _ts_decorate9([
916
1006
  _ts_decorate9([
917
1007
  Post3("reject"),
918
1008
  _ts_param7(0, Req4()),
919
- _ts_param7(1, Body2()),
1009
+ _ts_param7(1, Body3()),
920
1010
  _ts_metadata8("design:type", Function),
921
1011
  _ts_metadata8("design:paramtypes", [
922
1012
  typeof Request === "undefined" ? Object : Request,
@@ -934,10 +1024,152 @@ ToolCallController = _ts_decorate9([
934
1024
  ])
935
1025
  ], ToolCallController);
936
1026
 
937
- // src/discovery/ai-tool-discovery.service.ts
938
- import { AGENT_OPTIONS as AGENT_OPTIONS2, AGENT_REGISTRY as AGENT_REGISTRY2, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY2 } from "@dudousxd/nestjs-agent-core";
1027
+ // src/discovery/agent-discovery.service.ts
1028
+ import { AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS2, AGENT_REGISTRY as AGENT_REGISTRY2, AgentRegistry as AgentRegistry3 } from "@dudousxd/nestjs-agent-core";
939
1029
  import { Inject as Inject8, Injectable as Injectable5, Logger } from "@nestjs/common";
940
- import { DiscoveryService } from "@nestjs/core";
1030
+ import { DiscoveryService, MetadataScanner } from "@nestjs/core";
1031
+
1032
+ // src/decorator/agent.decorator.ts
1033
+ import "reflect-metadata";
1034
+ var AGENT_METADATA = Symbol.for("@dudousxd/nestjs-agent:agent-metadata");
1035
+ function readAgentMetadata(target) {
1036
+ return Reflect.getMetadata(AGENT_METADATA, target);
1037
+ }
1038
+ __name(readAgentMetadata, "readAgentMetadata");
1039
+
1040
+ // src/decorator/system-prompt.decorator.ts
1041
+ import "reflect-metadata";
1042
+ var SYSTEM_PROMPT_METADATA = Symbol.for("@dudousxd/nestjs-agent:system-prompt");
1043
+ var SYSTEM_PROMPT_CONTRIBUTOR_METADATA = Symbol.for("@dudousxd/nestjs-agent:system-prompt-contributor");
1044
+
1045
+ // src/discovery/agent-discovery.service.ts
1046
+ function _ts_decorate10(decorators, target, key, desc) {
1047
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1048
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1049
+ 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;
1050
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1051
+ }
1052
+ __name(_ts_decorate10, "_ts_decorate");
1053
+ function _ts_metadata9(k, v) {
1054
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1055
+ }
1056
+ __name(_ts_metadata9, "_ts_metadata");
1057
+ function _ts_param8(paramIndex, decorator) {
1058
+ return function(target, key) {
1059
+ decorator(target, key, paramIndex);
1060
+ };
1061
+ }
1062
+ __name(_ts_param8, "_ts_param");
1063
+ var AgentDiscoveryService = class _AgentDiscoveryService {
1064
+ static {
1065
+ __name(this, "AgentDiscoveryService");
1066
+ }
1067
+ discovery;
1068
+ scanner;
1069
+ registry;
1070
+ contributors;
1071
+ logger = new Logger(_AgentDiscoveryService.name);
1072
+ constructor(discovery, scanner, registry, contributors) {
1073
+ this.discovery = discovery;
1074
+ this.scanner = scanner;
1075
+ this.registry = registry;
1076
+ this.contributors = contributors;
1077
+ }
1078
+ onModuleInit() {
1079
+ for (const wrapper of this.discovery.getProviders()) {
1080
+ const instance = wrapper.instance;
1081
+ if (instance === null || typeof instance !== "object") {
1082
+ continue;
1083
+ }
1084
+ const meta = readAgentMetadata(instance.constructor);
1085
+ if (meta !== void 0) {
1086
+ this.registry.register(this.definitionFrom(instance, meta));
1087
+ }
1088
+ this.collectContributors(instance);
1089
+ }
1090
+ }
1091
+ /** Build the internal {@link AgentDefinition} from an `@Agent` instance and its options. */
1092
+ definitionFrom(instance, meta) {
1093
+ const promptMethod = this.methodWith(instance, SYSTEM_PROMPT_METADATA);
1094
+ const systemPrompt = promptMethod !== void 0 ? (ctx) => promptMethod(ctx) : meta.systemPrompt ?? "You are a helpful assistant.";
1095
+ return {
1096
+ name: meta.name,
1097
+ systemPrompt,
1098
+ ...meta.tools !== void 0 ? {
1099
+ tools: meta.tools
1100
+ } : {},
1101
+ ...meta.model !== void 0 ? {
1102
+ modelId: meta.model
1103
+ } : {},
1104
+ ...meta.maxSteps !== void 0 ? {
1105
+ maxSteps: meta.maxSteps
1106
+ } : {},
1107
+ ...meta.handoff !== void 0 ? {
1108
+ delegatesTo: this.handoffNames(meta)
1109
+ } : {}
1110
+ };
1111
+ }
1112
+ /** Resolve each handoff `@Agent` class to its registered name (skipping non-agent classes). */
1113
+ handoffNames(meta) {
1114
+ const names = [];
1115
+ for (const target of meta.handoff ?? []) {
1116
+ const targetMeta = readAgentMetadata(target);
1117
+ if (targetMeta === void 0) {
1118
+ this.logger.warn(`Agent "${meta.name}" hands off to ${target.name}, which is not an @Agent \u2014 skipped.`);
1119
+ continue;
1120
+ }
1121
+ names.push(targetMeta.name);
1122
+ }
1123
+ return names;
1124
+ }
1125
+ /** Push every `@SystemPromptContributor()` method on `instance` (bound) into the contributor list. */
1126
+ collectContributors(instance) {
1127
+ const prototype = Object.getPrototypeOf(instance);
1128
+ for (const name of this.scanner.getAllMethodNames(prototype)) {
1129
+ if (Reflect.getMetadata(SYSTEM_PROMPT_CONTRIBUTOR_METADATA, prototype, name) === true) {
1130
+ const method = this.boundMethod(instance, name);
1131
+ if (method !== void 0) {
1132
+ this.contributors.push((ctx) => method(ctx));
1133
+ }
1134
+ }
1135
+ }
1136
+ }
1137
+ /** The single method on `instance` carrying `metadataKey`, bound to the instance, or undefined. */
1138
+ methodWith(instance, metadataKey) {
1139
+ const prototype = Object.getPrototypeOf(instance);
1140
+ for (const name of this.scanner.getAllMethodNames(prototype)) {
1141
+ if (Reflect.getMetadata(metadataKey, prototype, name) === true) {
1142
+ return this.boundMethod(instance, name);
1143
+ }
1144
+ }
1145
+ return void 0;
1146
+ }
1147
+ /** Bind a named method to its instance, guarding that it is actually a function. */
1148
+ boundMethod(instance, name) {
1149
+ const candidate = instance[name];
1150
+ if (typeof candidate !== "function") {
1151
+ return void 0;
1152
+ }
1153
+ return (ctx) => candidate.call(instance, ctx);
1154
+ }
1155
+ };
1156
+ AgentDiscoveryService = _ts_decorate10([
1157
+ Injectable5(),
1158
+ _ts_param8(2, Inject8(AGENT_REGISTRY2)),
1159
+ _ts_param8(3, Inject8(AGENT_PROMPT_CONTRIBUTORS2)),
1160
+ _ts_metadata9("design:type", Function),
1161
+ _ts_metadata9("design:paramtypes", [
1162
+ typeof DiscoveryService === "undefined" ? Object : DiscoveryService,
1163
+ typeof MetadataScanner === "undefined" ? Object : MetadataScanner,
1164
+ typeof AgentRegistry3 === "undefined" ? Object : AgentRegistry3,
1165
+ Array
1166
+ ])
1167
+ ], AgentDiscoveryService);
1168
+
1169
+ // src/discovery/ai-tool-discovery.service.ts
1170
+ import { AGENT_OPTIONS as AGENT_OPTIONS2, AGENT_REGISTRY as AGENT_REGISTRY3, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY2 } from "@dudousxd/nestjs-agent-core";
1171
+ import { Inject as Inject9, Injectable as Injectable6, Logger as Logger2 } from "@nestjs/common";
1172
+ import { DiscoveryService as DiscoveryService2 } from "@nestjs/core";
941
1173
  import { z } from "zod";
942
1174
 
943
1175
  // src/decorator/ai-tool.decorator.ts
@@ -956,23 +1188,23 @@ function isBrandedFunctionalTool(value) {
956
1188
  __name(isBrandedFunctionalTool, "isBrandedFunctionalTool");
957
1189
 
958
1190
  // src/discovery/ai-tool-discovery.service.ts
959
- function _ts_decorate10(decorators, target, key, desc) {
1191
+ function _ts_decorate11(decorators, target, key, desc) {
960
1192
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
961
1193
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
962
1194
  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;
963
1195
  return c > 3 && r && Object.defineProperty(target, key, r), r;
964
1196
  }
965
- __name(_ts_decorate10, "_ts_decorate");
966
- function _ts_metadata9(k, v) {
1197
+ __name(_ts_decorate11, "_ts_decorate");
1198
+ function _ts_metadata10(k, v) {
967
1199
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
968
1200
  }
969
- __name(_ts_metadata9, "_ts_metadata");
970
- function _ts_param8(paramIndex, decorator) {
1201
+ __name(_ts_metadata10, "_ts_metadata");
1202
+ function _ts_param9(paramIndex, decorator) {
971
1203
  return function(target, key) {
972
1204
  decorator(target, key, paramIndex);
973
1205
  };
974
1206
  }
975
- __name(_ts_param8, "_ts_param");
1207
+ __name(_ts_param9, "_ts_param");
976
1208
  var AiToolDiscoveryService = class _AiToolDiscoveryService {
977
1209
  static {
978
1210
  __name(this, "AiToolDiscoveryService");
@@ -981,7 +1213,7 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
981
1213
  registry;
982
1214
  agents;
983
1215
  options;
984
- logger = new Logger(_AiToolDiscoveryService.name);
1216
+ logger = new Logger2(_AiToolDiscoveryService.name);
985
1217
  constructor(discovery, registry, agents, options) {
986
1218
  this.discovery = discovery;
987
1219
  this.registry = registry;
@@ -1039,7 +1271,7 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
1039
1271
  for (const target of definition.delegatesTo ?? []) {
1040
1272
  const targetDefinition = this.agents.get(target);
1041
1273
  if (targetDefinition === void 0) {
1042
- throw new Error(`Agent "${definition.name}" delegatesTo "${target}", which is not a registered agent. Register it via AgentModule.forFeature([...]) or fix the name.`);
1274
+ 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.`);
1043
1275
  }
1044
1276
  const name = delegateToolName(target);
1045
1277
  if (this.registry.has(name)) {
@@ -1079,14 +1311,14 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
1079
1311
  return true;
1080
1312
  }
1081
1313
  };
1082
- AiToolDiscoveryService = _ts_decorate10([
1083
- Injectable5(),
1084
- _ts_param8(1, Inject8(AGENT_TOOL_REGISTRY2)),
1085
- _ts_param8(2, Inject8(AGENT_REGISTRY2)),
1086
- _ts_param8(3, Inject8(AGENT_OPTIONS2)),
1087
- _ts_metadata9("design:type", Function),
1088
- _ts_metadata9("design:paramtypes", [
1089
- typeof DiscoveryService === "undefined" ? Object : DiscoveryService,
1314
+ AiToolDiscoveryService = _ts_decorate11([
1315
+ Injectable6(),
1316
+ _ts_param9(1, Inject9(AGENT_TOOL_REGISTRY2)),
1317
+ _ts_param9(2, Inject9(AGENT_REGISTRY3)),
1318
+ _ts_param9(3, Inject9(AGENT_OPTIONS2)),
1319
+ _ts_metadata10("design:type", Function),
1320
+ _ts_metadata10("design:paramtypes", [
1321
+ typeof DiscoveryService2 === "undefined" ? Object : DiscoveryService2,
1090
1322
  typeof ToolRegistry === "undefined" ? Object : ToolRegistry,
1091
1323
  typeof AgentRegistry === "undefined" ? Object : AgentRegistry,
1092
1324
  typeof AgentModuleOptions === "undefined" ? Object : AgentModuleOptions
@@ -1186,31 +1418,31 @@ var LedgerQuotaStore = class {
1186
1418
 
1187
1419
  // src/runner/inline-agent-runner.ts
1188
1420
  import { AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY3, AGENT_STORE as AGENT_STORE4, QuotaExceededError as QuotaExceededError2, publishAgentRunFailed as publishAgentRunFailed2, runAgentLoop as runAgentLoop2 } from "@dudousxd/nestjs-agent-core";
1189
- import { Inject as Inject9, Injectable as Injectable6, Logger as Logger2 } from "@nestjs/common";
1190
- function _ts_decorate11(decorators, target, key, desc) {
1421
+ import { Inject as Inject10, Injectable as Injectable7, Logger as Logger3 } from "@nestjs/common";
1422
+ function _ts_decorate12(decorators, target, key, desc) {
1191
1423
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1192
1424
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1193
1425
  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;
1194
1426
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1195
1427
  }
1196
- __name(_ts_decorate11, "_ts_decorate");
1197
- function _ts_metadata10(k, v) {
1428
+ __name(_ts_decorate12, "_ts_decorate");
1429
+ function _ts_metadata11(k, v) {
1198
1430
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1199
1431
  }
1200
- __name(_ts_metadata10, "_ts_metadata");
1201
- function _ts_param9(paramIndex, decorator) {
1432
+ __name(_ts_metadata11, "_ts_metadata");
1433
+ function _ts_param10(paramIndex, decorator) {
1202
1434
  return function(target, key) {
1203
1435
  decorator(target, key, paramIndex);
1204
1436
  };
1205
1437
  }
1206
- __name(_ts_param9, "_ts_param");
1438
+ __name(_ts_param10, "_ts_param");
1207
1439
  var InlineAgentRunner = class _InlineAgentRunner {
1208
1440
  static {
1209
1441
  __name(this, "InlineAgentRunner");
1210
1442
  }
1211
1443
  factory;
1212
1444
  store;
1213
- logger = new Logger2(_InlineAgentRunner.name);
1445
+ logger = new Logger3(_InlineAgentRunner.name);
1214
1446
  pending = /* @__PURE__ */ new Map();
1215
1447
  constructor(factory, store) {
1216
1448
  this.factory = factory;
@@ -1275,7 +1507,6 @@ var InlineAgentRunner = class _InlineAgentRunner {
1275
1507
  async runNested(agentName, task, actor, day, depth, sinkRunId) {
1276
1508
  const subThread = await this.store.createThread({
1277
1509
  actor,
1278
- persona: "default",
1279
1510
  transient: true
1280
1511
  });
1281
1512
  const runId = crypto.randomUUID();
@@ -1305,50 +1536,41 @@ var InlineAgentRunner = class _InlineAgentRunner {
1305
1536
  }, hooks);
1306
1537
  }
1307
1538
  };
1308
- InlineAgentRunner = _ts_decorate11([
1309
- Injectable6(),
1310
- _ts_param9(0, Inject9(AGENT_DEPS_FACTORY3)),
1311
- _ts_param9(1, Inject9(AGENT_STORE4)),
1312
- _ts_metadata10("design:type", Function),
1313
- _ts_metadata10("design:paramtypes", [
1539
+ InlineAgentRunner = _ts_decorate12([
1540
+ Injectable7(),
1541
+ _ts_param10(0, Inject10(AGENT_DEPS_FACTORY3)),
1542
+ _ts_param10(1, Inject10(AGENT_STORE4)),
1543
+ _ts_metadata11("design:type", Function),
1544
+ _ts_metadata11("design:paramtypes", [
1314
1545
  typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
1315
1546
  typeof AgentStore === "undefined" ? Object : AgentStore
1316
1547
  ])
1317
1548
  ], InlineAgentRunner);
1318
1549
 
1319
1550
  // src/agent.module.ts
1320
- function _ts_decorate12(decorators, target, key, desc) {
1551
+ function _ts_decorate13(decorators, target, key, desc) {
1321
1552
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1322
1553
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1323
1554
  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;
1324
1555
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1325
1556
  }
1326
- __name(_ts_decorate12, "_ts_decorate");
1327
- var FEATURE_INIT = Symbol("nestjs-agent:feature-init");
1557
+ __name(_ts_decorate13, "_ts_decorate");
1328
1558
  var DEFAULT_PATH = "agent";
1329
- function defaultDefinition(options) {
1330
- return {
1331
- name: "default",
1332
- ...options.defaultAgent
1333
- };
1334
- }
1335
- __name(defaultDefinition, "defaultDefinition");
1336
1559
  function sharedProviders(durable, includeStore) {
1337
1560
  const providers = [
1338
1561
  {
1339
1562
  provide: AGENT_TOOL_REGISTRY3,
1340
1563
  useFactory: /* @__PURE__ */ __name(() => new ToolRegistry3(), "useFactory")
1341
1564
  },
1565
+ // Starts empty; AgentDiscoveryService populates it from `@Agent`-decorated providers at boot.
1342
1566
  {
1343
- provide: AGENT_REGISTRY3,
1344
- useFactory: /* @__PURE__ */ __name((options) => {
1345
- const registry = new AgentRegistry3();
1346
- registry.register(defaultDefinition(options));
1347
- return registry;
1348
- }, "useFactory"),
1349
- inject: [
1350
- AGENT_OPTIONS3
1351
- ]
1567
+ provide: AGENT_REGISTRY4,
1568
+ useFactory: /* @__PURE__ */ __name(() => new AgentRegistry4(), "useFactory")
1569
+ },
1570
+ // A shared, mutable list AgentDiscoveryService fills with `@SystemPromptContributor()` methods.
1571
+ {
1572
+ provide: AGENT_PROMPT_CONTRIBUTORS3,
1573
+ useFactory: /* @__PURE__ */ __name(() => [], "useFactory")
1352
1574
  },
1353
1575
  {
1354
1576
  provide: AGENT_SINK2,
@@ -1382,7 +1604,7 @@ function sharedProviders(durable, includeStore) {
1382
1604
  // An explicit `quota` wins; otherwise `quotaLimitTokens` binds the built-in ledger-backed
1383
1605
  // store; otherwise quotas are off (undefined). The ledger store reads the same usage rows
1384
1606
  // the loop already writes, so enforcement needs no extra shared state across replicas.
1385
- provide: AGENT_QUOTA_STORE2,
1607
+ provide: AGENT_QUOTA_STORE3,
1386
1608
  useFactory: /* @__PURE__ */ __name((o, store) => o.quota ?? (o.quotaLimitTokens !== void 0 ? new LedgerQuotaStore(store, o.quotaLimitTokens) : void 0), "useFactory"),
1387
1609
  inject: [
1388
1610
  AGENT_OPTIONS3,
@@ -1394,6 +1616,9 @@ function sharedProviders(durable, includeStore) {
1394
1616
  provide: AGENT_DEPS_FACTORY4,
1395
1617
  useExisting: AgentDepsFactory2
1396
1618
  },
1619
+ // Populates the registry + contributors (onModuleInit) BEFORE AiToolDiscoveryService synthesizes
1620
+ // handoff tools (onApplicationBootstrap) reads the registry.
1621
+ AgentDiscoveryService,
1397
1622
  AiToolDiscoveryService,
1398
1623
  InlineAgentRunner,
1399
1624
  AgentService
@@ -1436,7 +1661,7 @@ function exportsFor(includeStore) {
1436
1661
  return [
1437
1662
  AGENT_OPTIONS3,
1438
1663
  AGENT_TOOL_REGISTRY3,
1439
- AGENT_REGISTRY3,
1664
+ AGENT_REGISTRY4,
1440
1665
  AGENT_SINK2,
1441
1666
  AGENT_ROLES_POLICY2,
1442
1667
  AGENT_ACTOR_RESOLVER5,
@@ -1444,7 +1669,8 @@ function exportsFor(includeStore) {
1444
1669
  ...includeStore ? [
1445
1670
  AGENT_STORE5
1446
1671
  ] : [],
1447
- AGENT_QUOTA_STORE2,
1672
+ AGENT_QUOTA_STORE3,
1673
+ AGENT_PROMPT_CONTRIBUTORS3,
1448
1674
  AGENT_DEPS_FACTORY4,
1449
1675
  AgentDepsFactory2,
1450
1676
  AgentService,
@@ -1516,28 +1742,8 @@ var AgentModule = class _AgentModule {
1516
1742
  exports: exportsFor(true)
1517
1743
  };
1518
1744
  }
1519
- /** Register additional named agents (an orchestrator + its sub-agents). */
1520
- static forFeature(definitions) {
1521
- return {
1522
- module: _AgentModule,
1523
- providers: [
1524
- {
1525
- provide: FEATURE_INIT,
1526
- useFactory: /* @__PURE__ */ __name((registry) => {
1527
- for (const definition of definitions) {
1528
- registry.register(definition);
1529
- }
1530
- return true;
1531
- }, "useFactory"),
1532
- inject: [
1533
- AGENT_REGISTRY3
1534
- ]
1535
- }
1536
- ]
1537
- };
1538
- }
1539
1745
  };
1540
- AgentModule = _ts_decorate12([
1746
+ AgentModule = _ts_decorate13([
1541
1747
  Global2(),
1542
1748
  Module2({})
1543
1749
  ], AgentModule);