@bivelio/savings-layer 0.4.36 → 0.5.0-rc.1

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
@@ -47,12 +47,6 @@ interface CostModel {
47
47
  /** Optional discounted rate for provider-cached (prefix) input tokens. */
48
48
  cachedInputPer1k?: number;
49
49
  }
50
- /** Oldest provider counter a repeat can be valued against: one billing period. */
51
- declare const REFERENCE_MAX_AGE_MS$1: number;
52
- /** Share of the counted output credited to a repeat: only under deterministic sampling, on a catalog model that does not reason and honors it, when the call that ran carried no hidden reasoning. */
53
- declare const REFERENCE_OUTPUT_SHARE$1 = 0.95;
54
- /** Input tokens deducted per piece the layer inserted in the call that ran: a message, the wrapper around a native output schema, or half of the empty parameters given to a tool that had none. */
55
- declare const REFERENCE_MESSAGE_ALLOWANCE$1 = 8;
56
50
  /**
57
51
  * Why an avoided call (a cache or coalesced hit) could not be valued by
58
52
  * reference, and so stays `estimated`.
@@ -102,185 +96,6 @@ interface ReferenceCredit {
102
96
  /** Fraction of the standard price applied: 1, or the discounted tier the call ran on or this request declared. */
103
97
  tierFactor: number;
104
98
  }
105
- declare class SavingsLedger$1 {
106
- avoidedLlm: number;
107
- baselineLlm: number;
108
- actualLlm: number;
109
- baselineRetrieval: number;
110
- actualRetrieval: number;
111
- baselineTools: number;
112
- actualTools: number;
113
- retries: number;
114
- baselineInput: number;
115
- actualInput: number;
116
- eliminatedInput: number;
117
- compressedInput: number;
118
- baselineOutput: number;
119
- actualOutput: number;
120
- eliminatedOutput: number;
121
- providerCachedInput: number;
122
- /** Tokens the provider billed as prefix-cache writes. */
123
- cacheWriteInputTokens: number;
124
- /** The premium on those writes, already priced in USD. Adds to `actual` only. */
125
- cacheWritePremiumUsd: number;
126
- /** Provider-initiated cache-write premium, priced in USD. Adds to baseline and `actual` alike. */
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;
134
- /** Cuenta LOCAL del prompt que de verdad se envió al proveedor. */
135
- sentInputLocal: number;
136
- /** Tokens que la capa quitó de ese prompt, en cuenta LOCAL. */
137
- removedInputLocal: number;
138
- /**
139
- * Tokens (LOCAL ruler) that tool_result ELISION removed from the sent prompt.
140
- * They exist to be SUBTRACTED from `removedInputLocal`: live deletion really
141
- * lowers `sentInputLocal`, so without this correction the elision saving would
142
- * enter the reconstructed baseline and the commission, labelled "estimated".
143
- * The doctrine is the opposite — "live count, shadow money": elision is a COUNT
144
- * (ledger 2 `eliminatedInput`), its dollar is measured by the shadow lane out
145
- * of commission, and `basis` stays "measured". Deliberately distinct from the
146
- * tool-selector drop, which DOES count in the baseline (a declared tool that is
147
- * not sent is an attributable saving; a superseded tool_result is redundancy
148
- * not yet billed as verifiable against the invoice).
149
- */
150
- elididoLocal: number;
151
- /**
152
- * Tokens (LOCAL ruler) that tool-output compaction removed from the sent
153
- * prompt. Subtracted from `removedInputLocal` for the same reason as
154
- * {@link elididoLocal}: the saving is a COUNT in ledger 3 (`compressedInput`)
155
- * and never enters the reconstructed baseline or the commission, so `basis`
156
- * stays "measured" and the provider's invoice shows the effect on its own.
157
- */
158
- compactedLocal: number;
159
- /**
160
- * ¿El estimador que produjo las dos cifras anteriores cuenta con la regla del
161
- * proveedor? Lo fija el pipeline al resolver el tokenizador del modelo.
162
- * Defaults to NO: exactness is claimed only once it has been verified.
163
- */
164
- estimatorExact: boolean;
165
- /** Salida del reintento de reparación. Es coste NUESTRO, nunca del baseline. */
166
- repairOutput: number;
167
- /**
168
- * INPUT of the repair retry. Mirrors `repairOutput`.
169
- *
170
- * Both are OUR cost, never the customer's, so both are subtracted from the
171
- * reconstructed baseline. The baseline is what the naive path would have
172
- * cost; work the layer does to fix its own output has no place in it.
173
- */
174
- repairInput: number;
175
- /**
176
- * Billed provider calls in this request that came back WITHOUT a complete
177
- * usage counter (`usage.complete === false`). Any value above zero makes the
178
- * request `unmeasured`: a figure built on a missing counter is not the
179
- * provider's meter.
180
- */
181
- callsWithoutUsage: number;
182
- /**
183
- * INPUT of the schema-on-demand discovery probe. Held apart exactly like
184
- * {@link repairInput}, and for the same reason.
185
- *
186
- * The layer ADDS this call; the naive path would never make it. Letting its
187
- * tokens into the reconstructed baseline would make the probe pay for itself,
188
- * and a request that cost MORE than going without the layer would publish a
189
- * positive saving. It still counts in full towards `actualInput` — that is
190
- * money genuinely spent — it just cannot inflate what that is compared against.
191
- */
192
- discoveryInput: number;
193
- /** OUTPUT of the discovery probe. Our cost, kept out of the baseline. */
194
- discoveryOutput: number;
195
- /**
196
- * Already-priced cost of a call the model cascade made to a cheaper model
197
- * whose answer was NOT served. Added to `actual`, never to the baseline.
198
- */
199
- extraCostUsd: number;
200
- /** Input tokens of that call. Published by the pipeline, not priced here. */
201
- cascadeInput: number;
202
- /** Output tokens of that call. Published by the pipeline, not priced here. */
203
- cascadeOutput: number;
204
- /**
205
- * Record a call to the cheap model that did not produce the served answer:
206
- * the one discarded on an escalation, or a shadow-mode sample.
207
- *
208
- * The caller raises `actualLlm`, because the call happened and the report owes
209
- * the reader that count.
210
- *
211
- * @param providerWritePremium the multiplier the provider bills on its own
212
- * for the call's cache writes (`usage.cacheWriteInputTokens`); 1 = none.
213
- */
214
- cascadeAttempt(usage: {
215
- inputTokens: number;
216
- outputTokens: number;
217
- cacheWriteInputTokens?: number;
218
- }, cheapPrice: CostModel, providerWritePremium?: number): void;
219
- /** Record the premium for `tokens` of cache write billed at `multiplicador`x. */
220
- cacheWritePremium(tokens: number, multiplicador: number, precioDelQueMarco: CostModel): void;
221
- /**
222
- * Lo que de verdad hizo la compresión, para publicarlo en
223
- * `SavingsReport.compression`. El campo estaba declarado en el contrato y no lo
224
- * rellenaba nadie: salía `undefined` aunque la compresión hubiera corrido, y
225
- * `fidelityPassed` se calculaba sin llegar nunca al informe.
226
- */
227
- compressionReport: {
228
- originalTokens: number;
229
- compressedTokens: number;
230
- protectedSpans: number;
231
- fidelityPassed: boolean;
232
- } | undefined;
233
- /** Ledger 2: tokens removed because they were not needed. */
234
- eliminate(tokens: number): void;
235
- /** Ledger 3: delta between an original encoding and a cheaper one. */
236
- compress(originalTokens: number, compressedTokens: number): void;
237
- /** Ledger 4: tokens still present but billed/processed as provider-cached. */
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;
241
- /** Record the premium for `tokens` of cache write the provider bills at `multiplier`x on its own. */
242
- providerCacheWritePremium(tokens: number, multiplier: number, price: CostModel): void;
243
- /** Input tokens of calls the provider documents as not billed; already included in `actualInput`. */
244
- unbilledInput: number;
245
- /** Output tokens of those calls; already included in `actualOutput`. */
246
- unbilledOutput: number;
247
- /** Provider-cached input tokens of those calls; already included in `providerCachedInput`. */
248
- unbilledCachedInput: number;
249
- /** True when the answer served is a refusal the provider does not bill: no saving is credited. */
250
- servedUnbilledRefusal: boolean;
251
- /** Record a call the provider documents as not billed: its tokens stay counted and are priced at 0. */
252
- unbilledCall(usage: {
253
- inputTokens: number;
254
- outputTokens: number;
255
- cachedInputTokens?: number;
256
- }): void;
257
- /** Set when an avoided call is valued against the provider counter of an identical call that ran. */
258
- reference: ReferenceCredit | null;
259
- /** Set when an avoided cache or coalesced hit could not be valued by reference: why it stays estimated. */
260
- referenceRejected: ReferenceRejection | null;
261
- /** Record an avoided call valued by reference. */
262
- avoidCallByReference(credit: ReferenceCredit): void;
263
- /** Record that a whole primary LLM call was avoided (cache / resolver hit). */
264
- avoidCall(baselineInput: number, baselineOutput: number): void;
265
- /**
266
- * Baseline de salida publicable.
267
- *
268
- * En una llamada EVITADA es el de la respuesta que se habría generado. En una
269
- * que se EJECUTÓ es la salida medida menos la de la reparación — nunca el techo
270
- * `maxOutputTokens ?? 256`. estimateCost ya lo hacía por dentro, pero el
271
- * informe publicaba el techo crudo, y el proyector público lo convertía en
272
- * dólares: se anunciaba un ahorro de salida que nunca existió.
273
- */
274
- get publishedBaselineOutput(): number;
275
- estimateCost(model: CostModel): {
276
- baselineEstimate: number;
277
- actual: number;
278
- netSavings: number;
279
- netSavingsRatio: number;
280
- netSavingsUsd: number;
281
- basis: CostBasis;
282
- };
283
- }
284
99
 
285
100
  /**
286
101
  * LIST PRICES PER MODEL.
@@ -308,7 +123,7 @@ declare class SavingsLedger$1 {
308
123
  * announced price steps, cache-write premiums, tier rates). Two computations
309
124
  * citing the same version were priced with the same content.
310
125
  */
311
- declare const PRECIOS_AL_DIA$1 = "2026-09-29";
126
+ declare const PRECIOS_AL_DIA = "2026-09-29";
312
127
  /**
313
128
  * Key = the model id as the provider publishes it, without a vendor prefix.
314
129
  * Lookup tries the exact id, then the id without its provider prefix, then the
@@ -319,7 +134,7 @@ declare const PRECIOS_AL_DIA$1 = "2026-09-29";
319
134
  * provider has already announced is applied by {@link precioDeLista} from its
320
135
  * effective date, so a request is always priced at the rate of its own day.
321
136
  */
322
- declare const CATALOGO$1: Readonly<Record<string, CostModel>>;
137
+ declare const CATALOGO: Readonly<Record<string, CostModel>>;
323
138
  /**
324
139
  * The list price for a model on the day of the request, or `undefined` when
325
140
  * the catalogue has no price for it in force that day.
@@ -329,7 +144,7 @@ declare const CATALOGO$1: Readonly<Record<string, CostModel>>;
329
144
  * Prices resolve per UTC day, so a price change the provider has announced
330
145
  * applies from its effective date.
331
146
  */
332
- declare function precioDeLista$1(model: string, at?: Date | number): CostModel | undefined;
147
+ declare function precioDeLista(model: string, at?: Date | number): CostModel | undefined;
333
148
 
334
149
  /**
335
150
  * The version the SDK reports for itself.
@@ -339,17 +154,7 @@ declare function precioDeLista$1(model: string, at?: Date | number): CostModel |
339
154
  * on the customer's machine. `test/version-declarada.test.ts` ties this
340
155
  * constant to package.json so the two can never drift.
341
156
  */
