@dudousxd/nestjs-agent 1.36.1 → 1.36.2

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.
@@ -585,10 +585,11 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
585
585
  * `DurableAgentRunner.cancel` puts it — `cancelling` while a compensating cancel is in flight,
586
586
  * `cancelled` once it has settled.
587
587
  *
588
- * Costs a run read at each of the loop's observation points (two per step). That is a row the
589
- * control plane already has, against a turn that is otherwise making model calls, and it buys the
590
- * property that matters: the answer comes from a place BOTH the canceller and every pod that might
591
- * replay this run can see.
588
+ * Costs a run read at each of the loop's observation points (two per step): the run's own row
589
+ * where the gateway can read it alone, else its detail, which carries every checkpoint of the run.
590
+ * That row is one the control plane already has, against a turn that is otherwise making model
591
+ * calls, and it buys the property that matters: the answer comes from a place BOTH the canceller
592
+ * and every pod that might replay this run can see.
592
593
  *
593
594
  * Failing to ask is not a cancel. A tenant with no gateway wired, or an operator briefly
594
595
  * unreachable, answers "no" and the run carries on — the alternative is failing healthy runs
@@ -596,8 +597,10 @@ var AgentRunWorkflow = class _AgentRunWorkflow {
596
597
  * can never disagree about what was seen here.
597
598
  */
598
599
  async isCancelled(runId) {
600
+ const runs = this.runs;
599
601
  try {
600
- const status = (await this.runs?.getRunDetail(runId))?.run.status;
602
+ const run = typeof runs?.getRun === "function" ? await runs.getRun(runId) : (await runs?.getRunDetail(runId))?.run;
603
+ const status = run?.status;
601
604
  return status === "cancelled" || status === "cancelling";
602
605
  } catch {
603
606
  return false;
@@ -909,49 +912,121 @@ var import_common3 = require("@nestjs/common");
909
912
 
910
913
  // src/in-process-sink.ts
911
914
  var import_nestjs_agent_core5 = require("@dudousxd/nestjs-agent-core");
915
+ var LIVE_TTL_MS = 36e5;
916
+ var ENDED_GRACE_MS = 6e4;
912
917
  var InProcessTokenStreamSink = class {
913
918
  static {
914
919
  __name(this, "InProcessTokenStreamSink");
915
920
  }
916
921
  runs = /* @__PURE__ */ new Map();
922
+ /** Subscribers of a run nothing has opened yet, woken by its `open()`. */
923
+ waiting = /* @__PURE__ */ new Map();
917
924
  buffer(runId) {
918
925
  let buf = this.runs.get(runId);
919
926
  if (buf === void 0) {
920
927
  buf = {
921
928
  chunks: [],
922
929
  ended: false,
923
- notify: /* @__PURE__ */ new Set()
930
+ notify: /* @__PURE__ */ new Set(),
931
+ lastWriteAt: Date.now(),
932
+ expiry: void 0
924
933
  };
925
934
  this.runs.set(runId, buf);
935
+ this.expireAfter(runId, buf, LIVE_TTL_MS);
936
+ const waiters = this.waiting.get(runId);
937
+ this.waiting.delete(runId);
938
+ for (const resolve2 of waiters ?? []) {
939
+ resolve2();
940
+ }
926
941
  }
927
942
  return buf;
928
943
  }
944
+ expireAfter(runId, buf, ms) {
945
+ if (buf.expiry !== void 0) {
946
+ clearTimeout(buf.expiry);
947
+ }
948
+ buf.expiry = setTimeout(() => {
949
+ buf.expiry = void 0;
950
+ const idle = Date.now() - buf.lastWriteAt;
951
+ if (!buf.ended && idle < LIVE_TTL_MS) {
952
+ this.expireAfter(runId, buf, LIVE_TTL_MS - idle);
953
+ return;
954
+ }
955
+ this.drop(runId, buf);
956
+ }, ms);
957
+ buf.expiry.unref?.();
958
+ }
959
+ /** Forget the run, and let anyone still following it finish as if it had ended. */
960
+ drop(runId, buf) {
961
+ if (buf.expiry !== void 0) {
962
+ clearTimeout(buf.expiry);
963
+ buf.expiry = void 0;
964
+ }
965
+ if (this.runs.get(runId) === buf) {
966
+ this.runs.delete(runId);
967
+ }
968
+ buf.ended = true;
969
+ this.wake(buf);
970
+ }
929
971
  wake(buf) {
930
972
  for (const resolve2 of buf.notify) {
931
973
  resolve2();
932
974
  }
933
975
  buf.notify.clear();
934
976
  }
977
+ finish(runId, buf) {
978
+ buf.ended = true;
979
+ this.wake(buf);
980
+ this.expireAfter(runId, buf, ENDED_GRACE_MS);
981
+ }
982
+ /**
983
+ * The run's writer. Each call finds the run's buffer afresh, so a run that went quiet past the
984
+ * live TTL (parked on a person) and then writes again starts a new buffer its next subscriber
985
+ * follows, rather than writing into one nothing reads.
986
+ */
935
987
  open(runId) {
936
- const buf = this.buffer(runId);
988
+ this.buffer(runId);
937
989
  return {
938
990
  write: /* @__PURE__ */ __name((chunk) => {
991
+ const buf = this.buffer(runId);
939
992
  buf.chunks.push(chunk);
993
+ buf.lastWriteAt = Date.now();
940
994
  this.wake(buf);
941
995
  }, "write"),
942
996
  end: /* @__PURE__ */ __name(() => {
943
- buf.ended = true;
944
- this.wake(buf);
997
+ this.finish(runId, this.buffer(runId));
945
998
  }, "end"),
946
999
  fail: /* @__PURE__ */ __name((error) => {
1000
+ const buf = this.buffer(runId);
947
1001
  buf.failure = error;
948
- buf.ended = true;
949
- this.wake(buf);
1002
+ this.finish(runId, buf);
950
1003
  }, "fail")
951
1004
  };
952
1005
  }
953
- async *subscribe(runId) {
954
- const buf = this.buffer(runId);
1006
+ async *subscribe(runId, options = {}) {
1007
+ const { signal } = options;
1008
+ let buf = this.runs.get(runId);
1009
+ while (buf === void 0) {
1010
+ const waiters = this.waiting.get(runId) ?? /* @__PURE__ */ new Set();
1011
+ this.waiting.set(runId, waiters);
1012
+ let resolve2 = /* @__PURE__ */ __name(() => {
1013
+ }, "resolve");
1014
+ const opened = new Promise((r) => {
1015
+ resolve2 = r;
1016
+ });
1017
+ waiters.add(resolve2);
1018
+ try {
1019
+ if (!await untilAborted(opened, signal)) {
1020
+ return;
1021
+ }
1022
+ } finally {
1023
+ waiters.delete(resolve2);
1024
+ if (waiters.size === 0 && this.waiting.get(runId) === waiters) {
1025
+ this.waiting.delete(runId);
1026
+ }
1027
+ }
1028
+ buf = this.runs.get(runId);
1029
+ }
955
1030
  let index = 0;
956
1031
  while (true) {
957
1032
  while (index < buf.chunks.length) {
@@ -967,13 +1042,56 @@ var InProcessTokenStreamSink = class {
967
1042
  }
968
1043
  return;
969
1044
  }
970
- await new Promise((resolve2) => buf.notify.add(resolve2));
1045
+ const current = buf;
1046
+ let resolve2 = /* @__PURE__ */ __name(() => {
1047
+ }, "resolve");
1048
+ const woken = new Promise((r) => {
1049
+ resolve2 = r;
1050
+ });
1051
+ current.notify.add(resolve2);
1052
+ try {
1053
+ if (!await untilAborted(woken, signal)) {
1054
+ return;
1055
+ }
1056
+ } finally {
1057
+ current.notify.delete(resolve2);
1058
+ }
971
1059
  }
972
1060
  }
973
1061
  close(runId) {
1062
+ const buf = this.runs.get(runId);
1063
+ if (buf?.expiry !== void 0) {
1064
+ clearTimeout(buf.expiry);
1065
+ }
974
1066
  this.runs.delete(runId);
975
1067
  }
976
1068
  };
1069
+ async function untilAborted(promise, signal) {
1070
+ if (signal === void 0) {
1071
+ await promise;
1072
+ return true;
1073
+ }
1074
+ if (signal.aborted) {
1075
+ return false;
1076
+ }
1077
+ let onAbort = /* @__PURE__ */ __name(() => {
1078
+ }, "onAbort");
1079
+ const aborted = new Promise((resolve2) => {
1080
+ onAbort = /* @__PURE__ */ __name(() => resolve2(false), "onAbort");
1081
+ signal.addEventListener("abort", onAbort, {
1082
+ once: true
1083
+ });
1084
+ });
1085
+ try {
1086
+ return await Promise.race([
1087
+ promise.then(() => true),
1088
+ aborted
1089
+ ]);
1090
+ } finally {
1091
+ signal.removeEventListener("abort", onAbort);
1092
+ }
1093
+ }
1094
+ __name(untilAborted, "untilAborted");
977
1095
 
978
1096
  // src/durable/durable-agent-runner.ts
979
1097
  function _ts_decorate3(decorators, target, key, desc) {
@@ -2849,6 +2967,26 @@ var RunNotActiveException = class extends import_common9.ConflictException {
2849
2967
  }
2850
2968
  };
2851
2969
 
2970
+ // src/thread-reads.ts
2971
+ function threadReads(store, threadId, separately) {
2972
+ const projecting = store;
2973
+ if (typeof projecting.threadSettings !== "function") {
2974
+ return separately;
2975
+ }
2976
+ let settings;
2977
+ const read = /* @__PURE__ */ __name(() => {
2978
+ settings ??= projecting.threadSettings?.(threadId) ?? Promise.resolve(null);
2979
+ return settings;
2980
+ }, "read");
2981
+ return {
2982
+ owner: /* @__PURE__ */ __name(async () => (await read())?.actorRef ?? null, "owner"),
2983
+ defaultAgent: /* @__PURE__ */ __name(async () => (await read())?.defaultAgent ?? null, "defaultAgent"),
2984
+ persona: /* @__PURE__ */ __name(async () => (await read())?.persona ?? null, "persona"),
2985
+ model: /* @__PURE__ */ __name(async () => (await read())?.model ?? null, "model")
2986
+ };
2987
+ }
2988
+ __name(threadReads, "threadReads");
2989
+
2852
2990
  // src/agent.service.ts
2853
2991
  function _ts_decorate9(decorators, target, key, desc) {
2854
2992
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -3112,7 +3250,7 @@ var AgentService = class {
3112
3250
  * else the thread's pinned one, else none. An agent the catalog locks to one model runs on it
3113
3251
  * whatever was sent or pinned, and a send naming another model is refused.
3114
3252
  */
3115
- async resolveModel(actor, agent, requested, threadId) {
3253
+ async resolveModel(actor, agent, requested, threadId, reads) {
3116
3254
  const locked = this.models !== void 0 ? (await this.models.list({
3117
3255
  actor,
3118
3256
  agent
@@ -3123,7 +3261,7 @@ var AgentService = class {
3123
3261
  }
3124
3262
  return locked.model;
3125
3263
  }
3126
- const model = requested ?? (threadId !== void 0 ? await this.threadModel(threadId) : null);
3264
+ const model = requested ?? (threadId !== void 0 ? await (reads?.model() ?? this.threadModel(threadId)) : null);
3127
3265
  if (model === null || model === void 0) {
3128
3266
  return void 0;
3129
3267
  }
@@ -3183,10 +3321,11 @@ var AgentService = class {
3183
3321
  if ("proposalDecision" in decision) return decision;
3184
3322
  }
3185
3323
  await this.assertWithinQuota(params.actor);
3186
- const target = this.deps.resolveAgent(await this.resolveAgentName(params.agentName, params.threadId));
3324
+ const reads = params.threadId !== void 0 ? this.threadReads(params.threadId) : void 0;
3325
+ const target = this.deps.resolveAgent(await this.resolveAgentName(params.agentName, params.threadId, reads));
3187
3326
  const agentName = target.agentName;
3188
- const persona = await this.resolvePersona(agentName, params.personaId ?? target.persona, params.threadId);
3189
- const model = await this.resolveModel(params.actor, agentName, params.model, params.threadId);
3327
+ const persona = await this.resolvePersona(agentName, params.personaId ?? target.persona, params.threadId, reads);
3328
+ const model = await this.resolveModel(params.actor, agentName, params.model, params.threadId, reads);
3190
3329
  const attachments = await this.resolveAttachments(params.actor, params.attachments ?? []);
3191
3330
  let threadId = params.threadId;
3192
3331
  if (threadId === void 0) {
@@ -3210,9 +3349,9 @@ var AgentService = class {
3210
3349
  });
3211
3350
  threadId = created.id;
3212
3351
  } else {
3213
- if (params.authorized !== true) await this.assertOwnsThread(params.actor, threadId);
3352
+ if (params.authorized !== true) await this.assertOwnsThread(params.actor, threadId, reads);
3214
3353
  if (params.personaId !== void 0) {
3215
- await this.pinThreadPersona(threadId, params.personaId);
3354
+ await this.pinThreadPersona(threadId, params.personaId, reads);
3216
3355
  }
3217
3356
  }
3218
3357
  const input = {
@@ -3538,8 +3677,8 @@ var AgentService = class {
3538
3677
  * {@link subscribeAs} instead: a runId is the only thing standing between a caller and another
3539
3678
  * actor's answer, tool arguments and tool results.
3540
3679
  */
3541
- subscribe(runId) {
3542
- return this.deps.forAgent().sink.subscribe(runId);
3680
+ subscribe(runId, options) {
3681
+ return this.deps.forAgent().sink.subscribe(runId, options);
3543
3682
  }
3544
3683
  /**
3545
3684
  * {@link subscribe}, gated the way {@link cancel} is: only the actor whose thread is currently
@@ -3547,9 +3686,9 @@ var AgentService = class {
3547
3686
  * replayed — the runner clears the thread's active stream as the run ends, and that field is what
3548
3687
  * ownership is derived from.
3549
3688
  */
3550
- async subscribeAs(actor, runId) {
3689
+ async subscribeAs(actor, runId, options) {
3551
3690
  await this.assertOwnsActiveStream(actor, runId);
3552
- return this.subscribe(runId);
3691
+ return this.subscribe(runId, options);
3553
3692
  }
3554
3693
  /**
3555
3694
  * Approve a parked action call as `actor`. Who may is the call's recorded approver's business
@@ -3756,7 +3895,7 @@ var AgentService = class {
3756
3895
  * The persona this send runs under — see {@link AgentDepsFactory.resolvePersona}. The thread's
3757
3896
  * pinned persona is read only when the send names none AND the agent has personas to pick from.
3758
3897
  */
3759
- async resolvePersona(agentName, requested, threadId) {
3898
+ async resolvePersona(agentName, requested, threadId, reads) {
3760
3899
  const needsThread = requested === void 0 && threadId !== void 0 && this.deps.personaCatalog(agentName).length > 0;
3761
3900
  return this.deps.resolvePersona({
3762
3901
  agentName,
@@ -3764,16 +3903,16 @@ var AgentService = class {
3764
3903
  requested
3765
3904
  } : {},
3766
3905
  ...needsThread ? {
3767
- threadPersona: await threadPersona(this.store, threadId)
3906
+ threadPersona: await (reads?.persona() ?? threadPersona(this.store, threadId))
3768
3907
  } : {}
3769
3908
  });
3770
3909
  }
3771
3910
  /** Pin `persona` on the thread when it is not already — a no-op on a store that cannot. */
3772
- async pinThreadPersona(threadId, persona) {
3911
+ async pinThreadPersona(threadId, persona, reads) {
3773
3912
  if (this.store.updateThread === void 0) {
3774
3913
  return;
3775
3914
  }
3776
- if (await threadPersona(this.store, threadId) !== persona) {
3915
+ if (await (reads?.persona() ?? threadPersona(this.store, threadId)) !== persona) {
3777
3916
  await this.store.updateThread(threadId, {
3778
3917
  persona
3779
3918
  });
@@ -3800,18 +3939,27 @@ var AgentService = class {
3800
3939
  * workflow, for a string. A store predating {@link ThreadDefaultAgentReader} still answers, via
3801
3940
  * the full read.
3802
3941
  */
3803
- async resolveAgentName(agentName, threadId) {
3942
+ async resolveAgentName(agentName, threadId, reads) {
3804
3943
  if (agentName !== void 0) {
3805
3944
  return agentName;
3806
3945
  }
3807
3946
  if (threadId !== void 0) {
3808
- const threadDefault = await this.threadDefaultAgent(threadId);
3947
+ const threadDefault = await (reads?.defaultAgent() ?? this.threadDefaultAgent(threadId));
3809
3948
  if (threadDefault !== null) {
3810
3949
  return threadDefault;
3811
3950
  }
3812
3951
  }
3813
3952
  return this.deps.defaultAgentName();
3814
3953
  }
3954
+ /** Everything a send reads off `threadId`, in one read where the store allows it. */
3955
+ threadReads(threadId) {
3956
+ return threadReads(this.store, threadId, {
3957
+ owner: /* @__PURE__ */ __name(() => this.store.ownerOfThread(threadId), "owner"),
3958
+ defaultAgent: /* @__PURE__ */ __name(() => this.threadDefaultAgent(threadId), "defaultAgent"),
3959
+ persona: /* @__PURE__ */ __name(() => threadPersona(this.store, threadId), "persona"),
3960
+ model: /* @__PURE__ */ __name(() => this.threadModel(threadId), "model")
3961
+ });
3962
+ }
3815
3963
  async threadDefaultAgent(threadId) {
3816
3964
  const projecting = this.store;
3817
3965
  if (typeof projecting.defaultAgentForThread === "function") {
@@ -3981,8 +4129,8 @@ var AgentService = class {
3981
4129
  * Authorization seam for thread-scoped endpoints: the caller must own the thread. A missing
3982
4130
  * thread is a 404; someone else's thread is a 403 — one actor never touches another's thread.
3983
4131
  */
3984
- async assertOwnsThread(actor, threadId) {
3985
- const owner = await this.store.ownerOfThread(threadId);
4132
+ async assertOwnsThread(actor, threadId, reads) {
4133
+ const owner = await (reads?.owner() ?? this.store.ownerOfThread(threadId));
3986
4134
  if (owner === null) {
3987
4135
  throw new import_common10.NotFoundException(`thread ${threadId} not found`);
3988
4136
  }
@@ -4422,6 +4570,18 @@ AttachmentsController = _ts_decorate12([
4422
4570
  var import_nestjs_agent_core19 = require("@dudousxd/nestjs-agent-core");
4423
4571
  var import_genui3 = require("@dudousxd/nestjs-agent-core/genui");
4424
4572
  var import_common14 = require("@nestjs/common");
4573
+
4574
+ // src/controller/reader-gone.ts
4575
+ function readerGone(res) {
4576
+ const controller = new AbortController();
4577
+ res.once("close", () => controller.abort());
4578
+ return {
4579
+ signal: controller.signal
4580
+ };
4581
+ }
4582
+ __name(readerGone, "readerGone");
4583
+
4584
+ // src/controller/chat.controller.ts
4425
4585
  function _ts_decorate13(decorators, target, key, desc) {
4426
4586
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4427
4587
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -4555,7 +4715,8 @@ var ChatController = class {
4555
4715
  return;
4556
4716
  }
4557
4717
  const { runId, threadId } = result;
4558
- await this.pipe(res, runId, this.agent.subscribe(runId), threadId);
4718
+ const gone = readerGone(res);
4719
+ await this.pipe(res, runId, this.agent.subscribe(runId, gone), threadId, 0, gone.signal);
4559
4720
  }
4560
4721
  /**
4561
4722
  * Attach to a run's stream: every buffered frame, then live ones. `?after=<seq>` (or the SSE
@@ -4565,7 +4726,8 @@ var ChatController = class {
4565
4726
  async stream(req, runId, res, after) {
4566
4727
  const actor = await this.actorResolver.resolve(req);
4567
4728
  const cursor = parseCursor(after) ?? parseCursor(req.headers["last-event-id"]) ?? 0;
4568
- await this.pipe(res, runId, await this.agent.subscribeAs(actor, runId), void 0, cursor);
4729
+ const gone = readerGone(res);
4730
+ await this.pipe(res, runId, await this.agent.subscribeAs(actor, runId, gone), void 0, cursor, gone.signal);
4569
4731
  }
4570
4732
  async cancel(req, runId) {
4571
4733
  const actor = await this.actorResolver.resolve(req);
@@ -4581,8 +4743,11 @@ var ChatController = class {
4581
4743
  * and on any later `GET …/stream`, whichever replica serves it. A reconnecting client passes the
4582
4744
  * last one it saw as `?after=`; frames at or below it are read off the sink but not re-sent.
4583
4745
  * `meta`, `done` and `error` carry no id: `meta` is re-sent on every attach, the terminals once.
4746
+ *
4747
+ * A reader that disconnects aborts `gone`, which the sink honours by ending the subscription even
4748
+ * while the run is silent (parked on a person, or never writing again).
4584
4749
  */
4585
- async pipe(res, runId, events, threadId, after = 0) {
4750
+ async pipe(res, runId, events, threadId, after = 0, gone) {
4586
4751
  res.setHeader("Content-Type", "text/event-stream");
4587
4752
  res.setHeader("Cache-Control", "no-cache");
4588
4753
  res.setHeader("Connection", "keep-alive");
@@ -4611,6 +4776,9 @@ data: ${line}
4611
4776
  }, "forward");
4612
4777
  try {
4613
4778
  for await (const chunk of events) {
4779
+ if (gone?.aborted) {
4780
+ return;
4781
+ }
4614
4782
  buffer += decoder.decode(chunk, {
4615
4783
  stream: true
4616
4784
  });
@@ -4624,11 +4792,17 @@ data: ${line}
4624
4792
  newline = buffer.indexOf("\n");
4625
4793
  }
4626
4794
  }
4795
+ if (gone?.aborted) {
4796
+ return;
4797
+ }
4627
4798
  if (buffer.length > 0) {
4628
4799
  forward(buffer);
4629
4800
  }
4630
4801
  res.write("event: done\ndata: {}\n\n");
4631
4802
  } catch (error) {
4803
+ if (gone?.aborted) {
4804
+ return;
4805
+ }
4632
4806
  const payload = error instanceof import_nestjs_agent_core19.AgentStreamError ? {
4633
4807
  code: error.code,
4634
4808
  message: error.message
@@ -6529,13 +6703,22 @@ var LedgerQuotaProvider = class {
6529
6703
  async report(query) {
6530
6704
  const now = query.now ?? /* @__PURE__ */ new Date();
6531
6705
  const actorRef = query.actor.id;
6532
- const windows = [
6533
- await this.dayWindow(actorRef, now)
6534
- ];
6535
- if (this.store.usageBetween !== void 0) {
6536
- const range = (0, import_nestjs_agent_core34.quotaPeriodRange)("month", now);
6537
- const used = await this.store.usageBetween(actorRef, range.fromDay, range.toDay);
6538
- windows.push(this.window("month", used.usedTokens, this.usd(used), range.resetsAt));
6706
+ const day = (0, import_nestjs_agent_core34.quotaPeriodRange)("day", now);
6707
+ const month = (0, import_nestjs_agent_core34.quotaPeriodRange)("month", now);
6708
+ const windows = [];
6709
+ if (this.store.usageWindows !== void 0) {
6710
+ const [dayUsed, monthUsed] = await this.store.usageWindows(actorRef, [
6711
+ day,
6712
+ month
6713
+ ]);
6714
+ windows.push(this.usedWindow("day", dayUsed, day.resetsAt));
6715
+ windows.push(this.usedWindow("month", monthUsed, month.resetsAt));
6716
+ } else {
6717
+ windows.push(this.usedWindow("day", await this.store.quotaToday(actorRef, day.fromDay), day.resetsAt));
6718
+ if (this.store.usageBetween !== void 0) {
6719
+ const used = await this.store.usageBetween(actorRef, month.fromDay, month.toDay);
6720
+ windows.push(this.usedWindow("month", used, month.resetsAt));
6721
+ }
6539
6722
  }
6540
6723
  const blocked = (0, import_nestjs_agent_core34.exhaustedWindow)(windows);
6541
6724
  const warning = (0, import_nestjs_agent_core34.quotaWarning)(windows);
@@ -6549,10 +6732,8 @@ var LedgerQuotaProvider = class {
6549
6732
  } : {}
6550
6733
  };
6551
6734
  }
6552
- async dayWindow(actorRef, now) {
6553
- const range = (0, import_nestjs_agent_core34.quotaPeriodRange)("day", now);
6554
- const used = await this.store.quotaToday(actorRef, range.fromDay);
6555
- return this.window("day", used.usedTokens, this.usd(used), range.resetsAt);
6735
+ usedWindow(period, used, resetsAt) {
6736
+ return this.window(period, used?.usedTokens ?? 0, used === void 0 ? 0 : this.usd(used), resetsAt);
6556
6737
  }
6557
6738
  /** The window's USD: every priced row, or (with `countEstimatedCost: false`) reported cost only. */
6558
6739
  usd(used) {