@dudousxd/nestjs-agent 1.7.0 → 1.8.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.
@@ -821,7 +821,7 @@ AgentDurableModule = _ts_decorate4([
821
821
  ], AgentDurableModule);
822
822
 
823
823
  // src/agent.module.ts
824
- var import_nestjs_agent_core26 = require("@dudousxd/nestjs-agent-core");
824
+ var import_nestjs_agent_core27 = require("@dudousxd/nestjs-agent-core");
825
825
  var import_common23 = require("@nestjs/common");
826
826
  var import_core4 = require("@nestjs/core");
827
827
 
@@ -1129,13 +1129,68 @@ var AgentService = class {
1129
1129
  quota;
1130
1130
  staging;
1131
1131
  models;
1132
- constructor(runner, store, deps, quota, staging, models) {
1132
+ quotaProvider;
1133
+ options;
1134
+ constructor(runner, store, deps, quota, staging, models, quotaProvider, options) {
1133
1135
  this.runner = runner;
1134
1136
  this.store = store;
1135
1137
  this.deps = deps;
1136
1138
  this.quota = quota;
1137
1139
  this.staging = staging;
1138
1140
  this.models = models;
1141
+ this.quotaProvider = quotaProvider;
1142
+ this.options = options;
1143
+ }
1144
+ /**
1145
+ * The actor's budget across windows (`GET <base>/quota`) — the bound {@link QuotaProvider}'s
1146
+ * report. Without one (a service built outside the module), a day window from the ledger.
1147
+ */
1148
+ async quotaReport(actor) {
1149
+ if (this.quotaProvider !== void 0) {
1150
+ return this.quotaProvider.report({
1151
+ actor
1152
+ });
1153
+ }
1154
+ const today = await this.quotaToday(actor.id);
1155
+ return {
1156
+ windows: [
1157
+ {
1158
+ period: "day",
1159
+ usedTokens: today.usedTokens,
1160
+ ...today.limitTokens !== null ? {
1161
+ limitTokens: today.limitTokens
1162
+ } : {},
1163
+ usedUsd: today.costUsd
1164
+ }
1165
+ ],
1166
+ ...today.withinLimit ? {} : {
1167
+ blocked: {
1168
+ period: "day"
1169
+ }
1170
+ }
1171
+ };
1172
+ }
1173
+ /**
1174
+ * Refuse a turn the actor's budget no longer covers — only when the host configured one
1175
+ * (`quotaProvider` or `quotaLimits`): the default report is informational, and the daily token
1176
+ * quota the loop enforces keeps working as it always has.
1177
+ */
1178
+ async assertWithinQuota(actor) {
1179
+ const gated = this.options?.quotaProvider !== void 0 || this.options?.quotaLimits !== void 0;
1180
+ if (!gated || this.quotaProvider === void 0) {
1181
+ return;
1182
+ }
1183
+ const { blocked } = await this.quotaProvider.report({
1184
+ actor
1185
+ });
1186
+ if (blocked !== void 0) {
1187
+ throw new import_common6.HttpException({
1188
+ statusCode: import_common6.HttpStatus.TOO_MANY_REQUESTS,
1189
+ code: "quota_exceeded",
1190
+ period: blocked.period,
1191
+ message: blocked.reason ?? `The ${blocked.period === "day" ? "daily" : "monthly"} quota is used up`
1192
+ }, import_common6.HttpStatus.TOO_MANY_REQUESTS);
1193
+ }
1139
1194
  }
1140
1195
  /**
1141
1196
  * The models `actor` may pick for `agent` (`GET <base>/models`). An empty catalog when none is
@@ -1192,6 +1247,7 @@ var AgentService = class {
1192
1247
  return (await this.store.getThread(threadId))?.model ?? null;
1193
1248
  }
1194
1249
  async chat(params) {
1250
+ await this.assertWithinQuota(params.actor);
1195
1251
  const agentName = await this.resolveAgentName(params.agentName, params.threadId);
1196
1252
  const model = await this.resolveModel(params.actor, agentName, params.model, params.threadId);
1197
1253
  const attachments = await this.resolveAttachments(params.actor, params.attachments ?? []);
@@ -1733,6 +1789,10 @@ AgentService = _ts_decorate6([
1733
1789
  _ts_param5(4, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_ATTACHMENT_STAGING)),
1734
1790
  _ts_param5(5, (0, import_common6.Optional)()),
1735
1791
  _ts_param5(5, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_MODEL_CATALOG)),
1792
+ _ts_param5(6, (0, import_common6.Optional)()),
1793
+ _ts_param5(6, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_QUOTA_PROVIDER)),
1794
+ _ts_param5(7, (0, import_common6.Optional)()),
1795
+ _ts_param5(7, (0, import_common6.Inject)(import_nestjs_agent_core8.AGENT_OPTIONS)),
1736
1796
  _ts_metadata5("design:type", Function),
1737
1797
  _ts_metadata5("design:paramtypes", [
1738
1798
  typeof AgentRunner === "undefined" ? Object : AgentRunner,
@@ -1740,7 +1800,9 @@ AgentService = _ts_decorate6([
1740
1800
  typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
1741
1801
  Object,
1742
1802
  typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore,
1743
- typeof ModelCatalog === "undefined" ? Object : ModelCatalog
1803
+ typeof ModelCatalog === "undefined" ? Object : ModelCatalog,
1804
+ typeof QuotaProvider === "undefined" ? Object : QuotaProvider,
1805
+ typeof Pick === "undefined" ? Object : Pick
1744
1806
  ])
1745
1807
  ], AgentService);
1746
1808
 
@@ -2587,11 +2649,28 @@ var QuotaController = class {
2587
2649
  this.agent = agent;
2588
2650
  this.actorResolver = actorResolver;
2589
2651
  }
2652
+ /**
2653
+ * The caller's budget across windows — `{ windows: [{ period, usedTokens, limitTokens?, usedUsd,
2654
+ * limitUsd?, resetsAt? }], blocked?: { period, reason? } }` — from the bound `QuotaProvider`.
2655
+ */
2656
+ async report(req) {
2657
+ const actor = await this.actorResolver.resolve(req);
2658
+ return this.agent.quotaReport(actor);
2659
+ }
2590
2660
  async today(req) {
2591
2661
  const actor = await this.actorResolver.resolve(req);
2592
2662
  return this.agent.quotaToday(actor.id);
2593
2663
  }
2594
2664
  };
2665
+ _ts_decorate14([
2666
+ (0, import_common14.Get)(),
2667
+ _ts_param12(0, (0, import_common14.Req)()),
2668
+ _ts_metadata13("design:type", Function),
2669
+ _ts_metadata13("design:paramtypes", [
2670
+ typeof Request === "undefined" ? Object : Request
2671
+ ]),
2672
+ _ts_metadata13("design:returntype", Promise)
2673
+ ], QuotaController.prototype, "report", null);
2595
2674
  _ts_decorate14([
2596
2675
  (0, import_common14.Get)("today"),
2597
2676
  _ts_param12(0, (0, import_common14.Req)()),
@@ -3639,6 +3718,69 @@ SkillDiscoveryService = _ts_decorate21([
3639
3718
  ])
3640
3719
  ], SkillDiscoveryService);
3641
3720
 
3721
+ // src/ledger-quota-provider.ts
3722
+ var import_nestjs_agent_core24 = require("@dudousxd/nestjs-agent-core");
3723
+ var LedgerQuotaProvider = class {
3724
+ static {
3725
+ __name(this, "LedgerQuotaProvider");
3726
+ }
3727
+ store;
3728
+ quota;
3729
+ limits;
3730
+ constructor(store, quota, limits = {}) {
3731
+ this.store = store;
3732
+ this.quota = quota;
3733
+ this.limits = limits;
3734
+ }
3735
+ async report(query) {
3736
+ const now = query.now ?? /* @__PURE__ */ new Date();
3737
+ const actorRef = query.actor.id;
3738
+ const windows = [
3739
+ await this.dayWindow(actorRef, now)
3740
+ ];
3741
+ if (this.store.usageBetween !== void 0) {
3742
+ const range = (0, import_nestjs_agent_core24.quotaPeriodRange)("month", now);
3743
+ const used = await this.store.usageBetween(actorRef, range.fromDay, range.toDay);
3744
+ windows.push(this.window("month", used.usedTokens, used.costUsd, range.resetsAt));
3745
+ }
3746
+ const blocked = (0, import_nestjs_agent_core24.exhaustedWindow)(windows);
3747
+ return {
3748
+ windows,
3749
+ ...blocked !== void 0 ? {
3750
+ blocked
3751
+ } : {}
3752
+ };
3753
+ }
3754
+ async dayWindow(actorRef, now) {
3755
+ const range = (0, import_nestjs_agent_core24.quotaPeriodRange)("day", now);
3756
+ const { usedTokens, costUsd } = await this.store.quotaToday(actorRef, range.fromDay);
3757
+ if (this.quota === void 0) {
3758
+ return this.window("day", usedTokens, costUsd, range.resetsAt);
3759
+ }
3760
+ const state = await this.quota.check(actorRef, range.fromDay);
3761
+ const window = this.window("day", state.usedTokens, costUsd, range.resetsAt);
3762
+ if (window.limitTokens === void 0) {
3763
+ window.limitTokens = state.limitTokens;
3764
+ }
3765
+ return window;
3766
+ }
3767
+ window(period, usedTokens, usedUsd, resetsAt) {
3768
+ const limits = this.limits[period] ?? {};
3769
+ return {
3770
+ period,
3771
+ usedTokens,
3772
+ ...limits.tokens !== void 0 ? {
3773
+ limitTokens: limits.tokens
3774
+ } : {},
3775
+ usedUsd,
3776
+ ...limits.usd !== void 0 ? {
3777
+ limitUsd: limits.usd
3778
+ } : {},
3779
+ resetsAt
3780
+ };
3781
+ }
3782
+ };
3783
+
3642
3784
  // src/ledger-quota-store.ts
3643
3785
  var LedgerQuotaStore = class {
3644
3786
  static {
@@ -3663,7 +3805,7 @@ var LedgerQuotaStore = class {
3663
3805
  };
3664
3806
 
3665
3807
  // src/runner/inline-agent-runner.ts
3666
- var import_nestjs_agent_core24 = require("@dudousxd/nestjs-agent-core");
3808
+ var import_nestjs_agent_core25 = require("@dudousxd/nestjs-agent-core");
3667
3809
  var import_common22 = require("@nestjs/common");
3668
3810
  function _ts_decorate22(decorators, target, key, desc) {
3669
3811
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -3726,18 +3868,18 @@ var InlineAgentRunner = class _InlineAgentRunner {
3726
3868
  ] : []
3727
3869
  ]
3728
3870
  });
3729
- void (0, import_nestjs_agent_core24.runAgentLoop)({
3871
+ void (0, import_nestjs_agent_core25.runAgentLoop)({
3730
3872
  ...deps,
3731
3873
  day
3732
3874
  }, input, hooks).then(() => this.store.setActiveStream(input.threadId, null)).catch(async (error) => {
3733
- if (error instanceof import_nestjs_agent_core24.RunCancelledError) {
3875
+ if (error instanceof import_nestjs_agent_core25.RunCancelledError) {
3734
3876
  await this.settleCancelled(runId, input.threadId, deps);
3735
3877
  return;
3736
3878
  }
3737
3879
  const message = error instanceof Error ? error.message : String(error);
3738
- const code = (0, import_nestjs_agent_core24.agentFailureCode)(error);
3880
+ const code = (0, import_nestjs_agent_core25.agentFailureCode)(error);
3739
3881
  this.logger.error(`agent run ${runId} failed (${code}): ${message}`);
3740
- (0, import_nestjs_agent_core24.publishAgentRunFailed)({
3882
+ (0, import_nestjs_agent_core25.publishAgentRunFailed)({
3741
3883
  runId,
3742
3884
  code,
3743
3885
  message
@@ -3786,7 +3928,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
3786
3928
  for (const [key, waiter] of this.pending) {
3787
3929
  if (key.startsWith(`${runId}:`)) {
3788
3930
  this.pending.delete(key);
3789
- waiter.reject(new import_nestjs_agent_core24.RunCancelledError());
3931
+ waiter.reject(new import_nestjs_agent_core25.RunCancelledError());
3790
3932
  }
3791
3933
  }
3792
3934
  await Promise.resolve();
@@ -3801,7 +3943,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
3801
3943
  this.logger.log(`agent run ${runId} cancelled`);
3802
3944
  await this.store.setActiveStream(threadId, null);
3803
3945
  const writer = await deps.sink.open(runId);
3804
- await writer.write((0, import_nestjs_agent_core24.encodeStreamEvent)({
3946
+ await writer.write((0, import_nestjs_agent_core25.encodeStreamEvent)({
3805
3947
  kind: "cancelled"
3806
3948
  }));
3807
3949
  await writer.end();
@@ -3862,7 +4004,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
3862
4004
  awaitApproval: /* @__PURE__ */ __name((call, _ctx, opts) => this.parkApproval(runId, call.id, opts?.timeoutMs), "awaitApproval"),
3863
4005
  awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
3864
4006
  step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
3865
- parallel: import_nestjs_agent_core24.settleAll,
4007
+ parallel: import_nestjs_agent_core25.settleAll,
3866
4008
  cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId), "cancelled"),
3867
4009
  runAgent: /* @__PURE__ */ __name((agentName, task) => this.runNested({
3868
4010
  agentName,
@@ -3913,7 +4055,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
3913
4055
  awaitApproval: /* @__PURE__ */ __name((call, _ctx, opts) => this.parkApproval(runId, call.id, opts?.timeoutMs), "awaitApproval"),
3914
4056
  awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
3915
4057
  step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
3916
- parallel: import_nestjs_agent_core24.settleAll,
4058
+ parallel: import_nestjs_agent_core25.settleAll,
3917
4059
  cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId), "cancelled"),
3918
4060
  runAgent: /* @__PURE__ */ __name((childName, childTask) => this.runNested({
3919
4061
  agentName: childName,
@@ -3946,7 +4088,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
3946
4088
  }
3947
4089
  }), "startAgent")
3948
4090
  };
3949
- void (0, import_nestjs_agent_core24.runAgentLoop)({
4091
+ void (0, import_nestjs_agent_core25.runAgentLoop)({
3950
4092
  ...deps,
3951
4093
  day
3952
4094
  }, {
@@ -3960,13 +4102,13 @@ var InlineAgentRunner = class _InlineAgentRunner {
3960
4102
  parentRunId,
3961
4103
  deliverTo
3962
4104
  }, hooks).catch(async (error) => {
3963
- const cancelled = error instanceof import_nestjs_agent_core24.RunCancelledError;
4105
+ const cancelled = error instanceof import_nestjs_agent_core25.RunCancelledError;
3964
4106
  const message = error instanceof Error ? error.message : String(error);
3965
4107
  if (!cancelled) {
3966
4108
  this.logger.error(`detached agent run ${runId} failed: ${message}`);
3967
- (0, import_nestjs_agent_core24.publishAgentRunFailed)({
4109
+ (0, import_nestjs_agent_core25.publishAgentRunFailed)({
3968
4110
  runId,
3969
- code: (0, import_nestjs_agent_core24.agentFailureCode)(error),
4111
+ code: (0, import_nestjs_agent_core25.agentFailureCode)(error),
3970
4112
  message
3971
4113
  });
3972
4114
  }
@@ -3974,11 +4116,11 @@ var InlineAgentRunner = class _InlineAgentRunner {
3974
4116
  runId,
3975
4117
  status: cancelled ? "cancelled" : "failed",
3976
4118
  ...cancelled ? {} : {
3977
- errorCode: (0, import_nestjs_agent_core24.agentFailureCode)(error),
4119
+ errorCode: (0, import_nestjs_agent_core25.agentFailureCode)(error),
3978
4120
  errorMessage: message
3979
4121
  }
3980
4122
  });
3981
- await (0, import_nestjs_agent_core24.settleUnsettledDelegation)({
4123
+ await (0, import_nestjs_agent_core25.settleUnsettledDelegation)({
3982
4124
  store: this.store,
3983
4125
  delivery: deliverTo,
3984
4126
  agent: agentName,
@@ -4017,7 +4159,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
4017
4159
  awaitApproval: /* @__PURE__ */ __name((call, _ctx, opts) => this.parkApproval(runId, call.id, opts?.timeoutMs), "awaitApproval"),
4018
4160
  awaitAnswers: /* @__PURE__ */ __name((request) => this.park(runId, request.id), "awaitAnswers"),
4019
4161
  step: /* @__PURE__ */ __name((_name, fn) => fn(), "step"),
4020
- parallel: import_nestjs_agent_core24.settleAll,
4162
+ parallel: import_nestjs_agent_core25.settleAll,
4021
4163
  // A child stops when it is cancelled OR when the run a human is actually watching is: the
4022
4164
  // canceller names the top-level run, which is the only id that ever left the server.
4023
4165
  cancelled: /* @__PURE__ */ __name(async () => this.cancelled.has(runId) || this.cancelled.has(sinkRunId), "cancelled"),
@@ -4052,7 +4194,7 @@ var InlineAgentRunner = class _InlineAgentRunner {
4052
4194
  }), "startAgent")
4053
4195
  };
4054
4196
  try {
4055
- return await (0, import_nestjs_agent_core24.runAgentLoop)({
4197
+ return await (0, import_nestjs_agent_core25.runAgentLoop)({
4056
4198
  ...deps,
4057
4199
  day
4058
4200
  }, {
@@ -4073,8 +4215,8 @@ var InlineAgentRunner = class _InlineAgentRunner {
4073
4215
  };
4074
4216
  InlineAgentRunner = _ts_decorate22([
4075
4217
  (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)),
4218
+ _ts_param20(0, (0, import_common22.Inject)(import_nestjs_agent_core25.AGENT_DEPS_FACTORY)),
4219
+ _ts_param20(1, (0, import_common22.Inject)(import_nestjs_agent_core25.AGENT_STORE)),
4078
4220
  _ts_metadata21("design:type", Function),
4079
4221
  _ts_metadata21("design:paramtypes", [
4080
4222
  typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
@@ -4083,7 +4225,7 @@ InlineAgentRunner = _ts_decorate22([
4083
4225
  ], InlineAgentRunner);
4084
4226
 
4085
4227
  // src/skills-config.ts
4086
- var import_nestjs_agent_core25 = require("@dudousxd/nestjs-agent-core");
4228
+ var import_nestjs_agent_core26 = require("@dudousxd/nestjs-agent-core");
4087
4229
  function declaredSkillProvider(declared) {
4088
4230
  return {
4089
4231
  list: /* @__PURE__ */ __name(({ scopes }) => declared.filter((skill) => scopes.includes(skill.scope)).map(({ name, description, scope }) => ({
@@ -4109,7 +4251,7 @@ function resolveSkillsConfig(options, declared) {
4109
4251
  declaredSkillProvider(declared)
4110
4252
  ];
4111
4253
  return {
4112
- provider: providers.length === 1 ? providers[0] : (0, import_nestjs_agent_core25.compositeSkillProvider)(providers),
4254
+ provider: providers.length === 1 ? providers[0] : (0, import_nestjs_agent_core26.compositeSkillProvider)(providers),
4113
4255
  ...options.scopes !== void 0 ? {
4114
4256
  scopes: options.scopes
4115
4257
  } : {},
@@ -4139,94 +4281,103 @@ var DEFAULT_PATH = "agent";
4139
4281
  function sharedProviders(durable, includeStore) {
4140
4282
  const providers = [
4141
4283
  {
4142
- provide: import_nestjs_agent_core26.AGENT_TOOL_REGISTRY,
4143
- useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core26.ToolRegistry(), "useFactory")
4284
+ provide: import_nestjs_agent_core27.AGENT_TOOL_REGISTRY,
4285
+ useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core27.ToolRegistry(), "useFactory")
4144
4286
  },
4145
4287
  // Starts empty; AgentDiscoveryService populates it from `@Agent`-decorated providers at boot.
4146
4288
  {
4147
- provide: import_nestjs_agent_core26.AGENT_REGISTRY,
4148
- useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core26.AgentRegistry(), "useFactory")
4289
+ provide: import_nestjs_agent_core27.AGENT_REGISTRY,
4290
+ useFactory: /* @__PURE__ */ __name(() => new import_nestjs_agent_core27.AgentRegistry(), "useFactory")
4149
4291
  },
4150
4292
  // A shared, mutable list AgentDiscoveryService fills with `@SystemPromptContributor()` methods.
4151
4293
  {
4152
- provide: import_nestjs_agent_core26.AGENT_PROMPT_CONTRIBUTORS,
4294
+ provide: import_nestjs_agent_core27.AGENT_PROMPT_CONTRIBUTORS,
4153
4295
  useFactory: /* @__PURE__ */ __name(() => [], "useFactory")
4154
4296
  },
4155
4297
  // Likewise for `@Skill`-decorated providers — filled by SkillDiscoveryService at onModuleInit,
4156
4298
  // read lazily by the AGENT_SKILLS provider below (which DI builds before discovery has run).
4157
4299
  {
4158
- provide: import_nestjs_agent_core26.AGENT_SKILL_SOURCES,
4300
+ provide: import_nestjs_agent_core27.AGENT_SKILL_SOURCES,
4159
4301
  useFactory: /* @__PURE__ */ __name(() => [], "useFactory")
4160
4302
  },
4161
4303
  {
4162
4304
  // One resolution, shared by the loop's deps and the listing endpoint: a second one would
4163
4305
  // drift, and a user would be offered a skill the agent cannot reach. `undefined` when the
4164
4306
  // host configured none — which is what keeps the turn's checkpoint sequence unchanged.
4165
- provide: import_nestjs_agent_core26.AGENT_SKILLS,
4307
+ provide: import_nestjs_agent_core27.AGENT_SKILLS,
4166
4308
  useFactory: /* @__PURE__ */ __name((options, declared) => resolveSkillsConfig(options.skills, declared), "useFactory"),
4167
4309
  inject: [
4168
- import_nestjs_agent_core26.AGENT_OPTIONS,
4169
- import_nestjs_agent_core26.AGENT_SKILL_SOURCES
4310
+ import_nestjs_agent_core27.AGENT_OPTIONS,
4311
+ import_nestjs_agent_core27.AGENT_SKILL_SOURCES
4170
4312
  ]
4171
4313
  },
4172
4314
  {
4173
4315
  // One resolution, shared by the loop's deps and the read-back endpoint: a person has to be
4174
4316
  // shown what the model was shown, and two resolutions would eventually disagree about that.
4175
- provide: import_nestjs_agent_core26.AGENT_MEMORY,
4317
+ provide: import_nestjs_agent_core27.AGENT_MEMORY,
4176
4318
  useFactory: /* @__PURE__ */ __name((options) => options.memory, "useFactory"),
4177
4319
  inject: [
4178
- import_nestjs_agent_core26.AGENT_OPTIONS
4320
+ import_nestjs_agent_core27.AGENT_OPTIONS
4179
4321
  ]
4180
4322
  },
4181
4323
  {
4182
- provide: import_nestjs_agent_core26.AGENT_SINK,
4324
+ provide: import_nestjs_agent_core27.AGENT_SINK,
4183
4325
  useFactory: /* @__PURE__ */ __name((options) => options.sink ?? new InProcessTokenStreamSink(), "useFactory"),
4184
4326
  inject: [
4185
- import_nestjs_agent_core26.AGENT_OPTIONS
4327
+ import_nestjs_agent_core27.AGENT_OPTIONS
4186
4328
  ]
4187
4329
  },
4188
4330
  {
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"),
4331
+ provide: import_nestjs_agent_core27.AGENT_ROLES_POLICY,
4332
+ useFactory: /* @__PURE__ */ __name((options) => options.rolesPolicy ?? new import_nestjs_agent_core27.DefaultRolesPolicy(options.defaultRoles), "useFactory"),
4191
4333
  inject: [
4192
- import_nestjs_agent_core26.AGENT_OPTIONS
4334
+ import_nestjs_agent_core27.AGENT_OPTIONS
4193
4335
  ]
4194
4336
  },
4195
4337
  {
4196
- provide: import_nestjs_agent_core26.AGENT_ACTOR_RESOLVER,
4338
+ provide: import_nestjs_agent_core27.AGENT_ACTOR_RESOLVER,
4197
4339
  useFactory: /* @__PURE__ */ __name((options) => options.actorResolver, "useFactory"),
4198
4340
  inject: [
4199
- import_nestjs_agent_core26.AGENT_OPTIONS
4341
+ import_nestjs_agent_core27.AGENT_OPTIONS
4200
4342
  ]
4201
4343
  },
4202
4344
  {
4203
- provide: import_nestjs_agent_core26.AGENT_MODEL,
4345
+ provide: import_nestjs_agent_core27.AGENT_MODEL,
4204
4346
  useFactory: /* @__PURE__ */ __name((o) => o.model, "useFactory"),
4205
4347
  inject: [
4206
- import_nestjs_agent_core26.AGENT_OPTIONS
4348
+ import_nestjs_agent_core27.AGENT_OPTIONS
4207
4349
  ]
4208
4350
  },
4209
4351
  {
4210
4352
  // An explicit `quota` wins; otherwise `quotaLimitTokens` binds the built-in ledger-backed
4211
4353
  // store; otherwise quotas are off (undefined). The ledger store reads the same usage rows
4212
4354
  // the loop already writes, so enforcement needs no extra shared state across replicas.
4213
- provide: import_nestjs_agent_core26.AGENT_QUOTA_STORE,
4355
+ provide: import_nestjs_agent_core27.AGENT_QUOTA_STORE,
4214
4356
  useFactory: /* @__PURE__ */ __name((o, store) => o.quota ?? (o.quotaLimitTokens !== void 0 ? new LedgerQuotaStore(store, o.quotaLimitTokens) : void 0), "useFactory"),
4215
4357
  inject: [
4216
- import_nestjs_agent_core26.AGENT_OPTIONS,
4217
- import_nestjs_agent_core26.AGENT_STORE
4358
+ import_nestjs_agent_core27.AGENT_OPTIONS,
4359
+ import_nestjs_agent_core27.AGENT_STORE
4360
+ ]
4361
+ },
4362
+ {
4363
+ provide: import_nestjs_agent_core27.AGENT_QUOTA_PROVIDER,
4364
+ useFactory: /* @__PURE__ */ __name((o, store, quota) => o.quotaProvider ?? new LedgerQuotaProvider(store, quota, o.quotaLimits), "useFactory"),
4365
+ inject: [
4366
+ import_nestjs_agent_core27.AGENT_OPTIONS,
4367
+ import_nestjs_agent_core27.AGENT_STORE,
4368
+ import_nestjs_agent_core27.AGENT_QUOTA_STORE
4218
4369
  ]
4219
4370
  },
4220
4371
  {
4221
- provide: import_nestjs_agent_core26.AGENT_MODEL_CATALOG,
4372
+ provide: import_nestjs_agent_core27.AGENT_MODEL_CATALOG,
4222
4373
  useFactory: /* @__PURE__ */ __name((o) => o.models, "useFactory"),
4223
4374
  inject: [
4224
- import_nestjs_agent_core26.AGENT_OPTIONS
4375
+ import_nestjs_agent_core27.AGENT_OPTIONS
4225
4376
  ]
4226
4377
  },
4227
4378
  AgentDepsFactory2,
4228
4379
  {
4229
- provide: import_nestjs_agent_core26.AGENT_DEPS_FACTORY,
4380
+ provide: import_nestjs_agent_core27.AGENT_DEPS_FACTORY,
4230
4381
  useExisting: AgentDepsFactory2
4231
4382
  },
4232
4383
  // Populates the registry + contributors (onModuleInit) BEFORE AiToolDiscoveryService synthesizes
@@ -4240,22 +4391,22 @@ function sharedProviders(durable, includeStore) {
4240
4391
  // through AgentService.signalToolCall, which reaches whichever AGENT_RUNNER is bound above.
4241
4392
  AgentApprovalPortAdapter,
4242
4393
  {
4243
- provide: import_nestjs_agent_core26.AGENT_APPROVAL_PORT,
4394
+ provide: import_nestjs_agent_core27.AGENT_APPROVAL_PORT,
4244
4395
  useExisting: AgentApprovalPortAdapter
4245
4396
  }
4246
4397
  ];
4247
4398
  if (includeStore) {
4248
4399
  providers.push({
4249
- provide: import_nestjs_agent_core26.AGENT_STORE,
4400
+ provide: import_nestjs_agent_core27.AGENT_STORE,
4250
4401
  useFactory: /* @__PURE__ */ __name((o) => o.store, "useFactory"),
4251
4402
  inject: [
4252
- import_nestjs_agent_core26.AGENT_OPTIONS
4403
+ import_nestjs_agent_core27.AGENT_OPTIONS
4253
4404
  ]
4254
4405
  });
4255
4406
  }
4256
4407
  if (durable) {
4257
4408
  providers.push({
4258
- provide: import_nestjs_agent_core26.AGENT_RUNNER,
4409
+ provide: import_nestjs_agent_core27.AGENT_RUNNER,
4259
4410
  useFactory: /* @__PURE__ */ __name((durableRunner) => {
4260
4411
  if (durableRunner === void 0) {
4261
4412
  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 +4415,14 @@ function sharedProviders(durable, includeStore) {
4264
4415
  }, "useFactory"),
4265
4416
  inject: [
4266
4417
  {
4267
- token: import_nestjs_agent_core26.AGENT_DURABLE_RUNNER,
4418
+ token: import_nestjs_agent_core27.AGENT_DURABLE_RUNNER,
4268
4419
  optional: true
4269
4420
  }
4270
4421
  ]
4271
4422
  });
4272
4423
  } else {
4273
4424
  providers.push({
4274
- provide: import_nestjs_agent_core26.AGENT_RUNNER,
4425
+ provide: import_nestjs_agent_core27.AGENT_RUNNER,
4275
4426
  useExisting: InlineAgentRunner
4276
4427
  });
4277
4428
  }
@@ -4280,26 +4431,27 @@ function sharedProviders(durable, includeStore) {
4280
4431
  __name(sharedProviders, "sharedProviders");
4281
4432
  function exportsFor(includeStore) {
4282
4433
  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,
4434
+ import_nestjs_agent_core27.AGENT_OPTIONS,
4435
+ import_nestjs_agent_core27.AGENT_TOOL_REGISTRY,
4436
+ import_nestjs_agent_core27.AGENT_REGISTRY,
4437
+ import_nestjs_agent_core27.AGENT_SINK,
4438
+ import_nestjs_agent_core27.AGENT_ROLES_POLICY,
4439
+ import_nestjs_agent_core27.AGENT_ACTOR_RESOLVER,
4440
+ import_nestjs_agent_core27.AGENT_MODEL,
4290
4441
  ...includeStore ? [
4291
- import_nestjs_agent_core26.AGENT_STORE
4442
+ import_nestjs_agent_core27.AGENT_STORE
4292
4443
  ] : [],
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,
4444
+ import_nestjs_agent_core27.AGENT_QUOTA_STORE,
4445
+ import_nestjs_agent_core27.AGENT_MODEL_CATALOG,
4446
+ import_nestjs_agent_core27.AGENT_QUOTA_PROVIDER,
4447
+ import_nestjs_agent_core27.AGENT_PROMPT_CONTRIBUTORS,
4448
+ import_nestjs_agent_core27.AGENT_SKILLS,
4449
+ import_nestjs_agent_core27.AGENT_MEMORY,
4450
+ import_nestjs_agent_core27.AGENT_DEPS_FACTORY,
4299
4451
  AgentDepsFactory2,
4300
4452
  AgentService,
4301
4453
  InlineAgentRunner,
4302
- import_nestjs_agent_core26.AGENT_APPROVAL_PORT
4454
+ import_nestjs_agent_core27.AGENT_APPROVAL_PORT
4303
4455
  ];
4304
4456
  }
4305
4457
  __name(exportsFor, "exportsFor");
@@ -4371,7 +4523,7 @@ var AgentModule = class _AgentModule {
4371
4523
  controllers: controllersForSurface(options.surface, options.attachments?.upload === true),
4372
4524
  providers: [
4373
4525
  {
4374
- provide: import_nestjs_agent_core26.AGENT_OPTIONS,
4526
+ provide: import_nestjs_agent_core27.AGENT_OPTIONS,
4375
4527
  useValue: options
4376
4528
  },
4377
4529
  ...sharedProviders(options.durable ?? false, includeStore),
@@ -4395,7 +4547,7 @@ var AgentModule = class _AgentModule {
4395
4547
  controllers: controllersForSurface(options.surface, options.attachmentsUpload === true),
4396
4548
  providers: [
4397
4549
  {
4398
- provide: import_nestjs_agent_core26.AGENT_OPTIONS,
4550
+ provide: import_nestjs_agent_core27.AGENT_OPTIONS,
4399
4551
  // Stamp the STATIC wiring flags onto the factory result: `durable`/`surface` are
4400
4552
  // authoritative on the async config object (they decided the actual wiring above), and
4401
4553
  // the durable module reads `durable` back off AGENT_OPTIONS. `surface` isn't read back by