342
- declare const BV_SALA_VERSION = "0.4.36";
343
-
344
- /**
345
- * Environment-agnostic UUID generation.
346
- * ---------------------------------------------------------------------------
347
- * Trace IDs only need to be unique, not cryptographically unpredictable. We
348
- * prefer the platform `crypto.randomUUID` (present in modern Node, browsers,
349
- * Deno and edge runtimes) and fall back to a v4-shaped id when it is absent, so
350
- * BV-SALA runs everywhere without a `node:crypto` import that breaks bundlers.
351
- */
352
- declare function randomId$1(): string;
157
+ declare const BV_SALA_VERSION = "0.5.0-rc.1";
353
158
 
354
159
  /** How the layer served a request that is eligible for a verification check. */
355
160
  type VerificationStratum =
@@ -429,7 +234,12 @@ interface VerificationCheck {
429
234
  * was not `missed`. Other pairs are counted and exported, but left out of every figure.
430
235
  */
431
236
  naive?: VerificationSide & {
432
- finishReason?: string;
237
+ /**
238
+ * Why the provider stopped the copy, in the same closed set as
239
+ * `SavingsResult.finishReason` (`"stop"`, `"length"`, `"tool_calls"`,
240
+ * `"content_filter"`, `"other"`), whatever the provider.
241
+ */
242
+ finishReason?: "stop" | "length" | "tool_calls" | "content_filter" | "other";
433
243
  /** Whether the copy met your output contract: `none` without a contract or on a tool-call turn. */
434
244
  contract: "met" | "missed" | "none";
435
245
  };
@@ -671,7 +481,7 @@ interface SavingsToggles {
671
481
  * `false` switches it off for this request even when the layer enables it.
672
482
  *
673
483
  * What it removes is a COUNT in `report.tokens.compressedInput`; it is never
674
- * priced into `cost.netSavings` or your commission — your provider's invoice
484
+ * priced into `cost.netSavingsRatio` or your commission — your provider's invoice
675
485
  * shows the effect.
676
486
  */
677
487
  toolOutputCompaction?: boolean;
@@ -746,7 +556,7 @@ interface SavingsToggles {
746
556
  * THE MARGIN IS NOT A GUARANTEE THAT EVERY REQUEST GETS CHEAPER. When the
747
557
  * model names no tool in the first call, the request still goes out with every
748
558
  * schema and the first call is pure added cost: that request costs MORE, and
749
- * the report says so (`cost.netSavings` goes negative). The margin required is
559
+ * the report says so (`cost.netSavingsRatio` goes negative). The margin required is
750
560
  * exactly the cost of that outcome, so the pattern breaks even while it
751
561
  * happens on at most one request in two. If your traffic asks for a tool less
752
562
  * often than that — a chat assistant with a big catalogue answers most turns
@@ -895,8 +705,6 @@ interface DeferredExecutionReport {
895
705
  * all. Present only when {@link credited}.
896
706
  */
897
707
  discountRate?: number;
898
- /** @deprecated Use `tierSaving.amount`; same value. Kept for compatibility. */
899
- estimatedTierSaving?: number;
900
708
  /**
901
709
  * What the served tier was worth on the one call whose tier was read: that call's
902
710
  * provider-reported usage at the standard rate card minus the same usage at the rate
@@ -921,7 +729,7 @@ interface DeferredExecutionReport {
921
729
  * nothing (3) and is not provider caching (4). It changes the PRICE of the
922
730
  * tokens, exactly as the model cascade does, and there is no ledger for that.
923
731
  *
924
- * `cost.netSavings` therefore does not move: it is a ratio of baseline to
732
+ * `cost.netSavingsRatio` therefore does not move: it is a ratio of baseline to
925
733
  * actual priced from a SINGLE rate card, and a discount that scales both sides
926
734
  * cannot change it. Folding this in would require a baseline priced from the
927
735
  * other card — a request nobody ran.
@@ -1061,7 +869,7 @@ interface ModelCascadeReport {
1061
869
  *
1062
870
  * A COUNTERFACTUAL: the strong model was not run, so this is priced from the
1063
871
  * measured token counts at both list prices. It is deliberately NOT part of
1064
- * `cost.netSavings` — that number stays a comparison at a single price, and
872
+ * `cost.netSavingsRatio` — that number stays a comparison at a single price, and
1065
873
  * this one would inflate it with a call nobody made. Negative on an escalated
1066
874
  * request, which is exactly what an escalation costs you.
1067
875
  */
@@ -1198,29 +1006,36 @@ interface SavingsResult<T = unknown> {
1198
1006
  */
1199
1007
  toolCalls?: ToolCallRequest[];
1200
1008
  /**
1201
- * Por qué paró de generar el modelo (`"stop"`, `"length"`, `"tool_calls"`, …).
1202
- * Presente cuando la respuesta viene del proveedor; ausente en los atajos
1203
- * (caché/resolver), que solo sirven respuestas finales completas.
1009
+ * Why the model stopped generating, the same five values for every provider:
1204
1010
  *
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.
1011
+ * - `"stop"`: a complete answer (Anthropic `end_turn` / `stop_sequence`,
1012
+ * Gemini `STOP`).
1013
+ * - `"length"`: cut off by the output limit (Anthropic `max_tokens`, Gemini
1014
+ * `MAX_TOKENS`). A truncated answer is never cached.
1015
+ * - `"tool_calls"`: the model asked to call tools (`toolCalls`).
1016
+ * - `"content_filter"`: the provider refused or filtered the answer.
1017
+ * - `"other"`: anything else (for example Anthropic `pause_turn`, Gemini
1018
+ * `MALFORMED_FUNCTION_CALL`); the provider's value is in
1019
+ * {@link finishReasonDetail}.
1020
+ *
1021
+ * Present when the answer came from the provider; absent on shortcuts (cache,
1022
+ * local resolver), which only serve complete final answers.
1210
1023
  */
1211
- finishReason?: string;
1024
+ finishReason?: "stop" | "length" | "tool_calls" | "content_filter" | "other";
1212
1025
  /**
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:
1026
+ * The provider's own reason behind `finishReason`, when it adds something.
1027
+ * Present only on answers the provider returned:
1215
1028
  *
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"`).
1029
+ * - A refusal or filter: the finer reason. Gemini's `SAFETY`, `OTHER`,
1030
+ * `PROHIBITED_CONTENT`… (native or `finish_reason: "content_filter: OTHER"`
1031
+ * on the OpenAI-compatible endpoint), its `promptFeedback.blockReason`, or
1032
+ * Anthropic's `stop_details.category` (for example `"cyber"` or `"bio"`).
1033
+ * - A stop reason that is not the provider's plain spelling of one of the
1034
+ * five values: the provider's literal (`"stop_sequence"`, `"pause_turn"`,
1035
+ * `"MALFORMED_FUNCTION_CALL"`…).
1223
1036
  *
1037
+ * Absent for the plain spellings (`stop`, `end_turn`, `STOP`, `length`,
1038
+ * `max_tokens`, `MAX_TOKENS`, `tool_calls`, `tool_use`, `content_filter`).
1224
1039
  * OpenAI's Structured Outputs refusal message travels in `refusal` instead.
1225
1040
  * Informational: it changes neither what is billed nor what is credited.
1226
1041
  */
@@ -1419,15 +1234,11 @@ interface QualityTruncationCheck {
1419
1234
  /** True when the provider reported `finishReason: "length"`. A truncated answer is never cached. */
1420
1235
  truncated: boolean;
1421
1236
  /**
1422
- * Why the provider stopped, as `SavingsResult.finishReason` reports it;
1423
- * absent when it reported none.
1424
- *
1425
- * In 0.5 this becomes the same CLOSED set as `SavingsResult.finishReason` —
1426
- * `"stop"`, `"length"`, `"tool_calls"`, `"content_filter"` or `"other"` — and
1427
- * the provider's own value moves to {@link finishReasonDetail}. Compare
1428
- * against those five values only; see the 0.5 migration guide.
1237
+ * Why the provider stopped, as `SavingsResult.finishReason` reports it (the
1238
+ * same five values); absent when it reported none. The provider's own value
1239
+ * is in {@link finishReasonDetail}.
1429
1240
  */
1430
- finishReason?: string;
1241
+ finishReason?: "stop" | "length" | "tool_calls" | "content_filter" | "other";
1431
1242
  /**
1432
1243
  * The provider's own reason behind `finishReason`, when it gave one: the same
1433
1244
  * value as `SavingsResult.finishReasonDetail` for the answer that was served.
@@ -1561,7 +1372,7 @@ interface QualityLedger {
1561
1372
  * `cache_control`), route (OpenAI `prompt_cache_key`) or keep the prefix
1562
1373
  * stable, but the discount is billed by the provider and much of it would be
1563
1374
  * there without the layer, so it is never credited as the layer's saving:
1564
- * it is not in `cost.netSavings`, not in `cost.baselineEstimate`, and not in
1375
+ * it is not in `cost.netSavingsRatio`, not in `cost.baselineEstimate`, and not in
1565
1376
  * any commission base.
1566
1377
  */
1567
1378
  interface NativeSavingsReport {
@@ -1728,7 +1539,7 @@ interface SavingsReport {
1728
1539
  * The provider's OWN prompt-cache discount on this call, shown apart. Present
1729
1540
  * only when a call ran and the provider reported cache reads or writes.
1730
1541
  *
1731
- * It is not the layer's saving and it is never part of `cost.netSavings`,
1542
+ * It is not the layer's saving and it is never part of `cost.netSavingsRatio`,
1732
1543
  * `cost.baselineEstimate`, `basis: "reference"` or the commission base: the
1733
1544
  * discount is the provider's, and `cost` prices cached tokens at the cached
1734
1545
  * rate on both sides for exactly that reason. It exists so the report adds up
@@ -1758,16 +1569,6 @@ interface SavingsReport {
1758
1569
  cost: {
1759
1570
  baselineEstimate: number;
1760
1571
  actual: number;
1761
- /**
1762
- * A RATIO, not money: `1 - actual / baselineEstimate`, rounded to six
1763
- * decimals (0 when nothing was saved, negative when the request cost more).
1764
- * Do not sum it across requests: it is a ratio, not dollars.
1765
- *
1766
- * @deprecated Since 0.4.33, read {@link netSavingsRatio} (the same value) or
1767
- * {@link netSavingsUsd} (the saving in USD). Removed in 0.5: see the 0.5
1768
- * migration guide.
1769
- */
1770
- netSavings: number;
1771
1572
  /**
1772
1573
  * The saving as a RATIO of the baseline: `1 - actual / baselineEstimate`,
1773
1574
  * rounded to six decimals (0 when nothing was saved or there is no baseline,
@@ -1909,7 +1710,7 @@ interface LicenseGate {
1909
1710
  * went to your provider untouched and nothing was served from a cache.
1910
1711
  *
1911
1712
  * Every figure is HYPOTHETICAL (`basis: "shadow"`): it is never part of
1912
- * `cost.baselineEstimate`, `cost.actual` or `cost.netSavings`, never in any
1713
+ * `cost.baselineEstimate`, `cost.actual` or `cost.netSavingsRatio`, never in any
1913
1714
  * commission base, and never added to measured money.
1914
1715
  */
1915
1716
  interface MeasureReport {
@@ -2105,7 +1906,7 @@ declare class InMemoryExactCache implements ExactCache {
2105
1906
  * requests that mean the same thing must canonicalize identically, and two
2106
1907
  * requests that differ in any way that could change the answer must not.
2107
1908
  */
2108
- interface CanonicalRequest$1 {
1909
+ interface CanonicalRequest {
2109
1910
  model: string;
2110
1911
  modelFamily: string;
2111
1912
  messages: ChatMessage[];
@@ -2162,27 +1963,6 @@ interface CanonicalRequest$1 {
2162
1963
  tokenizer: string | undefined;
2163
1964
  original: SavingsRequest;
2164
1965
  }
2165
- /**
2166
- * Normalized form of a turn's text, as it enters the cache key.
2167
- *
2168
- * Folded away: Unicode form, case, whitespace, typographic marks, Latin
2169
- * diacritics and sentence punctuation. Preserved exactly: numbers, decimal and
2170
- * thousands separators, times, dates, units, negations, math operators and any
2171
- * combining mark outside the Latin alphabet.
2172
- */
2173
- declare function normalizeText$1(text: string): string;
2174
- declare function sha256$1(input: string): string;
2175
- /** Stable JSON stringify with sorted keys so hashes are order-independent. */
2176
- declare function stableStringify$1(value: unknown): string;
2177
- /**
2178
- * The version-and-size-independent family of a model id.
2179
- *
2180
- * Exported because the cache key is now built for the model that will actually
2181
- * ANSWER, which is not always the one the caller named. Deriving the family a
2182
- * second time somewhere else is how two rulers start to disagree.
2183
- */
2184
- declare function modelFamilyOf$1(model: string): string;
2185
- declare function canonicalize$1(request: SavingsRequest): CanonicalRequest$1;
2186
1966
 
2187
1967
  /**
2188
1968
  * Thrown by `importCalibration` / `exportCalibration` when a calibration state
@@ -2335,8 +2115,6 @@ interface SemanticCalibrationStatus {
2335
2115
  /** Online only: the label count at which the floor is re-tested next. Each test comes when the labels have grown by half. */
2336
2116
  nextTestAt?: number;
2337
2117
  }
2338
- /** Default {@link AnswerJudge}: the stored answer counts as right only if it is the same answer. */
2339
- declare function sameAnswer$1(stored: CachedAnswer, fresh: CachedAnswer): boolean;
2340
2118
  /**
2341
2119
  * Certifies an acceptance floor from labels you already have (your own traffic,
2342
2120
  * or a labeled set scored with your embedder), with the same test the cache
@@ -2474,7 +2252,7 @@ interface SemanticLookup {
2474
2252
  }
2475
2253
  interface SemanticCacheOptions {
2476
2254
  /**
2477
- * How text becomes a vector. OPTIONAL: omit it and {@link embebedorLocal} is
2255
+ * How text becomes a vector. OPTIONAL: omit it and {@link localEmbedding} is
2478
2256
  * used — no network, no API key, no per-call cost.
2479
2257
  *
2480
2258
  * It used to be required, and the package shipped NO implementation, so this
@@ -2517,13 +2295,6 @@ interface SemanticCacheOptions {
2517
2295
  */
2518
2296
  calibration?: SemanticCalibrationOptions;
2519
2297
  }
2520
- declare function cosine$1(a: number[], b: number[]): number;
2521
- declare function numericTokens$1(s: string): string[];
2522
- declare function multisetEqual$1(a: string[], b: string[]): boolean;
2523
- declare function words$1(s: string): string[];
2524
- declare function negationCount$1(tokens: string[]): number;
2525
- /** True when two normalized queries agree on the facts an embedding tends to blur. */
2526
- declare function keyTokensMatch$1(a: string, b: string): boolean;
2527
2298
  /**
2528
2299
  * In-memory reference implementation. A production build would back this with a
2529
2300
  * real vector store and metadata filters pushed down
@@ -2557,7 +2328,7 @@ declare class InMemorySemanticCache {
2557
2328
  * and labels nothing: without {@link lookup} and {@link observe} (the layer
2558
2329
  * calls both) the calibration never gets a label and never certifies.
2559
2330
  */
2560
- find(c: CanonicalRequest$1): Promise<SemanticHit | null>;
2331
+ find(c: CanonicalRequest): Promise<SemanticHit | null>;
2561
2332
  /**
2562
2333
  * The best candidate that passes every hard filter, the similarity floor and
2563
2334
  * the fact guard. With `conAceptacion`, also the confidence floor (the path
@@ -2572,7 +2343,7 @@ declare class InMemorySemanticCache {
2572
2343
  * `agentic` picks the traffic segment: calibrations are kept apart for
2573
2344
  * single-shot and agentic requests.
2574
2345
  */
2575
- lookup(c: CanonicalRequest$1, opts?: {
2346
+ lookup(c: CanonicalRequest, opts?: {
2576
2347
  agentic?: boolean;
2577
2348
  }): Promise<SemanticLookup>;
2578
2349
  /**
@@ -2620,7 +2391,7 @@ declare class InMemorySemanticCache {
2620
2391
  importCalibration(state: SemanticCalibrationState | string | unknown): void;
2621
2392
  private identidad;
2622
2393
  private estadoDe;
2623
- store(c: CanonicalRequest$1, answer: CachedAnswer): Promise<void>;
2394
+ store(c: CanonicalRequest, answer: CachedAnswer): Promise<void>;
2624
2395
  /** Drop every record for a knowledge epoch (invalidation on re-index). */
2625
2396
  invalidateEpoch(knowledgeEpoch: string): number;
2626
2397
  get size(): number;
@@ -2723,12 +2494,12 @@ interface ResolverResult {
2723
2494
  }
2724
2495
  interface DeterministicResolver {
2725
2496
  readonly name: string;
2726
- try(c: CanonicalRequest$1): ResolverResult | null;
2497
+ try(c: CanonicalRequest): ResolverResult | null;
2727
2498
  }
2728
2499
  declare class ResolverRegistry {
2729
2500
  private readonly resolvers;
2730
2501
  register(resolver: DeterministicResolver): this;
2731
- try(c: CanonicalRequest$1): ResolverResult | null;
2502
+ try(c: CanonicalRequest): ResolverResult | null;
2732
2503
  get size(): number;
2733
2504
  }
2734
2505
  /**
@@ -2737,8 +2508,6 @@ declare class ResolverRegistry {
2737
2508
  * decimals. It never uses eval, and declines anything it does not fully parse.
2738
2509
  */
2739
2510
  declare const arithmeticResolver: DeterministicResolver;
2740
- /** Shunting-yard evaluation of a numeric expression. Returns null on any parse issue. */
2741
- declare function evalArithmetic$1(expr: string): number | null;
2742
2511
  /** A registry seeded with the built-in safe resolvers. */
2743
2512
  declare function createDefaultResolvers(): ResolverRegistry;
2744
2513
 
@@ -2779,7 +2548,7 @@ declare class ExecutionRouter {
2779
2548
  classifier?: LocalClassifier;
2780
2549
  maxRounds?: number;
2781
2550
  });
2782
- classify(c: CanonicalRequest$1): RouteDecision;
2551
+ classify(c: CanonicalRequest): RouteDecision;
2783
2552
  }
2784
2553
 
2785
2554
  /**
@@ -3005,14 +2774,6 @@ interface ConstraintPlan {
3005
2774
  backend: ConstraintBackendId;
3006
2775
  reason: string;
3007
2776
  }
3008
- /**
3009
- * Resolve a constraint backend from an ordered preference list. Each candidate
3010
- * declares whether it supports the (model, schema) pair; the first supporting
3011
- * backend wins. A conformance suite (see benchmarks/) must confirm that a
3012
- * backend which *claims* support actually enforces every constraint — declared
3013
- * support and empirical coverage are not the same thing.
3014
- */
3015
- declare function resolveConstraintBackend$1(model: string, schema: JsonSchema, backends: ConstraintBackend[]): ConstraintPlan;
3016
2777
  /** A permissive backend used when the provider validates structured output natively. */
3017
2778
  declare function providerNativeBackend(isSupported?: (model: string, schema: JsonSchema) => boolean): ConstraintBackend;
3018
2779
 
@@ -3068,33 +2829,8 @@ interface CompressionPolicyInput {
3068
2829
  /** Do not compress contexts smaller than this. */
3069
2830
  minimumContextTokens?: number;
3070
2831
  }
3071
- /**
3072
- * Decide whether compression is net-positive:
3073
- * benefit = eliminable - compressorCost - latencyPenalty - qualityRisk
3074
- * Here we model the token side; latency/quality penalties are folded into
3075
- * `compressorCostTokens` and `minimumNetTokens` by the caller.
3076
- */
3077
- declare function shouldCompress$1(input: CompressionPolicyInput): {
3078
- compress: boolean;
3079
- reason: string;
3080
- };
3081
- /**
3082
- * Protected-span aware wrapper. Extracts protected spans (replacing them with
3083
- * stable placeholders), runs the inner compressor on the remainder, restores
3084
- * the spans, and verifies every one survived. On any fidelity failure it falls
3085
- * back to the ORIGINAL text — a compressor that drops a negation or a number is
3086
- * worse than no compressor at all.
3087
- */
3088
- declare function withProtectedSpans$1(inner: Compressor): Compressor;
3089
2832
  /** No-op compressor: the safe default until a real compressor sidecar is wired in. */
3090
2833
  declare const noopCompressor: Compressor;
3091
- /**
3092
- * Did the compression keep the facts that must not change? Verifies the RESULT —
3093
- * number/date multiset and negation parity — not the compressor's own claim.
3094
- *
3095
- * @deprecated Internal check of the compression stage; leaves the public API in 0.5.
3096
- */
3097
- declare function compresionFiel(original: string, comprimido: string): boolean;
3098
2834
 
3099
2835
  /** A deterministic, content-only transformation applied to a tool output. */
3100
2836
  type CompactionTransform = "ansi" | "carriage-return" | "json" | "repeated-lines";
@@ -3245,25 +2981,6 @@ interface RetrievalOutcome {
3245
2981
  retrievedCount: number;
3246
2982
  keptCount: number;
3247
2983
  }
3248
- /** Remove exact and near-duplicate docs by normalized text / hash. */
3249
- declare function dedupe$1(docs: EvidenceDoc[]): EvidenceDoc[];
3250
- /**
3251
- * Adaptive-k: choose how many documents to keep based on the score distribution
3252
- * rather than a fixed cutoff. When the top document dominates, keep fewer; when
3253
- * scores are flat, keep up to the cap. This directly trims input tokens.
3254
- */
3255
- declare function adaptiveK$1(docs: EvidenceDoc[], opts?: {
3256
- maxDocuments: number;
3257
- minDocuments?: number;
3258
- }): EvidenceDoc[];
3259
- /**
3260
- * Execute a retrieval plan. NO_RETRIEVAL / TOOL_ACTION classes retrieve nothing.
3261
- * Otherwise: retrieve -> dedupe -> rerank -> adaptive-k, bounded by maxRounds.
3262
- */
3263
- declare function executeRetrievalPlan$1(plan: RetrievalPlan, deps: {
3264
- retriever?: Retriever;
3265
- reranker?: Reranker;
3266
- }): Promise<RetrievalOutcome>;
3267
2984
 
3268
2985
  /**
3269
2986
  * Provider-neutral generation interface. Every provider (OpenAI-compatible,
@@ -3465,8 +3182,13 @@ interface ProviderResponse {
3465
3182
  * valida, y reintentar con el MISMO tope vuelve a truncarlo — se paga una
3466
3183
  * segunda llamada para obtener el mismo fallo. Sin este campo el layer no
3467
3184
  * podía distinguirlo y hacía exactamente eso.
3185
+ *
3186
+ * A custom provider may return any string here; the layer normalizes it to
3187
+ * `SavingsResult.finishReason`'s five values (`"stop"`, `"length"`,
3188
+ * `"tool_calls"`, `"content_filter"`, `"other"`) and keeps the original in
3189
+ * `finishReasonDetail` when it is not one of them.
3468
3190
  */
3469
- finishReason?: "stop" | "length" | "content_filter" | "tool_calls" | (string & {});
3191
+ finishReason?: "stop" | "length" | "content_filter" | "tool_calls" | "other" | (string & {});
3470
3192
  /**
3471
3193
  * The provider's own reason behind `finishReason`, when it gave one: Gemini's
3472
3194
  * OpenAI-compatible endpoint stops a filtered answer with
@@ -3596,73 +3318,6 @@ interface Provider {
3596
3318
  generateStream?(req: ProviderRequest, options?: ProviderStreamOptions): AsyncIterable<ProviderStreamEvent>;
3597
3319
  }
3598
3320
 
3599
- /**
3600
- * Offline license verification for the paid SDK.
3601
- *
3602
- * A license is a compact signed token `base64url(header).base64url(payload).
3603
- * base64url(sig)`, the exact format BiVelio's licensing service mints. We verify
3604
- * the Ed25519 signature against BiVelio's public key, decode the payload, and
3605
- * apply the same grace policy the issuer applies. Verification is
3606
- * **browser-safe**: it uses
3607
- * `@noble/curves` (pure JS) + Web primitives (`atob`, `TextEncoder`) rather than
3608
- * `node:crypto`, so the shared entry point still compiles into the browser
3609
- * demo bundle. The private signing key never leaves the control plane; only the
3610
- * public key is embedded here, so a token cannot be forged or tampered with.
3611
- */
3612
- /**
3613
- * `stale` NO es una licencia caducada: es una licencia PAGADA Y VIGENTE que no ha
3614
- * podido confirmar su estado contra el control plane dentro de la ventana de
3615
- * frescura — típicamente porque la salida de red está bloqueada.
3616
- *
3617
- * Existe porque antes ese caso reutilizaba `expired` "para que el union y todos
3618
- * los consumidores siguieran igual", y el ahorro de tipo se pagaba con el peor
3619
- * mensaje posible del producto: a un cliente al día, cuyo único problema era un
3620
- * cortafuegos, se le decía *"license is not active (expired). Renew your
3621
- * subscription"*. Le mandábamos a pagar otra vez algo que ya había pagado, y a
3622
- * mirar donde no estaba el problema.
3623
- *
3624
- * El comportamiento no cambia —sigue siendo fail-closed, `granted()` no lo
3625
- * concede— pero ahora el mensaje puede decir la verdad.
3626
- *
3627
- * `none` means "there is no key": what is left after `normalizeLicenseKey` is
3628
- * EMPTY. It is the same value `LicenseError.status` already carries when nothing
3629
- * was configured, because it is the same problem with the same fix: a
3630
- * `licenseKey: " "` (an empty environment variable, a blank secret file) used
3631
- * to tell the customer their key "does not verify" — there was no key.
3632
- */
3633
- type LicenseStatus$1 = "active" | "grace" | "expired" | "invalid" | "revoked" | "stale" | "none";
3634
- /** Decoded license token body (mirror of `@bivelio/protocol`'s LicensePayload,
3635
- * declared locally so the SDK stays free of a control-plane dependency). */
3636
- interface LicenseTokenPayload$1 {
3637
- jti: string;
3638
- org_id: string;
3639
- plan: string;
3640
- seats: number;
3641
- features: string[];
3642
- issued_at: number;
3643
- expires_at: number;
3644
- grace_days: number;
3645
- iss?: string;
3646
- /** Measure licenses only: the REAL term (see `vigenciaEfectiva` in ./vigencia.ts). */
3647
- measure_expires_at?: number;
3648
- measure_grace_days?: number;
3649
- }
3650
- interface ResolvedLicense$1 {
3651
- status: LicenseStatus$1;
3652
- payload?: LicenseTokenPayload$1;
3653
- reason?: string;
3654
- }
3655
- declare const EMBEDDED_PUBLIC_KEY$1: string;
3656
- /** Result of verifying a compact `head.body.sig` token's signature. */
3657
- interface CompactVerification$1 {
3658
- /** True only if the signature is valid for the given public key. */
3659
- ok: boolean;
3660
- /** Decoded header (present when `ok`), e.g. `{ alg, typ, v }`. */
3661
- header?: Record<string, unknown>;
3662
- /** Raw payload bytes (present when `ok`); the caller decodes/parses them. */
3663
- payloadBytes?: Uint8Array;
3664
- reason?: string;
3665
- }
3666
3321
  /**
3667
3322
  * A pinned set of Ed25519 public keys addressed by key-id (`kid`), enabling signing
3668
3323
  * key ROTATION without breaking already-deployed SDKs: new keys are added as extra
@@ -3676,100 +3331,6 @@ interface LicenseKeyset {
3676
3331
  /** kid used for tokens without a `kid` header (the current/legacy key). */
3677
3332
  defaultKid: string;
3678
3333
  }
3679
- /** Narrow a verification key to a {@link LicenseKeyset} (vs a bare SPKI PEM string). */
3680
- declare function isKeyset$1(k: string | LicenseKeyset): k is LicenseKeyset;
3681
- /**
3682
- * Normalize a license key the way it arrives from the real world — ONCE, at the
3683
- * entry point, never inside the verifier.
3684
- *
3685
- * The README says `export BIVELIO_LICENSE_KEY=…` and dotenv trims, so that path
3686
- * never showed it. But anyone reading the key from a file (`readFileSync`), from
3687
- * a Docker/Kubernetes secret (mounted as a file, trailing newline included) or
3688
- * copying it out of an `Authorization` header handed over a CORRECT key with a
3689
- * `\n` after it, a space before it, quotes around it or a `Bearer ` in front —
3690
- * and the SDK answered "does not verify, check you pasted the WHOLE key". A
3691
- * wrong diagnosis on a good key is the worst possible hint: it sends the
3692
- * customer to look where the problem is not.
3693
- *
3694
- * Worse, it was INCONSISTENT: `tok + "\r\n"` passed and `tok + "\n"` did not,
3695
- * because `atob` ignores ASCII whitespace while the padding was computed from a
3696
- * length that included it, and two extra characters give the same remainder
3697
- * modulo 4 as zero. Behavior that depends on which editor saved the file is not
3698
- * behavior.
3699
- *
3700
- * Only OUTER wrapping is removed — whitespace, one pair of single or double
3701
- * quotes, a `Bearer` prefix in any capitalization — in that order, in one pass.
3702
- * Anything INSIDE the key is left alone: an interior space is not wrapping, it
3703
- * is a broken key, and {@link licenseKeyShape} reports it as `malformed`.
3704
- */
3705
- declare function normalizeLicenseKey$1(raw: string): string;
3706
- /**
3707
- * The SHAPE of an already-normalized key, so the error message can tell apart
3708
- * three problems that used to get the same text:
3709
- *
3710
- * · `empty` — there is no key (only whitespace, or nothing at all).
3711
- * · `malformed` — not even the shape of a token: not three dot-separated
3712
- * base64url segments. This is where the `bvk_` service key
3713
- * pasted where the license goes lands, as does arbitrary text
3714
- * or a token with a line break in the middle.
3715
- * · `token` — has the shape; whether it verifies is up to the signature.
3716
- *
3717
- * It is the SAME shape rule {@link verifyCompactSignature} enforces, so that "has
3718
- * the shape" and "verification was attempted" mean the same thing.
3719
- */
3720
- type LicenseKeyShape$1 = "empty" | "malformed" | "token";
3721
- /** Classify a normalized key. See {@link LicenseKeyShape}. */
3722
- declare function licenseKeyShape$1(normalizedKey: string): LicenseKeyShape$1;
3723
- /**
3724
- * Verify the Ed25519 signature of any BV-SALA compact token
3725
- * (`base64url(header).base64url(body).base64url(sig)`, sig over `${head}.${body}`)
3726
- * and return the decoded header + raw payload bytes. This is the single shared
3727
- * crypto primitive: license tokens AND signed revocation lists both go through it,
3728
- * so the browser (`@noble/curves`) and node (`node:crypto`) sides agree byte-for-byte
3729
- * and there is no bespoke per-message verification path to keep in sync. It does NOT
3730
- * interpret the payload or the header `typ` — callers do that.
3731
- *
3732
- * Shape is checked SEGMENT by segment, not just by counting dots. Three parts
3733
- * used to be enough and the rest was left to `atob`, which ignores whitespace:
3734
- * that is how a token with `\r\n` after it verified while the same token with
3735
- * `\n` did not (see {@link normalizeLicenseKey}). The shared primitive must give
3736
- * the same answer to the same input, always; a caller that wants to tolerate
3737
- * wrapping normalizes BEFORE calling.
3738
- */
3739
- declare function verifyCompactSignature$1(token: string, publicKey: string | LicenseKeyset): CompactVerification$1;
3740
- /** Verify a token's signature and decode its payload. Does not check expiry. */
3741
- declare function verifyLicenseToken$1(token: string, publicKey: string | LicenseKeyset): {
3742
- signatureValid: boolean;
3743
- payload?: LicenseTokenPayload$1;
3744
- reason?: string;
3745
- };
3746
- /**
3747
- * Apply the grace + revocation policy to an already-decoded payload → a status.
3748
- * Pure and clock-injected, so a LIVE gate can call it on every request to pick up
3749
- * both revocation (jti in the set) AND expiry transitions without re-verifying the
3750
- * signature. Revocation takes precedence over the time-based status.
3751
- * jti on the revocation set → revoked
3752
- * now <= expires_at → active
3753
- * expires_at < now <= +grace_days → grace (still entitled)
3754
- * now > expires_at + grace_days → expired
3755
- */
3756
- declare function deriveStatus$1(payload: {
3757
- jti: string;
3758
- expires_at: number;
3759
- grace_days: number;
3760
- }, nowSeconds: number, revoked?: ReadonlySet<string>): LicenseStatus$1;
3761
- /**
3762
- * Verify + apply the grace policy → a resolved status. Mirrors what the issuing
3763
- * control plane resolves for the same token. Bad signature / malformed
3764
- * → invalid; otherwise the status comes from {@link deriveStatus}.
3765
- *
3766
- * A public entry point, so it normalizes like the others (gate and refresher):
3767
- * the same key must resolve the same whichever way it comes in.
3768
- */
3769
- declare function resolveLicense$1(token: string, publicKey: string | LicenseKeyset, opts?: {
3770
- nowSeconds?: number;
3771
- revoked?: ReadonlySet<string>;
3772
- }): ResolvedLicense$1;
3773
3334
 
3774
3335
  /**
3775
3336
  * Everything the pipeline depends on. All fields except `provider` and
@@ -3801,20 +3362,11 @@ interface SavingsLayerConfig {
3801
3362
  * asks for it nor turns it off gets a one-time console warning (silenced by
3802
3363
  * `silenceWarnings`, or by setting `semanticCacheDefault`, `false` included).
3803
3364
  *
3804
- * Called `semanticCache` until 0.4.33, so that the store and the per-request
3805
- * switch (`savings.semanticCache`) no longer share a name. See the 0.5
3806
- * migration guide.
3365
+ * Called `semanticCache` up to 0.4.x; renamed in 0.5 so that the store and
3366
+ * the per-request switch (`savings.semanticCache`) no longer share a name.
3367
+ * See the 0.5 migration guide.
3807
3368
  */
3808
3369
  semanticCacheStore?: InMemorySemanticCache;
3809
- /**
3810
- * @deprecated Renamed {@link semanticCacheStore} in 0.4.33, so that the store
3811
- * and the per-request switch (`savings.semanticCache`) no longer share a name.
3812
- * It still works, with a one-time warning (silenced by `silenceWarnings` or
3813
- * `BVSALA_SILENCE_DEPRECATIONS=1`);
3814
- * when both are given, `semanticCacheStore` wins. Removed in 0.5: see the 0.5
3815
- * migration guide.
3816
- */
3817
- semanticCache?: InMemorySemanticCache;
3818
3370
  /**
3819
3371
  * Default for `savings.semanticCache` on every request of this layer. A
3820
3372
  * request's own value always wins, `false` included. Unset, the semantic cache
@@ -3926,8 +3478,7 @@ interface SavingsLayerConfig {
3926
3478
  /**
3927
3479
  * Signed BiVelio license token (from your paid subscription). This is the
3928
3480
  * primary way to license the SDK: `createSavingsLayer` verifies it offline
3929
- * against the embedded public key and builds a {@link licenseGate} from it.
3930
- * Without a valid, active license (and without {@link devUnlicensed}), the
3481
+ * against the embedded public key. Without a valid, active license the
3931
3482
  * pipeline refuses to run — get a key at https://savings.bivelio.com.
3932
3483
  *
3933
3484
  * Surrounding whitespace (the trailing newline of a file or mounted secret),
@@ -3937,32 +3488,7 @@ interface SavingsLayerConfig {
3937
3488
  */
3938
3489
  licenseKey?: string;
3939
3490
  /**
3940
- * Override the public key used to verify {@link licenseKey}. An SPKI PEM string,
3941
- * or a kid-addressed {@link LicenseKeyset} (`{ keys: {kid: pem}, defaultKid }`)
3942
- * to support signing-key rotation — legacy no-kid tokens use `defaultKid`, and
3943
- * an unknown kid fails closed. For self-hosting/self-testing; defaults to the
3944
- * build-embedded BiVelio key.
3945
- *
3946
- * @deprecated Has no effect in the published package, which always verifies
3947
- * against the embedded BiVelio key; passing it there logs a one-time warning
3948
- * (silenced by `silenceWarnings` or `BVSALA_SILENCE_DEPRECATIONS=1`). Removed
3949
- * from the public type in 0.5: delete it from your config.
3950
- */
3951
- licensePublicKey?: string | LicenseKeyset;
3952
- /**
3953
- * Pre-built license gate. **Ignored in the published npm package**, where a
3954
- * {@link licenseKey} verified against the embedded BiVelio public key is the
3955
- * only accepted license — passing a gate there logs a warning and changes
3956
- * nothing. It exists for builds from source (this repo's own tests and
3957
- * benchmarks), where it takes precedence over {@link licenseKey}.
3958
- *
3959
- * @deprecated Ignored in the published package. Removed from the public type
3960
- * in 0.5; license the layer with {@link licenseKey} or `serviceAccountKey`.
3961
- */
3962
- licenseGate?: LicenseGate;
3963
- /**
3964
- * OPT-IN online revocation call-home. When set (alongside {@link licenseKey} and
3965
- * with no explicit {@link licenseGate}), the SDK polls this base's
3491
+ * OPT-IN online revocation call-home. When set (alongside {@link licenseKey}), the SDK polls this base's
3966
3492
  * `GET /licenses/revocations` for a signed revocation list and enforces it via a
3967
3493
  * LIVE gate — a license cancelled mid-term stops working without a restart.
3968
3494
  *
@@ -4067,20 +3593,6 @@ interface SavingsLayerConfig {
4067
3593
  };
4068
3594
  /** Opt-in A/B verification on your own traffic. Off by default. See VerificationSettings. */
4069
3595
  verification?: VerificationSettings;
4070
- /**
4071
- * Development-only escape hatch to run ungated, honored ONLY when building from
4072
- * source (local dev, CI, benchmarks) — also via the `BVSALA_DEV_OPEN=1`
4073
- * environment variable.
4074
- *
4075
- * IMPORTANT: this flag is **disabled in the published npm package**. The
4076
- * distributed build hard-codes the licensing check on, so setting
4077
- * `devUnlicensed` (or `BVSALA_DEV_OPEN`) there has NO effect — the layer still
4078
- * requires a valid `licenseKey`. It is not a way to run the product for free.
4079
- *
4080
- * @deprecated No effect in the published package. Removed from the public type
4081
- * in 0.5: delete it from your config.
4082
- */
4083
- devUnlicensed?: boolean;
4084
3596
  /** Per-model cost models; falls back to `defaultCostModel`. */
4085
3597
  costModels?: Record<string, CostModel>;
4086
3598
  defaultCostModel?: CostModel;
@@ -4379,7 +3891,22 @@ interface BatchItemResult<T = unknown> {
4379
3891
  /** Whether the answer met the output contract, when the request had one and no tool was called. */
4380
3892
  contract?: "met" | "missed";
4381
3893
  toolCalls?: ToolCallRequest[];
4382
- finishReason?: string;
3894
+ /**
3895
+ * Why the provider stopped, as `SavingsResult.finishReason` reports it:
3896
+ * one of the same five values for every provider (`"stop"`, `"length"`,
3897
+ * `"tool_calls"`, `"content_filter"`, `"other"`). A `"length"` answer was cut
3898
+ * off by the output limit. The provider's own value, when it adds something,
3899
+ * is in {@link finishReasonDetail}.
3900
+ */
3901
+ finishReason?: "stop" | "length" | "tool_calls" | "content_filter" | "other";
3902
+ /**
3903
+ * The provider's own reason behind `finishReason`, with the same rule as
3904
+ * `SavingsResult.finishReasonDetail`: the refusal category or the
3905
+ * provider's literal (`"stop_sequence"`, `"model_context_window_exceeded"`,
3906
+ * `"pause_turn"`…), absent for the plain spellings (`end_turn`, `stop`,
3907
+ * `max_tokens`, `tool_use`…).
3908
+ */
3909
+ finishReasonDetail?: string;
4383
3910
  /** The provider's own counter for this request. */
4384
3911
  usage?: ProviderUsage;
4385
3912
  /** The processing tier this result was billed at, as read from the provider. */
@@ -4514,81 +4041,6 @@ declare function registerExactTokenizer(registro: {
4514
4041
  }, opciones?: {
4515
4042
  codificaciones?: readonly string[];
4516
4043
  }): Promise<boolean>;
4517
- /**
4518
- * @deprecated Spanish-named aliases kept for one minor version. Use
4519
- * {@link MODELS_BY_ENCODING} and {@link registerExactTokenizer}. The public
4520
- * surface of this package is English-only; these leaked and are on the way out.
4521
- */
4522
- declare const MODELOS_POR_CODIFICACION: Readonly<Record<string, readonly string[]>>;
4523
- /** @deprecated Use {@link registerExactTokenizer}. */
4524
- declare const registrarTokenizadorExacto: typeof registerExactTokenizer;
4525
-
4526
- /**
4527
- * Exact-cache key.
4528
- *
4529
- * A hash of the user text alone is NOT a safe cache key. Two requests may share
4530
- * text but differ in tenant, permission scope, model version, system prompt,
4531
- * schema, toolset, tool-loop fields (tool calls, the call a tool result answers,
4532
- * its error flag), locale, sampling, knowledge epoch or safety policy — any of
4533
- * which can change the correct answer. The exact key includes all of them.
4534
- *
4535
- * `servedModel` CARRIES THE MODEL THAT WILL ACTUALLY ANSWER, not the one the
4536
- * caller named, and that distinction is what stops the model cascade from
4537
- * poisoning the cache. Routing to a cheap model and storing its answer under the
4538
- * STRONG model's key would hand that answer to the next request — one with the
4539
- * cascade off, or from another process entirely — while the report claims the
4540
- * requested model served it. That is a silent model swap, deferred, which is the
4541
- * worst kind of silent model swap.
4542
- *
4543
- * `modelFamily` is derived from whichever id is used, for the same reason: it is
4544
- * part of the identity of whoever answers.
4545
- */
4546
- declare function buildExactKey$1(c: CanonicalRequest$1, opciones?: {
4547
- servedModel?: string;
4548
- }): string;
4549
- /**
4550
- * In-flight (singleflight) key. Coalesces concurrent, equivalent requests onto
4551
- * a single execution. It can be slightly looser than the exact key (it does not
4552
- * need freshness bucketing, since the work is happening *now*), but must still
4553
- * isolate tenants and permissions.
4554
- *
4555
- * `schema` is REQUIRED here, even though `contract` is already part of the key:
4556
- * two concurrent calls that differ only in `schemaVersion` are different
4557
- * requests and must never coalesce. All three doors — exact key, in-flight key
4558
- * and semantic filter — key on the same identity, by design.
4559
- *
4560
- * `servedModel` CARRIES THE MODEL THAT WILL ACTUALLY ANSWER, for the same reason
4561
- * {@link buildExactKey} does, and this door is the one that leaks FIRST. The
4562
- * exact key protects the answer AFTER it is stored; this one protects it while
4563
- * it is still being written, and a follower does not re-run anything — it is
4564
- * handed the leader's text verbatim.
4565
- *
4566
- * The leak it closes, measured: two concurrent requests for the same text, one
4567
- * with `savings.modelCascade: "on"` and one with the cascade OFF, coalesced onto
4568
- * one execution. The routed leader called the cheap model, and the caller who
4569
- * never opted in — whose own decision was "do not route" — was served the cheap
4570
- * model's answer. Same shape inside a single uniformly-configured deployment:
4571
- * the automatic shut-off can latch between two concurrent requests, so one is
4572
- * routed and the other is not, and coalescing hands one of them the other's
4573
- * model. Whoever the layer decided must go to the strong model has to actually
4574
- * go there.
4575
- *
4576
- * `deferrable` CLOSES THE SAME HOLE ON THE LATENCY AXIS, which is why it belongs
4577
- * here and NOT in {@link buildExactKey}. The two doors do not risk the same
4578
- * thing: the exact key hands out an answer that is ALREADY WRITTEN, where the
4579
- * processing tier only picked a queue and changes neither the text nor the wait
4580
- * of whoever receives it. This one binds a follower to a call that HAS NOT COME
4581
- * BACK YET, so it imposes the leader's wait on them.
4582
- *
4583
- * A caller who never set `savings.deferrable` must not be made to wait for one
4584
- * who did.
4585
- */
4586
- declare function buildInflightKey$1(c: CanonicalRequest$1, opciones?: {
4587
- servedModel?: string;
4588
- deferrable?: boolean;
4589
- toolDiscovery?: boolean;
4590
- maxOutputTokens?: number;
4591
- }): string;
4592
4044
 
4593
4045
  /**
4594
4046
  * Policy engine: risk and freshness.
@@ -4650,50 +4102,7 @@ interface Policy {
4650
4102
  sensitiveTopic: "self-harm" | "mental-health-crisis" | "medical-emergency" | null;
4651
4103
  reasons: string[];
4652
4104
  }
4653
- declare function evaluatePolicy$1(c: CanonicalRequest$1): Policy;
4654
4105
 
4655
- /**
4656
- * A LOCAL EMBEDDING FUNCTION — no network, no API key, no per-call cost.
4657
- *
4658
- * The semantic cache needs a way to compare meaning. Wiring it to a hosted
4659
- * embedding endpoint is the obvious answer and a bad default: it makes every
4660
- * miss cost a network round-trip and money, and it forces a provider choice onto
4661
- * a customer who never asked for one. So the cache shipped with no embedder at
4662
- * all, which means it never matched anything.
4663
- *
4664
- * This is the third option: a deterministic bag-of-features vector computed in
4665
- * microseconds from the text itself. It captures LEXICAL closeness — the same
4666
- * question asked with different filler words — which is the overwhelming majority
4667
- * of real repeat traffic. It does NOT capture deep semantics: "what is a CDN"
4668
- * and "explain content delivery networks" share no tokens and will not match.
4669
- *
4670
- * WHY THAT IS SAFE, AND THIS IS THE PART THAT MATTERS. A semantic cache's one
4671
- * unforgivable failure is confidently answering a NEARBY BUT DIFFERENT question.
4672
- * This vector never gets the chance: the cache runs a deterministic precision
4673
- * guard beneath the embedding — matching numbers and dates, negation parity and a
4674
- * content-overlap floor — and every isolation field (tenant, principal, model,
4675
- * schema, attached data) is a hard filter applied before similarity is scored.
4676
- * A weak embedding can only cause a MISS, which costs one real call. It cannot
4677
- * produce a wrong answer.
4678
- *
4679
- * Pass your own `embed` to {@link InMemorySemanticCache} to get true semantics.
4680
- * This one exists so that the feature is worth something with zero setup.
4681
- */
4682
- /**
4683
- * The vector for a piece of text.
4684
- *
4685
- * Features are unigrams plus adjacent bigrams: bigrams are what keep word ORDER
4686
- * from being free. Without them "does A cause B" and "does B cause A" are the
4687
- * same point in space.
4688
- *
4689
- * Term weight is sublinear (`1 + log tf`) so a word repeated forty times does not
4690
- * dominate the direction of the vector, and the result is L2-normalised so cosine
4691
- * similarity is a plain dot product.
4692
- *
4693
- * @deprecated Internal detail of {@link localEmbedding}; leaves the public API in 0.5.
4694
- * Use {@link localEmbedding}, which returns the same vector.
4695
- */
4696
- declare function vectorLocal(texto: string): number[];
4697
4106
  /**
4698
4107
  * The default embedding function for {@link InMemorySemanticCache}.
4699
4108
  *
@@ -4701,8 +4110,6 @@ declare function vectorLocal(texto: string): number[];
4701
4110
  * adds no await and no latency to the request path.
4702
4111
  */
4703
4112
  declare function localEmbedding(text: string): number[];
4704
- /** @deprecated Spanish name, removed in 0.5. Use {@link localEmbedding}. */
4705
- declare function embebedorLocal(texto: string): number[];
4706
4113
  /**
4707
4114
  * The similarity floor this embedder is calibrated for.
4708
4115
  *
@@ -4713,8 +4120,6 @@ declare function embebedorLocal(texto: string): number[];
4713
4120
  * populations stop being separable.
4714
4121
  */
4715
4122
  declare const LOCAL_EMBEDDING_THRESHOLD = 0.72;
4716
- /** @deprecated Spanish name, removed in 0.5. Use {@link LOCAL_EMBEDDING_THRESHOLD}. */
4717
- declare const UMBRAL_LOCAL = 0.72;
4718
4123
 
4719
4124
  /**
4720
4125
  * Conversational memory by deltas.
@@ -4745,17 +4150,6 @@ declare function emptyState(): ConversationState;
4745
4150
  * The merge is deterministic and side-effect-free (returns a new object).
4746
4151
  */
4747
4152
  declare function mergeDelta(state: ConversationState, delta: MemoryDelta): ConversationState;
4748
- /**
4749
- * Project the state + recent turns into the minimal message set to send. Only
4750
- * relevant, non-empty state is serialized, then the last `rawTurns` messages,
4751
- * then the current message.
4752
- */
4753
- declare function projectContext$1(opts: {
4754
- state: ConversationState;
4755
- history: ChatMessage[];
4756
- current: ChatMessage;
4757
- rawTurns?: number;
4758
- }): ChatMessage[];
4759
4153
  declare function renderState(state: ConversationState): string;
4760
4154
 
4761
4155
  /**
@@ -4787,8 +4181,6 @@ interface CompactRowsOptions {
4787
4181
  indent?: string;
4788
4182
  }
4789
4183
  declare function encodeCompactRows(value: unknown, options?: CompactRowsOptions): string;
4790
- /** Return shared column names iff every element is a flat, scalar-valued object with identical keys. */
4791
- declare function uniformColumns$1(arr: unknown[]): string[] | null;
4792
4184
  /**
4793
4185
  * The instruction a model needs to read the compact encoder. Kept short on purpose — this text
4794
4186
  * is the per-request overhead the selector must amortize before it wins.
@@ -4987,30 +4379,6 @@ interface OpenAICompatibleOptions {
4987
4379
  */
4988
4380
  sendPromptCacheKey?: boolean;
4989
4381
  }
4990
- /**
4991
- * ¿Cumple este esquema las reglas del modo `strict` de OpenAI?
4992
- *
4993
- * Son dos, y aplican a TODO objeto anidado:
4994
- * 1. `additionalProperties: false`.
4995
- * 2. `required` tiene que listar TODAS las claves de `properties` — no solo
4996
- * las obligatorias. En modo strict no existe el campo opcional.
4997
- *
4998
- * Un esquema perfectamente válido como
4999
- * { properties: { answer, refs }, required: ["answer"] }
5000
- * incumple la segunda y el proveedor responde 400. No es un fallo del cliente:
5001
- * es una restricción de OpenAI que JSON Schema no tiene.
5002
- */
5003
- declare function isStrictCompatible$1(schema: unknown): boolean;
5004
- /**
5005
- * Decides the id that travels on the wire. Explicit option wins; otherwise the
5006
- * endpoint decides: OpenAI/Azure and Google's own Gemini API get the bare id,
5007
- * everything else keeps what the caller wrote. Exported for the pipeline-level test that pins the README
5008
- * snippet; not part of the public API.
5009
- *
5010
- * @deprecated Not part of the public API; leaves it in 0.5. Use the adapter option
5011
- * `stripProviderPrefix`.
5012
- */
5013
- declare function quitarPrefijoDeProveedor(model: string, explicito: boolean | undefined, baseUrl: string): string;
5014
4382
  declare class OpenAICompatibleProvider implements Provider {
5015
4383
  readonly id: string;
5016
4384
  private readonly opts;
@@ -5257,21 +4625,6 @@ declare class GoogleProvider implements Provider {
5257
4625
  private cerrar;
5258
4626
  }
5259
4627
 
5260
- /**
5261
- * Trace collector: an ordered log of pipeline decisions with elapsed timings.
5262
- * Every stage records why it did what it did, so a SavingsReport can be audited
5263
- * and so ablations can attribute savings to a specific module.
5264
- */
5265
- declare class TraceCollector$1 {
5266
- private readonly events;
5267
- private readonly start;
5268
- private readonly now;
5269
- constructor(now?: () => number);
5270
- record(stage: string, outcome: string, detail?: Record<string, unknown>): void;
5271
- elapsed(): number;
5272
- all(): TraceEvent[];
5273
- }
5274
-
5275
4628
  /**
5276
4629
  * Thrown when the pipeline is asked to run without a valid, active BiVelio
5277
4630
  * license. This is the fail-closed contract: a paid SDK must refuse to operate
@@ -5295,383 +4648,6 @@ declare class LicenseError extends Error {
5295
4648
  constructor(message: string, status?: string);
5296
4649
  }
5297
4650
 
5298
- /** Decoded revocation-list body (mirror of @bivelio/protocol's RevocationListPayload). */
5299
- interface RevocationListBody$1 {
5300
- v: number;
5301
- asOf: number;
5302
- seq: number;
5303
- revoked: string[];
5304
- iss?: string;
5305
- }
5306
- interface RevocationListVerification$1 {
5307
- /** True only if signature + typ + monotonic-seq + skew all pass. */
5308
- ok: boolean;
5309
- /** List revision (monotonic). -1 when not ok. */
5310
- seq: number;
5311
- /** Unix seconds the list was minted. 0 when not ok. */
5312
- asOf: number;
5313
- /** Revoked jti in this list (empty when not ok). */
5314
- revoked: Set<string>;
5315
- reason?: string;
5316
- }
5317
- /**
5318
- * Verify a signed revocation-list token offline and enforce the client-side
5319
- * policy: (1) valid Ed25519 signature, (2) header `typ` is a revocation list
5320
- * (a license token can't be replayed here), (3) `seq >= minSeq` — reject a
5321
- * stale/rolled-back list, (4) `asOf <= now + maxSkew` — reject a future-dated list.
5322
- * ANY failure returns `ok:false` with an empty set; the poller then keeps its
5323
- * sticky last-known-good (fail-open), never dropping known revocations.
5324
- */
5325
- declare function verifyRevocationList$1(token: string, publicKey: string | LicenseKeyset, opts?: {
5326
- minSeq?: number;
5327
- nowSeconds?: number;
5328
- maxSkewSeconds?: number;
5329
- }): RevocationListVerification$1;
5330
- /**
5331
- * The SDK's live, sticky, monotonic view of the revocation set. It only ever
5332
- * GROWS (a jti, once seen revoked, stays revoked for the process lifetime) and
5333
- * only advances on a higher-or-equal `seq` — so a stale, rolled-back, or empty
5334
- * list can never un-revoke a license. The live gate reads {@link snapshot} on
5335
- * every request; the poller feeds it via {@link apply}.
5336
- */
5337
- declare class RevocationSnapshot$1 {
5338
- private _seq;
5339
- private _asOf;
5340
- private _lastContactAt;
5341
- private readonly set;
5342
- get seq(): number;
5343
- get asOf(): number;
5344
- /** Unix seconds of the last CONFIRMED authorized heartbeat (a 304 or a verified
5345
- * list). Feeds the live gate's online staleness check; 0 until the first one. */
5346
- get lastContactAt(): number;
5347
- /** Record a confirmed authorized heartbeat from the control plane (monotonic). */
5348
- markContact(nowSeconds: number): void;
5349
- has(jti: string): boolean;
5350
- /** Live view of the revoked set (the same Set instance — read-only to callers). */
5351
- snapshot(): ReadonlySet<string>;
5352
- /**
5353
- * Merge an already-verified list. Accepts only `seq >= current seq`; UNIONS the
5354
- * jti (never removes); advances seq/asOf monotonically. Returns whether the
5355
- * revoked set grew or the revision advanced.
5356
- */
5357
- apply(list: {
5358
- seq: number;
5359
- asOf: number;
5360
- revoked: Iterable<string>;
5361
- }): boolean;
5362
- }
5363
-
5364
- /** A resolved gate that also exposes overall status + a refresh horizon. */
5365
- interface ResolvedGate$1 extends LicenseGate {
5366
- isActive(): boolean;
5367
- status(): LicenseStatus$1;
5368
- /**
5369
- * Why the key does not open, when it does not; `undefined` when it verified.
5370
- * Under `status() === "invalid"` it tells a key that does NOT EVEN HAVE THE
5371
- * SHAPE of a token (`"malformed"`: the `bvk_` pasted where the license goes,
5372
- * arbitrary text) from a well-formed one whose signature fails (the verifier's
5373
- * reason, e.g. `"bad signature"`). Both are `invalid` — the stable handle for
5374
- * branching does not change — but the advice given to the customer differs.
5375
- */
5376
- reason(): string | undefined;
5377
- /** The signed plan while the license grants (`"measure"` = shadow mode). */
5378
- plan?(): string | undefined;
5379
- /** Unix seconds after which the online status should be re-checked (poller anchor). */
5380
- refreshAfter?(): number | undefined;
5381
- }
5382
- /**
5383
- * Build a LIVE license gate from a signed key. The token is verified + decoded
5384
- * ONCE (no per-request Ed25519 verify — hot-path safe); each `isActive()` /
5385
- * `status()` / `isEntitled()` then re-derives the status from the cached payload +
5386
- * the LIVE clock + the (mutable, sticky) {@link RevocationSnapshot}. This is what
5387
- * lets a revocation — or an expiry crossed mid-process — take effect without a
5388
- * restart, while the customer request path never touches the network (it reads an
5389
- * in-memory Set).
5390
- *
5391
- * The offline path passes a fresh, never-updated snapshot (live clock, zero
5392
- * network); the online path passes a snapshot a {@link RevocationPoller} feeds.
5393
- */
5394
- declare function liveGateFromKey$1(licenseKey: string, publicKey: string | LicenseKeyset, opts: {
5395
- revocation: RevocationSnapshot$1;
5396
- now?: () => number;
5397
- /** Online staleness ceiling, seconds. If the gate goes this long without a
5398
- * confirmed authorized heartbeat, it stops granting (closes the block-egress
5399
- * fail-open). Undefined = check disabled (the offline path never sets it). */
5400
- maxStalenessSeconds?: number;
5401
- /** Freshness anchor (unix seconds); defaults to construction time (boot). */
5402
- startedAt?: number;
5403
- }): ResolvedGate$1;
5404
-
5405
- /**
5406
- * Build the SDK's structural {@link import("../contracts/types.js").LicenseGate}
5407
- * from a signed license key — the object `createSavingsLayer({ licenseKey })`
5408
- * injects on the OFFLINE path (no `licenseServerUrl`).
5409
- *
5410
- * It is a LIVE gate over an EMPTY, never-updated revocation snapshot: zero network,
5411
- * but the clock is LIVE, so a license that crosses its expiry (past grace) stops
5412
- * working mid-process instead of only after a restart — closing the frozen-clock
5413
- * hole the old one-shot resolution left open. `isActive()` is true while active or
5414
- * in grace; `isEntitled` additionally requires the feature in the token's grant.
5415
- * Online revocation is added by pairing {@link liveGateFromKey} with a
5416
- * poller-fed snapshot, which `createSavingsLayer` wires up for you.
5417
- */
5418
- declare function gateFromKey$1(licenseKey: string, publicKey: string | LicenseKeyset, now?: () => number): ResolvedGate$1;
5419
-
5420
- type RevocationPollEvent$1 = {
5421
- type: "applied";
5422
- seq: number;
5423
- size: number;
5424
- } | {
5425
- type: "unchanged";
5426
- seq: number;
5427
- } | {
5428
- type: "rejected";
5429
- reason: string;
5430
- } | {
5431
- type: "error";
5432
- error: unknown;
5433
- } | {
5434
- type: "no-fetch";
5435
- };
5436
- interface RevocationPollerOptions$1 {
5437
- /** Absolute URL of GET /licenses/revocations. */
5438
- url: string;
5439
- /** SPKI PEM (or a kid-addressed {@link LicenseKeyset}) used to verify the signed
5440
- * list — the same key/keyset that verifies license tokens. */
5441
- publicKeyPem: string | LicenseKeyset;
5442
- /** The sticky snapshot to feed. */
5443
- snapshot: RevocationSnapshot$1;
5444
- /** Anchor cadence to the license refresh horizon (unix seconds). */
5445
- getRefreshAfter?: () => number | undefined;
5446
- /** Injectable clock (unix seconds). */
5447
- nowSeconds?: () => number;
5448
- /** Injectable fetch (defaults to the global). */
5449
- fetchImpl?: typeof fetch;
5450
- pollIntervalSeconds?: number;
5451
- floorSeconds?: number;
5452
- maxIntervalSeconds?: number;
5453
- jitterRatio?: number;
5454
- maxSkewSeconds?: number;
5455
- requestTimeoutMs?: number;
5456
- /** Injectable RNG in [0,1) for jitter. Default Math.random. */
5457
- random?: () => number;
5458
- /** Optional observer (telemetry/tests). */
5459
- onEvent?: (e: RevocationPollEvent$1) => void;
5460
- /**
5461
- * Silencia los avisos por consola. Por defecto están ENCENDIDOS, y ese defecto
5462
- * es la corrección: el sondeo es fail-open, así que un call-home roto no rompe
5463
- * nada visible — la lista de revocaciones simplemente se queda vieja, en
5464
- * silencio, durante días. Quien tenga observabilidad propia puede apagarlos;
5465
- * quien no la tenga, que es casi todo el mundo, se entera igual.
5466
- */
5467
- silenceWarnings?: boolean;
5468
- /**
5469
- * @deprecated Spanish name that leaked into the public options. Use
5470
- * {@link RevocationPollerOptions.silenceWarnings}. Honoured for one minor
5471
- * version so nobody gets their warnings back by surprise.
5472
- */
5473
- silenciarAvisos?: boolean;
5474
- }
5475
- /**
5476
- * PURE, unit-testable next-delay policy (seconds). Steady state anchors to the
5477
- * license refresh horizon, clamped to [floor, ceiling] and jittered. After a
5478
- * failure it backs off exponentially (a revocation can't land during an outage
5479
- * anyway), capped, still jittered, never below the floor.
5480
- */
5481
- declare function computeNextDelay$1(opts: {
5482
- refreshAfter?: number;
5483
- nowSeconds: number;
5484
- consecutiveFailures: number;
5485
- floorSeconds: number;
5486
- pollIntervalSeconds: number;
5487
- maxIntervalSeconds: number;
5488
- jitterRatio: number;
5489
- random?: () => number;
5490
- }): number;
5491
- declare class RevocationPoller$1 {
5492
- private readonly opts;
5493
- private timer;
5494
- private controller;
5495
- private consecutiveFailures;
5496
- private stopped;
5497
- private started;
5498
- /** ETag of the last 200; sent as If-None-Match so an unchanged list 304s (cheap no-op). */
5499
- private lastEtag;
5500
- /** 304 seguidos; al llegar al tope se fuerza una descarga firmada. */
5501
- private consecutive304;
5502
- constructor(opts: RevocationPollerOptions$1);
5503
- private now;
5504
- private resolveFetch;
5505
- /**
5506
- * One poll cycle: fetch → verify → apply. NEVER throws (fail-open). A reachable
5507
- * CP resets the failure backoff even if the returned list is rejected — we keep
5508
- * last-known-good. Only a transport/abort/parse error counts as a failure.
5509
- */
5510
- pollOnce(): Promise<void>;
5511
- /** El interruptor, aceptando todavía el nombre viejo. */
5512
- private callado;
5513
- /** Un aviso por causa y por proceso, respetando el interruptor. */
5514
- private avisar;
5515
- /**
5516
- * THE CONTROL PLANE HAS BEEN UNREACHABLE FOR A WHILE.
5517
- *
5518
- * Polling is fail-open by design: a network outage must never take down the
5519
- * customer's production traffic. The trade-off is that an unreachable control
5520
- * plane has no visible symptom — the license keeps working and requests keep
5521
- * flowing while the revocation list quietly goes stale.
5522
- *
5523
- * So the warning goes to the console BY DEFAULT, not only through the optional
5524
- * `onEvent` observer. It fires on the third consecutive failure and then every
5525
- * twelfth: a lost request is normal, a week-long outage must keep reminding.
5526
- * Silence it with `silenceWarnings` if you have your own observability.
5527
- */
5528
- private avisarFalloDeRed;
5529
- /** Fire one non-blocking warm poll, then self-schedule. Idempotent. */
5530
- start(): void;
5531
- private schedule;
5532
- /** Stop polling and abort any in-flight request. Idempotent. */
5533
- stop(): void;
5534
- }
5535
-
5536
- interface UsageEmitterOptions$1 {
5537
- /** Full ingest URL, e.g. `https://savings.bivelio.com/api/metering/usage`. */
5538
- url: string;
5539
- /** Service-account key (`bvk_…`) sent as a Bearer token; the server derives the org from it. */
5540
- serviceAccountKey: string;
5541
- /** Optional org hint; the server always derives the authoritative org from the key. */
5542
- orgId?: string;
5543
- /** Flush cadence in ms (default 15000). */
5544
- flushIntervalMs?: number;
5545
- /** Records per POST (default 50). */
5546
- maxBatch?: number;
5547
- /** Hard in-memory cap; oldest records are dropped past it (default 1000). */
5548
- maxBuffer?: number;
5549
- /** Injectable fetch (defaults to the global). */
5550
- fetchImpl?: typeof fetch;
5551
- /** Injectable clock. */
5552
- now?: () => number;
5553
- /** Whether this process is a CI/ephemeral runner (excluded from billable seats). */
5554
- ci?: boolean;
5555
- /**
5556
- * Which surface owns this process: the local gateway (`bvsala claude` and
5557
- * friends) or the in-process SDK. Sent with the version in the batch's
5558
- * `x-bvsala-version` header (`gateway/0.4.16`, `sdk/0.4.16`) so the control
5559
- * plane can tell a gateway that lacks a lever from an SDK that never had it.
5560
- * Defaults to `"sdk"`; the gateway sets `"gateway"`.
5561
- */
5562
- surface?: "gateway" | "sdk";
5563
- /**
5564
- * Se llama cuando el ingest rechaza la credencial (401/403). Existe para que un
5565
- * despliegue con observabilidad pueda ENTERARSE: el aviso por consola sirve en
5566
- * un portátil, pero en producción los `console.warn` no despiertan a nadie, y
5567
- * este fallo concreto es invisible por definición —deja de llegar uso, que es
5568
- * exactamente lo mismo que se ve cuando no hay tráfico—.
5569
- */
5570
- onAuthError?: (status: number) => void;
5571
- /**
5572
- * Silence the console warnings. They are ON by default, exactly as in the
5573
- * revocation poller: metering is best-effort, so a broken ingest breaks
5574
- * nothing visible — usage simply stops arriving, silently, and the customer's
5575
- * dashboard stays empty forever.
5576
- */
5577
- silenceWarnings?: boolean;
5578
- }
5579
- /**
5580
- * Buffers usage records (counts, cost figures and opaque identifiers, never
5581
- * content) and flushes them to the control plane. DETECTIVE
5582
- * metering: strictly best-effort and NON-BLOCKING. `record()` is O(1) and
5583
- * `flush()` never throws, so a slow, unreachable, or erroring control plane can
5584
- * neither block nor crash the customer's request path. The buffer is hard-capped
5585
- * so a sustained outage can never grow memory without bound.
5586
- */
5587
- declare class UsageEmitter$1 {
5588
- private readonly options;
5589
- private readonly now;
5590
- private readonly flushIntervalMs;
5591
- private readonly maxBatch;
5592
- private readonly maxBuffer;
5593
- private buffer;
5594
- private seatId;
5595
- private ci;
5596
- private timer;
5597
- private inflight;
5598
- /**
5599
- * CONSECUTIVE failed flushes. Warn on the third and then every twelfth: one
5600
- * lost batch is normal, a whole hour is not. Same cadence as the revocation
5601
- * poller on purpose — two different rhythms for the same class of failure
5602
- * only confuse whoever reads the logs.
5603
- */
5604
- private fallosSeguidos;
5605
- constructor(options: UsageEmitterOptions$1);
5606
- /** Set the resolved seat identity (derivation is async; records emitted before
5607
- * it resolves are stamped at flush time, so none are lost). */
5608
- setSeat(seatId: string | undefined, ci: boolean): void;
5609
- /** Record one request's usage. Never blocks; O(1). */
5610
- record(report: SavingsReport): void;
5611
- start(): void;
5612
- /** Stop the timer and attempt a final flush. Safe to call more than once.
5613
- * Fire-and-forget: for a CLEAN shutdown that must not lose the last batch,
5614
- * use `stopAndDrain` and await it. */
5615
- stop(): void;
5616
- /** Clean shutdown: stop the timer and DRAIN the buffer, awaiting each POST.
5617
- * Unlike `stop()` (fire-and-forget), this resolves only once the final batch
5618
- * has actually been sent, so a graceful exit doesn't lose the last session's
5619
- * usage. Bounded, so an unreachable control plane can't block shutdown. */
5620
- stopAndDrain(maxIntentos?: number): Promise<void>;
5621
- /**
5622
- * Flush one batch. Never throws. A transient server error (5xx) or network
5623
- * failure re-queues the batch (capped); a 4xx (bad request / bad key) drops it,
5624
- * since retrying a rejected payload would loop forever.
5625
- */
5626
- flush(): Promise<void>;
5627
- private hacerFlush;
5628
- /**
5629
- * THE INGEST HAS BEEN FAILING FOR A WHILE AND NOBODY NOTICED.
5630
- *
5631
- * Metering is best-effort by design — it must never take down the customer's
5632
- * request — and that turns every failure into SILENT data loss. Without this,
5633
- * the only symptom is an empty dashboard, which is indistinguishable from
5634
- * "you haven't sent anything yet": the symptom points the opposite way from
5635
- * the cause.
5636
- *
5637
- * Warns on the third consecutive failure and then every twelfth. Not the
5638
- * first — a lost request is normal — and not every one, which becomes noise.
5639
- */
5640
- private avisarDeFallo;
5641
- private requeue;
5642
- private toWire;
5643
- }
5644
-
5645
- /** True when running in a CI / ephemeral environment. */
5646
- declare function detectCi$1(): boolean;
5647
- /**
5648
- * Derive the machine seat id for a service-account key. Resolves to `undefined`
5649
- * when no machine fingerprint is available (e.g. a browser) — the caller then
5650
- * reports no seatId and the server counts the request under an "unknown" seat.
5651
- * The id (`m-<32 hex>`) matches the control plane's identity charset.
5652
- */
5653
- declare function deriveSeatId$1(serviceAccountKey: string): Promise<string | undefined>;
5654
-
5655
- /** Fully-resolved, non-optional dependency set the pipeline runs against. */
5656
- interface ResolvedDeps$1 {
5657
- exactCache: ExactCache;
5658
- semanticCache: InMemorySemanticCache | undefined;
5659
- singleflight: Singleflight;
5660
- resolvers: ResolverRegistry;
5661
- router: ExecutionRouter;
5662
- toolSelector: ToolSelector;
5663
- formatSelector: FormatSelector;
5664
- schemaRegistry: SchemaRegistry;
5665
- constraintBackends: ConstraintBackend[];
5666
- }
5667
- /**
5668
- * Wire defaults for anything the caller did not supply. Every default is an
5669
- * in-memory, dependency-free implementation, so `createSavingsLayer({ provider,
5670
- * tokenizer })` is a working layer, and each piece can be replaced à la carte.
5671
- */
5672
- declare function resolveDependencies$1(config: SavingsLayerConfig): ResolvedDeps$1;
5673
-
5674
- declare const DEFAULT_MAX_STALENESS_SECONDS$1: number;
5675
4651
  /** The public handle returned by {@link createSavingsLayer}. */
5676
4652
  interface SavingsLayer {
5677
4653
  generate<T = unknown>(request: SavingsRequest): Promise<SavingsResult<T>>;
@@ -5734,7 +4710,7 @@ interface SavingsLayer {
5734
4710
  * messages: [{ role: "user", content: "What is 2 + 2 * 3?" }],
5735
4711
  * });
5736
4712
  */
5737
- declare function createSavingsLayer(config: Omit<SavingsLayerConfig, "tokenizer"> & Partial<Pick<SavingsLayerConfig, "tokenizer">>): SavingsLayer;
4713
+ declare function createSavingsLayer(configPublica: Omit<SavingsLayerConfig, "tokenizer"> & Partial<Pick<SavingsLayerConfig, "tokenizer">>): SavingsLayer;
5738
4714
 
5739
4715
  /**
5740
4716
  * Rejection of `SavingsStream.result` when the stream was aborted before the
@@ -6132,143 +5108,6 @@ declare function toCsv(rows: readonly Readonly<Record<string, CsvValue>>[], opti
6132
5108
  columns?: readonly string[];
6133
5109
  }): string;
6134
5110
 
6135
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6136
- type CanonicalRequest = CanonicalRequest$1;
6137
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6138
- declare const canonicalize: typeof canonicalize$1;
6139
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6140
- declare const modelFamilyOf: typeof modelFamilyOf$1;
6141
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6142
- declare const normalizeText: typeof normalizeText$1;
6143
- /** @deprecated Internal helper, removed from the public API in 0.5. Use `createHash("sha256").update(text).digest("hex")` from `node:crypto`. */
6144
- declare const sha256: typeof sha256$1;
6145
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6146
- declare const stableStringify: typeof stableStringify$1;
6147
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6148
- declare const buildExactKey: typeof buildExactKey$1;
6149
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6150
- declare const buildInflightKey: typeof buildInflightKey$1;
6151
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6152
- type CompactVerification = CompactVerification$1;
6153
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6154
- declare const EMBEDDED_PUBLIC_KEY: typeof EMBEDDED_PUBLIC_KEY$1;
6155
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6156
- type LicenseKeyShape = LicenseKeyShape$1;
6157
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6158
- type LicenseStatus = LicenseStatus$1;
6159
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6160
- type LicenseTokenPayload = LicenseTokenPayload$1;
6161
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6162
- type ResolvedGate = ResolvedGate$1;
6163
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6164
- type ResolvedLicense = ResolvedLicense$1;
6165
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6166
- type RevocationListBody = RevocationListBody$1;
6167
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6168
- type RevocationListVerification = RevocationListVerification$1;
6169
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6170
- type RevocationPollEvent = RevocationPollEvent$1;
6171
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6172
- declare const RevocationPoller: typeof RevocationPoller$1;
6173
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6174
- type RevocationPoller = RevocationPoller$1;
6175
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6176
- type RevocationPollerOptions = RevocationPollerOptions$1;
6177
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6178
- declare const RevocationSnapshot: typeof RevocationSnapshot$1;
6179
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6180
- type RevocationSnapshot = RevocationSnapshot$1;
6181
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6182
- declare const computeNextDelay: typeof computeNextDelay$1;
6183
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6184
- declare const deriveStatus: typeof deriveStatus$1;
6185
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6186
- declare const gateFromKey: typeof gateFromKey$1;
6187
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6188
- declare const isKeyset: typeof isKeyset$1;
6189
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6190
- declare const licenseKeyShape: typeof licenseKeyShape$1;
6191
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6192
- declare const liveGateFromKey: typeof liveGateFromKey$1;
6193
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6194
- declare const normalizeLicenseKey: typeof normalizeLicenseKey$1;
6195
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6196
- declare const resolveLicense: typeof resolveLicense$1;
6197
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6198
- declare const verifyCompactSignature: typeof verifyCompactSignature$1;
6199
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6200
- declare const verifyLicenseToken: typeof verifyLicenseToken$1;
6201
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6202
- declare const verifyRevocationList: typeof verifyRevocationList$1;
6203
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6204
- declare const UsageEmitter: typeof UsageEmitter$1;
6205
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6206
- type UsageEmitter = UsageEmitter$1;
6207
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6208
- type UsageEmitterOptions = UsageEmitterOptions$1;
6209
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6210
- declare const deriveSeatId: typeof deriveSeatId$1;
6211
- /** @deprecated Internal license machinery, removed from the public API in 0.5: no replacement. In the published package a license enters only through `licenseKey` / `serviceAccountKey`. */
6212
- declare const detectCi: typeof detectCi$1;
6213
- /** @deprecated Internal constant, removed from the public API in 0.5. The default is documented on `licenseRevocation.maxStalenessSeconds`; set that option to change it. */
6214
- declare const DEFAULT_MAX_STALENESS_SECONDS: typeof DEFAULT_MAX_STALENESS_SECONDS$1;
6215
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6216
- type ResolvedDeps = ResolvedDeps$1;
6217
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6218
- declare const resolveDependencies: typeof resolveDependencies$1;
6219
- /** @deprecated Internal constant of the reference-commission rule, removed from the public API in 0.5: no replacement (the rule is described in the documentation, not frozen as API). */
6220
- declare const REFERENCE_MAX_AGE_MS: typeof REFERENCE_MAX_AGE_MS$1;
6221
- /** @deprecated Internal constant of the reference-commission rule, removed from the public API in 0.5: no replacement (the rule is described in the documentation, not frozen as API). */
6222
- declare const REFERENCE_MESSAGE_ALLOWANCE: typeof REFERENCE_MESSAGE_ALLOWANCE$1;
6223
- /** @deprecated Internal constant of the reference-commission rule, removed from the public API in 0.5: no replacement (the rule is described in the documentation, not frozen as API). */
6224
- declare const REFERENCE_OUTPUT_SHARE: typeof REFERENCE_OUTPUT_SHARE$1;
6225
- /** @deprecated Internal ledger of the pipeline, removed from the public API in 0.5. Read the four ledgers from the `SavingsReport` each call returns. */
6226
- declare const SavingsLedger: typeof SavingsLedger$1;
6227
- /** @deprecated Internal ledger of the pipeline, removed from the public API in 0.5. Read the four ledgers from the `SavingsReport` each call returns. */
6228
- type SavingsLedger = SavingsLedger$1;
6229
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5. Read the stage traces from `report.traces`. */
6230
- declare const TraceCollector: typeof TraceCollector$1;
6231
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5. Read the stage traces from `report.traces`. */
6232
- type TraceCollector = TraceCollector$1;
6233
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6234
- declare const adaptiveK: typeof adaptiveK$1;
6235
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6236
- declare const dedupe: typeof dedupe$1;
6237
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6238
- declare const executeRetrievalPlan: typeof executeRetrievalPlan$1;
6239
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6240
- declare const cosine: typeof cosine$1;
6241
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6242
- declare const keyTokensMatch: typeof keyTokensMatch$1;
6243
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6244
- declare const multisetEqual: typeof multisetEqual$1;
6245
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6246
- declare const negationCount: typeof negationCount$1;
6247
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6248
- declare const numericTokens: typeof numericTokens$1;
6249
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6250
- declare const words: typeof words$1;
6251
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6252
- declare const sameAnswer: typeof sameAnswer$1;
6253
- /** @deprecated Internal helper, removed from the public API in 0.5. Arithmetic questions are still answered locally by `arithmeticResolver` / `createDefaultResolvers()`. */
6254
- declare const evalArithmetic: typeof evalArithmetic$1;
6255
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6256
- declare const evaluatePolicy: typeof evaluatePolicy$1;
6257
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6258
- declare const isStrictCompatible: typeof isStrictCompatible$1;
6259
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6260
- declare const projectContext: typeof projectContext$1;
6261
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6262
- declare const resolveConstraintBackend: typeof resolveConstraintBackend$1;
6263
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6264
- declare const shouldCompress: typeof shouldCompress$1;
6265
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6266
- declare const withProtectedSpans: typeof withProtectedSpans$1;
6267
- /** @deprecated Internal pipeline helper, removed from the public API in 0.5: no replacement. */
6268
- declare const uniformColumns: typeof uniformColumns$1;
6269
- /** @deprecated Internal helper, removed from the public API in 0.5. Use `crypto.randomUUID()`. */
6270
- declare const randomId: typeof randomId$1;
6271
-
6272
5111
  /**
6273
5112
  * bivelio-savings-layer (BV-SALA)
6274
5113
  * ---------------------------------------------------------------------------
@@ -6292,19 +5131,13 @@ declare const randomId: typeof randomId$1;
6292
5131
  * The list-price catalogue: model id (without vendor prefix) → USD per 1K
6293
5132
  * tokens. `costModels` on the layer config always wins over it.
6294
5133
  */
6295
- declare const PRICE_CATALOG: typeof CATALOGO$1;
5134
+ declare const PRICE_CATALOG: typeof CATALOGO;
6296
5135
  /**
6297
5136
  * The list price for a model on the day of the request, or `undefined` when the
6298
5137
  * catalogue has no price for it in force that day.
6299
5138
  */
6300
- declare const listPrice: typeof precioDeLista$1;
5139
+ declare const listPrice: typeof precioDeLista;
6301
5140
  /** When the catalogue prices were last checked against the providers' public rates (YYYY-MM-DD). */
6302
- declare const PRICES_AS_OF: typeof PRECIOS_AL_DIA$1;
6303
- /** @deprecated Spanish name, removed in 0.5. Use {@link PRICE_CATALOG}. */
6304
- declare const CATALOGO: typeof CATALOGO$1;
6305
- /** @deprecated Spanish name, removed in 0.5. Use {@link listPrice}. */
6306
- declare const precioDeLista: typeof precioDeLista$1;
6307
- /** @deprecated Spanish name, removed in 0.5. Use {@link PRICES_AS_OF}. */
6308
- declare const PRECIOS_AL_DIA: typeof PRECIOS_AL_DIA$1;
5141
+ declare const PRICES_AS_OF: typeof PRECIOS_AL_DIA;
6309
5142
 
6310
- 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 };
5143
+ 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, COMPACTION_TRANSFORMS, COMPACT_ROWS_INSTRUCTION, type CacheBreakpointStore, type CacheOutcome, type CachePlacement, type CacheTier, type CacheWriteReport, type CachedAnswer, type CalibrationObservation, CalibrationStateError, type ChatMessage, type CompactRowsDecodeOptions, type CompactRowsOptions, 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_MIN_SAVED_CHARS, type DeferredExecutionReport, type DeterministicResolver, 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 LicenseKeyset, type LocalClassifier, 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, 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, type ReasoningEffort, type ReferenceCredit, type ReferenceRejection, type RequestContext, type Reranker, ResolverRegistry, type ResolverResult, type RetrievalOptions, type RetrievalOutcome, type RetrievalPlan, type Retriever, type RouteDecision, type SavingsAdapterLevers, type SavingsAdapterOptions, type SavingsAttributeOptions, type SavingsBatches, type SavingsCallOptions, type SavingsLayer, type SavingsLayerConfig, 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, type TraceEvent, type TracerLike, type TracerProviderLike, type ValidationError, type ValidationResult, type VerificationCheck, type VerificationExclusion, type VerificationOutcome, type VerificationReport, type VerificationSettings, type VerificationSide, type VerificationStratum, arithmeticResolver, calibrateSemanticFloor, compactRowsSerializer, compactToolOutput, createCompactRowsSerializer, createDefaultResolvers, createHandoff, createMockProvider, createSavingsLayer, csvSerializer, decodeCompactRows, defaultTokenizerRegistry, emptyState, encodeCompactRows, heuristicEstimator, instrumentSavingsLayer, jsonCompactSerializer, listPrice, localEmbedding, mergeDelta, noopCompressor, providerNativeBackend, recordSavingsOnSpan, registerExactTokenizer, renderState, savingsSpanAttributes, toCsv, toFocusRows, toLangfuseGeneration, toSavingsSeries, validateAgainstSchema };