@hostwebhook/platform-contracts 0.8.0 → 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,22 +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 },
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
'gpt-5.
|
|
81
|
-
'gpt-5.
|
|
82
|
-
'gpt-5.
|
|
83
|
-
'gpt-5.
|
|
117
|
+
'gpt-5.6-sol': { input: 4.00, output: 20.00, umbralEntrada: 272000, inputLargo: 8.00, outputLargo: 30.00 },
|
|
118
|
+
// `gpt-5.6` a secas es el alias documentado de Sol, y sin esta entrada caia
|
|
119
|
+
// por prefijo en `gpt-5` — otro modelo y otro precio.
|
|
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 },
|
|
84
127
|
'gpt-5.4-mini': { input: 0.75, output: 4.50 },
|
|
85
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.
|
|
86
131
|
'gpt-5.2-pro': { input: 21.00, output: 168.00 },
|
|
87
132
|
'gpt-5.2': { input: 1.75, output: 14.00 },
|
|
88
133
|
'gpt-5.1': { input: 1.25, output: 10.00 },
|
|
@@ -132,6 +177,30 @@ exports.MODEL_PRICING = {
|
|
|
132
177
|
'claude-sonnet-4': { input: 3.00, output: 15.00 },
|
|
133
178
|
'claude-sonnet-4-20250514': { input: 3.00, output: 15.00 },
|
|
134
179
|
'claude-haiku-4-5-20251001': { input: 1.00, output: 5.00 },
|
|
180
|
+
// (!) Sin apellido de fecha, y NO es redundante: la clave fechada es mas
|
|
181
|
+
// LARGA, asi que la regla de prefijo nunca alcanzaba a `claude-haiku-4-5`.
|
|
182
|
+
// Y ese es `getDefaultModel('anthropic')` —con el nace todo nodo de IA— y
|
|
183
|
+
// tambien `PLATFORM_LLM_CHEAP_MODEL`. Mientras falto, cada nodo nuevo salia
|
|
184
|
+
// a coste CERO y su tope de gasto en dolares no podia saltar jamas.
|
|
185
|
+
'claude-haiku-4-5': { input: 1.00, output: 5.00 },
|
|
186
|
+
// ── Groq ────────────────────────────────────────────────────────────────
|
|
187
|
+
// (!) Estas tres NO estan verificadas contra una pagina oficial de Groq:
|
|
188
|
+
// console.groq.com/docs/pricing da 404 y groq.com/pricing es marketing. Salen
|
|
189
|
+
// de agregadores de terceros coincidentes entre si (agosto 2026). Reverificar
|
|
190
|
+
// en cuanto Groq publique una pagina consultable.
|
|
191
|
+
//
|
|
192
|
+
// Aun asi entran: sin ellas el coste sale CERO, y cero no es "barato", es
|
|
193
|
+
// "un tope de gasto que no salta". Una cifra aproximada de la fuente correcta
|
|
194
|
+
// protege; la ausencia no protege nada.
|
|
195
|
+
'openai/gpt-oss-20b': { input: 0.075, output: 0.30 },
|
|
196
|
+
'openai/gpt-oss-120b': { input: 0.15, output: 0.60 },
|
|
197
|
+
'qwen/qwen3.6-27b': { input: 0.60, output: 3.00 },
|
|
198
|
+
//
|
|
199
|
+
// `groq/compound` y `groq/compound-mini` NO se ponen, y no por falta de dato:
|
|
200
|
+
// es que NO TIENEN tarifa plana por token. Son sistemas agenticos que
|
|
201
|
+
// repercuten el modelo subyacente MAS el coste de las herramientas que usan,
|
|
202
|
+
// asi que no hay un numero unico que sea correcto. Inventar uno seria peor que
|
|
203
|
+
// el hueco. Quedan en la lista de excepciones del test, con este motivo.
|
|
135
204
|
'claude-3-7-sonnet-20250219': { input: 3.00, output: 15.00 },
|
|
136
205
|
'claude-3-5-sonnet-20241022': { input: 3.00, output: 15.00 },
|
|
137
206
|
'claude-3-5-haiku-20241022': { input: 0.80, output: 4.00 },
|
|
@@ -142,10 +211,10 @@ exports.MODEL_PRICING = {
|
|
|
142
211
|
'gemini-3.6-flash': { input: 0.75, output: 3.75 },
|
|
143
212
|
'gemini-3.5-flash-lite': { input: 0.30, output: 2.50 },
|
|
144
213
|
'gemini-3.5-flash': { input: 1.50, output: 9.00 },
|
|
145
|
-
'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 },
|
|
146
215
|
'gemini-3.1-flash-lite': { input: 0.25, output: 1.50 },
|
|
147
216
|
'gemini-3-flash': { input: 0.50, output: 3.00 },
|
|
148
|
-
'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 },
|
|
149
218
|
'gemini-2.5-flash': { input: 0.30, output: 2.50 },
|
|
150
219
|
'gemini-2.5-flash-lite': { input: 0.10, output: 0.40 },
|
|
151
220
|
'gemini-2.0-flash': { input: 0.10, output: 0.40 },
|
|
@@ -277,13 +346,27 @@ function calculateCost(model, inputTokens, outputTokens, cacheReadInputTokens =
|
|
|
277
346
|
return 0;
|
|
278
347
|
const pricing = exports.MODEL_PRICING[key];
|
|
279
348
|
const provider = detectProvider(key);
|
|
280
|
-
|
|
281
|
-
|
|
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;
|
|
282
362
|
// Caché: multiplicadores por proveedor
|
|
283
363
|
const cacheReadMul = CACHE_READ_MULTIPLIERS[provider] ?? 0.1;
|
|
284
364
|
const cacheCreationMul = CACHE_CREATION_MULTIPLIERS[provider] ?? 0;
|
|
285
|
-
|
|
286
|
-
|
|
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;
|
|
287
370
|
return (Math.round((inputCost + outputCost + cacheReadCost + cacheCreationCost) * 1000000) / 1000000);
|
|
288
371
|
}
|
|
289
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",
|