@productmaker/mcp 8.5.0 → 8.5.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/README.md +4 -0
- package/dist/http.js +93 -43
- package/dist/stdio.js +93 -43
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -269,6 +269,10 @@ The `base64` field was removed. MCP JSON-RPC transports truncate large tool argu
|
|
|
269
269
|
|
|
270
270
|
## Version history
|
|
271
271
|
|
|
272
|
+
### 8.5.1 — Escenas silenciosas aprobables
|
|
273
|
+
|
|
274
|
+
- `approve_video_script` admite `dialogue: ""` en el esquema: las escenas silenciosas por diseño (`silentAllowed` en `get_video_script` — shots `productOnly` o ángulos winner-copy) son legales y antes el esquema las rechazaba con error de validación antes de llegar a la API. Una escena hablada con diálogo vacío sigue rechazada por el backend con 400.
|
|
275
|
+
|
|
272
276
|
### 8.5.0 — Estudio de mercado apagado por default
|
|
273
277
|
|
|
274
278
|
- `competitorScanEnabled` omitido ya no activa el estudio de mercado: la API trata la omisión de un llamador API/MCP como `false` (sin escaneo de competencia ni reserva de réplica del ganador, también en la cotización). La web no cambia.
|
package/dist/http.js
CHANGED
|
@@ -5256,7 +5256,10 @@ var ApproveVideoScriptRequest = z27.object({
|
|
|
5256
5256
|
angleKey: z27.string().trim().min(1).max(120).optional(),
|
|
5257
5257
|
scenes: z27.array(z27.object({
|
|
5258
5258
|
index: z27.number().int().nonnegative(),
|
|
5259
|
-
|
|
5259
|
+
// Empty is admitted at the wire: only the service knows whether the
|
|
5260
|
+
// shot is a designed-silent beat (productOnly / winner-copy), so the
|
|
5261
|
+
// per-shot empty-line policy lives there — NOT here.
|
|
5262
|
+
dialogue: z27.string().trim().max(VIDEO_SCRIPT_APPROVAL_MAX_DIALOGUE_CHARS)
|
|
5260
5263
|
}).strict()).min(1).max(VIDEO_SCRIPT_APPROVAL_MAX_SCENES)
|
|
5261
5264
|
}).strict();
|
|
5262
5265
|
var ApproveVideoScriptResponse = z27.object({
|
|
@@ -8645,13 +8648,16 @@ var DEFAULT_PRICING = {
|
|
|
8645
8648
|
ourCostCents: 0.07,
|
|
8646
8649
|
userPriceCents: 0.14
|
|
8647
8650
|
},
|
|
8651
|
+
// Both rewrites: RE-DERIVED 2026-09-28 from 14d of prod BillingEntry.
|
|
8652
|
+
// final-simplify n=123 mean 1.26¢ / p95 1.98¢ user; targeted-retry n=439 mean 2.09¢ /
|
|
8653
|
+
// p95 3.37¢ user. The old 0.8¢ (a Flash-era guess) under-quoted both 2.5-4x.
|
|
8648
8654
|
"openrouter:video-final-simplify-rewrite": {
|
|
8649
|
-
ourCostCents:
|
|
8650
|
-
userPriceCents:
|
|
8655
|
+
ourCostCents: 1,
|
|
8656
|
+
userPriceCents: 2
|
|
8651
8657
|
},
|
|
8652
8658
|
"openrouter:video-targeted-retry-rewrite": {
|
|
8653
|
-
ourCostCents:
|
|
8654
|
-
userPriceCents:
|
|
8659
|
+
ourCostCents: 1.7,
|
|
8660
|
+
userPriceCents: 3.4
|
|
8655
8661
|
},
|
|
8656
8662
|
// For helper-recorded entries (`callOpenRouter`), `ourCostCents` here is
|
|
8657
8663
|
// only used when `usage.cost` is missing from the provider response —
|
|
@@ -9713,11 +9719,15 @@ var DEFAULT_PRICING = {
|
|
|
9713
9719
|
// Video QA — combined describe+judge pass. The DETECTOR runs on gemini-3.8-flash at
|
|
9714
9720
|
// reasoning.effort=high (recall-critical: it gates a $2-4 re-render). Real billing
|
|
9715
9721
|
// uses OpenRouter's per-call usage.cost (×2), so this value is ONLY the estimator
|
|
9716
|
-
// basis + the rare fallback when usage.cost is missing
|
|
9717
|
-
//
|
|
9722
|
+
// basis + the rare fallback when usage.cost is missing.
|
|
9723
|
+
// RE-DERIVED 2026-09-28 (14d prod BillingEntry):
|
|
9724
|
+
// n=2073, mean 3.57¢ / p95 8.95¢ / p99 12.04¢ / max 13.50¢ user per call.
|
|
9725
|
+
// 12¢ sits at the p99 and still covers DETECTOR_MAX_CALLS (3) × the mean (10.71¢) —
|
|
9726
|
+
// the invariant pinned in cost-estimator.spec.test.ts. The former 20¢ was sized to a
|
|
9727
|
+
// Pro+high call that no longer runs and inflated every QA pass of the credit gate.
|
|
9718
9728
|
"openrouter:video-qa-describe-judge": {
|
|
9719
|
-
ourCostCents:
|
|
9720
|
-
userPriceCents:
|
|
9729
|
+
ourCostCents: 6,
|
|
9730
|
+
userPriceCents: 12
|
|
9721
9731
|
},
|
|
9722
9732
|
// Video QA — hand scanner reinforcement (Gemini 3.7 Flash, dense frames around spike)
|
|
9723
9733
|
"openrouter:video-hand-reinforcement": {
|
|
@@ -9786,13 +9796,16 @@ var DEFAULT_PRICING = {
|
|
|
9786
9796
|
userPriceCents: 0.22
|
|
9787
9797
|
},
|
|
9788
9798
|
// Clip Judge — text-only comparison of QA results between original and retry clips
|
|
9789
|
-
// (google/gemini-3.8-flash, text-only).
|
|
9799
|
+
// (google/gemini-3.8-flash, text-only). RE-DERIVED 2026-09-28 (14d prod BillingEntry):
|
|
9800
|
+
// n=92, mean 0.34¢ / p95 0.54¢ user
|
|
9801
|
+
// (the old 0.12¢ assumed ~$0.0006 and under-quoted 4.5x).
|
|
9790
9802
|
"openrouter:clip-judge-text": {
|
|
9791
|
-
ourCostCents: 0.
|
|
9792
|
-
userPriceCents: 0.
|
|
9803
|
+
ourCostCents: 0.28,
|
|
9804
|
+
userPriceCents: 0.56
|
|
9793
9805
|
},
|
|
9794
9806
|
// Clip Judge — vision comparison of two video clips (google/gemini-3.8-flash, 2 videos)
|
|
9795
|
-
// Our cost: ~$0.01 => 1.0 cents; 2x markup.
|
|
9807
|
+
// Our cost: ~$0.01 => 1.0 cents; 2x markup. Checked 2026-09-28 (n=346): mean 1.38¢ /
|
|
9808
|
+
// p95 1.90¢ user — already covered, unchanged.
|
|
9796
9809
|
"openrouter:clip-judge-vision": {
|
|
9797
9810
|
ourCostCents: 1,
|
|
9798
9811
|
userPriceCents: 2
|
|
@@ -9809,10 +9822,13 @@ var DEFAULT_PRICING = {
|
|
|
9809
9822
|
ourCostCents: 0.89,
|
|
9810
9823
|
userPriceCents: 1.78
|
|
9811
9824
|
},
|
|
9812
|
-
// Video QA — product integrity scanner (
|
|
9825
|
+
// Video QA — product integrity scanner (gemini-3.8-flash, 5 frames + reference).
|
|
9826
|
+
// RE-DERIVED 2026-09-28 (14d prod BillingEntry):
|
|
9827
|
+
// n=1828, mean 2.91¢ / p95 5.07¢ / max 11.50¢ user per call. The old 0.3¢
|
|
9828
|
+
// (a 3.7-Flash-era guess) under-quoted it ~10x on every QA pass.
|
|
9813
9829
|
"openrouter:video-product-integrity": {
|
|
9814
|
-
ourCostCents:
|
|
9815
|
-
userPriceCents:
|
|
9830
|
+
ourCostCents: 2.6,
|
|
9831
|
+
userPriceCents: 5.2
|
|
9816
9832
|
},
|
|
9817
9833
|
// Video QA — anatomy. THREE keys, and they do NOT share a unit. Getting this wrong
|
|
9818
9834
|
// over-charges by ~42x, which is exactly what a first pass at the 2026-07-30 change did.
|
|
@@ -9850,11 +9866,35 @@ var DEFAULT_PRICING = {
|
|
|
9850
9866
|
userPriceCents: 0.4
|
|
9851
9867
|
},
|
|
9852
9868
|
// (c) Tracing confirmation of a frames-only finding: 3 stills + the full downscaled video,
|
|
9853
|
-
// one call.
|
|
9854
|
-
//
|
|
9869
|
+
// one call. RE-DERIVED 2026-09-28 (14d prod BillingEntry):
|
|
9870
|
+
// n=46, mean 2.67¢ / p95 4.48¢ / max 5.43¢ user — the
|
|
9871
|
+
// former 3.0¢ (from a 14-call spike, 0.59¢ our mean) sat below the prod p95.
|
|
9855
9872
|
"openrouter:video-qa-anatomy-tracing-confirm": {
|
|
9856
|
-
ourCostCents:
|
|
9857
|
-
userPriceCents:
|
|
9873
|
+
ourCostCents: 2.25,
|
|
9874
|
+
userPriceCents: 4.5
|
|
9875
|
+
},
|
|
9876
|
+
// (d) DENSE anatomy detector (the default anatomy detector since 2026-09-26;
|
|
9877
|
+
// QA_ANATOMY_DETECTOR=frame_judge reverts): gemini-3.1-pro judges every extracted
|
|
9878
|
+
// frame at 1 fps, 5 frames per call, each call billing its frame count — the rate is
|
|
9879
|
+
// PER FRAME like (b) and scales with QA_DENSE_DETECTOR_MAX_FRAMES. Measured on the
|
|
9880
|
+
// owner corpus with the shipped config (reasoning=low, grouped): $1.062 / 296 frames
|
|
9881
|
+
// ≈ 0.36c/frame; 0.5c keeps ~40% headroom. The old 3.0c fallback was the 2026-09-22
|
|
9882
|
+
// one-still-per-call spike at default reasoning (~1.95c/frame) and would have quoted
|
|
9883
|
+
// QA ~10x its cost. Re-derive from 30d BillingEntry once live.
|
|
9884
|
+
"openrouter:video-qa-anatomy-dense-detector": {
|
|
9885
|
+
ourCostCents: 0.5,
|
|
9886
|
+
userPriceCents: 1
|
|
9887
|
+
},
|
|
9888
|
+
// (e) Dense-mode tracing confirmation: the SAME confirmer call as (c) but routed
|
|
9889
|
+
// to gemini-3.1-pro — flash measured 3/11 recall confirming dense stills, so
|
|
9890
|
+
// dense findings never confirm on the gate model. PER CALL.
|
|
9891
|
+
// Spike measured $2.22/80 ≈ 2.8c/call; the 2026-09-26 A/B measured 2.6c/flag.
|
|
9892
|
+
// 3.0c keeps it above both. (The former 5.0c/10.0c, times the old 4-confirmation cap,
|
|
9893
|
+
// inflated the credit gate's `max` by up to ~12,600 credits on a 30 s multi-scene.)
|
|
9894
|
+
// Re-derive from 30d BillingEntry once live.
|
|
9895
|
+
"openrouter:video-qa-anatomy-dense-confirm": {
|
|
9896
|
+
ourCostCents: 3,
|
|
9897
|
+
userPriceCents: 6
|
|
9858
9898
|
},
|
|
9859
9899
|
// Physics confirmation — skeptical second opinion on D+J floating-object flags
|
|
9860
9900
|
// (Gemini 3.7 Flash, ~3 frames per flagged moment, 1 call). Aligned with other vision-QA keys.
|
|
@@ -13534,25 +13574,37 @@ function whatsappFieldAuthority(field, source) {
|
|
|
13534
13574
|
}
|
|
13535
13575
|
__name(whatsappFieldAuthority, "whatsappFieldAuthority");
|
|
13536
13576
|
var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
13537
|
-
defineCapability(
|
|
13577
|
+
defineCapability(
|
|
13578
|
+
"approve_video_script",
|
|
13579
|
+
// 2026-09-29: dialogue admits "" at the wire — silent-allowed shots
|
|
13580
|
+
// (productOnly / gap_replication) are legal, the API decides per-shot.
|
|
13581
|
+
// Recomputed over the Fase-4 shared ApproveVideoScriptSceneEdit.
|
|
13582
|
+
"fdd641922f73907881ee09b62a006e0af1b277cab3d990ebc8c151c96b715693",
|
|
13538
13583
|
"credit_consuming",
|
|
13539
|
-
"
|
|
13540
|
-
|
|
13541
|
-
|
|
13542
|
-
"
|
|
13543
|
-
]
|
|
13544
|
-
|
|
13545
|
-
"
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
"
|
|
13549
|
-
|
|
13550
|
-
|
|
13551
|
-
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13555
|
-
|
|
13584
|
+
"creative",
|
|
13585
|
+
[
|
|
13586
|
+
"credit_consuming",
|
|
13587
|
+
"state_change"
|
|
13588
|
+
],
|
|
13589
|
+
[
|
|
13590
|
+
slot("task", true, [
|
|
13591
|
+
"taskId"
|
|
13592
|
+
]),
|
|
13593
|
+
slot("angle", false, [
|
|
13594
|
+
"angleKey"
|
|
13595
|
+
]),
|
|
13596
|
+
slot("script_scenes", true, [
|
|
13597
|
+
"scenes"
|
|
13598
|
+
])
|
|
13599
|
+
],
|
|
13600
|
+
[
|
|
13601
|
+
"task",
|
|
13602
|
+
"video_script"
|
|
13603
|
+
],
|
|
13604
|
+
[
|
|
13605
|
+
"task"
|
|
13606
|
+
]
|
|
13607
|
+
),
|
|
13556
13608
|
defineCapability("check_meta_media_upload", "62b1af1d796d9466f8926afc5e6d18c4ddeccd5b0269ca7b21c2f6ebcfd2a945", "none", "read_only", [
|
|
13557
13609
|
"read"
|
|
13558
13610
|
], [
|
|
@@ -16359,9 +16411,7 @@ var FlightRecorderResponseSchema = z75.object({
|
|
|
16359
16411
|
import { z as z76 } from "zod";
|
|
16360
16412
|
var ApproveVideoScriptSceneEdit = z76.object({
|
|
16361
16413
|
index: z76.number().int().nonnegative().describe("\xCDndice de la escena (0-based, mismo que devuelve get_video_script)."),
|
|
16362
|
-
dialogue: z76.string().
|
|
16363
|
-
message: "dialogue no puede ser s\xF3lo espacios"
|
|
16364
|
-
}).describe("Di\xE1logo final de la escena. NO puede estar vac\xEDo ni ser s\xF3lo espacios. Puede ser el original sin cambios o la edici\xF3n del usuario.")
|
|
16414
|
+
dialogue: z76.string().trim().max(VIDEO_SCRIPT_APPROVAL_MAX_DIALOGUE_CHARS).describe('Di\xE1logo final de la escena. Puede ser el original sin cambios o la edici\xF3n del usuario. Vac\xEDo ("") s\xF3lo es v\xE1lido en escenas silenciosas por dise\xF1o (productOnly o \xE1ngulos winner-copy); en una escena hablada el backend lo rechaza con 400.')
|
|
16365
16415
|
}).strict();
|
|
16366
16416
|
var ApproveVideoScriptCapabilityRequest = z76.object({
|
|
16367
16417
|
taskId: z76.string().min(1).describe("ID de la tarea."),
|
|
@@ -18057,7 +18107,7 @@ var ApiClient = class {
|
|
|
18057
18107
|
};
|
|
18058
18108
|
|
|
18059
18109
|
// src/index.ts
|
|
18060
|
-
var MCP_VERSION = "8.5.
|
|
18110
|
+
var MCP_VERSION = "8.5.1";
|
|
18061
18111
|
|
|
18062
18112
|
// src/meta-upload-app.ts
|
|
18063
18113
|
import { readFileSync } from "fs";
|
|
@@ -22579,7 +22629,7 @@ function registerScriptReviewTools(server, api) {
|
|
|
22579
22629
|
}
|
|
22580
22630
|
});
|
|
22581
22631
|
server.registerTool("approve_video_script", {
|
|
22582
|
-
description: approveVideoScriptGuidance.summary + ' Tras llamarlo, el render arranca y consume cr\xE9ditos.\n\nREGLAS DURAS:\n1. INCLUYE EN scenes[] S\xD3LO las escenas que cambian. El backend mergea por `index` \u2014 las escenas no incluidas conservan su di\xE1logo original. scenes vac\xEDo es rechazado con 400, as\xED que si el usuario no quiere editar nada, manda AL MENOS UNA escena con su `dialogue` original (ser\xE1 un no-op sem\xE1ntico pero satisface el
|
|
22632
|
+
description: approveVideoScriptGuidance.summary + ' Tras llamarlo, el render arranca y consume cr\xE9ditos.\n\nREGLAS DURAS:\n1. INCLUYE EN scenes[] S\xD3LO las escenas que cambian. El backend mergea por `index` \u2014 las escenas no incluidas conservan su di\xE1logo original. scenes vac\xEDo es rechazado con 400, as\xED que si el usuario no quiere editar nada, manda AL MENOS UNA escena con su `dialogue` original (ser\xE1 un no-op sem\xE1ntico pero satisface el m\xEDnimo de 1 escena).\n2. Para cada entrada incluida cuyo `dialogue` difiera del original, el backend valida `minWords \u2264 words(dialogue) \u2264 maxWords` (los rangos vienen en get_video_script). Si te sales del rango, rechaza con 400 \u2014 NO recortes en silencio; p\xEDdele al usuario que ajuste. Excepci\xF3n: un `dialogue` vac\xEDo es legal s\xF3lo en escenas silenciosas por dise\xF1o (`silentAllowed` en get_video_script); en una escena hablada el backend rechaza el vac\xEDo con 400.\n3. Escenas con LLM-original ya fuera de rango: el backend NO valida el rango POR-ESCENA si no las incluyes (la regla #2 s\xF3lo aplica a escenas editadas).\n4. TOPE GLOBAL: adem\xE1s del rango por-escena, el backend rechaza con 400 ("El guion no cabe en el tiempo del video. Ac\xF3rtalo y vuelve a aprobar.") cuando el TOTAL de palabras de TODO el guion (incluidas las escenas que no editaste) supera el cupo de la voz \u2014 porque ese guion se pasar\xEDa del tope de duraci\xF3n al renderizar. Si lo ves, acorta las escenas m\xE1s largas (la suma de `maxWords` de get_video_script es el techo total) y reintenta; o usa regenerate_video_script. Este 400 es s\xEDncrono y NO consume render.\n5. NUNCA inventes ni reescribas el guion por tu cuenta. Aplica los cambios del usuario al pie de la letra dentro de los l\xEDmites de palabras.\n6. MULTI-ANGLE: pasa el mismo `angleKey` que usaste en get_video_script. Si lo omites, el backend resuelve a "angle_0" literal \u2014 puedes aprobar un \xE1ngulo equivocado.\n\nDevuelve { status }. status="approved" confirma la aprobaci\xF3n; otro valor significa que la pausa sigue activa.',
|
|
22583
22633
|
inputSchema: ApproveVideoScriptInput.shape,
|
|
22584
22634
|
annotations: CREATES_PAID
|
|
22585
22635
|
}, async (input) => {
|
package/dist/stdio.js
CHANGED
|
@@ -5278,7 +5278,10 @@ var ApproveVideoScriptRequest = z27.object({
|
|
|
5278
5278
|
angleKey: z27.string().trim().min(1).max(120).optional(),
|
|
5279
5279
|
scenes: z27.array(z27.object({
|
|
5280
5280
|
index: z27.number().int().nonnegative(),
|
|
5281
|
-
|
|
5281
|
+
// Empty is admitted at the wire: only the service knows whether the
|
|
5282
|
+
// shot is a designed-silent beat (productOnly / winner-copy), so the
|
|
5283
|
+
// per-shot empty-line policy lives there — NOT here.
|
|
5284
|
+
dialogue: z27.string().trim().max(VIDEO_SCRIPT_APPROVAL_MAX_DIALOGUE_CHARS)
|
|
5282
5285
|
}).strict()).min(1).max(VIDEO_SCRIPT_APPROVAL_MAX_SCENES)
|
|
5283
5286
|
}).strict();
|
|
5284
5287
|
var ApproveVideoScriptResponse = z27.object({
|
|
@@ -8667,13 +8670,16 @@ var DEFAULT_PRICING = {
|
|
|
8667
8670
|
ourCostCents: 0.07,
|
|
8668
8671
|
userPriceCents: 0.14
|
|
8669
8672
|
},
|
|
8673
|
+
// Both rewrites: RE-DERIVED 2026-09-28 from 14d of prod BillingEntry.
|
|
8674
|
+
// final-simplify n=123 mean 1.26¢ / p95 1.98¢ user; targeted-retry n=439 mean 2.09¢ /
|
|
8675
|
+
// p95 3.37¢ user. The old 0.8¢ (a Flash-era guess) under-quoted both 2.5-4x.
|
|
8670
8676
|
"openrouter:video-final-simplify-rewrite": {
|
|
8671
|
-
ourCostCents:
|
|
8672
|
-
userPriceCents:
|
|
8677
|
+
ourCostCents: 1,
|
|
8678
|
+
userPriceCents: 2
|
|
8673
8679
|
},
|
|
8674
8680
|
"openrouter:video-targeted-retry-rewrite": {
|
|
8675
|
-
ourCostCents:
|
|
8676
|
-
userPriceCents:
|
|
8681
|
+
ourCostCents: 1.7,
|
|
8682
|
+
userPriceCents: 3.4
|
|
8677
8683
|
},
|
|
8678
8684
|
// For helper-recorded entries (`callOpenRouter`), `ourCostCents` here is
|
|
8679
8685
|
// only used when `usage.cost` is missing from the provider response —
|
|
@@ -9735,11 +9741,15 @@ var DEFAULT_PRICING = {
|
|
|
9735
9741
|
// Video QA — combined describe+judge pass. The DETECTOR runs on gemini-3.8-flash at
|
|
9736
9742
|
// reasoning.effort=high (recall-critical: it gates a $2-4 re-render). Real billing
|
|
9737
9743
|
// uses OpenRouter's per-call usage.cost (×2), so this value is ONLY the estimator
|
|
9738
|
-
// basis + the rare fallback when usage.cost is missing
|
|
9739
|
-
//
|
|
9744
|
+
// basis + the rare fallback when usage.cost is missing.
|
|
9745
|
+
// RE-DERIVED 2026-09-28 (14d prod BillingEntry):
|
|
9746
|
+
// n=2073, mean 3.57¢ / p95 8.95¢ / p99 12.04¢ / max 13.50¢ user per call.
|
|
9747
|
+
// 12¢ sits at the p99 and still covers DETECTOR_MAX_CALLS (3) × the mean (10.71¢) —
|
|
9748
|
+
// the invariant pinned in cost-estimator.spec.test.ts. The former 20¢ was sized to a
|
|
9749
|
+
// Pro+high call that no longer runs and inflated every QA pass of the credit gate.
|
|
9740
9750
|
"openrouter:video-qa-describe-judge": {
|
|
9741
|
-
ourCostCents:
|
|
9742
|
-
userPriceCents:
|
|
9751
|
+
ourCostCents: 6,
|
|
9752
|
+
userPriceCents: 12
|
|
9743
9753
|
},
|
|
9744
9754
|
// Video QA — hand scanner reinforcement (Gemini 3.7 Flash, dense frames around spike)
|
|
9745
9755
|
"openrouter:video-hand-reinforcement": {
|
|
@@ -9808,13 +9818,16 @@ var DEFAULT_PRICING = {
|
|
|
9808
9818
|
userPriceCents: 0.22
|
|
9809
9819
|
},
|
|
9810
9820
|
// Clip Judge — text-only comparison of QA results between original and retry clips
|
|
9811
|
-
// (google/gemini-3.8-flash, text-only).
|
|
9821
|
+
// (google/gemini-3.8-flash, text-only). RE-DERIVED 2026-09-28 (14d prod BillingEntry):
|
|
9822
|
+
// n=92, mean 0.34¢ / p95 0.54¢ user
|
|
9823
|
+
// (the old 0.12¢ assumed ~$0.0006 and under-quoted 4.5x).
|
|
9812
9824
|
"openrouter:clip-judge-text": {
|
|
9813
|
-
ourCostCents: 0.
|
|
9814
|
-
userPriceCents: 0.
|
|
9825
|
+
ourCostCents: 0.28,
|
|
9826
|
+
userPriceCents: 0.56
|
|
9815
9827
|
},
|
|
9816
9828
|
// Clip Judge — vision comparison of two video clips (google/gemini-3.8-flash, 2 videos)
|
|
9817
|
-
// Our cost: ~$0.01 => 1.0 cents; 2x markup.
|
|
9829
|
+
// Our cost: ~$0.01 => 1.0 cents; 2x markup. Checked 2026-09-28 (n=346): mean 1.38¢ /
|
|
9830
|
+
// p95 1.90¢ user — already covered, unchanged.
|
|
9818
9831
|
"openrouter:clip-judge-vision": {
|
|
9819
9832
|
ourCostCents: 1,
|
|
9820
9833
|
userPriceCents: 2
|
|
@@ -9831,10 +9844,13 @@ var DEFAULT_PRICING = {
|
|
|
9831
9844
|
ourCostCents: 0.89,
|
|
9832
9845
|
userPriceCents: 1.78
|
|
9833
9846
|
},
|
|
9834
|
-
// Video QA — product integrity scanner (
|
|
9847
|
+
// Video QA — product integrity scanner (gemini-3.8-flash, 5 frames + reference).
|
|
9848
|
+
// RE-DERIVED 2026-09-28 (14d prod BillingEntry):
|
|
9849
|
+
// n=1828, mean 2.91¢ / p95 5.07¢ / max 11.50¢ user per call. The old 0.3¢
|
|
9850
|
+
// (a 3.7-Flash-era guess) under-quoted it ~10x on every QA pass.
|
|
9835
9851
|
"openrouter:video-product-integrity": {
|
|
9836
|
-
ourCostCents:
|
|
9837
|
-
userPriceCents:
|
|
9852
|
+
ourCostCents: 2.6,
|
|
9853
|
+
userPriceCents: 5.2
|
|
9838
9854
|
},
|
|
9839
9855
|
// Video QA — anatomy. THREE keys, and they do NOT share a unit. Getting this wrong
|
|
9840
9856
|
// over-charges by ~42x, which is exactly what a first pass at the 2026-07-30 change did.
|
|
@@ -9872,11 +9888,35 @@ var DEFAULT_PRICING = {
|
|
|
9872
9888
|
userPriceCents: 0.4
|
|
9873
9889
|
},
|
|
9874
9890
|
// (c) Tracing confirmation of a frames-only finding: 3 stills + the full downscaled video,
|
|
9875
|
-
// one call.
|
|
9876
|
-
//
|
|
9891
|
+
// one call. RE-DERIVED 2026-09-28 (14d prod BillingEntry):
|
|
9892
|
+
// n=46, mean 2.67¢ / p95 4.48¢ / max 5.43¢ user — the
|
|
9893
|
+
// former 3.0¢ (from a 14-call spike, 0.59¢ our mean) sat below the prod p95.
|
|
9877
9894
|
"openrouter:video-qa-anatomy-tracing-confirm": {
|
|
9878
|
-
ourCostCents:
|
|
9879
|
-
userPriceCents:
|
|
9895
|
+
ourCostCents: 2.25,
|
|
9896
|
+
userPriceCents: 4.5
|
|
9897
|
+
},
|
|
9898
|
+
// (d) DENSE anatomy detector (the default anatomy detector since 2026-09-26;
|
|
9899
|
+
// QA_ANATOMY_DETECTOR=frame_judge reverts): gemini-3.1-pro judges every extracted
|
|
9900
|
+
// frame at 1 fps, 5 frames per call, each call billing its frame count — the rate is
|
|
9901
|
+
// PER FRAME like (b) and scales with QA_DENSE_DETECTOR_MAX_FRAMES. Measured on the
|
|
9902
|
+
// owner corpus with the shipped config (reasoning=low, grouped): $1.062 / 296 frames
|
|
9903
|
+
// ≈ 0.36c/frame; 0.5c keeps ~40% headroom. The old 3.0c fallback was the 2026-09-22
|
|
9904
|
+
// one-still-per-call spike at default reasoning (~1.95c/frame) and would have quoted
|
|
9905
|
+
// QA ~10x its cost. Re-derive from 30d BillingEntry once live.
|
|
9906
|
+
"openrouter:video-qa-anatomy-dense-detector": {
|
|
9907
|
+
ourCostCents: 0.5,
|
|
9908
|
+
userPriceCents: 1
|
|
9909
|
+
},
|
|
9910
|
+
// (e) Dense-mode tracing confirmation: the SAME confirmer call as (c) but routed
|
|
9911
|
+
// to gemini-3.1-pro — flash measured 3/11 recall confirming dense stills, so
|
|
9912
|
+
// dense findings never confirm on the gate model. PER CALL.
|
|
9913
|
+
// Spike measured $2.22/80 ≈ 2.8c/call; the 2026-09-26 A/B measured 2.6c/flag.
|
|
9914
|
+
// 3.0c keeps it above both. (The former 5.0c/10.0c, times the old 4-confirmation cap,
|
|
9915
|
+
// inflated the credit gate's `max` by up to ~12,600 credits on a 30 s multi-scene.)
|
|
9916
|
+
// Re-derive from 30d BillingEntry once live.
|
|
9917
|
+
"openrouter:video-qa-anatomy-dense-confirm": {
|
|
9918
|
+
ourCostCents: 3,
|
|
9919
|
+
userPriceCents: 6
|
|
9880
9920
|
},
|
|
9881
9921
|
// Physics confirmation — skeptical second opinion on D+J floating-object flags
|
|
9882
9922
|
// (Gemini 3.7 Flash, ~3 frames per flagged moment, 1 call). Aligned with other vision-QA keys.
|
|
@@ -13556,25 +13596,37 @@ function whatsappFieldAuthority(field, source) {
|
|
|
13556
13596
|
}
|
|
13557
13597
|
__name(whatsappFieldAuthority, "whatsappFieldAuthority");
|
|
13558
13598
|
var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
13559
|
-
defineCapability(
|
|
13599
|
+
defineCapability(
|
|
13600
|
+
"approve_video_script",
|
|
13601
|
+
// 2026-09-29: dialogue admits "" at the wire — silent-allowed shots
|
|
13602
|
+
// (productOnly / gap_replication) are legal, the API decides per-shot.
|
|
13603
|
+
// Recomputed over the Fase-4 shared ApproveVideoScriptSceneEdit.
|
|
13604
|
+
"fdd641922f73907881ee09b62a006e0af1b277cab3d990ebc8c151c96b715693",
|
|
13560
13605
|
"credit_consuming",
|
|
13561
|
-
"
|
|
13562
|
-
|
|
13563
|
-
|
|
13564
|
-
"
|
|
13565
|
-
]
|
|
13566
|
-
|
|
13567
|
-
"
|
|
13568
|
-
|
|
13569
|
-
|
|
13570
|
-
"
|
|
13571
|
-
|
|
13572
|
-
|
|
13573
|
-
|
|
13574
|
-
|
|
13575
|
-
|
|
13576
|
-
|
|
13577
|
-
|
|
13606
|
+
"creative",
|
|
13607
|
+
[
|
|
13608
|
+
"credit_consuming",
|
|
13609
|
+
"state_change"
|
|
13610
|
+
],
|
|
13611
|
+
[
|
|
13612
|
+
slot("task", true, [
|
|
13613
|
+
"taskId"
|
|
13614
|
+
]),
|
|
13615
|
+
slot("angle", false, [
|
|
13616
|
+
"angleKey"
|
|
13617
|
+
]),
|
|
13618
|
+
slot("script_scenes", true, [
|
|
13619
|
+
"scenes"
|
|
13620
|
+
])
|
|
13621
|
+
],
|
|
13622
|
+
[
|
|
13623
|
+
"task",
|
|
13624
|
+
"video_script"
|
|
13625
|
+
],
|
|
13626
|
+
[
|
|
13627
|
+
"task"
|
|
13628
|
+
]
|
|
13629
|
+
),
|
|
13578
13630
|
defineCapability("check_meta_media_upload", "62b1af1d796d9466f8926afc5e6d18c4ddeccd5b0269ca7b21c2f6ebcfd2a945", "none", "read_only", [
|
|
13579
13631
|
"read"
|
|
13580
13632
|
], [
|
|
@@ -16127,9 +16179,7 @@ var FlightRecorderResponseSchema = z75.object({
|
|
|
16127
16179
|
import { z as z76 } from "zod";
|
|
16128
16180
|
var ApproveVideoScriptSceneEdit = z76.object({
|
|
16129
16181
|
index: z76.number().int().nonnegative().describe("\xCDndice de la escena (0-based, mismo que devuelve get_video_script)."),
|
|
16130
|
-
dialogue: z76.string().
|
|
16131
|
-
message: "dialogue no puede ser s\xF3lo espacios"
|
|
16132
|
-
}).describe("Di\xE1logo final de la escena. NO puede estar vac\xEDo ni ser s\xF3lo espacios. Puede ser el original sin cambios o la edici\xF3n del usuario.")
|
|
16182
|
+
dialogue: z76.string().trim().max(VIDEO_SCRIPT_APPROVAL_MAX_DIALOGUE_CHARS).describe('Di\xE1logo final de la escena. Puede ser el original sin cambios o la edici\xF3n del usuario. Vac\xEDo ("") s\xF3lo es v\xE1lido en escenas silenciosas por dise\xF1o (productOnly o \xE1ngulos winner-copy); en una escena hablada el backend lo rechaza con 400.')
|
|
16133
16183
|
}).strict();
|
|
16134
16184
|
var ApproveVideoScriptCapabilityRequest = z76.object({
|
|
16135
16185
|
taskId: z76.string().min(1).describe("ID de la tarea."),
|
|
@@ -16389,7 +16439,7 @@ var ApiClient = class {
|
|
|
16389
16439
|
};
|
|
16390
16440
|
|
|
16391
16441
|
// src/index.ts
|
|
16392
|
-
var MCP_VERSION = "8.5.
|
|
16442
|
+
var MCP_VERSION = "8.5.1";
|
|
16393
16443
|
|
|
16394
16444
|
// src/meta-upload-app.ts
|
|
16395
16445
|
import { readFileSync } from "fs";
|
|
@@ -20964,7 +21014,7 @@ function registerScriptReviewTools(server, api) {
|
|
|
20964
21014
|
}
|
|
20965
21015
|
});
|
|
20966
21016
|
server.registerTool("approve_video_script", {
|
|
20967
|
-
description: approveVideoScriptGuidance.summary + ' Tras llamarlo, el render arranca y consume cr\xE9ditos.\n\nREGLAS DURAS:\n1. INCLUYE EN scenes[] S\xD3LO las escenas que cambian. El backend mergea por `index` \u2014 las escenas no incluidas conservan su di\xE1logo original. scenes vac\xEDo es rechazado con 400, as\xED que si el usuario no quiere editar nada, manda AL MENOS UNA escena con su `dialogue` original (ser\xE1 un no-op sem\xE1ntico pero satisface el
|
|
21017
|
+
description: approveVideoScriptGuidance.summary + ' Tras llamarlo, el render arranca y consume cr\xE9ditos.\n\nREGLAS DURAS:\n1. INCLUYE EN scenes[] S\xD3LO las escenas que cambian. El backend mergea por `index` \u2014 las escenas no incluidas conservan su di\xE1logo original. scenes vac\xEDo es rechazado con 400, as\xED que si el usuario no quiere editar nada, manda AL MENOS UNA escena con su `dialogue` original (ser\xE1 un no-op sem\xE1ntico pero satisface el m\xEDnimo de 1 escena).\n2. Para cada entrada incluida cuyo `dialogue` difiera del original, el backend valida `minWords \u2264 words(dialogue) \u2264 maxWords` (los rangos vienen en get_video_script). Si te sales del rango, rechaza con 400 \u2014 NO recortes en silencio; p\xEDdele al usuario que ajuste. Excepci\xF3n: un `dialogue` vac\xEDo es legal s\xF3lo en escenas silenciosas por dise\xF1o (`silentAllowed` en get_video_script); en una escena hablada el backend rechaza el vac\xEDo con 400.\n3. Escenas con LLM-original ya fuera de rango: el backend NO valida el rango POR-ESCENA si no las incluyes (la regla #2 s\xF3lo aplica a escenas editadas).\n4. TOPE GLOBAL: adem\xE1s del rango por-escena, el backend rechaza con 400 ("El guion no cabe en el tiempo del video. Ac\xF3rtalo y vuelve a aprobar.") cuando el TOTAL de palabras de TODO el guion (incluidas las escenas que no editaste) supera el cupo de la voz \u2014 porque ese guion se pasar\xEDa del tope de duraci\xF3n al renderizar. Si lo ves, acorta las escenas m\xE1s largas (la suma de `maxWords` de get_video_script es el techo total) y reintenta; o usa regenerate_video_script. Este 400 es s\xEDncrono y NO consume render.\n5. NUNCA inventes ni reescribas el guion por tu cuenta. Aplica los cambios del usuario al pie de la letra dentro de los l\xEDmites de palabras.\n6. MULTI-ANGLE: pasa el mismo `angleKey` que usaste en get_video_script. Si lo omites, el backend resuelve a "angle_0" literal \u2014 puedes aprobar un \xE1ngulo equivocado.\n\nDevuelve { status }. status="approved" confirma la aprobaci\xF3n; otro valor significa que la pausa sigue activa.',
|
|
20968
21018
|
inputSchema: ApproveVideoScriptInput.shape,
|
|
20969
21019
|
annotations: CREATES_PAID
|
|
20970
21020
|
}, async (input) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@productmaker/mcp",
|
|
3
|
-
"version": "8.5.
|
|
3
|
+
"version": "8.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "ProductMaker MCP server — cost products, generate landing pages, UGC videos, and ad creatives, and publish to Shopify, Meta Ads, and TikTok Ads.",
|