@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.
@@ -1,6 +1,6 @@
1
1
  import { AgentStore, AgentRunInput, AgentLoopResult, LlmStepEnvelope, BufferedModelTurnResult, ToolStepEnvelope, AgentRunner, TokenStreamSink, HumanReply } from '@dudousxd/nestjs-agent-core';
2
2
  import { RunGateway, WorkflowCtx } from '@dudousxd/nestjs-durable-core';
3
- import { A as AgentDepsFactory, a as AgentSurface, b as AgentModuleOptions } from '../agent-deps.factory-CiC5Va9J.cjs';
3
+ import { A as AgentDepsFactory, a as AgentSurface, b as AgentModuleOptions } from '../agent-deps.factory-DuTy1UyU.cjs';
4
4
  import { WorkflowService } from '@dudousxd/nestjs-durable';
5
5
  import { DynamicModule } from '@nestjs/common';
6
6
  import '@standard-schema/spec';
@@ -1,6 +1,6 @@
1
1
  import { AgentStore, AgentRunInput, AgentLoopResult, LlmStepEnvelope, BufferedModelTurnResult, ToolStepEnvelope, AgentRunner, TokenStreamSink, HumanReply } from '@dudousxd/nestjs-agent-core';
2
2
  import { RunGateway, WorkflowCtx } from '@dudousxd/nestjs-durable-core';
3
- import { A as AgentDepsFactory, a as AgentSurface, b as AgentModuleOptions } from '../agent-deps.factory-CiC5Va9J.js';
3
+ import { A as AgentDepsFactory, a as AgentSurface, b as AgentModuleOptions } from '../agent-deps.factory-DuTy1UyU.js';
4
4
  import { WorkflowService } from '@dudousxd/nestjs-durable';
5
5
  import { DynamicModule } from '@nestjs/common';
6
6
  import '@standard-schema/spec';
