floe-guard 0.7.0 → 0.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.
package/dist/index.d.cts CHANGED
@@ -142,6 +142,22 @@ interface BudgetAdvisory {
142
142
  spentUsd: number;
143
143
  /** Hosted reports the tightest cap across all scopes; local is always "local". */
144
144
  scope: "local";
145
+ /**
146
+ * The guard's own next-call estimate (the costlier of the last LLM and last
147
+ * tool call — the same value the default reservation uses). 0 until the first
148
+ * call is recorded, so a planner can't divide by a cold estimate.
149
+ *
150
+ * Optional so adding it stays a non-breaking, additive change for any code
151
+ * that constructs a `BudgetAdvisory` literal; `advisory()` always sets it.
152
+ */
153
+ expectedCost?: number;
154
+ /**
155
+ * How many more calls the remaining budget buys at expectedCost:
156
+ * floor(remainingUsd / expectedCost). null when expectedCost is 0 (no call
157
+ * recorded yet) — unknown, not zero. Optional for the same additive reason as
158
+ * expectedCost; `advisory()` always sets it.
159
+ */
160
+ estCallsRemaining?: number | null;
145
161
  }
146
162
  declare class BudgetGuard {
147
163
  readonly limitUsd: number;
package/dist/index.d.ts CHANGED
@@ -142,6 +142,22 @@ interface BudgetAdvisory {
142
142
  spentUsd: number;
143
143
  /** Hosted reports the tightest cap across all scopes; local is always "local". */
144
144
  scope: "local";
145
+ /**
146
+ * The guard's own next-call estimate (the costlier of the last LLM and last
147
+ * tool call — the same value the default reservation uses). 0 until the first
148
+ * call is recorded, so a planner can't divide by a cold estimate.
149
+ *
150
+ * Optional so adding it stays a non-breaking, additive change for any code
151
+ * that constructs a `BudgetAdvisory` literal; `advisory()` always sets it.
152
+ */
153
+ expectedCost?: number;
154
+ /**
155
+ * How many more calls the remaining budget buys at expectedCost:
156
+ * floor(remainingUsd / expectedCost). null when expectedCost is 0 (no call
157
+ * recorded yet) — unknown, not zero. Optional for the same additive reason as
158
+ * expectedCost; `advisory()` always sets it.
159
+ */
160
+ estCallsRemaining?: number | null;
145
161
  }
146
162
  declare class BudgetGuard {
147
163
  readonly limitUsd: number;
package/dist/index.js CHANGED
@@ -1451,6 +1451,9 @@ var BudgetGuard = class {
1451
1451
  */
1452
1452
  advisory() {
1453
1453
  const usedBps = this.limitUsd <= 0 ? 1e4 : Math.max(0, Math.min(1e4, Math.floor(this.spentUsd / this.limitUsd * 1e4 + 1e-9)));
1454
+ const remainingUsd = Math.max(0, this.limitUsd - this.spentUsd);
1455
+ const expectedCost = Math.max(this.lastLlmCost, this.lastToolCost);
1456
+ const estCallsRemaining = expectedCost > 0 ? Math.floor(remainingUsd / expectedCost + 1e-9) : null;
1454
1457
  return {
1455
1458
  nearLimit: usedBps >= this.nearLimitBps,
1456
1459
  usedBps,
@@ -1458,10 +1461,12 @@ var BudgetGuard = class {
1458
1461
  // in-flight reservations. Unlike the remainingUsd getter (which subtracts
1459
1462
  // `reserved`), the advisory is a soft utilization signal about money already
1460
1463
  // spent, while the getter reports what a new call can still claim.
1461
- remainingUsd: Math.max(0, this.limitUsd - this.spentUsd),
1464
+ remainingUsd,
1462
1465
  limitUsd: this.limitUsd,
1463
1466
  spentUsd: this.spentUsd,
1464
- scope: "local"
1467
+ scope: "local",
1468
+ expectedCost,
1469
+ estCallsRemaining
1465
1470
  };
1466
1471
  }
1467
1472
  };