@dudousxd/nestjs-agent 1.7.0 → 1.9.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.
@@ -100,7 +100,14 @@ var AgentRunSteps = class {
100
100
  const tools = (0, import_nestjs_agent_core.withMemoryTool)({
101
101
  tools: (0, import_nestjs_agent_core.withSkillTool)({
102
102
  tools: (0, import_nestjs_agent_core.withAskTool)({
103
- tools: await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList),
103
+ tools: await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList, {
104
+ ...input.threadId !== void 0 ? {
105
+ threadId: input.threadId
106
+ } : {},
107
+ ...input.agentName !== void 0 ? {
108
+ agentName: input.agentName
109
+ } : {}
110
+ }),
104
111
  ask: deps.ask
105
112
  }),
106
113
  enabled: deps.skills !== void 0
@@ -821,7 +828,7 @@ AgentDurableModule = _ts_decorate4([
821
828
  ], AgentDurableModule);
822
829
 
823
830
  // src/agent.module.ts
824
- var import_nestjs_agent_core26 = require("@dudousxd/nestjs-agent-core");
831
+ var import_nestjs_agent_core27 = require("@dudousxd/nestjs-agent-core");
825
832
  var import_common23 = require("@nestjs/common");
826
833
  var import_core4 = require("@nestjs/core");
827
834
 
@@ -1129,13 +1136,68 @@ var AgentService = class {
1129
1136
  quota;
1130
1137
  staging;
1131
1138
  models;
1132
- constructor(runner, store, deps, quota, staging, models) {
1139
+ quotaProvider;
1140
+ options;
1141
+ constructor(runner, store, deps, quota, staging, models, quotaProvider, options) {
1133
1142
  this.runner = runner;
1134
1143
  this.store = store;
1135
1144
  this.deps = deps;
1136
1145
  this.quota = quota;
1137
1146
  this.staging = staging;
1138
1147
  this.models = models;
1148
+ this.quotaProvider = quotaProvider;
1149
+ this.options = options;
1150
+ }
1151
+ /**
1152
+ * The actor's budget across windows (`GET <base>/quota`) — the bound {@link QuotaProvider}'s
1153
+ * report. Without one (a service built outside the module), a day window from the ledger.
1154
+ */
1155
+ async quotaReport(actor) {
1156
+ if (this.quotaProvider !== void 0) {
1157
+ return this.quotaProvider.report({
1158
+ actor
1159
+ });
1160
+ }
1161
+ const today = await this.quotaToday(actor.id);
1162
+ return {
1163
+ windows: [
1164
+ {
1165
+ period: "day",
1166
+ usedTokens: today.usedTokens,
1167
+ ...today.limitTokens !== null ? {
1168
+ limitTokens: today.limitTokens
1169
+ } : {},
1170
+ usedUsd: today.costUsd
1171
+ }
1172
+ ],
1173
+ ...today.withinLimit ? {} : {
1174
+ blocked: {
1175
+ period: "day"
1176
+ }
1177
+ }
1178
+ };
1179
+ }
1180
+ /**
1181
+ * Refuse a turn the actor's budget no longer covers — only when the host configured one
1182
+ * (`quotaProvider` or `quotaLimits`): the default report is informational, and the daily token
1183
+ * quota the loop enforces keeps working as it always has.
1184
+ */
1185
+ async assertWithinQuota(actor) {
1186
+ const gated = this.options?.quotaProvider !== void 0 || this.options?.quotaLimits !== void 0;
1187
+ if (!gated || this.quotaProvider === void 0) {
1188
+ return;
1189
+ }
1190
+ const { blocked } = await this.quotaProvider.report({
1191
+ actor
1192
+ });
1193
+ if (blocked !== void 0) {
1194
+ throw new import_common6.HttpException({
1195
+ statusCode: import_common6.HttpStatus.TOO_MANY_REQUESTS,
1196
+ code: "quota_exceeded",
1197
+ period: blocked.period,
1198
+ message: blocked.reason ?? `The ${blocked.period === "day" ? "daily" : "monthly"} quota is used up`
1199
+ }, import_common6.HttpStatus.TOO_MANY_REQUESTS);
1200
+ }
1139
1201
  }
1140
1202
  /**
1141
1203
  * The models `actor` may pick for `agent` (`GET <base>/models`). An empty catalog when none is
@@ -1192,6 +1254,7 @@ var AgentService = class {
1192
1254
  return (await this.store.getThread(threadId))?.model ?? null;
1193
1255
  }
1194
1256
  async chat(params) {
1257
+ await this.assertWithinQuota(params.actor);
1195
1258
  const agentName = await this.resolveAgentName(params.agentName, params.threadId);
1196
1259
  const model = await this.resolveModel(params.actor, agentName, params.model, params.threadId);
1197
1260
  const attachments = await this.resolveAttachments(params.actor, params.attachments ?? []);
@@ -1733,6 +1796,10 @@ AgentService = _ts_decorate6([
1733
1796
  _ts_param5(4, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_ATTACHMENT_STAGING)),
1734
1797
  _ts_param5(5, (0, import_common6.Optional)()),
1735
1798
  _ts_param5(5, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_MODEL_CATALOG)),
1799
+ _ts_param5(6, (0, import_common6.Optional)()),
1800
+ _ts_param5(6, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_QUOTA_PROVIDER)),
1801
+ _ts_param5(7, (0, import_common6.Optional)()),
1802
+ _ts_param5(7, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_OPTIONS)),
1736
1803
  _ts_metadata5("design:type", Function),
1737
1804
  _ts_metadata5("design:paramtypes", [
1738
1805
  typeof AgentRunner === "undefined" ? Object : AgentRunner,
@@ -1740,7 +1807,9 @@ AgentService = _ts_decorate6([
1740
1807
  typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
1741
1808
  Object,
1742
1809
  typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore,
1743
- typeof ModelCatalog === "undefined" ? Object : ModelCatalog
1810
+ typeof ModelCatalog === "undefined" ? Object : ModelCatalog,
1811
+ typeof QuotaProvider === "undefined" ? Object : QuotaProvider,
1812
+ typeof Pick === "undefined" ? Object : Pick
1744
1813
  ])
1745
1814
  ], AgentService);
1746
1815
 
@@ -2587,11 +2656,28 @@ var QuotaController = class {
2587
2656
  this.agent = agent;
2588
2657
  this.actorResolver = actorResolver;
2589
2658
  }
2659
+ /**
2660
+ * The caller's budget across windows — `{ windows: [{ period, usedTokens, limitTokens?, usedUsd,
2661
+ * limitUsd?, resetsAt? }], blocked?: { period, reason? } }` — from the bound `QuotaProvider`.
2662
+ */
2663
+ async report(req) {
2664
+ const actor = await this.actorResolver.resolve(req);
2665
+ return this.agent.quotaReport(actor);
2666
+ }
2590
2667
  async today(req) {
2591
2668
  const actor = await this.actorResolver.resolve(req);
2592
2669
  return this.agent.quotaToday(actor.id);
2593
2670
  }
2594
2671
  };
2672
+ _ts_decorate14([
2673
+ (0, import_common14.Get)(),
2674
+ _ts_param12(0, (0, import_common14.Req)()),
2675
+ _ts_metadata13("design:type", Function),
2676
+ _ts_metadata13("design:paramtypes", [
2677
+ typeof Request === "undefined" ? Object : Request
2678
+ ]),
2679
+ _ts_metadata13("design:returntype", Promise)
2680
+ ], QuotaController.prototype, "report", null);
2595
2681
  _ts_decorate14([
2596
2682
  (0, import_common14.Get)("today"),
2597
2683
  _ts_param12(0, (0, import_common14.Req)()),
@@ -3418,6 +3504,14 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
3418
3504
  if (instance === null || instance === void 0 || typeof instance !== "object") {
3419
3505
  continue;
3420
3506
  }
3507
+ if (Array.isArray(instance) && instance.length > 0 && instance.every((each) => typeof each === "object" && each !== null && isBrandedFunctionalTool(each))) {
3508
+ for (const tool of instance) {
3509
+ if (this.registerFunctionalTool(tool)) {
3510
+ functional += 1;
3511
+ }
3512
+ }
3513
+ continue;
3514
+ }
3421
3515
  if (isBrandedFunctionalTool(instance)) {
3422
3516
  if (this.registerFunctionalTool(instance)) {
3423
3517
  functional += 1;
@@ -3465,6 +3559,9 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
3465
3559
  } : {},
3466
3560
  ...typeof handler.canUse === "function" ? {
3467
3561
  canUse: /* @__PURE__ */ __name((actor) => instance.canUse(actor), "canUse")
3562
+ } : {},
3563
+ ...typeof handler.describe === "function" ? {
3564
+ describe: /* @__PURE__ */ __name((scope) => instance.describe(scope), "describe")
3468
3565
  } : {}
3469
3566
  });
3470
3567
  count += 1;
@@ -3639,6 +3736,69 @@ SkillDiscoveryService = _ts_decorate21([
3639
3736
  ])
3640
3737
  ], SkillDiscoveryService);
3641
3738
 
3739
+ // src/ledger-quota-provider.ts
3740
+ var import_nestjs_agent_core24 = require("@dudousxd/nestjs-agent-core");
3741
+ var LedgerQuotaProvider = class {
3742
+ static {
3743
+ __name(this, "LedgerQuotaProvider");
3744
+ }
3745
+ store;
3746
+ quota;
3747
+ limits;
3748
+ constructor(store, quota, limits = {}) {
3749
+ this.store = store;
3750
+ this.quota = quota;
3751
+ this.limits = limits;
3752
+ }
3753
+ async report(query) {
3754
+ const now = query.now ?? /* @__PURE__ */ new Date();
3755
+ const actorRef = query.actor.id;
3756
+ const windows = [
3757
+ await this.dayWindow(actorRef, now)
3758
+ ];
3759
+ if (this.store.usageBetween !== void 0) {
3760
+ const range = (0, import_nestjs_agent_core24.quotaPeriodRange)("month", now);
3761
+ const used = await this.store.usageBetween(actorRef, range.fromDay, range.toDay);
3762
+ windows.push(this.window("month", used.usedTokens, used.costUsd, range.resetsAt));
3763
+ }
3764
+ const blocked = (0, import_nestjs_agent_core24.exhaustedWindow)(windows);
3765
+ return {
3766
+ windows,
3767
+ ...blocked !== void 0 ? {
3768
+ blocked
3769
+ } : {}
3770
+ };
3771
+ }
3772
+ async dayWindow(actorRef, now) {
3773
+ const range = (0, import_nestjs_agent_core24.quotaPeriodRange)("day", now);
3774
+ const { usedTokens, costUsd } = await this.store.quotaToday(actorRef, range.fromDay);
3775
+ if (this.quota === void 0) {
3776
+ return this.window("day", usedTokens, costUsd, range.resetsAt);
3777
+ }
3778
+ const state = await this.quota.check(actorRef, range.fromDay);
3779
+ const window = this.window("day", state.usedTokens, costUsd, range.resetsAt);
3780
+ if (window.limitTokens === void 0) {
3781
+ window.limitTokens = state.limitTokens;
3782
+ }
3783
+ return window;
3784
+ }
3785
+ window(period, usedTokens, usedUsd, resetsAt) {
3786
+ const limits = this.limits[period] ?? {};
3787
+ return {
3788
+ period,
3789
+ usedTokens,
3790
+ ...limits.tokens !== void 0 ? {
3791
+ limitTokens: limits.tokens
3792
+ } : {},
3793
+ usedUsd,
3794
+ ...limits.usd !== void 0 ? {
3795
+ limitUsd: limits.usd
3796
+ } : {},
3797
+ resetsAt
3798
+ };
3799
+ }
3800
+ };
3801
+
3642
3802
  // src/ledger-quota-store.ts
3643
3803
  var LedgerQuotaStore = class {
3644
3804
  static {
@@ -3663,7 +3823,7 @@ var LedgerQuotaStore = class {
3663
3823
  };
3664
3824
 
3665
3825
  // src/runner/inline-agent-runner.ts
3666
- var import_nestjs_agent_core24 = require("@dudousxd/nestjs-agent-core");
3826
+ var import_nestjs_agent_core25 = require("@dudousxd/nestjs-agent-core");
3667
3827
  var import_common22 = require("@nestjs/common");
3668
3828
  function _ts_decorate22(decorators, target, key, desc) {
3669
3829
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -3726,18 +3886,18 @@ var InlineAgentRunner = class _InlineAgentRunner {
3726
3886
  ] : []
3727
3887
  ]
3728
3888
  });
3729
- void (0, import_nestjs_agent_core24.runAgentLoop)({
3889
+ void (0, import_nestjs_agent_core25.runAgentLoop)({
3730
3890
  ...deps,
3731
3891
  day
3732
3892
  }, input, hooks).then(() => this.store.setActiveStream(input.threadId, null)).catch(async (error) => {
3733
- if (error instanceof import_nestjs_agent_core24.RunCancelledError) {
3893
+ if (error instanceof import_nestjs_agent_core25.RunCancelledError) {
3734
3894
  await this.settleCancelled(runId, input.threadId, deps);
3735
3895
  return;
3736
3896
  }
3737
3897
  const message = error instanceof Error ? error.message : String(error);
3738
- const code = (0, import_nestjs_agent_core24.agentFailureCode)(error);
3898
+ const code = (0, import_nestjs_agent_core25.agentFailureCode)(error);
3739
3899
  this.logger.error(`agent run ${runId} failed (${code}): ${message}`);
3740
- (0, import_nestjs_agent_core24.publishAgentRunFailed)({
3900
+ (0, import_nestjs_agent_core25.publishAgentRunFailed)({
3741
3901
  runId,
3742
3902
  code,
3743
3903
  message
@@ -3786,7 +3946,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
3786
3946
  for (const [key, waiter] of this.pending) {
3787
3947
  if (key.startsWith(`${runId}:`)) {
3788
3948
  this.pending.delete(key);
3789
- waiter.reject(new import_nestjs_agent_core24.RunCancelledError());
3949
+ waiter.reject(new import_nestjs_agent_core25.RunCancelledError());
3790
3950
  }
3791
3951
  }
3792
3952
  await Promise.resolve();
@@ -3801,7 +3961,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
3801
3961
  this.logger.log(`agent run ${runId} cancelled`);
3802
3962
  await this.store.setActiveStream(threadId, null);
3803
3963
  const writer = await deps.sink.open(runId);
3804
- await writer.write((0, import_nestjs_agent_core24.encodeStreamEvent)({
3964
+ await writer.write((0, import_nestjs_agent_core25.encodeStreamEvent)({
3805
3965
  kind: "cancelled"
3806
3966
  }));
3807
3967
  await writer.end();
@@ -3862,7 +4022,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
3862
4022
  awaitApproval: /* @__PURE__ */ __name((call, _ctx, opts) => this.parkApproval(runId, call.id, opts?.timeoutMs), "awaitApproval"),
3863
4023
  awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
3864
4024
  step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
3865
- parallel: import_nestjs_agent_core24.settleAll,
4025
+ parallel: import_nestjs_agent_core25.settleAll,
3866
4026
  cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId), "cancelled"),
3867
4027
  runAgent: /* @__PURE__ */ __name((agentName, task) => this.runNested({
3868
4028
  agentName,
@@ -3913,7 +4073,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
3913
4073
  awaitApproval: /* @__PURE__ */ __name((call, _ctx, opts) => this.parkApproval(runId, call.id, opts?.timeoutMs), "awaitApproval"),
3914
4074
  awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
3915
4075
  step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
3916
- parallel: import_nestjs_agent_core24.settleAll,
4076
+ parallel: import_nestjs_agent_core25.settleAll,
3917
4077
  cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId), "cancelled"),
3918
4078
  runAgent: /* @__PURE__ */ __name((childName, childTask) => this.runNested({
3919
4079
  agentName: childName,
@@ -3946,7 +4106,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
3946
4106
  }
3947
4107
  }), "startAgent")
3948
4108
  };
3949
- void (0, import_nestjs_agent_core24.runAgentLoop)({
4109
+ void (0, import_nestjs_agent_core25.runAgentLoop)({
3950
4110
  ...deps,
3951
4111
  day
3952
4112
  }, {
@@ -3960,13 +4120,13 @@ var InlineAgentRunner = class _InlineAgentRunner {
3960
4120
  parentRunId,
3961
4121
  deliverTo
3962
4122
  }, hooks).catch(async (error) => {
3963
- const cancelled = error instanceof import_nestjs_agent_core24.RunCancelledError;
4123
+ const cancelled = error instanceof import_nestjs_agent_core25.RunCancelledError;
3964
4124
  const message = error instanceof Error ? error.message : String(error);
3965
4125
  if (!cancelled) {
3966
4126
  this.logger.error(`detached agent run ${runId} failed: ${message}`);
3967
- (0, import_nestjs_agent_core24.publishAgentRunFailed)({
4127
+ (0, import_nestjs_agent_core25.publishAgentRunFailed)({
3968
4128
  runId,
3969
- code: (0, import_nestjs_agent_core24.agentFailureCode)(error),
4129
+ code: (0, import_nestjs_agent_core25.agentFailureCode)(error),
3970
4130
  message
3971
4131
  });
3972
4132
  }
@@ -3974,11 +4134,11 @@ var InlineAgentRunner = class _InlineAgentRunner {
3974
4134
  runId,
3975
4135
  status: cancelled ? "cancelled" : "failed",
3976
4136
  ...cancelled ? {} : {
3977
- errorCode: (0, import_nestjs_agent_core24.agentFailureCode)(error),
4137
+ errorCode: (0, import_nestjs_agent_core25.agentFailureCode)(error),
3978
4138
  errorMessage: message
3979
4139
  }
3980
4140
  });
3981
- await (0, import_nestjs_agent_core24.settleUnsettledDelegation)({
4141
+ await (0, import_nestjs_agent_core25.settleUnsettledDelegation)({
3982
4142
  store: this.store,
3983
4143
  delivery: deliverTo,
3984
4144
  agent: agentName,
@@ -4017,7 +4177,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
4017
4177
  awaitApproval: /* @__PURE__ */ __name((call, _ctx, opts) => this.parkApproval(runId, call.id, opts?.timeoutMs), "awaitApproval"),
4018
4178
  awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
4019
4179
  step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
4020
- parallel: import_nestjs_agent_core24.settleAll,
4180
+ parallel: import_nestjs_agent_core25.settleAll,
4021
4181
  // A child stops when it is cancelled OR when the run a human is actually watching is: the
4022
4182
  // canceller names the top-level run, which is the only id that ever left the server.
4023
4183
  cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId) || this.cancelled.has(sinkRunId), "cancelled"),
@@ -4052,7 +4212,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
4052
4212
  }), "startAgent")
4053
4213
  };
4054
4214
  try {
4055
- return await (0, import_nestjs_agent_core24.runAgentLoop)({
4215
+ return await (0, import_nestjs_agent_core25.runAgentLoop)({
4056
4216
  ...deps,
4057
4217
  day
4058
4218
  }, {
@@ -4073,8 +4233,8 @@ var InlineAgentRunner = class _InlineAgentRunner {
4073
4233
  };
4074
4234
  InlineAgentRunner = _ts_decorate22([
4075
4235
  (0, import_common22.Injectable)(),
4076
- _ts_param20(0, (0, import_common22.Inject)(import_nestjs_agent_core24.AGENT_DEPS_FACTORY)),
4077
- _ts_param20(1, (0, import_common22.Inject)(import_nestjs_agent_core24.AGENT_STORE)),
4236
+ _ts_param20(0, (0, import_common22.Inject)(import_nestjs_agent_core25.AGENT_DEPS_FACTORY)),
4237
+ _ts_param20(1, (0, import_common22.Inject)(import_nestjs_agent_core25.AGENT_STORE)),
4078
4238
  _ts_metadata21("design:type", Function),
4079
4239
  _ts_metadata21("design:paramtypes", [
4080
4240
  typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
@@ -4083,7 +4243,7 @@ InlineAgentRunner = _ts_decorate22([
4083
4243
  ], InlineAgentRunner);
4084
4244
 
4085
4245
  // src/skills-config.ts
4086
- var import_nestjs_agent_core25 = require("@dudousxd/nestjs-agent-core");
4246
+ var import_nestjs_agent_core26 = require("@dudousxd/nestjs-agent-core");
4087
4247
  function declaredSkillProvider(declared) {
4088
4248
  return {
4089
4249
  list: /* @__PURE__ */ __name(({ scopes }) => declared.filter((skill) => scopes.includes(skill.scope)).map(({ name, description, scope }) => ({
@@ -4109,7 +4269,7 @@ function resolveSkillsConfig(options, declared) {
4109
4269
  declaredSkillProvider(declared)
4110
4270
  ];
4111
4271
  return {
4112
- provider: providers.length === 1 ? providers[0] : (0, import_nestjs_agent_core25.compositeSkillProvider)(providers),
4272
+ provider: providers.length === 1 ? providers[0] : (0, import_nestjs_agent_core26.compositeSkillProvider)(providers),
4113
4273
  ...options.scopes !== void 0 ? {
4114
4274
  scopes: options.scopes
4115
4275
  } : {},
@@ -4139,94 +4299,103 @@ var DEFAULT_PATH = "agent";
4139
4299
  function sharedProviders(durable, includeStore) {
4140
4300
  const providers = [
4141
4301
  {
4142
- provide: import_nestjs_agent_core26.AGENT_TOOL_REGISTRY,
4143
- useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core26.ToolRegistry(), "useFactory")
4302
+ provide: import_nestjs_agent_core27.AGENT_TOOL_REGISTRY,
4303
+ useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core27.ToolRegistry(), "useFactory")
4144
4304
  },
4145
4305
  // Starts empty; AgentDiscoveryService populates it from `@Agent`-decorated providers at boot.
4146
4306
  {
4147
- provide: import_nestjs_agent_core26.AGENT_REGISTRY,
4148
- useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core26.AgentRegistry(), "useFactory")
4307
+ provide: import_nestjs_agent_core27.AGENT_REGISTRY,
4308
+ useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core27.AgentRegistry(), "useFactory")
4149
4309
  },
4150
4310
  // A shared, mutable list AgentDiscoveryService fills with `@SystemPromptContributor()` methods.
4151
4311
  {
4152
- provide: import_nestjs_agent_core26.AGENT_PROMPT_CONTRIBUTORS,
4312
+ provide: import_nestjs_agent_core27.AGENT_PROMPT_CONTRIBUTORS,
4153
4313
  useFactory: /* @__PURE__ */ __name(() => [], "useFactory")
4154
4314
  },
4155
4315
  // Likewise for `@Skill`-decorated providers — filled by SkillDiscoveryService at onModuleInit,
4156
4316
  // read lazily by the AGENT_SKILLS provider below (which DI builds before discovery has run).
4157
4317
  {
4158
- provide: import_nestjs_agent_core26.AGENT_SKILL_SOURCES,
4318
+ provide: import_nestjs_agent_core27.AGENT_SKILL_SOURCES,
4159
4319
  useFactory: /* @__PURE__ */ __name(() => [], "useFactory")
4160
4320
  },
4161
4321
  {
4162
4322
  // One resolution, shared by the loop's deps and the listing endpoint: a second one would
4163
4323
  // drift, and a user would be offered a skill the agent cannot reach. `undefined` when the
4164
4324
  // host configured none — which is what keeps the turn's checkpoint sequence unchanged.
4165
- provide: import_nestjs_agent_core26.AGENT_SKILLS,
4325
+ provide: import_nestjs_agent_core27.AGENT_SKILLS,
4166
4326
  useFactory: /* @__PURE__ */ __name((options, declared) => resolveSkillsConfig(options.skills, declared), "useFactory"),
4167
4327
  inject: [
4168
- import_nestjs_agent_core26.AGENT_OPTIONS,
4169
- import_nestjs_agent_core26.AGENT_SKILL_SOURCES
4328
+ import_nestjs_agent_core27.AGENT_OPTIONS,
4329
+ import_nestjs_agent_core27.AGENT_SKILL_SOURCES
4170
4330
  ]
4171
4331
  },
4172
4332
  {
4173
4333
  // One resolution, shared by the loop's deps and the read-back endpoint: a person has to be
4174
4334
  // shown what the model was shown, and two resolutions would eventually disagree about that.
4175
- provide: import_nestjs_agent_core26.AGENT_MEMORY,
4335
+ provide: import_nestjs_agent_core27.AGENT_MEMORY,
4176
4336
  useFactory: /* @__PURE__ */ __name((options) => options.memory, "useFactory"),
4177
4337
  inject: [
4178
- import_nestjs_agent_core26.AGENT_OPTIONS
4338
+ import_nestjs_agent_core27.AGENT_OPTIONS
4179
4339
  ]
4180
4340
  },
4181
4341
  {
4182
- provide: import_nestjs_agent_core26.AGENT_SINK,
4342
+ provide: import_nestjs_agent_core27.AGENT_SINK,
4183
4343
  useFactory: /* @__PURE__ */ __name((options) => options.sink ?? new InProcessTokenStreamSink(), "useFactory"),
4184
4344
  inject: [
4185
- import_nestjs_agent_core26.AGENT_OPTIONS
4345
+ import_nestjs_agent_core27.AGENT_OPTIONS
4186
4346
  ]
4187
4347
  },
4188
4348
  {
4189
- provide: import_nestjs_agent_core26.AGENT_ROLES_POLICY,
4190
- useFactory: /* @__PURE__ */ __name((options) => options.rolesPolicy ?? new import_nestjs_agent_core26.DefaultRolesPolicy(options.defaultRoles), "useFactory"),
4349
+ provide: import_nestjs_agent_core27.AGENT_ROLES_POLICY,
4350
+ useFactory: /* @__PURE__ */ __name((options) => options.rolesPolicy ?? new import_nestjs_agent_core27.DefaultRolesPolicy(options.defaultRoles), "useFactory"),
4191
4351
  inject: [
4192
- import_nestjs_agent_core26.AGENT_OPTIONS
4352
+ import_nestjs_agent_core27.AGENT_OPTIONS
4193
4353
  ]
4194
4354
  },
4195
4355
  {
4196
- provide: import_nestjs_agent_core26.AGENT_ACTOR_RESOLVER,
4356
+ provide: import_nestjs_agent_core27.AGENT_ACTOR_RESOLVER,
4197
4357
  useFactory: /* @__PURE__ */ __name((options) => options.actorResolver, "useFactory"),
4198
4358
  inject: [
4199
- import_nestjs_agent_core26.AGENT_OPTIONS
4359
+ import_nestjs_agent_core27.AGENT_OPTIONS
4200
4360
  ]
4201
4361
  },
4202
4362
  {
4203
- provide: import_nestjs_agent_core26.AGENT_MODEL,
4363
+ provide: import_nestjs_agent_core27.AGENT_MODEL,
4204
4364
  useFactory: /* @__PURE__ */ __name((o) => o.model, "useFactory"),
4205
4365
  inject: [
4206
- import_nestjs_agent_core26.AGENT_OPTIONS
4366
+ import_nestjs_agent_core27.AGENT_OPTIONS
4207
4367
  ]
4208
4368
  },
4209
4369
  {
4210
4370
  // An explicit `quota` wins; otherwise `quotaLimitTokens` binds the built-in ledger-backed
4211
4371
  // store; otherwise quotas are off (undefined). The ledger store reads the same usage rows
4212
4372
  // the loop already writes, so enforcement needs no extra shared state across replicas.
4213
- provide: import_nestjs_agent_core26.AGENT_QUOTA_STORE,
4373
+ provide: import_nestjs_agent_core27.AGENT_QUOTA_STORE,
4214
4374
  useFactory: /* @__PURE__ */ __name((o, store) => o.quota ?? (o.quotaLimitTokens !== void 0 ? new LedgerQuotaStore(store, o.quotaLimitTokens) : void 0), "useFactory"),
4215
4375
  inject: [
4216
- import_nestjs_agent_core26.AGENT_OPTIONS,
4217
- import_nestjs_agent_core26.AGENT_STORE
4376
+ import_nestjs_agent_core27.AGENT_OPTIONS,
4377
+ import_nestjs_agent_core27.AGENT_STORE
4378
+ ]
4379
+ },
4380
+ {
4381
+ provide: import_nestjs_agent_core27.AGENT_QUOTA_PROVIDER,
4382
+ useFactory: /* @__PURE__ */ __name((o, store, quota) => o.quotaProvider ?? new LedgerQuotaProvider(store, quota, o.quotaLimits), "useFactory"),
4383
+ inject: [
4384
+ import_nestjs_agent_core27.AGENT_OPTIONS,
4385
+ import_nestjs_agent_core27.AGENT_STORE,
4386
+ import_nestjs_agent_core27.AGENT_QUOTA_STORE
4218
4387
  ]
4219
4388
  },
4220
4389
  {
4221
- provide: import_nestjs_agent_core26.AGENT_MODEL_CATALOG,
4390
+ provide: import_nestjs_agent_core27.AGENT_MODEL_CATALOG,
4222
4391
  useFactory: /* @__PURE__ */ __name((o) => o.models, "useFactory"),
4223
4392
  inject: [
4224
- import_nestjs_agent_core26.AGENT_OPTIONS
4393
+ import_nestjs_agent_core27.AGENT_OPTIONS
4225
4394
  ]
4226
4395
  },
4227
4396
  AgentDepsFactory2,
4228
4397
  {
4229
- provide: import_nestjs_agent_core26.AGENT_DEPS_FACTORY,
4398
+ provide: import_nestjs_agent_core27.AGENT_DEPS_FACTORY,
4230
4399
  useExisting: AgentDepsFactory2
4231
4400
  },
4232
4401
  // Populates the registry + contributors (onModuleInit) BEFORE AiToolDiscoveryService synthesizes
@@ -4240,22 +4409,22 @@ function sharedProviders(durable, includeStore) {
4240
4409
  // through AgentService.signalToolCall, which reaches whichever AGENT_RUNNER is bound above.
4241
4410
  AgentApprovalPortAdapter,
4242
4411
  {
4243
- provide: import_nestjs_agent_core26.AGENT_APPROVAL_PORT,
4412
+ provide: import_nestjs_agent_core27.AGENT_APPROVAL_PORT,
4244
4413
  useExisting: AgentApprovalPortAdapter
4245
4414
  }
4246
4415
  ];
4247
4416
  if (includeStore) {
4248
4417
  providers.push({
4249
- provide: import_nestjs_agent_core26.AGENT_STORE,
4418
+ provide: import_nestjs_agent_core27.AGENT_STORE,
4250
4419
  useFactory: /* @__PURE__ */ __name((o) => o.store, "useFactory"),
4251
4420
  inject: [
4252
- import_nestjs_agent_core26.AGENT_OPTIONS
4421
+ import_nestjs_agent_core27.AGENT_OPTIONS
4253
4422
  ]
4254
4423
  });
4255
4424
  }
4256
4425
  if (durable) {
4257
4426
  providers.push({
4258
- provide: import_nestjs_agent_core26.AGENT_RUNNER,
4427
+ provide: import_nestjs_agent_core27.AGENT_RUNNER,
4259
4428
  useFactory: /* @__PURE__ */ __name((durableRunner) => {
4260
4429
  if (durableRunner === void 0) {
4261
4430
  throw new Error("AgentModule.forRoot({ durable: true }) requires importing AgentDurableModule from '@dudousxd/nestjs-agent/durable' (alongside a configured DurableModule). It was not found.");
@@ -4264,14 +4433,14 @@ function sharedProviders(durable, includeStore) {
4264
4433
  }, "useFactory"),
4265
4434
  inject: [
4266
4435
  {
4267
- token: import_nestjs_agent_core26.AGENT_DURABLE_RUNNER,
4436
+ token: import_nestjs_agent_core27.AGENT_DURABLE_RUNNER,
4268
4437
  optional: true
4269
4438
  }
4270
4439
  ]
4271
4440
  });
4272
4441
  } else {
4273
4442
  providers.push({
4274
- provide: import_nestjs_agent_core26.AGENT_RUNNER,
4443
+ provide: import_nestjs_agent_core27.AGENT_RUNNER,
4275
4444
  useExisting: InlineAgentRunner
4276
4445
  });
4277
4446
  }
@@ -4280,26 +4449,27 @@ function sharedProviders(durable, includeStore) {
4280
4449
  __name(sharedProviders, "sharedProviders");
4281
4450
  function exportsFor(includeStore) {
4282
4451
  return [
4283
- import_nestjs_agent_core26.AGENT_OPTIONS,
4284
- import_nestjs_agent_core26.AGENT_TOOL_REGISTRY,
4285
- import_nestjs_agent_core26.AGENT_REGISTRY,
4286
- import_nestjs_agent_core26.AGENT_SINK,
4287
- import_nestjs_agent_core26.AGENT_ROLES_POLICY,
4288
- import_nestjs_agent_core26.AGENT_ACTOR_RESOLVER,
4289
- import_nestjs_agent_core26.AGENT_MODEL,
4452
+ import_nestjs_agent_core27.AGENT_OPTIONS,
4453
+ import_nestjs_agent_core27.AGENT_TOOL_REGISTRY,
4454
+ import_nestjs_agent_core27.AGENT_REGISTRY,
4455
+ import_nestjs_agent_core27.AGENT_SINK,
4456
+ import_nestjs_agent_core27.AGENT_ROLES_POLICY,
4457
+ import_nestjs_agent_core27.AGENT_ACTOR_RESOLVER,
4458
+ import_nestjs_agent_core27.AGENT_MODEL,
4290
4459
  ...includeStore ? [
4291
- import_nestjs_agent_core26.AGENT_STORE
4460
+ import_nestjs_agent_core27.AGENT_STORE
4292
4461
  ] : [],
4293
- import_nestjs_agent_core26.AGENT_QUOTA_STORE,
4294
- import_nestjs_agent_core26.AGENT_MODEL_CATALOG,
4295
- import_nestjs_agent_core26.AGENT_PROMPT_CONTRIBUTORS,
4296
- import_nestjs_agent_core26.AGENT_SKILLS,
4297
- import_nestjs_agent_core26.AGENT_MEMORY,
4298
- import_nestjs_agent_core26.AGENT_DEPS_FACTORY,
4462
+ import_nestjs_agent_core27.AGENT_QUOTA_STORE,
4463
+ import_nestjs_agent_core27.AGENT_MODEL_CATALOG,
4464
+ import_nestjs_agent_core27.AGENT_QUOTA_PROVIDER,
4465
+ import_nestjs_agent_core27.AGENT_PROMPT_CONTRIBUTORS,
4466
+ import_nestjs_agent_core27.AGENT_SKILLS,
4467
+ import_nestjs_agent_core27.AGENT_MEMORY,
4468
+ import_nestjs_agent_core27.AGENT_DEPS_FACTORY,
4299
4469
  AgentDepsFactory2,
4300
4470
  AgentService,
4301
4471
  InlineAgentRunner,
4302
- import_nestjs_agent_core26.AGENT_APPROVAL_PORT
4472
+ import_nestjs_agent_core27.AGENT_APPROVAL_PORT
4303
4473
  ];
4304
4474
  }
4305
4475
  __name(exportsFor, "exportsFor");
@@ -4371,7 +4541,7 @@ var AgentModule = class _AgentModule {
4371
4541
  controllers: controllersForSurface(options.surface, options.attachments?.upload === true),
4372
4542
  providers: [
4373
4543
  {
4374
- provide: import_nestjs_agent_core26.AGENT_OPTIONS,
4544
+ provide: import_nestjs_agent_core27.AGENT_OPTIONS,
4375
4545
  useValue: options
4376
4546
  },
4377
4547
  ...sharedProviders(options.durable ?? false, includeStore),
@@ -4395,7 +4565,7 @@ var AgentModule = class _AgentModule {
4395
4565
  controllers: controllersForSurface(options.surface, options.attachmentsUpload === true),
4396
4566
  providers: [
4397
4567
  {
4398
- provide: import_nestjs_agent_core26.AGENT_OPTIONS,
4568
+ provide: import_nestjs_agent_core27.AGENT_OPTIONS,
4399
4569
  // Stamp the STATIC wiring flags onto the factory result: `durable`/`surface` are
4400
4570
  // authoritative on the async config object (they decided the actual wiring above), and
4401
4571
  // the durable module reads `durable` back off AGENT_OPTIONS. `surface` isn't read back by