@bivelio/savings-layer 0.4.28 → 0.4.29
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 +5 -1
- package/dist/gateway/bin.js +516 -512
- package/dist/index.d.ts +59 -7
- package/dist/index.js +1057 -1050
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -311,7 +311,7 @@ declare function precioDeLista(model: string, at?: Date | number): CostModel | u
|
|
|
311
311
|
* on the customer's machine. `test/version-declarada.test.ts` ties this
|
|
312
312
|
* constant to package.json so the two can never drift.
|
|
313
313
|
*/
|
|
314
|
-
declare const BV_SALA_VERSION = "0.4.
|
|
314
|
+
declare const BV_SALA_VERSION = "0.4.29";
|
|
315
315
|
|
|
316
316
|
/**
|
|
317
317
|
* Environment-agnostic UUID generation.
|
|
@@ -483,7 +483,12 @@ interface ChatMessage {
|
|
|
483
483
|
* ids included.
|
|
484
484
|
*/
|
|
485
485
|
toolCalls?: ToolCallRequest[];
|
|
486
|
-
/**
|
|
486
|
+
/**
|
|
487
|
+
* Opaque provider metadata; never used for the exact-cache key. The one
|
|
488
|
+
* exception is `tool_call_id` on a `role: "tool"` message: the OpenAI
|
|
489
|
+
* adapter still sends it as the call id when `toolCallId` is absent,
|
|
490
|
+
* so the key reads it as that same field.
|
|
491
|
+
*/
|
|
487
492
|
metadata?: Record<string, unknown>;
|
|
488
493
|
}
|
|
489
494
|
/** How a request is classified by the execution router. */
|
|
@@ -1121,6 +1126,14 @@ interface SavingsResult<T = unknown> {
|
|
|
1121
1126
|
* (caché/resolver), que solo sirven respuestas finales completas.
|
|
1122
1127
|
*/
|
|
1123
1128
|
finishReason?: string;
|
|
1129
|
+
/**
|
|
1130
|
+
* The refusal message the model returned instead of an answer (OpenAI
|
|
1131
|
+
* Structured Outputs: `message.refusal`, with `finish_reason: "stop"` and no
|
|
1132
|
+
* content). When present, the request was refused: `text` is empty and no
|
|
1133
|
+
* output contract was met. It is measured like any call, and it is never
|
|
1134
|
+
* repaired, cached or replayed.
|
|
1135
|
+
*/
|
|
1136
|
+
refusal?: string;
|
|
1124
1137
|
report: SavingsReport;
|
|
1125
1138
|
}
|
|
1126
1139
|
/** One event of a streamed answer. */
|
|
@@ -1296,8 +1309,9 @@ interface QualityRepairCheck {
|
|
|
1296
1309
|
* - `decode_time_constraint`: generation was already constrained, so a retry
|
|
1297
1310
|
* would not change the outcome.
|
|
1298
1311
|
* - `provider_refusal`: the provider refused the request (`finishReason:
|
|
1299
|
-
* "content_filter"`, Anthropic's `stop_reason: "refusal"
|
|
1300
|
-
* same model would be refused, and may
|
|
1312
|
+
* "content_filter"`, Anthropic's `stop_reason: "refusal"`, or OpenAI's
|
|
1313
|
+
* `message.refusal`); a repair on the same model would be refused, and may
|
|
1314
|
+
* be billed, again.
|
|
1301
1315
|
*/
|
|
1302
1316
|
skipReason?: "output_truncated" | "schema_defect" | "would_cost_more_than_no_layer" | "decode_time_constraint" | "provider_refusal";
|
|
1303
1317
|
}
|
|
@@ -1849,6 +1863,25 @@ interface CanonicalRequest {
|
|
|
1849
1863
|
normalizedText: string;
|
|
1850
1864
|
systemPromptHash: string;
|
|
1851
1865
|
toolsetHash: string;
|
|
1866
|
+
/**
|
|
1867
|
+
* Hash of the tool-loop fields of the conversation, the part of each turn
|
|
1868
|
+
* that `normalizedText` does not carry: the calls on an assistant turn (name,
|
|
1869
|
+
* arguments and id) and, on a `role: "tool"` message, the call it answers,
|
|
1870
|
+
* its error flag and its name. Part of the exact key, the in-flight key and
|
|
1871
|
+
* the semantic filter, so two conversations that differ only there never
|
|
1872
|
+
* share an answer.
|
|
1873
|
+
*
|
|
1874
|
+
* Call ids count by what they pair, not by their value: results matched to
|
|
1875
|
+
* other calls give another hash, while the same conversation with its ids
|
|
1876
|
+
* consistently renamed (a new run of the same agent loop gets fresh ids from
|
|
1877
|
+
* the provider) keeps it.
|
|
1878
|
+
*
|
|
1879
|
+
* Absent when the request carries none of them: the keys are then built from
|
|
1880
|
+
* exactly the same material as before this field existed. A field that is
|
|
1881
|
+
* present but empty or false (`toolCalls: []`, `isError: false`, `name: ""`)
|
|
1882
|
+
* reaches the provider exactly as an absent one, and counts as absent.
|
|
1883
|
+
*/
|
|
1884
|
+
toolTurnsHash?: string;
|
|
1852
1885
|
/** Hash of the structured payload; part of the cache key so different data never collides. */
|
|
1853
1886
|
structuredDataHash: string;
|
|
1854
1887
|
schemaVersion: string;
|
|
@@ -2122,6 +2155,13 @@ interface SemanticRecord {
|
|
|
2122
2155
|
safetyPolicyVersion: string;
|
|
2123
2156
|
/** Hash of the declared tool catalog (ids, risk and parameters). */
|
|
2124
2157
|
toolsetHash: string;
|
|
2158
|
+
/**
|
|
2159
|
+
* Hash of the tool-loop fields of the conversation (tool calls, the call each
|
|
2160
|
+
* tool result answers, its error flag and name); absent when it had none.
|
|
2161
|
+
* Compared for equality like the other identity fields: similarity is scored
|
|
2162
|
+
* on text only, and never decides between two tool loops.
|
|
2163
|
+
*/
|
|
2164
|
+
toolTurnsHash?: string;
|
|
2125
2165
|
/** Sampling temperature of the request, or null when it set none. */
|
|
2126
2166
|
temperature: number | null;
|
|
2127
2167
|
/** Sampling seed of the request, or null when it set none. */
|
|
@@ -3138,6 +3178,17 @@ interface ProviderResponse {
|
|
|
3138
3178
|
* podía distinguirlo y hacía exactamente eso.
|
|
3139
3179
|
*/
|
|
3140
3180
|
finishReason?: "stop" | "length" | "content_filter" | "tool_calls" | (string & {});
|
|
3181
|
+
/**
|
|
3182
|
+
* The refusal message the model returned INSTEAD of an answer, exactly as the
|
|
3183
|
+
* provider wrote it: OpenAI's `message.refusal` (Chat Completions with
|
|
3184
|
+
* Structured Outputs), which arrives with `finish_reason: "stop"` and no
|
|
3185
|
+
* `content`. Present only when non-empty.
|
|
3186
|
+
*
|
|
3187
|
+
* The layer treats it like `finishReason: "content_filter"`: the call is
|
|
3188
|
+
* measured, and the answer is never repaired against its contract, cached, or
|
|
3189
|
+
* replayed by reference. `text` and `finishReason` stay what the provider said.
|
|
3190
|
+
*/
|
|
3191
|
+
refusal?: string;
|
|
3141
3192
|
/**
|
|
3142
3193
|
* Llamadas a herramienta que pidió el modelo, tal cual las devolvió el
|
|
3143
3194
|
* proveedor.
|
|
@@ -3724,7 +3775,8 @@ interface SavingsLayerConfig {
|
|
|
3724
3775
|
* revocation list going stale. Nothing here throws and nothing here changes
|
|
3725
3776
|
* what the layer does — turning it on only removes the console noise, so set
|
|
3726
3777
|
* it when you have your own observability. Applies to the pipeline, the usage
|
|
3727
|
-
* emitter
|
|
3778
|
+
* emitter, the revocation poller and the provider adapters shipped in this
|
|
3779
|
+
* package alike.
|
|
3728
3780
|
*/
|
|
3729
3781
|
silenceWarnings?: boolean;
|
|
3730
3782
|
/**
|
|
@@ -4104,7 +4156,8 @@ declare const registrarTokenizadorExacto: typeof registerExactTokenizer;
|
|
|
4104
4156
|
*
|
|
4105
4157
|
* A hash of the user text alone is NOT a safe cache key. Two requests may share
|
|
4106
4158
|
* text but differ in tenant, permission scope, model version, system prompt,
|
|
4107
|
-
* schema, toolset,
|
|
4159
|
+
* schema, toolset, tool-loop fields (tool calls, the call a tool result answers,
|
|
4160
|
+
* its error flag), locale, sampling, knowledge epoch or safety policy — any of
|
|
4108
4161
|
* which can change the correct answer. The exact key includes all of them.
|
|
4109
4162
|
*
|
|
4110
4163
|
* `servedModel` CARRIES THE MODEL THAT WILL ACTUALLY ANSWER, not the one the
|
|
@@ -4902,7 +4955,6 @@ declare class RevocationPoller {
|
|
|
4902
4955
|
private consecutiveFailures;
|
|
4903
4956
|
private stopped;
|
|
4904
4957
|
private started;
|
|
4905
|
-
private warnedNoFetch;
|
|
4906
4958
|
/** ETag of the last 200; sent as If-None-Match so an unchanged list 304s (cheap no-op). */
|
|
4907
4959
|
private lastEtag;
|
|
4908
4960
|
/** 304 seguidos; al llegar al tope se fuerza una descarga firmada. */
|