@@ -72,7 +72,14 @@ var AgentRunSteps = class {
72
72
  const tools = withMemoryTool({
73
73
  tools: withSkillTool({
74
74
  tools: withAskTool({
75
- tools: await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList),
75
+ tools: await deps.registry.definitionsFor(input.actor, deps.rolesPolicy, deps.toolAllowList, {
76
+ ...input.threadId !== void 0 ? {
77
+ threadId: input.threadId
78
+ } : {},
79
+ ...input.agentName !== void 0 ? {
80
+ agentName: input.agentName
81
+ } : {}
82
+ }),
76
83
  ask: deps.ask
77
84
  }),
78
85
  enabled: deps.skills !== void 0
@@ -793,7 +800,7 @@ AgentDurableModule = _ts_decorate4([
793
800
  ], AgentDurableModule);
794
801
 
795
802
  // src/agent.module.ts
796
- import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER11, AGENT_APPROVAL_PORT, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY7, AGENT_DURABLE_RUNNER as AGENT_DURABLE_RUNNER2, AGENT_MEMORY as AGENT_MEMORY3, AGENT_MODEL as AGENT_MODEL2, AGENT_MODEL_CATALOG as AGENT_MODEL_CATALOG2, AGENT_OPTIONS as AGENT_OPTIONS4, AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS3, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE3, AGENT_REGISTRY as AGENT_REGISTRY6, AGENT_ROLES_POLICY as AGENT_ROLES_POLICY2, AGENT_RUNNER as AGENT_RUNNER2, AGENT_SINK as AGENT_SINK3, AGENT_SKILLS as AGENT_SKILLS3, AGENT_SKILL_SOURCES as AGENT_SKILL_SOURCES2, AGENT_STORE as AGENT_STORE6, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY3, AgentRegistry as AgentRegistry6, DefaultRolesPolicy, ToolRegistry as ToolRegistry3 } from "@dudousxd/nestjs-agent-core";
803
+ import { AGENT_ACTOR_RESOLVER as AGENT_ACTOR_RESOLVER11, AGENT_APPROVAL_PORT, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY7, AGENT_DURABLE_RUNNER as AGENT_DURABLE_RUNNER2, AGENT_MEMORY as AGENT_MEMORY3, AGENT_MODEL as AGENT_MODEL2, AGENT_MODEL_CATALOG as AGENT_MODEL_CATALOG2, AGENT_OPTIONS as AGENT_OPTIONS5, AGENT_PROMPT_CONTRIBUTORS as AGENT_PROMPT_CONTRIBUTORS3, AGENT_QUOTA_PROVIDER as AGENT_QUOTA_PROVIDER2, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE3, AGENT_REGISTRY as AGENT_REGISTRY6, AGENT_ROLES_POLICY as AGENT_ROLES_POLICY2, AGENT_RUNNER as AGENT_RUNNER2, AGENT_SINK as AGENT_SINK3, AGENT_SKILLS as AGENT_SKILLS3, AGENT_SKILL_SOURCES as AGENT_SKILL_SOURCES2, AGENT_STORE as AGENT_STORE6, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY3, AgentRegistry as AgentRegistry6, DefaultRolesPolicy, ToolRegistry as ToolRegistry3 } from "@dudousxd/nestjs-agent-core";
797
804
  import { Global as Global2, Module as Module2 } from "@nestjs/common";
798
805
  import { DiscoveryModule, RouterModule } from "@nestjs/core";
799
806
 
@@ -1063,8 +1070,8 @@ AgentDepsFactory2 = _ts_decorate5([
1063
1070
  ], AgentDepsFactory2);
1064
1071
 
1065
1072
  // src/agent.service.ts
1066
- import { AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY3, AGENT_MODEL_CATALOG, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE4, REQUESTER_APPROVER, findCatalogModel, mayDecideApproval, readElicitationQuestions, validateElicitationAnswer } from "@dudousxd/nestjs-agent-core";
1067
- import { BadRequestException, ForbiddenException, GoneException, Inject as Inject5, Injectable as Injectable5, NotFoundException, NotImplementedException, Optional as Optional3 } from "@nestjs/common";
1073
+ import { AGENT_ATTACHMENT_STAGING, AGENT_DEPS_FACTORY as AGENT_DEPS_FACTORY3, AGENT_MODEL_CATALOG, AGENT_OPTIONS as AGENT_OPTIONS2, AGENT_QUOTA_PROVIDER, AGENT_QUOTA_STORE as AGENT_QUOTA_STORE2, AGENT_RUNNER, AGENT_STORE as AGENT_STORE4, REQUESTER_APPROVER, findCatalogModel, mayDecideApproval, readElicitationQuestions, validateElicitationAnswer } from "@dudousxd/nestjs-agent-core";
1074
+ import { BadRequestException, ForbiddenException, GoneException, HttpException, HttpStatus, Inject as Inject5, Injectable as Injectable5, NotFoundException, NotImplementedException, Optional as Optional3 } from "@nestjs/common";
1068
1075
  function _ts_decorate6(decorators, target, key, desc) {
1069
1076
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1070
1077
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -1101,13 +1108,68 @@ var AgentService = class {
1101
1108
  quota;
1102
1109
  staging;
1103
1110
  models;
1104
- constructor(runner, store, deps, quota, staging, models) {
1111
+ quotaProvider;
1112
+ options;
1113
+ constructor(runner, store, deps, quota, staging, models, quotaProvider, options) {
1105
1114
  this.runner = runner;
1106
1115
  this.store = store;
1107
1116
  this.deps = deps;
1108
1117
  this.quota = quota;
1109
1118
  this.staging = staging;
1110
1119
  this.models = models;
1120
+ this.quotaProvider = quotaProvider;
1121
+ this.options = options;
1122
+ }
1123
+ /**
1124
+ * The actor's budget across windows (`GET <base>/quota`) — the bound {@link QuotaProvider}'s
1125
+ * report. Without one (a service built outside the module), a day window from the ledger.
1126
+ */
1127
+ async quotaReport(actor) {
1128
+ if (this.quotaProvider !== void 0) {
1129
+ return this.quotaProvider.report({
1130
+ actor
1131
+ });
1132
+ }
1133
+ const today = await this.quotaToday(actor.id);
1134
+ return {
1135
+ windows: [
1136
+ {
1137
+ period: "day",
1138
+ usedTokens: today.usedTokens,
1139
+ ...today.limitTokens !== null ? {
1140
+ limitTokens: today.limitTokens
1141
+ } : {},
1142
+ usedUsd: today.costUsd
1143
+ }
1144
+ ],
1145
+ ...today.withinLimit ? {} : {
1146
+ blocked: {
1147
+ period: "day"
1148
+ }
1149
+ }
1150
+ };
1151
+ }
1152
+ /**
1153
+ * Refuse a turn the actor's budget no longer covers — only when the host configured one
1154
+ * (`quotaProvider` or `quotaLimits`): the default report is informational, and the daily token
1155
+ * quota the loop enforces keeps working as it always has.
1156
+ */
1157
+ async assertWithinQuota(actor) {
1158
+ const gated = this.options?.quotaProvider !== void 0 || this.options?.quotaLimits !== void 0;
1159
+ if (!gated || this.quotaProvider === void 0) {
1160
+ return;
1161
+ }
1162
+ const { blocked } = await this.quotaProvider.report({
1163
+ actor
1164
+ });
1165
+ if (blocked !== void 0) {
1166
+ throw new HttpException({
1167
+ statusCode: HttpStatus.TOO_MANY_REQUESTS,
1168
+ code: "quota_exceeded",
1169
+ period: blocked.period,
1170
+ message: blocked.reason ?? `The ${blocked.period === "day" ? "daily" : "monthly"} quota is used up`
1171
+ }, HttpStatus.TOO_MANY_REQUESTS);
1172
+ }
1111
1173
  }
1112
1174
  /**
1113
1175
  * The models `actor` may pick for `agent` (`GET <base>/models`). An empty catalog when none is
@@ -1164,6 +1226,7 @@ var AgentService = class {
1164
1226
  return (await this.store.getThread(threadId))?.model ?? null;
1165
1227
  }
1166
1228
  async chat(params) {
1229
+ await this.assertWithinQuota(params.actor);
1167
1230
  const agentName = await this.resolveAgentName(params.agentName, params.threadId);
1168
1231
  const model = await this.resolveModel(params.actor, agentName, params.model, params.threadId);
1169
1232
  const attachments = await this.resolveAttachments(params.actor, params.attachments ?? []);
@@ -1705,6 +1768,10 @@ AgentService = _ts_decorate6([
1705
1768
  _ts_param5(4, Inject5(AGENT_ATTACHMENT_STAGING)),
1706
1769
  _ts_param5(5, Optional3()),
1707
1770
  _ts_param5(5, Inject5(AGENT_MODEL_CATALOG)),
1771
+ _ts_param5(6, Optional3()),
1772
+ _ts_param5(6, Inject5(AGENT_QUOTA_PROVIDER)),
1773
+ _ts_param5(7, Optional3()),
1774
+ _ts_param5(7, Inject5(AGENT_OPTIONS2)),
1708
1775
  _ts_metadata5("design:type", Function),
1709
1776
  _ts_metadata5("design:paramtypes", [
1710
1777
  typeof AgentRunner === "undefined" ? Object : AgentRunner,
@@ -1712,7 +1779,9 @@ AgentService = _ts_decorate6([
1712
1779
  typeof AgentDepsFactory === "undefined" ? Object : AgentDepsFactory,
1713
1780
  Object,
1714
1781
  typeof AttachmentStagingStore === "undefined" ? Object : AttachmentStagingStore,
1715
- typeof ModelCatalog === "undefined" ? Object : ModelCatalog
1782
+ typeof ModelCatalog === "undefined" ? Object : ModelCatalog,
1783
+ typeof QuotaProvider === "undefined" ? Object : QuotaProvider,
1784
+ typeof Pick === "undefined" ? Object : Pick
1716
1785
  ])
1717
1786
  ], AgentService);
1718
1787
 
@@ -1851,7 +1920,7 @@ AgentsController = _ts_decorate8([
1851
1920
  ], AgentsController);
1852
1921
 
1853
1922
  // src/controller/attachments.controller.ts
1854
- import { AGENT_ACTOR_RESOLVER, AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING2, AGENT_OPTIONS as AGENT_OPTIONS2 } from "@dudousxd/nestjs-agent-core";
1923
+ import { AGENT_ACTOR_RESOLVER, AGENT_ATTACHMENT_STAGING as AGENT_ATTACHMENT_STAGING2, AGENT_OPTIONS as AGENT_OPTIONS3 } from "@dudousxd/nestjs-agent-core";
1855
1924
  import { BadRequestException as BadRequestException2, Controller as Controller2, Get as Get2, Inject as Inject7, NotImplementedException as NotImplementedException2, Optional as Optional4, PayloadTooLargeException, Post, Req, UnsupportedMediaTypeException, UploadedFile, UseInterceptors } from "@nestjs/common";
1856
1925
  import { FileInterceptor } from "@nestjs/platform-express";
1857
1926
  function _ts_decorate9(decorators, target, key, desc) {
@@ -1984,7 +2053,7 @@ _ts_decorate9([
1984
2053
  ], AttachmentsController.prototype, "upload", null);
1985
2054
  AttachmentsController = _ts_decorate9([
1986
2055
  Controller2("attachments"),
1987
- _ts_param7(0, Inject7(AGENT_OPTIONS2)),
2056
+ _ts_param7(0, Inject7(AGENT_OPTIONS3)),
1988
2057
  _ts_param7(1, Inject7(AGENT_ACTOR_RESOLVER)),
1989
2058
  _ts_param7(3, Optional4()),
1990
2059
  _ts_param7(3, Inject7(AGENT_ATTACHMENT_STAGING2)),
@@ -2559,11 +2628,28 @@ var QuotaController = class {
2559
2628
  this.agent = agent;
2560
2629
  this.actorResolver = actorResolver;
2561
2630
  }
2631
+ /**
2632
+ * The caller's budget across windows — `{ windows: [{ period, usedTokens, limitTokens?, usedUsd,
2633
+ * limitUsd?, resetsAt? }], blocked?: { period, reason? } }` — from the bound `QuotaProvider`.
2634
+ */
2635
+ async report(req) {
2636
+ const actor = await this.actorResolver.resolve(req);
2637
+ return this.agent.quotaReport(actor);
2638
+ }
2562
2639
  async today(req) {
2563
2640
  const actor = await this.actorResolver.resolve(req);
2564
2641
  return this.agent.quotaToday(actor.id);
2565
2642
  }
2566
2643
  };
2644
+ _ts_decorate14([
2645
+ Get6(),
2646
+ _ts_param12(0, Req6()),
2647
+ _ts_metadata13("design:type", Function),
2648
+ _ts_metadata13("design:paramtypes", [
2649
+ typeof Request === "undefined" ? Object : Request
2650
+ ]),
2651
+ _ts_metadata13("design:returntype", Promise)
2652
+ ], QuotaController.prototype, "report", null);
2567
2653
  _ts_decorate14([
2568
2654
  Get6("today"),
2569
2655
  _ts_param12(0, Req6()),
@@ -3320,7 +3406,7 @@ AgentDiscoveryService = _ts_decorate19([
3320
3406
  ], AgentDiscoveryService);
3321
3407
 
3322
3408
  // src/discovery/ai-tool-discovery.service.ts
3323
- import { AGENT_OPTIONS as AGENT_OPTIONS3, AGENT_REGISTRY as AGENT_REGISTRY5, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY2, normalizeDelegation as normalizeDelegation2 } from "@dudousxd/nestjs-agent-core";
3409
+ import { AGENT_OPTIONS as AGENT_OPTIONS4, AGENT_REGISTRY as AGENT_REGISTRY5, AGENT_TOOL_REGISTRY as AGENT_TOOL_REGISTRY2, normalizeDelegation as normalizeDelegation2 } from "@dudousxd/nestjs-agent-core";
3324
3410
  import { Inject as Inject18, Injectable as Injectable8, Logger as Logger3 } from "@nestjs/common";
3325
3411
  import { DiscoveryService as DiscoveryService2 } from "@nestjs/core";
3326
3412
  import { z } from "zod";
@@ -3390,6 +3476,14 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
3390
3476
  if (instance === null || instance === void 0 || typeof instance !== "object") {
3391
3477
  continue;
3392
3478
  }
3479
+ if (Array.isArray(instance) && instance.length > 0 && instance.every((each) => typeof each === "object" && each !== null && isBrandedFunctionalTool(each))) {
3480
+ for (const tool of instance) {
3481
+ if (this.registerFunctionalTool(tool)) {
3482
+ functional += 1;
3483
+ }
3484
+ }
3485
+ continue;
3486
+ }
3393
3487
  if (isBrandedFunctionalTool(instance)) {
3394
3488
  if (this.registerFunctionalTool(instance)) {
3395
3489
  functional += 1;
@@ -3437,6 +3531,9 @@ var AiToolDiscoveryService = class _AiToolDiscoveryService {
3437
3531
  } : {},
3438
3532
  ...typeof handler.canUse === "function" ? {
3439
3533
  canUse: /* @__PURE__ */ __name((actor) => instance.canUse(actor), "canUse")
3534
+ } : {},
3535
+ ...typeof handler.describe === "function" ? {
3536
+ describe: /* @__PURE__ */ __name((scope) => instance.describe(scope), "describe")
3440
3537
  } : {}
3441
3538
  });
3442
3539
  count += 1;
@@ -3503,7 +3600,7 @@ AiToolDiscoveryService = _ts_decorate20([
3503
3600
  Injectable8(),
3504
3601
  _ts_param18(1, Inject18(AGENT_TOOL_REGISTRY2)),
3505
3602
  _ts_param18(2, Inject18(AGENT_REGISTRY5)),
3506
- _ts_param18(3, Inject18(AGENT_OPTIONS3)),
3603
+ _ts_param18(3, Inject18(AGENT_OPTIONS4)),
3507
3604
  _ts_metadata19("design:type", Function),
3508
3605
  _ts_metadata19("design:paramtypes", [
3509
3606
  typeof DiscoveryService2 === "undefined" ? Object : DiscoveryService2,
@@ -3611,6 +3708,69 @@ SkillDiscoveryService = _ts_decorate21([
3611
3708
  ])
3612
3709
  ], SkillDiscoveryService);
3613
3710
 
3711
+ // src/ledger-quota-provider.ts
3712
+ import { exhaustedWindow, quotaPeriodRange } from "@dudousxd/nestjs-agent-core";
3713
+ var LedgerQuotaProvider = class {
3714
+ static {
3715
+ __name(this, "LedgerQuotaProvider");
3716
+ }
3717
+ store;
3718
+ quota;
3719
+ limits;
3720
+ constructor(store, quota, limits = {}) {
3721
+ this.store = store;
3722
+ this.quota = quota;
3723
+ this.limits = limits;
3724
+ }
3725
+ async report(query) {
3726
+ const now = query.now ?? /* @__PURE__ */ new Date();
3727
+ const actorRef = query.actor.id;
3728
+ const windows = [
3729
+ await this.dayWindow(actorRef, now)
3730
+ ];
3731
+ if (this.store.usageBetween !== void 0) {
3732
+ const range = quotaPeriodRange("month", now);
3733
+ const used = await this.store.usageBetween(actorRef, range.fromDay, range.toDay);
3734
+ windows.push(this.window("month", used.usedTokens, used.costUsd, range.resetsAt));
3735
+ }
3736
+ const blocked = exhaustedWindow(windows);
3737
+ return {
3738
+ windows,
3739
+ ...blocked !== void 0 ? {
3740
+ blocked
3741
+ } : {}
3742
+ };
3743
+ }
3744
+ async dayWindow(actorRef, now) {
3745
+ const range = quotaPeriodRange("day", now);
3746
+ const { usedTokens, costUsd } = await this.store.quotaToday(actorRef, range.fromDay);
3747
+ if (this.quota === void 0) {
3748
+ return this.window("day", usedTokens, costUsd, range.resetsAt);
3749
+ }
3750
+ const state = await this.quota.check(actorRef, range.fromDay);
3751
+ const window = this.window("day", state.usedTokens, costUsd, range.resetsAt);
3752
+ if (window.limitTokens === void 0) {
3753
+ window.limitTokens = state.limitTokens;
3754
+ }
3755
+ return window;
3756
+ }
3757
+ window(period, usedTokens, usedUsd, resetsAt) {
3758
+ const limits = this.limits[period] ?? {};
3759
+ return {
3760
+ period,
3761
+ usedTokens,
3762
+ ...limits.tokens !== void 0 ? {
3763
+ limitTokens: limits.tokens
3764
+ } : {},
3765
+ usedUsd,
3766
+ ...limits.usd !== void 0 ? {
3767
+ limitUsd: limits.usd
3768
+ } : {},
3769
+ resetsAt
3770
+ };
3771
+ }
3772
+ };
3773
+
3614
3774
  // src/ledger-quota-store.ts
3615
3775
  var LedgerQuotaStore = class {
3616
3776
  static {
@@ -4137,7 +4297,7 @@ function sharedProviders(durable, includeStore) {
4137
4297
  provide: AGENT_SKILLS3,
4138
4298
  useFactory: /* @__PURE__ */ __name((options, declared) => resolveSkillsConfig(options.skills, declared), "useFactory"),
4139
4299
  inject: [
4140
- AGENT_OPTIONS4,
4300
+ AGENT_OPTIONS5,
4141
4301
  AGENT_SKILL_SOURCES2
4142
4302
  ]
4143
4303
  },
@@ -4147,35 +4307,35 @@ function sharedProviders(durable, includeStore) {
4147
4307
  provide: AGENT_MEMORY3,
4148
4308
  useFactory: /* @__PURE__ */ __name((options) => options.memory, "useFactory"),
4149
4309
  inject: [
4150
- AGENT_OPTIONS4
4310
+ AGENT_OPTIONS5
4151
4311
  ]
4152
4312
  },
4153
4313
  {
4154
4314
  provide: AGENT_SINK3,
4155
4315
  useFactory: /* @__PURE__ */ __name((options) => options.sink ?? new InProcessTokenStreamSink(), "useFactory"),
4156
4316
  inject: [
4157
- AGENT_OPTIONS4
4317
+ AGENT_OPTIONS5
4158
4318
  ]
4159
4319
  },
4160
4320
  {
4161
4321
  provide: AGENT_ROLES_POLICY2,
4162
4322
  useFactory: /* @__PURE__ */ __name((options) => options.rolesPolicy ?? new DefaultRolesPolicy(options.defaultRoles), "useFactory"),
4163
4323
  inject: [
4164
- AGENT_OPTIONS4
4324
+ AGENT_OPTIONS5
4165
4325
  ]
4166
4326
  },
4167
4327
  {
4168
4328
  provide: AGENT_ACTOR_RESOLVER11,
4169
4329
  useFactory: /* @__PURE__ */ __name((options) => options.actorResolver, "useFactory"),
4170
4330
  inject: [
4171
- AGENT_OPTIONS4
4331
+ AGENT_OPTIONS5
4172
4332
  ]
4173
4333
  },
4174
4334
  {
4175
4335
  provide: AGENT_MODEL2,
4176
4336
  useFactory: /* @__PURE__ */ __name((o) => o.model, "useFactory"),
4177
4337
  inject: [
4178
- AGENT_OPTIONS4
4338
+ AGENT_OPTIONS5
4179
4339
  ]
4180
4340
  },
4181
4341
  {
@@ -4185,15 +4345,24 @@ function sharedProviders(durable, includeStore) {
4185
4345
  provide: AGENT_QUOTA_STORE3,
4186
4346
  useFactory: /* @__PURE__ */ __name((o, store) => o.quota ?? (o.quotaLimitTokens !== void 0 ? new LedgerQuotaStore(store, o.quotaLimitTokens) : void 0), "useFactory"),
4187
4347
  inject: [
4188
- AGENT_OPTIONS4,
4348
+ AGENT_OPTIONS5,
4189
4349
  AGENT_STORE6
4190
4350
  ]
4191
4351
  },
4352
+ {
4353
+ provide: AGENT_QUOTA_PROVIDER2,
4354
+ useFactory: /* @__PURE__ */ __name((o, store, quota) => o.quotaProvider ?? new LedgerQuotaProvider(store, quota, o.quotaLimits), "useFactory"),
4355
+ inject: [
4356
+ AGENT_OPTIONS5,
4357
+ AGENT_STORE6,
4358
+ AGENT_QUOTA_STORE3
4359
+ ]
4360
+ },
4192
4361
  {
4193
4362
  provide: AGENT_MODEL_CATALOG2,
4194
4363
  useFactory: /* @__PURE__ */ __name((o) => o.models, "useFactory"),
4195
4364
  inject: [
4196
- AGENT_OPTIONS4
4365
+ AGENT_OPTIONS5
4197
4366
  ]
4198
4367
  },
4199
4368
  AgentDepsFactory2,
@@ -4221,7 +4390,7 @@ function sharedProviders(durable, includeStore) {
4221
4390
  provide: AGENT_STORE6,
4222
4391
  useFactory: /* @__PURE__ */ __name((o) => o.store, "useFactory"),
4223
4392
  inject: [
4224
- AGENT_OPTIONS4
4393
+ AGENT_OPTIONS5
4225
4394
  ]
4226
4395
  });
4227
4396
  }
@@ -4252,7 +4421,7 @@ function sharedProviders(durable, includeStore) {
4252
4421
  __name(sharedProviders, "sharedProviders");
4253
4422
  function exportsFor(includeStore) {
4254
4423
  return [
4255
- AGENT_OPTIONS4,
4424
+ AGENT_OPTIONS5,
4256
4425
  AGENT_TOOL_REGISTRY3,
4257
4426
  AGENT_REGISTRY6,
4258
4427
  AGENT_SINK3,
@@ -4264,6 +4433,7 @@ function exportsFor(includeStore) {
4264
4433
  ] : [],
4265
4434
  AGENT_QUOTA_STORE3,
4266
4435
  AGENT_MODEL_CATALOG2,
4436
+ AGENT_QUOTA_PROVIDER2,
4267
4437
  AGENT_PROMPT_CONTRIBUTORS3,
4268
4438
  AGENT_SKILLS3,
4269
4439
  AGENT_MEMORY3,
@@ -4343,7 +4513,7 @@ var AgentModule = class _AgentModule {
4343
4513
  controllers: controllersForSurface(options.surface, options.attachments?.upload === true),
4344
4514
  providers: [
4345
4515
  {
4346
- provide: AGENT_OPTIONS4,
4516
+ provide: AGENT_OPTIONS5,
4347
4517
  useValue: options
4348
4518
  },
4349
4519
  ...sharedProviders(options.durable ?? false, includeStore),
@@ -4367,7 +4537,7 @@ var AgentModule = class _AgentModule {
4367
4537
  controllers: controllersForSurface(options.surface, options.attachmentsUpload === true),
4368
4538
  providers: [
4369
4539
  {
4370
- provide: AGENT_OPTIONS4,
4540
+ provide: AGENT_OPTIONS5,
4371
4541
  // Stamp the STATIC wiring flags onto the factory result: `durable`/`surface` are
4372
4542
  // authoritative on the async config object (they decided the actual wiring above), and
4373
4543
  // the durable module reads `durable` back off AGENT_OPTIONS. `surface` isn't read back by