@bivelio/savings-layer 0.4.20 → 0.4.22
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/README.md +20 -8
- package/dist/gateway/bin.js +350 -337
- package/dist/index.d.ts +113 -4
- package/dist/index.js +665 -656
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -205,7 +205,7 @@ declare function precioDeLista(model: string): CostModel | undefined;
|
|
|
205
205
|
* on the customer's machine. `test/version-declarada.test.ts` ties this
|
|
206
206
|
* constant to package.json so the two can never drift.
|
|
207
207
|
*/
|
|
208
|
-
declare const BV_SALA_VERSION = "0.4.
|
|
208
|
+
declare const BV_SALA_VERSION = "0.4.22";
|
|
209
209
|
|
|
210
210
|
/**
|
|
211
211
|
* Environment-agnostic UUID generation.
|
|
@@ -990,6 +990,15 @@ interface LicenseGate {
|
|
|
990
990
|
* que tener una rama por defecto de todas formas.
|
|
991
991
|
*/
|
|
992
992
|
status?(): string;
|
|
993
|
+
/**
|
|
994
|
+
* Why the key does not open, when it does not; `undefined` when it does. It
|
|
995
|
+
* only refines the MESSAGE, never the verdict: an `"invalid"` whose reason is
|
|
996
|
+
* `"malformed"` (not even the shape of a token: the `bvk_` pasted where the
|
|
997
|
+
* license goes) gets different advice from an `"invalid"` that has the shape
|
|
998
|
+
* but no valid signature. Optional because a gate is implemented by the
|
|
999
|
+
* caller; without it, the generic message for that status.
|
|
1000
|
+
*/
|
|
1001
|
+
reason?(): string | undefined;
|
|
993
1002
|
}
|
|
994
1003
|
interface TraceEvent {
|
|
995
1004
|
stage: string;
|
|
@@ -2378,7 +2387,18 @@ declare function createMockProvider(options?: MockProviderOptions): Provider;
|
|
|
2378
2387
|
interface OpenAICompatibleOptions {
|
|
2379
2388
|
baseUrl: string;
|
|
2380
2389
|
apiKey?: string;
|
|
2381
|
-
/**
|
|
2390
|
+
/**
|
|
2391
|
+
* Strip the `provider/` prefix from model ids before sending (`openai/gpt-4o-mini`
|
|
2392
|
+
* → `gpt-4o-mini`).
|
|
2393
|
+
*
|
|
2394
|
+
* Default (undefined): strip when `baseUrl` is OpenAI's own API or an Azure
|
|
2395
|
+
* OpenAI endpoint, keep otherwise. OpenAI rejects a prefixed id with a 404
|
|
2396
|
+
* ("model does not exist"), so the qualified ids the layer uses everywhere
|
|
2397
|
+
* else — pricing, cache keys, the report — would break the very first call
|
|
2398
|
+
* that reaches the provider. A gateway or a self-hosted server with a
|
|
2399
|
+
* namespaced model name usually WANTS the prefix, so it is kept there. Set `true`/`false` to decide explicitly; an explicit value
|
|
2400
|
+
* always wins.
|
|
2401
|
+
*/
|
|
2382
2402
|
stripProviderPrefix?: boolean;
|
|
2383
2403
|
/** Extra headers (e.g. for a gateway). */
|
|
2384
2404
|
headers?: Record<string, string>;
|
|
@@ -2408,6 +2428,13 @@ interface OpenAICompatibleOptions {
|
|
|
2408
2428
|
* es una restricción de OpenAI que JSON Schema no tiene.
|
|
2409
2429
|
*/
|
|
2410
2430
|
declare function isStrictCompatible(schema: unknown): boolean;
|
|
2431
|
+
/**
|
|
2432
|
+
* Decides the id that travels on the wire. Explicit option wins; otherwise the
|
|
2433
|
+
* endpoint decides: OpenAI/Azure get the bare id, everything else keeps what
|
|
2434
|
+
* the caller wrote. Exported for the pipeline-level test that pins the README
|
|
2435
|
+
* snippet; not part of the public API.
|
|
2436
|
+
*/
|
|
2437
|
+
declare function quitarPrefijoDeProveedor(model: string, explicito: boolean | undefined, baseUrl: string): string;
|
|
2411
2438
|
declare class OpenAICompatibleProvider implements Provider {
|
|
2412
2439
|
readonly id: string;
|
|
2413
2440
|
private readonly opts;
|
|
@@ -2439,6 +2466,14 @@ interface AnthropicOptions {
|
|
|
2439
2466
|
apiKey?: string;
|
|
2440
2467
|
/** Defaults to the public API. Override for a gateway or a proxy. */
|
|
2441
2468
|
baseUrl?: string;
|
|
2469
|
+
/**
|
|
2470
|
+
* Strip the `provider/` prefix from model ids before sending
|
|
2471
|
+
* (`anthropic/claude-sonnet-4-5` → `claude-sonnet-4-5`). Default (undefined):
|
|
2472
|
+
* strip when talking to `api.anthropic.com`, which rejects a prefixed id;
|
|
2473
|
+
* keep for a gateway or proxy, which usually routes on it. An explicit value
|
|
2474
|
+
* always wins.
|
|
2475
|
+
*/
|
|
2476
|
+
stripProviderPrefix?: boolean;
|
|
2442
2477
|
/** Wire version pinned in the `anthropic-version` header. */
|
|
2443
2478
|
apiVersion?: string;
|
|
2444
2479
|
/** Extra headers (e.g. for a gateway). */
|
|
@@ -2503,6 +2538,8 @@ declare class AnthropicProvider implements Provider {
|
|
|
2503
2538
|
private readonly opts;
|
|
2504
2539
|
private readonly fetchImpl;
|
|
2505
2540
|
constructor(opts?: AnthropicOptions);
|
|
2541
|
+
/** The id Anthropic's API sees: bare at `api.anthropic.com`, as written elsewhere. */
|
|
2542
|
+
private modeloEnElCable;
|
|
2506
2543
|
generate(req: ProviderRequest): Promise<ProviderResponse>;
|
|
2507
2544
|
private construirCuerpo;
|
|
2508
2545
|
private marcarCache;
|
|
@@ -2575,8 +2612,14 @@ declare class LicenseError extends Error {
|
|
|
2575
2612
|
*
|
|
2576
2613
|
* El comportamiento no cambia —sigue siendo fail-closed, `granted()` no lo
|
|
2577
2614
|
* concede— pero ahora el mensaje puede decir la verdad.
|
|
2615
|
+
*
|
|
2616
|
+
* `none` means "there is no key": what is left after `normalizeLicenseKey` is
|
|
2617
|
+
* EMPTY. It is the same value `LicenseError.status` already carries when nothing
|
|
2618
|
+
* was configured, because it is the same problem with the same fix: a
|
|
2619
|
+
* `licenseKey: " "` (an empty environment variable, a blank secret file) used
|
|
2620
|
+
* to tell the customer their key "does not verify" — there was no key.
|
|
2578
2621
|
*/
|
|
2579
|
-
type LicenseStatus = "active" | "grace" | "expired" | "invalid" | "revoked" | "stale";
|
|
2622
|
+
type LicenseStatus = "active" | "grace" | "expired" | "invalid" | "revoked" | "stale" | "none";
|
|
2580
2623
|
/** Decoded license token body (mirror of `@bivelio/protocol`'s LicensePayload,
|
|
2581
2624
|
* declared locally so the SDK stays free of a control-plane dependency). */
|
|
2582
2625
|
interface LicenseTokenPayload {
|
|
@@ -2621,6 +2664,48 @@ interface LicenseKeyset {
|
|
|
2621
2664
|
}
|
|
2622
2665
|
/** Narrow a verification key to a {@link LicenseKeyset} (vs a bare SPKI PEM string). */
|
|
2623
2666
|
declare function isKeyset(k: string | LicenseKeyset): k is LicenseKeyset;
|
|
2667
|
+
/**
|
|
2668
|
+
* Normalize a license key the way it arrives from the real world — ONCE, at the
|
|
2669
|
+
* entry point, never inside the verifier.
|
|
2670
|
+
*
|
|
2671
|
+
* The README says `export BIVELIO_LICENSE_KEY=…` and dotenv trims, so that path
|
|
2672
|
+
* never showed it. But anyone reading the key from a file (`readFileSync`), from
|
|
2673
|
+
* a Docker/Kubernetes secret (mounted as a file, trailing newline included) or
|
|
2674
|
+
* copying it out of an `Authorization` header handed over a CORRECT key with a
|
|
2675
|
+
* `\n` after it, a space before it, quotes around it or a `Bearer ` in front —
|
|
2676
|
+
* and the SDK answered "does not verify, check you pasted the WHOLE key". A
|
|
2677
|
+
* wrong diagnosis on a good key is the worst possible hint: it sends the
|
|
2678
|
+
* customer to look where the problem is not.
|
|
2679
|
+
*
|
|
2680
|
+
* Worse, it was INCONSISTENT: `tok + "\r\n"` passed and `tok + "\n"` did not,
|
|
2681
|
+
* because `atob` ignores ASCII whitespace while the padding was computed from a
|
|
2682
|
+
* length that included it, and two extra characters give the same remainder
|
|
2683
|
+
* modulo 4 as zero. Behavior that depends on which editor saved the file is not
|
|
2684
|
+
* behavior.
|
|
2685
|
+
*
|
|
2686
|
+
* Only OUTER wrapping is removed — whitespace, one pair of single or double
|
|
2687
|
+
* quotes, a `Bearer` prefix in any capitalization — in that order, in one pass.
|
|
2688
|
+
* Anything INSIDE the key is left alone: an interior space is not wrapping, it
|
|
2689
|
+
* is a broken key, and {@link licenseKeyShape} reports it as `malformed`.
|
|
2690
|
+
*/
|
|
2691
|
+
declare function normalizeLicenseKey(raw: string): string;
|
|
2692
|
+
/**
|
|
2693
|
+
* The SHAPE of an already-normalized key, so the error message can tell apart
|
|
2694
|
+
* three problems that used to get the same text:
|
|
2695
|
+
*
|
|
2696
|
+
* · `empty` — there is no key (only whitespace, or nothing at all).
|
|
2697
|
+
* · `malformed` — not even the shape of a token: not three dot-separated
|
|
2698
|
+
* base64url segments. This is where the `bvk_` service key
|
|
2699
|
+
* pasted where the license goes lands, as does arbitrary text
|
|
2700
|
+
* or a token with a line break in the middle.
|
|
2701
|
+
* · `token` — has the shape; whether it verifies is up to the signature.
|
|
2702
|
+
*
|
|
2703
|
+
* It is the SAME shape rule {@link verifyCompactSignature} enforces, so that "has
|
|
2704
|
+
* the shape" and "verification was attempted" mean the same thing.
|
|
2705
|
+
*/
|
|
2706
|
+
type LicenseKeyShape = "empty" | "malformed" | "token";
|
|
2707
|
+
/** Classify a normalized key. See {@link LicenseKeyShape}. */
|
|
2708
|
+
declare function licenseKeyShape(normalizedKey: string): LicenseKeyShape;
|
|
2624
2709
|
/**
|
|
2625
2710
|
* Verify the Ed25519 signature of any BV-SALA compact token
|
|
2626
2711
|
* (`base64url(header).base64url(body).base64url(sig)`, sig over `${head}.${body}`)
|
|
@@ -2629,6 +2714,13 @@ declare function isKeyset(k: string | LicenseKeyset): k is LicenseKeyset;
|
|
|
2629
2714
|
* so the browser (`@noble/curves`) and node (`node:crypto`) sides agree byte-for-byte
|
|
2630
2715
|
* and there is no bespoke per-message verification path to keep in sync. It does NOT
|
|
2631
2716
|
* interpret the payload or the header `typ` — callers do that.
|
|
2717
|
+
*
|
|
2718
|
+
* Shape is checked SEGMENT by segment, not just by counting dots. Three parts
|
|
2719
|
+
* used to be enough and the rest was left to `atob`, which ignores whitespace:
|
|
2720
|
+
* that is how a token with `\r\n` after it verified while the same token with
|
|
2721
|
+
* `\n` did not (see {@link normalizeLicenseKey}). The shared primitive must give
|
|
2722
|
+
* the same answer to the same input, always; a caller that wants to tolerate
|
|
2723
|
+
* wrapping normalizes BEFORE calling.
|
|
2632
2724
|
*/
|
|
2633
2725
|
declare function verifyCompactSignature(token: string, publicKey: string | LicenseKeyset): CompactVerification;
|
|
2634
2726
|
/** Verify a token's signature and decode its payload. Does not check expiry. */
|
|
@@ -2656,6 +2748,9 @@ declare function deriveStatus(payload: {
|
|
|
2656
2748
|
* Verify + apply the grace policy → a resolved status. Mirrors what the issuing
|
|
2657
2749
|
* control plane resolves for the same token. Bad signature / malformed
|
|
2658
2750
|
* → invalid; otherwise the status comes from {@link deriveStatus}.
|
|
2751
|
+
*
|
|
2752
|
+
* A public entry point, so it normalizes like the others (gate and refresher):
|
|
2753
|
+
* the same key must resolve the same whichever way it comes in.
|
|
2659
2754
|
*/
|
|
2660
2755
|
declare function resolveLicense(token: string, publicKey: string | LicenseKeyset, opts?: {
|
|
2661
2756
|
nowSeconds?: number;
|
|
@@ -2732,6 +2827,15 @@ declare class RevocationSnapshot {
|
|
|
2732
2827
|
interface ResolvedGate extends LicenseGate {
|
|
2733
2828
|
isActive(): boolean;
|
|
2734
2829
|
status(): LicenseStatus;
|
|
2830
|
+
/**
|
|
2831
|
+
* Why the key does not open, when it does not; `undefined` when it verified.
|
|
2832
|
+
* Under `status() === "invalid"` it tells a key that does NOT EVEN HAVE THE
|
|
2833
|
+
* SHAPE of a token (`"malformed"`: the `bvk_` pasted where the license goes,
|
|
2834
|
+
* arbitrary text) from a well-formed one whose signature fails (the verifier's
|
|
2835
|
+
* reason, e.g. `"bad signature"`). Both are `invalid` — the stable handle for
|
|
2836
|
+
* branching does not change — but the advice given to the customer differs.
|
|
2837
|
+
*/
|
|
2838
|
+
reason(): string | undefined;
|
|
2735
2839
|
/** Unix seconds after which the online status should be re-checked (poller anchor). */
|
|
2736
2840
|
refreshAfter?(): number | undefined;
|
|
2737
2841
|
}
|
|
@@ -3063,6 +3167,11 @@ interface SavingsLayerConfig {
|
|
|
3063
3167
|
* against the embedded public key and builds a {@link licenseGate} from it.
|
|
3064
3168
|
* Without a valid, active license (and without {@link devUnlicensed}), the
|
|
3065
3169
|
* pipeline refuses to run — get a key at https://savings.bivelio.com.
|
|
3170
|
+
*
|
|
3171
|
+
* Surrounding whitespace (the trailing newline of a file or mounted secret),
|
|
3172
|
+
* wrapping quotes and a `Bearer ` prefix are stripped before verification, so
|
|
3173
|
+
* a key read with `readFileSync` works as-is. Anything INSIDE the key is not
|
|
3174
|
+
* touched: a key with a space in the middle is a broken key.
|
|
3066
3175
|
*/
|
|
3067
3176
|
licenseKey?: string;
|
|
3068
3177
|
/**
|
|
@@ -3366,4 +3475,4 @@ interface SavingsLayer {
|
|
|
3366
3475
|
*/
|
|
3367
3476
|
declare function createSavingsLayer(config: Omit<SavingsLayerConfig, "tokenizer"> & Partial<Pick<SavingsLayerConfig, "tokenizer">>): SavingsLayer;
|
|
3368
3477
|
|
|
3369
|
-
export { type AnthropicOptions, AnthropicProvider, BV_SALA_VERSION, type BivelioHandoff, CATALOGO, COMPACT_ROWS_INSTRUCTION, type CacheOutcome, type CacheTier, type CachedAnswer, type CanonicalRequest, type ChatMessage, type CompactRowsDecodeOptions, type CompactRowsOptions, type CompactVerification, type CompressionEconomics, type CompressionPolicyInput, type CompressionRequest, type CompressionResult, type Compressor, type ConstraintBackend, type ConstraintBackendId, type ConstraintPlan, type ConversationState, type CostBasis, type CostModel, DEFAULT_COST_MODEL, DEFAULT_MAX_STALENESS_SECONDS, type DeferredExecutionReport, type DeterministicResolver, EMBEDDED_PUBLIC_KEY, type EmbeddingFn, type EvidenceDoc, type ExactCache, ExactTokenizer, type ExecutionClass, ExecutionRouter, type FormatChoice, FormatSelector, type FormatSelectorOptions, type HandoffFact, HeuristicEstimator, InMemoryExactCache, InMemorySemanticCache, InMemoryToolSetFreezer, type JsonSchema, LicenseError, type LicenseGate, type LicenseKeyset, type LicenseStatus, type LicenseTokenPayload, type LocalClassifier, MODELOS_POR_CODIFICACION, MODELS_BY_ENCODING, type MemoryDelta, type MessageRole, MockProvider, type MockProviderOptions, type ModelCascadeMode, type ModelCascadeReport, type ModelCascadeSettings, type OpenAICompatibleOptions, OpenAICompatibleProvider, type OutputContract, PRECIOS_AL_DIA, type Policy, type ProtectedSpan, type Provider, type ProviderRequest, type ProviderResponse, type ProviderUsage, QUALITY_STATUSES, type QualityStatus, 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 SavingsLayer, type SavingsLayerConfig, SavingsLedger, type SavingsReport, type SavingsRequest, type SavingsResult, type SavingsToggles, SchemaRegistry, type SemanticCacheOptions, type SemanticHit, type SemanticRecord, type SemanticVerifier, type SerializationFormat, type Serializer, Singleflight, type TokenEstimator, TokenizerRegistry, type ToolCallRequest, type ToolDescriptor, type ToolRisk, type ToolSelection, ToolSelector, type ToolSelectorOptions, type ToolSetFreezer, TraceCollector, type TraceEvent, UMBRAL_LOCAL, UsageEmitter, type UsageEmitterOptions, type ValidationError, type ValidationResult, adaptiveK, arithmeticResolver, buildExactKey, buildInflightKey, canonicalize, compactRowsSerializer, compresionFiel, computeNextDelay, cosine, createCompactRowsSerializer, createDefaultResolvers, createHandoff, createMockProvider, createSavingsLayer, csvSerializer, decodeCompactRows, dedupe, defaultTokenizerRegistry, deriveSeatId, deriveStatus, detectCi, embebedorLocal, emptyState, encodeCompactRows, evalArithmetic, evaluatePolicy, executeRetrievalPlan, gateFromKey, heuristicEstimator, isKeyset, isStrictCompatible, jsonCompactSerializer, keyTokensMatch, liveGateFromKey, mergeDelta, modelFamilyOf, multisetEqual, negationCount, noopCompressor, normalizeText, numericTokens, precioDeLista, projectContext, providerNativeBackend, randomId, registerExactTokenizer, registrarTokenizadorExacto, renderState, resolveConstraintBackend, resolveDependencies, resolveLicense, sha256, shouldCompress, stableStringify, uniformColumns, validateAgainstSchema, vectorLocal, verifyCompactSignature, verifyLicenseToken, verifyRevocationList, withProtectedSpans, words };
|
|
3478
|
+
export { type AnthropicOptions, AnthropicProvider, BV_SALA_VERSION, type BivelioHandoff, CATALOGO, COMPACT_ROWS_INSTRUCTION, type CacheOutcome, type CacheTier, type CachedAnswer, type CanonicalRequest, type ChatMessage, type CompactRowsDecodeOptions, type CompactRowsOptions, type CompactVerification, type CompressionEconomics, type CompressionPolicyInput, type CompressionRequest, type CompressionResult, type Compressor, type ConstraintBackend, type ConstraintBackendId, type ConstraintPlan, type ConversationState, type CostBasis, type CostModel, DEFAULT_COST_MODEL, DEFAULT_MAX_STALENESS_SECONDS, type DeferredExecutionReport, type DeterministicResolver, EMBEDDED_PUBLIC_KEY, type EmbeddingFn, type EvidenceDoc, type ExactCache, ExactTokenizer, type ExecutionClass, ExecutionRouter, type FormatChoice, FormatSelector, type FormatSelectorOptions, type HandoffFact, HeuristicEstimator, InMemoryExactCache, InMemorySemanticCache, InMemoryToolSetFreezer, type JsonSchema, LicenseError, type LicenseGate, type LicenseKeyShape, type LicenseKeyset, type LicenseStatus, type LicenseTokenPayload, type LocalClassifier, MODELOS_POR_CODIFICACION, MODELS_BY_ENCODING, type MemoryDelta, type MessageRole, MockProvider, type MockProviderOptions, type ModelCascadeMode, type ModelCascadeReport, type ModelCascadeSettings, type OpenAICompatibleOptions, OpenAICompatibleProvider, type OutputContract, PRECIOS_AL_DIA, type Policy, type ProtectedSpan, type Provider, type ProviderRequest, type ProviderResponse, type ProviderUsage, QUALITY_STATUSES, type QualityStatus, 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 SavingsLayer, type SavingsLayerConfig, SavingsLedger, type SavingsReport, type SavingsRequest, type SavingsResult, type SavingsToggles, SchemaRegistry, type SemanticCacheOptions, type SemanticHit, type SemanticRecord, type SemanticVerifier, type SerializationFormat, type Serializer, Singleflight, type TokenEstimator, TokenizerRegistry, type ToolCallRequest, type ToolDescriptor, type ToolRisk, type ToolSelection, ToolSelector, type ToolSelectorOptions, type ToolSetFreezer, TraceCollector, type TraceEvent, UMBRAL_LOCAL, UsageEmitter, type UsageEmitterOptions, type ValidationError, type ValidationResult, adaptiveK, arithmeticResolver, buildExactKey, buildInflightKey, canonicalize, compactRowsSerializer, compresionFiel, computeNextDelay, cosine, createCompactRowsSerializer, createDefaultResolvers, createHandoff, createMockProvider, createSavingsLayer, csvSerializer, decodeCompactRows, dedupe, defaultTokenizerRegistry, deriveSeatId, deriveStatus, detectCi, embebedorLocal, emptyState, encodeCompactRows, evalArithmetic, evaluatePolicy, executeRetrievalPlan, gateFromKey, heuristicEstimator, isKeyset, isStrictCompatible, jsonCompactSerializer, keyTokensMatch, licenseKeyShape, liveGateFromKey, mergeDelta, modelFamilyOf, multisetEqual, negationCount, noopCompressor, normalizeLicenseKey, normalizeText, numericTokens, precioDeLista, projectContext, providerNativeBackend, quitarPrefijoDeProveedor, randomId, registerExactTokenizer, registrarTokenizadorExacto, renderState, resolveConstraintBackend, resolveDependencies, resolveLicense, sha256, shouldCompress, stableStringify, uniformColumns, validateAgainstSchema, vectorLocal, verifyCompactSignature, verifyLicenseToken, verifyRevocationList, withProtectedSpans, words };
|