@productmaker/mcp 12.1.0 → 12.1.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 +8 -0
- package/dist/http.js +1290 -869
- package/dist/stdio.js +1349 -829
- package/dist/ui/task-results-app.html +398 -0
- package/package.json +2 -2
package/dist/stdio.js
CHANGED
|
@@ -5348,6 +5348,7 @@ var ImageCreativeArchetype = z24.enum([
|
|
|
5348
5348
|
"problem_solution",
|
|
5349
5349
|
"lifestyle_identity"
|
|
5350
5350
|
]);
|
|
5351
|
+
var MAX_IMAGE_CREATIVE_VARIANTS = 6;
|
|
5351
5352
|
var ImageCreativeVisualTreatment = z24.enum([
|
|
5352
5353
|
"performance_product_ad",
|
|
5353
5354
|
"premium_dtc_carousel"
|
|
@@ -23552,14 +23553,37 @@ var WebsiteCaptureResearchSchema = z116.object({
|
|
|
23552
23553
|
});
|
|
23553
23554
|
|
|
23554
23555
|
// ../../packages/types/src/demo-mode.ts
|
|
23556
|
+
import { z as z118 } from "zod";
|
|
23557
|
+
|
|
23558
|
+
// ../../packages/types/src/demo-mode-service-page-assets.ts
|
|
23555
23559
|
import { z as z117 } from "zod";
|
|
23560
|
+
var DemoServicePageAssetSourceSchema = z117.object({
|
|
23561
|
+
pageId: z117.string().uuid(),
|
|
23562
|
+
ownerId: z117.string().min(1),
|
|
23563
|
+
assets: z117.array(z117.object({
|
|
23564
|
+
id: z117.string().uuid(),
|
|
23565
|
+
storageKey: z117.string().min(1).max(1024),
|
|
23566
|
+
mediaType: z117.enum([
|
|
23567
|
+
"image/webp",
|
|
23568
|
+
"video/mp4"
|
|
23569
|
+
]),
|
|
23570
|
+
byteSize: z117.number().int().positive().max(32 * 1024 * 1024),
|
|
23571
|
+
width: z117.number().int().positive().max(1920),
|
|
23572
|
+
height: z117.number().int().positive().max(1920),
|
|
23573
|
+
contentHash: z117.string().regex(/^[a-f0-9]{64}$/i),
|
|
23574
|
+
sourceKind: ServicePageSourceKindSchema,
|
|
23575
|
+
approvedAt: z117.string().datetime()
|
|
23576
|
+
}).strict()).max(24)
|
|
23577
|
+
}).strict();
|
|
23578
|
+
|
|
23579
|
+
// ../../packages/types/src/demo-mode.ts
|
|
23556
23580
|
var DEMO_MODE_FLOWS = [
|
|
23557
23581
|
"brand",
|
|
23558
23582
|
"servicePage",
|
|
23559
23583
|
"motion",
|
|
23560
23584
|
"image"
|
|
23561
23585
|
];
|
|
23562
|
-
var DemoModeFlowSchema =
|
|
23586
|
+
var DemoModeFlowSchema = z118.enum(DEMO_MODE_FLOWS);
|
|
23563
23587
|
var DEMO_MODE_STEPS = [
|
|
23564
23588
|
"running",
|
|
23565
23589
|
"research",
|
|
@@ -23572,27 +23596,30 @@ var DEMO_MODE_STEPS = [
|
|
|
23572
23596
|
"final",
|
|
23573
23597
|
"watchdog"
|
|
23574
23598
|
];
|
|
23575
|
-
var DemoModeStepSchema =
|
|
23599
|
+
var DemoModeStepSchema = z118.enum(DEMO_MODE_STEPS);
|
|
23576
23600
|
var DEMO_MODE_WAIT_SECONDS = {
|
|
23577
23601
|
min: 30,
|
|
23578
23602
|
max: 450,
|
|
23579
23603
|
default: 150
|
|
23580
23604
|
};
|
|
23581
|
-
var centsSchema =
|
|
23582
|
-
var emailSchema =
|
|
23583
|
-
var
|
|
23584
|
-
|
|
23585
|
-
|
|
23586
|
-
|
|
23587
|
-
|
|
23588
|
-
|
|
23589
|
-
|
|
23590
|
-
|
|
23591
|
-
|
|
23605
|
+
var centsSchema = z118.number().int().min(0).max(1e5);
|
|
23606
|
+
var emailSchema = z118.string().trim().toLowerCase().email();
|
|
23607
|
+
var optionalTemplateId = z118.preprocess((value) => value === "" ? void 0 : value, z118.string().uuid().optional());
|
|
23608
|
+
var DemoModeTemplatesSchema = z118.object({
|
|
23609
|
+
brandId: z118.string().uuid(),
|
|
23610
|
+
servicePageId: z118.string().uuid(),
|
|
23611
|
+
motionTaskId: z118.string().uuid(),
|
|
23612
|
+
motionVariantTaskId: optionalTemplateId,
|
|
23613
|
+
motionThirdTaskId: optionalTemplateId,
|
|
23614
|
+
imageTaskId: z118.string().uuid()
|
|
23615
|
+
});
|
|
23616
|
+
var DemoModeEditableSchema = z118.object({
|
|
23617
|
+
enabled: z118.boolean(),
|
|
23618
|
+
emails: z118.array(emailSchema).max(50).transform((list) => [
|
|
23592
23619
|
...new Set(list)
|
|
23593
23620
|
]),
|
|
23594
|
-
waitSeconds:
|
|
23595
|
-
chargeCents:
|
|
23621
|
+
waitSeconds: z118.number().int().min(DEMO_MODE_WAIT_SECONDS.min).max(DEMO_MODE_WAIT_SECONDS.max),
|
|
23622
|
+
chargeCents: z118.object({
|
|
23596
23623
|
brand: centsSchema,
|
|
23597
23624
|
servicePage: centsSchema,
|
|
23598
23625
|
motion: centsSchema,
|
|
@@ -23600,73 +23627,77 @@ var DemoModeEditableSchema = z117.object({
|
|
|
23600
23627
|
}),
|
|
23601
23628
|
templates: DemoModeTemplatesSchema
|
|
23602
23629
|
});
|
|
23603
|
-
var nullableString =
|
|
23604
|
-
var DemoModeSnapshotSchema =
|
|
23605
|
-
brand:
|
|
23630
|
+
var nullableString = z118.string().nullable();
|
|
23631
|
+
var DemoModeSnapshotSchema = z118.object({
|
|
23632
|
+
brand: z118.object({
|
|
23606
23633
|
/** Columnas de identidad de `Brand` listas para un `update` (sin id/userId/slug/estado/fechas). */
|
|
23607
|
-
identity:
|
|
23608
|
-
productSamples:
|
|
23609
|
-
name:
|
|
23610
|
-
priceCents:
|
|
23634
|
+
identity: z118.record(z118.unknown()),
|
|
23635
|
+
productSamples: z118.array(z118.object({
|
|
23636
|
+
name: z118.string(),
|
|
23637
|
+
priceCents: z118.number().int().nullable(),
|
|
23611
23638
|
currency: nullableString,
|
|
23612
|
-
imageKey:
|
|
23639
|
+
imageKey: z118.string(),
|
|
23613
23640
|
productUrl: nullableString,
|
|
23614
|
-
position:
|
|
23641
|
+
position: z118.number().int()
|
|
23615
23642
|
})),
|
|
23616
|
-
personas:
|
|
23617
|
-
name:
|
|
23643
|
+
personas: z118.array(z118.object({
|
|
23644
|
+
name: z118.string(),
|
|
23618
23645
|
demographics: nullableString,
|
|
23619
23646
|
painPoints: nullableString,
|
|
23620
23647
|
motivations: nullableString,
|
|
23621
23648
|
objections: nullableString,
|
|
23622
23649
|
gender: nullableString,
|
|
23623
|
-
isDefault:
|
|
23650
|
+
isDefault: z118.boolean()
|
|
23624
23651
|
}))
|
|
23625
23652
|
}),
|
|
23626
|
-
servicePage:
|
|
23627
|
-
facts:
|
|
23628
|
-
review:
|
|
23629
|
-
artifact:
|
|
23653
|
+
servicePage: z118.object({
|
|
23654
|
+
facts: z118.unknown(),
|
|
23655
|
+
review: z118.unknown(),
|
|
23656
|
+
artifact: z118.unknown(),
|
|
23657
|
+
/** Optional only for snapshots saved before page-owned demo media. */
|
|
23658
|
+
assetSource: DemoServicePageAssetSourceSchema.optional()
|
|
23630
23659
|
}),
|
|
23631
|
-
motion:
|
|
23660
|
+
motion: z118.object({
|
|
23632
23661
|
outputs: MotionGraphicsOutputsSchema,
|
|
23633
23662
|
/**
|
|
23634
23663
|
* La captura REAL de la web de la plantilla (nunca una fabricada por la
|
|
23635
23664
|
* demo). Null cuando la plantilla no tiene ninguna: la captura demo nunca
|
|
23636
23665
|
* va live, así que el servicio usa `DEMO_MODE_PLACEHOLDER_CAPTURE`.
|
|
23637
23666
|
*/
|
|
23638
|
-
capture:
|
|
23639
|
-
bundleKey:
|
|
23640
|
-
sha256:
|
|
23641
|
-
uploadBytes:
|
|
23667
|
+
capture: z118.object({
|
|
23668
|
+
bundleKey: z118.string(),
|
|
23669
|
+
sha256: z118.string(),
|
|
23670
|
+
uploadBytes: z118.number().int().nullable(),
|
|
23642
23671
|
previewKey: nullableString
|
|
23643
23672
|
}).nullable()
|
|
23644
23673
|
}),
|
|
23645
|
-
image:
|
|
23646
|
-
provider:
|
|
23647
|
-
model:
|
|
23648
|
-
prompt:
|
|
23649
|
-
imageUrl:
|
|
23650
|
-
width:
|
|
23651
|
-
height:
|
|
23674
|
+
image: z118.object({
|
|
23675
|
+
provider: z118.string(),
|
|
23676
|
+
model: z118.string(),
|
|
23677
|
+
prompt: z118.string(),
|
|
23678
|
+
imageUrl: z118.string(),
|
|
23679
|
+
width: z118.number().int(),
|
|
23680
|
+
height: z118.number().int(),
|
|
23652
23681
|
adCopy: nullableString,
|
|
23653
|
-
rawResponse:
|
|
23682
|
+
rawResponse: z118.unknown()
|
|
23654
23683
|
})
|
|
23655
23684
|
});
|
|
23656
23685
|
var DemoModeConfigSchema = DemoModeEditableSchema.extend({
|
|
23657
23686
|
snapshot: DemoModeSnapshotSchema.nullable(),
|
|
23658
|
-
snapshotAt:
|
|
23687
|
+
snapshotAt: z118.string().datetime().nullable()
|
|
23659
23688
|
});
|
|
23660
23689
|
var DemoModeAdminViewSchema = DemoModeEditableSchema.extend({
|
|
23661
23690
|
// Sin configurar, la API devuelve ids vacíos ("" no es uuid): la vista los
|
|
23662
23691
|
// admite; el PUT sí exige uuid (`DemoModeEditableSchema`).
|
|
23663
|
-
templates:
|
|
23664
|
-
brandId:
|
|
23665
|
-
servicePageId:
|
|
23666
|
-
motionTaskId:
|
|
23667
|
-
|
|
23692
|
+
templates: z118.object({
|
|
23693
|
+
brandId: z118.string(),
|
|
23694
|
+
servicePageId: z118.string(),
|
|
23695
|
+
motionTaskId: z118.string(),
|
|
23696
|
+
motionVariantTaskId: z118.string().optional(),
|
|
23697
|
+
motionThirdTaskId: z118.string().optional(),
|
|
23698
|
+
imageTaskId: z118.string()
|
|
23668
23699
|
}),
|
|
23669
|
-
snapshotAt:
|
|
23700
|
+
snapshotAt: z118.string().nullable()
|
|
23670
23701
|
});
|
|
23671
23702
|
var DEMO_MODE_TEMPLATE_PROBLEMS = [
|
|
23672
23703
|
"not_found",
|
|
@@ -23677,31 +23708,33 @@ var DEMO_MODE_TEMPLATE_PROBLEMS = [
|
|
|
23677
23708
|
"no_video",
|
|
23678
23709
|
"no_creative"
|
|
23679
23710
|
];
|
|
23680
|
-
var DemoModeTemplateVerdictSchema =
|
|
23681
|
-
|
|
23682
|
-
ok:
|
|
23711
|
+
var DemoModeTemplateVerdictSchema = z118.discriminatedUnion("ok", [
|
|
23712
|
+
z118.object({
|
|
23713
|
+
ok: z118.literal(true)
|
|
23683
23714
|
}),
|
|
23684
|
-
|
|
23685
|
-
ok:
|
|
23686
|
-
problem:
|
|
23715
|
+
z118.object({
|
|
23716
|
+
ok: z118.literal(false),
|
|
23717
|
+
problem: z118.enum(DEMO_MODE_TEMPLATE_PROBLEMS)
|
|
23687
23718
|
})
|
|
23688
23719
|
]);
|
|
23689
|
-
var DemoModeValidationSchema =
|
|
23720
|
+
var DemoModeValidationSchema = z118.object({
|
|
23690
23721
|
brandId: DemoModeTemplateVerdictSchema,
|
|
23691
23722
|
servicePageId: DemoModeTemplateVerdictSchema,
|
|
23692
23723
|
motionTaskId: DemoModeTemplateVerdictSchema,
|
|
23724
|
+
motionVariantTaskId: DemoModeTemplateVerdictSchema.optional(),
|
|
23725
|
+
motionThirdTaskId: DemoModeTemplateVerdictSchema.optional(),
|
|
23693
23726
|
imageTaskId: DemoModeTemplateVerdictSchema
|
|
23694
23727
|
});
|
|
23695
|
-
var DemoModeJobSchema =
|
|
23728
|
+
var DemoModeJobSchema = z118.object({
|
|
23696
23729
|
flow: DemoModeFlowSchema,
|
|
23697
23730
|
step: DemoModeStepSchema,
|
|
23698
23731
|
/** brandId | servicePageOperationId | taskId según el flujo. */
|
|
23699
|
-
targetId:
|
|
23700
|
-
userId:
|
|
23732
|
+
targetId: z118.string().uuid(),
|
|
23733
|
+
userId: z118.string().min(1),
|
|
23701
23734
|
/** Solo marca: la generación de extracción que el guion completa. */
|
|
23702
|
-
generation:
|
|
23735
|
+
generation: z118.number().int().positive().optional(),
|
|
23703
23736
|
/** Solo `final`/`watchdog`: la parte del snapshot de ESTE flujo, congelada al empezar. */
|
|
23704
|
-
result:
|
|
23737
|
+
result: z118.unknown().optional()
|
|
23705
23738
|
});
|
|
23706
23739
|
|
|
23707
23740
|
// ../../packages/utils/src/retry-after.ts
|
|
@@ -24177,7 +24210,7 @@ var ApiClient = class {
|
|
|
24177
24210
|
};
|
|
24178
24211
|
|
|
24179
24212
|
// src/index.ts
|
|
24180
|
-
var MCP_VERSION = "12.1.
|
|
24213
|
+
var MCP_VERSION = "12.1.1";
|
|
24181
24214
|
|
|
24182
24215
|
// src/meta-upload-app.ts
|
|
24183
24216
|
import { readFileSync } from "fs";
|
|
@@ -24248,8 +24281,123 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
|
|
|
24248
24281
|
}
|
|
24249
24282
|
__name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
|
|
24250
24283
|
|
|
24284
|
+
// src/task-results-app.ts
|
|
24285
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
24286
|
+
import { registerAppResource as registerAppResource2, RESOURCE_MIME_TYPE as RESOURCE_MIME_TYPE2 } from "@modelcontextprotocol/ext-apps/server";
|
|
24287
|
+
var TASK_RESULTS_APP_RESOURCE_URI = "ui://task-results/v1.html";
|
|
24288
|
+
var HTML_URL = new URL("./ui/task-results-app.html", import.meta.url);
|
|
24289
|
+
function assetOrigin(value) {
|
|
24290
|
+
if (!value) return null;
|
|
24291
|
+
try {
|
|
24292
|
+
const url = new URL(value);
|
|
24293
|
+
return url.protocol === "https:" && !url.username && !url.password ? url.origin : null;
|
|
24294
|
+
} catch {
|
|
24295
|
+
return null;
|
|
24296
|
+
}
|
|
24297
|
+
}
|
|
24298
|
+
__name(assetOrigin, "assetOrigin");
|
|
24299
|
+
function buildTaskResultsView(media, proxyBaseUrl) {
|
|
24300
|
+
const origin = assetOrigin(proxyBaseUrl);
|
|
24301
|
+
const safeUrl = /* @__PURE__ */ __name((value) => {
|
|
24302
|
+
if (!origin) return null;
|
|
24303
|
+
try {
|
|
24304
|
+
const url = new URL(value);
|
|
24305
|
+
return url.protocol === "https:" && url.origin === origin && url.pathname.startsWith("/assets/") && url.pathname.length > "/assets/".length && !url.username && !url.password ? url.href : null;
|
|
24306
|
+
} catch {
|
|
24307
|
+
return null;
|
|
24308
|
+
}
|
|
24309
|
+
}, "safeUrl");
|
|
24310
|
+
const images = media.images.flatMap((image, index) => {
|
|
24311
|
+
const url = safeUrl(image.url);
|
|
24312
|
+
return url ? [
|
|
24313
|
+
{
|
|
24314
|
+
url,
|
|
24315
|
+
alt: image.alt?.slice(0, 160) ?? `ProductMaker image ${index + 1}`
|
|
24316
|
+
}
|
|
24317
|
+
] : [];
|
|
24318
|
+
});
|
|
24319
|
+
const videos = media.videos.flatMap((video) => {
|
|
24320
|
+
const url = safeUrl(video.url);
|
|
24321
|
+
return url ? [
|
|
24322
|
+
{
|
|
24323
|
+
url,
|
|
24324
|
+
...video.label ? {
|
|
24325
|
+
label: video.label.slice(0, 120)
|
|
24326
|
+
} : {},
|
|
24327
|
+
...video.scriptRewritten === true ? {
|
|
24328
|
+
scriptRewritten: true
|
|
24329
|
+
} : {}
|
|
24330
|
+
}
|
|
24331
|
+
] : [];
|
|
24332
|
+
});
|
|
24333
|
+
const links = media.links.flatMap((link) => {
|
|
24334
|
+
const url = safeUrl(link.url);
|
|
24335
|
+
return url ? [
|
|
24336
|
+
{
|
|
24337
|
+
url,
|
|
24338
|
+
label: link.label?.slice(0, 120) ?? "Open result"
|
|
24339
|
+
}
|
|
24340
|
+
] : [];
|
|
24341
|
+
});
|
|
24342
|
+
return {
|
|
24343
|
+
state: images.length || videos.length || links.length ? "ready" : "empty",
|
|
24344
|
+
images,
|
|
24345
|
+
videos,
|
|
24346
|
+
links
|
|
24347
|
+
};
|
|
24348
|
+
}
|
|
24349
|
+
__name(buildTaskResultsView, "buildTaskResultsView");
|
|
24350
|
+
function taskResultsToolMeta() {
|
|
24351
|
+
return {
|
|
24352
|
+
ui: {
|
|
24353
|
+
resourceUri: TASK_RESULTS_APP_RESOURCE_URI
|
|
24354
|
+
},
|
|
24355
|
+
"openai/outputTemplate": TASK_RESULTS_APP_RESOURCE_URI
|
|
24356
|
+
};
|
|
24357
|
+
}
|
|
24358
|
+
__name(taskResultsToolMeta, "taskResultsToolMeta");
|
|
24359
|
+
function renderTaskResultsAppHtml(proxyBaseUrl) {
|
|
24360
|
+
return readFileSync2(HTML_URL, "utf8").replace("__PRODUCTMAKER_ASSET_ORIGIN__", JSON.stringify(assetOrigin(proxyBaseUrl)).replaceAll("<", "\\u003c"));
|
|
24361
|
+
}
|
|
24362
|
+
__name(renderTaskResultsAppHtml, "renderTaskResultsAppHtml");
|
|
24363
|
+
function registerTaskResultsAppResource(server, proxyBaseUrl) {
|
|
24364
|
+
const origin = assetOrigin(proxyBaseUrl);
|
|
24365
|
+
const resourceDomains = origin ? [
|
|
24366
|
+
origin
|
|
24367
|
+
] : [];
|
|
24368
|
+
const html = renderTaskResultsAppHtml(proxyBaseUrl);
|
|
24369
|
+
const meta = {
|
|
24370
|
+
ui: {
|
|
24371
|
+
csp: {
|
|
24372
|
+
resourceDomains,
|
|
24373
|
+
connectDomains: []
|
|
24374
|
+
}
|
|
24375
|
+
},
|
|
24376
|
+
"openai/widgetCSP": {
|
|
24377
|
+
resource_domains: resourceDomains,
|
|
24378
|
+
connect_domains: []
|
|
24379
|
+
},
|
|
24380
|
+
"openai/widgetDescription": "Displays the actual ProductMaker images and videos with playback controls and download links."
|
|
24381
|
+
};
|
|
24382
|
+
registerAppResource2(server, "ProductMaker task results", TASK_RESULTS_APP_RESOURCE_URI, {
|
|
24383
|
+
title: "Your creative",
|
|
24384
|
+
mimeType: RESOURCE_MIME_TYPE2,
|
|
24385
|
+
_meta: meta
|
|
24386
|
+
}, async () => ({
|
|
24387
|
+
contents: [
|
|
24388
|
+
{
|
|
24389
|
+
uri: TASK_RESULTS_APP_RESOURCE_URI,
|
|
24390
|
+
mimeType: RESOURCE_MIME_TYPE2,
|
|
24391
|
+
text: html,
|
|
24392
|
+
_meta: meta
|
|
24393
|
+
}
|
|
24394
|
+
]
|
|
24395
|
+
}));
|
|
24396
|
+
}
|
|
24397
|
+
__name(registerTaskResultsAppResource, "registerTaskResultsAppResource");
|
|
24398
|
+
|
|
24251
24399
|
// src/tools/tasks.ts
|
|
24252
|
-
import { z as
|
|
24400
|
+
import { z as z124 } from "zod";
|
|
24253
24401
|
|
|
24254
24402
|
// src/resolve-image.ts
|
|
24255
24403
|
import { lookup as dnsLookup } from "dns/promises";
|
|
@@ -24810,9 +24958,9 @@ async function resolveMediaRef(ref, opts) {
|
|
|
24810
24958
|
__name(resolveMediaRef, "resolveMediaRef");
|
|
24811
24959
|
|
|
24812
24960
|
// src/tools/shared.ts
|
|
24813
|
-
import { z as
|
|
24814
|
-
var Lang =
|
|
24815
|
-
var Country =
|
|
24961
|
+
import { z as z119 } from "zod";
|
|
24962
|
+
var Lang = z119.string().regex(/^[a-z]{2}(?:[-_][a-zA-Z]{2})?$/, "Usa un c\xF3digo de idioma BCP-47, por ejemplo es, en-US o pt-BR").max(10);
|
|
24963
|
+
var Country = z119.string().min(2).max(3);
|
|
24816
24964
|
var LandingStrategyEnum = LandingStrategySchema;
|
|
24817
24965
|
var LandingImageFormatEnum = LandingImageFormatSchema;
|
|
24818
24966
|
var VideoPresetEnum = VideoPreset.extract([
|
|
@@ -24916,7 +25064,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
|
|
|
24916
25064
|
return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
|
|
24917
25065
|
}
|
|
24918
25066
|
__name(animationStyleApplies, "animationStyleApplies");
|
|
24919
|
-
var VideoTierEnum =
|
|
25067
|
+
var VideoTierEnum = z119.enum([
|
|
24920
25068
|
"basic"
|
|
24921
25069
|
]);
|
|
24922
25070
|
function resolveVideoTier(_tier) {
|
|
@@ -24974,10 +25122,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
|
|
|
24974
25122
|
var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
|
|
24975
25123
|
var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
|
|
24976
25124
|
var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
|
|
24977
|
-
var ImageRefSchema =
|
|
24978
|
-
url:
|
|
24979
|
-
path:
|
|
24980
|
-
assetId:
|
|
25125
|
+
var ImageRefSchema = z119.object({
|
|
25126
|
+
url: z119.string().url().optional().describe('URL p\xFAblica HTTPS de la foto. Ej: una URL de Shopify CDN, Cloudinary, Imgur. \xDAsala cuando el usuario te diga "est\xE1 en X.com/foto.jpg" o cuando la foto ya est\xE9 hospedada.'),
|
|
25127
|
+
path: z119.string().min(1).optional().describe('Ruta del archivo en el computador del usuario. Ej: "/Users/maria/Desktop/foto.jpg", "~/Pictures/camiseta.png", "C:\\Users\\Maria\\Desktop\\foto.jpg". El MCP local la lee del disco y la sube. SOLO funciona cuando el MCP corre local (stdio). NO funciona en mcp.productmaker.app (HTTP) \u2014 ah\xED usa `url`.'),
|
|
25128
|
+
assetId: z119.string().uuid().optional().describe("ID opaco devuelto por check_media_upload. \xDAsalo para una imagen subida desde el MCP App; ProductMaker adopta el archivo directamente y el MCP nunca descarga sus bytes.")
|
|
24981
25129
|
}).refine((v) => [
|
|
24982
25130
|
v.url,
|
|
24983
25131
|
v.path,
|
|
@@ -24985,11 +25133,11 @@ var ImageRefSchema = z118.object({
|
|
|
24985
25133
|
].filter(Boolean).length === 1, {
|
|
24986
25134
|
message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
|
|
24987
25135
|
});
|
|
24988
|
-
var ImagesInput =
|
|
25136
|
+
var ImagesInput = z119.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
|
|
24989
25137
|
const assetCount = images.filter((image) => Boolean(image.assetId)).length;
|
|
24990
25138
|
if (assetCount > 0 && assetCount !== images.length) {
|
|
24991
25139
|
ctx.addIssue({
|
|
24992
|
-
code:
|
|
25140
|
+
code: z119.ZodIssueCode.custom,
|
|
24993
25141
|
message: "all image entries must use assetId, or all must use URL/path sources"
|
|
24994
25142
|
});
|
|
24995
25143
|
}
|
|
@@ -25070,14 +25218,14 @@ async function submitCreative(api, opts) {
|
|
|
25070
25218
|
});
|
|
25071
25219
|
}
|
|
25072
25220
|
__name(submitCreative, "submitCreative");
|
|
25073
|
-
var ResearchTargetCountryEnum =
|
|
25221
|
+
var ResearchTargetCountryEnum = z119.enum([
|
|
25074
25222
|
"CO",
|
|
25075
25223
|
"MX",
|
|
25076
25224
|
"PE",
|
|
25077
25225
|
"EC",
|
|
25078
25226
|
"CL"
|
|
25079
25227
|
]);
|
|
25080
|
-
var ResearchCategoryEnum =
|
|
25228
|
+
var ResearchCategoryEnum = z119.enum([
|
|
25081
25229
|
"auto",
|
|
25082
25230
|
"automotive",
|
|
25083
25231
|
"kitchen",
|
|
@@ -25872,7 +26020,7 @@ function approveRefusalMessage(reason) {
|
|
|
25872
26020
|
__name(approveRefusalMessage, "approveRefusalMessage");
|
|
25873
26021
|
|
|
25874
26022
|
// src/tools/task-outputs.ts
|
|
25875
|
-
import { z as
|
|
26023
|
+
import { z as z120 } from "zod";
|
|
25876
26024
|
|
|
25877
26025
|
// src/asset-proxy.ts
|
|
25878
26026
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
@@ -25978,12 +26126,90 @@ __name(formatCredits, "formatCredits");
|
|
|
25978
26126
|
|
|
25979
26127
|
// src/tools/task-outputs.ts
|
|
25980
26128
|
var WEBAPP_BASE = "https://productmaker.app";
|
|
25981
|
-
|
|
25982
|
-
|
|
25983
|
-
|
|
26129
|
+
function proxifyServiceVideoResult(result, proxyBaseUrl) {
|
|
26130
|
+
if (!proxyBaseUrl || !isProxyEnabled()) return result;
|
|
26131
|
+
const rewrite = /* @__PURE__ */ __name((url, filename) => buildProxyUrl({
|
|
26132
|
+
r2Url: url,
|
|
26133
|
+
filename,
|
|
26134
|
+
proxyBaseUrl
|
|
26135
|
+
}) ?? url, "rewrite");
|
|
26136
|
+
const mg = result.motionGraphics;
|
|
26137
|
+
return {
|
|
26138
|
+
...result,
|
|
26139
|
+
...result.finalMp4Url ? {
|
|
26140
|
+
finalMp4Url: rewrite(result.finalMp4Url, "video-final.mp4")
|
|
26141
|
+
} : {},
|
|
26142
|
+
...result.concatMp4Url ? {
|
|
26143
|
+
concatMp4Url: rewrite(result.concatMp4Url, "video-voices.mp4")
|
|
26144
|
+
} : {},
|
|
26145
|
+
...mg ? {
|
|
26146
|
+
motionGraphics: {
|
|
26147
|
+
...mg,
|
|
26148
|
+
...Array.isArray(mg.variantUrls) ? {
|
|
26149
|
+
variantUrls: mg.variantUrls.map((url, i) => rewrite(url, `video-variant-${i + 2}.mp4`))
|
|
26150
|
+
} : {},
|
|
26151
|
+
...mg.cleanVideoUrl ? {
|
|
26152
|
+
cleanVideoUrl: rewrite(mg.cleanVideoUrl, "video-clean.mp4")
|
|
26153
|
+
} : {},
|
|
26154
|
+
...Array.isArray(mg.cleanVariantUrls) ? {
|
|
26155
|
+
cleanVariantUrls: mg.cleanVariantUrls.map((url, i) => rewrite(url, `video-clean-variant-${i + 2}.mp4`))
|
|
26156
|
+
} : {},
|
|
26157
|
+
...mg.previewUrl ? {
|
|
26158
|
+
previewUrl: rewrite(mg.previewUrl, "service-preview.png")
|
|
26159
|
+
} : {}
|
|
26160
|
+
}
|
|
26161
|
+
} : {}
|
|
26162
|
+
};
|
|
26163
|
+
}
|
|
26164
|
+
__name(proxifyServiceVideoResult, "proxifyServiceVideoResult");
|
|
26165
|
+
function serviceVideoResultMedia(result) {
|
|
26166
|
+
const mg = result.motionGraphics;
|
|
26167
|
+
const candidates = [
|
|
26168
|
+
{
|
|
26169
|
+
url: result.finalMp4Url,
|
|
26170
|
+
label: "Video final"
|
|
26171
|
+
},
|
|
26172
|
+
{
|
|
26173
|
+
url: result.concatMp4Url,
|
|
26174
|
+
label: "Video solo voces"
|
|
26175
|
+
},
|
|
26176
|
+
...(Array.isArray(mg?.variantUrls) ? mg.variantUrls : []).map((url, i) => ({
|
|
26177
|
+
url,
|
|
26178
|
+
label: `Versi\xF3n ${i + 2}`
|
|
26179
|
+
})),
|
|
26180
|
+
{
|
|
26181
|
+
url: mg?.cleanVideoUrl,
|
|
26182
|
+
label: "Video limpio"
|
|
26183
|
+
},
|
|
26184
|
+
...(Array.isArray(mg?.cleanVariantUrls) ? mg.cleanVariantUrls : []).map((url, i) => ({
|
|
26185
|
+
url,
|
|
26186
|
+
label: `Versi\xF3n limpia ${i + 2}`
|
|
26187
|
+
}))
|
|
26188
|
+
];
|
|
26189
|
+
const seen = /* @__PURE__ */ new Set();
|
|
26190
|
+
const videos = candidates.flatMap(({ url, label }) => {
|
|
26191
|
+
if (!url || seen.has(url)) return [];
|
|
26192
|
+
seen.add(url);
|
|
26193
|
+
return [
|
|
26194
|
+
{
|
|
26195
|
+
url,
|
|
26196
|
+
label
|
|
26197
|
+
}
|
|
26198
|
+
];
|
|
26199
|
+
});
|
|
26200
|
+
return {
|
|
26201
|
+
images: [],
|
|
26202
|
+
videos,
|
|
26203
|
+
links: videos
|
|
26204
|
+
};
|
|
26205
|
+
}
|
|
26206
|
+
__name(serviceVideoResultMedia, "serviceVideoResultMedia");
|
|
26207
|
+
var CreativeVariantIdentity = z120.object({
|
|
26208
|
+
variantTaskId: z120.string().uuid(),
|
|
26209
|
+
sourceTaskId: z120.string().uuid(),
|
|
25984
26210
|
kind: TaskCreativeVariantKind,
|
|
25985
26211
|
status: TaskStatusSchema,
|
|
25986
|
-
error:
|
|
26212
|
+
error: z120.string().optional()
|
|
25987
26213
|
});
|
|
25988
26214
|
function proxifyOutputs(outputs, proxyBaseUrl) {
|
|
25989
26215
|
if (!proxyBaseUrl || !isProxyEnabled()) return outputs;
|
|
@@ -26587,29 +26813,29 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
|
|
|
26587
26813
|
__name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
|
|
26588
26814
|
|
|
26589
26815
|
// src/tools/media-presentation.ts
|
|
26590
|
-
import { z as
|
|
26591
|
-
var HttpsPresentationUrlSchema =
|
|
26816
|
+
import { z as z121 } from "zod";
|
|
26817
|
+
var HttpsPresentationUrlSchema = z121.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
|
|
26592
26818
|
var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
|
|
26593
26819
|
const hostname = new URL(value).hostname.toLowerCase();
|
|
26594
26820
|
return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
|
|
26595
26821
|
}, "preview URL must be owned by ProductMaker");
|
|
26596
|
-
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) =>
|
|
26597
|
-
var PresentationImageSchema =
|
|
26598
|
-
kind:
|
|
26822
|
+
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z121.number().int().positive().max(maximum), "positiveIntAtMost");
|
|
26823
|
+
var PresentationImageSchema = z121.object({
|
|
26824
|
+
kind: z121.literal("image"),
|
|
26599
26825
|
url: HttpsPresentationUrlSchema,
|
|
26600
|
-
mimeType:
|
|
26826
|
+
mimeType: z121.enum([
|
|
26601
26827
|
"image/jpeg",
|
|
26602
26828
|
"image/png"
|
|
26603
26829
|
]),
|
|
26604
26830
|
byteSize: positiveIntAtMost(5 * 1024 * 1024),
|
|
26605
26831
|
width: positiveIntAtMost(16384),
|
|
26606
26832
|
height: positiveIntAtMost(16384),
|
|
26607
|
-
alt:
|
|
26833
|
+
alt: z121.string().trim().min(1).max(240)
|
|
26608
26834
|
}).strict();
|
|
26609
26835
|
var McpMediaPresentationSchema = PresentationImageSchema;
|
|
26610
|
-
var GalleryImageSchema =
|
|
26836
|
+
var GalleryImageSchema = z121.object({
|
|
26611
26837
|
url: ProductMakerPreviewUrlSchema,
|
|
26612
|
-
alt:
|
|
26838
|
+
alt: z121.string().trim().min(1).max(240)
|
|
26613
26839
|
});
|
|
26614
26840
|
var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
26615
26841
|
async function imageBlocks(image, transport) {
|
|
@@ -26666,12 +26892,12 @@ async function buildMcpMediaPresentationContent(rawPresentation, transport = "ht
|
|
|
26666
26892
|
];
|
|
26667
26893
|
}
|
|
26668
26894
|
__name(buildMcpMediaPresentationContent, "buildMcpMediaPresentationContent");
|
|
26669
|
-
var OwnedImagePreviewSchema =
|
|
26895
|
+
var OwnedImagePreviewSchema = z121.object({
|
|
26670
26896
|
url: HttpsPresentationUrlSchema.refine((value) => {
|
|
26671
26897
|
const url = new URL(value);
|
|
26672
26898
|
return !url.username && !url.password && !isPrivateHost(url.hostname);
|
|
26673
26899
|
}, "Preview URL must be public HTTPS without credentials"),
|
|
26674
|
-
alt:
|
|
26900
|
+
alt: z121.string().trim().min(1).max(240)
|
|
26675
26901
|
});
|
|
26676
26902
|
async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
|
|
26677
26903
|
const preview2 = OwnedImagePreviewSchema.safeParse(rawPreview);
|
|
@@ -26686,6 +26912,53 @@ async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
|
|
|
26686
26912
|
return imageBlocks(preview2.data, transport);
|
|
26687
26913
|
}
|
|
26688
26914
|
__name(buildMcpImagePreviewContent, "buildMcpImagePreviewContent");
|
|
26915
|
+
async function buildMcpGeneratedImageContent(rawItems, transport = "http") {
|
|
26916
|
+
const blocks = await Promise.all(rawItems.slice(0, MAX_IMAGE_CREATIVE_VARIANTS).map(async (rawItem, index) => {
|
|
26917
|
+
const preview2 = OwnedImagePreviewSchema.safeParse(rawItem);
|
|
26918
|
+
if (!preview2.success) {
|
|
26919
|
+
return [
|
|
26920
|
+
{
|
|
26921
|
+
type: "text",
|
|
26922
|
+
text: `Imagen ${index + 1}: vista previa bloqueada por seguridad. No generes ni recrees una imagen sustituta.`
|
|
26923
|
+
}
|
|
26924
|
+
];
|
|
26925
|
+
}
|
|
26926
|
+
const heading = {
|
|
26927
|
+
type: "text",
|
|
26928
|
+
text: `Imagen ${index + 1} de ProductMaker: ${preview2.data.alt}`
|
|
26929
|
+
};
|
|
26930
|
+
try {
|
|
26931
|
+
const [resolved] = await resolveImages([
|
|
26932
|
+
{
|
|
26933
|
+
url: preview2.data.url
|
|
26934
|
+
}
|
|
26935
|
+
], {
|
|
26936
|
+
transport,
|
|
26937
|
+
maxBytes: MCP_GALLERY_IMAGE_MAX_BYTES
|
|
26938
|
+
});
|
|
26939
|
+
if (resolved) {
|
|
26940
|
+
return [
|
|
26941
|
+
heading,
|
|
26942
|
+
{
|
|
26943
|
+
type: "image",
|
|
26944
|
+
data: resolved.buffer.toString("base64"),
|
|
26945
|
+
mimeType: resolved.mimetype
|
|
26946
|
+
}
|
|
26947
|
+
];
|
|
26948
|
+
}
|
|
26949
|
+
} catch {
|
|
26950
|
+
}
|
|
26951
|
+
return [
|
|
26952
|
+
heading,
|
|
26953
|
+
{
|
|
26954
|
+
type: "text",
|
|
26955
|
+
text: `Imagen ${index + 1}: no se pudo mostrar la imagen original de ProductMaker en este resultado. No generes ni recrees una imagen sustituta; usa el enlace protegido devuelto para esta imagen.`
|
|
26956
|
+
}
|
|
26957
|
+
];
|
|
26958
|
+
}));
|
|
26959
|
+
return blocks.flat();
|
|
26960
|
+
}
|
|
26961
|
+
__name(buildMcpGeneratedImageContent, "buildMcpGeneratedImageContent");
|
|
26689
26962
|
async function buildMcpImageGalleryContent(rawItems, transport = "http") {
|
|
26690
26963
|
const items = rawItems.slice(0, 5).map((rawItem, index) => ({
|
|
26691
26964
|
index,
|
|
@@ -26753,8 +27026,174 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
|
|
|
26753
27026
|
}
|
|
26754
27027
|
__name(buildMcpImageGalleryContent, "buildMcpImageGalleryContent");
|
|
26755
27028
|
|
|
27029
|
+
// src/analytics.ts
|
|
27030
|
+
import { PostHog } from "posthog-node";
|
|
27031
|
+
var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com";
|
|
27032
|
+
var REDACTED = "[REDACTED]";
|
|
27033
|
+
var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
|
|
27034
|
+
"token",
|
|
27035
|
+
"authorization",
|
|
27036
|
+
"apikey",
|
|
27037
|
+
"clientsecret",
|
|
27038
|
+
"subjecttoken",
|
|
27039
|
+
"accesstoken",
|
|
27040
|
+
"refreshtoken",
|
|
27041
|
+
"idtoken",
|
|
27042
|
+
"code",
|
|
27043
|
+
"secret",
|
|
27044
|
+
"password"
|
|
27045
|
+
]);
|
|
27046
|
+
var SENSITIVE_ASSIGNMENT_PATTERN = /(\b(?:access[_-]?token|authorization|client[_-]?secret|subject[_-]?token|refresh[_-]?token|id[_-]?token|api[_-]?key|token|secret|password|code)\b\s*[:=]\s*)(?:(bearer)\s+)?(?:(['"])(.*?)\3|([^\s,;&}"']+))/gi;
|
|
27047
|
+
var BEARER_TOKEN_PATTERN = /\b(bearer\s+)([A-Za-z0-9._~+/=-]+)/gi;
|
|
27048
|
+
var client = null;
|
|
27049
|
+
function getPostHogClient() {
|
|
27050
|
+
if (client) return client;
|
|
27051
|
+
const apiKey = process.env.POSTHOG_API_KEY;
|
|
27052
|
+
if (!apiKey) return null;
|
|
27053
|
+
client = new PostHog(apiKey, {
|
|
27054
|
+
host: process.env.POSTHOG_HOST || DEFAULT_POSTHOG_HOST,
|
|
27055
|
+
flushAt: 20,
|
|
27056
|
+
flushInterval: 1e4
|
|
27057
|
+
});
|
|
27058
|
+
return client;
|
|
27059
|
+
}
|
|
27060
|
+
__name(getPostHogClient, "getPostHogClient");
|
|
27061
|
+
function normalizeKey(key) {
|
|
27062
|
+
return key.replace(/[^a-z0-9]/gi, "").toLowerCase();
|
|
27063
|
+
}
|
|
27064
|
+
__name(normalizeKey, "normalizeKey");
|
|
27065
|
+
function isSensitiveKey(key) {
|
|
27066
|
+
const normalizedKey = normalizeKey(key);
|
|
27067
|
+
return SENSITIVE_KEYS.has(normalizedKey) || normalizedKey.endsWith("token") || normalizedKey.endsWith("secret");
|
|
27068
|
+
}
|
|
27069
|
+
__name(isSensitiveKey, "isSensitiveKey");
|
|
27070
|
+
function sanitizeUrl(value) {
|
|
27071
|
+
try {
|
|
27072
|
+
const parsed = new URL(value);
|
|
27073
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
27074
|
+
return value;
|
|
27075
|
+
}
|
|
27076
|
+
parsed.username = "";
|
|
27077
|
+
parsed.password = "";
|
|
27078
|
+
parsed.search = "";
|
|
27079
|
+
parsed.hash = "";
|
|
27080
|
+
return parsed.toString();
|
|
27081
|
+
} catch {
|
|
27082
|
+
return value;
|
|
27083
|
+
}
|
|
27084
|
+
}
|
|
27085
|
+
__name(sanitizeUrl, "sanitizeUrl");
|
|
27086
|
+
function sanitizeString(value) {
|
|
27087
|
+
const redacted = value.replace(SENSITIVE_ASSIGNMENT_PATTERN, (_match, prefix, scheme, quote) => {
|
|
27088
|
+
const replacement = quote ? `${quote}${REDACTED}${quote}` : REDACTED;
|
|
27089
|
+
return `${prefix}${scheme ? `${scheme} ` : ""}${replacement}`;
|
|
27090
|
+
}).replace(BEARER_TOKEN_PATTERN, `$1${REDACTED}`);
|
|
27091
|
+
const sanitizedUrl = sanitizeUrl(redacted);
|
|
27092
|
+
if (sanitizedUrl !== redacted) return sanitizedUrl;
|
|
27093
|
+
return redacted.replace(/https?:\/\/[^\s"'<>]+/gi, sanitizeUrl);
|
|
27094
|
+
}
|
|
27095
|
+
__name(sanitizeString, "sanitizeString");
|
|
27096
|
+
function sanitizeValue(value) {
|
|
27097
|
+
if (Array.isArray(value)) {
|
|
27098
|
+
return value.map((entry) => sanitizeValue(entry));
|
|
27099
|
+
}
|
|
27100
|
+
if (value && typeof value === "object") {
|
|
27101
|
+
return sanitizeProperties(value);
|
|
27102
|
+
}
|
|
27103
|
+
if (typeof value === "string") {
|
|
27104
|
+
return sanitizeString(value);
|
|
27105
|
+
}
|
|
27106
|
+
return value;
|
|
27107
|
+
}
|
|
27108
|
+
__name(sanitizeValue, "sanitizeValue");
|
|
27109
|
+
function sanitizeProperties(value) {
|
|
27110
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
|
|
27111
|
+
key,
|
|
27112
|
+
isSensitiveKey(key) ? REDACTED : sanitizeValue(entry)
|
|
27113
|
+
]));
|
|
27114
|
+
}
|
|
27115
|
+
__name(sanitizeProperties, "sanitizeProperties");
|
|
27116
|
+
function captureMcpAnalytics(event, subject, properties) {
|
|
27117
|
+
try {
|
|
27118
|
+
const posthog = getPostHogClient();
|
|
27119
|
+
if (!posthog) return;
|
|
27120
|
+
posthog.capture({
|
|
27121
|
+
distinctId: subject ?? "mcp_oauth_aggregate",
|
|
27122
|
+
event,
|
|
27123
|
+
properties: properties ? sanitizeProperties(properties) : void 0
|
|
27124
|
+
});
|
|
27125
|
+
} catch {
|
|
27126
|
+
}
|
|
27127
|
+
}
|
|
27128
|
+
__name(captureMcpAnalytics, "captureMcpAnalytics");
|
|
27129
|
+
|
|
27130
|
+
// src/media-delivery-analytics.ts
|
|
27131
|
+
var MCP_MEDIA_DELIVERY_ANALYTICS_EVENTS = {
|
|
27132
|
+
STARTED: "mcp_media_delivery_started",
|
|
27133
|
+
RESPONSE_DELIVERED: "mcp_media_response_delivered",
|
|
27134
|
+
FAILED: "mcp_media_delivery_failed",
|
|
27135
|
+
SAFE_VARIANT: "mcp_media_delivery_variant"
|
|
27136
|
+
};
|
|
27137
|
+
var RESPONSE_STATES = [
|
|
27138
|
+
"ready",
|
|
27139
|
+
"empty",
|
|
27140
|
+
"pending",
|
|
27141
|
+
"awaiting_review",
|
|
27142
|
+
"error"
|
|
27143
|
+
];
|
|
27144
|
+
var isRecord4 = /* @__PURE__ */ __name((value) => value !== null && typeof value === "object" && !Array.isArray(value), "isRecord");
|
|
27145
|
+
function deliveryProperties(result) {
|
|
27146
|
+
const view = result._meta?.taskResults;
|
|
27147
|
+
const data = isRecord4(view) ? view : {};
|
|
27148
|
+
const responseState = RESPONSE_STATES.find((state) => state === data.state) ?? "unknown";
|
|
27149
|
+
const nativeImageCount = result.content.filter((block) => block.type === "image").length;
|
|
27150
|
+
const viewerImageCount = Array.isArray(data.images) ? data.images.length : 0;
|
|
27151
|
+
const viewerVideoCount = Array.isArray(data.videos) ? data.videos.length : 0;
|
|
27152
|
+
const imageFallbackCount = result.content.filter((block) => block.type === "text" && /^Imagen \d+: (?:no se pudo mostrar|vista previa bloqueada por seguridad)/.test(block.text)).length;
|
|
27153
|
+
const hasImages = nativeImageCount > 0 || viewerImageCount > 0 || imageFallbackCount > 0;
|
|
27154
|
+
return {
|
|
27155
|
+
measurement: "response_delivery",
|
|
27156
|
+
responseState,
|
|
27157
|
+
mediaKind: hasImages ? viewerVideoCount ? "mixed" : "image" : viewerVideoCount ? "video" : "none",
|
|
27158
|
+
nativeImageCount,
|
|
27159
|
+
viewerImageCount,
|
|
27160
|
+
viewerVideoCount,
|
|
27161
|
+
imageFallbackCount
|
|
27162
|
+
};
|
|
27163
|
+
}
|
|
27164
|
+
__name(deliveryProperties, "deliveryProperties");
|
|
27165
|
+
async function observeMcpMediaDelivery(fingerprint, work) {
|
|
27166
|
+
const subject = /^[a-f0-9]{32}$/.test(fingerprint) ? `mcp_credential_${fingerprint}` : "mcp_media_aggregate";
|
|
27167
|
+
const events = MCP_MEDIA_DELIVERY_ANALYTICS_EVENTS;
|
|
27168
|
+
captureMcpAnalytics(events.STARTED, subject, {
|
|
27169
|
+
measurement: "response_delivery"
|
|
27170
|
+
});
|
|
27171
|
+
let result;
|
|
27172
|
+
try {
|
|
27173
|
+
result = await work();
|
|
27174
|
+
} catch (error) {
|
|
27175
|
+
captureMcpAnalytics(events.FAILED, subject, {
|
|
27176
|
+
measurement: "response_delivery",
|
|
27177
|
+
reason: "exception"
|
|
27178
|
+
});
|
|
27179
|
+
throw error;
|
|
27180
|
+
}
|
|
27181
|
+
const properties = deliveryProperties(result);
|
|
27182
|
+
captureMcpAnalytics(events.SAFE_VARIANT, subject, properties);
|
|
27183
|
+
if (result.isError || properties.responseState === "error") {
|
|
27184
|
+
captureMcpAnalytics(events.FAILED, subject, {
|
|
27185
|
+
...properties,
|
|
27186
|
+
reason: result.isError ? "tool_error" : "delivery_error"
|
|
27187
|
+
});
|
|
27188
|
+
} else {
|
|
27189
|
+
captureMcpAnalytics(events.RESPONSE_DELIVERED, subject, properties);
|
|
27190
|
+
}
|
|
27191
|
+
return result;
|
|
27192
|
+
}
|
|
27193
|
+
__name(observeMcpMediaDelivery, "observeMcpMediaDelivery");
|
|
27194
|
+
|
|
26756
27195
|
// src/tools/animated-video.ts
|
|
26757
|
-
import { z as
|
|
27196
|
+
import { z as z122 } from "zod";
|
|
26758
27197
|
|
|
26759
27198
|
// src/tools/paid-confirmation.ts
|
|
26760
27199
|
function describeMarketStudyChoice(enabled) {
|
|
@@ -26867,17 +27306,17 @@ function sortCanonical(items) {
|
|
|
26867
27306
|
});
|
|
26868
27307
|
}
|
|
26869
27308
|
__name(sortCanonical, "sortCanonical");
|
|
26870
|
-
function
|
|
27309
|
+
function isRecord5(value) {
|
|
26871
27310
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26872
27311
|
}
|
|
26873
|
-
__name(
|
|
27312
|
+
__name(isRecord5, "isRecord");
|
|
26874
27313
|
function collectLanguageCodes(value, out) {
|
|
26875
27314
|
if (Array.isArray(value)) {
|
|
26876
27315
|
const items = value;
|
|
26877
27316
|
for (const item of items) collectLanguageCodes(item, out);
|
|
26878
27317
|
return out;
|
|
26879
27318
|
}
|
|
26880
|
-
if (!
|
|
27319
|
+
if (!isRecord5(value)) return out;
|
|
26881
27320
|
for (const [key, entry] of Object.entries(value)) {
|
|
26882
27321
|
if (LANGUAGE_FIELDS.has(key) && typeof entry === "string") {
|
|
26883
27322
|
const base = entry.trim().split(/[-_]/)[0]?.toLowerCase();
|
|
@@ -26923,7 +27362,7 @@ function normalizeForKey(value, languages) {
|
|
|
26923
27362
|
const items = value;
|
|
26924
27363
|
return items.map((item) => normalizeForKey(item, languages));
|
|
26925
27364
|
}
|
|
26926
|
-
if (!
|
|
27365
|
+
if (!isRecord5(value)) return value;
|
|
26927
27366
|
const out = {};
|
|
26928
27367
|
for (const [key, entry] of Object.entries(value)) {
|
|
26929
27368
|
if (PARAPHRASE_PRONE_FIELDS.has(key)) {
|
|
@@ -27003,30 +27442,30 @@ function hookVariantsLabel(count) {
|
|
|
27003
27442
|
return count === 1 ? "1 versi\xF3n del gancho" : `${count} versiones del gancho`;
|
|
27004
27443
|
}
|
|
27005
27444
|
__name(hookVariantsLabel, "hookVariantsLabel");
|
|
27006
|
-
var DurationInput =
|
|
27007
|
-
var CreateAnimatedVideoInput =
|
|
27008
|
-
action:
|
|
27445
|
+
var DurationInput = z122.union(MOTION_GRAPHICS_DURATIONS.map((d) => z122.literal(d)));
|
|
27446
|
+
var CreateAnimatedVideoInput = z122.object({
|
|
27447
|
+
action: z122.enum([
|
|
27009
27448
|
"prepare",
|
|
27010
27449
|
"status",
|
|
27011
27450
|
"cancel",
|
|
27012
27451
|
"generate"
|
|
27013
27452
|
]).default("prepare").describe("prepare inicia una captura gratuita; status consulta websiteCaptureId; cancel la cancela; generate requiere captura ready y confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrar vista previa y precio."),
|
|
27014
|
-
brandId:
|
|
27015
|
-
websiteCaptureId:
|
|
27016
|
-
generationRequestId:
|
|
27017
|
-
confirmed:
|
|
27453
|
+
brandId: z122.string().uuid().optional().describe("ID de un servicio propio y listo (de create_brand). Obligatorio al preparar y crear videos nuevos. Conserva el mismo brandId en reintentos; si recuperas una generaci\xF3n hist\xF3rica aceptada sin este campo, om\xEDtelo como en la petici\xF3n original. status/cancel no lo necesitan."),
|
|
27454
|
+
websiteCaptureId: z122.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
|
|
27455
|
+
generationRequestId: z122.string().uuid().optional().describe("Identidad opcional de una generaci\xF3n confirmada. Repite el mismo UUID al recuperar una respuesta perdida; usa otro \xFAnicamente cuando el usuario pida y confirme otro video, nunca por un error de transporte."),
|
|
27456
|
+
confirmed: z122.boolean().optional().describe("Solo true despu\xE9s de que el usuario confirme esta captura, formato, duraci\xF3n, idioma y precio. Obligatorio para generate; preparar no genera ni cobra."),
|
|
27018
27457
|
// Plain text, not `.url()`: users type «cal.com», and the web accepts it.
|
|
27019
27458
|
// normalizeWebAddress (shared with the web) adds https:// and refuses
|
|
27020
27459
|
// anything that is not a public http(s) address.
|
|
27021
|
-
landingUrl:
|
|
27460
|
+
landingUrl: z122.string().trim().min(1).optional().describe("Enlace p\xFAblico de la p\xE1gina del servicio, como lo dio el usuario (\xABcal.com\xBB o \xABhttps://cal.com\xBB). El video sale de lo que muestra esa p\xE1gina: su marca, colores y mensajes."),
|
|
27022
27461
|
format: MotionGraphicsFormatSchema.optional().describe('Formato: "vertical" (9:16, Reels/TikTok), "square" (1:1, feed) u "horizontal" (16:9, YouTube/web). Si el usuario no lo dijo, PREG\xDANTALE.'),
|
|
27023
27462
|
durationSec: DurationInput.optional().describe(`Duraci\xF3n en segundos: ${MOTION_GRAPHICS_DURATIONS.join(", ")}. Fija el precio (ver la descripci\xF3n de la herramienta). Si el usuario no la dijo, PREG\xDANTALE.`),
|
|
27024
27463
|
language: MotionGraphicsLanguageSchema.optional().describe('Idioma de los textos del video: "es", "en" o "pt".'),
|
|
27025
27464
|
videoQuality: MotionGraphicsVideoQualitySchema.default(DEFAULT_MOTION_GRAPHICS_VIDEO_QUALITY).describe('Calidad IA: "economy" (econ\xF3mica) o "pro" (alta, por defecto). Afecta el precio de los clips IA.'),
|
|
27026
27465
|
videoResolution: MotionGraphicsVideoResolutionSchema.default(DEFAULT_MOTION_GRAPHICS_VIDEO_RESOLUTION).describe('Resoluci\xF3n: "480p" (por defecto), "720p" o "1080p". 1080p solo est\xE1 disponible con videoQuality="pro".'),
|
|
27027
|
-
notes:
|
|
27466
|
+
notes: z122.string().trim().max(MOTION_GRAPHICS_NOTES_MAX_CHARS).optional().describe("Opcional. Idea creativa, escenarios, acciones, di\xE1logo, voz o m\xFAsica en lenguaje natural. El director puede hacer solo motion graphics, escenas reales o escenas imposibles seg\xFAn la idea; las frases gu\xEDan el guion sin garantizar reproducci\xF3n exacta."),
|
|
27028
27467
|
hookVariants: MotionGraphicsHookVariantsSchema.optional().describe(`Opcional. Cantidad de videos independientes, de 1 a ${MOTION_GRAPHICS_HOOK_VARIANTS_MAX} (por defecto 1). Cada uno tiene su propio \xE1ngulo, guion y estilo visual, respetando notes, y reserva el precio completo de un video (ver la descripci\xF3n); \xFAsalo solo si el usuario lo pide.`),
|
|
27029
|
-
music:
|
|
27468
|
+
music: z122.boolean().optional().describe("Opcional. M\xFAsica y efectos dirigidos seg\xFAn el negocio y el video (por defecto true), con una copia adicional solo con voces. false entrega solo voces, sin m\xFAsica ni efectos a\xF1adidos ni el cargo de m\xFAsica. \xDAsalo solo si el usuario lo pide.")
|
|
27030
27469
|
}).strict();
|
|
27031
27470
|
function captureNextAction(capture) {
|
|
27032
27471
|
if (capture.status === "ready") return "Muestra la vista previa al usuario y confirma formato, duraci\xF3n, idioma, calidad IA, resoluci\xF3n y precio. Solo despu\xE9s llama create_animated_video con action=generate, este websiteCaptureId y confirmed=true.";
|
|
@@ -27079,33 +27518,33 @@ var FORMAT_LABELS = {
|
|
|
27079
27518
|
square: "cuadrado 1:1",
|
|
27080
27519
|
horizontal: "horizontal 16:9"
|
|
27081
27520
|
};
|
|
27082
|
-
var AnimatedVideoResultSchema =
|
|
27083
|
-
status:
|
|
27521
|
+
var AnimatedVideoResultSchema = z122.object({
|
|
27522
|
+
status: z122.enum([
|
|
27084
27523
|
"pending",
|
|
27085
27524
|
"done",
|
|
27086
27525
|
"error"
|
|
27087
27526
|
]),
|
|
27088
|
-
serviceMode:
|
|
27089
|
-
finalMp4Url:
|
|
27090
|
-
adCopy:
|
|
27091
|
-
adCopies:
|
|
27092
|
-
error:
|
|
27093
|
-
motionGraphics:
|
|
27527
|
+
serviceMode: z122.literal("motion_graphics"),
|
|
27528
|
+
finalMp4Url: z122.string().optional(),
|
|
27529
|
+
adCopy: z122.string().optional(),
|
|
27530
|
+
adCopies: z122.array(z122.string()).optional(),
|
|
27531
|
+
error: z122.string().optional(),
|
|
27532
|
+
motionGraphics: z122.object({
|
|
27094
27533
|
stage: MotionGraphicsStageSchema,
|
|
27095
27534
|
format: MotionGraphicsFormatSchema,
|
|
27096
|
-
durationSec:
|
|
27097
|
-
width:
|
|
27098
|
-
height:
|
|
27535
|
+
durationSec: z122.number(),
|
|
27536
|
+
width: z122.number().optional(),
|
|
27537
|
+
height: z122.number().optional(),
|
|
27099
27538
|
language: MotionGraphicsLanguageSchema.optional(),
|
|
27100
27539
|
videoQuality: MotionGraphicsVideoQualitySchema.optional().catch(void 0),
|
|
27101
27540
|
videoResolution: MotionGraphicsVideoResolutionSchema.optional().catch(void 0),
|
|
27102
|
-
creativeBatch:
|
|
27541
|
+
creativeBatch: z122.object({
|
|
27103
27542
|
index: MotionGraphicsHookVariantsSchema,
|
|
27104
27543
|
count: MotionGraphicsHookVariantsSchema,
|
|
27105
|
-
tasks:
|
|
27106
|
-
taskId:
|
|
27544
|
+
tasks: z122.array(z122.object({
|
|
27545
|
+
taskId: z122.string().uuid(),
|
|
27107
27546
|
index: MotionGraphicsHookVariantsSchema,
|
|
27108
|
-
status:
|
|
27547
|
+
status: z122.enum([
|
|
27109
27548
|
"queued",
|
|
27110
27549
|
"processing",
|
|
27111
27550
|
"done",
|
|
@@ -27113,29 +27552,29 @@ var AnimatedVideoResultSchema = z121.object({
|
|
|
27113
27552
|
])
|
|
27114
27553
|
})).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX)
|
|
27115
27554
|
}).optional().catch(void 0),
|
|
27116
|
-
queuedAt:
|
|
27117
|
-
jobsAhead:
|
|
27118
|
-
stageStartedAt:
|
|
27119
|
-
renderProgress:
|
|
27555
|
+
queuedAt: z122.string().optional(),
|
|
27556
|
+
jobsAhead: z122.number().int().nonnegative().optional(),
|
|
27557
|
+
stageStartedAt: z122.string().optional(),
|
|
27558
|
+
renderProgress: z122.number().optional(),
|
|
27120
27559
|
// AI clip fields (absent on a video paid before clips, or from an API
|
|
27121
27560
|
// that predates them). Lenient: an unreadable value is dropped
|
|
27122
27561
|
// instead of hiding the status.
|
|
27123
|
-
clipCount:
|
|
27124
|
-
clipsUsed:
|
|
27125
|
-
clipPriceCents:
|
|
27126
|
-
clipsRefunded:
|
|
27562
|
+
clipCount: z122.number().int().nonnegative().optional().catch(void 0),
|
|
27563
|
+
clipsUsed: z122.number().int().nonnegative().optional().catch(void 0),
|
|
27564
|
+
clipPriceCents: z122.number().finite().nonnegative().optional().catch(void 0),
|
|
27565
|
+
clipsRefunded: z122.number().int().nonnegative().optional().catch(void 0),
|
|
27127
27566
|
// Hook versions (absent from an API or a video before them): the
|
|
27128
27567
|
// count ordered and, once done, the signed URLs of the EXTRA versions
|
|
27129
27568
|
// (hook 2, hook 3); `finalMp4Url` is hook 1.
|
|
27130
|
-
hookVariants:
|
|
27131
|
-
cleanVideoUrl:
|
|
27132
|
-
cleanVariantUrls:
|
|
27133
|
-
variantUrls:
|
|
27569
|
+
hookVariants: z122.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
|
|
27570
|
+
cleanVideoUrl: z122.string().url().optional().catch(void 0),
|
|
27571
|
+
cleanVariantUrls: z122.array(z122.string().url()).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
|
|
27572
|
+
variantUrls: z122.array(z122.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
|
|
27134
27573
|
// Extra hook versions given back, as the task recorded it once the
|
|
27135
27574
|
// refunds landed (absent until then, and from an API before it).
|
|
27136
|
-
variantsRefunded:
|
|
27137
|
-
activity:
|
|
27138
|
-
previewUrl:
|
|
27575
|
+
variantsRefunded: z122.number().int().nonnegative().optional().catch(void 0),
|
|
27576
|
+
activity: z122.array(MotionGraphicsActivitySchema).optional().catch(void 0),
|
|
27577
|
+
previewUrl: z122.string().optional()
|
|
27139
27578
|
}).passthrough()
|
|
27140
27579
|
}).passthrough();
|
|
27141
27580
|
function parseAnimatedVideoResult(value) {
|
|
@@ -27414,7 +27853,7 @@ function registerAnimatedVideoTools(server, api) {
|
|
|
27414
27853
|
nowMs: 0
|
|
27415
27854
|
})
|
|
27416
27855
|
});
|
|
27417
|
-
const parsedTaskIds =
|
|
27856
|
+
const parsedTaskIds = z122.array(z122.string().uuid()).min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).safeParse(created.taskIds);
|
|
27418
27857
|
const taskIds = parsedTaskIds.success && parsedTaskIds.data[0] === created.taskId ? parsedTaskIds.data : void 0;
|
|
27419
27858
|
const receipt = {
|
|
27420
27859
|
taskId: created.taskId,
|
|
@@ -27456,10 +27895,10 @@ function registerAnimatedVideoTools(server, api) {
|
|
|
27456
27895
|
__name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
|
|
27457
27896
|
|
|
27458
27897
|
// src/tools/winning-product-image.ts
|
|
27459
|
-
import { z as
|
|
27460
|
-
var WinnerReferenceInput =
|
|
27461
|
-
runId:
|
|
27462
|
-
candidateSourceId:
|
|
27898
|
+
import { z as z123 } from "zod";
|
|
27899
|
+
var WinnerReferenceInput = z123.object({
|
|
27900
|
+
runId: z123.string().uuid(),
|
|
27901
|
+
candidateSourceId: z123.string().trim().min(1).max(160)
|
|
27463
27902
|
}).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
|
|
27464
27903
|
async function resolveWinnerImages(api, winnerReference, images) {
|
|
27465
27904
|
if (!winnerReference) return images;
|
|
@@ -27496,62 +27935,62 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
|
|
|
27496
27935
|
var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
|
|
27497
27936
|
var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
|
|
27498
27937
|
var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
|
|
27499
|
-
var CreateProductTaskInput =
|
|
27938
|
+
var CreateProductTaskInput = z124.object({
|
|
27500
27939
|
images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
|
|
27501
27940
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
27502
|
-
projectId:
|
|
27503
|
-
productUrl:
|
|
27941
|
+
projectId: z124.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
|
|
27942
|
+
productUrl: z124.string().url().optional().describe("Opcional. URL de la p\xE1gina del producto (Shopify, AliExpress, Amazon, etc.) para enriquecer el contexto. Si se omite, la IA infiere todo desde la imagen."),
|
|
27504
27943
|
language: Lang.describe('C\xF3digo de idioma para el contenido generado. Ejemplos: "es", "en", "pt". REQUERIDO \u2014 si el usuario no lo especific\xF3, PREG\xDANTALE antes de invocar. NUNCA infieras desde el contexto del chat ni asumas "es" por default.'),
|
|
27505
27944
|
country: Country.describe('C\xF3digo ISO del pa\xEDs objetivo. Ejemplos: "CO", "MX", "US", "AR". Define moneda, m\xE9todos de pago locales y tono. REQUERIDO \u2014 si el usuario no lo especific\xF3, PREG\xDANTALE antes de invocar. NUNCA infieras desde el contexto del chat.'),
|
|
27506
|
-
price:
|
|
27507
|
-
compareAtPrice:
|
|
27508
|
-
offer:
|
|
27509
|
-
paymentMethods:
|
|
27510
|
-
productContext:
|
|
27511
|
-
productLabel:
|
|
27945
|
+
price: z124.string().min(1).max(120).optional().describe('Precio que se mostrar\xE1 en la landing y video. Formato libre \u2014 ej. "$89.900", "USD 29.99", "MXN 599". Opcional pero MUY IMPACTANTE: si el usuario no lo mencion\xF3, PREG\xDANTALE antes de invocar. Si te dice "t\xFA elige", om\xEDtelo y el backend sugiere uno.'),
|
|
27946
|
+
compareAtPrice: z124.string().min(1).max(120).optional().describe('Opcional. Precio anterior para comunicar un descuento real en landing e im\xE1genes. Ej. "$129.000" cuando price="$89.900".'),
|
|
27947
|
+
offer: z124.string().min(1).max(240).optional().describe('Oferta o promoci\xF3n a destacar. Ej. "2x1", "Env\xEDo gratis hoy", "50% OFF". Opcional pero MUY IMPACTANTE: si el usuario no lo mencion\xF3, PREG\xDANTALE antes de invocar (es v\xE1lido que diga "sin oferta"). Si te dice "t\xFA elige", om\xEDtelo.'),
|
|
27948
|
+
paymentMethods: z124.string().min(1).max(240).optional().describe('Opcional. M\xE9todos de pago que puede mostrar la landing. Ej. "Tarjeta, PSE, Nequi, Contraentrega". Si se omite, la landing no muestra m\xE9todos de pago.'),
|
|
27949
|
+
productContext: z124.string().max(PRODUCT_CONTEXT_MAX_CHARS).optional().describe("Opcional. Informacion adicional del producto que la IA debe usar como contexto prioritario: uso real, comprador, restricciones, diferenciadores o direccion creativa. No reemplaza la investigacion de competencia; si hay competencia, guia el primer angulo y los outputs no deben contradecirlo."),
|
|
27950
|
+
productLabel: z124.string().trim().max(80).optional().describe('Opcional. Qu\xE9 es el producto, en pocas palabras (ej. "quita pelusas para ropa"). Es AUTORITATIVO: si lo env\xEDas, la IA usa esta identidad y no la reemplaza por otra categor\xEDa. Si lo omites, la IA detecta el producto desde la imagen.'),
|
|
27512
27951
|
videoPreset: VideoPresetEnum.default("auto").describe('Opcional. Tipo/narrativa del video \u2014 \xFAnico campo de "estilo" que el usuario controla. Default "auto" (la IA escoge tras analizar el producto). Todos los presets funcionan a 15s (single_call) y 30s (Multiescena); "problem_solution" en single_call abre sin el producto y el producto entra por referencia en su beat de soluci\xF3n. Opciones: "auto", "ugc_dynamic" (review con experiencia y prueba), "ugc_how_to" (tutorial con pasos y resultado visible), "ugc_unboxing_chaos" (apertura y primera prueba), "problem_solution" (problema concreto, producto como soluci\xF3n y CTA), "product_showcase" (producto ejecutando una funci\xF3n real), "wearable_showcase" (prenda o accesorio modelado), "cinematic" (TV spot con receta cinematogr\xE1fica), "wild_card" (idea imposible: un truco visual que en la vida real no podr\xEDa pasar, y al cierre la invitaci\xF3n a comprar), "pixar_problem" (problema animado 3D), "pixar_sassy" (producto que habla). Si el usuario pide algo fuera de esta lista, p\xEDdele una opci\xF3n v\xE1lida.'),
|
|
27513
27952
|
animationStyle: AnimationStyleEnum.optional().describe('Opcional. Estilo visual SOLO para presets animados ("pixar_problem" o "pixar_sassy") \u2014 la API lo rechaza con cualquier otro preset. Opciones: "pixar_3d" (default, look 3D de pel\xEDcula animada), "claymation" (plastilina stop-motion artesanal), "wes_anderson" (tableau sim\xE9trico pastel), "sci_fi" (futurista con HUDs y ne\xF3n), "realista" (fotorrealista, fiel al producto). Si el usuario pide un look animado sin nombrar el estilo, omite el campo.'),
|
|
27514
|
-
durationSeconds:
|
|
27515
|
-
|
|
27516
|
-
|
|
27953
|
+
durationSeconds: z124.union([
|
|
27954
|
+
z124.literal(15),
|
|
27955
|
+
z124.literal(30)
|
|
27517
27956
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
27518
|
-
pauseForAngleReview:
|
|
27519
|
-
aiDecidesAll:
|
|
27957
|
+
pauseForAngleReview: z124.boolean().optional().describe("Compatibilidad heredada. MCP deriva esta pausa de aiDecidesAll: manual siempre pausa y autom\xE1tico siempre la omite. No uses este campo para saltar reviews."),
|
|
27958
|
+
aiDecidesAll: z124.boolean().optional().describe("Mapea el toggle web \u201CDejar que la IA decida todo\u201D. Si true, ProductMaker omite reviews. Act\xEDvalo \xFAnicamente cuando el usuario lo pida expl\xEDcitamente. Omitido/false = reviews conversacionales."),
|
|
27520
27959
|
videoTier: VideoTierEnum.optional().describe('Opcional. Estilo del video. "basic" = "Realista" para 15s; al pedir durationSeconds=30 el sistema selecciona internamente Multiescena. No se expone el tier interno directamente.'),
|
|
27521
27960
|
videoStructure: VideoStructureEnum.default("single_take").describe('Opcional. Formato: "single_take" = Un solo clip (generado completo; puede incluir cambios de plano) o "multi_scene" = Multiescena. Default: single_take.'),
|
|
27522
27961
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
27523
27962
|
videoResolution: VideoResolutionEnum.optional().describe('Opcional. Resoluci\xF3n del render. En la web se pregunta "\xBFResoluci\xF3n del video?". "480p" = excelente calidad y m\xE1s econ\xF3mico (RECOMENDADO, default si se omite); "720p" = m\xE1xima nitidez, entre 3% y 15% m\xE1s caro seg\xFAn formato y tier. Si el usuario no menciona resoluci\xF3n, OMITE este campo (el backend usa 480p).'),
|
|
27524
|
-
videoAngleCount:
|
|
27963
|
+
videoAngleCount: z124.number().int().min(1).max(3).optional().describe("Cantidad de videos a renderizar: 1, 2 o 3. REQUERIDO cuando outputs incluye video (o se omite outputs, cuyo default incluye video); om\xEDtelo s\xF3lo cuando no se generar\xE1 video. Preg\xFAntalo incluso con aiDecidesAll=true porque cambia el costo."),
|
|
27525
27964
|
angleNarratives: PublicNarrativeStyleEnum.array().max(3).optional().describe('Opcional. Narrativa POR \xC1NGULO (posicional). Valores actuales: "review", "ugc_how_to", "ugc_unboxing_chaos", "problem_product_cta" (problema concreto, producto como soluci\xF3n y CTA), "product_showcase", "wearable_showcase", "cinematic", "wild_card", "animated_problem_pixar", "sassy_product_pixar", "market" (narrativa an\xE1lisis de mercado: adapta el video a los patrones ganadores estudiados de la competencia; requiere competitorScanEnabled: true). angleNarratives[i] fuerza la narrativa del \xE1ngulo i; las posiciones restantes las elige la IA. La lista no puede superar videoAngleCount.'),
|
|
27526
|
-
outputs:
|
|
27965
|
+
outputs: z124.array(z124.enum([
|
|
27527
27966
|
"landing",
|
|
27528
27967
|
"video",
|
|
27529
27968
|
"image"
|
|
27530
27969
|
])).min(1).max(3).optional().describe(`Opcional. Qu\xE9 outputs generar. Default: todos ["landing","video","image"]. Para 2 outputs: ["landing","image"] (sin video), ["video","image"] (sin landing), ["landing","video"] (sin imagen). ${createProductTaskSingleOutputDescription}`),
|
|
27531
|
-
includeInitialLandingGif:
|
|
27532
|
-
competitorScanEnabled:
|
|
27970
|
+
includeInitialLandingGif: z124.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
|
|
27971
|
+
competitorScanEnabled: z124.boolean().optional().describe("Opcional. Default false: omitirlo significa SIN estudio de mercado. Antes de crear, llama estimate_market_study_cost con kind=product_task, muestra al usuario el costo con y sin estudio y preg\xFAntale si lo quiere; env\xEDa true solo si lo acepta (o si solicita la narrativa an\xE1lisis de mercado). Si la tarea incluye video, true analiza anuncios de la competencia y desbloquea la narrativa an\xE1lisis de mercado; si el estudio no encuentra datos suficientes, degrada al planner cl\xE1sico."),
|
|
27533
27972
|
generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, efectos y m\xFAsica sobre cada video entregado (variante with_ai_edit; se cobra al entregar, por video). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro"; false/omitido = sin edici\xF3n.'),
|
|
27534
|
-
replicateWinnerWhenFound:
|
|
27535
|
-
brandId:
|
|
27536
|
-
actorId:
|
|
27973
|
+
replicateWinnerWhenFound: z124.boolean().optional().describe("Conserva la preferencia de copiar un ganador si existe. false estudia el mercado sin reemplazar un \xE1ngulo por el anuncio ganador. No a\xF1ade una pregunta obligatoria."),
|
|
27974
|
+
brandId: z124.string().uuid().optional().describe("Opcional. ID de una marca del usuario; si se env\xEDa, el sistema usa su voz, colores y persona para enriquecer los outputs generados."),
|
|
27975
|
+
actorId: z124.string().trim().min(1).max(120).optional().describe("Opcional. ID de un personaje guardado (usa list_actors para verlos). Si lo env\xEDas, su foto y su voz mandan sobre la descripci\xF3n de texto."),
|
|
27537
27976
|
creativeGender: CreativeGenderEnum.optional().describe('Opcional. QUI\xC9N APARECE EN PANTALLA en todos los creativos de la task: el presentador del video, las personas fotografiadas en la landing y la persona del anuncio. NO es la voz. M\xE1ndalo en cuanto el usuario lo diga en cualquier momento de la conversaci\xF3n y con cualquier redacci\xF3n ("quiero una mujer", "que salga un hombre", "esto es para hombres"): si no lo mandas, el g\xE9nero lo inventa la IA y el usuario recibe lo contrario de lo que pidi\xF3 sin ning\xFAn aviso. "mixed" solo cuando pida expl\xEDcitamente ambos. Si adem\xE1s mandas actorId, el personaje guardado manda sobre este campo.'),
|
|
27538
|
-
creativeDirection:
|
|
27539
|
-
headline:
|
|
27540
|
-
subheadline:
|
|
27977
|
+
creativeDirection: z124.string().max(500).optional().describe('Opcional. Direcci\xF3n creativa en texto libre (colores, mood, estilo) que aplica a los outputs de IMAGEN y LANDING (no al video \u2014 el estilo/ambiente del video se dirige con scriptNotes). M\xC1XIMA PRIORIDAD: anula marca, colores y estilo por defecto. Ej. "amarillo y azul, minimalista". M\xE1x 500 caracteres.'),
|
|
27978
|
+
headline: z124.string().max(120).optional().describe("Opcional. Titular EXACTO a renderizar. Se imprime tal cual: la IA no lo reescribe, no lo acorta y no lo traduce. Se aplica a las IM\xC1GENES y a la portada de la landing de esta task (el video no lo usa; para el video usa scriptNotes). \xDAsalo cuando el copy es de marca y no es negociable. M\xE1x 120 caracteres. Si lo omites, la IA escribe el titular."),
|
|
27979
|
+
subheadline: z124.string().max(160).optional().describe("Opcional. Subt\xEDtulo EXACTO a renderizar, misma regla que headline. Independiente: puedes fijar solo el subt\xEDtulo. M\xE1x 160 caracteres."),
|
|
27541
27980
|
landingStrategy: LandingStrategyEnum.optional().describe('Opcional. Estructura de la landing cl\xE1sica cuando landing est\xE1 entre outputs: "classic" (estructura original probada y recomendada; default del primer rollout), "auto" (la IA decide; experimental), "pain_solution", "social_proof" (Landing Viral: UGC, WhatsApp, Instagram y evidencia social), "benefits_clarity", "offer_value" o "lifestyle_identity". Default "classic".'),
|
|
27542
27981
|
landingImageFormat: LandingImageFormatEnum.default("9:16").describe('Opcional. Formato/relaci\xF3n de aspecto de las im\xE1genes de la landing cl\xE1sica cuando landing est\xE1 entre outputs: "9:16" (vertical, por defecto), "4:5" (vertical compacto para feed) o "1:1" (cuadrado). Default "9:16".')
|
|
27543
27982
|
}).strict();
|
|
27544
|
-
var CreateServiceVideoInput =
|
|
27545
|
-
landingUrl:
|
|
27546
|
-
additionalContext:
|
|
27983
|
+
var CreateServiceVideoInput = z124.object({
|
|
27984
|
+
landingUrl: z124.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
|
|
27985
|
+
additionalContext: z124.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
|
|
27547
27986
|
language: Lang.describe("Idioma del video: es, en o pt."),
|
|
27548
|
-
voiceId:
|
|
27549
|
-
brandId:
|
|
27550
|
-
reviewMode:
|
|
27987
|
+
voiceId: z124.string().trim().min(1).pipe(VoiceId).optional().describe('Opcional. Voz para toda la narraci\xF3n. Usa "auto" para que la IA la alinee con el presentador. Las voces del banco compartido fueron retiradas.'),
|
|
27988
|
+
brandId: z124.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
|
|
27989
|
+
reviewMode: z124.enum([
|
|
27551
27990
|
"automatic",
|
|
27552
27991
|
"guided"
|
|
27553
27992
|
]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
|
|
27554
|
-
videoPreset:
|
|
27993
|
+
videoPreset: z124.enum([
|
|
27555
27994
|
"auto",
|
|
27556
27995
|
"ugc_dynamic",
|
|
27557
27996
|
"ugc_how_to",
|
|
@@ -27561,128 +28000,128 @@ var CreateServiceVideoInput = z123.object({
|
|
|
27561
28000
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
27562
28001
|
videoResolution: VideoResolutionEnum.default("480p").describe('Opcional. Resoluci\xF3n: "480p" o "720p". 720p cuesta m\xE1s por segundo y solo est\xE1 disponible en "economy" y "pro" (Medio = 768P). Default: 480p.')
|
|
27563
28002
|
}).strict();
|
|
27564
|
-
var GetTaskStatusInput =
|
|
27565
|
-
taskId:
|
|
27566
|
-
waitSeconds:
|
|
28003
|
+
var GetTaskStatusInput = z124.object({
|
|
28004
|
+
taskId: z124.string().min(1),
|
|
28005
|
+
waitSeconds: z124.number().int().min(0).max(120).optional()
|
|
27567
28006
|
});
|
|
27568
|
-
var ListTasksInput =
|
|
27569
|
-
limit:
|
|
27570
|
-
offset:
|
|
27571
|
-
search:
|
|
28007
|
+
var ListTasksInput = z124.object({
|
|
28008
|
+
limit: z124.number().int().min(1).max(50).optional(),
|
|
28009
|
+
offset: z124.number().int().min(0).optional(),
|
|
28010
|
+
search: z124.string().optional()
|
|
27572
28011
|
});
|
|
27573
28012
|
var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
|
|
27574
28013
|
var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
|
|
27575
|
-
var EditTaskDraftInput =
|
|
27576
|
-
taskId:
|
|
27577
|
-
angleIndex:
|
|
27578
|
-
angle:
|
|
27579
|
-
angle:
|
|
27580
|
-
buyerPersona:
|
|
27581
|
-
actor:
|
|
27582
|
-
actorId:
|
|
27583
|
-
gender:
|
|
28014
|
+
var EditTaskDraftInput = z124.object({
|
|
28015
|
+
taskId: z124.string().min(1),
|
|
28016
|
+
angleIndex: z124.number().int().min(0),
|
|
28017
|
+
angle: z124.object({
|
|
28018
|
+
angle: z124.string().min(1).max(480),
|
|
28019
|
+
buyerPersona: z124.string().min(1).max(360),
|
|
28020
|
+
actor: z124.string().min(1).max(360).optional(),
|
|
28021
|
+
actorId: z124.string().trim().min(1).optional().describe("Opcional. ID de un personaje guardado (usa list_actors para verlos). Si lo env\xEDas, su foto y su voz mandan sobre la descripci\xF3n de texto."),
|
|
28022
|
+
gender: z124.enum([
|
|
27584
28023
|
"female",
|
|
27585
28024
|
"male"
|
|
27586
28025
|
]).optional(),
|
|
27587
|
-
scriptNotes:
|
|
28026
|
+
scriptNotes: z124.string().max(2e3).optional()
|
|
27588
28027
|
})
|
|
27589
28028
|
});
|
|
27590
|
-
var PendingActionPayload =
|
|
27591
|
-
|
|
27592
|
-
kind:
|
|
28029
|
+
var PendingActionPayload = z124.discriminatedUnion("kind", [
|
|
28030
|
+
z124.object({
|
|
28031
|
+
kind: z124.literal("product_reference_set_approval"),
|
|
27593
28032
|
scope: ProductReferenceScopeEnum.optional(),
|
|
27594
|
-
scopeKey:
|
|
27595
|
-
scopeSnapshotId:
|
|
27596
|
-
expectedScopeHash:
|
|
28033
|
+
scopeKey: z124.string().min(1).max(120).optional(),
|
|
28034
|
+
scopeSnapshotId: z124.string().uuid().optional(),
|
|
28035
|
+
expectedScopeHash: z124.string().min(1).max(128).optional(),
|
|
27597
28036
|
decision: ProductReferenceResolutionDecisionEnum,
|
|
27598
28037
|
reason: ProductReferenceRejectionReasonEnum.optional(),
|
|
27599
|
-
affectedRefKeys:
|
|
27600
|
-
affectedPhotoNumbers:
|
|
27601
|
-
recoveryAction:
|
|
28038
|
+
affectedRefKeys: z124.array(z124.string().min(1).max(200)).min(1).optional(),
|
|
28039
|
+
affectedPhotoNumbers: z124.array(z124.number().int().positive()).min(1).optional(),
|
|
28040
|
+
recoveryAction: z124.enum([
|
|
27602
28041
|
"remove",
|
|
27603
28042
|
"replace",
|
|
27604
28043
|
"upload",
|
|
27605
28044
|
"return_to_selection"
|
|
27606
28045
|
]).optional()
|
|
27607
28046
|
}),
|
|
27608
|
-
|
|
27609
|
-
kind:
|
|
27610
|
-
selectedPhotoNumbers:
|
|
28047
|
+
z124.object({
|
|
28048
|
+
kind: z124.literal("product_reference_confirmation"),
|
|
28049
|
+
selectedPhotoNumbers: z124.array(z124.number().int().positive().max(5)).min(1).max(5).optional().describe("Opcional. N\xFAmeros visibles de las fotos que el usuario quiere conservar; las dem\xE1s se deseleccionan. Debe quedar al menos una."),
|
|
27611
28050
|
userChoice: ProductReferenceUserChoiceEnum.optional(),
|
|
27612
|
-
confirmedProductNames:
|
|
28051
|
+
confirmedProductNames: z124.array(z124.string().min(1).max(120)).min(2).max(8).optional(),
|
|
27613
28052
|
videoStructure: VideoStructureEnum.optional().describe("Opcional. Formato para reanudar el video: single_take (Un solo clip, generado completo; puede incluir cambios de plano) o multi_scene (Multiescena). El backend vuelve a validar que sea compatible con el agrupamiento confirmado."),
|
|
27614
28053
|
videoQuality: VideoQualityEnum.optional().describe("Opcional. Calidad para reanudar el video: economy (Econ\xF3mico), medium (Medio) o pro. El proveedor se elige internamente y el backend vuelve a cotizar la ruta."),
|
|
27615
|
-
useMultiSceneShowcase:
|
|
28054
|
+
useMultiSceneShowcase: z124.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
|
|
27616
28055
|
}),
|
|
27617
|
-
|
|
27618
|
-
kind:
|
|
28056
|
+
z124.object({
|
|
28057
|
+
kind: z124.literal("angle_review_approval"),
|
|
27619
28058
|
// All edits are optional — empty action body just approves the
|
|
27620
28059
|
// backend-generated draft as-is. Field shapes mirror the angle-review
|
|
27621
28060
|
// request contracts in @packages/types/wizard.ts; the handler routes to
|
|
27622
28061
|
// the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
|
|
27623
|
-
customAngle:
|
|
28062
|
+
customAngle: z124.string().min(1).max(480).optional(),
|
|
27624
28063
|
// Keep the shared MCP action within the strictest downstream contract:
|
|
27625
28064
|
// autopilot/image resume endpoints cap these fields at 1500 characters.
|
|
27626
|
-
painPoints:
|
|
27627
|
-
benefits:
|
|
28065
|
+
painPoints: z124.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
28066
|
+
benefits: z124.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
27628
28067
|
// Same policy as the two fields above: the strictest downstream contract
|
|
27629
28068
|
// wins. The image endpoint caps each feature at 240 while landing/video
|
|
27630
28069
|
// accept 300, and this single action routes to whichever the task is — so
|
|
27631
28070
|
// accepting 300 here turns a 250-character feature on an image task into
|
|
27632
28071
|
// an opaque HTTP 400 after the model already believed it had been saved.
|
|
27633
|
-
features:
|
|
27634
|
-
buyerPersona:
|
|
28072
|
+
features: z124.array(z124.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
|
|
28073
|
+
buyerPersona: z124.string().min(1).max(360).optional(),
|
|
27635
28074
|
narrativeStyle: PublicNarrativeStyleEnum.optional().describe('Narrativa del video. "problem_product_cta" (Problema y Soluci\xF3n) funciona en ambos formatos \u2014 en Un solo clip abre sin producto y el producto entra por referencia en su beat. La familia storyteller ("animated_storyteller", "animated_inner_journey", "animated_object_soul", "animated_timeline") no est\xE1 disponible por ahora.'),
|
|
27636
|
-
actor:
|
|
27637
|
-
actorId:
|
|
27638
|
-
creativeDirection:
|
|
27639
|
-
selectedAngleNumbers:
|
|
27640
|
-
angleEdits:
|
|
27641
|
-
angleNumber:
|
|
27642
|
-
narrativeSelection:
|
|
28075
|
+
actor: z124.string().min(1).max(360).optional().describe("Nueva descripci\xF3n del presentador. Al enviarla sin actorId, se elimina autom\xE1ticamente cualquier actor guardado previo de esos \xE1ngulos."),
|
|
28076
|
+
actorId: z124.string().max(120).nullable().optional(),
|
|
28077
|
+
creativeDirection: z124.string().max(2e3).optional(),
|
|
28078
|
+
selectedAngleNumbers: z124.array(z124.number().int().positive()).min(1).max(3).optional().describe("N\xFAmeros visibles (1-based) de los \xE1ngulos que el usuario quiere renderizar. Deben ser \xFAnicos, existir en la review y no superar el videoAngleCount autorizado."),
|
|
28079
|
+
angleEdits: z124.array(z124.object({
|
|
28080
|
+
angleNumber: z124.number().int().positive(),
|
|
28081
|
+
narrativeSelection: z124.enum([
|
|
27643
28082
|
"market",
|
|
27644
28083
|
"guided"
|
|
27645
28084
|
]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
|
|
27646
|
-
angle:
|
|
27647
|
-
buyerPersona:
|
|
28085
|
+
angle: z124.string().min(1).max(480).optional(),
|
|
28086
|
+
buyerPersona: z124.string().min(1).max(360).optional(),
|
|
27648
28087
|
narrativeStyle: PublicNarrativeStyleEnum.optional().describe('Narrativa del video. "problem_product_cta" (Problema y Soluci\xF3n) funciona en ambos formatos \u2014 en Un solo clip abre sin producto y el producto entra por referencia en su beat. La familia storyteller ("animated_storyteller", "animated_inner_journey", "animated_object_soul", "animated_timeline") no est\xE1 disponible por ahora.'),
|
|
27649
|
-
actor:
|
|
27650
|
-
actorId:
|
|
27651
|
-
creativeDirection:
|
|
28088
|
+
actor: z124.string().min(1).max(360).optional(),
|
|
28089
|
+
actorId: z124.string().max(120).nullable().optional(),
|
|
28090
|
+
creativeDirection: z124.string().max(2e3).optional()
|
|
27652
28091
|
}).strict()).max(3).optional().describe("Ediciones independientes por n\xFAmero visible de \xE1ngulo. S\xF3lo se aceptan para \xE1ngulos incluidos en selectedAngleNumbers (o en la selecci\xF3n por defecto)."),
|
|
27653
|
-
gapDurationSeconds:
|
|
27654
|
-
|
|
27655
|
-
|
|
28092
|
+
gapDurationSeconds: z124.union([
|
|
28093
|
+
z124.literal(15),
|
|
28094
|
+
z124.literal(30)
|
|
27656
28095
|
]).optional().describe("Opcional. Solo para aceptar expl\xEDcitamente la recomendaci\xF3n gapDurationChoice del status. 30 env\xEDa el override double_30s para el \xE1ngulo recomendado; 15 u omitido conserva la duraci\xF3n cotizada.")
|
|
27657
28096
|
}),
|
|
27658
|
-
|
|
27659
|
-
kind:
|
|
27660
|
-
angleId:
|
|
27661
|
-
angleNumber:
|
|
27662
|
-
content:
|
|
27663
|
-
creativeDirection:
|
|
27664
|
-
actor:
|
|
28097
|
+
z124.object({
|
|
28098
|
+
kind: z124.literal("service_angle_approval"),
|
|
28099
|
+
angleId: z124.string().uuid().optional(),
|
|
28100
|
+
angleNumber: z124.number().int().positive().optional(),
|
|
28101
|
+
content: z124.string().min(1).max(480).optional(),
|
|
28102
|
+
creativeDirection: z124.string().min(1).max(1500).optional(),
|
|
28103
|
+
actor: z124.string().min(1).max(360).optional()
|
|
27665
28104
|
}),
|
|
27666
|
-
|
|
27667
|
-
kind:
|
|
27668
|
-
voiceovers:
|
|
27669
|
-
visualDirections:
|
|
27670
|
-
voiceoversByScene:
|
|
27671
|
-
visualDirectionsByScene:
|
|
28105
|
+
z124.object({
|
|
28106
|
+
kind: z124.literal("service_script_approval"),
|
|
28107
|
+
voiceovers: z124.record(z124.string(), z124.string().min(1).max(600)).optional(),
|
|
28108
|
+
visualDirections: z124.record(z124.string(), z124.string().min(1).max(1200)).optional(),
|
|
28109
|
+
voiceoversByScene: z124.record(z124.string(), z124.string().min(1).max(600)).optional(),
|
|
28110
|
+
visualDirectionsByScene: z124.record(z124.string(), z124.string().min(1).max(1200)).optional()
|
|
27672
28111
|
})
|
|
27673
28112
|
]);
|
|
27674
|
-
var ResolvePendingActionInput =
|
|
27675
|
-
taskId:
|
|
28113
|
+
var ResolvePendingActionInput = z124.object({
|
|
28114
|
+
taskId: z124.string().min(1),
|
|
27676
28115
|
action: PendingActionPayload
|
|
27677
28116
|
}).strict();
|
|
27678
28117
|
function resolveVariantConfirmVideoTier(action) {
|
|
27679
28118
|
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
27680
28119
|
}
|
|
27681
28120
|
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
27682
|
-
var StatusForResolveSchema =
|
|
28121
|
+
var StatusForResolveSchema = z124.object({
|
|
27683
28122
|
// Metadata used to select the backend resume contract. Older API responses
|
|
27684
28123
|
// may omit these fields, so the resolver keeps the generic fallback.
|
|
27685
|
-
kind:
|
|
28124
|
+
kind: z124.enum([
|
|
27686
28125
|
"autopilot",
|
|
27687
28126
|
"video",
|
|
27688
28127
|
"image",
|
|
@@ -27690,18 +28129,18 @@ var StatusForResolveSchema = z123.object({
|
|
|
27690
28129
|
"mix",
|
|
27691
28130
|
"service"
|
|
27692
28131
|
]).optional(),
|
|
27693
|
-
selectedOutputs:
|
|
28132
|
+
selectedOutputs: z124.array(z124.enum([
|
|
27694
28133
|
"landing",
|
|
27695
28134
|
"video",
|
|
27696
28135
|
"image"
|
|
27697
28136
|
])).optional(),
|
|
27698
|
-
videoAngleCount:
|
|
27699
|
-
ugcFormat:
|
|
28137
|
+
videoAngleCount: z124.number().int().min(1).max(3).optional(),
|
|
28138
|
+
ugcFormat: z124.enum([
|
|
27700
28139
|
"single_8s",
|
|
27701
28140
|
"single_15s",
|
|
27702
28141
|
"double_30s"
|
|
27703
28142
|
]).optional(),
|
|
27704
|
-
videoStyle:
|
|
28143
|
+
videoStyle: z124.enum([
|
|
27705
28144
|
"ugc",
|
|
27706
28145
|
"cartoon_3d",
|
|
27707
28146
|
"product_only",
|
|
@@ -27711,13 +28150,13 @@ var StatusForResolveSchema = z123.object({
|
|
|
27711
28150
|
videoQuality: VideoQualityEnum.optional(),
|
|
27712
28151
|
videoRouteId: VideoRouteIdEnum.optional(),
|
|
27713
28152
|
videoModel: TaskVideoModelEnum.optional(),
|
|
27714
|
-
videoTier:
|
|
28153
|
+
videoTier: z124.enum([
|
|
27715
28154
|
"legacy",
|
|
27716
28155
|
"standard",
|
|
27717
28156
|
"pro",
|
|
27718
28157
|
"single_call"
|
|
27719
28158
|
]).optional(),
|
|
27720
|
-
videoResolution:
|
|
28159
|
+
videoResolution: z124.enum([
|
|
27721
28160
|
"480p",
|
|
27722
28161
|
"720p"
|
|
27723
28162
|
]).optional(),
|
|
@@ -27725,60 +28164,60 @@ var StatusForResolveSchema = z123.object({
|
|
|
27725
28164
|
// A task created before a narrative was blocked/hidden must still parse,
|
|
27726
28165
|
// or resolve_pending_action could never approve it.
|
|
27727
28166
|
narrativeStyle: NarrativeStyle.optional(),
|
|
27728
|
-
pauseForVideoScriptReview:
|
|
27729
|
-
pendingUserAction:
|
|
27730
|
-
kind:
|
|
27731
|
-
candidateGrouping:
|
|
27732
|
-
selectedImageUrls:
|
|
27733
|
-
proposedProductNames:
|
|
28167
|
+
pauseForVideoScriptReview: z124.boolean().optional(),
|
|
28168
|
+
pendingUserAction: z124.object({
|
|
28169
|
+
kind: z124.string(),
|
|
28170
|
+
candidateGrouping: z124.string().optional(),
|
|
28171
|
+
selectedImageUrls: z124.array(z124.string()).optional(),
|
|
28172
|
+
proposedProductNames: z124.array(z124.string()).optional(),
|
|
27734
28173
|
// Adaptive reference questions are server-owned. Echo only the evidence
|
|
27735
28174
|
// identity and the choices shown by the current snapshot; never accept a
|
|
27736
28175
|
// client-supplied reference set as authorization.
|
|
27737
|
-
options:
|
|
27738
|
-
mode:
|
|
28176
|
+
options: z124.array(ProductReferenceUserChoiceEnum).max(4).optional(),
|
|
28177
|
+
mode: z124.enum([
|
|
27739
28178
|
"question",
|
|
27740
28179
|
"visual_recovery"
|
|
27741
28180
|
]).optional(),
|
|
27742
28181
|
/** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
|
|
27743
|
-
canKeepSelection:
|
|
27744
|
-
decisionKey:
|
|
27745
|
-
questionOrdinal:
|
|
27746
|
-
questionCeiling:
|
|
27747
|
-
|
|
27748
|
-
|
|
28182
|
+
canKeepSelection: z124.boolean().optional(),
|
|
28183
|
+
decisionKey: z124.string().optional(),
|
|
28184
|
+
questionOrdinal: z124.number().int().min(1).max(5).optional(),
|
|
28185
|
+
questionCeiling: z124.union([
|
|
28186
|
+
z124.literal(3),
|
|
28187
|
+
z124.literal(5)
|
|
27749
28188
|
]).optional(),
|
|
27750
|
-
referenceEvidenceVersion:
|
|
27751
|
-
expectedEvidenceHash:
|
|
27752
|
-
question:
|
|
27753
|
-
prompt:
|
|
27754
|
-
helpText:
|
|
27755
|
-
options:
|
|
28189
|
+
referenceEvidenceVersion: z124.number().int().positive().optional(),
|
|
28190
|
+
expectedEvidenceHash: z124.string().optional(),
|
|
28191
|
+
question: z124.object({
|
|
28192
|
+
prompt: z124.string().min(1).max(240),
|
|
28193
|
+
helpText: z124.string().min(1).max(300).optional(),
|
|
28194
|
+
options: z124.array(z124.object({
|
|
27756
28195
|
value: ProductReferenceUserChoiceEnum,
|
|
27757
|
-
label:
|
|
27758
|
-
description:
|
|
28196
|
+
label: z124.string().min(1).max(120),
|
|
28197
|
+
description: z124.string().min(1).max(240).optional()
|
|
27759
28198
|
})).min(2).max(4)
|
|
27760
28199
|
}).optional(),
|
|
27761
28200
|
scope: ProductReferenceScopeEnum.optional(),
|
|
27762
|
-
scopeKey:
|
|
27763
|
-
scopeSnapshotId:
|
|
27764
|
-
scopeHash:
|
|
27765
|
-
baseReferenceSetHash:
|
|
27766
|
-
phase:
|
|
28201
|
+
scopeKey: z124.string().optional(),
|
|
28202
|
+
scopeSnapshotId: z124.string().uuid().optional(),
|
|
28203
|
+
scopeHash: z124.string().optional(),
|
|
28204
|
+
baseReferenceSetHash: z124.string().optional(),
|
|
28205
|
+
phase: z124.enum([
|
|
27767
28206
|
"preparation",
|
|
27768
28207
|
"final"
|
|
27769
28208
|
]).optional(),
|
|
27770
|
-
selectedRefKeys:
|
|
27771
|
-
allowedDecisions:
|
|
27772
|
-
previews:
|
|
27773
|
-
refKey:
|
|
28209
|
+
selectedRefKeys: z124.array(z124.string().min(1).max(200)).optional(),
|
|
28210
|
+
allowedDecisions: z124.array(ProductReferenceResolutionDecisionEnum).optional(),
|
|
28211
|
+
previews: z124.array(z124.object({
|
|
28212
|
+
refKey: z124.string().min(1).max(200)
|
|
27774
28213
|
}).passthrough()).optional(),
|
|
27775
|
-
customAngleDraft:
|
|
27776
|
-
painPointsDraft:
|
|
27777
|
-
benefitsDraft:
|
|
27778
|
-
featuresDraft:
|
|
27779
|
-
angleOptions:
|
|
27780
|
-
index:
|
|
27781
|
-
angle:
|
|
28214
|
+
customAngleDraft: z124.string().optional(),
|
|
28215
|
+
painPointsDraft: z124.string().optional(),
|
|
28216
|
+
benefitsDraft: z124.string().optional(),
|
|
28217
|
+
featuresDraft: z124.array(z124.string()).optional(),
|
|
28218
|
+
angleOptions: z124.array(z124.object({
|
|
28219
|
+
index: z124.number().int().nonnegative(),
|
|
28220
|
+
angle: z124.string().min(1)
|
|
27782
28221
|
}).passthrough()).min(1).max(5).optional(),
|
|
27783
28222
|
// Recommendation consumed only when the caller explicitly sends
|
|
27784
28223
|
// gapDurationSeconds: 30 in the angle approval action.
|
|
@@ -27788,17 +28227,17 @@ var StatusForResolveSchema = z123.object({
|
|
|
27788
28227
|
// keys. `actorId` (the saved custom actor the picker stored) was silently
|
|
27789
28228
|
// dropped here, so the approval handler below could not echo it back on the
|
|
27790
28229
|
// PATCH — the selection looked accepted and reached no render.
|
|
27791
|
-
angles:
|
|
27792
|
-
id:
|
|
27793
|
-
content:
|
|
27794
|
-
creativeDirection:
|
|
27795
|
-
actor:
|
|
27796
|
-
actorId:
|
|
28230
|
+
angles: z124.array(z124.object({
|
|
28231
|
+
id: z124.string().uuid(),
|
|
28232
|
+
content: z124.string(),
|
|
28233
|
+
creativeDirection: z124.string(),
|
|
28234
|
+
actor: z124.string(),
|
|
28235
|
+
actorId: z124.string().nullable().optional()
|
|
27797
28236
|
}).passthrough()).optional(),
|
|
27798
|
-
panels:
|
|
27799
|
-
beatId:
|
|
27800
|
-
voiceover:
|
|
27801
|
-
visualDirection:
|
|
28237
|
+
panels: z124.array(z124.object({
|
|
28238
|
+
beatId: z124.string(),
|
|
28239
|
+
voiceover: z124.string(),
|
|
28240
|
+
visualDirection: z124.string()
|
|
27802
28241
|
}).passthrough()).optional()
|
|
27803
28242
|
}).optional()
|
|
27804
28243
|
}).passthrough();
|
|
@@ -28151,8 +28590,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
28151
28590
|
server.registerTool("verify_landing_commerce", {
|
|
28152
28591
|
description: getProductMakerCapabilityModelGuidance("verify_landing_commerce").summary + " Verifica una correcci\xF3n manual de precios, tachados o packs de una landing editable existente. Solo relee Shopify y los recibos externos; no cambia precios, inventario, SKU ni compra una edici\xF3n. Pasa taskId y editId de la edici\xF3n ya conocida; nunca inventes IDs ni pidas repetir el cambio. Devuelve el estado can\xF3nico por proveedor: conserva el aviso pendiente hasta confirmar los valores reales. Solo despu\xE9s de confirmar todos los valores, el servidor puede volver a habilitar la compra. Web guardada no demuestra publicaci\xF3n p\xFAblica ni checkout; muestra las correcciones y enlaces pendientes sin c\xF3digos t\xE9cnicos. La disponibilidad del editor conserva sus permisos actuales.",
|
|
28153
28592
|
inputSchema: {
|
|
28154
|
-
taskId:
|
|
28155
|
-
editId:
|
|
28593
|
+
taskId: z124.string().uuid(),
|
|
28594
|
+
editId: z124.string().uuid()
|
|
28156
28595
|
},
|
|
28157
28596
|
annotations: OVERWRITES_EXTERNAL
|
|
28158
28597
|
}, async (input) => {
|
|
@@ -28173,16 +28612,28 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
28173
28612
|
}
|
|
28174
28613
|
});
|
|
28175
28614
|
server.registerTool("get_task_status", {
|
|
28176
|
-
description: `Devuelve estado y outputs. Sigue llam\xE1ndola hasta done/error o una review; un timeout significa que sigue corriendo. Cuando aparece pendingUserAction, la respuesta a\xF1ade Markdown conversacional con el draft y opciones: mu\xE9stralo, pregunta y espera. Usa resolve_pending_action s\xF3lo tras la respuesta del usuario o delegaci\xF3n expl\xEDcita. Nunca expongas IDs, hashes ni payloads t\xE9cnicos. Despu\xE9s de resolver una review, sigue reviewNextAction cuando exista; s\xF3lo vuelve a get_task_status cuando esa transici\xF3n no exista o cuando get_video_script termine en approved/skipped. En un video animado, ${UNTRUSTED_SITE_TEXT_NOTE}`,
|
|
28615
|
+
description: `Devuelve estado y outputs. Sigue llam\xE1ndola hasta done/error o una review; un timeout significa que sigue corriendo. Cuando aparece pendingUserAction, la respuesta a\xF1ade Markdown conversacional con el draft y opciones: mu\xE9stralo, pregunta y espera. Usa resolve_pending_action s\xF3lo tras la respuesta del usuario o delegaci\xF3n expl\xEDcita. Nunca expongas IDs, hashes ni payloads t\xE9cnicos. Despu\xE9s de resolver una review, sigue reviewNextAction cuando exista; s\xF3lo vuelve a get_task_status cuando esa transici\xF3n no exista o cuando get_video_script termine en approved/skipped. Entrega \xFAnicamente los medios originales de ProductMaker en el visor y los bloques de imagen; nunca los sustituyas ni recrees con otra herramienta. En un video animado, ${UNTRUSTED_SITE_TEXT_NOTE}`,
|
|
28177
28616
|
inputSchema: GetTaskStatusInput.shape,
|
|
28178
|
-
annotations: READS_INTERNAL
|
|
28179
|
-
|
|
28617
|
+
annotations: READS_INTERNAL,
|
|
28618
|
+
_meta: taskResultsToolMeta()
|
|
28619
|
+
}, async (input, extra) => observeMcpMediaDelivery(api.fingerprint(), async () => {
|
|
28180
28620
|
try {
|
|
28181
28621
|
const signal = extra?.signal;
|
|
28182
28622
|
const fetcher = /* @__PURE__ */ __name(() => api.getJson(`/v1/status/${encodeURIComponent(input.taskId)}`, {
|
|
28183
28623
|
signal
|
|
28184
28624
|
}), "fetcher");
|
|
28185
28625
|
const snapshot = await pollStatus(fetcher, input.waitSeconds ?? 0, signal);
|
|
28626
|
+
const statusMeta = {
|
|
28627
|
+
taskResults: {
|
|
28628
|
+
state: snapshot.status === "error" ? "error" : [
|
|
28629
|
+
"awaiting_review",
|
|
28630
|
+
"waiting_for_user"
|
|
28631
|
+
].includes(snapshot.status) ? "awaiting_review" : "pending",
|
|
28632
|
+
images: [],
|
|
28633
|
+
videos: [],
|
|
28634
|
+
links: []
|
|
28635
|
+
}
|
|
28636
|
+
};
|
|
28186
28637
|
if (snapshot.status !== "done") {
|
|
28187
28638
|
const review = renderPendingActionMarkdown(snapshot);
|
|
28188
28639
|
if (review) {
|
|
@@ -28201,14 +28652,29 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
28201
28652
|
}) ?? review : review
|
|
28202
28653
|
}
|
|
28203
28654
|
],
|
|
28204
|
-
structuredContent: snapshot
|
|
28655
|
+
structuredContent: snapshot,
|
|
28656
|
+
_meta: {
|
|
28657
|
+
taskResults: {
|
|
28658
|
+
...statusMeta.taskResults,
|
|
28659
|
+
state: "awaiting_review"
|
|
28660
|
+
}
|
|
28661
|
+
}
|
|
28205
28662
|
};
|
|
28206
28663
|
}
|
|
28207
28664
|
if (snapshot.kind === "service") {
|
|
28208
|
-
const
|
|
28209
|
-
if (
|
|
28665
|
+
const rawAnimated = await fetchAnimatedVideoResult(api, input.taskId, signal, "serviceMode" in snapshot ? snapshot.serviceMode : void 0);
|
|
28666
|
+
if (rawAnimated) {
|
|
28667
|
+
const animated = proxifyServiceVideoResult(rawAnimated, proxyBaseUrl);
|
|
28210
28668
|
const continuation2 = buildPollingContinuation(snapshot);
|
|
28669
|
+
const view = buildTaskResultsView(serviceVideoResultMedia(animated), proxyBaseUrl);
|
|
28211
28670
|
return {
|
|
28671
|
+
structuredContent: {
|
|
28672
|
+
...snapshot,
|
|
28673
|
+
animatedVideo: toAgentFacingAnimatedVideo(animated)
|
|
28674
|
+
},
|
|
28675
|
+
_meta: view.state === "ready" ? {
|
|
28676
|
+
taskResults: view
|
|
28677
|
+
} : statusMeta,
|
|
28212
28678
|
content: [
|
|
28213
28679
|
{
|
|
28214
28680
|
type: "text",
|
|
@@ -28237,6 +28703,7 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
28237
28703
|
const continuation = buildPollingContinuation(snapshot);
|
|
28238
28704
|
if (continuation) {
|
|
28239
28705
|
return {
|
|
28706
|
+
_meta: statusMeta,
|
|
28240
28707
|
content: [
|
|
28241
28708
|
{
|
|
28242
28709
|
type: "text",
|
|
@@ -28252,15 +28719,26 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
28252
28719
|
]
|
|
28253
28720
|
};
|
|
28254
28721
|
}
|
|
28255
|
-
return
|
|
28722
|
+
return {
|
|
28723
|
+
...asText(snapshot),
|
|
28724
|
+
_meta: statusMeta
|
|
28725
|
+
};
|
|
28256
28726
|
}
|
|
28257
28727
|
if (snapshot.kind === "service") {
|
|
28258
|
-
const
|
|
28728
|
+
const rawResult = await api.getJson(`/v1/tasks/${encodeURIComponent(input.taskId)}/service-result`, {
|
|
28259
28729
|
signal
|
|
28260
28730
|
});
|
|
28731
|
+
const result = proxifyServiceVideoResult(rawResult, proxyBaseUrl);
|
|
28261
28732
|
const animated = parseAnimatedVideoResult(result);
|
|
28262
28733
|
if (animated) {
|
|
28263
28734
|
return {
|
|
28735
|
+
structuredContent: {
|
|
28736
|
+
...snapshot,
|
|
28737
|
+
result: toAgentFacingAnimatedVideo(animated)
|
|
28738
|
+
},
|
|
28739
|
+
_meta: {
|
|
28740
|
+
taskResults: buildTaskResultsView(serviceVideoResultMedia(animated), proxyBaseUrl)
|
|
28741
|
+
},
|
|
28264
28742
|
content: [
|
|
28265
28743
|
{
|
|
28266
28744
|
type: "text",
|
|
@@ -28277,6 +28755,13 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
28277
28755
|
};
|
|
28278
28756
|
}
|
|
28279
28757
|
return {
|
|
28758
|
+
structuredContent: {
|
|
28759
|
+
...snapshot,
|
|
28760
|
+
result
|
|
28761
|
+
},
|
|
28762
|
+
_meta: {
|
|
28763
|
+
taskResults: buildTaskResultsView(serviceVideoResultMedia(result), proxyBaseUrl)
|
|
28764
|
+
},
|
|
28280
28765
|
content: [
|
|
28281
28766
|
{
|
|
28282
28767
|
type: "text",
|
|
@@ -28298,13 +28783,39 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
28298
28783
|
const rawOutputs = await fetchTaskOutputs(api, input.taskId, {
|
|
28299
28784
|
signal
|
|
28300
28785
|
});
|
|
28301
|
-
const
|
|
28302
|
-
|
|
28303
|
-
|
|
28304
|
-
|
|
28305
|
-
}, transport)).filter((block) => block.type === "image") : [];
|
|
28786
|
+
const imageContent = await buildMcpGeneratedImageContent(rawOutputs.images.map((image, i) => ({
|
|
28787
|
+
url: image.url,
|
|
28788
|
+
alt: `Imagen ${i + 1}`
|
|
28789
|
+
})), transport);
|
|
28306
28790
|
const outputs = proxifyOutputs(rawOutputs, proxyBaseUrl);
|
|
28791
|
+
const media = {
|
|
28792
|
+
images: [
|
|
28793
|
+
...outputs.images.map((image, i) => ({
|
|
28794
|
+
url: image.url,
|
|
28795
|
+
alt: `Imagen ${i + 1}`
|
|
28796
|
+
})),
|
|
28797
|
+
...outputs.landing.sections.map((section) => ({
|
|
28798
|
+
url: section.url,
|
|
28799
|
+
alt: section.role
|
|
28800
|
+
}))
|
|
28801
|
+
],
|
|
28802
|
+
videos: outputs.videos.flatMap((video) => video.variants.map((variant) => ({
|
|
28803
|
+
url: variant.url,
|
|
28804
|
+
label: `${video.angleKey} \xB7 ${variant.kind}`,
|
|
28805
|
+
...video.scriptRewritten ? {
|
|
28806
|
+
scriptRewritten: true
|
|
28807
|
+
} : {}
|
|
28808
|
+
}))),
|
|
28809
|
+
links: []
|
|
28810
|
+
};
|
|
28307
28811
|
return {
|
|
28812
|
+
structuredContent: {
|
|
28813
|
+
...snapshot,
|
|
28814
|
+
outputs
|
|
28815
|
+
},
|
|
28816
|
+
_meta: {
|
|
28817
|
+
taskResults: buildTaskResultsView(media, proxyBaseUrl)
|
|
28818
|
+
},
|
|
28308
28819
|
content: [
|
|
28309
28820
|
{
|
|
28310
28821
|
type: "text",
|
|
@@ -28325,12 +28836,20 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
28325
28836
|
const detail = err instanceof Error ? err.stack ?? err.message : String(err);
|
|
28326
28837
|
process.stderr.write(`mcp get_task_status: fetchTaskOutputs failed for ${input.taskId}: ${detail}
|
|
28327
28838
|
`);
|
|
28328
|
-
return
|
|
28839
|
+
return {
|
|
28840
|
+
...asText(snapshot),
|
|
28841
|
+
_meta: {
|
|
28842
|
+
taskResults: {
|
|
28843
|
+
...statusMeta.taskResults,
|
|
28844
|
+
state: "error"
|
|
28845
|
+
}
|
|
28846
|
+
}
|
|
28847
|
+
};
|
|
28329
28848
|
}
|
|
28330
28849
|
} catch (e) {
|
|
28331
28850
|
throw translateError(e);
|
|
28332
28851
|
}
|
|
28333
|
-
});
|
|
28852
|
+
}));
|
|
28334
28853
|
server.registerTool("list_tasks", {
|
|
28335
28854
|
description: listTasksGuidance.summary + " \xDAsala para encontrar una tarea previa por nombre o revisar el historial antes de pedir un taskId. Soporta paginaci\xF3n con limit/offset y filtro de texto. No crea, reanuda ni modifica tareas.",
|
|
28336
28855
|
inputSchema: ListTasksInput.shape,
|
|
@@ -28343,16 +28862,16 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
28343
28862
|
if (input.search) qs.set("search", input.search);
|
|
28344
28863
|
const path3 = `/v1/tasks${qs.toString() ? "?" + qs.toString() : ""}`;
|
|
28345
28864
|
const r = await api.getJson(path3);
|
|
28346
|
-
const page =
|
|
28347
|
-
items:
|
|
28865
|
+
const page = z124.object({
|
|
28866
|
+
items: z124.array(z124.unknown())
|
|
28348
28867
|
}).passthrough().safeParse(r);
|
|
28349
28868
|
if (!page.success) return asText(r);
|
|
28350
28869
|
return asText({
|
|
28351
28870
|
...page.data,
|
|
28352
28871
|
items: page.data.items.map((item) => {
|
|
28353
|
-
const servicePage =
|
|
28354
|
-
taskId:
|
|
28355
|
-
resourceType:
|
|
28872
|
+
const servicePage = z124.object({
|
|
28873
|
+
taskId: z124.string().uuid(),
|
|
28874
|
+
resourceType: z124.literal("service_page")
|
|
28356
28875
|
}).passthrough().safeParse(item);
|
|
28357
28876
|
if (!servicePage.success) return item;
|
|
28358
28877
|
return {
|
|
@@ -28842,28 +29361,28 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
28842
29361
|
__name(registerTaskTools, "registerTaskTools");
|
|
28843
29362
|
|
|
28844
29363
|
// src/tools/brands.ts
|
|
28845
|
-
import { z as
|
|
29364
|
+
import { z as z125 } from "zod";
|
|
28846
29365
|
var guidance2 = getProductMakerCapabilityModelGuidance("create_brand");
|
|
28847
29366
|
var BRAND_START_REPLAY_WINDOW_MS = 15 * 60 * 1e3;
|
|
28848
29367
|
var BRAND_NOTES_MAX_CHARS = 2e4;
|
|
28849
29368
|
var BRAND_AMBIGUOUS_REQUEST_RETENTION_MS = 24 * 60 * 60 * 1e3;
|
|
28850
29369
|
var BRAND_CREATION_REQUEST_LIMIT = 500;
|
|
28851
29370
|
var brandCreationRequests = /* @__PURE__ */ new Map();
|
|
28852
|
-
var CreateBrandInput =
|
|
28853
|
-
action:
|
|
29371
|
+
var CreateBrandInput = z125.object({
|
|
29372
|
+
action: z125.enum([
|
|
28854
29373
|
"start",
|
|
28855
29374
|
"status",
|
|
28856
29375
|
"list"
|
|
28857
29376
|
]).default("start").describe("start cotiza (sin confirmed) o inicia (confirmed=true) el an\xE1lisis; status consulta brandId hasta ready o failed; list muestra las marcas que el usuario ya tiene."),
|
|
28858
|
-
sourceUrl:
|
|
28859
|
-
businessNotes:
|
|
28860
|
-
language:
|
|
29377
|
+
sourceUrl: z125.string().trim().min(1).max(BRAND_SOURCE_URL_MAX_LENGTH).optional().describe("Instagram, Facebook, TikTok o web p\xFAblica del negocio, como la dio el usuario (\xAB@sanlucasbarberia\xBB, \xABinstagram.com/sanlucasbarberia\xBB, \xABmibarberia.com\xBB). Obligatorio para start."),
|
|
29378
|
+
businessNotes: z125.string().trim().max(BRAND_NOTES_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cuente de su negocio en el chat (servicios y precios, WhatsApp, ciudad o zona, horarios). Se guarda como documento del negocio y llega tal cual a la marca y a su landing. Copia sus palabras; no inventes datos."),
|
|
29379
|
+
language: z125.enum([
|
|
28861
29380
|
"es",
|
|
28862
29381
|
"en",
|
|
28863
29382
|
"pt"
|
|
28864
29383
|
]).optional().describe("Idioma de la conversaci\xF3n. Solo se usa si la p\xE1gina del negocio no deja claro su idioma."),
|
|
28865
|
-
confirmed:
|
|
28866
|
-
brandId:
|
|
29384
|
+
confirmed: z125.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, start solo cotiza y no cobra."),
|
|
29385
|
+
brandId: z125.string().uuid().optional().describe("ID de la marca. Obligatorio para status; no lo inventes.")
|
|
28867
29386
|
}).strict();
|
|
28868
29387
|
function normalizeBrandSourceUrl(raw) {
|
|
28869
29388
|
const value = raw.trim();
|
|
@@ -29147,24 +29666,24 @@ __name(registerBrandTools, "registerBrandTools");
|
|
|
29147
29666
|
|
|
29148
29667
|
// src/tools/service-landing.ts
|
|
29149
29668
|
import { createHash as createHash3, randomUUID } from "crypto";
|
|
29150
|
-
import { z as
|
|
29669
|
+
import { z as z126 } from "zod";
|
|
29151
29670
|
var guidance3 = getProductMakerCapabilityModelGuidance("create_service_landing");
|
|
29152
29671
|
var SERVICE_LANDING_KEY_NAMESPACE = "6f1d8c2a-3b4e-5f60-8a7b-9c0d1e2f3a4b";
|
|
29153
29672
|
var SERVICE_LANDING_INFO_MAX_CHARS = 2e4;
|
|
29154
|
-
var CreateServiceLandingInput =
|
|
29155
|
-
action:
|
|
29673
|
+
var CreateServiceLandingInput = z126.object({
|
|
29674
|
+
action: z126.enum([
|
|
29156
29675
|
"prepare",
|
|
29157
29676
|
"build",
|
|
29158
29677
|
"status",
|
|
29159
29678
|
"publish"
|
|
29160
29679
|
]).default("prepare").describe("prepare (gratis) crea o retoma la landing de la marca y da el precio; build (pagado, confirmed=true) genera la p\xE1gina directamente con la marca y los datos guardados; status sigue el avance; publish la publica y devuelve su enlace."),
|
|
29161
|
-
brandId:
|
|
29162
|
-
servicePageId:
|
|
29163
|
-
businessInfo:
|
|
29164
|
-
confirmed:
|
|
29165
|
-
maxCredits:
|
|
29166
|
-
operationId:
|
|
29167
|
-
slug:
|
|
29680
|
+
brandId: z126.string().uuid().optional().describe("ID de la marca (de create_brand). Obligatorio para prepare. Nunca un taskId de producto."),
|
|
29681
|
+
servicePageId: z126.string().uuid().optional().describe("ID de la landing que devolvi\xF3 prepare. Obligatorio para build, status y publish."),
|
|
29682
|
+
businessInfo: z126.string().trim().max(SERVICE_LANDING_INFO_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cont\xF3 del negocio y no estaba en su marca: servicios y precios, WhatsApp o tel\xE9fono, ciudad o zona, horarios. Copia sus palabras; no inventes datos."),
|
|
29683
|
+
confirmed: z126.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio total y que el usuario acepte. Obligatorio para build."),
|
|
29684
|
+
maxCredits: z126.number().int().positive().optional().describe("El total en cr\xE9ditos que el usuario acept\xF3 (el que devolvi\xF3 prepare). Obligatorio para build: ninguna etapa se inicia si su precio supera este total."),
|
|
29685
|
+
operationId: z126.string().uuid().optional().describe("Opcional en status: la operaci\xF3n que devolvi\xF3 build."),
|
|
29686
|
+
slug: z126.string().trim().toLowerCase().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(64).optional().describe("Opcional en publish: la direcci\xF3n corta de la p\xE1gina (ej. sanlucas-barberia). Si falta se usa la sugerida desde el nombre del negocio.")
|
|
29168
29687
|
}).strict();
|
|
29169
29688
|
function serviceKey(...parts) {
|
|
29170
29689
|
return deriveUuidV5(parts.join(":"), SERVICE_LANDING_KEY_NAMESPACE);
|
|
@@ -29397,7 +29916,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
29397
29916
|
const build = quoteRange(generationQuote);
|
|
29398
29917
|
const totalMin = build.min;
|
|
29399
29918
|
const totalCredits = build.max;
|
|
29400
|
-
const requiredBalanceCredits =
|
|
29919
|
+
const requiredBalanceCredits = totalCredits;
|
|
29401
29920
|
const askFor = page2.facts.contact.channels.some((channel) => channel.kind === "whatsapp") ? "su ciudad o zona y sus servicios con precio (su WhatsApp ya viene de la marca: no lo pidas)" : "su WhatsApp o tel\xE9fono, su ciudad o zona y sus servicios con precio";
|
|
29402
29921
|
const priceText = totalMin === totalCredits ? `${totalCredits} cr\xE9ditos` : `entre ${totalMin} y ${totalCredits} cr\xE9ditos`;
|
|
29403
29922
|
return asText({
|
|
@@ -29414,7 +29933,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
29414
29933
|
totalCredits,
|
|
29415
29934
|
requiredBalanceCredits
|
|
29416
29935
|
},
|
|
29417
|
-
nextAction: `En un solo mensaje: dile al usuario que crear su landing cuesta ${priceText} en total (se cobra lo que se use; necesita al menos ${requiredBalanceCredits} cr\xE9ditos de saldo para empezar) y preg\xFAntale, solo si no lo dijo ya en esta conversaci\xF3n, ${askFor} (puede omitirlo). Cuando acepte el precio, llama action=build con servicePageId=${page2.id}, confirmed=true, maxCredits=${totalCredits} y businessInfo con lo que respondi\xF3.`
|
|
29936
|
+
nextAction: `En un solo mensaje: dile al usuario que crear su landing cuesta ${priceText} en total (se cobra lo que se use; necesita al menos ${requiredBalanceCredits} cr\xE9ditos de saldo para empezar) y preg\xFAntale, solo si no lo dijo ya en esta conversaci\xF3n, ${askFor} (puede omitirlo). prepare no consulta el saldo: no interpretes un saldo desconocido como insuficiente ni exijas una comprobaci\xF3n manual. Cuando acepte el precio, llama action=build con servicePageId=${page2.id}, confirmed=true, maxCredits=${totalCredits} y businessInfo con lo que respondi\xF3; comunica cualquier rechazo que devuelva el servidor.`
|
|
29418
29937
|
});
|
|
29419
29938
|
}
|
|
29420
29939
|
if (!input.servicePageId) {
|
|
@@ -29539,7 +30058,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
29539
30058
|
__name(registerServiceLandingTools, "registerServiceLandingTools");
|
|
29540
30059
|
|
|
29541
30060
|
// src/tools/service-images.ts
|
|
29542
|
-
import { z as
|
|
30061
|
+
import { z as z127 } from "zod";
|
|
29543
30062
|
var guidance4 = getProductMakerCapabilityModelGuidance("create_service_images");
|
|
29544
30063
|
var SERVICE_IMAGE_FORMATS = [
|
|
29545
30064
|
"4:5",
|
|
@@ -29552,23 +30071,23 @@ var LANGUAGE_TAGS = {
|
|
|
29552
30071
|
en: "en-US",
|
|
29553
30072
|
pt: "pt-BR"
|
|
29554
30073
|
};
|
|
29555
|
-
var CreateServiceImagesInput =
|
|
29556
|
-
brandId:
|
|
29557
|
-
instruction:
|
|
29558
|
-
delegateToAi:
|
|
29559
|
-
format:
|
|
29560
|
-
count:
|
|
29561
|
-
quality:
|
|
30074
|
+
var CreateServiceImagesInput = z127.object({
|
|
30075
|
+
brandId: z127.string().uuid().optional().describe("ID de un servicio propio y listo (de create_brand), obligatorio para cotizar y crear im\xE1genes nuevas. En un retry hist\xF3rico ya confirmado que originalmente no ten\xEDa este campo, conserva la petici\xF3n original. Nunca un taskId de producto."),
|
|
30076
|
+
instruction: z127.string().trim().max(4e3).optional().describe("Opcional. Qu\xE9 servicio o promoci\xF3n mostrar, con las palabras del usuario (ej. \xABcorte + barba a $35.000 los martes\xBB). Si se omite, la IA propone la imagen usando la informaci\xF3n del servicio."),
|
|
30077
|
+
delegateToAi: z127.boolean().optional().describe("true si el usuario prefiere que la IA elija qu\xE9 mostrar a partir de su servicio. Tambi\xE9n se delega cuando instruction est\xE1 vac\xEDo."),
|
|
30078
|
+
format: z127.enum(SERVICE_IMAGE_FORMATS).optional().describe('Formato: "4:5" (feed, por defecto), "9:16" (historias/reels) o "1:1" (cuadrado).'),
|
|
30079
|
+
count: z127.number().int().min(1).max(SERVICE_IMAGE_MAX_COUNT).optional().describe("Cu\xE1ntas im\xE1genes, de 1 a 3 (por defecto 1)."),
|
|
30080
|
+
quality: z127.enum([
|
|
29562
30081
|
"standard",
|
|
29563
30082
|
"high"
|
|
29564
30083
|
]).optional().describe('Calidad: "standard" (por defecto) o "high" (m\xE1s cara; no disponible en 4:5).'),
|
|
29565
|
-
language:
|
|
30084
|
+
language: z127.enum([
|
|
29566
30085
|
"es",
|
|
29567
30086
|
"en",
|
|
29568
30087
|
"pt"
|
|
29569
30088
|
]).optional().describe("Idioma de los textos de la imagen (por defecto es)."),
|
|
29570
|
-
adCopy:
|
|
29571
|
-
confirmed:
|
|
30089
|
+
adCopy: z127.boolean().optional().describe("Compatibilidad con clientes anteriores: el copy para publicar siempre est\xE1 incluido en cada imagen de servicios."),
|
|
30090
|
+
confirmed: z127.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, solo cotiza y no cobra.")
|
|
29572
30091
|
}).strict();
|
|
29573
30092
|
function serviceImageModel(quality) {
|
|
29574
30093
|
return quality === "high" ? AD_CREATIVE_MODELS.PREMIUM : AD_CREATIVE_MODELS.STANDARD;
|
|
@@ -29682,10 +30201,10 @@ function registerServiceImageTools(server, api, options = {}) {
|
|
|
29682
30201
|
...priceCredits ? {
|
|
29683
30202
|
priceCredits
|
|
29684
30203
|
} : {},
|
|
29685
|
-
nextAction: "Dile al usuario que est\xE1s creando sus im\xE1genes. Llama get_task_status con este taskId (waitSeconds=45) hasta done (trae las im\xE1genes) o error."
|
|
30204
|
+
nextAction: "Dile al usuario que est\xE1s creando sus im\xE1genes. Llama get_task_status con este taskId (waitSeconds=45) hasta done (trae las im\xE1genes reales de ProductMaker) o error. Muestra los recursos de imagen devueltos directamente en el chat. Nunca generes ni recrees una imagen sustituta con otra herramienta. Si la vista previa falla, explica el fallo y conserva los enlaces protegidos devueltos."
|
|
29686
30205
|
});
|
|
29687
30206
|
} catch (error) {
|
|
29688
|
-
if (error instanceof
|
|
30207
|
+
if (error instanceof z127.ZodError) throw invalidInputFromZod(error);
|
|
29689
30208
|
throw translateError(error);
|
|
29690
30209
|
}
|
|
29691
30210
|
});
|
|
@@ -29693,7 +30212,7 @@ function registerServiceImageTools(server, api, options = {}) {
|
|
|
29693
30212
|
__name(registerServiceImageTools, "registerServiceImageTools");
|
|
29694
30213
|
|
|
29695
30214
|
// src/tools/creatives.ts
|
|
29696
|
-
import { z as
|
|
30215
|
+
import { z as z128 } from "zod";
|
|
29697
30216
|
var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
|
|
29698
30217
|
var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
|
|
29699
30218
|
var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
|
|
@@ -29704,72 +30223,72 @@ var CreativeRefs = {
|
|
|
29704
30223
|
images: ImagesInput,
|
|
29705
30224
|
language: Lang.describe('Idioma del contenido. Ej. "es", "en", "pt". REQUERIDO \u2014 si el usuario no lo dijo, PREG\xDANTALE antes de invocar. NUNCA infieras desde el contexto del chat ni asumas un default.'),
|
|
29706
30225
|
country: Country.describe('Pa\xEDs objetivo ISO. Ej. "CO", "MX", "US", "AR". Define moneda, m\xE9todos de pago y tono. REQUERIDO \u2014 si el usuario no lo dijo, PREG\xDANTALE antes de invocar. NUNCA infieras desde el contexto del chat ni asumas un default.'),
|
|
29707
|
-
price:
|
|
29708
|
-
offer:
|
|
29709
|
-
compareAtPrice:
|
|
29710
|
-
productContext:
|
|
29711
|
-
productLabel:
|
|
29712
|
-
buyerPersona:
|
|
29713
|
-
isCombo:
|
|
29714
|
-
competitorScanEnabled:
|
|
29715
|
-
brandId:
|
|
30226
|
+
price: z128.string().min(1).max(120).optional().describe('Precio en formato libre \u2014 ej. "$89.900", "USD 29.99". Opcional pero MUY IMPACTANTE para conversi\xF3n: si el usuario no lo mencion\xF3, PREG\xDANTALE antes de invocar. Si el usuario te dice "t\xFA elige", omite el campo y la IA del backend sugiere uno.'),
|
|
30227
|
+
offer: z128.string().min(1).max(240).optional().describe('Oferta a destacar \u2014 ej. "2x1", "Env\xEDo gratis", "50% OFF". Opcional pero MUY IMPACTANTE: si el usuario no lo mencion\xF3, PREG\xDANTALE antes de invocar (es v\xE1lido que diga "sin oferta"). Si el usuario te dice "t\xFA elige", omite el campo.'),
|
|
30228
|
+
compareAtPrice: z128.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
|
|
30229
|
+
productContext: z128.string().max(3e3).optional().describe("Opcional. Informacion adicional del producto que la IA debe usar como contexto prioritario: uso real, comprador, restricciones, diferenciadores o direccion creativa. No reemplaza la investigacion de competencia; si hay competencia, guia el primer angulo y los outputs no deben contradecirlo."),
|
|
30230
|
+
productLabel: z128.string().trim().max(80).optional().describe('Opcional. Nombre o tipo del producto en pocas palabras (ej. "collar de oro", "quita pelusas para ropa"). Es AUTORITATIVO: la IA usa esta identidad y no la reemplaza por otra categor\xEDa. Si lo omites, la IA lo detecta desde la imagen. NO salta la extracci\xF3n.'),
|
|
30231
|
+
buyerPersona: z128.string().optional().describe('Opcional. Descripci\xF3n del comprador objetivo. Ej. "Mujeres 35-50, profesionales urbanas". Si se omite, la IA infiere desde el \xE1ngulo y producto.'),
|
|
30232
|
+
isCombo: z128.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
|
|
30233
|
+
competitorScanEnabled: z128.boolean().optional().describe("Opcional. Default false: omitirlo significa SIN estudio de mercado. Antes de crear, llama estimate_market_study_cost, muestra al usuario el costo con y sin estudio y preg\xFAntale si lo quiere; env\xEDa true solo si lo acepta (o si solicita la narrativa an\xE1lisis de mercado). En video, true analiza anuncios de la competencia y desbloquea la narrativa an\xE1lisis de mercado; si el estudio no encuentra datos suficientes, degrada al planner cl\xE1sico."),
|
|
30234
|
+
brandId: z128.string().uuid().optional().describe("Opcional. ID de una marca del usuario; si se env\xEDa, el sistema usa su voz, colores y persona para enriquecer el creativo.")
|
|
29716
30235
|
};
|
|
29717
|
-
var VideoPresenter =
|
|
29718
|
-
|
|
29719
|
-
mode:
|
|
30236
|
+
var VideoPresenter = z128.discriminatedUnion("mode", [
|
|
30237
|
+
z128.object({
|
|
30238
|
+
mode: z128.literal("none")
|
|
29720
30239
|
}).strict(),
|
|
29721
|
-
|
|
29722
|
-
mode:
|
|
29723
|
-
actorId:
|
|
30240
|
+
z128.object({
|
|
30241
|
+
mode: z128.literal("saved_actor"),
|
|
30242
|
+
actorId: z128.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
|
|
29724
30243
|
}).strict(),
|
|
29725
|
-
|
|
29726
|
-
mode:
|
|
29727
|
-
description:
|
|
30244
|
+
z128.object({
|
|
30245
|
+
mode: z128.literal("described"),
|
|
30246
|
+
description: z128.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
|
|
29728
30247
|
}).strict()
|
|
29729
30248
|
]);
|
|
29730
|
-
var VideoCreativeSetup =
|
|
29731
|
-
|
|
29732
|
-
mode:
|
|
30249
|
+
var VideoCreativeSetup = z128.discriminatedUnion("mode", [
|
|
30250
|
+
z128.object({
|
|
30251
|
+
mode: z128.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
|
|
29733
30252
|
}).strict(),
|
|
29734
|
-
|
|
29735
|
-
mode:
|
|
30253
|
+
z128.object({
|
|
30254
|
+
mode: z128.literal("guided"),
|
|
29736
30255
|
videoPreset: VideoPresetEnum.default("auto").describe('Narrativa opcional. Con estudio de mercado no la preguntes: se usa "auto" y el estudio define la estructura. Sin estudio conserva la elecci\xF3n del usuario. Todas las narrativas funcionan en Un solo clip y Multiescena.'),
|
|
29737
|
-
buyerPersona:
|
|
30256
|
+
buyerPersona: z128.string().trim().min(1).max(360),
|
|
29738
30257
|
animationStyle: AnimationStyleEnum.optional().describe('Opcional. Estilo visual SOLO para presets animados ("pixar_problem" o "pixar_sassy") \u2014 la API lo rechaza con cualquier otro preset. Opciones: "pixar_3d" (default, look 3D de pel\xEDcula animada), "claymation" (plastilina stop-motion artesanal), "wes_anderson" (tableau sim\xE9trico pastel), "sci_fi" (futurista con HUDs y ne\xF3n), "realista" (fotorrealista, fiel al producto). Si el usuario pide un look animado sin nombrar el estilo, omite el campo.'),
|
|
29739
30258
|
presenter: VideoPresenter,
|
|
29740
|
-
creativeDirection:
|
|
30259
|
+
creativeDirection: z128.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
|
|
29741
30260
|
}).strict()
|
|
29742
30261
|
]);
|
|
29743
|
-
var VideoInput =
|
|
30262
|
+
var VideoInput = z128.object({
|
|
29744
30263
|
images: CreativeRefs.images.optional(),
|
|
29745
30264
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
29746
|
-
title:
|
|
29747
|
-
primaryAngle:
|
|
30265
|
+
title: z128.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
|
|
30266
|
+
primaryAngle: z128.string().min(1).describe('\xC1ngulo de venta principal (frase del beneficio). Ej. "Reduce arrugas en 14 d\xEDas" o "Para quienes odian las cremas grasosas".'),
|
|
29748
30267
|
language: CreativeRefs.language,
|
|
29749
30268
|
country: CreativeRefs.country,
|
|
29750
|
-
aspectRatio:
|
|
30269
|
+
aspectRatio: z128.enum([
|
|
29751
30270
|
"9:16",
|
|
29752
30271
|
"16:9",
|
|
29753
30272
|
"Auto"
|
|
29754
30273
|
]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
|
|
29755
30274
|
generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, efectos y m\xFAsica sobre cada video entregado (variante with_ai_edit; se cobra al entregar, por video). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro"; false/omitido = sin edici\xF3n.'),
|
|
29756
|
-
durationSeconds:
|
|
29757
|
-
videoAngleCount:
|
|
30275
|
+
durationSeconds: z128.number().int().min(4).max(30).default(15).describe("Opcional. Duraci\xF3n objetivo: Un solo clip Econ\xF3mico o Medio usa 15s; Un solo clip Pro usa 15s o 30s; Multiescena usa 15s o 30s totales. La combinaci\xF3n de formato y calidad determina la ruta y el costo."),
|
|
30276
|
+
videoAngleCount: z128.number().int().min(1).max(3).describe("Cantidad de videos a renderizar: 1, 2 o 3. Es una decisi\xF3n de costo obligatoria: preg\xFAntala incluso cuando creativeSetup.mode=automatic."),
|
|
29758
30277
|
angleNarratives: PublicNarrativeStyleEnum.array().max(3).optional().describe('Opcional. Narrativa POR \xC1NGULO (posicional). Valores actuales: "review", "ugc_how_to", "ugc_unboxing_chaos", "problem_product_cta" (problema concreto, producto como soluci\xF3n y CTA), "product_showcase", "wearable_showcase", "cinematic", "wild_card", "animated_problem_pixar", "sassy_product_pixar", "market" (narrativa an\xE1lisis de mercado: adapta el video a los patrones ganadores estudiados de la competencia; requiere competitorScanEnabled: true). angleNarratives[i] fuerza la narrativa del \xE1ngulo i; las posiciones restantes las elige la IA. La lista no puede superar videoAngleCount.'),
|
|
29759
30278
|
creativeSetup: VideoCreativeSetup.describe("Configuraci\xF3n creativa obligatoria. En guided pregunta narrativa, p\xFAblico, presentador y direcci\xF3n antes de confirmar. Usa automatic s\xF3lo si el usuario deleg\xF3 todo expl\xEDcitamente."),
|
|
29760
30279
|
videoStructure: VideoStructureEnum.default("single_take").describe('Opcional. Formato: "single_take" = Un solo clip (generado completo; puede incluir cambios de plano) o "multi_scene" = Multiescena (varias tomas concatenadas). Default: single_take.'),
|
|
29761
30280
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
|
|
29762
30281
|
videoResolution: VideoResolutionEnum.optional().describe('Opcional. Resoluci\xF3n del render: "480p" o "720p". Si se omite, se usa 480p; elige 720p expl\xEDcitamente si necesitas m\xE1s nitidez.'),
|
|
29763
|
-
features:
|
|
30282
|
+
features: z128.array(z128.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
|
|
29764
30283
|
price: CreativeRefs.price,
|
|
29765
30284
|
offer: CreativeRefs.offer,
|
|
29766
30285
|
productContext: CreativeRefs.productContext,
|
|
29767
30286
|
productLabel: CreativeRefs.productLabel,
|
|
29768
|
-
cta:
|
|
29769
|
-
scriptNotes:
|
|
30287
|
+
cta: z128.string().optional().describe('Opcional. Call-to-action final del video. Ej. "Compra ahora", "Pide el tuyo hoy", "Link en bio". Si se omite, la IA escribe uno.'),
|
|
30288
|
+
scriptNotes: z128.string().optional().describe('Opcional. Notas/restricciones para el guion (la IA las usa al redactar). Ej. "No mencionar la marca X", "Tono divertido, no cl\xEDnico", "Mencionar 2x1". NO es el guion literal: creativeSetup.mode=guided activa siempre la revisi\xF3n palabra-por-palabra con get_video_script / approve_video_script.'),
|
|
29770
30289
|
creativeGender: CreativeGenderEnum.optional().describe('Opcional. QUI\xC9N APARECE EN PANTALLA en el video: mujer ("female"), hombre ("male") o ambos ("mixed"). NO es la voz; cuando se fija, la voz se alinea sola con el personaje. M\xE1ndalo en cuanto el usuario diga qui\xE9n debe SALIR en el video, con cualquier redacci\xF3n ("quiero una mujer", "que salga un hombre", "protagonista femenina"): si no lo mandas, el g\xE9nero lo inventa la IA y el usuario puede recibir lo contrario de lo que pidi\xF3 sin ning\xFAn aviso. NO lo mandes cuando hable del P\xDABLICO COMPRADOR ("esto es para hombres", "mi p\xFAblico son mujeres", "va dirigido a mam\xE1s"): eso es a qui\xE9n se le vende, no qui\xE9n act\xFAa, y fijarlo ah\xED pinea un protagonista que nadie pidi\xF3. "mixed" solo cuando pida expl\xEDcitamente ambos, y ten en cuenta que no garantiza una mezcla: no fija ning\xFAn g\xE9nero y cada creativo elige su protagonista. No lo preguntes como paso obligatorio. Si creativeSetup.presenter.mode="saved_actor", el personaje guardado manda sobre este campo.'),
|
|
29771
30290
|
competitorScanEnabled: CreativeRefs.competitorScanEnabled,
|
|
29772
|
-
replicateWinnerWhenFound:
|
|
30291
|
+
replicateWinnerWhenFound: z128.boolean().optional().describe("Conserva la preferencia de copiar un ganador si existe. false permite estudiar el mercado sin reemplazar un \xE1ngulo por el anuncio ganador. No a\xF1adas una pregunta obligatoria para este campo."),
|
|
29773
30292
|
brandId: CreativeRefs.brandId
|
|
29774
30293
|
}).strict();
|
|
29775
30294
|
var FreeVideoQualityEnum = VideoQualityEnum;
|
|
@@ -29787,7 +30306,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
|
|
|
29787
30306
|
length: 29
|
|
29788
30307
|
}, (_, index) => index + 2)
|
|
29789
30308
|
};
|
|
29790
|
-
var FreeVideoModelIdEnum =
|
|
30309
|
+
var FreeVideoModelIdEnum = z128.enum([
|
|
29791
30310
|
"grok-imagine-video-1-5-preview",
|
|
29792
30311
|
"minimax-h3/reference-to-video",
|
|
29793
30312
|
"wan/3-0-video",
|
|
@@ -29798,66 +30317,66 @@ var FREE_SELECTABLE_MODEL_IDS = [
|
|
|
29798
30317
|
"minimax-h3/reference-to-video",
|
|
29799
30318
|
"wan/3-0-video"
|
|
29800
30319
|
];
|
|
29801
|
-
var FreeVideoInput =
|
|
30320
|
+
var FreeVideoInput = z128.object({
|
|
29802
30321
|
images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
|
|
29803
|
-
rawPrompt:
|
|
30322
|
+
rawPrompt: z128.string().trim().min(1).max(2e3).describe("Prompt o guion exacto del video. Si activas subt\xEDtulos, este mismo texto se usa como guion de subt\xEDtulos."),
|
|
29804
30323
|
language: CreativeRefs.language,
|
|
29805
30324
|
quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
|
|
29806
30325
|
// Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
|
|
29807
30326
|
// parsed ONLY so the handler can reject it with a message naming its
|
|
29808
30327
|
// replacement — dropping it silently would turn a caller's explicit
|
|
29809
30328
|
// Pro++ pick into a quiet fallback to Wan.
|
|
29810
|
-
freeProModel:
|
|
30329
|
+
freeProModel: z128.enum([
|
|
29811
30330
|
"wan",
|
|
29812
30331
|
"seedance"
|
|
29813
30332
|
]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
|
|
29814
30333
|
modelId: FreeVideoModelIdEnum.optional().describe('Opcional. Elige expl\xEDcitamente el modelo del registro en vez del default de la calidad: "grok-imagine-video-1-5-preview" (Grok 1.5), "minimax-h3/reference-to-video" (H3 Max) o "wan/3-0-video" (Wan 3.0). Om\xEDtelo para usar el modelo por defecto de la calidad elegida. El modelo determina la duraci\xF3n permitida (Grok 6/8/10/15s, H3 Max 4-15s, Wan 2-30s) y el precio. "bytedance/seedance-2-5" est\xE1 inactivo y se rechaza con un error claro, nunca un 500.'),
|
|
29815
|
-
durationSeconds:
|
|
30334
|
+
durationSeconds: z128.number().int().min(2).max(30).describe("Duraci\xF3n exacta. Econ\xF3mico: 6, 8, 10 o 15s; Medio: enteros de 4 a 15s; Pro Wan: 2 a 30s; Pro++ Seedance: 4 a 30s."),
|
|
29816
30335
|
videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
|
|
29817
|
-
generateAiMusic:
|
|
30336
|
+
generateAiMusic: z128.boolean().default(false).describe('Opcional. Agrega m\xFAsica instrumental IA debajo del audio nativo. Default false. Equivale a generateAiEdit (nivel "pro"): la Edici\xF3n con IA trae su propia m\xFAsica.'),
|
|
29818
30337
|
generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, gr\xE1ficos y m\xFAsica sobre el video ya entregado (variante with_ai_edit; se cobra al entregar). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro". Default sin edici\xF3n.'),
|
|
29819
|
-
addSubtitles:
|
|
29820
|
-
idempotencyKey:
|
|
30338
|
+
addSubtitles: z128.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
|
|
30339
|
+
idempotencyKey: z128.string().uuid().optional().describe("Opcional. Se acepta por compatibilidad pero se ignora: la identidad del reintento se deriva autom\xE1ticamente de los argumentos sem\xE1nticos, as\xED que un retry con los mismos argumentos ya es idempotente sin este campo.")
|
|
29821
30340
|
}).strict();
|
|
29822
30341
|
var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
|
|
29823
|
-
var ImageCreativeSetup =
|
|
29824
|
-
|
|
29825
|
-
mode:
|
|
30342
|
+
var ImageCreativeSetup = z128.discriminatedUnion("mode", [
|
|
30343
|
+
z128.object({
|
|
30344
|
+
mode: z128.literal("automatic")
|
|
29826
30345
|
}).strict(),
|
|
29827
|
-
|
|
29828
|
-
mode:
|
|
29829
|
-
creativeArchetype:
|
|
30346
|
+
z128.object({
|
|
30347
|
+
mode: z128.literal("guided"),
|
|
30348
|
+
creativeArchetype: z128.union([
|
|
29830
30349
|
ImageCreativeArchetypeEnum,
|
|
29831
|
-
|
|
30350
|
+
z128.literal("ai_decides")
|
|
29832
30351
|
]),
|
|
29833
|
-
visualTreatment:
|
|
30352
|
+
visualTreatment: z128.union([
|
|
29834
30353
|
ImageCreativeVisualTreatmentEnum,
|
|
29835
|
-
|
|
30354
|
+
z128.literal("ai_decides")
|
|
29836
30355
|
]),
|
|
29837
30356
|
aspectRatio: ImageCreativeAspectRatioEnum,
|
|
29838
|
-
nVariants:
|
|
29839
|
-
|
|
29840
|
-
|
|
29841
|
-
|
|
29842
|
-
|
|
29843
|
-
|
|
30357
|
+
nVariants: z128.union([
|
|
30358
|
+
z128.literal(1),
|
|
30359
|
+
z128.literal(2),
|
|
30360
|
+
z128.literal(3),
|
|
30361
|
+
z128.literal(4),
|
|
30362
|
+
z128.literal(6)
|
|
29844
30363
|
]),
|
|
29845
|
-
imageModel:
|
|
29846
|
-
styleMix:
|
|
29847
|
-
generateAdCopy:
|
|
29848
|
-
competitorScanEnabled:
|
|
29849
|
-
productContext:
|
|
29850
|
-
creativeDirection:
|
|
29851
|
-
brandColors:
|
|
29852
|
-
headline:
|
|
29853
|
-
subheadline:
|
|
30364
|
+
imageModel: z128.enum(PUBLIC_IMAGE_QUALITY_INPUTS).describe('Calidad: "image:1k" (Est\xE1ndar) o "image:2k" (Premium). Los tokens gpt-image-2-5:{1k,2k} y gpt-image-2:{1k,2k} se siguen aceptando.'),
|
|
30365
|
+
styleMix: z128.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
|
|
30366
|
+
generateAdCopy: z128.boolean(),
|
|
30367
|
+
competitorScanEnabled: z128.boolean(),
|
|
30368
|
+
productContext: z128.string().trim().min(1).max(3e3).nullable(),
|
|
30369
|
+
creativeDirection: z128.string().trim().min(1).max(500).nullable(),
|
|
30370
|
+
brandColors: z128.string().trim().min(1).max(240).nullable().describe('Colores en lenguaje natural, igual que en el chat web. Ej. "Azul y Dorado". null significa sin colores espec\xEDficos.'),
|
|
30371
|
+
headline: z128.string().trim().min(1).max(120).nullable(),
|
|
30372
|
+
subheadline: z128.string().trim().min(1).max(160).nullable()
|
|
29854
30373
|
}).strict()
|
|
29855
30374
|
]).superRefine((setup, context) => {
|
|
29856
30375
|
if (setup.mode !== "guided") return;
|
|
29857
30376
|
const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
|
|
29858
30377
|
if (needsStyleMix && setup.styleMix === null) {
|
|
29859
30378
|
context.addIssue({
|
|
29860
|
-
code:
|
|
30379
|
+
code: z128.ZodIssueCode.custom,
|
|
29861
30380
|
path: [
|
|
29862
30381
|
"styleMix"
|
|
29863
30382
|
],
|
|
@@ -29866,7 +30385,7 @@ var ImageCreativeSetup = z127.discriminatedUnion("mode", [
|
|
|
29866
30385
|
}
|
|
29867
30386
|
if (!needsStyleMix && setup.styleMix !== null) {
|
|
29868
30387
|
context.addIssue({
|
|
29869
|
-
code:
|
|
30388
|
+
code: z128.ZodIssueCode.custom,
|
|
29870
30389
|
path: [
|
|
29871
30390
|
"styleMix"
|
|
29872
30391
|
],
|
|
@@ -29875,7 +30394,7 @@ var ImageCreativeSetup = z127.discriminatedUnion("mode", [
|
|
|
29875
30394
|
}
|
|
29876
30395
|
if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
|
|
29877
30396
|
context.addIssue({
|
|
29878
|
-
code:
|
|
30397
|
+
code: z128.ZodIssueCode.custom,
|
|
29879
30398
|
path: [
|
|
29880
30399
|
"aspectRatio"
|
|
29881
30400
|
],
|
|
@@ -29883,55 +30402,55 @@ var ImageCreativeSetup = z127.discriminatedUnion("mode", [
|
|
|
29883
30402
|
});
|
|
29884
30403
|
}
|
|
29885
30404
|
});
|
|
29886
|
-
var LandingCreativeSetup =
|
|
29887
|
-
|
|
29888
|
-
mode:
|
|
30405
|
+
var LandingCreativeSetup = z128.discriminatedUnion("mode", [
|
|
30406
|
+
z128.object({
|
|
30407
|
+
mode: z128.literal("automatic")
|
|
29889
30408
|
}).strict(),
|
|
29890
|
-
|
|
29891
|
-
mode:
|
|
30409
|
+
z128.object({
|
|
30410
|
+
mode: z128.literal("guided"),
|
|
29892
30411
|
landingStrategy: LandingStrategyEnum,
|
|
29893
30412
|
landingImageFormat: LandingImageFormatEnum,
|
|
29894
|
-
competitorScanEnabled:
|
|
29895
|
-
paymentMethods:
|
|
29896
|
-
productContext:
|
|
29897
|
-
creativeDirection:
|
|
29898
|
-
headline:
|
|
29899
|
-
subheadline:
|
|
30413
|
+
competitorScanEnabled: z128.boolean(),
|
|
30414
|
+
paymentMethods: z128.string().trim().min(1).max(240).nullable(),
|
|
30415
|
+
productContext: z128.string().trim().min(1).max(3e3).nullable(),
|
|
30416
|
+
creativeDirection: z128.string().trim().min(1).max(500).nullable(),
|
|
30417
|
+
headline: z128.string().trim().min(1).max(120).nullable(),
|
|
30418
|
+
subheadline: z128.string().trim().min(1).max(160).nullable()
|
|
29900
30419
|
}).strict()
|
|
29901
30420
|
]);
|
|
29902
|
-
var ImageInput =
|
|
30421
|
+
var ImageInput = z128.object({
|
|
29903
30422
|
images: CreativeRefs.images.optional(),
|
|
29904
30423
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
29905
|
-
productTitle:
|
|
29906
|
-
primaryAngle:
|
|
30424
|
+
productTitle: z128.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
|
|
30425
|
+
primaryAngle: z128.string().min(1).optional().describe('Opcional. \xC1ngulo de venta principal. Si se omite, ProductMaker lo genera y creativeSetup.mode="guided" lo muestra para revisi\xF3n antes de crear las im\xE1genes.'),
|
|
29907
30426
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
29908
30427
|
language: CreativeRefs.language,
|
|
29909
30428
|
country: CreativeRefs.country,
|
|
29910
30429
|
creativeSetup: ImageCreativeSetup.describe("Configuraci\xF3n obligatoria equivalente al wizard web. Usa guided salvo que el usuario delegue expl\xEDcitamente todo; presenta las decisiones guiadas en un \xFAnico checklist compacto."),
|
|
29911
30430
|
imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
|
|
29912
|
-
features:
|
|
30431
|
+
features: z128.array(z128.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
|
|
29913
30432
|
price: CreativeRefs.price,
|
|
29914
|
-
omitPrice:
|
|
30433
|
+
omitPrice: z128.boolean().optional().describe("Pon true \xFAnicamente cuando el usuario pida expl\xEDcitamente una imagen sin precio. Evita que el backend reutilice un precio extra\xEDdo del producto. No lo combines con price ni compareAtPrice."),
|
|
29915
30434
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
29916
30435
|
offer: CreativeRefs.offer,
|
|
29917
30436
|
productLabel: CreativeRefs.productLabel,
|
|
29918
30437
|
isCombo: CreativeRefs.isCombo,
|
|
29919
30438
|
brandId: CreativeRefs.brandId
|
|
29920
30439
|
});
|
|
29921
|
-
var EditImageCreativeInput =
|
|
29922
|
-
taskId:
|
|
29923
|
-
variantIndex:
|
|
29924
|
-
clientRequestId:
|
|
29925
|
-
instruction:
|
|
30440
|
+
var EditImageCreativeInput = z128.object({
|
|
30441
|
+
taskId: z128.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
|
|
30442
|
+
variantIndex: z128.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
|
|
30443
|
+
clientRequestId: z128.string().min(1).max(160).optional().describe("Identidad estable de esta correcci\xF3n; reutil\xEDzala al reconciliar una respuesta perdida, no para otra instrucci\xF3n."),
|
|
30444
|
+
instruction: z128.string().min(1).max(1e3).describe('Qu\xE9 cambiar en esa imagen. Ej. "quita el badge de env\xEDo gratis", "cambia el fondo a blanco".')
|
|
29926
30445
|
});
|
|
29927
|
-
var LandingInput =
|
|
29928
|
-
includeInitialLandingGif:
|
|
30446
|
+
var LandingInput = z128.object({
|
|
30447
|
+
includeInitialLandingGif: z128.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
|
|
29929
30448
|
images: CreativeRefs.images.optional(),
|
|
29930
30449
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
29931
30450
|
language: CreativeRefs.language,
|
|
29932
30451
|
country: CreativeRefs.country,
|
|
29933
30452
|
creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
|
|
29934
|
-
salesAngle:
|
|
30453
|
+
salesAngle: z128.string().optional().describe('Opcional. \xC1ngulo de venta principal. Ej. "Reduce arrugas en 14 d\xEDas". Si se omite, la IA lo deduce de la imagen.'),
|
|
29935
30454
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
29936
30455
|
price: CreativeRefs.price,
|
|
29937
30456
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
@@ -30213,8 +30732,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
30213
30732
|
server.registerTool("get_image_edit_status", {
|
|
30214
30733
|
description: imageEditStatusGuidance.summary,
|
|
30215
30734
|
inputSchema: {
|
|
30216
|
-
taskId:
|
|
30217
|
-
operationId:
|
|
30735
|
+
taskId: z128.string().uuid(),
|
|
30736
|
+
operationId: z128.string().uuid()
|
|
30218
30737
|
},
|
|
30219
30738
|
annotations: READS_INTERNAL
|
|
30220
30739
|
}, async (input) => {
|
|
@@ -30271,10 +30790,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
30271
30790
|
__name(registerCreativeTools, "registerCreativeTools");
|
|
30272
30791
|
|
|
30273
30792
|
// src/tools/creative-variants.ts
|
|
30274
|
-
import { z as
|
|
30793
|
+
import { z as z129 } from "zod";
|
|
30275
30794
|
var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
|
|
30276
30795
|
var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
|
|
30277
|
-
var LandingSectionKeyEnum =
|
|
30796
|
+
var LandingSectionKeyEnum = z129.enum([
|
|
30278
30797
|
"problem_hook",
|
|
30279
30798
|
"problem_cost",
|
|
30280
30799
|
"solution_mechanism",
|
|
@@ -30314,24 +30833,24 @@ var LandingSectionKeyEnum = z128.enum([
|
|
|
30314
30833
|
"lifestyle_fit",
|
|
30315
30834
|
"join_lifestyle"
|
|
30316
30835
|
]);
|
|
30317
|
-
var CreativeVariantKindEnum =
|
|
30836
|
+
var CreativeVariantKindEnum = z129.enum([
|
|
30318
30837
|
"video",
|
|
30319
30838
|
"image",
|
|
30320
30839
|
"landing"
|
|
30321
30840
|
]);
|
|
30322
|
-
var EstimateCreativeVariantInputBase =
|
|
30323
|
-
sourceTaskId:
|
|
30841
|
+
var EstimateCreativeVariantInputBase = z129.object({
|
|
30842
|
+
sourceTaskId: z129.string().uuid().describe("ID de la tarea original completada."),
|
|
30324
30843
|
kind: CreativeVariantKindEnum,
|
|
30325
30844
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
|
|
30326
30845
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
|
|
30327
|
-
nVariants:
|
|
30846
|
+
nVariants: z129.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
30328
30847
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
|
|
30329
|
-
instructions:
|
|
30848
|
+
instructions: z129.string().trim().min(1).max(2e3).optional().describe("Opcional para landing. Si se env\xEDa sin sectionKey, el estimado suma la clasificaci\xF3n pagada con IA.")
|
|
30330
30849
|
}).strict();
|
|
30331
30850
|
var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
30332
30851
|
if (input.kind === "video" && input.nVariants !== void 0) {
|
|
30333
30852
|
ctx.addIssue({
|
|
30334
|
-
code:
|
|
30853
|
+
code: z129.ZodIssueCode.custom,
|
|
30335
30854
|
path: [
|
|
30336
30855
|
"nVariants"
|
|
30337
30856
|
],
|
|
@@ -30341,7 +30860,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
30341
30860
|
if (input.kind !== "video") {
|
|
30342
30861
|
if (input.videoPreset !== void 0) {
|
|
30343
30862
|
ctx.addIssue({
|
|
30344
|
-
code:
|
|
30863
|
+
code: z129.ZodIssueCode.custom,
|
|
30345
30864
|
path: [
|
|
30346
30865
|
"videoPreset"
|
|
30347
30866
|
],
|
|
@@ -30350,7 +30869,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
30350
30869
|
}
|
|
30351
30870
|
if (input.videoResolution !== void 0) {
|
|
30352
30871
|
ctx.addIssue({
|
|
30353
|
-
code:
|
|
30872
|
+
code: z129.ZodIssueCode.custom,
|
|
30354
30873
|
path: [
|
|
30355
30874
|
"videoResolution"
|
|
30356
30875
|
],
|
|
@@ -30360,7 +30879,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
30360
30879
|
}
|
|
30361
30880
|
if (input.kind !== "image" && input.nVariants !== void 0) {
|
|
30362
30881
|
ctx.addIssue({
|
|
30363
|
-
code:
|
|
30882
|
+
code: z129.ZodIssueCode.custom,
|
|
30364
30883
|
path: [
|
|
30365
30884
|
"nVariants"
|
|
30366
30885
|
],
|
|
@@ -30370,7 +30889,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
30370
30889
|
if (input.kind !== "landing") {
|
|
30371
30890
|
if (input.sectionKey !== void 0) {
|
|
30372
30891
|
ctx.addIssue({
|
|
30373
|
-
code:
|
|
30892
|
+
code: z129.ZodIssueCode.custom,
|
|
30374
30893
|
path: [
|
|
30375
30894
|
"sectionKey"
|
|
30376
30895
|
],
|
|
@@ -30379,7 +30898,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
30379
30898
|
}
|
|
30380
30899
|
if (input.instructions !== void 0) {
|
|
30381
30900
|
ctx.addIssue({
|
|
30382
|
-
code:
|
|
30901
|
+
code: z129.ZodIssueCode.custom,
|
|
30383
30902
|
path: [
|
|
30384
30903
|
"instructions"
|
|
30385
30904
|
],
|
|
@@ -30388,31 +30907,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
30388
30907
|
}
|
|
30389
30908
|
}
|
|
30390
30909
|
});
|
|
30391
|
-
var CreateCreativeVariantInputBase =
|
|
30392
|
-
sourceTaskId:
|
|
30910
|
+
var CreateCreativeVariantInputBase = z129.object({
|
|
30911
|
+
sourceTaskId: z129.string().uuid().describe("ID de la tarea original completada."),
|
|
30393
30912
|
kind: CreativeVariantKindEnum,
|
|
30394
|
-
confirm:
|
|
30395
|
-
clientRequestId:
|
|
30396
|
-
angle:
|
|
30397
|
-
buyerPersona:
|
|
30398
|
-
scriptNotes:
|
|
30399
|
-
creativeDirection:
|
|
30913
|
+
confirm: z129.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
|
|
30914
|
+
clientRequestId: z129.string().uuid().describe("UUID estable para esta intenci\xF3n (obligatorio por compatibilidad de contrato; el servidor deriva la identidad real del request desde los argumentos sem\xE1nticos, as\xED que un UUID nuevo en un retry NO crea una variante duplicada). Si la API devuelve status=error, una nueva generaci\xF3n exige otra confirmaci\xF3n."),
|
|
30915
|
+
angle: z129.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
|
|
30916
|
+
buyerPersona: z129.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
|
|
30917
|
+
scriptNotes: z129.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
|
|
30918
|
+
creativeDirection: z129.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
|
|
30400
30919
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
|
|
30401
30920
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
|
|
30402
|
-
generateAiMusic:
|
|
30403
|
-
nVariants:
|
|
30921
|
+
generateAiMusic: z129.boolean().optional().describe("Opcional para video."),
|
|
30922
|
+
nVariants: z129.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
30404
30923
|
imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
|
|
30405
30924
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
|
|
30406
30925
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
|
|
30407
30926
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
|
|
30408
|
-
styleMix:
|
|
30927
|
+
styleMix: z129.boolean().optional().describe("Opcional para imagen."),
|
|
30409
30928
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
|
|
30410
|
-
instructions:
|
|
30929
|
+
instructions: z129.string().trim().min(1).max(2e3).optional().describe("Solicitud libre para una nueva secci\xF3n de landing. La IA la clasifica si no env\xEDas sectionKey.")
|
|
30411
30930
|
}).strict();
|
|
30412
30931
|
var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
30413
30932
|
if ((input.kind === "video" || input.kind === "image") && !input.angle) {
|
|
30414
30933
|
ctx.addIssue({
|
|
30415
|
-
code:
|
|
30934
|
+
code: z129.ZodIssueCode.custom,
|
|
30416
30935
|
path: [
|
|
30417
30936
|
"angle"
|
|
30418
30937
|
],
|
|
@@ -30421,7 +30940,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
30421
30940
|
}
|
|
30422
30941
|
if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
|
|
30423
30942
|
ctx.addIssue({
|
|
30424
|
-
code:
|
|
30943
|
+
code: z129.ZodIssueCode.custom,
|
|
30425
30944
|
path: [
|
|
30426
30945
|
"instructions"
|
|
30427
30946
|
],
|
|
@@ -30467,7 +30986,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
30467
30986
|
for (const field of fieldsByKind[input.kind]) {
|
|
30468
30987
|
if (input[field] !== void 0) {
|
|
30469
30988
|
ctx.addIssue({
|
|
30470
|
-
code:
|
|
30989
|
+
code: z129.ZodIssueCode.custom,
|
|
30471
30990
|
path: [
|
|
30472
30991
|
field
|
|
30473
30992
|
],
|
|
@@ -30625,13 +31144,13 @@ function registerCreativeVariantTools(server, api) {
|
|
|
30625
31144
|
__name(registerCreativeVariantTools, "registerCreativeVariantTools");
|
|
30626
31145
|
|
|
30627
31146
|
// src/tools/script-review.ts
|
|
30628
|
-
import { z as
|
|
31147
|
+
import { z as z130 } from "zod";
|
|
30629
31148
|
var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
|
|
30630
31149
|
var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
|
|
30631
31150
|
var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
|
|
30632
|
-
var GetVideoScriptInput =
|
|
30633
|
-
taskId:
|
|
30634
|
-
angleKey:
|
|
31151
|
+
var GetVideoScriptInput = z130.object({
|
|
31152
|
+
taskId: z130.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
|
|
31153
|
+
angleKey: z130.string().min(1).optional().describe('Clave persistida del \xE1ngulo cuyo guion se quiere leer (formato "angle_0", "angle_1", ...). Usa exactamente el angleKey recibido en reviewNextAction.calls al aprobar \xE1ngulos, incluso si s\xF3lo elegiste uno. Si se omite, el backend resuelve a "angle_0" literal; elegir el segundo candidato no crea angle_0. No derives esta clave del n\xFAmero visible del candidato.')
|
|
30635
31154
|
}).strict();
|
|
30636
31155
|
var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
|
|
30637
31156
|
var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
|
|
@@ -30736,7 +31255,7 @@ Consulta get_task_status con esta tarea antes de reintentar. Si la tarea termin\
|
|
|
30736
31255
|
__name(registerScriptReviewTools, "registerScriptReviewTools");
|
|
30737
31256
|
|
|
30738
31257
|
// src/tools/connections.ts
|
|
30739
|
-
import { z as
|
|
31258
|
+
import { z as z131 } from "zod";
|
|
30740
31259
|
var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
|
|
30741
31260
|
var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
|
|
30742
31261
|
var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
|
|
@@ -30745,7 +31264,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
|
|
|
30745
31264
|
function registerConnectionTools(server, api) {
|
|
30746
31265
|
server.registerTool("list_shopify_shops", {
|
|
30747
31266
|
description: listShopifyShopsGuidance.summary + " Si la lista est\xE1 vac\xEDa, dile al usuario que conecte una tienda en productmaker.app/integrations antes de intentar publicar.",
|
|
30748
|
-
inputSchema:
|
|
31267
|
+
inputSchema: z131.object({}).shape,
|
|
30749
31268
|
annotations: READS_INTERNAL
|
|
30750
31269
|
}, async () => {
|
|
30751
31270
|
try {
|
|
@@ -30757,10 +31276,10 @@ function registerConnectionTools(server, api) {
|
|
|
30757
31276
|
});
|
|
30758
31277
|
server.registerTool("list_shopify_products", {
|
|
30759
31278
|
description: listShopifyProductsGuidance.summary + ' Usa el `id` devuelto junto con `publicationMode="existing"` en `publish_to_shopify`. Si `taskId` se proporciona, la respuesta tambi\xE9n indica el producto publicado actualmente para esa tarea y tienda. No modifica Shopify.',
|
|
30760
|
-
inputSchema:
|
|
30761
|
-
shopDomain:
|
|
30762
|
-
query:
|
|
30763
|
-
taskId:
|
|
31279
|
+
inputSchema: z131.object({
|
|
31280
|
+
shopDomain: z131.string().min(3).max(120),
|
|
31281
|
+
query: z131.string().trim().max(120).optional(),
|
|
31282
|
+
taskId: z131.string().uuid().optional()
|
|
30764
31283
|
}).shape,
|
|
30765
31284
|
annotations: READS_EXTERNAL
|
|
30766
31285
|
}, async ({ shopDomain, query, taskId }) => {
|
|
@@ -30778,7 +31297,7 @@ function registerConnectionTools(server, api) {
|
|
|
30778
31297
|
});
|
|
30779
31298
|
server.registerTool("list_meta_ad_accounts", {
|
|
30780
31299
|
description: listMetaAdAccountsGuidance.summary + " Para publicar, prefiere `list_meta_destinations`, que tambi\xE9n devuelve el portfolio y las p\xE1ginas disponibles. Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar Meta en productmaker.app/integrations.",
|
|
30781
|
-
inputSchema:
|
|
31300
|
+
inputSchema: z131.object({}).shape,
|
|
30782
31301
|
annotations: READS_EXTERNAL
|
|
30783
31302
|
}, async () => {
|
|
30784
31303
|
try {
|
|
@@ -30790,7 +31309,7 @@ function registerConnectionTools(server, api) {
|
|
|
30790
31309
|
});
|
|
30791
31310
|
server.registerTool("list_meta_destinations", {
|
|
30792
31311
|
description: listMetaDestinationsGuidance.summary + " Es obligatorio llamar esta herramienta antes de publicar, mostrar las opciones y enviar al publicador el `portfolioId`, `adAccountId` y `pageId` elegidos; nunca elijas silenciosamente la primera p\xE1gina o cuenta. No modifica Meta.",
|
|
30793
|
-
inputSchema:
|
|
31312
|
+
inputSchema: z131.object({}).shape,
|
|
30794
31313
|
annotations: READS_EXTERNAL,
|
|
30795
31314
|
_meta: {
|
|
30796
31315
|
"openai/widgetAccessible": true
|
|
@@ -30805,7 +31324,7 @@ function registerConnectionTools(server, api) {
|
|
|
30805
31324
|
});
|
|
30806
31325
|
server.registerTool("list_tiktok_advertisers", {
|
|
30807
31326
|
description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
|
|
30808
|
-
inputSchema:
|
|
31327
|
+
inputSchema: z131.object({}).shape,
|
|
30809
31328
|
annotations: READS_EXTERNAL
|
|
30810
31329
|
}, async () => {
|
|
30811
31330
|
try {
|
|
@@ -30819,7 +31338,7 @@ function registerConnectionTools(server, api) {
|
|
|
30819
31338
|
__name(registerConnectionTools, "registerConnectionTools");
|
|
30820
31339
|
|
|
30821
31340
|
// src/tools/actors.ts
|
|
30822
|
-
import { z as
|
|
31341
|
+
import { z as z132 } from "zod";
|
|
30823
31342
|
var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
|
|
30824
31343
|
var actorVoiceGuidance = {
|
|
30825
31344
|
capabilities: getProductMakerCapabilityModelGuidance("get_actor_voice_capabilities"),
|
|
@@ -30859,7 +31378,7 @@ function sanitizeVoiceResult(value) {
|
|
|
30859
31378
|
__name(sanitizeVoiceResult, "sanitizeVoiceResult");
|
|
30860
31379
|
function registerActorTools(server, api) {
|
|
30861
31380
|
const actor = {
|
|
30862
|
-
actorId:
|
|
31381
|
+
actorId: z132.string().min(1).max(64)
|
|
30863
31382
|
};
|
|
30864
31383
|
const safe = /* @__PURE__ */ __name(async (request) => {
|
|
30865
31384
|
try {
|
|
@@ -30888,8 +31407,8 @@ function registerActorTools(server, api) {
|
|
|
30888
31407
|
inputSchema: {
|
|
30889
31408
|
...actor,
|
|
30890
31409
|
draft: ActorVoiceDraftSchema,
|
|
30891
|
-
requestKey:
|
|
30892
|
-
acceptedQuoteId:
|
|
31410
|
+
requestKey: z132.string().trim().min(1).max(128),
|
|
31411
|
+
acceptedQuoteId: z132.string().trim().min(1).max(128)
|
|
30893
31412
|
},
|
|
30894
31413
|
annotations: CREATES_PAID
|
|
30895
31414
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews`, body)));
|
|
@@ -30897,7 +31416,7 @@ function registerActorTools(server, api) {
|
|
|
30897
31416
|
description: actorVoiceGuidance.get.summary,
|
|
30898
31417
|
inputSchema: {
|
|
30899
31418
|
...actor,
|
|
30900
|
-
candidateId:
|
|
31419
|
+
candidateId: z132.string().min(1).max(64)
|
|
30901
31420
|
},
|
|
30902
31421
|
// Polling can resume the first paid submission of an accepted quote.
|
|
30903
31422
|
// The immutable candidate/operation key keeps recovery idempotent.
|
|
@@ -30910,16 +31429,16 @@ function registerActorTools(server, api) {
|
|
|
30910
31429
|
description: actorVoiceGuidance.approve.summary,
|
|
30911
31430
|
inputSchema: {
|
|
30912
31431
|
...actor,
|
|
30913
|
-
candidateId:
|
|
30914
|
-
expectedRevision:
|
|
30915
|
-
expectedApprovedRevision:
|
|
31432
|
+
candidateId: z132.string().min(1).max(64),
|
|
31433
|
+
expectedRevision: z132.number().int().positive(),
|
|
31434
|
+
expectedApprovedRevision: z132.number().int().positive().nullable().optional()
|
|
30916
31435
|
},
|
|
30917
31436
|
// Replaces the selected voice and withdraws the old catalog grants.
|
|
30918
31437
|
annotations: OVERWRITES_INTERNAL
|
|
30919
31438
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/approve`, body)));
|
|
30920
31439
|
server.registerTool("list_actors", {
|
|
30921
31440
|
description: listActorsGuidance.summary + " Devuelve id, nombre, descripci\xF3n, g\xE9nero y voz privada del personaje. Cuando el personaje tiene una voz personalizada, `voice.identityId` y `voice.revision` identifican la versi\xF3n aprobada \u2014 conserva la revisi\xF3n al llamar `approve_actor_voice` (expectedApprovedRevision) para reemplazarla. Los IDs de proveedor nunca se exponen por MCP. Usa el `id` como `actorId` al crear o editar una tarea. Solo aparecen los personajes listos para usar; si la lista est\xE1 vac\xEDa, dile al usuario que cree uno en productmaker.app antes de intentar asignarlo. No modifica nada.",
|
|
30922
|
-
inputSchema:
|
|
31441
|
+
inputSchema: z132.object({}).shape,
|
|
30923
31442
|
annotations: READS_INTERNAL
|
|
30924
31443
|
}, async () => {
|
|
30925
31444
|
try {
|
|
@@ -30952,7 +31471,7 @@ function registerActorTools(server, api) {
|
|
|
30952
31471
|
__name(registerActorTools, "registerActorTools");
|
|
30953
31472
|
|
|
30954
31473
|
// src/tools/publish.ts
|
|
30955
|
-
import { z as
|
|
31474
|
+
import { z as z133 } from "zod";
|
|
30956
31475
|
|
|
30957
31476
|
// src/tools/meta-publish-attempt-id.ts
|
|
30958
31477
|
var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
|
|
@@ -30991,40 +31510,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
|
|
|
30991
31510
|
var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
|
|
30992
31511
|
var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
|
|
30993
31512
|
var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
|
|
30994
|
-
var ShopifyInput =
|
|
30995
|
-
taskId:
|
|
30996
|
-
shopDomain:
|
|
31513
|
+
var ShopifyInput = z133.object({
|
|
31514
|
+
taskId: z133.string().min(1),
|
|
31515
|
+
shopDomain: z133.string().min(1),
|
|
30997
31516
|
/** Override: number of landing images to include. Default = ALL images the
|
|
30998
31517
|
* task generated (the MCP fetches /v1/results first to count). Bounded
|
|
30999
31518
|
* generously here; the backend validates each index against
|
|
31000
31519
|
* landing.images.length and rejects out-of-range. */
|
|
31001
|
-
numLandingImages:
|
|
31002
|
-
variantIndex:
|
|
31520
|
+
numLandingImages: z133.number().int().min(1).max(20).optional(),
|
|
31521
|
+
variantIndex: z133.number().int().min(0).optional(),
|
|
31003
31522
|
/** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
|
|
31004
31523
|
* When true, the landing renders variant-picker pills; when false, it ships
|
|
31005
31524
|
* a single-option product page. Defaults to false. */
|
|
31006
|
-
showVariantPicker:
|
|
31525
|
+
showVariantPicker: z133.boolean().optional(),
|
|
31007
31526
|
/** Default `auto` updates the product previously published for this task and
|
|
31008
31527
|
* shop. Use `existing` with targetProductId to choose another product, or
|
|
31009
31528
|
* `new` only when the user explicitly wants a duplicate/new listing. */
|
|
31010
|
-
publicationMode:
|
|
31529
|
+
publicationMode: z133.enum([
|
|
31011
31530
|
"auto",
|
|
31012
31531
|
"existing",
|
|
31013
31532
|
"new"
|
|
31014
31533
|
]).optional(),
|
|
31015
31534
|
/** Shopify product GID, numeric id, or admin product URL. Required when
|
|
31016
31535
|
* publicationMode is `existing`. */
|
|
31017
|
-
targetProductId:
|
|
31536
|
+
targetProductId: z133.string().trim().min(1).max(300).optional(),
|
|
31018
31537
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
31019
|
-
announcementBarEnabled:
|
|
31020
|
-
announcementBarText:
|
|
31538
|
+
announcementBarEnabled: z133.boolean().optional(),
|
|
31539
|
+
announcementBarText: z133.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
|
|
31021
31540
|
commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
|
|
31022
|
-
confirmed:
|
|
31541
|
+
confirmed: z133.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
|
|
31023
31542
|
});
|
|
31024
31543
|
var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
|
|
31025
31544
|
if (value.commerceCorrection && value.confirmed !== true) {
|
|
31026
31545
|
ctx.addIssue({
|
|
31027
|
-
code:
|
|
31546
|
+
code: z133.ZodIssueCode.custom,
|
|
31028
31547
|
path: [
|
|
31029
31548
|
"confirmed"
|
|
31030
31549
|
],
|
|
@@ -31033,7 +31552,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
31033
31552
|
}
|
|
31034
31553
|
if (value.announcementBarEnabled && !value.announcementBarText) {
|
|
31035
31554
|
ctx.addIssue({
|
|
31036
|
-
code:
|
|
31555
|
+
code: z133.ZodIssueCode.custom,
|
|
31037
31556
|
path: [
|
|
31038
31557
|
"announcementBarText"
|
|
31039
31558
|
],
|
|
@@ -31042,7 +31561,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
31042
31561
|
}
|
|
31043
31562
|
if (!value.announcementBarEnabled && value.announcementBarText) {
|
|
31044
31563
|
ctx.addIssue({
|
|
31045
|
-
code:
|
|
31564
|
+
code: z133.ZodIssueCode.custom,
|
|
31046
31565
|
path: [
|
|
31047
31566
|
"announcementBarText"
|
|
31048
31567
|
],
|
|
@@ -31056,90 +31575,90 @@ function parseShopifyInput(rawInput) {
|
|
|
31056
31575
|
return parsed.data;
|
|
31057
31576
|
}
|
|
31058
31577
|
__name(parseShopifyInput, "parseShopifyInput");
|
|
31059
|
-
var McpCampaignConfig =
|
|
31578
|
+
var McpCampaignConfig = z133.object({
|
|
31060
31579
|
/** Legacy USD amount. Meta retains its existing conversion; the TikTok
|
|
31061
31580
|
* schema below restricts this input to USD advertiser accounts. */
|
|
31062
|
-
dailyBudgetUsd:
|
|
31581
|
+
dailyBudgetUsd: z133.number().positive().optional(),
|
|
31063
31582
|
/** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
|
|
31064
31583
|
* normalizes at validation). Meta accepts max 1 (single-country ad set).
|
|
31065
31584
|
* TikTok takes only the first entry. */
|
|
31066
|
-
targetCountries:
|
|
31067
|
-
campaignName:
|
|
31585
|
+
targetCountries: z133.array(CountryIso2Schema).max(1).optional(),
|
|
31586
|
+
campaignName: z133.string().trim().min(1).max(100).optional()
|
|
31068
31587
|
});
|
|
31069
31588
|
var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
|
|
31070
|
-
var MetaInput =
|
|
31071
|
-
taskId:
|
|
31589
|
+
var MetaInput = z133.object({
|
|
31590
|
+
taskId: z133.string().min(1),
|
|
31072
31591
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
31073
|
-
portfolioId:
|
|
31592
|
+
portfolioId: z133.string().trim().min(1),
|
|
31074
31593
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
31075
|
-
pageId:
|
|
31594
|
+
pageId: z133.string().trim().min(1),
|
|
31076
31595
|
adAccountId: McpAdAccountId,
|
|
31077
|
-
pixelId:
|
|
31078
|
-
landingUrl:
|
|
31596
|
+
pixelId: z133.string().min(1).optional(),
|
|
31597
|
+
landingUrl: z133.string().url().optional(),
|
|
31079
31598
|
/** Select which angles to publish by 0-based index. Omit to publish all
|
|
31080
31599
|
* successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
|
|
31081
|
-
angleIndexes:
|
|
31600
|
+
angleIndexes: z133.array(z133.number().int().nonnegative()).optional(),
|
|
31082
31601
|
campaignConfig: McpCampaignConfig.optional(),
|
|
31083
31602
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
31084
31603
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
31085
31604
|
* (Meta's primary-text limit). */
|
|
31086
|
-
primaryText:
|
|
31605
|
+
primaryText: z133.string().trim().min(1).max(500).optional(),
|
|
31087
31606
|
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
31088
31607
|
* (wa.me) instead of a landing page. */
|
|
31089
|
-
phoneNumber:
|
|
31608
|
+
phoneNumber: z133.string().min(8).max(32).optional()
|
|
31090
31609
|
});
|
|
31091
|
-
var GroupedTaskSource =
|
|
31092
|
-
type:
|
|
31093
|
-
taskId:
|
|
31094
|
-
angleIndex:
|
|
31095
|
-
videoVariant:
|
|
31610
|
+
var GroupedTaskSource = z133.object({
|
|
31611
|
+
type: z133.literal("task"),
|
|
31612
|
+
taskId: z133.string().min(1),
|
|
31613
|
+
angleIndex: z133.number().int().min(0).optional(),
|
|
31614
|
+
videoVariant: z133.enum([
|
|
31096
31615
|
"with_subtitles",
|
|
31097
31616
|
"without_subtitles"
|
|
31098
31617
|
]).optional(),
|
|
31099
|
-
imageVariantIndex:
|
|
31100
|
-
});
|
|
31101
|
-
var GroupedMediaSource =
|
|
31102
|
-
type:
|
|
31103
|
-
url:
|
|
31104
|
-
path:
|
|
31105
|
-
thumbnailUrl:
|
|
31106
|
-
thumbnailPath:
|
|
31618
|
+
imageVariantIndex: z133.number().int().min(0).optional()
|
|
31619
|
+
});
|
|
31620
|
+
var GroupedMediaSource = z133.object({
|
|
31621
|
+
type: z133.literal("media"),
|
|
31622
|
+
url: z133.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
|
|
31623
|
+
path: z133.string().min(1).optional().describe('Local file path only when this MCP runs over stdio. On the hosted MCP, call request_media_upload and then use source.type="asset".'),
|
|
31624
|
+
thumbnailUrl: z133.string().url().optional(),
|
|
31625
|
+
thumbnailPath: z133.string().min(1).optional()
|
|
31107
31626
|
}).refine((value) => Boolean(value.url) !== Boolean(value.path), {
|
|
31108
31627
|
message: "media source needs exactly one of `url` or `path`"
|
|
31109
31628
|
}).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
|
|
31110
31629
|
message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
|
|
31111
31630
|
});
|
|
31112
|
-
var GroupedUploadedAssetSource =
|
|
31113
|
-
type:
|
|
31631
|
+
var GroupedUploadedAssetSource = z133.object({
|
|
31632
|
+
type: z133.literal("asset"),
|
|
31114
31633
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
31115
|
-
assetId:
|
|
31116
|
-
thumbnailAssetId:
|
|
31634
|
+
assetId: z133.string().uuid(),
|
|
31635
|
+
thumbnailAssetId: z133.string().uuid().optional()
|
|
31117
31636
|
});
|
|
31118
|
-
var GroupedCreative =
|
|
31119
|
-
type:
|
|
31637
|
+
var GroupedCreative = z133.object({
|
|
31638
|
+
type: z133.enum([
|
|
31120
31639
|
"image",
|
|
31121
31640
|
"video"
|
|
31122
31641
|
]),
|
|
31123
|
-
source:
|
|
31642
|
+
source: z133.union([
|
|
31124
31643
|
GroupedTaskSource,
|
|
31125
31644
|
GroupedMediaSource,
|
|
31126
31645
|
GroupedUploadedAssetSource
|
|
31127
31646
|
]),
|
|
31128
|
-
title:
|
|
31129
|
-
description:
|
|
31647
|
+
title: z133.string().max(120).optional(),
|
|
31648
|
+
description: z133.string().max(500).optional(),
|
|
31130
31649
|
cta: MetaCtaType.optional(),
|
|
31131
|
-
creativeId:
|
|
31650
|
+
creativeId: z133.string().min(1).optional()
|
|
31132
31651
|
});
|
|
31133
|
-
var GroupedCampaignConfigBase =
|
|
31652
|
+
var GroupedCampaignConfigBase = z133.object({
|
|
31134
31653
|
campaignType: MetaCampaignType.default("sales"),
|
|
31135
31654
|
optimizationMode: MetaOptimizationMode.default("advantage_plus"),
|
|
31136
31655
|
budgetMode: MetaBudgetMode.optional(),
|
|
31137
|
-
campaignDailyBudget:
|
|
31138
|
-
adSets:
|
|
31139
|
-
tempId:
|
|
31140
|
-
name:
|
|
31141
|
-
dailyBudget:
|
|
31142
|
-
creativeIds:
|
|
31656
|
+
campaignDailyBudget: z133.number().int().positive().optional(),
|
|
31657
|
+
adSets: z133.array(z133.object({
|
|
31658
|
+
tempId: z133.string().min(1).max(80),
|
|
31659
|
+
name: z133.string().min(1).max(100),
|
|
31660
|
+
dailyBudget: z133.number().int().positive().optional(),
|
|
31661
|
+
creativeIds: z133.array(z133.string().min(1)).min(1)
|
|
31143
31662
|
})).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
|
|
31144
31663
|
/**
|
|
31145
31664
|
* Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
|
|
@@ -31147,17 +31666,17 @@ var GroupedCampaignConfigBase = z132.object({
|
|
|
31147
31666
|
* opaque `invalid_literal` and made the WhatsApp destination — supported by
|
|
31148
31667
|
* the API since #849 — unreachable from this tool.
|
|
31149
31668
|
*/
|
|
31150
|
-
destination:
|
|
31151
|
-
|
|
31152
|
-
type:
|
|
31153
|
-
landingUrl:
|
|
31669
|
+
destination: z133.discriminatedUnion("type", [
|
|
31670
|
+
z133.object({
|
|
31671
|
+
type: z133.literal("landing"),
|
|
31672
|
+
landingUrl: z133.string().url()
|
|
31154
31673
|
}),
|
|
31155
|
-
|
|
31156
|
-
type:
|
|
31157
|
-
phoneNumber:
|
|
31674
|
+
z133.object({
|
|
31675
|
+
type: z133.literal("whatsapp"),
|
|
31676
|
+
phoneNumber: z133.string().min(8).max(32)
|
|
31158
31677
|
})
|
|
31159
31678
|
]),
|
|
31160
|
-
saveAsDefault:
|
|
31679
|
+
saveAsDefault: z133.boolean().default(false),
|
|
31161
31680
|
budgetPolicy: MetaBudgetPolicy.optional()
|
|
31162
31681
|
});
|
|
31163
31682
|
function resolveBudgetMode(value) {
|
|
@@ -31171,7 +31690,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
31171
31690
|
const budgetMode = resolveBudgetMode(value);
|
|
31172
31691
|
if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
|
|
31173
31692
|
ctx.addIssue({
|
|
31174
|
-
code:
|
|
31693
|
+
code: z133.ZodIssueCode.custom,
|
|
31175
31694
|
path: [
|
|
31176
31695
|
"campaignDailyBudget"
|
|
31177
31696
|
],
|
|
@@ -31182,7 +31701,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
31182
31701
|
value.adSets.forEach((adSet, index) => {
|
|
31183
31702
|
if (adSet.dailyBudget === void 0) {
|
|
31184
31703
|
ctx.addIssue({
|
|
31185
|
-
code:
|
|
31704
|
+
code: z133.ZodIssueCode.custom,
|
|
31186
31705
|
path: [
|
|
31187
31706
|
"adSets",
|
|
31188
31707
|
index,
|
|
@@ -31197,25 +31716,25 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
31197
31716
|
...value,
|
|
31198
31717
|
budgetMode: resolveBudgetMode(value)
|
|
31199
31718
|
}));
|
|
31200
|
-
var PublishCreativesToMetaInputBase =
|
|
31201
|
-
creatives:
|
|
31719
|
+
var PublishCreativesToMetaInputBase = z133.object({
|
|
31720
|
+
creatives: z133.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
|
|
31202
31721
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
31203
|
-
portfolioId:
|
|
31722
|
+
portfolioId: z133.string().trim().min(1),
|
|
31204
31723
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
31205
|
-
pageId:
|
|
31724
|
+
pageId: z133.string().trim().min(1),
|
|
31206
31725
|
adAccountId: McpAdAccountId,
|
|
31207
|
-
pixelId:
|
|
31726
|
+
pixelId: z133.string().min(1).optional(),
|
|
31208
31727
|
/** Required unless `campaignConfig.destination` is whatsapp or a creative
|
|
31209
31728
|
* comes from a task (the API then lands on the published service landing
|
|
31210
31729
|
* of its service tasks) — see the superRefine below. Mirrors the API's
|
|
31211
31730
|
* `FacebookCreateCampaignFromTasksBodySchema`. */
|
|
31212
|
-
landingUrl:
|
|
31731
|
+
landingUrl: z133.string().url().optional(),
|
|
31213
31732
|
/** ISO-2 code or resolvable country name — mirrors the API contract
|
|
31214
31733
|
* (CountryIso2Schema), which normalizes names to alpha-2 at validation.
|
|
31215
31734
|
* Omitted: the brand country of its service tasks (the API answers
|
|
31216
31735
|
* META_NO_TARGET_COUNTRY when it has none); "US" for products. */
|
|
31217
31736
|
targetCountry: CountryIso2Schema.optional(),
|
|
31218
|
-
campaignName:
|
|
31737
|
+
campaignName: z133.string().trim().min(1).max(100),
|
|
31219
31738
|
campaignConfig: GroupedCampaignConfig.optional()
|
|
31220
31739
|
});
|
|
31221
31740
|
var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
|
|
@@ -31223,7 +31742,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
31223
31742
|
const hasTaskCreative = value.creatives.some((creative) => creative.source.type === "task");
|
|
31224
31743
|
if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl && !hasTaskCreative) {
|
|
31225
31744
|
ctx.addIssue({
|
|
31226
|
-
code:
|
|
31745
|
+
code: z133.ZodIssueCode.custom,
|
|
31227
31746
|
path: [
|
|
31228
31747
|
"landingUrl"
|
|
31229
31748
|
],
|
|
@@ -31232,7 +31751,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
31232
31751
|
}
|
|
31233
31752
|
if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
|
|
31234
31753
|
ctx.addIssue({
|
|
31235
|
-
code:
|
|
31754
|
+
code: z133.ZodIssueCode.custom,
|
|
31236
31755
|
path: [
|
|
31237
31756
|
"campaignConfig",
|
|
31238
31757
|
"destination",
|
|
@@ -31251,16 +31770,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
31251
31770
|
}
|
|
31252
31771
|
return value;
|
|
31253
31772
|
});
|
|
31254
|
-
var PresignUploadResponseSchema =
|
|
31255
|
-
uploadUrl:
|
|
31773
|
+
var PresignUploadResponseSchema = z133.object({
|
|
31774
|
+
uploadUrl: z133.string().url().refine((value) => {
|
|
31256
31775
|
const url = new URL(value);
|
|
31257
31776
|
return !url.username && !url.password && url.protocol === "https:";
|
|
31258
31777
|
}, "presigned upload URL must be HTTPS without embedded credentials"),
|
|
31259
|
-
publicUrl:
|
|
31778
|
+
publicUrl: z133.string().url().refine((value) => {
|
|
31260
31779
|
const url = new URL(value);
|
|
31261
31780
|
return !url.username && !url.password;
|
|
31262
31781
|
}, "public media URL must not contain embedded credentials"),
|
|
31263
|
-
stagingAssetId:
|
|
31782
|
+
stagingAssetId: z133.string().uuid()
|
|
31264
31783
|
});
|
|
31265
31784
|
async function uploadResolvedMedia(api, media, assetRole) {
|
|
31266
31785
|
if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
|
|
@@ -31286,14 +31805,14 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
|
|
|
31286
31805
|
}
|
|
31287
31806
|
__name(resolveAndUploadMedia, "resolveAndUploadMedia");
|
|
31288
31807
|
var TikTokMcpCampaignConfig = McpCampaignConfig.extend({
|
|
31289
|
-
dailyBudgetUsd:
|
|
31290
|
-
dailyBudget:
|
|
31808
|
+
dailyBudgetUsd: z133.number().finite().positive().optional().describe("Legacy USD amount, supported only for USD advertiser accounts. No FX conversion."),
|
|
31809
|
+
dailyBudget: z133.number().finite().positive().optional().describe("Daily budget in the selected advertiser currency major units; pass budgetCurrency together."),
|
|
31291
31810
|
budgetCurrency: TikTokBudgetCurrencySchema.optional(),
|
|
31292
31811
|
destination: TikTokCampaignDestinationSchema.optional()
|
|
31293
31812
|
}).superRefine((value, ctx) => {
|
|
31294
31813
|
if (value.dailyBudgetUsd !== void 0 && (value.dailyBudget !== void 0 || value.budgetCurrency !== void 0)) {
|
|
31295
31814
|
ctx.addIssue({
|
|
31296
|
-
code:
|
|
31815
|
+
code: z133.ZodIssueCode.custom,
|
|
31297
31816
|
path: [
|
|
31298
31817
|
"dailyBudgetUsd"
|
|
31299
31818
|
],
|
|
@@ -31302,7 +31821,7 @@ var TikTokMcpCampaignConfig = McpCampaignConfig.extend({
|
|
|
31302
31821
|
}
|
|
31303
31822
|
if (value.dailyBudget !== void 0 !== (value.budgetCurrency !== void 0)) {
|
|
31304
31823
|
ctx.addIssue({
|
|
31305
|
-
code:
|
|
31824
|
+
code: z133.ZodIssueCode.custom,
|
|
31306
31825
|
path: [
|
|
31307
31826
|
"budgetCurrency"
|
|
31308
31827
|
],
|
|
@@ -31310,16 +31829,16 @@ var TikTokMcpCampaignConfig = McpCampaignConfig.extend({
|
|
|
31310
31829
|
});
|
|
31311
31830
|
}
|
|
31312
31831
|
});
|
|
31313
|
-
var TikTokInput =
|
|
31314
|
-
taskId:
|
|
31315
|
-
advertiserId:
|
|
31316
|
-
pixelId:
|
|
31317
|
-
landingUrl:
|
|
31318
|
-
angleIndexes:
|
|
31832
|
+
var TikTokInput = z133.object({
|
|
31833
|
+
taskId: z133.string().min(1),
|
|
31834
|
+
advertiserId: z133.string().min(1),
|
|
31835
|
+
pixelId: z133.string().min(1).optional(),
|
|
31836
|
+
landingUrl: z133.string().url().optional(),
|
|
31837
|
+
angleIndexes: z133.array(z133.number().int().nonnegative()).optional(),
|
|
31319
31838
|
campaignConfig: TikTokMcpCampaignConfig.optional(),
|
|
31320
31839
|
/** Override the ad's description (TikTok's body copy). If omitted,
|
|
31321
31840
|
* ProductMaker uses the auto-generated copy attached to the task. */
|
|
31322
|
-
primaryText:
|
|
31841
|
+
primaryText: z133.string().trim().min(1).max(500).optional()
|
|
31323
31842
|
});
|
|
31324
31843
|
function registerPublishTools(server, api, opts = {}) {
|
|
31325
31844
|
const transport = opts.transport ?? "http";
|
|
@@ -31678,39 +32197,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
|
|
|
31678
32197
|
|
|
31679
32198
|
// src/tools/meta-upload.ts
|
|
31680
32199
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
31681
|
-
import { z as
|
|
32200
|
+
import { z as z134 } from "zod";
|
|
31682
32201
|
var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
|
|
31683
|
-
var UploadSessionInputBase =
|
|
31684
|
-
mediaKind:
|
|
32202
|
+
var UploadSessionInputBase = z134.object({
|
|
32203
|
+
mediaKind: z134.enum([
|
|
31685
32204
|
"image",
|
|
31686
32205
|
"video",
|
|
31687
32206
|
"mixed"
|
|
31688
32207
|
]).default("mixed").describe("The kind of file the user will select. Use image for product references and landing pages, video for a single video, and mixed only when the consumer supports both."),
|
|
31689
|
-
assetRole:
|
|
32208
|
+
assetRole: z134.enum([
|
|
31690
32209
|
"media",
|
|
31691
32210
|
"thumbnail"
|
|
31692
32211
|
]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
|
|
31693
|
-
uploadPurpose:
|
|
32212
|
+
uploadPurpose: z134.enum([
|
|
31694
32213
|
"product_reference",
|
|
31695
32214
|
"creative",
|
|
31696
32215
|
"generic"
|
|
31697
32216
|
]).default("generic").describe("The user's purpose for these files. Use product_reference for a product photo used by tasks or landings, creative for media that will become an ad or creative, and generic only when neither applies."),
|
|
31698
|
-
maxFiles:
|
|
32217
|
+
maxFiles: z134.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
31699
32218
|
});
|
|
31700
|
-
var OpenAiFileReference =
|
|
31701
|
-
download_url:
|
|
31702
|
-
file_id:
|
|
31703
|
-
mime_type:
|
|
31704
|
-
file_name:
|
|
32219
|
+
var OpenAiFileReference = z134.object({
|
|
32220
|
+
download_url: z134.string().url().describe("Required by ChatGPT's openai/fileParams schema. The App prefers getFileDownloadUrl(file_id) for a fresh URL, and the server never fetches this value."),
|
|
32221
|
+
file_id: z134.string().min(1),
|
|
32222
|
+
mime_type: z134.string().min(1).optional(),
|
|
32223
|
+
file_name: z134.string().min(1).optional()
|
|
31705
32224
|
});
|
|
31706
32225
|
var UploadSessionToolInputShape = {
|
|
31707
32226
|
...UploadSessionInputBase.shape,
|
|
31708
|
-
files:
|
|
32227
|
+
files: z134.array(OpenAiFileReference).max(10).optional().describe("Optional OpenAI-hosted file references provided by ChatGPT. They are only metadata for the UI bridge and are never forwarded to ProductMaker.")
|
|
31709
32228
|
};
|
|
31710
|
-
var UploadSessionToolInput =
|
|
32229
|
+
var UploadSessionToolInput = z134.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
31711
32230
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
31712
32231
|
ctx.addIssue({
|
|
31713
|
-
code:
|
|
32232
|
+
code: z134.ZodIssueCode.custom,
|
|
31714
32233
|
path: [
|
|
31715
32234
|
"mediaKind"
|
|
31716
32235
|
],
|
|
@@ -31719,7 +32238,7 @@ var UploadSessionToolInput = z133.object(UploadSessionToolInputShape).superRefin
|
|
|
31719
32238
|
}
|
|
31720
32239
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
31721
32240
|
ctx.addIssue({
|
|
31722
|
-
code:
|
|
32241
|
+
code: z134.ZodIssueCode.custom,
|
|
31723
32242
|
path: [
|
|
31724
32243
|
"maxFiles"
|
|
31725
32244
|
],
|
|
@@ -31728,7 +32247,7 @@ var UploadSessionToolInput = z133.object(UploadSessionToolInputShape).superRefin
|
|
|
31728
32247
|
}
|
|
31729
32248
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
|
|
31730
32249
|
ctx.addIssue({
|
|
31731
|
-
code:
|
|
32250
|
+
code: z134.ZodIssueCode.custom,
|
|
31732
32251
|
path: [
|
|
31733
32252
|
"maxFiles"
|
|
31734
32253
|
],
|
|
@@ -31736,38 +32255,38 @@ var UploadSessionToolInput = z133.object(UploadSessionToolInputShape).superRefin
|
|
|
31736
32255
|
});
|
|
31737
32256
|
}
|
|
31738
32257
|
});
|
|
31739
|
-
var UploadSessionResponse =
|
|
31740
|
-
sessionId:
|
|
31741
|
-
uploadPageUrl:
|
|
31742
|
-
mediaKind:
|
|
32258
|
+
var UploadSessionResponse = z134.object({
|
|
32259
|
+
sessionId: z134.string().uuid(),
|
|
32260
|
+
uploadPageUrl: z134.string().url(),
|
|
32261
|
+
mediaKind: z134.enum([
|
|
31743
32262
|
"image",
|
|
31744
32263
|
"video",
|
|
31745
32264
|
"mixed"
|
|
31746
32265
|
]),
|
|
31747
|
-
assetRole:
|
|
32266
|
+
assetRole: z134.enum([
|
|
31748
32267
|
"media",
|
|
31749
32268
|
"thumbnail"
|
|
31750
32269
|
]),
|
|
31751
|
-
maxFiles:
|
|
31752
|
-
expiresAt:
|
|
32270
|
+
maxFiles: z134.number().int().positive(),
|
|
32271
|
+
expiresAt: z134.string().datetime()
|
|
31753
32272
|
});
|
|
31754
|
-
var UploadStatusInput =
|
|
31755
|
-
sessionId:
|
|
32273
|
+
var UploadStatusInput = z134.object({
|
|
32274
|
+
sessionId: z134.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
31756
32275
|
});
|
|
31757
|
-
var UniversalUploadStatusResponse =
|
|
31758
|
-
|
|
31759
|
-
status:
|
|
31760
|
-
assets:
|
|
32276
|
+
var UniversalUploadStatusResponse = z134.discriminatedUnion("status", [
|
|
32277
|
+
z134.object({
|
|
32278
|
+
status: z134.literal("pending"),
|
|
32279
|
+
assets: z134.array(z134.never()).length(0)
|
|
31761
32280
|
}),
|
|
31762
|
-
|
|
31763
|
-
status:
|
|
31764
|
-
assets:
|
|
31765
|
-
assetId:
|
|
31766
|
-
mediaKind:
|
|
32281
|
+
z134.object({
|
|
32282
|
+
status: z134.literal("uploaded"),
|
|
32283
|
+
assets: z134.array(z134.object({
|
|
32284
|
+
assetId: z134.string().uuid(),
|
|
32285
|
+
mediaKind: z134.enum([
|
|
31767
32286
|
"image",
|
|
31768
32287
|
"video"
|
|
31769
32288
|
]),
|
|
31770
|
-
assetRole:
|
|
32289
|
+
assetRole: z134.enum([
|
|
31771
32290
|
"media",
|
|
31772
32291
|
"thumbnail"
|
|
31773
32292
|
])
|
|
@@ -31775,13 +32294,13 @@ var UniversalUploadStatusResponse = z133.discriminatedUnion("status", [
|
|
|
31775
32294
|
})
|
|
31776
32295
|
]);
|
|
31777
32296
|
var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
|
|
31778
|
-
uploadPurpose:
|
|
32297
|
+
uploadPurpose: z134.enum([
|
|
31779
32298
|
"product_reference",
|
|
31780
32299
|
"creative",
|
|
31781
32300
|
"generic"
|
|
31782
32301
|
]),
|
|
31783
|
-
checkToolName:
|
|
31784
|
-
resolveEndpoint:
|
|
32302
|
+
checkToolName: z134.literal("check_media_upload"),
|
|
32303
|
+
resolveEndpoint: z134.string().url()
|
|
31785
32304
|
});
|
|
31786
32305
|
function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
|
|
31787
32306
|
const url = new URL(uploadPageUrl);
|
|
@@ -31872,15 +32391,15 @@ function registerMediaUploadTools(server, api) {
|
|
|
31872
32391
|
__name(registerMediaUploadTools, "registerMediaUploadTools");
|
|
31873
32392
|
|
|
31874
32393
|
// src/tools/campaigns.ts
|
|
31875
|
-
import { z as
|
|
32394
|
+
import { z as z135 } from "zod";
|
|
31876
32395
|
var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
|
|
31877
32396
|
var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
|
|
31878
|
-
var MetaStatusInput =
|
|
31879
|
-
campaignId:
|
|
32397
|
+
var MetaStatusInput = z135.object({
|
|
32398
|
+
campaignId: z135.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
|
|
31880
32399
|
});
|
|
31881
|
-
var TikTokStatusInput =
|
|
31882
|
-
campaignId:
|
|
31883
|
-
advertiserId:
|
|
32400
|
+
var TikTokStatusInput = z135.object({
|
|
32401
|
+
campaignId: z135.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
|
|
32402
|
+
advertiserId: z135.string().min(1).describe("The same advertiserId used to publish the campaign.")
|
|
31884
32403
|
});
|
|
31885
32404
|
function registerCampaignTools(server, api) {
|
|
31886
32405
|
server.registerTool("get_meta_campaign_status", {
|
|
@@ -31985,10 +32504,10 @@ function renderTikTokStatusMarkdown(r) {
|
|
|
31985
32504
|
__name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
|
|
31986
32505
|
|
|
31987
32506
|
// ../../packages/product-economics/src/product-costing.ts
|
|
31988
|
-
import { z as
|
|
32507
|
+
import { z as z137 } from "zod";
|
|
31989
32508
|
|
|
31990
32509
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
31991
|
-
import { z as
|
|
32510
|
+
import { z as z136 } from "zod";
|
|
31992
32511
|
|
|
31993
32512
|
// ../../packages/product-economics/src/product-costing-shipping-references.json
|
|
31994
32513
|
var product_costing_shipping_references_default = {
|
|
@@ -32052,21 +32571,21 @@ var product_costing_shipping_references_default = {
|
|
|
32052
32571
|
};
|
|
32053
32572
|
|
|
32054
32573
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
32055
|
-
var ShippingReferenceSchema =
|
|
32056
|
-
reference:
|
|
32057
|
-
min:
|
|
32058
|
-
max:
|
|
32059
|
-
updatedAt:
|
|
32060
|
-
confidence:
|
|
32574
|
+
var ShippingReferenceSchema = z136.object({
|
|
32575
|
+
reference: z136.number().positive(),
|
|
32576
|
+
min: z136.number().nonnegative(),
|
|
32577
|
+
max: z136.number().positive(),
|
|
32578
|
+
updatedAt: z136.string().date(),
|
|
32579
|
+
confidence: z136.enum([
|
|
32061
32580
|
"high",
|
|
32062
32581
|
"medium",
|
|
32063
32582
|
"medium-low"
|
|
32064
32583
|
]),
|
|
32065
|
-
sources:
|
|
32584
|
+
sources: z136.array(z136.string().url().startsWith("https://")).min(1).max(3)
|
|
32066
32585
|
}).superRefine(({ reference, min, max }, context) => {
|
|
32067
32586
|
if (min > reference || reference > max) {
|
|
32068
32587
|
context.addIssue({
|
|
32069
|
-
code:
|
|
32588
|
+
code: z136.ZodIssueCode.custom,
|
|
32070
32589
|
message: "shipping_reference_outside_range",
|
|
32071
32590
|
path: [
|
|
32072
32591
|
"reference"
|
|
@@ -32074,7 +32593,7 @@ var ShippingReferenceSchema = z135.object({
|
|
|
32074
32593
|
});
|
|
32075
32594
|
}
|
|
32076
32595
|
});
|
|
32077
|
-
var SHIPPING_REFERENCES =
|
|
32596
|
+
var SHIPPING_REFERENCES = z136.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
|
|
32078
32597
|
var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
|
|
32079
32598
|
var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
|
|
32080
32599
|
"MX",
|
|
@@ -32256,18 +32775,18 @@ function getProductCostingCountryName(country) {
|
|
|
32256
32775
|
__name(getProductCostingCountryName, "getProductCostingCountryName");
|
|
32257
32776
|
|
|
32258
32777
|
// ../../packages/product-economics/src/product-costing.ts
|
|
32259
|
-
var ProductCostingInputSchema =
|
|
32260
|
-
country:
|
|
32261
|
-
supplierCost:
|
|
32262
|
-
shippingCost:
|
|
32263
|
-
returnRate:
|
|
32264
|
-
cancellationRate:
|
|
32265
|
-
adsManagerCpa:
|
|
32266
|
-
desiredMargin:
|
|
32778
|
+
var ProductCostingInputSchema = z137.object({
|
|
32779
|
+
country: z137.string().refine(isProductCostingCountryCode, "unsupported_country"),
|
|
32780
|
+
supplierCost: z137.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
|
|
32781
|
+
shippingCost: z137.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
|
|
32782
|
+
returnRate: z137.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
32783
|
+
cancellationRate: z137.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
32784
|
+
adsManagerCpa: z137.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
|
|
32785
|
+
desiredMargin: z137.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
|
|
32267
32786
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
32268
32787
|
if (returnRate + cancellationRate >= 1) {
|
|
32269
32788
|
context.addIssue({
|
|
32270
|
-
code:
|
|
32789
|
+
code: z137.ZodIssueCode.custom,
|
|
32271
32790
|
message: "delivery_rate_positive",
|
|
32272
32791
|
path: [
|
|
32273
32792
|
"cancellationRate"
|
|
@@ -32364,15 +32883,15 @@ function calculateProductCosting(rawInput) {
|
|
|
32364
32883
|
__name(calculateProductCosting, "calculateProductCosting");
|
|
32365
32884
|
|
|
32366
32885
|
// src/tools/product-costing.ts
|
|
32367
|
-
import { z as
|
|
32886
|
+
import { z as z138 } from "zod";
|
|
32368
32887
|
var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
|
|
32369
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
32370
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
32371
|
-
var ProductCostingToolInput =
|
|
32372
|
-
country:
|
|
32888
|
+
var optionalAmount = /* @__PURE__ */ __name((description) => z138.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
|
|
32889
|
+
var optionalPercent = /* @__PURE__ */ __name((description) => z138.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
|
|
32890
|
+
var ProductCostingToolInput = z138.object({
|
|
32891
|
+
country: z138.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
32373
32892
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
32374
32893
|
}).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
|
|
32375
|
-
supplierCost:
|
|
32894
|
+
supplierCost: z138.number().finite().max(Number.MAX_SAFE_INTEGER).positive().optional().describe("Costo real de una unidad con el proveedor, en la moneda del pa\xEDs. Requerido salvo que uses supplierCostCop para Colombia."),
|
|
32376
32895
|
supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
|
|
32377
32896
|
shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
|
|
32378
32897
|
shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
|
|
@@ -32535,7 +33054,7 @@ function formatPercent(value) {
|
|
|
32535
33054
|
__name(formatPercent, "formatPercent");
|
|
32536
33055
|
|
|
32537
33056
|
// src/tools/product-research.ts
|
|
32538
|
-
import { z as
|
|
33057
|
+
import { z as z139 } from "zod";
|
|
32539
33058
|
|
|
32540
33059
|
// src/tools/product-research-idempotency.ts
|
|
32541
33060
|
var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
|
|
@@ -32906,17 +33425,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
|
|
|
32906
33425
|
]);
|
|
32907
33426
|
var POLL_INTERVAL_MS = 5e3;
|
|
32908
33427
|
var MAX_WAIT_SECONDS = 120;
|
|
32909
|
-
var FindInput =
|
|
33428
|
+
var FindInput = z139.object({
|
|
32910
33429
|
targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
|
|
32911
33430
|
categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
|
|
32912
|
-
confirmed:
|
|
32913
|
-
waitSeconds:
|
|
33431
|
+
confirmed: z139.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
|
|
33432
|
+
waitSeconds: z139.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
|
|
32914
33433
|
});
|
|
32915
|
-
var GetInput =
|
|
32916
|
-
runId:
|
|
33434
|
+
var GetInput = z139.object({
|
|
33435
|
+
runId: z139.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
32917
33436
|
});
|
|
32918
|
-
var ListInput =
|
|
32919
|
-
limit:
|
|
33437
|
+
var ListInput = z139.object({
|
|
33438
|
+
limit: z139.number().int().min(1).max(20).default(10)
|
|
32920
33439
|
});
|
|
32921
33440
|
function textResult(text3) {
|
|
32922
33441
|
return {
|
|
@@ -33055,17 +33574,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
33055
33574
|
__name(registerProductResearchTools, "registerProductResearchTools");
|
|
33056
33575
|
|
|
33057
33576
|
// src/tools/dropshipping-projects.ts
|
|
33058
|
-
import { z as
|
|
33577
|
+
import { z as z140 } from "zod";
|
|
33059
33578
|
var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
|
|
33060
33579
|
var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
|
|
33061
33580
|
var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
|
|
33062
|
-
var ProjectId =
|
|
33063
|
-
var DropshippingProjectStatus =
|
|
33581
|
+
var ProjectId = z140.string().uuid();
|
|
33582
|
+
var DropshippingProjectStatus = z140.enum([
|
|
33064
33583
|
"active",
|
|
33065
33584
|
"completed",
|
|
33066
33585
|
"archived"
|
|
33067
33586
|
]);
|
|
33068
|
-
var DropshippingProjectPhase =
|
|
33587
|
+
var DropshippingProjectPhase = z140.enum([
|
|
33069
33588
|
"research",
|
|
33070
33589
|
"costing",
|
|
33071
33590
|
"media",
|
|
@@ -33074,21 +33593,21 @@ var DropshippingProjectPhase = z139.enum([
|
|
|
33074
33593
|
"advertising",
|
|
33075
33594
|
"complete"
|
|
33076
33595
|
]);
|
|
33077
|
-
var DropshippingRewardMilestone =
|
|
33596
|
+
var DropshippingRewardMilestone = z140.enum([
|
|
33078
33597
|
"product_selected",
|
|
33079
33598
|
"costing_saved",
|
|
33080
33599
|
"product_media_ready",
|
|
33081
33600
|
"creatives_completed",
|
|
33082
33601
|
"campaign_created"
|
|
33083
33602
|
]);
|
|
33084
|
-
var TargetCountry =
|
|
33603
|
+
var TargetCountry = z140.enum([
|
|
33085
33604
|
"CO",
|
|
33086
33605
|
"MX",
|
|
33087
33606
|
"PE",
|
|
33088
33607
|
"EC",
|
|
33089
33608
|
"CL"
|
|
33090
33609
|
]);
|
|
33091
|
-
var ResearchCategory =
|
|
33610
|
+
var ResearchCategory = z140.enum([
|
|
33092
33611
|
"auto",
|
|
33093
33612
|
"automotive",
|
|
33094
33613
|
"kitchen",
|
|
@@ -33103,7 +33622,7 @@ var ResearchCategory = z139.enum([
|
|
|
33103
33622
|
"garden",
|
|
33104
33623
|
"cleaning"
|
|
33105
33624
|
]);
|
|
33106
|
-
var HttpUrl3 =
|
|
33625
|
+
var HttpUrl3 = z140.string().url().max(2e3).refine((value) => {
|
|
33107
33626
|
try {
|
|
33108
33627
|
return [
|
|
33109
33628
|
"http:",
|
|
@@ -33113,45 +33632,45 @@ var HttpUrl3 = z139.string().url().max(2e3).refine((value) => {
|
|
|
33113
33632
|
return false;
|
|
33114
33633
|
}
|
|
33115
33634
|
}, "URL must use HTTP(S)");
|
|
33116
|
-
var ResearchCandidateOrigin =
|
|
33117
|
-
type:
|
|
33635
|
+
var ResearchCandidateOrigin = z140.object({
|
|
33636
|
+
type: z140.literal("research_candidate"),
|
|
33118
33637
|
runId: ProjectId,
|
|
33119
|
-
candidateSourceId:
|
|
33638
|
+
candidateSourceId: z140.string().min(1).max(160)
|
|
33120
33639
|
});
|
|
33121
|
-
var TaskOrigin =
|
|
33122
|
-
type:
|
|
33640
|
+
var TaskOrigin = z140.object({
|
|
33641
|
+
type: z140.literal("task"),
|
|
33123
33642
|
taskId: ProjectId
|
|
33124
33643
|
});
|
|
33125
|
-
var ManualOrigin =
|
|
33126
|
-
type:
|
|
33644
|
+
var ManualOrigin = z140.object({
|
|
33645
|
+
type: z140.literal("manual"),
|
|
33127
33646
|
clientRequestId: ProjectId,
|
|
33128
|
-
country:
|
|
33647
|
+
country: z140.string().min(2).max(3).optional()
|
|
33129
33648
|
});
|
|
33130
|
-
var StartProjectInput =
|
|
33131
|
-
origin:
|
|
33649
|
+
var StartProjectInput = z140.object({
|
|
33650
|
+
origin: z140.discriminatedUnion("type", [
|
|
33132
33651
|
ResearchCandidateOrigin,
|
|
33133
33652
|
TaskOrigin,
|
|
33134
33653
|
ManualOrigin
|
|
33135
33654
|
]),
|
|
33136
|
-
productName:
|
|
33655
|
+
productName: z140.string().trim().min(1).max(240).optional(),
|
|
33137
33656
|
productUrl: HttpUrl3.optional(),
|
|
33138
|
-
country:
|
|
33139
|
-
languageCode:
|
|
33657
|
+
country: z140.string().min(2).max(3).optional(),
|
|
33658
|
+
languageCode: z140.string().min(2).max(16).optional()
|
|
33140
33659
|
}).strict();
|
|
33141
|
-
var CostProjectInput =
|
|
33660
|
+
var CostProjectInput = z140.object({
|
|
33142
33661
|
projectId: ProjectId,
|
|
33143
|
-
version:
|
|
33144
|
-
country:
|
|
33662
|
+
version: z140.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
|
|
33663
|
+
country: z140.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
33145
33664
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
33146
33665
|
}).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
|
|
33147
|
-
supplierCost:
|
|
33148
|
-
shippingCost:
|
|
33149
|
-
returnRate:
|
|
33150
|
-
cancellationRate:
|
|
33151
|
-
adsManagerCpa:
|
|
33152
|
-
desiredMargin:
|
|
33153
|
-
});
|
|
33154
|
-
var GuideInput =
|
|
33666
|
+
supplierCost: z140.number().finite().positive().describe("Costo real de una unidad con el proveedor, en la moneda del pa\xEDs. \xDANICO dato que debes pedirle al usuario: nunca lo inventes."),
|
|
33667
|
+
shippingCost: z140.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
|
|
33668
|
+
returnRate: z140.number().finite().min(0).lt(1).optional().describe("Fracci\xF3n de pedidos devueltos (0.25 = 25%). Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
33669
|
+
cancellationRate: z140.number().finite().min(0).lt(1).optional().describe("Fracci\xF3n de pedidos cancelados (0.15 = 15%). Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
33670
|
+
adsManagerCpa: z140.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
33671
|
+
desiredMargin: z140.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
|
|
33672
|
+
});
|
|
33673
|
+
var GuideInput = z140.object({
|
|
33155
33674
|
projectId: ProjectId.optional()
|
|
33156
33675
|
}).strict();
|
|
33157
33676
|
var NEXT_ACTION_KINDS = [
|
|
@@ -33169,29 +33688,29 @@ var NEXT_ACTION_KINDS = [
|
|
|
33169
33688
|
"repair_meta_campaign",
|
|
33170
33689
|
"review_paused_campaign"
|
|
33171
33690
|
];
|
|
33172
|
-
var DropshippingProjectNextAction =
|
|
33173
|
-
kind:
|
|
33174
|
-
href:
|
|
33691
|
+
var DropshippingProjectNextAction = z140.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z140.object({
|
|
33692
|
+
kind: z140.literal(kind),
|
|
33693
|
+
href: z140.string().min(1)
|
|
33175
33694
|
})));
|
|
33176
|
-
var CostingInputSchema =
|
|
33177
|
-
country:
|
|
33178
|
-
supplierCost:
|
|
33179
|
-
shippingCost:
|
|
33180
|
-
returnRate:
|
|
33181
|
-
cancellationRate:
|
|
33182
|
-
adsManagerCpa:
|
|
33183
|
-
desiredMargin:
|
|
33695
|
+
var CostingInputSchema = z140.object({
|
|
33696
|
+
country: z140.string().min(2).max(3),
|
|
33697
|
+
supplierCost: z140.number().finite().positive(),
|
|
33698
|
+
shippingCost: z140.number().finite().nonnegative(),
|
|
33699
|
+
returnRate: z140.number().finite().min(0).lt(1),
|
|
33700
|
+
cancellationRate: z140.number().finite().min(0).lt(1),
|
|
33701
|
+
adsManagerCpa: z140.number().finite().nonnegative(),
|
|
33702
|
+
desiredMargin: z140.number().finite().min(0).lt(1)
|
|
33184
33703
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
33185
33704
|
if (returnRate + cancellationRate >= 1) context.addIssue({
|
|
33186
|
-
code:
|
|
33705
|
+
code: z140.ZodIssueCode.custom,
|
|
33187
33706
|
path: [
|
|
33188
33707
|
"cancellationRate"
|
|
33189
33708
|
]
|
|
33190
33709
|
});
|
|
33191
33710
|
});
|
|
33192
|
-
var FiniteCostingNumber =
|
|
33193
|
-
var CostingResultSchema =
|
|
33194
|
-
country:
|
|
33711
|
+
var FiniteCostingNumber = z140.number().finite();
|
|
33712
|
+
var CostingResultSchema = z140.object({
|
|
33713
|
+
country: z140.string().min(2).max(3),
|
|
33195
33714
|
deliveryRate: FiniteCostingNumber,
|
|
33196
33715
|
adjustedShippingCost: FiniteCostingNumber,
|
|
33197
33716
|
adjustedCpa: FiniteCostingNumber,
|
|
@@ -33204,45 +33723,45 @@ var CostingResultSchema = z139.object({
|
|
|
33204
33723
|
estimatedProfit: FiniteCostingNumber,
|
|
33205
33724
|
actualMargin: FiniteCostingNumber,
|
|
33206
33725
|
breakEvenAdsManagerCpa: FiniteCostingNumber,
|
|
33207
|
-
wasPriceAutoAdjusted:
|
|
33208
|
-
profitabilityStatus:
|
|
33209
|
-
});
|
|
33210
|
-
var RewardProgressSchema =
|
|
33211
|
-
campaignKey:
|
|
33212
|
-
totalCredits:
|
|
33213
|
-
earnedCredits:
|
|
33214
|
-
milestones:
|
|
33726
|
+
wasPriceAutoAdjusted: z140.boolean(),
|
|
33727
|
+
profitabilityStatus: z140.literal("healthy")
|
|
33728
|
+
});
|
|
33729
|
+
var RewardProgressSchema = z140.object({
|
|
33730
|
+
campaignKey: z140.literal("dropshipping-launch-v1"),
|
|
33731
|
+
totalCredits: z140.number().int().positive(),
|
|
33732
|
+
earnedCredits: z140.number().int().nonnegative(),
|
|
33733
|
+
milestones: z140.array(z140.object({
|
|
33215
33734
|
milestone: DropshippingRewardMilestone,
|
|
33216
|
-
credits:
|
|
33217
|
-
available:
|
|
33218
|
-
earned:
|
|
33735
|
+
credits: z140.number().int().positive(),
|
|
33736
|
+
available: z140.boolean().optional(),
|
|
33737
|
+
earned: z140.boolean(),
|
|
33219
33738
|
grantId: ProjectId.nullable(),
|
|
33220
|
-
grantedAt:
|
|
33739
|
+
grantedAt: z140.string().datetime().nullable()
|
|
33221
33740
|
})).length(DropshippingRewardMilestone.options.length)
|
|
33222
33741
|
});
|
|
33223
|
-
var ProjectResponseSchema =
|
|
33742
|
+
var ProjectResponseSchema = z140.object({
|
|
33224
33743
|
id: ProjectId,
|
|
33225
33744
|
taskId: ProjectId.nullable(),
|
|
33226
33745
|
status: DropshippingProjectStatus,
|
|
33227
|
-
originKey:
|
|
33746
|
+
originKey: z140.string().min(1),
|
|
33228
33747
|
researchRunId: ProjectId.nullable(),
|
|
33229
|
-
candidateSourceId:
|
|
33230
|
-
productName:
|
|
33748
|
+
candidateSourceId: z140.string().nullable(),
|
|
33749
|
+
productName: z140.string().nullable(),
|
|
33231
33750
|
productUrl: HttpUrl3.nullable(),
|
|
33232
33751
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
33233
|
-
targetCountry:
|
|
33234
|
-
languageCode:
|
|
33235
|
-
hasReferenceImage:
|
|
33236
|
-
hasWinnerReferenceImage:
|
|
33752
|
+
targetCountry: z140.string().nullable(),
|
|
33753
|
+
languageCode: z140.string().nullable(),
|
|
33754
|
+
hasReferenceImage: z140.boolean(),
|
|
33755
|
+
hasWinnerReferenceImage: z140.boolean(),
|
|
33237
33756
|
costingInput: CostingInputSchema.nullable(),
|
|
33238
33757
|
costingResult: CostingResultSchema.nullable(),
|
|
33239
|
-
costingVersion:
|
|
33240
|
-
version:
|
|
33758
|
+
costingVersion: z140.number().int().positive().nullable(),
|
|
33759
|
+
version: z140.number().int().positive(),
|
|
33241
33760
|
phase: DropshippingProjectPhase,
|
|
33242
33761
|
nextAction: DropshippingProjectNextAction.nullable(),
|
|
33243
33762
|
rewards: RewardProgressSchema,
|
|
33244
|
-
createdAt:
|
|
33245
|
-
updatedAt:
|
|
33763
|
+
createdAt: z140.string().datetime(),
|
|
33764
|
+
updatedAt: z140.string().datetime()
|
|
33246
33765
|
}).passthrough();
|
|
33247
33766
|
var NEXT_ACTION_GUIDANCE = {
|
|
33248
33767
|
cost_product: "Llama `cost_dropshipping_project` con el costo real del proveedor. Nunca lo inventes: p\xEDdeselo al usuario. Es el \xDANICO dato que debes pedirle: omite env\xEDo, devoluciones, cancelaciones, CPA y margen para que ProductMaker use los valores gu\xEDa del pa\xEDs, y luego dile al usuario cu\xE1les us\xF3 por si quiere corregirlos.",
|
|
@@ -33362,58 +33881,58 @@ function registerDropshippingProjectTools(server, api) {
|
|
|
33362
33881
|
__name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
|
|
33363
33882
|
|
|
33364
33883
|
// src/tools/daily-control.ts
|
|
33365
|
-
import { z as
|
|
33884
|
+
import { z as z141 } from "zod";
|
|
33366
33885
|
var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
|
|
33367
33886
|
var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
|
|
33368
33887
|
var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
|
|
33369
|
-
var ProviderCampaignIdentifier =
|
|
33370
|
-
var DateOnly =
|
|
33371
|
-
var DailyControlInput =
|
|
33888
|
+
var ProviderCampaignIdentifier = z141.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
|
|
33889
|
+
var DateOnly = z141.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
33890
|
+
var DailyControlInput = z141.object({
|
|
33372
33891
|
date: DateOnly.optional().describe("D\xEDa final de la ventana (YYYY-MM-DD). Si se omite, la ventana termina AYER en UTC \u2014 nunca hoy, porque el d\xEDa en curso est\xE1 incompleto \u2014 y el servidor puede correrla un d\xEDa m\xE1s atr\xE1s si en la zona horaria de la tienda ese d\xEDa todav\xEDa no ha cerrado."),
|
|
33373
|
-
days:
|
|
33374
|
-
projectId:
|
|
33892
|
+
days: z141.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
33893
|
+
projectId: z141.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
|
|
33375
33894
|
}).strict();
|
|
33376
|
-
var LinkCampaignInput =
|
|
33377
|
-
projectId:
|
|
33378
|
-
provider:
|
|
33895
|
+
var LinkCampaignInput = z141.object({
|
|
33896
|
+
projectId: z141.string().uuid(),
|
|
33897
|
+
provider: z141.enum([
|
|
33379
33898
|
"meta",
|
|
33380
33899
|
"tiktok"
|
|
33381
33900
|
]),
|
|
33382
33901
|
accountId: ProviderCampaignIdentifier.describe("Cuenta publicitaria del proveedor. Para Meta el servidor la IGNORA y deriva la cuenta real de la campa\xF1a \u2014 se sigue pidiendo aqu\xED solo porque TikTok s\xED la necesita para resolver la campa\xF1a."),
|
|
33383
33902
|
campaignId: ProviderCampaignIdentifier
|
|
33384
33903
|
}).strict();
|
|
33385
|
-
var ReportReturnsInput =
|
|
33386
|
-
projectId:
|
|
33904
|
+
var ReportReturnsInput = z141.object({
|
|
33905
|
+
projectId: z141.string().uuid(),
|
|
33387
33906
|
date: DateOnly,
|
|
33388
|
-
returnedOrders:
|
|
33389
|
-
note:
|
|
33390
|
-
}).strict();
|
|
33391
|
-
var DailyControlStatusMirror = DailyControlStatusEnum.or(
|
|
33392
|
-
var DailyControlLightMirror = DailyControlLightEnum.or(
|
|
33393
|
-
var DailyControlSourceMirror = DailyControlSourceEnum.or(
|
|
33394
|
-
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(
|
|
33395
|
-
var DailyControlDayMirror =
|
|
33396
|
-
date:
|
|
33397
|
-
returnedOrders:
|
|
33907
|
+
returnedOrders: z141.number().int().min(0).max(1e5),
|
|
33908
|
+
note: z141.string().trim().max(280).optional()
|
|
33909
|
+
}).strict();
|
|
33910
|
+
var DailyControlStatusMirror = DailyControlStatusEnum.or(z141.string());
|
|
33911
|
+
var DailyControlLightMirror = DailyControlLightEnum.or(z141.string());
|
|
33912
|
+
var DailyControlSourceMirror = DailyControlSourceEnum.or(z141.string());
|
|
33913
|
+
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z141.string());
|
|
33914
|
+
var DailyControlDayMirror = z141.object({
|
|
33915
|
+
date: z141.string(),
|
|
33916
|
+
returnedOrders: z141.number(),
|
|
33398
33917
|
returnedSource: DailyControlSourceMirror,
|
|
33399
33918
|
cancelledSource: DailyControlSourceMirror,
|
|
33400
|
-
hasEstimates:
|
|
33919
|
+
hasEstimates: z141.boolean(),
|
|
33401
33920
|
light: DailyControlLightMirror
|
|
33402
33921
|
}).passthrough();
|
|
33403
|
-
var DailyControlProductMirror =
|
|
33404
|
-
projectId:
|
|
33405
|
-
productName:
|
|
33922
|
+
var DailyControlProductMirror = z141.object({
|
|
33923
|
+
projectId: z141.string().uuid(),
|
|
33924
|
+
productName: z141.string().nullable(),
|
|
33406
33925
|
status: DailyControlStatusMirror,
|
|
33407
|
-
statusMessage:
|
|
33408
|
-
days:
|
|
33926
|
+
statusMessage: z141.string().nullable(),
|
|
33927
|
+
days: z141.array(DailyControlDayMirror),
|
|
33409
33928
|
verdict: DailyControlVerdictMirror.nullable(),
|
|
33410
|
-
rationale:
|
|
33929
|
+
rationale: z141.string().nullable()
|
|
33411
33930
|
}).passthrough();
|
|
33412
|
-
var DailyControlResponseMirror =
|
|
33413
|
-
since:
|
|
33414
|
-
until:
|
|
33415
|
-
products:
|
|
33416
|
-
archivedProjectSpend:
|
|
33931
|
+
var DailyControlResponseMirror = z141.object({
|
|
33932
|
+
since: z141.string(),
|
|
33933
|
+
until: z141.string(),
|
|
33934
|
+
products: z141.array(DailyControlProductMirror),
|
|
33935
|
+
archivedProjectSpend: z141.array(z141.unknown())
|
|
33417
33936
|
}).passthrough();
|
|
33418
33937
|
var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
|
|
33419
33938
|
function withWarnings(response) {
|
|
@@ -33488,7 +34007,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
|
|
|
33488
34007
|
// src/tools/product-control.ts
|
|
33489
34008
|
import { readFile, stat } from "fs/promises";
|
|
33490
34009
|
import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
|
|
33491
|
-
import { z as
|
|
34010
|
+
import { z as z142 } from "zod";
|
|
33492
34011
|
var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
|
|
33493
34012
|
var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
|
|
33494
34013
|
var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
|
|
@@ -33501,36 +34020,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
|
|
|
33501
34020
|
var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
|
|
33502
34021
|
var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
|
|
33503
34022
|
var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
|
|
33504
|
-
var DateOnly2 =
|
|
34023
|
+
var DateOnly2 = z142.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
33505
34024
|
var IMPORT_BATCH_MAX2 = 50;
|
|
33506
|
-
var ProductControlListInput =
|
|
33507
|
-
days:
|
|
34025
|
+
var ProductControlListInput = z142.object({
|
|
34026
|
+
days: z142.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
33508
34027
|
date: DateOnly2.optional().describe("D\xEDa final de la ventana (YYYY-MM-DD). Si se omite, termina en el \xFAltimo d\xEDa cerrado \u2014 nunca hoy, que est\xE1 incompleto."),
|
|
33509
|
-
shopDomain:
|
|
34028
|
+
shopDomain: z142.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
33510
34029
|
}).strict();
|
|
33511
|
-
var ImportableProductsInput =
|
|
33512
|
-
q:
|
|
33513
|
-
after:
|
|
33514
|
-
shopDomain:
|
|
34030
|
+
var ImportableProductsInput = z142.object({
|
|
34031
|
+
q: z142.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
|
|
34032
|
+
after: z142.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
|
|
34033
|
+
shopDomain: z142.string().min(1).optional()
|
|
33515
34034
|
}).strict();
|
|
33516
|
-
var ImportProductControlsInput =
|
|
33517
|
-
shopifyProductIds:
|
|
34035
|
+
var ImportProductControlsInput = z142.object({
|
|
34036
|
+
shopifyProductIds: z142.array(z142.string().min(1).max(64)).min(1).max(IMPORT_BATCH_MAX2).describe("Identificadores tal como vinieron de list_importable_products. NO los inventes ni los deduzcas del t\xEDtulo."),
|
|
33518
34037
|
// Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
|
|
33519
34038
|
// sin decir a cuál archivaría el producto bajo la tienda equivocada.
|
|
33520
|
-
shopDomain:
|
|
33521
|
-
}).strict();
|
|
33522
|
-
var SetProductCostingInput =
|
|
33523
|
-
shopDomain:
|
|
33524
|
-
shopifyProductId:
|
|
33525
|
-
targetCountry:
|
|
33526
|
-
supplierCost:
|
|
33527
|
-
shippingCost:
|
|
33528
|
-
returnRate:
|
|
33529
|
-
cancellationRate:
|
|
33530
|
-
}).strict();
|
|
33531
|
-
var Count =
|
|
33532
|
-
var ReportProductCountsInput =
|
|
33533
|
-
productControlId:
|
|
34039
|
+
shopDomain: z142.string().min(1)
|
|
34040
|
+
}).strict();
|
|
34041
|
+
var SetProductCostingInput = z142.object({
|
|
34042
|
+
shopDomain: z142.string().min(1),
|
|
34043
|
+
shopifyProductId: z142.string().min(1).max(64),
|
|
34044
|
+
targetCountry: z142.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
|
|
34045
|
+
supplierCost: z142.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
|
|
34046
|
+
shippingCost: z142.number().finite().nonnegative(),
|
|
34047
|
+
returnRate: z142.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
|
|
34048
|
+
cancellationRate: z142.number().finite().min(0).lt(1)
|
|
34049
|
+
}).strict();
|
|
34050
|
+
var Count = z142.number().int().min(0).max(1e5).nullable().optional();
|
|
34051
|
+
var ReportProductCountsInput = z142.object({
|
|
34052
|
+
productControlId: z142.string().uuid().describe("El identificador que devuelve get_product_control."),
|
|
33534
34053
|
date: DateOnly2,
|
|
33535
34054
|
orders: Count.describe("Pedidos que entraron ese d\xEDa."),
|
|
33536
34055
|
cancelledOrders: Count,
|
|
@@ -33540,36 +34059,36 @@ var ReportProductCountsInput = z141.object({
|
|
|
33540
34059
|
}).strict();
|
|
33541
34060
|
var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
|
|
33542
34061
|
var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
|
|
33543
|
-
var ImportOrdersFileInput =
|
|
34062
|
+
var ImportOrdersFileInput = z142.object({
|
|
33544
34063
|
/** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
|
|
33545
|
-
path:
|
|
33546
|
-
operationId:
|
|
34064
|
+
path: z142.string().min(1),
|
|
34065
|
+
operationId: z142.string().uuid().optional(),
|
|
33547
34066
|
/** Solo mirar: devuelve el resumen y no escribe nada. */
|
|
33548
|
-
dryRun:
|
|
34067
|
+
dryRun: z142.boolean().optional()
|
|
33549
34068
|
}).strict();
|
|
33550
|
-
var CreateOperationInput =
|
|
33551
|
-
countryCode:
|
|
33552
|
-
label:
|
|
34069
|
+
var CreateOperationInput = z142.object({
|
|
34070
|
+
countryCode: z142.string().length(2),
|
|
34071
|
+
label: z142.string().trim().min(1).max(60).optional()
|
|
33553
34072
|
}).strict();
|
|
33554
|
-
var MergeProductsInput =
|
|
33555
|
-
sourceId:
|
|
33556
|
-
targetId:
|
|
34073
|
+
var MergeProductsInput = z142.object({
|
|
34074
|
+
sourceId: z142.string().uuid(),
|
|
34075
|
+
targetId: z142.string().uuid()
|
|
33557
34076
|
}).strict();
|
|
33558
|
-
var SetMonthlyExpenseInput =
|
|
33559
|
-
month:
|
|
34077
|
+
var SetMonthlyExpenseInput = z142.object({
|
|
34078
|
+
month: z142.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
33560
34079
|
label: SaveMonthlyExpenseSchema.shape.label,
|
|
33561
|
-
amount:
|
|
33562
|
-
operationId:
|
|
34080
|
+
amount: z142.number().finite().min(0),
|
|
34081
|
+
operationId: z142.string().uuid().optional()
|
|
33563
34082
|
}).strict();
|
|
33564
|
-
var SetAdSpendInput =
|
|
33565
|
-
month:
|
|
33566
|
-
operationId:
|
|
34083
|
+
var SetAdSpendInput = z142.object({
|
|
34084
|
+
month: z142.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
34085
|
+
operationId: z142.string().uuid().optional(),
|
|
33567
34086
|
/** null RETIRA la corrección; cero afirma que no pautó. */
|
|
33568
|
-
amount:
|
|
34087
|
+
amount: z142.number().finite().min(0).nullable()
|
|
33569
34088
|
}).strict();
|
|
33570
|
-
var GetFinancesInput =
|
|
33571
|
-
month:
|
|
33572
|
-
operationId:
|
|
34089
|
+
var GetFinancesInput = z142.object({
|
|
34090
|
+
month: z142.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional().describe("Mes en YYYY-MM. Si se omite, el mes en curso. Solo mes calendario."),
|
|
34091
|
+
operationId: z142.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
|
|
33573
34092
|
}).strict();
|
|
33574
34093
|
function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
33575
34094
|
server.registerTool("get_product_control", {
|
|
@@ -33761,28 +34280,28 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
|
33761
34280
|
__name(registerProductControlTools, "registerProductControlTools");
|
|
33762
34281
|
|
|
33763
34282
|
// src/tools/market-study-estimate.ts
|
|
33764
|
-
import { z as
|
|
34283
|
+
import { z as z143 } from "zod";
|
|
33765
34284
|
var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
|
|
33766
|
-
var ProductTaskOutputEnum =
|
|
34285
|
+
var ProductTaskOutputEnum = z143.enum([
|
|
33767
34286
|
"landing",
|
|
33768
34287
|
"video",
|
|
33769
34288
|
"image"
|
|
33770
34289
|
]);
|
|
33771
|
-
var EstimateMarketStudyInput =
|
|
33772
|
-
kind:
|
|
34290
|
+
var EstimateMarketStudyInput = z143.object({
|
|
34291
|
+
kind: z143.enum([
|
|
33773
34292
|
"video",
|
|
33774
34293
|
"product_task"
|
|
33775
34294
|
]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
|
|
33776
|
-
videoAngleCount:
|
|
33777
|
-
durationSeconds:
|
|
34295
|
+
videoAngleCount: z143.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
|
|
34296
|
+
durationSeconds: z143.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
|
|
33778
34297
|
videoStructure: VideoStructureEnum.default("single_take"),
|
|
33779
34298
|
videoQuality: VideoQualityEnum.default("economy"),
|
|
33780
34299
|
videoResolution: VideoResolutionEnum.default("480p"),
|
|
33781
|
-
productImageCount:
|
|
34300
|
+
productImageCount: z143.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
|
|
33782
34301
|
outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
|
|
33783
|
-
generateAiMusic:
|
|
34302
|
+
generateAiMusic: z143.boolean().optional(),
|
|
33784
34303
|
generateAiEdit: AiEditRequestSchema.optional(),
|
|
33785
|
-
replicateWinnerWhenFound:
|
|
34304
|
+
replicateWinnerWhenFound: z143.boolean().optional().describe("La misma preferencia que enviar\xE1s al crear. false excluye la reserva de r\xE9plica del ganador de la cotizaci\xF3n con estudio.")
|
|
33786
34305
|
}).strict();
|
|
33787
34306
|
function buildMarketStudyEstimateRequests(input) {
|
|
33788
34307
|
const quotesVideo = input.kind === "video" || (input.outputs ?? [
|
|
@@ -33981,6 +34500,7 @@ function createServer(opts) {
|
|
|
33981
34500
|
});
|
|
33982
34501
|
registerProductMakerPrompts(server);
|
|
33983
34502
|
registerMediaUploadAppResource(server, api.publicUrl("/v1/uploaded-assets/sessions/resolve"));
|
|
34503
|
+
registerTaskResultsAppResource(server, proxyBaseUrl);
|
|
33984
34504
|
registerProductCostingTools(server);
|
|
33985
34505
|
registerProductResearchTools(server, api);
|
|
33986
34506
|
registerDropshippingProjectTools(server, api);
|