@bivelio/savings-layer 0.4.31 → 0.4.33

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.ts CHANGED
@@ -125,6 +125,12 @@ declare class SavingsLedger {
125
125
  cacheWritePremiumUsd: number;
126
126
  /** Provider-initiated cache-write premium, priced in USD. Adds to baseline and `actual` alike. */
127
127
  providerCacheWritePremiumUsd: number;
128
+ /** Cache-write tokens of the served call, every TTL. Read only for `report.nativeSavings`. */
129
+ nativeCacheWriteInput: number;
130
+ /** The one-hour part of `nativeCacheWriteInput`. */
131
+ nativeCacheWrite1hInput: number;
132
+ /** Whether the layer placed the cache breakpoint on the served call; `null` when unknown. */
133
+ nativeCacheMarkedByLayer: boolean | null;
128
134
  /** Cuenta LOCAL del prompt que de verdad se envió al proveedor. */
129
135
  sentInputLocal: number;
130
136
  /** Tokens que la capa quitó de ese prompt, en cuenta LOCAL. */
@@ -230,6 +236,8 @@ declare class SavingsLedger {
230
236
  compress(originalTokens: number, compressedTokens: number): void;
231
237
  /** Ledger 4: tokens still present but billed/processed as provider-cached. */
232
238
  providerCached(tokens: number): void;
239
+ /** Record the served call's cache writes for `report.nativeSavings`. Never priced into `estimateCost`. */
240
+ nativeCacheWrite(tokens: number, tokens1h: number): void;
233
241
  /** Record the premium for `tokens` of cache write the provider bills at `multiplier`x on its own. */
234
242
  providerCacheWritePremium(tokens: number, multiplier: number, price: CostModel): void;
235
243
  /** Input tokens of calls the provider documents as not billed; already included in `actualInput`. */
@@ -268,6 +276,8 @@ declare class SavingsLedger {
268
276
  baselineEstimate: number;
269
277
  actual: number;
270
278
  netSavings: number;
279
+ netSavingsRatio: number;
280
+ netSavingsUsd: number;
271
281
  basis: CostBasis;
272
282
  };
273
283
  }
@@ -293,8 +303,12 @@ declare class SavingsLedger {
293
303
  * discounts, negotiated rates or a different region sets their own and this
294
304
  * catalogue stays out of the way.
295
305
  */
296
- /** When these prices were last checked against the providers' public rates. */
297
- declare const PRECIOS_AL_DIA = "2026-09-27";
306
+ /**
307
+ * Version of this price catalogue: the UTC day its content last changed (rows,
308
+ * announced price steps, cache-write premiums, tier rates). Two computations
309
+ * citing the same version were priced with the same content.
310
+ */
311
+ declare const PRECIOS_AL_DIA$1 = "2026-09-29";
298
312
  /**
299
313
  * Key = the model id as the provider publishes it, without a vendor prefix.
300
314
  * Lookup tries the exact id, then the id without its provider prefix, then the
@@ -305,7 +319,7 @@ declare const PRECIOS_AL_DIA = "2026-09-27";
305
319
  * provider has already announced is applied by {@link precioDeLista} from its
306
320
  * effective date, so a request is always priced at the rate of its own day.
307
321
  */
308
- declare const CATALOGO: Readonly<Record<string, CostModel>>;
322
+ declare const CATALOGO$1: Readonly<Record<string, CostModel>>;
309
323
  /**
310
324
  * The list price for a model on the day of the request, or `undefined` when
311
325
  * the catalogue has no price for it in force that day.
@@ -315,7 +329,7 @@ declare const CATALOGO: Readonly<Record<string, CostModel>>;
315
329
  * Prices resolve per UTC day, so a price change the provider has announced
316
330
  * applies from its effective date.
317
331
  */
318
- declare function precioDeLista(model: string, at?: Date | number): CostModel | undefined;
332
+ declare function precioDeLista$1(model: string, at?: Date | number): CostModel | undefined;
319
333
 
320
334
  /**
321
335
  * The version the SDK reports for itself.
@@ -325,7 +339,7 @@ declare function precioDeLista(model: string, at?: Date | number): CostModel | u
325
339
  * on the customer's machine. `test/version-declarada.test.ts` ties this
326
340
  * constant to package.json so the two can never drift.
327
341
  */
328
- declare const BV_SALA_VERSION = "0.4.31";
342
+ declare const BV_SALA_VERSION = "0.4.33";
329
343
 
330
344
  /**
331
345
  * Environment-agnostic UUID generation.
@@ -781,8 +795,12 @@ interface SavingsToggles {
781
795
  * When your catalogue declares `risk`, write and destructive tools are still withheld
782
796
  * from requests the router does not classify as actions, as with the selector. Each
783
797
  * search is a short extra step inside the same call, and the definitions it loads are
784
- * billed as normal input. This adapter sends earlier turns as text, so a later turn
785
- * that needs a tool searches again.
798
+ * billed as normal input. Across turns, append the assistant turn with its
799
+ * `toolCalls` (ids as returned) before the tool results: the adapter then sends that
800
+ * turn's search results back with it, so the model calls the tools it already found
801
+ * without searching again. It remembers them in memory, per adapter instance and
802
+ * bounded; a turn it no longer remembers (another process, say) goes out without them
803
+ * and the model searches again.
786
804
  */
787
805
  toolSearch?: ToolSearchMode | ToolSearchOptions;
788
806
  /**
@@ -1107,6 +1125,23 @@ interface SavingsRequest {
1107
1125
  /** Sampling controls that participate in the exact-cache key. */
1108
1126
  temperature?: number;
1109
1127
  seed?: number;
1128
+ /**
1129
+ * How hard a reasoning model should think, sent as OpenAI's `reasoning_effort`
1130
+ * by the OpenAI-compatible adapter (`"none"`, `"minimal"`, `"low"`,
1131
+ * `"medium"`, `"high"`, `"xhigh"`; the value travels as written). Nothing is
1132
+ * sent when absent: the layer never picks an effort for you.
1133
+ *
1134
+ * Required for the gpt-5.6 family with tools on Chat Completions: OpenAI
1135
+ * rejects function tools there unless it is `"none"` («Function tools with
1136
+ * reasoning_effort are not supported for gpt-5.6-sol in
1137
+ * /v1/chat/completions … set reasoning_effort to 'none'»). Gemini's
1138
+ * OpenAI-compatible endpoint maps it to its thinking level. A compatible
1139
+ * endpoint that rejects the field by name gets the request once more without
1140
+ * it (OpenAI's own API never: there its 400 is the answer). It is part of the
1141
+ * cache identity, like `temperature` and `seed`. The Anthropic adapter
1142
+ * ignores it.
1143
+ */
1144
+ reasoningEffort?: ReasoningEffort;
1110
1145
  /**
1111
1146
  * Hard ceiling on generated tokens for this request, with or without an
1112
1147
  * output contract. It travels to every adapter: Anthropic `max_tokens`,
@@ -1126,11 +1161,22 @@ interface SavingsRequest {
1126
1161
  structuredData?: unknown;
1127
1162
  }
1128
1163
  /** A tool invocation the model requested (the provider-neutral shape). */
1164
+ /** OpenAI's `reasoning_effort` values; any other string travels as written. */
1165
+ type ReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | (string & {});
1129
1166
  interface ToolCallRequest {
1130
1167
  id?: string;
1131
1168
  name: string;
1132
1169
  /** Argumentos tal cual los serializó el modelo (JSON en crudo). */
1133
1170
  arguments: string;
1171
+ /**
1172
+ * Provider data attached to this call that must travel back, untouched, when
1173
+ * the conversation returns it: Gemini 3's
1174
+ * `extra_content.google.thought_signature` through its OpenAI-compatible
1175
+ * endpoint, without which the next turn is rejected with a 400 («Function
1176
+ * call is missing a thought_signature»). Opaque: pass it back as received in
1177
+ * the assistant message's `toolCalls`. It is not part of any cache key.
1178
+ */
1179
+ extraContent?: Record<string, unknown>;
1134
1180
  }
1135
1181
  /** Result returned to the caller. */
1136
1182
  interface SavingsResult<T = unknown> {
@@ -1155,8 +1201,30 @@ interface SavingsResult<T = unknown> {
1155
1201
  * Por qué paró de generar el modelo (`"stop"`, `"length"`, `"tool_calls"`, …).
1156
1202
  * Presente cuando la respuesta viene del proveedor; ausente en los atajos
1157
1203
  * (caché/resolver), que solo sirven respuestas finales completas.
1204
+ *
1205
+ * In 0.5 this becomes a CLOSED set — `"stop"`, `"length"`, `"tool_calls"`,
1206
+ * `"content_filter"` or `"other"` — and the provider's own value (for example
1207
+ * `"stop_sequence"`, `"pause_turn"` or `"content_filter: OTHER"`) moves to
1208
+ * `finishReasonDetail`. Compare against those five values only; see the 0.5
1209
+ * migration guide.
1158
1210
  */
1159
1211
  finishReason?: string;
1212
+ /**
1213
+ * The provider's own reason behind `finishReason`, when it gave one. Present
1214
+ * only on answers the provider returned, and only with a non-empty reason:
1215
+ *
1216
+ * - Gemini (OpenAI-compatible endpoint): a filtered answer stops with
1217
+ * `finish_reason: "content_filter: OTHER"` (or `PROHIBITED_CONTENT`,
1218
+ * `SAFETY`…); it arrives as `finishReason: "content_filter"` and
1219
+ * `finishReasonDetail: "OTHER"`.
1220
+ * - Anthropic: a refusal (`stop_reason: "refusal"`) arrives as `finishReason:
1221
+ * "content_filter"` and `finishReasonDetail` set to `stop_details.category`
1222
+ * (for example `"cyber"` or `"bio"`).
1223
+ *
1224
+ * OpenAI's Structured Outputs refusal message travels in `refusal` instead.
1225
+ * Informational: it changes neither what is billed nor what is credited.
1226
+ */
1227
+ finishReasonDetail?: string;
1160
1228
  /**
1161
1229
  * The refusal message the model returned instead of an answer (OpenAI
1162
1230
  * Structured Outputs: `message.refusal`, with `finish_reason: "stop"` and no
@@ -1463,6 +1531,64 @@ interface QualityLedger {
1463
1531
  /** Present when `savings.modelCascade` is not `"off"`. */
1464
1532
  cascade?: QualityCascadeCheck;
1465
1533
  }
1534
+ /**
1535
+ * The provider's native prompt-cache saving on the call that produced the
1536
+ * answer: what the provider's own cache took off the invoice, net of the
1537
+ * cache-write premium the provider billed on that same call.
1538
+ *
1539
+ * `netUsd = readDiscountUsd − writePremiumUsd`, where
1540
+ * `readDiscountUsd = cacheReadTokens / 1000 × (inputPer1k − cachedInputPer1k)` and
1541
+ * `writePremiumUsd` is the write tokens at `inputPer1k × (multiplier − 1)`
1542
+ * (Anthropic 1.25× for 5 minutes and 2× for one hour; OpenAI 1.25× from
1543
+ * gpt-5.6 on, 1× before; Gemini 1×). Every input is in this block, so it can be
1544
+ * recomputed without trusting the layer. `netUsd` can be negative: a cold
1545
+ * write pays the premium before any read.
1546
+ *
1547
+ * It is SEPARATE on purpose. The layer can place the breakpoint (Anthropic
1548
+ * `cache_control`), route (OpenAI `prompt_cache_key`) or keep the prefix
1549
+ * stable, but the discount is billed by the provider and much of it would be
1550
+ * there without the layer, so it is never credited as the layer's saving:
1551
+ * it is not in `cost.netSavings`, not in `cost.baselineEstimate`, and not in
1552
+ * any commission base.
1553
+ */
1554
+ interface NativeSavingsReport {
1555
+ /** Who billed the cache, inferred from the model id. */
1556
+ provider: "anthropic" | "openai" | "google" | "unknown";
1557
+ /**
1558
+ * How that provider caches: `explicit` (Anthropic, `cache_control`
1559
+ * breakpoints), `automatic` (OpenAI, prefix cache with no marking) or
1560
+ * `implicit` (Gemini implicit caching).
1561
+ */
1562
+ mechanism: "explicit" | "automatic" | "implicit" | "unknown";
1563
+ /** True when the layer placed the cache breakpoint on the call that ran. Absent where the layer does not know. */
1564
+ layerMarked?: boolean;
1565
+ /** Input tokens the provider served from its cache on this call (its own counter). */
1566
+ cacheReadTokens: number;
1567
+ /** Input tokens the provider billed as cache writes on this call (its own counter, every TTL). */
1568
+ cacheWriteTokens: number;
1569
+ /** The part of `cacheWriteTokens` written with a one-hour TTL. */
1570
+ cacheWrite1hTokens: number;
1571
+ /** Input rate applied, per 1K tokens. */
1572
+ inputPer1k: number;
1573
+ /** Cache-read rate applied, per 1K tokens. */
1574
+ cachedInputPer1k: number;
1575
+ /** Write multiplier applied to five-minute (or untyped) writes. */
1576
+ writeMultiplier: number;
1577
+ /** Write multiplier applied to one-hour writes. */
1578
+ write1hMultiplier: number;
1579
+ /** What the cache reads saved against the input rate, USD. */
1580
+ readDiscountUsd: number;
1581
+ /** The premium the provider billed for the cache writes, USD. */
1582
+ writePremiumUsd: number;
1583
+ /** `readDiscountUsd − writePremiumUsd`, USD. Can be negative. */
1584
+ netUsd: number;
1585
+ /**
1586
+ * `measured`: the provider's own counter at list price. `unmeasured`: the
1587
+ * counter was incomplete or there is no cache-read price for the model, and
1588
+ * every USD figure is 0.
1589
+ */
1590
+ basis: "measured" | "unmeasured";
1591
+ }
1466
1592
  interface SavingsReport {
1467
1593
  requestId: string;
1468
1594
  /**
@@ -1585,6 +1711,17 @@ interface SavingsReport {
1585
1711
  * `cacheBreakpoints: "auto"` switched this request to explicit mode.
1586
1712
  */
1587
1713
  cacheWrites?: CacheWriteReport;
1714
+ /**
1715
+ * The provider's OWN prompt-cache discount on this call, shown apart. Present
1716
+ * only when a call ran and the provider reported cache reads or writes.
1717
+ *
1718
+ * It is not the layer's saving and it is never part of `cost.netSavings`,
1719
+ * `cost.baselineEstimate`, `basis: "reference"` or the commission base: the
1720
+ * discount is the provider's, and `cost` prices cached tokens at the cached
1721
+ * rate on both sides for exactly that reason. It exists so the report adds up
1722
+ * to your invoice. See {@link NativeSavingsReport}.
1723
+ */
1724
+ nativeSavings?: NativeSavingsReport;
1588
1725
  /** How a streamed request was delivered. Present only on results of `generateStream`. */
1589
1726
  streaming?: StreamingReport;
1590
1727
  /**
@@ -1608,7 +1745,29 @@ interface SavingsReport {
1608
1745
  cost: {
1609
1746
  baselineEstimate: number;
1610
1747
  actual: number;
1748
+ /**
1749
+ * A RATIO, not money: `1 - actual / baselineEstimate`, rounded to six
1750
+ * decimals (0 when nothing was saved, negative when the request cost more).
1751
+ * Do not sum it across requests: it is a ratio, not dollars.
1752
+ *
1753
+ * @deprecated Since 0.4.33, read {@link netSavingsRatio} (the same value) or
1754
+ * {@link netSavingsUsd} (the saving in USD). Removed in 0.5: see the 0.5
1755
+ * migration guide.
1756
+ */
1611
1757
  netSavings: number;
1758
+ /**
1759
+ * The saving as a RATIO of the baseline: `1 - actual / baselineEstimate`,
1760
+ * rounded to six decimals (0 when nothing was saved or there is no baseline,
1761
+ * negative when the request cost more). Do not sum it across requests: sum
1762
+ * {@link netSavingsUsd}.
1763
+ */
1764
+ netSavingsRatio: number;
1765
+ /**
1766
+ * The saving in USD: `baselineEstimate - actual` (negative when the request
1767
+ * cost more). Sum it only within one `basis`: measured and estimated money
1768
+ * are never added together.
1769
+ */
1770
+ netSavingsUsd: number;
1612
1771
  /**
1613
1772
  * Where the baseline comes from. It is what separates measured money from
1614
1773
  * estimated money.
@@ -1666,6 +1825,12 @@ interface SavingsReport {
1666
1825
  preprocessing: number;
1667
1826
  provider: number;
1668
1827
  };
1828
+ /**
1829
+ * Present only when the layer runs on the free «Measure» license (shadow
1830
+ * mode): what the levers would have saved on this request. Nothing was
1831
+ * applied — `cost` is this call's measured spend with no saving claimed.
1832
+ */
1833
+ measure?: MeasureReport;
1669
1834
  /** Ordered pipeline decision breadcrumbs, for debugging and audit. */
1670
1835
  traces: TraceEvent[];
1671
1836
  }
@@ -1716,6 +1881,50 @@ interface LicenseGate {
1716
1881
  * caller; without it, the generic message for that status.
1717
1882
  */
1718
1883
  reason?(): string | undefined;
1884
+ /**
1885
+ * The plan of the license in force, when there is one. `"measure"` (the free
1886
+ * «Measure» license) puts the layer in SHADOW MODE: the request goes to the
1887
+ * provider exactly as you built it, nothing is served from any cache, and
1888
+ * `report.measure` says what the levers would have saved. Optional because a
1889
+ * gate is implemented by the caller; without it, the layer is not in shadow.
1890
+ */
1891
+ plan?(): string | undefined;
1892
+ }
1893
+ /**
1894
+ * What a layer running on the free «Measure» license would have saved on this
1895
+ * request. Present ONLY in shadow mode. Nothing here was applied: the request
1896
+ * went to your provider untouched and nothing was served from a cache.
1897
+ *
1898
+ * Every figure is HYPOTHETICAL (`basis: "shadow"`): it is never part of
1899
+ * `cost.baselineEstimate`, `cost.actual` or `cost.netSavings`, never in any
1900
+ * commission base, and never added to measured money.
1901
+ */
1902
+ interface MeasureReport {
1903
+ mode: "shadow";
1904
+ /** Always false: in shadow mode no lever changes the request or avoids a call. */
1905
+ applied: false;
1906
+ wouldHaveSaved: {
1907
+ /** USD this request would not have cost with the simulated levers on. */
1908
+ usd: number;
1909
+ basis: "shadow";
1910
+ /**
1911
+ * Which lever would have avoided the call entirely, valued with THIS call's
1912
+ * provider counter (`cost.actual`):
1913
+ * · `exact-repeat` — a byte-identical, cacheable request already ran
1914
+ * in this process within the exact-cache TTL;
1915
+ * · `in-flight-duplicate`— an identical request was in flight at the same
1916
+ * time and would have been coalesced.
1917
+ * `null` when no simulated lever would have avoided it.
1918
+ */
1919
+ avoidedCall: "exact-repeat" | "in-flight-duplicate" | null;
1920
+ };
1921
+ /**
1922
+ * Levers this shadow does NOT simulate, so `wouldHaveSaved` is a LOWER bound:
1923
+ * they need a model call, an embedding, or a paid entitlement to estimate.
1924
+ */
1925
+ notSimulated: string[];
1926
+ /** Where to turn the levers on. */
1927
+ upgradeUrl: string;
1719
1928
  }
1720
1929
  interface TraceEvent {
1721
1930
  stage: string;
@@ -1920,6 +2129,8 @@ interface CanonicalRequest {
1920
2129
  contractId: string | null;
1921
2130
  temperature: number | null;
1922
2131
  seed: number | null;
2132
+ /** `reasoning_effort` declared by the caller; absent when it declared none. */
2133
+ reasoningEffort?: string;
1923
2134
  tenantId: string;
1924
2135
  authorizationScope: string;
1925
2136
  /**
@@ -2198,6 +2409,8 @@ interface SemanticRecord {
2198
2409
  temperature: number | null;
2199
2410
  /** Sampling seed of the request, or null when it set none. */
2200
2411
  seed: number | null;
2412
+ /** `reasoning_effort` of the request; absent when it declared none. */
2413
+ reasoningEffort?: string;
2201
2414
  storedAtMs: number;
2202
2415
  /**
2203
2416
  * With calibration on: the highest score at which this stored answer was
@@ -2582,17 +2795,22 @@ interface ToolSelection {
2582
2795
  }
2583
2796
  interface ToolSelectorOptions {
2584
2797
  /**
2585
- * Max tools the selector keeps when it has a SIGNAL to select on: a catalogue
2586
- * whose tools declare `intents` and/or `risk`, with the router on. Default 8.
2587
- *
2588
- * It never truncates a catalogue it cannot rank. A catalogue that declares no
2589
- * `intents` and no `risk` (the usual case: MCP and OpenAI tool lists) and every
2590
- * request with `savings: { router: false }` go to the provider WHOLE, exactly as
2591
- * the caller sent them, and the layer credits nothing for the tool block:
2592
- * cutting by position left the model unable to call the rest (on BFCL
2593
- * multi-turn, gpt-4o-mini hit the reference call 8/10 times directly and 1/10
2594
- * through the layer). When the selector does prune a typed catalogue, the
2595
- * report's `tool-selector` trace lists what was left out and the SDK warns
2798
+ * Cap on the tools the selector keeps by relevance. Unset (the default since
2799
+ * 0.4.33), there is NO cap and NO relevance pruning: every tool the request
2800
+ * may use reaches the provider, and the layer credits nothing for the tool
2801
+ * block. Set it to opt in to pruning a TYPED catalogue (tools that declare
2802
+ * `intents` and/or `risk`, with the router on) down to the `maxTools` most
2803
+ * relevant ones — up to 0.4.32 that was the default, with 8.
2804
+ *
2805
+ * What is never affected by this option: write and destructive tools are
2806
+ * still withheld from a request the router does not classify as an action
2807
+ * (that gate is about safety, not size), and a catalogue that declares no
2808
+ * `intents` and no `risk` (the usual case: MCP and OpenAI tool lists), or any
2809
+ * request with `savings: { router: false }`, goes to the provider WHOLE,
2810
+ * exactly as the caller sent it. Cutting blind left the model unable to call
2811
+ * the rest (on BFCL multi-turn, gpt-4o-mini hit the reference call 8/10 times
2812
+ * directly and 1/10 through the layer). Whenever the selector does leave a
2813
+ * tool out, the report's `tool-selector` trace lists it and the SDK warns
2596
2814
  * (once per process, silenced by `silenceWarnings`).
2597
2815
  */
2598
2816
  maxTools?: number;
@@ -2860,6 +3078,8 @@ declare const noopCompressor: Compressor;
2860
3078
  /**
2861
3079
  * Did the compression keep the facts that must not change? Verifies the RESULT —
2862
3080
  * number/date multiset and negation parity — not the compressor's own claim.
3081
+ *
3082
+ * @deprecated Internal check of the compression stage; leaves the public API in 0.5.
2863
3083
  */
2864
3084
  declare function compresionFiel(original: string, comprimido: string): boolean;
2865
3085
 
@@ -3050,6 +3270,12 @@ interface ProviderRequest {
3050
3270
  maxOutputTokens?: number;
3051
3271
  temperature?: number;
3052
3272
  seed?: number;
3273
+ /**
3274
+ * `SavingsRequest.reasoningEffort`, as the caller declared it. The
3275
+ * OpenAI-compatible adapter sends it as `reasoning_effort`; absent means
3276
+ * nothing is sent.
3277
+ */
3278
+ reasoningEffort?: string;
3053
3279
  /** Backend id selected by the constraints layer, for observability. */
3054
3280
  constraintBackend?: string;
3055
3281
  /**
@@ -3061,6 +3287,9 @@ interface ProviderRequest {
3061
3287
  * boundary; adapters that cache automatically (OpenAI) may ignore it. The
3062
3288
  * count is a claim about byte-for-byte stability, so a caller that rewrites an
3063
3289
  * earlier turn must lower it.
3290
+ *
3291
+ * `0` claims only what renders BEFORE the messages: the tool catalogue. The
3292
+ * Anthropic adapter then marks the end of the `tools` block (its last tool).
3064
3293
  */
3065
3294
  stablePrefixMessages?: number;
3066
3295
  /**
@@ -3225,6 +3454,17 @@ interface ProviderResponse {
3225
3454
  * podía distinguirlo y hacía exactamente eso.
3226
3455
  */
3227
3456
  finishReason?: "stop" | "length" | "content_filter" | "tool_calls" | (string & {});
3457
+ /**
3458
+ * The provider's own reason behind `finishReason`, when it gave one: Gemini's
3459
+ * OpenAI-compatible endpoint stops a filtered answer with
3460
+ * `finish_reason: "content_filter: OTHER"` (or `PROHIBITED_CONTENT`,
3461
+ * `SAFETY`…), which the built-in adapter reports as `finishReason:
3462
+ * "content_filter"` and `finishReasonDetail: "OTHER"`. Anthropic's refusal
3463
+ * (`stop_reason: "refusal"`) carries its `stop_details.category` here.
3464
+ * Informational: the layer decides on `finishReason` alone, and passes this
3465
+ * on to the caller as `SavingsResult.finishReasonDetail`.
3466
+ */
3467
+ finishReasonDetail?: string;
3228
3468
  /**
3229
3469
  * The refusal message the model returned INSTEAD of an answer, exactly as the
3230
3470
  * provider wrote it: OpenAI's `message.refusal` (Chat Completions with
@@ -3390,6 +3630,9 @@ interface LicenseTokenPayload {
3390
3630
  expires_at: number;
3391
3631
  grace_days: number;
3392
3632
  iss?: string;
3633
+ /** Measure licenses only: the REAL term (see `vigenciaEfectiva` in ./vigencia.ts). */
3634
+ measure_expires_at?: number;
3635
+ measure_grace_days?: number;
3393
3636
  }
3394
3637
  interface ResolvedLicense {
3395
3638
  status: LicenseStatus;
@@ -3544,6 +3787,18 @@ interface SavingsLayerConfig {
3544
3787
  * it on every request. A layer that has a cache and a request that neither
3545
3788
  * asks for it nor turns it off gets a one-time console warning (silenced by
3546
3789
  * `silenceWarnings`, or by setting `semanticCacheDefault`, `false` included).
3790
+ *
3791
+ * Called `semanticCache` until 0.4.33, so that the store and the per-request
3792
+ * switch (`savings.semanticCache`) no longer share a name. See the 0.5
3793
+ * migration guide.
3794
+ */
3795
+ semanticCacheStore?: InMemorySemanticCache;
3796
+ /**
3797
+ * @deprecated Renamed {@link semanticCacheStore} in 0.4.33, so that the store
3798
+ * and the per-request switch (`savings.semanticCache`) no longer share a name.
3799
+ * It still works, with a one-time warning (silenced by `silenceWarnings`);
3800
+ * when both are given, `semanticCacheStore` wins. Removed in 0.5: see the 0.5
3801
+ * migration guide.
3547
3802
  */
3548
3803
  semanticCache?: InMemorySemanticCache;
3549
3804
  /**
@@ -3551,7 +3806,7 @@ interface SavingsLayerConfig {
3551
3806
  * request's own value always wins, `false` included. Unset, the semantic cache
3552
3807
  * is used only by requests that ask for it.
3553
3808
  *
3554
- * OPT-IN, and deliberately a separate field from {@link semanticCache}: the
3809
+ * OPT-IN, and deliberately a separate field from {@link semanticCacheStore}: the
3555
3810
  * cache is the backend, this is the decision to serve answers to reworded
3556
3811
  * questions, which can serve a wrong answer. Prefer it with a cache built with
3557
3812
  * `calibration`, which serves nothing until your own traffic certifies a
@@ -3673,6 +3928,9 @@ interface SavingsLayerConfig {
3673
3928
  * to support signing-key rotation — legacy no-kid tokens use `defaultKid`, and
3674
3929
  * an unknown kid fails closed. For self-hosting/self-testing; defaults to the
3675
3930
  * build-embedded BiVelio key.
3931
+ *
3932
+ * @deprecated Has no effect in the published package, which always verifies
3933
+ * against the embedded BiVelio key. Removed from the public type in 0.5.
3676
3934
  */
3677
3935
  licensePublicKey?: string | LicenseKeyset;
3678
3936
  /**
@@ -3681,6 +3939,9 @@ interface SavingsLayerConfig {
3681
3939
  * only accepted license — passing a gate there logs a warning and changes
3682
3940
  * nothing. It exists for builds from source (this repo's own tests and
3683
3941
  * benchmarks), where it takes precedence over {@link licenseKey}.
3942
+ *
3943
+ * @deprecated Ignored in the published package. Removed from the public type
3944
+ * in 0.5; license the layer with {@link licenseKey} or `serviceAccountKey`.
3684
3945
  */
3685
3946
  licenseGate?: LicenseGate;
3686
3947
  /**
@@ -3799,6 +4060,9 @@ interface SavingsLayerConfig {
3799
4060
  * distributed build hard-codes the licensing check on, so setting
3800
4061
  * `devUnlicensed` (or `BVSALA_DEV_OPEN`) there has NO effect — the layer still
3801
4062
  * requires a valid `licenseKey`. It is not a way to run the product for free.
4063
+ *
4064
+ * @deprecated No effect in the published package. Removed from the public type
4065
+ * in 0.5.
3802
4066
  */
3803
4067
  devUnlicensed?: boolean;
3804
4068
  /** Per-model cost models; falls back to `defaultCostModel`. */
@@ -4361,6 +4625,13 @@ interface Policy {
4361
4625
  * así que sin esto "hour" y "day" no significaban nada operativamente.
4362
4626
  */
4363
4627
  maxCacheAgeMs: number | null;
4628
+ /**
4629
+ * The user turns touch a sensitive topic (self-harm or suicide, a mental
4630
+ * health crisis, a medical emergency), or null. With a topic, neither the
4631
+ * exact nor the semantic cache is used and no reference record is left: the
4632
+ * answer is measured and served, never replayed or credited as a saving.
4633
+ */
4634
+ sensitiveTopic: "self-harm" | "mental-health-crisis" | "medical-emergency" | null;
4364
4635
  reasons: string[];
4365
4636
  }
4366
4637
  declare function evaluatePolicy(c: CanonicalRequest): Policy;
@@ -4402,6 +4673,9 @@ declare function evaluatePolicy(c: CanonicalRequest): Policy;
4402
4673
  * Term weight is sublinear (`1 + log tf`) so a word repeated forty times does not
4403
4674
  * dominate the direction of the vector, and the result is L2-normalised so cosine
4404
4675
  * similarity is a plain dot product.
4676
+ *
4677
+ * @deprecated Internal detail of {@link localEmbedding}; leaves the public API in 0.5.
4678
+ * Use {@link localEmbedding}, which returns the same vector.
4405
4679
  */
4406
4680
  declare function vectorLocal(texto: string): number[];
4407
4681
  /**
@@ -4410,6 +4684,8 @@ declare function vectorLocal(texto: string): number[];
4410
4684
  * Synchronous by design — it returns the array, not a promise — so a cache lookup
4411
4685
  * adds no await and no latency to the request path.
4412
4686
  */
4687
+ declare function localEmbedding(text: string): number[];
4688
+ /** @deprecated Spanish name, removed in 0.5. Use {@link localEmbedding}. */
4413
4689
  declare function embebedorLocal(texto: string): number[];
4414
4690
  /**
4415
4691
  * The similarity floor this embedder is calibrated for.
@@ -4420,6 +4696,8 @@ declare function embebedorLocal(texto: string): number[];
4420
4696
  * guessed — see `test/embebedor-local.test.ts`, which fails if the two
4421
4697
  * populations stop being separable.
4422
4698
  */
4699
+ declare const LOCAL_EMBEDDING_THRESHOLD = 0.72;
4700
+ /** @deprecated Spanish name, removed in 0.5. Use {@link LOCAL_EMBEDDING_THRESHOLD}. */
4423
4701
  declare const UMBRAL_LOCAL = 0.72;
4424
4702
 
4425
4703
  /**
@@ -4610,6 +4888,21 @@ declare function createMockProvider(options?: MockProviderOptions): Provider;
4610
4888
  * `constraints.backend: "none"` rather than claiming a guarantee the provider
4611
4889
  * never gave.
4612
4890
  *
4891
+ * OpenAI-only request fields are sent only to OpenAI's own API
4892
+ * (`prompt_cache_key`, see {@link OpenAICompatibleOptions.sendPromptCacheKey}).
4893
+ * An optional field an endpoint still rejects by name with a 400/422
4894
+ * (`prompt_cache_key`, `service_tier`, `seed`) is dropped and the request
4895
+ * repeated once, and the model is remembered, as with `response_format`.
4896
+ *
4897
+ * Output is counted as the provider bills it: where `total_tokens` exceeds
4898
+ * `prompt_tokens + completion_tokens` (Gemini's OpenAI-compatible endpoint
4899
+ * leaves its thinking tokens out of `completion_tokens`), the difference is
4900
+ * added to the output and reported as reasoning. Against OpenAI's own API,
4901
+ * whose `completion_tokens` already include reasoning, nothing is added. A
4902
+ * content-filter stop with a reason (Gemini's `"content_filter: OTHER"`) is
4903
+ * reported as `finishReason: "content_filter"`, the reason in
4904
+ * `finishReasonDetail`.
4905
+ *
4613
4906
  * Network calls use global `fetch` (Node >= 18) so there is no SDK dependency.
4614
4907
  */
4615
4908
  interface OpenAICompatibleOptions {
@@ -4619,8 +4912,11 @@ interface OpenAICompatibleOptions {
4619
4912
  * Strip the `provider/` prefix from model ids before sending (`openai/gpt-4o-mini`
4620
4913
  * → `gpt-4o-mini`).
4621
4914
  *
4622
- * Default (undefined): strip when `baseUrl` is OpenAI's own API or an Azure
4623
- * OpenAI endpoint, keep otherwise. OpenAI rejects a prefixed id with a 404
4915
+ * Default (undefined): strip when `baseUrl` is OpenAI's own API, an Azure
4916
+ * OpenAI endpoint or Google's own Gemini API
4917
+ * (https://generativelanguage.googleapis.com, whose OpenAI-compatible
4918
+ * endpoint answers 404 «models/google/gemini-… is not found» to a prefixed
4919
+ * id), keep otherwise. OpenAI rejects a prefixed id with a 404
4624
4920
  * ("model does not exist"), so the qualified ids the layer uses everywhere
4625
4921
  * else — pricing, cache keys, the report — would break the very first call
4626
4922
  * that reaches the provider. A gateway or a self-hosted server with a
@@ -4660,6 +4956,20 @@ interface OpenAICompatibleOptions {
4660
4956
  * explicit value always wins and is never switched.
4661
4957
  */
4662
4958
  maxTokensParam?: "max_tokens" | "max_completion_tokens";
4959
+ /**
4960
+ * Whether to send `prompt_cache_key`, the routing hint OpenAI uses to land
4961
+ * requests that share a prefix on the same cache instance.
4962
+ *
4963
+ * Default (undefined): only when `baseUrl` is OpenAI's own API
4964
+ * (https://api.openai.com). The field is OpenAI's, and strict endpoints
4965
+ * reject what they do not know: Gemini's OpenAI-compatible endpoint answers
4966
+ * 400 «Unknown name "prompt_cache_key"», so from 0.4.1 to 0.4.31 every
4967
+ * request with a cached prefix failed there. Set `true` for a proxy or router
4968
+ * in front of OpenAI that forwards it (if the endpoint rejects it anyway,
4969
+ * the request is repeated once without it and the model is remembered), or
4970
+ * `false` to never send it.
4971
+ */
4972
+ sendPromptCacheKey?: boolean;
4663
4973
  }
4664
4974
  /**
4665
4975
  * ¿Cumple este esquema las reglas del modo `strict` de OpenAI?
@@ -4677,9 +4987,12 @@ interface OpenAICompatibleOptions {
4677
4987
  declare function isStrictCompatible(schema: unknown): boolean;
4678
4988
  /**
4679
4989
  * Decides the id that travels on the wire. Explicit option wins; otherwise the
4680
- * endpoint decides: OpenAI/Azure get the bare id, everything else keeps what
4681
- * the caller wrote. Exported for the pipeline-level test that pins the README
4990
+ * endpoint decides: OpenAI/Azure and Google's own Gemini API get the bare id,
4991
+ * everything else keeps what the caller wrote. Exported for the pipeline-level test that pins the README
4682
4992
  * snippet; not part of the public API.
4993
+ *
4994
+ * @deprecated Not part of the public API; leaves it in 0.5. Use the adapter option
4995
+ * `stripProviderPrefix`.
4683
4996
  */
4684
4997
  declare function quitarPrefijoDeProveedor(model: string, explicito: boolean | undefined, baseUrl: string): string;
4685
4998
  declare class OpenAICompatibleProvider implements Provider {
@@ -4690,6 +5003,7 @@ declare class OpenAICompatibleProvider implements Provider {
4690
5003
  private readonly sinResponseFormat;
4691
5004
  private streamOptionsRejected;
4692
5005
  private readonly campoDeTopeAprendido;
5006
+ private readonly camposRechazados;
4693
5007
  private readonly origen;
4694
5008
  constructor(opts: OpenAICompatibleOptions);
4695
5009
  generate(req: ProviderRequest, options?: ProviderStreamOptions): Promise<ProviderResponse>;
@@ -4705,6 +5019,8 @@ declare class OpenAICompatibleProvider implements Provider {
4705
5019
  generateStream(req: ProviderRequest, options?: ProviderStreamOptions): AsyncGenerator<ProviderStreamEvent, void, undefined>;
4706
5020
  private campoDeTope;
4707
5021
  private corregirCampoDeTope;
5022
+ private corregirCampoOpcional;
5023
+ private campoAdmitido;
4708
5024
  private enviar;
4709
5025
  private construirCuerpo;
4710
5026
  /** Translate a 2xx endpoint response into the provider-neutral shape. */
@@ -4808,6 +5124,8 @@ declare class AnthropicProvider implements Provider {
4808
5124
  private readonly opts;
4809
5125
  private readonly fetchImpl;
4810
5126
  private readonly busquedas;
5127
+ private readonly sinToolChoiceForzado;
5128
+ private readonly sinMuestreo;
4811
5129
  constructor(opts?: AnthropicOptions);
4812
5130
  /** The id Anthropic's API sees: bare at `api.anthropic.com`, as written elsewhere. */
4813
5131
  private modeloEnElCable;
@@ -4822,6 +5140,7 @@ declare class AnthropicProvider implements Provider {
4822
5140
  * as one text event.
4823
5141
  */
4824
5142
  generateStream(req: ProviderRequest, options?: ProviderStreamOptions): AsyncGenerator<ProviderStreamEvent, void, undefined>;
5143
+ private enviarConCorrecciones;
4825
5144
  private enviar;
4826
5145
  private construirCuerpo;
4827
5146
  private reenvioDeBusquedas;
@@ -4833,6 +5152,95 @@ declare class AnthropicProvider implements Provider {
4833
5152
  private leerMensaje;
4834
5153
  }
4835
5154
 
5155
+ /** Gemini's `ThinkingConfig`, as its API reference defines it. */
5156
+ interface GoogleThinkingConfig {
5157
+ thinkingLevel?: "MINIMAL" | "LOW" | "MEDIUM" | "HIGH" | (string & {});
5158
+ thinkingBudget?: number;
5159
+ includeThoughts?: boolean;
5160
+ }
5161
+
5162
+ /**
5163
+ * Options for {@link GoogleProvider}, the adapter for Gemini's native API
5164
+ * (`generateContent` / `streamGenerateContent`, v1beta).
5165
+ */
5166
+ interface GoogleOptions {
5167
+ /** Gemini API key, sent in the `x-goog-api-key` header. */
5168
+ apiKey?: string;
5169
+ /**
5170
+ * Defaults to `https://generativelanguage.googleapis.com/v1beta`, Google's
5171
+ * own API. Override for a gateway or a proxy that speaks the same shape;
5172
+ * repeats of calls that went anywhere else are never valued by reference.
5173
+ */
5174
+ baseUrl?: string;
5175
+ /** Extra headers (e.g. for a gateway). */
5176
+ headers?: Record<string, string>;
5177
+ /** Injectable fetch for testing. */
5178
+ fetchImpl?: typeof fetch;
5179
+ /**
5180
+ * When true (recommended for measurement), a response without the prompt
5181
+ * and output counters in `usageMetadata` is a hard error instead of being
5182
+ * counted as 0 tokens, which would otherwise fabricate a saving.
5183
+ */
5184
+ requireUsage?: boolean;
5185
+ /**
5186
+ * Default `generationConfig.thinkingConfig` for every request, sent as
5187
+ * written (`{ thinkingLevel: "LOW" }`, `{ thinkingBudget: 0 }`,
5188
+ * `{ includeThoughts: true }`). A request's `reasoningEffort` replaces its
5189
+ * level or budget. Thought summaries (`includeThoughts`) are billed output
5190
+ * and never part of `text`.
5191
+ */
5192
+ thinkingConfig?: GoogleThinkingConfig;
5193
+ /** `safetySettings`, sent as written with every request. */
5194
+ safetySettings?: unknown[];
5195
+ }
5196
+ /**
5197
+ * Adapter for Gemini's NATIVE API (`models/{model}:generateContent` and
5198
+ * `:streamGenerateContent?alt=sse`, v1beta). Recommended for Gemini; use
5199
+ * {@link OpenAICompatibleProvider} for every other provider.
5200
+ *
5201
+ * Unlike Gemini's OpenAI-compatible endpoint, the native API documents what the
5202
+ * layer measures: the system prompt travels in `systemInstruction`; tools are
5203
+ * `functionDeclarations` and calls come back as `functionCall` parts whose
5204
+ * `thoughtSignature` is returned in `ToolCallRequest.extraContent` (the same
5205
+ * shape as the compatible endpoint's) and sent back untouched; `usageMetadata`
5206
+ * separates prompt, cached prompt (implicit caching), visible output and
5207
+ * thinking (`thoughtsTokenCount`, billed as output); and a blocked prompt
5208
+ * (`promptFeedback.blockReason`) or a filtered answer (`finishReason` `SAFETY`,
5209
+ * `PROHIBITED_CONTENT`, `BLOCKLIST`…) is reported as
5210
+ * `finishReason: "content_filter"` with the native reason in
5211
+ * `finishReasonDetail`, so it is measured, never cached and never credited.
5212
+ *
5213
+ * The output contract travels in `responseJsonSchema` with
5214
+ * `responseMimeType: "application/json"`; `maxOutputTokens`, `temperature` and
5215
+ * `seed` in `generationConfig`; `reasoningEffort` becomes `thinkingLevel`
5216
+ * (Gemini 3) or `thinkingBudget` (Gemini 2.5); a deferrable request asks for
5217
+ * `serviceTier: "flex"`. Explicit context caching (`cachedContents`) is not
5218
+ * used.
5219
+ *
5220
+ * Network calls use global `fetch` (Node >= 18) so there is no SDK dependency.
5221
+ */
5222
+ declare class GoogleProvider implements Provider {
5223
+ readonly id: string;
5224
+ private readonly opts;
5225
+ private readonly fetchImpl;
5226
+ private readonly base;
5227
+ private readonly oficial;
5228
+ private readonly nivelAprendido;
5229
+ constructor(opts?: GoogleOptions);
5230
+ generate(req: ProviderRequest, options?: ProviderStreamOptions): Promise<ProviderResponse>;
5231
+ /**
5232
+ * Streaming variant of generate() over `streamGenerateContent?alt=sse`.
5233
+ * Requests with an output contract or a deferrable tier are served by
5234
+ * generate() and yielded as one text event.
5235
+ */
5236
+ generateStream(req: ProviderRequest, options?: ProviderStreamOptions): AsyncGenerator<ProviderStreamEvent, void, undefined>;
5237
+ private enviarConCorrecciones;
5238
+ private enviar;
5239
+ private cuerpo;
5240
+ private pensamiento;
5241
+ private cerrar;
5242
+ }
5243
+
4836
5244
  /**
4837
5245
  * Trace collector: an ordered log of pipeline decisions with elapsed timings.
4838
5246
  * Every stage records why it did what it did, so a SavingsReport can be audited
@@ -4950,6 +5358,8 @@ interface ResolvedGate extends LicenseGate {
4950
5358
  * branching does not change — but the advice given to the customer differs.
4951
5359
  */
4952
5360
  reason(): string | undefined;
5361
+ /** The signed plan while the license grants (`"measure"` = shadow mode). */
5362
+ plan?(): string | undefined;
4953
5363
  /** Unix seconds after which the online status should be re-checked (poller anchor). */
4954
5364
  refreshAfter?(): number | undefined;
4955
5365
  }
@@ -5706,4 +6116,42 @@ declare function toCsv(rows: readonly Readonly<Record<string, CsvValue>>[], opti
5706
6116
  columns?: readonly string[];
5707
6117
  }): string;
5708
6118
 
5709
- export { type AnswerJudge, type AnswerSource, type AnthropicOptions, AnthropicProvider, BV_SALA_VERSION, type BatchCounts, type BatchItemResult, type BatchJob, type BatchJobStatus, type BatchRequest, type BatchResults, BatchSubmitError, type BatchSubmitOptions, type BatchSummary, type BivelioHandoff, CATALOGO, COMPACTION_TRANSFORMS, COMPACT_ROWS_INSTRUCTION, type CacheBreakpointStore, type CacheOutcome, type CachePlacement, type CacheTier, type CacheWriteReport, type CachedAnswer, type CalibrationObservation, CalibrationStateError, type CanonicalRequest, type ChatMessage, type CompactRowsDecodeOptions, type CompactRowsOptions, type CompactVerification, type CompactionTransform, type CompressionEconomics, type CompressionPolicyInput, type CompressionRequest, type CompressionResult, type Compressor, type ConstraintBackend, type ConstraintBackendId, type ConstraintPlan, type ConversationState, type CostBasis, type CostModel, type CsvValue, DEFAULT_COST_MODEL, DEFAULT_MAX_STALENESS_SECONDS, DEFAULT_MIN_SAVED_CHARS, type DeferredExecutionReport, type DeterministicResolver, EMBEDDED_PUBLIC_KEY, type EmbeddingFn, type EvidenceDoc, type ExactCache, ExactTokenizer, type ExecutionClass, ExecutionRouter, type FocusExportOptions, type FocusRow, type FormatChoice, FormatSelector, type FormatSelectorOptions, type HandoffFact, HeuristicEstimator, InMemoryCacheBreakpointStore, InMemoryExactCache, InMemorySemanticCache, InMemoryToolSetFreezer, type JsonSchema, type LangfuseGenerationUpdate, LicenseError, type LicenseGate, type LicenseKeyShape, type LicenseKeyset, type LicenseStatus, type LicenseTokenPayload, type LocalClassifier, MODELOS_POR_CODIFICACION, MODELS_BY_ENCODING, type MemoryDelta, type MessageRole, MockProvider, type MockProviderOptions, type ModelCascadeMode, type ModelCascadeReport, type ModelCascadeSettings, type OpenAICompatibleOptions, OpenAICompatibleProvider, type OutputContract, PRECIOS_AL_DIA, type Policy, type PriceLeverSaving, type PriceLeverSettings, type ProtectedSpan, type Provider, type ProviderRequest, type ProviderResponse, type ProviderStreamEvent, type ProviderStreamOptions, type ProviderToolSearch, type ProviderToolSearchUsage, type ProviderUsage, QUALITY_STATUSES, type QualityCacheMatch, type QualityCascadeCheck, type QualityLedger, type QualityRepairCheck, type QualitySchemaCheck, type QualityStatus, type QualityTruncationCheck, REFERENCE_MAX_AGE_MS, REFERENCE_MESSAGE_ALLOWANCE, REFERENCE_OUTPUT_SHARE, type ReferenceCredit, type ReferenceRejection, type RequestContext, type Reranker, type ResolvedDeps, type ResolvedGate, type ResolvedLicense, ResolverRegistry, type ResolverResult, type RetrievalOptions, type RetrievalOutcome, type RetrievalPlan, type Retriever, type RevocationListBody, type RevocationListVerification, type RevocationPollEvent, RevocationPoller, type RevocationPollerOptions, RevocationSnapshot, type RouteDecision, type SavingsAdapterLevers, type SavingsAdapterOptions, type SavingsAttributeOptions, type SavingsBatches, type SavingsCallOptions, type SavingsLayer, type SavingsLayerConfig, SavingsLedger, type SavingsRecord, type SavingsReport, type SavingsReportForExport, type SavingsRequest, type SavingsResult, type SavingsSeriesOptions, type SavingsSeriesRow, type SavingsSpanAttributes, type SavingsSpanOptions, type SavingsStream, type SavingsStreamEvent, type SavingsStreamOptions, type SavingsToggles, type SavingsTracingOptions, SchemaRegistry, type SemanticCacheOptions, type SemanticCalibrationBound, type SemanticCalibrationOptions, type SemanticCalibrationSegmentState, type SemanticCalibrationState, type SemanticCalibrationStatus, type SemanticHit, type SemanticLookup, type SemanticProbe, type SemanticRecord, type SemanticVerifier, type SerializationFormat, type Serializer, Singleflight, type SpanAttributeValue, type SpanLike, type SpanStartOptionsLike, StreamAbortedError, type StreamingReport, type TokenEstimator, TokenizerRegistry, type ToolCallRequest, type ToolDescriptor, type ToolOutputCompaction, type ToolOutputCompactionSettings, type ToolRisk, type ToolSearchMode, type ToolSearchOptions, type ToolSelection, ToolSelector, type ToolSelectorOptions, type ToolSetFreezer, TraceCollector, type TraceEvent, type TracerLike, type TracerProviderLike, UMBRAL_LOCAL, UsageEmitter, type UsageEmitterOptions, type ValidationError, type ValidationResult, type VerificationCheck, type VerificationExclusion, type VerificationOutcome, type VerificationReport, type VerificationSettings, type VerificationSide, type VerificationStratum, adaptiveK, arithmeticResolver, buildExactKey, buildInflightKey, calibrateSemanticFloor, canonicalize, compactRowsSerializer, compactToolOutput, compresionFiel, computeNextDelay, cosine, createCompactRowsSerializer, createDefaultResolvers, createHandoff, createMockProvider, createSavingsLayer, csvSerializer, decodeCompactRows, dedupe, defaultTokenizerRegistry, deriveSeatId, deriveStatus, detectCi, embebedorLocal, emptyState, encodeCompactRows, evalArithmetic, evaluatePolicy, executeRetrievalPlan, gateFromKey, heuristicEstimator, instrumentSavingsLayer, isKeyset, isStrictCompatible, jsonCompactSerializer, keyTokensMatch, licenseKeyShape, liveGateFromKey, mergeDelta, modelFamilyOf, multisetEqual, negationCount, noopCompressor, normalizeLicenseKey, normalizeText, numericTokens, precioDeLista, projectContext, providerNativeBackend, quitarPrefijoDeProveedor, randomId, recordSavingsOnSpan, registerExactTokenizer, registrarTokenizadorExacto, renderState, resolveConstraintBackend, resolveDependencies, resolveLicense, sameAnswer, savingsSpanAttributes, sha256, shouldCompress, stableStringify, toCsv, toFocusRows, toLangfuseGeneration, toSavingsSeries, uniformColumns, validateAgainstSchema, vectorLocal, verifyCompactSignature, verifyLicenseToken, verifyRevocationList, withProtectedSpans, words };
6119
+ /**
6120
+ * bivelio-savings-layer (BV-SALA)
6121
+ * ---------------------------------------------------------------------------
6122
+ * PROPRIETARY AND CONFIDENTIAL. Copyright (c) 2026 BiVelio Inc.
6123
+ * All Rights Reserved. Unauthorized copying, distribution, or use of this
6124
+ * software, in whole or in part, is strictly prohibited. See LICENSE.
6125
+ * ---------------------------------------------------------------------------
6126
+ *
6127
+ * A provider-neutral LLM execution optimizer. For every request it answers, in
6128
+ * order: Can I avoid this call? Can I avoid retrieval? Can I send fewer tools?
6129
+ * What context is actually needed? Should I compress it? Which format costs
6130
+ * least for this tokenizer? What is the minimal output contract? Is the saving
6131
+ * still positive after all infrastructure is counted?
6132
+ *
6133
+ * It keeps FOUR separate ledgers — avoided_calls, eliminated_tokens,
6134
+ * compressed_tokens, provider_cached_tokens — because mixing them produces
6135
+ * misleading metrics.
6136
+ */
6137
+
6138
+ /**
6139
+ * The list-price catalogue: model id (without vendor prefix) → USD per 1K
6140
+ * tokens. `costModels` on the layer config always wins over it.
6141
+ */
6142
+ declare const PRICE_CATALOG: typeof CATALOGO$1;
6143
+ /**
6144
+ * The list price for a model on the day of the request, or `undefined` when the
6145
+ * catalogue has no price for it in force that day.
6146
+ */
6147
+ declare const listPrice: typeof precioDeLista$1;
6148
+ /** When the catalogue prices were last checked against the providers' public rates (YYYY-MM-DD). */
6149
+ declare const PRICES_AS_OF: typeof PRECIOS_AL_DIA$1;
6150
+ /** @deprecated Spanish name, removed in 0.5. Use {@link PRICE_CATALOG}. */
6151
+ declare const CATALOGO: typeof CATALOGO$1;
6152
+ /** @deprecated Spanish name, removed in 0.5. Use {@link listPrice}. */
6153
+ declare const precioDeLista: typeof precioDeLista$1;
6154
+ /** @deprecated Spanish name, removed in 0.5. Use {@link PRICES_AS_OF}. */
6155
+ declare const PRECIOS_AL_DIA: typeof PRECIOS_AL_DIA$1;
6156
+
6157
+ export { type AnswerJudge, type AnswerSource, type AnthropicOptions, AnthropicProvider, BV_SALA_VERSION, type BatchCounts, type BatchItemResult, type BatchJob, type BatchJobStatus, type BatchRequest, type BatchResults, BatchSubmitError, type BatchSubmitOptions, type BatchSummary, type BivelioHandoff, CATALOGO, COMPACTION_TRANSFORMS, COMPACT_ROWS_INSTRUCTION, type CacheBreakpointStore, type CacheOutcome, type CachePlacement, type CacheTier, type CacheWriteReport, type CachedAnswer, type CalibrationObservation, CalibrationStateError, type CanonicalRequest, type ChatMessage, type CompactRowsDecodeOptions, type CompactRowsOptions, type CompactVerification, type CompactionTransform, type CompressionEconomics, type CompressionPolicyInput, type CompressionRequest, type CompressionResult, type Compressor, type ConstraintBackend, type ConstraintBackendId, type ConstraintPlan, type ConversationState, type CostBasis, type CostModel, type CsvValue, DEFAULT_COST_MODEL, DEFAULT_MAX_STALENESS_SECONDS, DEFAULT_MIN_SAVED_CHARS, type DeferredExecutionReport, type DeterministicResolver, EMBEDDED_PUBLIC_KEY, type EmbeddingFn, type EvidenceDoc, type ExactCache, ExactTokenizer, type ExecutionClass, ExecutionRouter, type FocusExportOptions, type FocusRow, type FormatChoice, FormatSelector, type FormatSelectorOptions, type GoogleOptions, GoogleProvider, type GoogleThinkingConfig, type HandoffFact, HeuristicEstimator, InMemoryCacheBreakpointStore, InMemoryExactCache, InMemorySemanticCache, InMemoryToolSetFreezer, type JsonSchema, LOCAL_EMBEDDING_THRESHOLD, type LangfuseGenerationUpdate, LicenseError, type LicenseGate, type LicenseKeyShape, type LicenseKeyset, type LicenseStatus, type LicenseTokenPayload, type LocalClassifier, MODELOS_POR_CODIFICACION, MODELS_BY_ENCODING, type MeasureReport, type MemoryDelta, type MessageRole, MockProvider, type MockProviderOptions, type ModelCascadeMode, type ModelCascadeReport, type ModelCascadeSettings, type NativeSavingsReport, type OpenAICompatibleOptions, OpenAICompatibleProvider, type OutputContract, PRECIOS_AL_DIA, PRICES_AS_OF, PRICE_CATALOG, type Policy, type PriceLeverSaving, type PriceLeverSettings, type ProtectedSpan, type Provider, type ProviderRequest, type ProviderResponse, type ProviderStreamEvent, type ProviderStreamOptions, type ProviderToolSearch, type ProviderToolSearchUsage, type ProviderUsage, QUALITY_STATUSES, type QualityCacheMatch, type QualityCascadeCheck, type QualityLedger, type QualityRepairCheck, type QualitySchemaCheck, type QualityStatus, type QualityTruncationCheck, REFERENCE_MAX_AGE_MS, REFERENCE_MESSAGE_ALLOWANCE, REFERENCE_OUTPUT_SHARE, type ReasoningEffort, type ReferenceCredit, type ReferenceRejection, type RequestContext, type Reranker, type ResolvedDeps, type ResolvedGate, type ResolvedLicense, ResolverRegistry, type ResolverResult, type RetrievalOptions, type RetrievalOutcome, type RetrievalPlan, type Retriever, type RevocationListBody, type RevocationListVerification, type RevocationPollEvent, RevocationPoller, type RevocationPollerOptions, RevocationSnapshot, type RouteDecision, type SavingsAdapterLevers, type SavingsAdapterOptions, type SavingsAttributeOptions, type SavingsBatches, type SavingsCallOptions, type SavingsLayer, type SavingsLayerConfig, SavingsLedger, type SavingsRecord, type SavingsReport, type SavingsReportForExport, type SavingsRequest, type SavingsResult, type SavingsSeriesOptions, type SavingsSeriesRow, type SavingsSpanAttributes, type SavingsSpanOptions, type SavingsStream, type SavingsStreamEvent, type SavingsStreamOptions, type SavingsToggles, type SavingsTracingOptions, SchemaRegistry, type SemanticCacheOptions, type SemanticCalibrationBound, type SemanticCalibrationOptions, type SemanticCalibrationSegmentState, type SemanticCalibrationState, type SemanticCalibrationStatus, type SemanticHit, type SemanticLookup, type SemanticProbe, type SemanticRecord, type SemanticVerifier, type SerializationFormat, type Serializer, Singleflight, type SpanAttributeValue, type SpanLike, type SpanStartOptionsLike, StreamAbortedError, type StreamingReport, type TokenEstimator, TokenizerRegistry, type ToolCallRequest, type ToolDescriptor, type ToolOutputCompaction, type ToolOutputCompactionSettings, type ToolRisk, type ToolSearchMode, type ToolSearchOptions, type ToolSelection, ToolSelector, type ToolSelectorOptions, type ToolSetFreezer, TraceCollector, type TraceEvent, type TracerLike, type TracerProviderLike, UMBRAL_LOCAL, UsageEmitter, type UsageEmitterOptions, type ValidationError, type ValidationResult, type VerificationCheck, type VerificationExclusion, type VerificationOutcome, type VerificationReport, type VerificationSettings, type VerificationSide, type VerificationStratum, adaptiveK, arithmeticResolver, buildExactKey, buildInflightKey, calibrateSemanticFloor, canonicalize, compactRowsSerializer, compactToolOutput, compresionFiel, computeNextDelay, cosine, createCompactRowsSerializer, createDefaultResolvers, createHandoff, createMockProvider, createSavingsLayer, csvSerializer, decodeCompactRows, dedupe, defaultTokenizerRegistry, deriveSeatId, deriveStatus, detectCi, embebedorLocal, emptyState, encodeCompactRows, evalArithmetic, evaluatePolicy, executeRetrievalPlan, gateFromKey, heuristicEstimator, instrumentSavingsLayer, isKeyset, isStrictCompatible, jsonCompactSerializer, keyTokensMatch, licenseKeyShape, listPrice, liveGateFromKey, localEmbedding, mergeDelta, modelFamilyOf, multisetEqual, negationCount, noopCompressor, normalizeLicenseKey, normalizeText, numericTokens, precioDeLista, projectContext, providerNativeBackend, quitarPrefijoDeProveedor, randomId, recordSavingsOnSpan, registerExactTokenizer, registrarTokenizadorExacto, renderState, resolveConstraintBackend, resolveDependencies, resolveLicense, sameAnswer, savingsSpanAttributes, sha256, shouldCompress, stableStringify, toCsv, toFocusRows, toLangfuseGeneration, toSavingsSeries, uniformColumns, validateAgainstSchema, vectorLocal, verifyCompactSignature, verifyLicenseToken, verifyRevocationList, withProtectedSpans, words };