@hostwebhook/platform-contracts 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -49,9 +49,32 @@
|
|
|
49
49
|
*
|
|
50
50
|
* ## Lo que esta tabla NO modela (aceptable para estimar coste)
|
|
51
51
|
*
|
|
52
|
-
* -
|
|
53
|
-
*
|
|
54
|
-
*
|
|
52
|
+
* - (RESUELTO, ver `umbralEntrada`) Contexto largo. Ya se modela en los diez
|
|
53
|
+
* modelos que lo publican: los siete de OpenAI 5.4/5.5/5.6 a partir de
|
|
54
|
+
* 272.000 tokens de entrada, y `gemini-3.1-pro` / `gemini-2.5-pro` a partir
|
|
55
|
+
* de 200.000. Es un ACANTILADO: la tarifa alta cubre la petición entera.
|
|
56
|
+
* - (!) Lo que del contexto largo SIGUE sin modelarse: en `gpt-5.5` y en
|
|
57
|
+
* `gpt-5.4` la ficha dice «for the full SESSION», no por petición. Basta que
|
|
58
|
+
* UNA llamada de la sesión cruce 272k para que toda la sesión vaya a tarifa
|
|
59
|
+
* alta. `calculateCost` es una función pura por llamada y no tiene noción de
|
|
60
|
+
* sesión: ahí INFRAVALORA, y se dice en vez de fingir que se modela.
|
|
61
|
+
* - ✅ Anthropic NO tiene tramos, y conviene dejarlo escrito en afirmativo:
|
|
62
|
+
* su doc dice que «Claude 4.6 and later models include the full 1M token
|
|
63
|
+
* context window at standard pricing». La regla que circula por terceros
|
|
64
|
+
* diciendo que Sonnet 4.5 cobra 2x/1.5x por encima de 200k es FALSA. No
|
|
65
|
+
* reintroducirla.
|
|
66
|
+
* - (!) `gpt-5.6-sol` (y su alias `gpt-5.6`) está a precio PROMOCIONAL: la
|
|
67
|
+
* propia tabla dice «available at least through November 21, 2026», y no
|
|
68
|
+
* publica a cuánto revierte. Un tope calibrado sobre 4.00/20.00 tiene fecha
|
|
69
|
+
* de caducidad documentada.
|
|
70
|
+
* - (!) Google factura los tokens de RAZONAMIENTO a precio de salida — el
|
|
71
|
+
* encabezado de su columna dice «Output price (including thinking tokens)».
|
|
72
|
+
* Quien multiplique sólo los tokens visibles por `output` se queda corto, y
|
|
73
|
+
* el razonamiento no se ve en la respuesta pero sí en la factura.
|
|
74
|
+
* - (!) Claude 4.7 en adelante usa un tokenizador que produce ~30% MÁS tokens
|
|
75
|
+
* para el mismo texto, y eso incluye Sonnet 5, Opus 5, Opus 4.8 y Opus 4.7,
|
|
76
|
+
* no sólo Fable 5. Sonnet 5 a $2 frente a Sonnet 4.6 a $3 parece un 33%
|
|
77
|
+
* más barato; con un 30% más de tokens el ahorro real se acerca a cero.
|
|
55
78
|
* - Audio: `gemini-2.5-flash` y `3.1-flash-lite` cobran más el audio que el
|
|
56
79
|
* texto. Aquí todo va a tarifa de texto.
|
|
57
80
|
* - Anthropic: `inference_geo` "us" multiplica por 1,1, y el modo rápido de
|
|
@@ -67,7 +90,42 @@
|
|
|
67
90
|
export interface ModelPricing {
|
|
68
91
|
input: number;
|
|
69
92
|
output: number;
|
|
93
|
+
/**
|
|
94
|
+
* Tokens de ENTRADA por encima de los cuales la petición cambia de tarifa.
|
|
95
|
+
* Ausente = tarifa plana en toda la ventana, que es el caso de Anthropic y de
|
|
96
|
+
* casi todo lo demás.
|
|
97
|
+
*
|
|
98
|
+
* El nombre dice qué se mide: los dos proveedores que tienen tramos lo miden
|
|
99
|
+
* sobre el PROMPT, nunca sobre entrada+salida. En Google la palabra literal de
|
|
100
|
+
* las tres filas de su tabla es «prompts».
|
|
101
|
+
*
|
|
102
|
+
* (!) La comparación es ESTRICTA: OpenAI escribe «>272K» y Google «> 200k».
|
|
103
|
+
* Exactamente 272.000 va a tarifa base.
|
|
104
|
+
*/
|
|
105
|
+
umbralEntrada?: number;
|
|
106
|
+
/**
|
|
107
|
+
* (!) NO es facturación marginal: es un ACANTILADO. La tarifa alta se aplica
|
|
108
|
+
* a TODOS los tokens de la petición, no sólo a los que exceden el umbral.
|
|
109
|
+
*
|
|
110
|
+
* Un prompt de 272.001 tokens en `gpt-5.5` se cobra ENTERO a $10, no 272.000
|
|
111
|
+
* a $5 más uno a $10. Cruzar el umbral por un token duplica la factura de
|
|
112
|
+
* entrada de esa llamada y encarece un 50 % su salida aunque la salida sean
|
|
113
|
+
* cincuenta tokens.
|
|
114
|
+
*/
|
|
115
|
+
inputLargo?: number;
|
|
116
|
+
outputLargo?: number;
|
|
70
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* La tarifa que toca, según cuánta entrada lleve la petición.
|
|
120
|
+
*
|
|
121
|
+
* Se saca aparte de `calculateCost` porque quien quiera estimar ANTES de llamar
|
|
122
|
+
* —la reserva del tope de gasto del Chat Trigger— necesita la misma decisión sin
|
|
123
|
+
* tener aún los tokens de salida.
|
|
124
|
+
*/
|
|
125
|
+
export declare function tarifaDelTramo(precio: ModelPricing, tokensDeEntrada: number): {
|
|
126
|
+
input: number;
|
|
127
|
+
output: number;
|
|
128
|
+
};
|
|
71
129
|
export declare const MODEL_PRICING: Record<string, ModelPricing>;
|
|
72
130
|
/**
|
|
73
131
|
* Qué entrada de la tabla pone precio a este modelo, o `null` cuando de verdad
|
|
@@ -50,9 +50,32 @@
|
|
|
50
50
|
*
|
|
51
51
|
* ## Lo que esta tabla NO modela (aceptable para estimar coste)
|
|
52
52
|
*
|
|
53
|
-
* -
|
|
54
|
-
*
|
|
55
|
-
*
|
|
53
|
+
* - (RESUELTO, ver `umbralEntrada`) Contexto largo. Ya se modela en los diez
|
|
54
|
+
* modelos que lo publican: los siete de OpenAI 5.4/5.5/5.6 a partir de
|
|
55
|
+
* 272.000 tokens de entrada, y `gemini-3.1-pro` / `gemini-2.5-pro` a partir
|
|
56
|
+
* de 200.000. Es un ACANTILADO: la tarifa alta cubre la petición entera.
|
|
57
|
+
* - (!) Lo que del contexto largo SIGUE sin modelarse: en `gpt-5.5` y en
|
|
58
|
+
* `gpt-5.4` la ficha dice «for the full SESSION», no por petición. Basta que
|
|
59
|
+
* UNA llamada de la sesión cruce 272k para que toda la sesión vaya a tarifa
|
|
60
|
+
* alta. `calculateCost` es una función pura por llamada y no tiene noción de
|
|
61
|
+
* sesión: ahí INFRAVALORA, y se dice en vez de fingir que se modela.
|
|
62
|
+
* - ✅ Anthropic NO tiene tramos, y conviene dejarlo escrito en afirmativo:
|
|
63
|
+
* su doc dice que «Claude 4.6 and later models include the full 1M token
|
|
64
|
+
* context window at standard pricing». La regla que circula por terceros
|
|
65
|
+
* diciendo que Sonnet 4.5 cobra 2x/1.5x por encima de 200k es FALSA. No
|
|
66
|
+
* reintroducirla.
|
|
67
|
+
* - (!) `gpt-5.6-sol` (y su alias `gpt-5.6`) está a precio PROMOCIONAL: la
|
|
68
|
+
* propia tabla dice «available at least through November 21, 2026», y no
|
|
69
|
+
* publica a cuánto revierte. Un tope calibrado sobre 4.00/20.00 tiene fecha
|
|
70
|
+
* de caducidad documentada.
|
|
71
|
+
* - (!) Google factura los tokens de RAZONAMIENTO a precio de salida — el
|
|
72
|
+
* encabezado de su columna dice «Output price (including thinking tokens)».
|
|
73
|
+
* Quien multiplique sólo los tokens visibles por `output` se queda corto, y
|
|
74
|
+
* el razonamiento no se ve en la respuesta pero sí en la factura.
|
|
75
|
+
* - (!) Claude 4.7 en adelante usa un tokenizador que produce ~30% MÁS tokens
|
|
76
|
+
* para el mismo texto, y eso incluye Sonnet 5, Opus 5, Opus 4.8 y Opus 4.7,
|
|
77
|
+
* no sólo Fable 5. Sonnet 5 a $2 frente a Sonnet 4.6 a $3 parece un 33%
|
|
78
|
+
* más barato; con un 30% más de tokens el ahorro real se acerca a cero.
|
|
56
79
|
* - Audio: `gemini-2.5-flash` y `3.1-flash-lite` cobran más el audio que el
|
|
57
80
|
* texto. Aquí todo va a tarifa de texto.
|
|
58
81
|
* - Anthropic: `inference_geo` "us" multiplica por 1,1, y el modo rápido de
|
|
@@ -67,25 +90,44 @@
|
|
|
67
90
|
*/
|
|
68
91
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
69
92
|
exports.MODEL_ALTERNATIVES = exports.MODEL_PRICING = void 0;
|
|
93
|
+
exports.tarifaDelTramo = tarifaDelTramo;
|
|
70
94
|
exports.findPricingKey = findPricingKey;
|
|
71
95
|
exports.isModelPriced = isModelPriced;
|
|
72
96
|
exports.calculateCost = calculateCost;
|
|
73
97
|
exports.getKnownModels = getKnownModels;
|
|
74
98
|
exports.getSuggestedAlternative = getSuggestedAlternative;
|
|
99
|
+
/**
|
|
100
|
+
* La tarifa que toca, según cuánta entrada lleve la petición.
|
|
101
|
+
*
|
|
102
|
+
* Se saca aparte de `calculateCost` porque quien quiera estimar ANTES de llamar
|
|
103
|
+
* —la reserva del tope de gasto del Chat Trigger— necesita la misma decisión sin
|
|
104
|
+
* tener aún los tokens de salida.
|
|
105
|
+
*/
|
|
106
|
+
function tarifaDelTramo(precio, tokensDeEntrada) {
|
|
107
|
+
if (precio.umbralEntrada === undefined) {
|
|
108
|
+
return { input: precio.input, output: precio.output };
|
|
109
|
+
}
|
|
110
|
+
if (tokensDeEntrada <= precio.umbralEntrada) {
|
|
111
|
+
return { input: precio.input, output: precio.output };
|
|
112
|
+
}
|
|
113
|
+
return { input: precio.inputLargo, output: precio.outputLargo };
|
|
114
|
+
}
|
|
75
115
|
exports.MODEL_PRICING = {
|
|
76
116
|
// OpenAI — GPT series
|
|
77
|
-
'gpt-5.6-sol': { input: 4.00, output: 20.00 },
|
|
117
|
+
'gpt-5.6-sol': { input: 4.00, output: 20.00, umbralEntrada: 272000, inputLargo: 8.00, outputLargo: 30.00 },
|
|
78
118
|
// `gpt-5.6` a secas es el alias documentado de Sol, y sin esta entrada caia
|
|
79
119
|
// por prefijo en `gpt-5` — otro modelo y otro precio.
|
|
80
|
-
'gpt-5.6': { input: 4.00, output: 20.00 },
|
|
81
|
-
'gpt-5.6-terra': { input: 2.00, output: 12.00 },
|
|
82
|
-
'gpt-5.6-luna': { input: 0.20, output: 1.20 },
|
|
83
|
-
'gpt-5.5-pro': { input: 30.00, output: 180.00 },
|
|
84
|
-
'gpt-5.5': { input: 5.00, output: 30.00 },
|
|
85
|
-
'gpt-5.4-pro': { input: 30.00, output: 180.00 },
|
|
86
|
-
'gpt-5.4': { input: 2.50, output: 15.00 },
|
|
120
|
+
'gpt-5.6': { input: 4.00, output: 20.00, umbralEntrada: 272000, inputLargo: 8.00, outputLargo: 30.00 },
|
|
121
|
+
'gpt-5.6-terra': { input: 2.00, output: 12.00, umbralEntrada: 272000, inputLargo: 4.00, outputLargo: 18.00 },
|
|
122
|
+
'gpt-5.6-luna': { input: 0.20, output: 1.20, umbralEntrada: 272000, inputLargo: 0.40, outputLargo: 1.80 },
|
|
123
|
+
'gpt-5.5-pro': { input: 30.00, output: 180.00, umbralEntrada: 272000, inputLargo: 60.00, outputLargo: 270.00 },
|
|
124
|
+
'gpt-5.5': { input: 5.00, output: 30.00, umbralEntrada: 272000, inputLargo: 10.00, outputLargo: 45.00 },
|
|
125
|
+
'gpt-5.4-pro': { input: 30.00, output: 180.00, umbralEntrada: 272000, inputLargo: 60.00, outputLargo: 270.00 },
|
|
126
|
+
'gpt-5.4': { input: 2.50, output: 15.00, umbralEntrada: 272000, inputLargo: 5.00, outputLargo: 22.50 },
|
|
87
127
|
'gpt-5.4-mini': { input: 0.75, output: 4.50 },
|
|
88
128
|
'gpt-5.4-nano': { input: 0.20, output: 1.25 },
|
|
129
|
+
// (!) SIN tramo, y es deliberado: es el unico *-pro de la familia 5.x cuya
|
|
130
|
+
// ficha no publica umbral de contexto largo. Verificado fila a fila.
|
|
89
131
|
'gpt-5.2-pro': { input: 21.00, output: 168.00 },
|
|
90
132
|
'gpt-5.2': { input: 1.75, output: 14.00 },
|
|
91
133
|
'gpt-5.1': { input: 1.25, output: 10.00 },
|
|
@@ -169,10 +211,10 @@ exports.MODEL_PRICING = {
|
|
|
169
211
|
'gemini-3.6-flash': { input: 0.75, output: 3.75 },
|
|
170
212
|
'gemini-3.5-flash-lite': { input: 0.30, output: 2.50 },
|
|
171
213
|
'gemini-3.5-flash': { input: 1.50, output: 9.00 },
|
|
172
|
-
'gemini-3.1-pro': { input: 2.00, output: 12.00 },
|
|
214
|
+
'gemini-3.1-pro': { input: 2.00, output: 12.00, umbralEntrada: 200000, inputLargo: 4.00, outputLargo: 18.00 },
|
|
173
215
|
'gemini-3.1-flash-lite': { input: 0.25, output: 1.50 },
|
|
174
216
|
'gemini-3-flash': { input: 0.50, output: 3.00 },
|
|
175
|
-
'gemini-2.5-pro': { input: 1.25, output: 10.00 },
|
|
217
|
+
'gemini-2.5-pro': { input: 1.25, output: 10.00, umbralEntrada: 200000, inputLargo: 2.50, outputLargo: 15.00 },
|
|
176
218
|
'gemini-2.5-flash': { input: 0.30, output: 2.50 },
|
|
177
219
|
'gemini-2.5-flash-lite': { input: 0.10, output: 0.40 },
|
|
178
220
|
'gemini-2.0-flash': { input: 0.10, output: 0.40 },
|
|
@@ -304,13 +346,27 @@ function calculateCost(model, inputTokens, outputTokens, cacheReadInputTokens =
|
|
|
304
346
|
return 0;
|
|
305
347
|
const pricing = exports.MODEL_PRICING[key];
|
|
306
348
|
const provider = detectProvider(key);
|
|
307
|
-
|
|
308
|
-
|
|
349
|
+
/**
|
|
350
|
+
* Los tokens cacheados CUENTAN para decidir el tramo: fisicamente son el
|
|
351
|
+
* prompt, y en un tope de gasto errar del lado caro es errar del lado seguro.
|
|
352
|
+
*
|
|
353
|
+
* (!) Ninguno de los dos proveedores lo dice explicitamente, asi que es una
|
|
354
|
+
* decision nuestra, no una cita. Hoy es INERTE —los llamadores pasan tres
|
|
355
|
+
* argumentos y el emisor de trazas nunca rellena los campos de cache—, pero
|
|
356
|
+
* hay que confirmarla antes de que alguien empiece a rellenarlos.
|
|
357
|
+
*/
|
|
358
|
+
const entradaParaElTramo = inputTokens + cacheReadInputTokens + cacheCreationInputTokens;
|
|
359
|
+
const tarifa = tarifaDelTramo(pricing, entradaParaElTramo);
|
|
360
|
+
const inputCost = (inputTokens / 1000000) * tarifa.input;
|
|
361
|
+
const outputCost = (outputTokens / 1000000) * tarifa.output;
|
|
309
362
|
// Caché: multiplicadores por proveedor
|
|
310
363
|
const cacheReadMul = CACHE_READ_MULTIPLIERS[provider] ?? 0.1;
|
|
311
364
|
const cacheCreationMul = CACHE_CREATION_MULTIPLIERS[provider] ?? 0;
|
|
312
|
-
|
|
313
|
-
|
|
365
|
+
// Sobre `tarifa.input`, no sobre `pricing.input`: en tramo alto la cache
|
|
366
|
+
// tambien se encarece, que es lo que dice la tabla de Google —su fila de
|
|
367
|
+
// cache esta partida por tamano de prompt igual que las otras dos.
|
|
368
|
+
const cacheReadCost = (cacheReadInputTokens / 1000000) * tarifa.input * cacheReadMul;
|
|
369
|
+
const cacheCreationCost = (cacheCreationInputTokens / 1000000) * tarifa.input * cacheCreationMul;
|
|
314
370
|
return (Math.round((inputCost + outputCost + cacheReadCost + cacheCreationCost) * 1000000) / 1000000);
|
|
315
371
|
}
|
|
316
372
|
/** Los modelos que la tabla sabe poner en precio, en orden de declaración. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hostwebhook/platform-contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Contratos compartidos entre los servicios de HostWebhook: addons del plan, identidad interna, y las formas que cruzan una frontera de red",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|