@productmaker/mcp 8.11.2 → 8.11.4
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 +6 -0
- package/dist/http.js +759 -682
- package/dist/stdio.js +748 -671
- package/package.json +1 -1
package/dist/http.js
CHANGED
|
@@ -151,6 +151,14 @@ var FrankensteinSourceUploadPresignResponseSchema = z2.object({
|
|
|
151
151
|
|
|
152
152
|
// ../../packages/types/src/product-context-limits.ts
|
|
153
153
|
var PRODUCT_CONTEXT_MAX_CHARS = 3e3;
|
|
154
|
+
function canonicalizeLineBreaks(value) {
|
|
155
|
+
return value.replace(/\r\n?/g, "\n");
|
|
156
|
+
}
|
|
157
|
+
__name(canonicalizeLineBreaks, "canonicalizeLineBreaks");
|
|
158
|
+
function canonicalizeProductContext(value) {
|
|
159
|
+
return canonicalizeLineBreaks(value).trim();
|
|
160
|
+
}
|
|
161
|
+
__name(canonicalizeProductContext, "canonicalizeProductContext");
|
|
154
162
|
|
|
155
163
|
// ../../packages/types/src/video-creation.ts
|
|
156
164
|
var VideoCreationAspectRatio = z3.enum([
|
|
@@ -182,7 +190,7 @@ var FrankensteinVideoRequestBaseSchema = z3.object({
|
|
|
182
190
|
generateAiMusic: z3.boolean().default(false),
|
|
183
191
|
title: z3.string().trim().min(1).max(300).optional(),
|
|
184
192
|
primaryAngle: z3.string().trim().max(500).optional(),
|
|
185
|
-
productContext: z3.string().
|
|
193
|
+
productContext: z3.string().transform(canonicalizeProductContext).pipe(z3.string().max(PRODUCT_CONTEXT_MAX_CHARS)).optional(),
|
|
186
194
|
productLabel: z3.string().trim().max(120).optional(),
|
|
187
195
|
buyerPersona: z3.string().trim().max(500).optional(),
|
|
188
196
|
cta: z3.string().trim().max(300).optional(),
|
|
@@ -4252,7 +4260,7 @@ var IngestOptions = z22.object({
|
|
|
4252
4260
|
* per task. Length only, never `.uuid()` — Actor.id is a CUID. */
|
|
4253
4261
|
actorId: z22.string().min(1).max(120).optional(),
|
|
4254
4262
|
isCombo: z22.boolean().default(false),
|
|
4255
|
-
productContext: z22.string().transform(
|
|
4263
|
+
productContext: z22.string().transform(canonicalizeProductContext).pipe(z22.string().max(PRODUCT_CONTEXT_MAX_CHARS)).optional(),
|
|
4256
4264
|
creativeDirection: z22.string().transform((value) => value.trim()).pipe(z22.string().max(500)).optional(),
|
|
4257
4265
|
/** Exact copy the user pinned. Rendered VERBATIM on the image creatives this task
|
|
4258
4266
|
* produces and on the landing hero — never on video, which steers via scriptNotes.
|
|
@@ -5813,7 +5821,12 @@ var ShopifyPublishErrorResponse = z29.discriminatedUnion("code", [
|
|
|
5813
5821
|
* variants, another app rewrote the product, landing too large).
|
|
5814
5822
|
* `message` carries the seller's next step; never a 500.
|
|
5815
5823
|
*/
|
|
5816
|
-
"SHOPIFY_PUBLISH_VERIFICATION_FAILED"
|
|
5824
|
+
"SHOPIFY_PUBLISH_VERIFICATION_FAILED",
|
|
5825
|
+
/**
|
|
5826
|
+
* The seller's store is frozen/paused/closed on Shopify's side (402/423
|
|
5827
|
+
* "Unavailable Shop"). 409; `message` says to reactivate it in Shopify.
|
|
5828
|
+
*/
|
|
5829
|
+
"SHOPIFY_SHOP_UNAVAILABLE"
|
|
5817
5830
|
]),
|
|
5818
5831
|
message: z29.string().optional(),
|
|
5819
5832
|
authUrl: z29.string().url().optional(),
|
|
@@ -12084,7 +12097,11 @@ var VideoRegenerationEngineSchema = z58.enum([
|
|
|
12084
12097
|
"free_text",
|
|
12085
12098
|
"free_image",
|
|
12086
12099
|
"single_call",
|
|
12087
|
-
"multi_shot"
|
|
12100
|
+
"multi_shot",
|
|
12101
|
+
// Voice-only script edit: TTS of the new script in the video's own voice,
|
|
12102
|
+
// muxed over the delivered video. Only for voiceover-only renders (no shot
|
|
12103
|
+
// with on-camera lipsync), so no frame is regenerated.
|
|
12104
|
+
"voiceover"
|
|
12088
12105
|
]);
|
|
12089
12106
|
var VideoRegenerationRouteFingerprintSchema = z58.string().trim().min(1).max(128);
|
|
12090
12107
|
var RegenerateEditRequestSchema = z58.object({
|
|
@@ -14282,6 +14299,8 @@ var ProductControlDailyCountsSchema = z69.object({
|
|
|
14282
14299
|
var ProductControlRowSchema = z69.object({
|
|
14283
14300
|
/** `null` hasta que la vendedora toca el producto por primera vez. */
|
|
14284
14301
|
productControlId: z69.string().nullable(),
|
|
14302
|
+
/** La operación a la que pertenece; opcional para payloads anteriores. */
|
|
14303
|
+
operationId: z69.string().nullable().optional(),
|
|
14285
14304
|
shopId: z69.string(),
|
|
14286
14305
|
shopDomain: z69.string(),
|
|
14287
14306
|
/** Nulo cuando el producto NO vive en Shopify: importado del archivo de un
|
|
@@ -14478,9 +14497,7 @@ var SaveProductCatalogSchema = z69.object({
|
|
|
14478
14497
|
"tiktok"
|
|
14479
14498
|
]).nullable().optional()
|
|
14480
14499
|
}).strict();
|
|
14481
|
-
var
|
|
14482
|
-
shopDomain: z69.string().min(1),
|
|
14483
|
-
shopifyProductId: z69.string().min(1),
|
|
14500
|
+
var ProductControlCampaignFieldsSchema = z69.object({
|
|
14484
14501
|
provider: z69.enum([
|
|
14485
14502
|
"meta",
|
|
14486
14503
|
"tiktok"
|
|
@@ -14488,6 +14505,15 @@ var LinkProductControlCampaignSchema = z69.object({
|
|
|
14488
14505
|
accountId: z69.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/),
|
|
14489
14506
|
campaignId: z69.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/)
|
|
14490
14507
|
}).strict();
|
|
14508
|
+
var LinkProductControlCampaignSchema = z69.union([
|
|
14509
|
+
ProductControlCampaignFieldsSchema.extend({
|
|
14510
|
+
productControlId: z69.string().uuid()
|
|
14511
|
+
}).strict(),
|
|
14512
|
+
ProductControlCampaignFieldsSchema.extend({
|
|
14513
|
+
shopDomain: z69.string().min(1),
|
|
14514
|
+
shopifyProductId: z69.string().min(1)
|
|
14515
|
+
}).strict()
|
|
14516
|
+
]);
|
|
14491
14517
|
var ReportProductControlReturnsSchema = z69.object({
|
|
14492
14518
|
returnedOrders: z69.number().int().min(0).max(1e5),
|
|
14493
14519
|
note: z69.string().trim().max(280).optional()
|
|
@@ -17784,6 +17810,53 @@ var RegenerateVideoScriptCapabilityRequest = z79.object({
|
|
|
17784
17810
|
]).optional().describe("Elecci\xF3n expl\xEDcita del usuario: market usa el estudio de mercado disponible; guided usa la narrativa elegida. Omitir conserva el comportamiento existente.")
|
|
17785
17811
|
}).strict();
|
|
17786
17812
|
|
|
17813
|
+
// ../../packages/types/src/dropi-financial.ts
|
|
17814
|
+
import { z as z80 } from "zod";
|
|
17815
|
+
var ConnectDropiFinancialSchema = z80.object({
|
|
17816
|
+
integrationKey: z80.string().trim().min(1).max(4096).regex(/^[\x21-\x7e]+$/)
|
|
17817
|
+
}).strict();
|
|
17818
|
+
var SyncDropiFinancialSchema = z80.object({
|
|
17819
|
+
operationId: z80.string().uuid().optional(),
|
|
17820
|
+
since: z80.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
|
|
17821
|
+
until: z80.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional()
|
|
17822
|
+
}).strict();
|
|
17823
|
+
var DropiFinancialStatusSchema = z80.object({
|
|
17824
|
+
enabled: z80.boolean(),
|
|
17825
|
+
connected: z80.boolean(),
|
|
17826
|
+
countryCode: z80.literal("CO"),
|
|
17827
|
+
environment: z80.enum([
|
|
17828
|
+
"sandbox",
|
|
17829
|
+
"production"
|
|
17830
|
+
]),
|
|
17831
|
+
lastSyncAt: z80.string().nullable(),
|
|
17832
|
+
lastError: z80.string().nullable(),
|
|
17833
|
+
historyNext: z80.string().nullable(),
|
|
17834
|
+
historyUntil: z80.string().nullable(),
|
|
17835
|
+
changesThrough: z80.string().nullable(),
|
|
17836
|
+
manualNext: z80.string().nullable(),
|
|
17837
|
+
manual: z80.object({
|
|
17838
|
+
since: z80.string(),
|
|
17839
|
+
until: z80.string(),
|
|
17840
|
+
next: z80.string().nullable()
|
|
17841
|
+
}).nullable(),
|
|
17842
|
+
retentionSince: z80.string()
|
|
17843
|
+
});
|
|
17844
|
+
var DropiFinancialSyncResultSchema = z80.object({
|
|
17845
|
+
orders: z80.number().int().nonnegative(),
|
|
17846
|
+
written: z80.number().int().nonnegative(),
|
|
17847
|
+
updated: z80.number().int().nonnegative(),
|
|
17848
|
+
pending: z80.boolean(),
|
|
17849
|
+
next: z80.string().nullable(),
|
|
17850
|
+
historyNext: z80.string().nullable(),
|
|
17851
|
+
changesThrough: z80.string().nullable(),
|
|
17852
|
+
since: z80.string(),
|
|
17853
|
+
until: z80.string(),
|
|
17854
|
+
unmatched: z80.array(z80.object({
|
|
17855
|
+
externalProductId: z80.string(),
|
|
17856
|
+
orders: z80.number().int().nonnegative()
|
|
17857
|
+
}))
|
|
17858
|
+
});
|
|
17859
|
+
|
|
17787
17860
|
// src/http.ts
|
|
17788
17861
|
import express4 from "express";
|
|
17789
17862
|
import rateLimit2 from "express-rate-limit";
|
|
@@ -18293,23 +18366,23 @@ import { InsufficientScopeError, InvalidTokenError } from "@modelcontextprotocol
|
|
|
18293
18366
|
import { createRemoteJWKSet as createRemoteJWKSet2, jwtVerify as jwtVerify2 } from "jose";
|
|
18294
18367
|
|
|
18295
18368
|
// src/auth/oauth-config.ts
|
|
18296
|
-
import { z as
|
|
18369
|
+
import { z as z81 } from "zod";
|
|
18297
18370
|
var MCP_RESOURCE = new URL("https://mcp.productmaker.app/mcp");
|
|
18298
18371
|
var MCP_SCOPE = "mcp:access";
|
|
18299
18372
|
var REFRESH_SCOPE = "offline_access";
|
|
18300
18373
|
var STATIC_CLIENT_ISSUER = new URL(MCP_RESOURCE.origin);
|
|
18301
|
-
var oauthEnvSchema =
|
|
18302
|
-
MCP_REMOTE_AUTH_MODE:
|
|
18303
|
-
MCP_AUTH0_ISSUER:
|
|
18304
|
-
MCP_AUTH0_AUDIENCE:
|
|
18374
|
+
var oauthEnvSchema = z81.object({
|
|
18375
|
+
MCP_REMOTE_AUTH_MODE: z81.literal("oauth"),
|
|
18376
|
+
MCP_AUTH0_ISSUER: z81.string().trim().min(1),
|
|
18377
|
+
MCP_AUTH0_AUDIENCE: z81.string().trim().refine((value) => value === MCP_RESOURCE.href, {
|
|
18305
18378
|
message: `must equal ${MCP_RESOURCE.href}`
|
|
18306
18379
|
}),
|
|
18307
|
-
MCP_AUTH0_CLIENT_ID:
|
|
18308
|
-
MCP_AUTH0_CLIENT_SECRET:
|
|
18309
|
-
PM_API_AUDIENCE:
|
|
18310
|
-
AUTH0_AUDIENCE:
|
|
18311
|
-
MCP_STATIC_CLIENT_ID:
|
|
18312
|
-
MCP_STATIC_CLIENT_SECRET:
|
|
18380
|
+
MCP_AUTH0_CLIENT_ID: z81.string().trim().min(1),
|
|
18381
|
+
MCP_AUTH0_CLIENT_SECRET: z81.string().trim().min(1),
|
|
18382
|
+
PM_API_AUDIENCE: z81.string().trim().min(1),
|
|
18383
|
+
AUTH0_AUDIENCE: z81.string().trim().min(1),
|
|
18384
|
+
MCP_STATIC_CLIENT_ID: z81.string().trim().min(1).optional(),
|
|
18385
|
+
MCP_STATIC_CLIENT_SECRET: z81.string().trim().min(1).optional()
|
|
18313
18386
|
});
|
|
18314
18387
|
function formatZodIssues(error) {
|
|
18315
18388
|
return error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ");
|
|
@@ -19462,7 +19535,7 @@ var ApiClient = class {
|
|
|
19462
19535
|
};
|
|
19463
19536
|
|
|
19464
19537
|
// src/index.ts
|
|
19465
|
-
var MCP_VERSION = "8.11.
|
|
19538
|
+
var MCP_VERSION = "8.11.4";
|
|
19466
19539
|
|
|
19467
19540
|
// src/meta-upload-app.ts
|
|
19468
19541
|
import { readFileSync } from "fs";
|
|
@@ -19534,7 +19607,7 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
|
|
|
19534
19607
|
__name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
|
|
19535
19608
|
|
|
19536
19609
|
// src/tools/tasks.ts
|
|
19537
|
-
import { z as
|
|
19610
|
+
import { z as z86 } from "zod";
|
|
19538
19611
|
|
|
19539
19612
|
// src/resolve-image.ts
|
|
19540
19613
|
import { lookup as dnsLookup } from "dns/promises";
|
|
@@ -20095,9 +20168,9 @@ async function resolveMediaRef(ref, opts) {
|
|
|
20095
20168
|
__name(resolveMediaRef, "resolveMediaRef");
|
|
20096
20169
|
|
|
20097
20170
|
// src/tools/shared.ts
|
|
20098
|
-
import { z as
|
|
20099
|
-
var Lang =
|
|
20100
|
-
var Country =
|
|
20171
|
+
import { z as z82 } from "zod";
|
|
20172
|
+
var Lang = z82.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);
|
|
20173
|
+
var Country = z82.string().min(2).max(3);
|
|
20101
20174
|
var LandingStrategyEnum = LandingStrategySchema;
|
|
20102
20175
|
var LandingImageFormatEnum = LandingImageFormatSchema;
|
|
20103
20176
|
var VideoPresetEnum = VideoPreset.extract([
|
|
@@ -20201,7 +20274,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
|
|
|
20201
20274
|
return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
|
|
20202
20275
|
}
|
|
20203
20276
|
__name(animationStyleApplies, "animationStyleApplies");
|
|
20204
|
-
var VideoTierEnum =
|
|
20277
|
+
var VideoTierEnum = z82.enum([
|
|
20205
20278
|
"basic"
|
|
20206
20279
|
]);
|
|
20207
20280
|
function resolveVideoTier(_tier) {
|
|
@@ -20259,10 +20332,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
|
|
|
20259
20332
|
var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
|
|
20260
20333
|
var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
|
|
20261
20334
|
var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
|
|
20262
|
-
var ImageRefSchema =
|
|
20263
|
-
url:
|
|
20264
|
-
path:
|
|
20265
|
-
assetId:
|
|
20335
|
+
var ImageRefSchema = z82.object({
|
|
20336
|
+
url: z82.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.'),
|
|
20337
|
+
path: z82.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`.'),
|
|
20338
|
+
assetId: z82.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.")
|
|
20266
20339
|
}).refine((v) => [
|
|
20267
20340
|
v.url,
|
|
20268
20341
|
v.path,
|
|
@@ -20270,11 +20343,11 @@ var ImageRefSchema = z81.object({
|
|
|
20270
20343
|
].filter(Boolean).length === 1, {
|
|
20271
20344
|
message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
|
|
20272
20345
|
});
|
|
20273
|
-
var ImagesInput =
|
|
20346
|
+
var ImagesInput = z82.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
|
|
20274
20347
|
const assetCount = images.filter((image) => Boolean(image.assetId)).length;
|
|
20275
20348
|
if (assetCount > 0 && assetCount !== images.length) {
|
|
20276
20349
|
ctx.addIssue({
|
|
20277
|
-
code:
|
|
20350
|
+
code: z82.ZodIssueCode.custom,
|
|
20278
20351
|
message: "all image entries must use assetId, or all must use URL/path sources"
|
|
20279
20352
|
});
|
|
20280
20353
|
}
|
|
@@ -20347,14 +20420,14 @@ async function submitCreative(api, opts) {
|
|
|
20347
20420
|
});
|
|
20348
20421
|
}
|
|
20349
20422
|
__name(submitCreative, "submitCreative");
|
|
20350
|
-
var ResearchTargetCountryEnum =
|
|
20423
|
+
var ResearchTargetCountryEnum = z82.enum([
|
|
20351
20424
|
"CO",
|
|
20352
20425
|
"MX",
|
|
20353
20426
|
"PE",
|
|
20354
20427
|
"EC",
|
|
20355
20428
|
"CL"
|
|
20356
20429
|
]);
|
|
20357
|
-
var ResearchCategoryEnum =
|
|
20430
|
+
var ResearchCategoryEnum = z82.enum([
|
|
20358
20431
|
"auto",
|
|
20359
20432
|
"automotive",
|
|
20360
20433
|
"kitchen",
|
|
@@ -20491,6 +20564,7 @@ var McpErrorCode = {
|
|
|
20491
20564
|
SHOPIFY_SCOPE_UPGRADE_REQUIRED: "SHOPIFY_SCOPE_UPGRADE_REQUIRED",
|
|
20492
20565
|
SHOPIFY_PUBLISH_FAILED: "SHOPIFY_PUBLISH_FAILED",
|
|
20493
20566
|
SHOPIFY_NO_PUBLISHED_THEME: "SHOPIFY_NO_PUBLISHED_THEME",
|
|
20567
|
+
SHOPIFY_SHOP_UNAVAILABLE: "SHOPIFY_SHOP_UNAVAILABLE",
|
|
20494
20568
|
SHOPIFY_THEME_STRUCTURE_UNSUPPORTED: "SHOPIFY_THEME_STRUCTURE_UNSUPPORTED",
|
|
20495
20569
|
SHOPIFY_PUBLISH_INPUT_REQUIRED: "SHOPIFY_PUBLISH_INPUT_REQUIRED",
|
|
20496
20570
|
SHOPIFY_PUBLISH_CONTEXT_CHANGED: "SHOPIFY_PUBLISH_CONTEXT_CHANGED",
|
|
@@ -20573,6 +20647,7 @@ var CODE_MESSAGES = {
|
|
|
20573
20647
|
SHOPIFY_PUBLISH_VERIFICATION_FAILED: "Shopify did not keep what the publish wrote (offer variants, template or inventory), or the landing is too large. Read the error's reason to the user; retry the publish once, and if it repeats follow the step in the reason (map packs to existing variants, check apps that edit products, or trim the landing in the editor).",
|
|
20574
20648
|
SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE: "The selected Shopify product cannot carry the confirmed offer (missing quantity options/prices) or no longer exists. Read the error's message to the user, then retry with publicationMode:'new' to create a fresh product, or ask the user to pick a different existing product.",
|
|
20575
20649
|
SHOPIFY_THEME_SETUP_REQUIRED: "The store's Shopify theme is missing the ProductMaker 'Code Landing' app block \u2014 publishing now would create a product whose page renders blank. Send the user the themeEditorDeepLink (in error data) to open the Shopify theme editor, have them confirm the Code Landing block is added and press Save, then retry publishing. This is a one-time step per store; nothing was published.",
|
|
20650
|
+
SHOPIFY_SHOP_UNAVAILABLE: "The user's Shopify store is unavailable (frozen, paused or closed on Shopify's side), so nothing was published. Ask the user to reactivate the store in Shopify (usually by settling the plan/billing) or reconnect it at https://productmaker.app/integrations, then retry. Retrying before that will fail the same way.",
|
|
20576
20651
|
SHOPIFY_NO_PUBLISHED_THEME: "The Shopify store has no published theme, so there is nowhere to place the landing. Ask the user to publish a theme (Online Store > Themes > Publish) and retry.",
|
|
20577
20652
|
SHOPIFY_THEME_STRUCTURE_UNSUPPORTED: "The active Shopify theme contains an HTML structure ProductMaker cannot process safely. Ask the user to restore a valid layout/theme.liquid or contact ProductMaker support to correct the theme, then retry.",
|
|
20578
20653
|
// Meta — high-frequency
|
|
@@ -20764,6 +20839,7 @@ var INVALID_PARAM_CODES = /* @__PURE__ */ new Set([
|
|
|
20764
20839
|
McpErrorCode.SHOPIFY_SCOPE_UPGRADE_REQUIRED,
|
|
20765
20840
|
McpErrorCode.SHOPIFY_NOT_CONNECTED,
|
|
20766
20841
|
McpErrorCode.SHOPIFY_NO_PUBLISHED_THEME,
|
|
20842
|
+
McpErrorCode.SHOPIFY_SHOP_UNAVAILABLE,
|
|
20767
20843
|
McpErrorCode.SHOPIFY_THEME_STRUCTURE_UNSUPPORTED,
|
|
20768
20844
|
McpErrorCode.SHOPIFY_PUBLISH_INPUT_REQUIRED,
|
|
20769
20845
|
McpErrorCode.SHOPIFY_PUBLISH_CONTEXT_CHANGED,
|
|
@@ -20806,6 +20882,7 @@ var PASSTHROUGH_CODES = /* @__PURE__ */ new Set([
|
|
|
20806
20882
|
McpErrorCode.SHOPIFY_SCOPE_UPGRADE_REQUIRED,
|
|
20807
20883
|
McpErrorCode.SHOPIFY_PUBLISH_FAILED,
|
|
20808
20884
|
McpErrorCode.SHOPIFY_NO_PUBLISHED_THEME,
|
|
20885
|
+
McpErrorCode.SHOPIFY_SHOP_UNAVAILABLE,
|
|
20809
20886
|
McpErrorCode.SHOPIFY_THEME_STRUCTURE_UNSUPPORTED,
|
|
20810
20887
|
// Meta
|
|
20811
20888
|
McpErrorCode.META_NO_FB_PAGE,
|
|
@@ -21520,29 +21597,29 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
|
|
|
21520
21597
|
__name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
|
|
21521
21598
|
|
|
21522
21599
|
// src/tools/media-presentation.ts
|
|
21523
|
-
import { z as
|
|
21524
|
-
var HttpsPresentationUrlSchema =
|
|
21600
|
+
import { z as z83 } from "zod";
|
|
21601
|
+
var HttpsPresentationUrlSchema = z83.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
|
|
21525
21602
|
var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
|
|
21526
21603
|
const hostname = new URL(value).hostname.toLowerCase();
|
|
21527
21604
|
return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
|
|
21528
21605
|
}, "preview URL must be owned by ProductMaker");
|
|
21529
|
-
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) =>
|
|
21530
|
-
var PresentationImageSchema =
|
|
21531
|
-
kind:
|
|
21606
|
+
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z83.number().int().positive().max(maximum), "positiveIntAtMost");
|
|
21607
|
+
var PresentationImageSchema = z83.object({
|
|
21608
|
+
kind: z83.literal("image"),
|
|
21532
21609
|
url: HttpsPresentationUrlSchema,
|
|
21533
|
-
mimeType:
|
|
21610
|
+
mimeType: z83.enum([
|
|
21534
21611
|
"image/jpeg",
|
|
21535
21612
|
"image/png"
|
|
21536
21613
|
]),
|
|
21537
21614
|
byteSize: positiveIntAtMost(5 * 1024 * 1024),
|
|
21538
21615
|
width: positiveIntAtMost(16384),
|
|
21539
21616
|
height: positiveIntAtMost(16384),
|
|
21540
|
-
alt:
|
|
21617
|
+
alt: z83.string().trim().min(1).max(240)
|
|
21541
21618
|
}).strict();
|
|
21542
21619
|
var McpMediaPresentationSchema = PresentationImageSchema;
|
|
21543
|
-
var GalleryImageSchema =
|
|
21620
|
+
var GalleryImageSchema = z83.object({
|
|
21544
21621
|
url: ProductMakerPreviewUrlSchema,
|
|
21545
|
-
alt:
|
|
21622
|
+
alt: z83.string().trim().min(1).max(240)
|
|
21546
21623
|
});
|
|
21547
21624
|
var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
21548
21625
|
async function imageBlocks(image, transport) {
|
|
@@ -21663,7 +21740,7 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
|
|
|
21663
21740
|
__name(buildMcpImageGalleryContent, "buildMcpImageGalleryContent");
|
|
21664
21741
|
|
|
21665
21742
|
// src/tools/animated-video.ts
|
|
21666
|
-
import { z as
|
|
21743
|
+
import { z as z84 } from "zod";
|
|
21667
21744
|
|
|
21668
21745
|
// src/tools/paid-confirmation.ts
|
|
21669
21746
|
function describeMarketStudyChoice(enabled) {
|
|
@@ -21876,44 +21953,44 @@ function describeAnimatedVideoPrices() {
|
|
|
21876
21953
|
return MOTION_GRAPHICS_DURATIONS.map((d) => `${d} s = ${creditsFor(d)} cr\xE9ditos (US$${usdFor(d)})`).join(", ");
|
|
21877
21954
|
}
|
|
21878
21955
|
__name(describeAnimatedVideoPrices, "describeAnimatedVideoPrices");
|
|
21879
|
-
var DurationInput =
|
|
21880
|
-
var CreateAnimatedVideoInput =
|
|
21956
|
+
var DurationInput = z84.union(MOTION_GRAPHICS_DURATIONS.map((d) => z84.literal(d)));
|
|
21957
|
+
var CreateAnimatedVideoInput = z84.object({
|
|
21881
21958
|
// Plain text, not `.url()`: users type «cal.com», and the web accepts it.
|
|
21882
21959
|
// normalizeWebAddress (shared with the web) adds https:// and refuses
|
|
21883
21960
|
// anything that is not a public http(s) address.
|
|
21884
|
-
landingUrl:
|
|
21961
|
+
landingUrl: z84.string().trim().min(1).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."),
|
|
21885
21962
|
format: MotionGraphicsFormatSchema.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.'),
|
|
21886
21963
|
durationSec: DurationInput.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.`),
|
|
21887
21964
|
language: MotionGraphicsLanguageSchema.describe('Idioma de los textos del video: "es", "en" o "pt".'),
|
|
21888
|
-
notes:
|
|
21965
|
+
notes: z84.string().trim().max(MOTION_GRAPHICS_NOTES_MAX_CHARS).optional().describe("Opcional. Indicaciones para el video en lenguaje natural (ej. enf\xF3cate en los precios, tono m\xE1s formal, menciona la prueba gratis).")
|
|
21889
21966
|
}).strict();
|
|
21890
21967
|
var FORMAT_LABELS = {
|
|
21891
21968
|
vertical: "vertical 9:16",
|
|
21892
21969
|
square: "cuadrado 1:1",
|
|
21893
21970
|
horizontal: "horizontal 16:9"
|
|
21894
21971
|
};
|
|
21895
|
-
var AnimatedVideoResultSchema =
|
|
21896
|
-
status:
|
|
21972
|
+
var AnimatedVideoResultSchema = z84.object({
|
|
21973
|
+
status: z84.enum([
|
|
21897
21974
|
"pending",
|
|
21898
21975
|
"done",
|
|
21899
21976
|
"error"
|
|
21900
21977
|
]),
|
|
21901
|
-
serviceMode:
|
|
21902
|
-
finalMp4Url:
|
|
21903
|
-
error:
|
|
21904
|
-
motionGraphics:
|
|
21978
|
+
serviceMode: z84.literal("motion_graphics"),
|
|
21979
|
+
finalMp4Url: z84.string().optional(),
|
|
21980
|
+
error: z84.string().optional(),
|
|
21981
|
+
motionGraphics: z84.object({
|
|
21905
21982
|
stage: MotionGraphicsStageSchema,
|
|
21906
21983
|
format: MotionGraphicsFormatSchema,
|
|
21907
|
-
durationSec:
|
|
21908
|
-
width:
|
|
21909
|
-
height:
|
|
21984
|
+
durationSec: z84.number(),
|
|
21985
|
+
width: z84.number().optional(),
|
|
21986
|
+
height: z84.number().optional(),
|
|
21910
21987
|
language: MotionGraphicsLanguageSchema.optional(),
|
|
21911
|
-
queuedAt:
|
|
21912
|
-
jobsAhead:
|
|
21913
|
-
stageStartedAt:
|
|
21914
|
-
renderProgress:
|
|
21915
|
-
activity:
|
|
21916
|
-
previewUrl:
|
|
21988
|
+
queuedAt: z84.string().optional(),
|
|
21989
|
+
jobsAhead: z84.number().int().nonnegative().optional(),
|
|
21990
|
+
stageStartedAt: z84.string().optional(),
|
|
21991
|
+
renderProgress: z84.number().optional(),
|
|
21992
|
+
activity: z84.array(MotionGraphicsActivitySchema).optional().catch(void 0),
|
|
21993
|
+
previewUrl: z84.string().optional()
|
|
21917
21994
|
}).passthrough()
|
|
21918
21995
|
}).passthrough();
|
|
21919
21996
|
function parseAnimatedVideoResult(value) {
|
|
@@ -22075,10 +22152,10 @@ function registerAnimatedVideoTools(server, api) {
|
|
|
22075
22152
|
__name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
|
|
22076
22153
|
|
|
22077
22154
|
// src/tools/winning-product-image.ts
|
|
22078
|
-
import { z as
|
|
22079
|
-
var WinnerReferenceInput =
|
|
22080
|
-
runId:
|
|
22081
|
-
candidateSourceId:
|
|
22155
|
+
import { z as z85 } from "zod";
|
|
22156
|
+
var WinnerReferenceInput = z85.object({
|
|
22157
|
+
runId: z85.string().uuid(),
|
|
22158
|
+
candidateSourceId: z85.string().trim().min(1).max(160)
|
|
22082
22159
|
}).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
|
|
22083
22160
|
async function resolveWinnerImages(api, winnerReference, images) {
|
|
22084
22161
|
if (!winnerReference) return images;
|
|
@@ -22115,60 +22192,60 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
|
|
|
22115
22192
|
var createServiceVideoGuidance = getProductMakerCapabilityModelGuidance("create_service_video");
|
|
22116
22193
|
var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
|
|
22117
22194
|
var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
|
|
22118
|
-
var CreateProductTaskInput =
|
|
22195
|
+
var CreateProductTaskInput = z86.object({
|
|
22119
22196
|
images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
|
|
22120
22197
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
22121
|
-
projectId:
|
|
22122
|
-
productUrl:
|
|
22198
|
+
projectId: z86.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
|
|
22199
|
+
productUrl: z86.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."),
|
|
22123
22200
|
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.'),
|
|
22124
22201
|
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.'),
|
|
22125
|
-
price:
|
|
22126
|
-
compareAtPrice:
|
|
22127
|
-
offer:
|
|
22128
|
-
paymentMethods:
|
|
22129
|
-
productContext:
|
|
22130
|
-
productLabel:
|
|
22202
|
+
price: z86.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.'),
|
|
22203
|
+
compareAtPrice: z86.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".'),
|
|
22204
|
+
offer: z86.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.'),
|
|
22205
|
+
paymentMethods: z86.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.'),
|
|
22206
|
+
productContext: z86.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."),
|
|
22207
|
+
productLabel: z86.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.'),
|
|
22131
22208
|
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.'),
|
|
22132
22209
|
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.'),
|
|
22133
|
-
durationSeconds:
|
|
22134
|
-
|
|
22135
|
-
|
|
22210
|
+
durationSeconds: z86.union([
|
|
22211
|
+
z86.literal(15),
|
|
22212
|
+
z86.literal(30)
|
|
22136
22213
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
22137
|
-
pauseForAngleReview:
|
|
22138
|
-
aiDecidesAll:
|
|
22214
|
+
pauseForAngleReview: z86.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."),
|
|
22215
|
+
aiDecidesAll: z86.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."),
|
|
22139
22216
|
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.'),
|
|
22140
22217
|
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.'),
|
|
22141
22218
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
22142
22219
|
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).'),
|
|
22143
|
-
videoAngleCount:
|
|
22220
|
+
videoAngleCount: z86.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."),
|
|
22144
22221
|
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.'),
|
|
22145
|
-
outputs:
|
|
22222
|
+
outputs: z86.array(z86.enum([
|
|
22146
22223
|
"landing",
|
|
22147
22224
|
"video",
|
|
22148
22225
|
"image"
|
|
22149
22226
|
])).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}`),
|
|
22150
|
-
competitorScanEnabled:
|
|
22151
|
-
replicateWinnerWhenFound:
|
|
22152
|
-
brandId:
|
|
22153
|
-
actorId:
|
|
22227
|
+
competitorScanEnabled: z86.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."),
|
|
22228
|
+
replicateWinnerWhenFound: z86.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."),
|
|
22229
|
+
brandId: z86.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."),
|
|
22230
|
+
actorId: z86.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."),
|
|
22154
22231
|
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.'),
|
|
22155
|
-
creativeDirection:
|
|
22156
|
-
headline:
|
|
22157
|
-
subheadline:
|
|
22232
|
+
creativeDirection: z86.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.'),
|
|
22233
|
+
headline: z86.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."),
|
|
22234
|
+
subheadline: z86.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."),
|
|
22158
22235
|
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".'),
|
|
22159
22236
|
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".')
|
|
22160
22237
|
}).strict();
|
|
22161
|
-
var CreateServiceVideoInput =
|
|
22162
|
-
landingUrl:
|
|
22163
|
-
additionalContext:
|
|
22238
|
+
var CreateServiceVideoInput = z86.object({
|
|
22239
|
+
landingUrl: z86.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
|
|
22240
|
+
additionalContext: z86.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
|
|
22164
22241
|
language: Lang.describe("Idioma del video: es, en o pt."),
|
|
22165
|
-
voiceId:
|
|
22166
|
-
brandId:
|
|
22167
|
-
reviewMode:
|
|
22242
|
+
voiceId: z86.string().trim().min(1).optional().describe('Opcional. Voz de ElevenLabs para toda la narraci\xF3n. Usa "auto" para que la IA la alinee con el presentador o env\xEDa un ID concreto de la lista de voces de la web.'),
|
|
22243
|
+
brandId: z86.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
|
|
22244
|
+
reviewMode: z86.enum([
|
|
22168
22245
|
"automatic",
|
|
22169
22246
|
"guided"
|
|
22170
22247
|
]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
|
|
22171
|
-
videoPreset:
|
|
22248
|
+
videoPreset: z86.enum([
|
|
22172
22249
|
"auto",
|
|
22173
22250
|
"ugc_dynamic",
|
|
22174
22251
|
"ugc_how_to",
|
|
@@ -22178,128 +22255,128 @@ var CreateServiceVideoInput = z85.object({
|
|
|
22178
22255
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
22179
22256
|
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.')
|
|
22180
22257
|
}).strict();
|
|
22181
|
-
var GetTaskStatusInput =
|
|
22182
|
-
taskId:
|
|
22183
|
-
waitSeconds:
|
|
22258
|
+
var GetTaskStatusInput = z86.object({
|
|
22259
|
+
taskId: z86.string().min(1),
|
|
22260
|
+
waitSeconds: z86.number().int().min(0).max(120).optional()
|
|
22184
22261
|
});
|
|
22185
|
-
var ListTasksInput =
|
|
22186
|
-
limit:
|
|
22187
|
-
offset:
|
|
22188
|
-
search:
|
|
22262
|
+
var ListTasksInput = z86.object({
|
|
22263
|
+
limit: z86.number().int().min(1).max(50).optional(),
|
|
22264
|
+
offset: z86.number().int().min(0).optional(),
|
|
22265
|
+
search: z86.string().optional()
|
|
22189
22266
|
});
|
|
22190
22267
|
var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
|
|
22191
22268
|
var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
|
|
22192
|
-
var EditTaskDraftInput =
|
|
22193
|
-
taskId:
|
|
22194
|
-
angleIndex:
|
|
22195
|
-
angle:
|
|
22196
|
-
angle:
|
|
22197
|
-
buyerPersona:
|
|
22198
|
-
actor:
|
|
22199
|
-
actorId:
|
|
22200
|
-
gender:
|
|
22269
|
+
var EditTaskDraftInput = z86.object({
|
|
22270
|
+
taskId: z86.string().min(1),
|
|
22271
|
+
angleIndex: z86.number().int().min(0),
|
|
22272
|
+
angle: z86.object({
|
|
22273
|
+
angle: z86.string().min(1).max(480),
|
|
22274
|
+
buyerPersona: z86.string().min(1).max(360),
|
|
22275
|
+
actor: z86.string().min(1).max(360).optional(),
|
|
22276
|
+
actorId: z86.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."),
|
|
22277
|
+
gender: z86.enum([
|
|
22201
22278
|
"female",
|
|
22202
22279
|
"male"
|
|
22203
22280
|
]).optional(),
|
|
22204
|
-
scriptNotes:
|
|
22281
|
+
scriptNotes: z86.string().max(2e3).optional()
|
|
22205
22282
|
})
|
|
22206
22283
|
});
|
|
22207
|
-
var PendingActionPayload =
|
|
22208
|
-
|
|
22209
|
-
kind:
|
|
22284
|
+
var PendingActionPayload = z86.discriminatedUnion("kind", [
|
|
22285
|
+
z86.object({
|
|
22286
|
+
kind: z86.literal("product_reference_set_approval"),
|
|
22210
22287
|
scope: ProductReferenceScopeEnum.optional(),
|
|
22211
|
-
scopeKey:
|
|
22212
|
-
scopeSnapshotId:
|
|
22213
|
-
expectedScopeHash:
|
|
22288
|
+
scopeKey: z86.string().min(1).max(120).optional(),
|
|
22289
|
+
scopeSnapshotId: z86.string().uuid().optional(),
|
|
22290
|
+
expectedScopeHash: z86.string().min(1).max(128).optional(),
|
|
22214
22291
|
decision: ProductReferenceResolutionDecisionEnum,
|
|
22215
22292
|
reason: ProductReferenceRejectionReasonEnum.optional(),
|
|
22216
|
-
affectedRefKeys:
|
|
22217
|
-
affectedPhotoNumbers:
|
|
22218
|
-
recoveryAction:
|
|
22293
|
+
affectedRefKeys: z86.array(z86.string().min(1).max(200)).min(1).optional(),
|
|
22294
|
+
affectedPhotoNumbers: z86.array(z86.number().int().positive()).min(1).optional(),
|
|
22295
|
+
recoveryAction: z86.enum([
|
|
22219
22296
|
"remove",
|
|
22220
22297
|
"replace",
|
|
22221
22298
|
"upload",
|
|
22222
22299
|
"return_to_selection"
|
|
22223
22300
|
]).optional()
|
|
22224
22301
|
}),
|
|
22225
|
-
|
|
22226
|
-
kind:
|
|
22227
|
-
selectedPhotoNumbers:
|
|
22302
|
+
z86.object({
|
|
22303
|
+
kind: z86.literal("product_reference_confirmation"),
|
|
22304
|
+
selectedPhotoNumbers: z86.array(z86.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."),
|
|
22228
22305
|
userChoice: ProductReferenceUserChoiceEnum.optional(),
|
|
22229
|
-
confirmedProductNames:
|
|
22306
|
+
confirmedProductNames: z86.array(z86.string().min(1).max(120)).min(2).max(8).optional(),
|
|
22230
22307
|
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."),
|
|
22231
22308
|
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."),
|
|
22232
|
-
useMultiSceneShowcase:
|
|
22309
|
+
useMultiSceneShowcase: z86.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
|
|
22233
22310
|
}),
|
|
22234
|
-
|
|
22235
|
-
kind:
|
|
22311
|
+
z86.object({
|
|
22312
|
+
kind: z86.literal("angle_review_approval"),
|
|
22236
22313
|
// All edits are optional — empty action body just approves the
|
|
22237
22314
|
// backend-generated draft as-is. Field shapes mirror the angle-review
|
|
22238
22315
|
// request contracts in @packages/types/wizard.ts; the handler routes to
|
|
22239
22316
|
// the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
|
|
22240
|
-
customAngle:
|
|
22317
|
+
customAngle: z86.string().min(1).max(480).optional(),
|
|
22241
22318
|
// Keep the shared MCP action within the strictest downstream contract:
|
|
22242
22319
|
// autopilot/image resume endpoints cap these fields at 1500 characters.
|
|
22243
|
-
painPoints:
|
|
22244
|
-
benefits:
|
|
22320
|
+
painPoints: z86.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
22321
|
+
benefits: z86.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
22245
22322
|
// Same policy as the two fields above: the strictest downstream contract
|
|
22246
22323
|
// wins. The image endpoint caps each feature at 240 while landing/video
|
|
22247
22324
|
// accept 300, and this single action routes to whichever the task is — so
|
|
22248
22325
|
// accepting 300 here turns a 250-character feature on an image task into
|
|
22249
22326
|
// an opaque HTTP 400 after the model already believed it had been saved.
|
|
22250
|
-
features:
|
|
22251
|
-
buyerPersona:
|
|
22327
|
+
features: z86.array(z86.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
|
|
22328
|
+
buyerPersona: z86.string().min(1).max(360).optional(),
|
|
22252
22329
|
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.'),
|
|
22253
|
-
actor:
|
|
22254
|
-
actorId:
|
|
22255
|
-
creativeDirection:
|
|
22256
|
-
selectedAngleNumbers:
|
|
22257
|
-
angleEdits:
|
|
22258
|
-
angleNumber:
|
|
22259
|
-
narrativeSelection:
|
|
22330
|
+
actor: z86.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."),
|
|
22331
|
+
actorId: z86.string().max(120).nullable().optional(),
|
|
22332
|
+
creativeDirection: z86.string().max(2e3).optional(),
|
|
22333
|
+
selectedAngleNumbers: z86.array(z86.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."),
|
|
22334
|
+
angleEdits: z86.array(z86.object({
|
|
22335
|
+
angleNumber: z86.number().int().positive(),
|
|
22336
|
+
narrativeSelection: z86.enum([
|
|
22260
22337
|
"market",
|
|
22261
22338
|
"guided"
|
|
22262
22339
|
]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
|
|
22263
|
-
angle:
|
|
22264
|
-
buyerPersona:
|
|
22340
|
+
angle: z86.string().min(1).max(480).optional(),
|
|
22341
|
+
buyerPersona: z86.string().min(1).max(360).optional(),
|
|
22265
22342
|
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.'),
|
|
22266
|
-
actor:
|
|
22267
|
-
actorId:
|
|
22268
|
-
creativeDirection:
|
|
22343
|
+
actor: z86.string().min(1).max(360).optional(),
|
|
22344
|
+
actorId: z86.string().max(120).nullable().optional(),
|
|
22345
|
+
creativeDirection: z86.string().max(2e3).optional()
|
|
22269
22346
|
}).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)."),
|
|
22270
|
-
gapDurationSeconds:
|
|
22271
|
-
|
|
22272
|
-
|
|
22347
|
+
gapDurationSeconds: z86.union([
|
|
22348
|
+
z86.literal(15),
|
|
22349
|
+
z86.literal(30)
|
|
22273
22350
|
]).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.")
|
|
22274
22351
|
}),
|
|
22275
|
-
|
|
22276
|
-
kind:
|
|
22277
|
-
angleId:
|
|
22278
|
-
angleNumber:
|
|
22279
|
-
content:
|
|
22280
|
-
creativeDirection:
|
|
22281
|
-
actor:
|
|
22352
|
+
z86.object({
|
|
22353
|
+
kind: z86.literal("service_angle_approval"),
|
|
22354
|
+
angleId: z86.string().uuid().optional(),
|
|
22355
|
+
angleNumber: z86.number().int().positive().optional(),
|
|
22356
|
+
content: z86.string().min(1).max(480).optional(),
|
|
22357
|
+
creativeDirection: z86.string().min(1).max(1500).optional(),
|
|
22358
|
+
actor: z86.string().min(1).max(360).optional()
|
|
22282
22359
|
}),
|
|
22283
|
-
|
|
22284
|
-
kind:
|
|
22285
|
-
voiceovers:
|
|
22286
|
-
visualDirections:
|
|
22287
|
-
voiceoversByScene:
|
|
22288
|
-
visualDirectionsByScene:
|
|
22360
|
+
z86.object({
|
|
22361
|
+
kind: z86.literal("service_script_approval"),
|
|
22362
|
+
voiceovers: z86.record(z86.string(), z86.string().min(1).max(600)).optional(),
|
|
22363
|
+
visualDirections: z86.record(z86.string(), z86.string().min(1).max(1200)).optional(),
|
|
22364
|
+
voiceoversByScene: z86.record(z86.string(), z86.string().min(1).max(600)).optional(),
|
|
22365
|
+
visualDirectionsByScene: z86.record(z86.string(), z86.string().min(1).max(1200)).optional()
|
|
22289
22366
|
})
|
|
22290
22367
|
]);
|
|
22291
|
-
var ResolvePendingActionInput =
|
|
22292
|
-
taskId:
|
|
22368
|
+
var ResolvePendingActionInput = z86.object({
|
|
22369
|
+
taskId: z86.string().min(1),
|
|
22293
22370
|
action: PendingActionPayload
|
|
22294
22371
|
}).strict();
|
|
22295
22372
|
function resolveVariantConfirmVideoTier(action) {
|
|
22296
22373
|
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
22297
22374
|
}
|
|
22298
22375
|
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
22299
|
-
var StatusForResolveSchema =
|
|
22376
|
+
var StatusForResolveSchema = z86.object({
|
|
22300
22377
|
// Metadata used to select the backend resume contract. Older API responses
|
|
22301
22378
|
// may omit these fields, so the resolver keeps the generic fallback.
|
|
22302
|
-
kind:
|
|
22379
|
+
kind: z86.enum([
|
|
22303
22380
|
"autopilot",
|
|
22304
22381
|
"video",
|
|
22305
22382
|
"image",
|
|
@@ -22307,18 +22384,18 @@ var StatusForResolveSchema = z85.object({
|
|
|
22307
22384
|
"mix",
|
|
22308
22385
|
"service"
|
|
22309
22386
|
]).optional(),
|
|
22310
|
-
selectedOutputs:
|
|
22387
|
+
selectedOutputs: z86.array(z86.enum([
|
|
22311
22388
|
"landing",
|
|
22312
22389
|
"video",
|
|
22313
22390
|
"image"
|
|
22314
22391
|
])).optional(),
|
|
22315
|
-
videoAngleCount:
|
|
22316
|
-
ugcFormat:
|
|
22392
|
+
videoAngleCount: z86.number().int().min(1).max(3).optional(),
|
|
22393
|
+
ugcFormat: z86.enum([
|
|
22317
22394
|
"single_8s",
|
|
22318
22395
|
"single_15s",
|
|
22319
22396
|
"double_30s"
|
|
22320
22397
|
]).optional(),
|
|
22321
|
-
videoStyle:
|
|
22398
|
+
videoStyle: z86.enum([
|
|
22322
22399
|
"ugc",
|
|
22323
22400
|
"cartoon_3d",
|
|
22324
22401
|
"product_only",
|
|
@@ -22328,13 +22405,13 @@ var StatusForResolveSchema = z85.object({
|
|
|
22328
22405
|
videoQuality: VideoQualityEnum.optional(),
|
|
22329
22406
|
videoRouteId: VideoRouteIdEnum.optional(),
|
|
22330
22407
|
videoModel: TaskVideoModelEnum.optional(),
|
|
22331
|
-
videoTier:
|
|
22408
|
+
videoTier: z86.enum([
|
|
22332
22409
|
"legacy",
|
|
22333
22410
|
"standard",
|
|
22334
22411
|
"pro",
|
|
22335
22412
|
"single_call"
|
|
22336
22413
|
]).optional(),
|
|
22337
|
-
videoResolution:
|
|
22414
|
+
videoResolution: z86.enum([
|
|
22338
22415
|
"480p",
|
|
22339
22416
|
"720p"
|
|
22340
22417
|
]).optional(),
|
|
@@ -22342,60 +22419,60 @@ var StatusForResolveSchema = z85.object({
|
|
|
22342
22419
|
// A task created before a narrative was blocked/hidden must still parse,
|
|
22343
22420
|
// or resolve_pending_action could never approve it.
|
|
22344
22421
|
narrativeStyle: NarrativeStyle.optional(),
|
|
22345
|
-
pauseForVideoScriptReview:
|
|
22346
|
-
pendingUserAction:
|
|
22347
|
-
kind:
|
|
22348
|
-
candidateGrouping:
|
|
22349
|
-
selectedImageUrls:
|
|
22350
|
-
proposedProductNames:
|
|
22422
|
+
pauseForVideoScriptReview: z86.boolean().optional(),
|
|
22423
|
+
pendingUserAction: z86.object({
|
|
22424
|
+
kind: z86.string(),
|
|
22425
|
+
candidateGrouping: z86.string().optional(),
|
|
22426
|
+
selectedImageUrls: z86.array(z86.string()).optional(),
|
|
22427
|
+
proposedProductNames: z86.array(z86.string()).optional(),
|
|
22351
22428
|
// Adaptive reference questions are server-owned. Echo only the evidence
|
|
22352
22429
|
// identity and the choices shown by the current snapshot; never accept a
|
|
22353
22430
|
// client-supplied reference set as authorization.
|
|
22354
|
-
options:
|
|
22355
|
-
mode:
|
|
22431
|
+
options: z86.array(ProductReferenceUserChoiceEnum).max(4).optional(),
|
|
22432
|
+
mode: z86.enum([
|
|
22356
22433
|
"question",
|
|
22357
22434
|
"visual_recovery"
|
|
22358
22435
|
]).optional(),
|
|
22359
22436
|
/** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
|
|
22360
|
-
canKeepSelection:
|
|
22361
|
-
decisionKey:
|
|
22362
|
-
questionOrdinal:
|
|
22363
|
-
questionCeiling:
|
|
22364
|
-
|
|
22365
|
-
|
|
22437
|
+
canKeepSelection: z86.boolean().optional(),
|
|
22438
|
+
decisionKey: z86.string().optional(),
|
|
22439
|
+
questionOrdinal: z86.number().int().min(1).max(5).optional(),
|
|
22440
|
+
questionCeiling: z86.union([
|
|
22441
|
+
z86.literal(3),
|
|
22442
|
+
z86.literal(5)
|
|
22366
22443
|
]).optional(),
|
|
22367
|
-
referenceEvidenceVersion:
|
|
22368
|
-
expectedEvidenceHash:
|
|
22369
|
-
question:
|
|
22370
|
-
prompt:
|
|
22371
|
-
helpText:
|
|
22372
|
-
options:
|
|
22444
|
+
referenceEvidenceVersion: z86.number().int().positive().optional(),
|
|
22445
|
+
expectedEvidenceHash: z86.string().optional(),
|
|
22446
|
+
question: z86.object({
|
|
22447
|
+
prompt: z86.string().min(1).max(240),
|
|
22448
|
+
helpText: z86.string().min(1).max(300).optional(),
|
|
22449
|
+
options: z86.array(z86.object({
|
|
22373
22450
|
value: ProductReferenceUserChoiceEnum,
|
|
22374
|
-
label:
|
|
22375
|
-
description:
|
|
22451
|
+
label: z86.string().min(1).max(120),
|
|
22452
|
+
description: z86.string().min(1).max(240).optional()
|
|
22376
22453
|
})).min(2).max(4)
|
|
22377
22454
|
}).optional(),
|
|
22378
22455
|
scope: ProductReferenceScopeEnum.optional(),
|
|
22379
|
-
scopeKey:
|
|
22380
|
-
scopeSnapshotId:
|
|
22381
|
-
scopeHash:
|
|
22382
|
-
baseReferenceSetHash:
|
|
22383
|
-
phase:
|
|
22456
|
+
scopeKey: z86.string().optional(),
|
|
22457
|
+
scopeSnapshotId: z86.string().uuid().optional(),
|
|
22458
|
+
scopeHash: z86.string().optional(),
|
|
22459
|
+
baseReferenceSetHash: z86.string().optional(),
|
|
22460
|
+
phase: z86.enum([
|
|
22384
22461
|
"preparation",
|
|
22385
22462
|
"final"
|
|
22386
22463
|
]).optional(),
|
|
22387
|
-
selectedRefKeys:
|
|
22388
|
-
allowedDecisions:
|
|
22389
|
-
previews:
|
|
22390
|
-
refKey:
|
|
22464
|
+
selectedRefKeys: z86.array(z86.string().min(1).max(200)).optional(),
|
|
22465
|
+
allowedDecisions: z86.array(ProductReferenceResolutionDecisionEnum).optional(),
|
|
22466
|
+
previews: z86.array(z86.object({
|
|
22467
|
+
refKey: z86.string().min(1).max(200)
|
|
22391
22468
|
}).passthrough()).optional(),
|
|
22392
|
-
customAngleDraft:
|
|
22393
|
-
painPointsDraft:
|
|
22394
|
-
benefitsDraft:
|
|
22395
|
-
featuresDraft:
|
|
22396
|
-
angleOptions:
|
|
22397
|
-
index:
|
|
22398
|
-
angle:
|
|
22469
|
+
customAngleDraft: z86.string().optional(),
|
|
22470
|
+
painPointsDraft: z86.string().optional(),
|
|
22471
|
+
benefitsDraft: z86.string().optional(),
|
|
22472
|
+
featuresDraft: z86.array(z86.string()).optional(),
|
|
22473
|
+
angleOptions: z86.array(z86.object({
|
|
22474
|
+
index: z86.number().int().nonnegative(),
|
|
22475
|
+
angle: z86.string().min(1)
|
|
22399
22476
|
}).passthrough()).min(1).max(5).optional(),
|
|
22400
22477
|
// Recommendation consumed only when the caller explicitly sends
|
|
22401
22478
|
// gapDurationSeconds: 30 in the angle approval action.
|
|
@@ -22405,17 +22482,17 @@ var StatusForResolveSchema = z85.object({
|
|
|
22405
22482
|
// keys. `actorId` (the saved custom actor the picker stored) was silently
|
|
22406
22483
|
// dropped here, so the approval handler below could not echo it back on the
|
|
22407
22484
|
// PATCH — the selection looked accepted and reached no render.
|
|
22408
|
-
angles:
|
|
22409
|
-
id:
|
|
22410
|
-
content:
|
|
22411
|
-
creativeDirection:
|
|
22412
|
-
actor:
|
|
22413
|
-
actorId:
|
|
22485
|
+
angles: z86.array(z86.object({
|
|
22486
|
+
id: z86.string().uuid(),
|
|
22487
|
+
content: z86.string(),
|
|
22488
|
+
creativeDirection: z86.string(),
|
|
22489
|
+
actor: z86.string(),
|
|
22490
|
+
actorId: z86.string().nullable().optional()
|
|
22414
22491
|
}).passthrough()).optional(),
|
|
22415
|
-
panels:
|
|
22416
|
-
beatId:
|
|
22417
|
-
voiceover:
|
|
22418
|
-
visualDirection:
|
|
22492
|
+
panels: z86.array(z86.object({
|
|
22493
|
+
beatId: z86.string(),
|
|
22494
|
+
voiceover: z86.string(),
|
|
22495
|
+
visualDirection: z86.string()
|
|
22419
22496
|
}).passthrough()).optional()
|
|
22420
22497
|
}).optional()
|
|
22421
22498
|
}).passthrough();
|
|
@@ -22762,8 +22839,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
22762
22839
|
server.registerTool("verify_landing_commerce", {
|
|
22763
22840
|
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.",
|
|
22764
22841
|
inputSchema: {
|
|
22765
|
-
taskId:
|
|
22766
|
-
editId:
|
|
22842
|
+
taskId: z86.string().uuid(),
|
|
22843
|
+
editId: z86.string().uuid()
|
|
22767
22844
|
},
|
|
22768
22845
|
annotations: OVERWRITES_EXTERNAL
|
|
22769
22846
|
}, async (input) => {
|
|
@@ -23402,7 +23479,7 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
23402
23479
|
__name(registerTaskTools, "registerTaskTools");
|
|
23403
23480
|
|
|
23404
23481
|
// src/tools/creatives.ts
|
|
23405
|
-
import { z as
|
|
23482
|
+
import { z as z87 } from "zod";
|
|
23406
23483
|
var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
|
|
23407
23484
|
var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
|
|
23408
23485
|
var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
|
|
@@ -23413,71 +23490,71 @@ var CreativeRefs = {
|
|
|
23413
23490
|
images: ImagesInput,
|
|
23414
23491
|
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.'),
|
|
23415
23492
|
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.'),
|
|
23416
|
-
price:
|
|
23417
|
-
offer:
|
|
23418
|
-
compareAtPrice:
|
|
23419
|
-
productContext:
|
|
23420
|
-
productLabel:
|
|
23421
|
-
buyerPersona:
|
|
23422
|
-
isCombo:
|
|
23423
|
-
competitorScanEnabled:
|
|
23424
|
-
brandId:
|
|
23493
|
+
price: z87.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.'),
|
|
23494
|
+
offer: z87.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.'),
|
|
23495
|
+
compareAtPrice: z87.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
|
|
23496
|
+
productContext: z87.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."),
|
|
23497
|
+
productLabel: z87.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.'),
|
|
23498
|
+
buyerPersona: z87.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.'),
|
|
23499
|
+
isCombo: z87.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
|
|
23500
|
+
competitorScanEnabled: z87.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."),
|
|
23501
|
+
brandId: z87.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.")
|
|
23425
23502
|
};
|
|
23426
|
-
var VideoPresenter =
|
|
23427
|
-
|
|
23428
|
-
mode:
|
|
23503
|
+
var VideoPresenter = z87.discriminatedUnion("mode", [
|
|
23504
|
+
z87.object({
|
|
23505
|
+
mode: z87.literal("none")
|
|
23429
23506
|
}).strict(),
|
|
23430
|
-
|
|
23431
|
-
mode:
|
|
23432
|
-
actorId:
|
|
23507
|
+
z87.object({
|
|
23508
|
+
mode: z87.literal("saved_actor"),
|
|
23509
|
+
actorId: z87.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
|
|
23433
23510
|
}).strict(),
|
|
23434
|
-
|
|
23435
|
-
mode:
|
|
23436
|
-
description:
|
|
23511
|
+
z87.object({
|
|
23512
|
+
mode: z87.literal("described"),
|
|
23513
|
+
description: z87.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
|
|
23437
23514
|
}).strict()
|
|
23438
23515
|
]);
|
|
23439
|
-
var VideoCreativeSetup =
|
|
23440
|
-
|
|
23441
|
-
mode:
|
|
23516
|
+
var VideoCreativeSetup = z87.discriminatedUnion("mode", [
|
|
23517
|
+
z87.object({
|
|
23518
|
+
mode: z87.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
|
|
23442
23519
|
}).strict(),
|
|
23443
|
-
|
|
23444
|
-
mode:
|
|
23520
|
+
z87.object({
|
|
23521
|
+
mode: z87.literal("guided"),
|
|
23445
23522
|
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.'),
|
|
23446
|
-
buyerPersona:
|
|
23523
|
+
buyerPersona: z87.string().trim().min(1).max(360),
|
|
23447
23524
|
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.'),
|
|
23448
23525
|
presenter: VideoPresenter,
|
|
23449
|
-
creativeDirection:
|
|
23526
|
+
creativeDirection: z87.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
|
|
23450
23527
|
}).strict()
|
|
23451
23528
|
]);
|
|
23452
|
-
var VideoInput =
|
|
23529
|
+
var VideoInput = z87.object({
|
|
23453
23530
|
images: CreativeRefs.images.optional(),
|
|
23454
23531
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
23455
|
-
title:
|
|
23456
|
-
primaryAngle:
|
|
23532
|
+
title: z87.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
|
|
23533
|
+
primaryAngle: z87.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".'),
|
|
23457
23534
|
language: CreativeRefs.language,
|
|
23458
23535
|
country: CreativeRefs.country,
|
|
23459
|
-
aspectRatio:
|
|
23536
|
+
aspectRatio: z87.enum([
|
|
23460
23537
|
"9:16",
|
|
23461
23538
|
"16:9",
|
|
23462
23539
|
"Auto"
|
|
23463
23540
|
]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
|
|
23464
|
-
durationSeconds:
|
|
23465
|
-
videoAngleCount:
|
|
23541
|
+
durationSeconds: z87.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."),
|
|
23542
|
+
videoAngleCount: z87.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."),
|
|
23466
23543
|
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.'),
|
|
23467
23544
|
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."),
|
|
23468
23545
|
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.'),
|
|
23469
23546
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
|
|
23470
23547
|
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.'),
|
|
23471
|
-
features:
|
|
23548
|
+
features: z87.array(z87.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
|
|
23472
23549
|
price: CreativeRefs.price,
|
|
23473
23550
|
offer: CreativeRefs.offer,
|
|
23474
23551
|
productContext: CreativeRefs.productContext,
|
|
23475
23552
|
productLabel: CreativeRefs.productLabel,
|
|
23476
|
-
cta:
|
|
23477
|
-
scriptNotes:
|
|
23553
|
+
cta: z87.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.'),
|
|
23554
|
+
scriptNotes: z87.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.'),
|
|
23478
23555
|
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.'),
|
|
23479
23556
|
competitorScanEnabled: CreativeRefs.competitorScanEnabled,
|
|
23480
|
-
replicateWinnerWhenFound:
|
|
23557
|
+
replicateWinnerWhenFound: z87.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."),
|
|
23481
23558
|
brandId: CreativeRefs.brandId
|
|
23482
23559
|
}).strict();
|
|
23483
23560
|
var FreeVideoQualityEnum = VideoQualityEnum;
|
|
@@ -23495,7 +23572,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
|
|
|
23495
23572
|
length: 29
|
|
23496
23573
|
}, (_, index) => index + 2)
|
|
23497
23574
|
};
|
|
23498
|
-
var FreeVideoModelIdEnum =
|
|
23575
|
+
var FreeVideoModelIdEnum = z87.enum([
|
|
23499
23576
|
"grok-imagine-video-1-5-preview",
|
|
23500
23577
|
"minimax-h3/reference-to-video",
|
|
23501
23578
|
"wan/3-0-video",
|
|
@@ -23506,65 +23583,65 @@ var FREE_SELECTABLE_MODEL_IDS = [
|
|
|
23506
23583
|
"minimax-h3/reference-to-video",
|
|
23507
23584
|
"wan/3-0-video"
|
|
23508
23585
|
];
|
|
23509
|
-
var FreeVideoInput =
|
|
23586
|
+
var FreeVideoInput = z87.object({
|
|
23510
23587
|
images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
|
|
23511
|
-
rawPrompt:
|
|
23588
|
+
rawPrompt: z87.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."),
|
|
23512
23589
|
language: CreativeRefs.language,
|
|
23513
23590
|
quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
|
|
23514
23591
|
// Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
|
|
23515
23592
|
// parsed ONLY so the handler can reject it with a message naming its
|
|
23516
23593
|
// replacement — dropping it silently would turn a caller's explicit
|
|
23517
23594
|
// Pro++ pick into a quiet fallback to Wan.
|
|
23518
|
-
freeProModel:
|
|
23595
|
+
freeProModel: z87.enum([
|
|
23519
23596
|
"wan",
|
|
23520
23597
|
"seedance"
|
|
23521
23598
|
]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
|
|
23522
23599
|
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.'),
|
|
23523
|
-
durationSeconds:
|
|
23600
|
+
durationSeconds: z87.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."),
|
|
23524
23601
|
videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
|
|
23525
|
-
generateAiMusic:
|
|
23526
|
-
addSubtitles:
|
|
23527
|
-
idempotencyKey:
|
|
23602
|
+
generateAiMusic: z87.boolean().default(false).describe("Opcional. Agrega m\xFAsica instrumental IA debajo del audio nativo. Default false."),
|
|
23603
|
+
addSubtitles: z87.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
|
|
23604
|
+
idempotencyKey: z87.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.")
|
|
23528
23605
|
}).strict();
|
|
23529
23606
|
var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
|
|
23530
|
-
var ImageCreativeSetup =
|
|
23531
|
-
|
|
23532
|
-
mode:
|
|
23607
|
+
var ImageCreativeSetup = z87.discriminatedUnion("mode", [
|
|
23608
|
+
z87.object({
|
|
23609
|
+
mode: z87.literal("automatic")
|
|
23533
23610
|
}).strict(),
|
|
23534
|
-
|
|
23535
|
-
mode:
|
|
23536
|
-
creativeArchetype:
|
|
23611
|
+
z87.object({
|
|
23612
|
+
mode: z87.literal("guided"),
|
|
23613
|
+
creativeArchetype: z87.union([
|
|
23537
23614
|
ImageCreativeArchetypeEnum,
|
|
23538
|
-
|
|
23615
|
+
z87.literal("ai_decides")
|
|
23539
23616
|
]),
|
|
23540
|
-
visualTreatment:
|
|
23617
|
+
visualTreatment: z87.union([
|
|
23541
23618
|
ImageCreativeVisualTreatmentEnum,
|
|
23542
|
-
|
|
23619
|
+
z87.literal("ai_decides")
|
|
23543
23620
|
]),
|
|
23544
23621
|
aspectRatio: ImageCreativeAspectRatioEnum,
|
|
23545
|
-
nVariants:
|
|
23546
|
-
|
|
23547
|
-
|
|
23548
|
-
|
|
23549
|
-
|
|
23550
|
-
|
|
23622
|
+
nVariants: z87.union([
|
|
23623
|
+
z87.literal(1),
|
|
23624
|
+
z87.literal(2),
|
|
23625
|
+
z87.literal(3),
|
|
23626
|
+
z87.literal(4),
|
|
23627
|
+
z87.literal(6)
|
|
23551
23628
|
]),
|
|
23552
|
-
imageModel:
|
|
23553
|
-
styleMix:
|
|
23554
|
-
generateAdCopy:
|
|
23555
|
-
competitorScanEnabled:
|
|
23556
|
-
productContext:
|
|
23557
|
-
creativeDirection:
|
|
23558
|
-
brandColors:
|
|
23559
|
-
headline:
|
|
23560
|
-
subheadline:
|
|
23629
|
+
imageModel: z87.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.'),
|
|
23630
|
+
styleMix: z87.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
|
|
23631
|
+
generateAdCopy: z87.boolean(),
|
|
23632
|
+
competitorScanEnabled: z87.boolean(),
|
|
23633
|
+
productContext: z87.string().trim().min(1).max(3e3).nullable(),
|
|
23634
|
+
creativeDirection: z87.string().trim().min(1).max(500).nullable(),
|
|
23635
|
+
brandColors: z87.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.'),
|
|
23636
|
+
headline: z87.string().trim().min(1).max(120).nullable(),
|
|
23637
|
+
subheadline: z87.string().trim().min(1).max(160).nullable()
|
|
23561
23638
|
}).strict()
|
|
23562
23639
|
]).superRefine((setup, context) => {
|
|
23563
23640
|
if (setup.mode !== "guided") return;
|
|
23564
23641
|
const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
|
|
23565
23642
|
if (needsStyleMix && setup.styleMix === null) {
|
|
23566
23643
|
context.addIssue({
|
|
23567
|
-
code:
|
|
23644
|
+
code: z87.ZodIssueCode.custom,
|
|
23568
23645
|
path: [
|
|
23569
23646
|
"styleMix"
|
|
23570
23647
|
],
|
|
@@ -23573,7 +23650,7 @@ var ImageCreativeSetup = z86.discriminatedUnion("mode", [
|
|
|
23573
23650
|
}
|
|
23574
23651
|
if (!needsStyleMix && setup.styleMix !== null) {
|
|
23575
23652
|
context.addIssue({
|
|
23576
|
-
code:
|
|
23653
|
+
code: z87.ZodIssueCode.custom,
|
|
23577
23654
|
path: [
|
|
23578
23655
|
"styleMix"
|
|
23579
23656
|
],
|
|
@@ -23582,7 +23659,7 @@ var ImageCreativeSetup = z86.discriminatedUnion("mode", [
|
|
|
23582
23659
|
}
|
|
23583
23660
|
if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
|
|
23584
23661
|
context.addIssue({
|
|
23585
|
-
code:
|
|
23662
|
+
code: z87.ZodIssueCode.custom,
|
|
23586
23663
|
path: [
|
|
23587
23664
|
"aspectRatio"
|
|
23588
23665
|
],
|
|
@@ -23590,54 +23667,54 @@ var ImageCreativeSetup = z86.discriminatedUnion("mode", [
|
|
|
23590
23667
|
});
|
|
23591
23668
|
}
|
|
23592
23669
|
});
|
|
23593
|
-
var LandingCreativeSetup =
|
|
23594
|
-
|
|
23595
|
-
mode:
|
|
23670
|
+
var LandingCreativeSetup = z87.discriminatedUnion("mode", [
|
|
23671
|
+
z87.object({
|
|
23672
|
+
mode: z87.literal("automatic")
|
|
23596
23673
|
}).strict(),
|
|
23597
|
-
|
|
23598
|
-
mode:
|
|
23674
|
+
z87.object({
|
|
23675
|
+
mode: z87.literal("guided"),
|
|
23599
23676
|
landingStrategy: LandingStrategyEnum,
|
|
23600
23677
|
landingImageFormat: LandingImageFormatEnum,
|
|
23601
|
-
competitorScanEnabled:
|
|
23602
|
-
paymentMethods:
|
|
23603
|
-
productContext:
|
|
23604
|
-
creativeDirection:
|
|
23605
|
-
headline:
|
|
23606
|
-
subheadline:
|
|
23678
|
+
competitorScanEnabled: z87.boolean(),
|
|
23679
|
+
paymentMethods: z87.string().trim().min(1).max(240).nullable(),
|
|
23680
|
+
productContext: z87.string().trim().min(1).max(3e3).nullable(),
|
|
23681
|
+
creativeDirection: z87.string().trim().min(1).max(500).nullable(),
|
|
23682
|
+
headline: z87.string().trim().min(1).max(120).nullable(),
|
|
23683
|
+
subheadline: z87.string().trim().min(1).max(160).nullable()
|
|
23607
23684
|
}).strict()
|
|
23608
23685
|
]);
|
|
23609
|
-
var ImageInput =
|
|
23686
|
+
var ImageInput = z87.object({
|
|
23610
23687
|
images: CreativeRefs.images.optional(),
|
|
23611
23688
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
23612
|
-
productTitle:
|
|
23613
|
-
primaryAngle:
|
|
23689
|
+
productTitle: z87.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
|
|
23690
|
+
primaryAngle: z87.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.'),
|
|
23614
23691
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
23615
23692
|
language: CreativeRefs.language,
|
|
23616
23693
|
country: CreativeRefs.country,
|
|
23617
23694
|
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."),
|
|
23618
23695
|
imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
|
|
23619
|
-
features:
|
|
23696
|
+
features: z87.array(z87.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
|
|
23620
23697
|
price: CreativeRefs.price,
|
|
23621
|
-
omitPrice:
|
|
23698
|
+
omitPrice: z87.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."),
|
|
23622
23699
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
23623
23700
|
offer: CreativeRefs.offer,
|
|
23624
23701
|
productLabel: CreativeRefs.productLabel,
|
|
23625
23702
|
isCombo: CreativeRefs.isCombo,
|
|
23626
23703
|
brandId: CreativeRefs.brandId
|
|
23627
23704
|
});
|
|
23628
|
-
var EditImageCreativeInput =
|
|
23629
|
-
taskId:
|
|
23630
|
-
variantIndex:
|
|
23631
|
-
clientRequestId:
|
|
23632
|
-
instruction:
|
|
23705
|
+
var EditImageCreativeInput = z87.object({
|
|
23706
|
+
taskId: z87.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
|
|
23707
|
+
variantIndex: z87.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
|
|
23708
|
+
clientRequestId: z87.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."),
|
|
23709
|
+
instruction: z87.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".')
|
|
23633
23710
|
});
|
|
23634
|
-
var LandingInput =
|
|
23711
|
+
var LandingInput = z87.object({
|
|
23635
23712
|
images: CreativeRefs.images.optional(),
|
|
23636
23713
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
23637
23714
|
language: CreativeRefs.language,
|
|
23638
23715
|
country: CreativeRefs.country,
|
|
23639
23716
|
creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
|
|
23640
|
-
salesAngle:
|
|
23717
|
+
salesAngle: z87.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.'),
|
|
23641
23718
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
23642
23719
|
price: CreativeRefs.price,
|
|
23643
23720
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
@@ -23916,8 +23993,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
23916
23993
|
server.registerTool("get_image_edit_status", {
|
|
23917
23994
|
description: imageEditStatusGuidance.summary,
|
|
23918
23995
|
inputSchema: {
|
|
23919
|
-
taskId:
|
|
23920
|
-
operationId:
|
|
23996
|
+
taskId: z87.string().uuid(),
|
|
23997
|
+
operationId: z87.string().uuid()
|
|
23921
23998
|
},
|
|
23922
23999
|
annotations: READS_INTERNAL
|
|
23923
24000
|
}, async (input) => {
|
|
@@ -23974,10 +24051,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
23974
24051
|
__name(registerCreativeTools, "registerCreativeTools");
|
|
23975
24052
|
|
|
23976
24053
|
// src/tools/creative-variants.ts
|
|
23977
|
-
import { z as
|
|
24054
|
+
import { z as z88 } from "zod";
|
|
23978
24055
|
var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
|
|
23979
24056
|
var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
|
|
23980
|
-
var LandingSectionKeyEnum =
|
|
24057
|
+
var LandingSectionKeyEnum = z88.enum([
|
|
23981
24058
|
"problem_hook",
|
|
23982
24059
|
"problem_cost",
|
|
23983
24060
|
"solution_mechanism",
|
|
@@ -24017,24 +24094,24 @@ var LandingSectionKeyEnum = z87.enum([
|
|
|
24017
24094
|
"lifestyle_fit",
|
|
24018
24095
|
"join_lifestyle"
|
|
24019
24096
|
]);
|
|
24020
|
-
var CreativeVariantKindEnum =
|
|
24097
|
+
var CreativeVariantKindEnum = z88.enum([
|
|
24021
24098
|
"video",
|
|
24022
24099
|
"image",
|
|
24023
24100
|
"landing"
|
|
24024
24101
|
]);
|
|
24025
|
-
var EstimateCreativeVariantInputBase =
|
|
24026
|
-
sourceTaskId:
|
|
24102
|
+
var EstimateCreativeVariantInputBase = z88.object({
|
|
24103
|
+
sourceTaskId: z88.string().uuid().describe("ID de la tarea original completada."),
|
|
24027
24104
|
kind: CreativeVariantKindEnum,
|
|
24028
24105
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
|
|
24029
24106
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
|
|
24030
|
-
nVariants:
|
|
24107
|
+
nVariants: z88.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
24031
24108
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
|
|
24032
|
-
instructions:
|
|
24109
|
+
instructions: z88.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.")
|
|
24033
24110
|
}).strict();
|
|
24034
24111
|
var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
24035
24112
|
if (input.kind === "video" && input.nVariants !== void 0) {
|
|
24036
24113
|
ctx.addIssue({
|
|
24037
|
-
code:
|
|
24114
|
+
code: z88.ZodIssueCode.custom,
|
|
24038
24115
|
path: [
|
|
24039
24116
|
"nVariants"
|
|
24040
24117
|
],
|
|
@@ -24044,7 +24121,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
24044
24121
|
if (input.kind !== "video") {
|
|
24045
24122
|
if (input.videoPreset !== void 0) {
|
|
24046
24123
|
ctx.addIssue({
|
|
24047
|
-
code:
|
|
24124
|
+
code: z88.ZodIssueCode.custom,
|
|
24048
24125
|
path: [
|
|
24049
24126
|
"videoPreset"
|
|
24050
24127
|
],
|
|
@@ -24053,7 +24130,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
24053
24130
|
}
|
|
24054
24131
|
if (input.videoResolution !== void 0) {
|
|
24055
24132
|
ctx.addIssue({
|
|
24056
|
-
code:
|
|
24133
|
+
code: z88.ZodIssueCode.custom,
|
|
24057
24134
|
path: [
|
|
24058
24135
|
"videoResolution"
|
|
24059
24136
|
],
|
|
@@ -24063,7 +24140,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
24063
24140
|
}
|
|
24064
24141
|
if (input.kind !== "image" && input.nVariants !== void 0) {
|
|
24065
24142
|
ctx.addIssue({
|
|
24066
|
-
code:
|
|
24143
|
+
code: z88.ZodIssueCode.custom,
|
|
24067
24144
|
path: [
|
|
24068
24145
|
"nVariants"
|
|
24069
24146
|
],
|
|
@@ -24073,7 +24150,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
24073
24150
|
if (input.kind !== "landing") {
|
|
24074
24151
|
if (input.sectionKey !== void 0) {
|
|
24075
24152
|
ctx.addIssue({
|
|
24076
|
-
code:
|
|
24153
|
+
code: z88.ZodIssueCode.custom,
|
|
24077
24154
|
path: [
|
|
24078
24155
|
"sectionKey"
|
|
24079
24156
|
],
|
|
@@ -24082,7 +24159,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
24082
24159
|
}
|
|
24083
24160
|
if (input.instructions !== void 0) {
|
|
24084
24161
|
ctx.addIssue({
|
|
24085
|
-
code:
|
|
24162
|
+
code: z88.ZodIssueCode.custom,
|
|
24086
24163
|
path: [
|
|
24087
24164
|
"instructions"
|
|
24088
24165
|
],
|
|
@@ -24091,31 +24168,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
24091
24168
|
}
|
|
24092
24169
|
}
|
|
24093
24170
|
});
|
|
24094
|
-
var CreateCreativeVariantInputBase =
|
|
24095
|
-
sourceTaskId:
|
|
24171
|
+
var CreateCreativeVariantInputBase = z88.object({
|
|
24172
|
+
sourceTaskId: z88.string().uuid().describe("ID de la tarea original completada."),
|
|
24096
24173
|
kind: CreativeVariantKindEnum,
|
|
24097
|
-
confirm:
|
|
24098
|
-
clientRequestId:
|
|
24099
|
-
angle:
|
|
24100
|
-
buyerPersona:
|
|
24101
|
-
scriptNotes:
|
|
24102
|
-
creativeDirection:
|
|
24174
|
+
confirm: z88.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
|
|
24175
|
+
clientRequestId: z88.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."),
|
|
24176
|
+
angle: z88.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
|
|
24177
|
+
buyerPersona: z88.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
|
|
24178
|
+
scriptNotes: z88.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
|
|
24179
|
+
creativeDirection: z88.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
|
|
24103
24180
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
|
|
24104
24181
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
|
|
24105
|
-
generateAiMusic:
|
|
24106
|
-
nVariants:
|
|
24182
|
+
generateAiMusic: z88.boolean().optional().describe("Opcional para video."),
|
|
24183
|
+
nVariants: z88.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
24107
24184
|
imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
|
|
24108
24185
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
|
|
24109
24186
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
|
|
24110
24187
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
|
|
24111
|
-
styleMix:
|
|
24188
|
+
styleMix: z88.boolean().optional().describe("Opcional para imagen."),
|
|
24112
24189
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
|
|
24113
|
-
instructions:
|
|
24190
|
+
instructions: z88.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.")
|
|
24114
24191
|
}).strict();
|
|
24115
24192
|
var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
24116
24193
|
if ((input.kind === "video" || input.kind === "image") && !input.angle) {
|
|
24117
24194
|
ctx.addIssue({
|
|
24118
|
-
code:
|
|
24195
|
+
code: z88.ZodIssueCode.custom,
|
|
24119
24196
|
path: [
|
|
24120
24197
|
"angle"
|
|
24121
24198
|
],
|
|
@@ -24124,7 +24201,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
24124
24201
|
}
|
|
24125
24202
|
if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
|
|
24126
24203
|
ctx.addIssue({
|
|
24127
|
-
code:
|
|
24204
|
+
code: z88.ZodIssueCode.custom,
|
|
24128
24205
|
path: [
|
|
24129
24206
|
"instructions"
|
|
24130
24207
|
],
|
|
@@ -24170,7 +24247,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
24170
24247
|
for (const field of fieldsByKind[input.kind]) {
|
|
24171
24248
|
if (input[field] !== void 0) {
|
|
24172
24249
|
ctx.addIssue({
|
|
24173
|
-
code:
|
|
24250
|
+
code: z88.ZodIssueCode.custom,
|
|
24174
24251
|
path: [
|
|
24175
24252
|
field
|
|
24176
24253
|
],
|
|
@@ -24303,13 +24380,13 @@ function registerCreativeVariantTools(server, api) {
|
|
|
24303
24380
|
__name(registerCreativeVariantTools, "registerCreativeVariantTools");
|
|
24304
24381
|
|
|
24305
24382
|
// src/tools/script-review.ts
|
|
24306
|
-
import { z as
|
|
24383
|
+
import { z as z89 } from "zod";
|
|
24307
24384
|
var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
|
|
24308
24385
|
var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
|
|
24309
24386
|
var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
|
|
24310
|
-
var GetVideoScriptInput =
|
|
24311
|
-
taskId:
|
|
24312
|
-
angleKey:
|
|
24387
|
+
var GetVideoScriptInput = z89.object({
|
|
24388
|
+
taskId: z89.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
|
|
24389
|
+
angleKey: z89.string().min(1).optional().describe('Clave del \xE1ngulo cuyo guion se quiere leer (formato "angle_0", "angle_1", ...). REQUERIDO para tareas multi-angle: si se omite, el backend resuelve a "angle_0" LITERAL (no "el primer pendiente"), as\xED que en multi-angle donde angle_0 ya est\xE9 aprobado/saltado obtendr\xEDas status="approved" y nunca alcanzar\xEDas el \xE1ngulo realmente pendiente. Para single-angle puede omitirse.')
|
|
24313
24390
|
}).strict();
|
|
24314
24391
|
var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
|
|
24315
24392
|
var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
|
|
@@ -24392,7 +24469,7 @@ function registerScriptReviewTools(server, api) {
|
|
|
24392
24469
|
__name(registerScriptReviewTools, "registerScriptReviewTools");
|
|
24393
24470
|
|
|
24394
24471
|
// src/tools/connections.ts
|
|
24395
|
-
import { z as
|
|
24472
|
+
import { z as z90 } from "zod";
|
|
24396
24473
|
var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
|
|
24397
24474
|
var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
|
|
24398
24475
|
var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
|
|
@@ -24401,7 +24478,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
|
|
|
24401
24478
|
function registerConnectionTools(server, api) {
|
|
24402
24479
|
server.registerTool("list_shopify_shops", {
|
|
24403
24480
|
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.",
|
|
24404
|
-
inputSchema:
|
|
24481
|
+
inputSchema: z90.object({}).shape,
|
|
24405
24482
|
annotations: READS_INTERNAL
|
|
24406
24483
|
}, async () => {
|
|
24407
24484
|
try {
|
|
@@ -24413,10 +24490,10 @@ function registerConnectionTools(server, api) {
|
|
|
24413
24490
|
});
|
|
24414
24491
|
server.registerTool("list_shopify_products", {
|
|
24415
24492
|
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.',
|
|
24416
|
-
inputSchema:
|
|
24417
|
-
shopDomain:
|
|
24418
|
-
query:
|
|
24419
|
-
taskId:
|
|
24493
|
+
inputSchema: z90.object({
|
|
24494
|
+
shopDomain: z90.string().min(3).max(120),
|
|
24495
|
+
query: z90.string().trim().max(120).optional(),
|
|
24496
|
+
taskId: z90.string().uuid().optional()
|
|
24420
24497
|
}).shape,
|
|
24421
24498
|
annotations: READS_EXTERNAL
|
|
24422
24499
|
}, async ({ shopDomain, query, taskId }) => {
|
|
@@ -24434,7 +24511,7 @@ function registerConnectionTools(server, api) {
|
|
|
24434
24511
|
});
|
|
24435
24512
|
server.registerTool("list_meta_ad_accounts", {
|
|
24436
24513
|
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.",
|
|
24437
|
-
inputSchema:
|
|
24514
|
+
inputSchema: z90.object({}).shape,
|
|
24438
24515
|
annotations: READS_EXTERNAL
|
|
24439
24516
|
}, async () => {
|
|
24440
24517
|
try {
|
|
@@ -24446,7 +24523,7 @@ function registerConnectionTools(server, api) {
|
|
|
24446
24523
|
});
|
|
24447
24524
|
server.registerTool("list_meta_destinations", {
|
|
24448
24525
|
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.",
|
|
24449
|
-
inputSchema:
|
|
24526
|
+
inputSchema: z90.object({}).shape,
|
|
24450
24527
|
annotations: READS_EXTERNAL,
|
|
24451
24528
|
_meta: {
|
|
24452
24529
|
"openai/widgetAccessible": true
|
|
@@ -24461,7 +24538,7 @@ function registerConnectionTools(server, api) {
|
|
|
24461
24538
|
});
|
|
24462
24539
|
server.registerTool("list_tiktok_advertisers", {
|
|
24463
24540
|
description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
|
|
24464
|
-
inputSchema:
|
|
24541
|
+
inputSchema: z90.object({}).shape,
|
|
24465
24542
|
annotations: READS_EXTERNAL
|
|
24466
24543
|
}, async () => {
|
|
24467
24544
|
try {
|
|
@@ -24475,12 +24552,12 @@ function registerConnectionTools(server, api) {
|
|
|
24475
24552
|
__name(registerConnectionTools, "registerConnectionTools");
|
|
24476
24553
|
|
|
24477
24554
|
// src/tools/actors.ts
|
|
24478
|
-
import { z as
|
|
24555
|
+
import { z as z91 } from "zod";
|
|
24479
24556
|
var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
|
|
24480
24557
|
function registerActorTools(server, api) {
|
|
24481
24558
|
server.registerTool("list_actors", {
|
|
24482
24559
|
description: listActorsGuidance.summary + " Devuelve id, nombre, descripci\xF3n, g\xE9nero y voz. 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.",
|
|
24483
|
-
inputSchema:
|
|
24560
|
+
inputSchema: z91.object({}).shape,
|
|
24484
24561
|
annotations: READS_INTERNAL
|
|
24485
24562
|
}, async () => {
|
|
24486
24563
|
try {
|
|
@@ -24503,7 +24580,7 @@ function registerActorTools(server, api) {
|
|
|
24503
24580
|
__name(registerActorTools, "registerActorTools");
|
|
24504
24581
|
|
|
24505
24582
|
// src/tools/publish.ts
|
|
24506
|
-
import { z as
|
|
24583
|
+
import { z as z92 } from "zod";
|
|
24507
24584
|
|
|
24508
24585
|
// src/tools/meta-publish-attempt-id.ts
|
|
24509
24586
|
var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
|
|
@@ -24542,40 +24619,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
|
|
|
24542
24619
|
var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
|
|
24543
24620
|
var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
|
|
24544
24621
|
var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
|
|
24545
|
-
var ShopifyInput =
|
|
24546
|
-
taskId:
|
|
24547
|
-
shopDomain:
|
|
24622
|
+
var ShopifyInput = z92.object({
|
|
24623
|
+
taskId: z92.string().min(1),
|
|
24624
|
+
shopDomain: z92.string().min(1),
|
|
24548
24625
|
/** Override: number of landing images to include. Default = ALL images the
|
|
24549
24626
|
* task generated (the MCP fetches /v1/results first to count). Bounded
|
|
24550
24627
|
* generously here; the backend validates each index against
|
|
24551
24628
|
* landing.images.length and rejects out-of-range. */
|
|
24552
|
-
numLandingImages:
|
|
24553
|
-
variantIndex:
|
|
24629
|
+
numLandingImages: z92.number().int().min(1).max(20).optional(),
|
|
24630
|
+
variantIndex: z92.number().int().min(0).optional(),
|
|
24554
24631
|
/** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
|
|
24555
24632
|
* When true, the landing renders variant-picker pills; when false, it ships
|
|
24556
24633
|
* a single-option product page. Defaults to false. */
|
|
24557
|
-
showVariantPicker:
|
|
24634
|
+
showVariantPicker: z92.boolean().optional(),
|
|
24558
24635
|
/** Default `auto` updates the product previously published for this task and
|
|
24559
24636
|
* shop. Use `existing` with targetProductId to choose another product, or
|
|
24560
24637
|
* `new` only when the user explicitly wants a duplicate/new listing. */
|
|
24561
|
-
publicationMode:
|
|
24638
|
+
publicationMode: z92.enum([
|
|
24562
24639
|
"auto",
|
|
24563
24640
|
"existing",
|
|
24564
24641
|
"new"
|
|
24565
24642
|
]).optional(),
|
|
24566
24643
|
/** Shopify product GID, numeric id, or admin product URL. Required when
|
|
24567
24644
|
* publicationMode is `existing`. */
|
|
24568
|
-
targetProductId:
|
|
24645
|
+
targetProductId: z92.string().trim().min(1).max(300).optional(),
|
|
24569
24646
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
24570
|
-
announcementBarEnabled:
|
|
24571
|
-
announcementBarText:
|
|
24647
|
+
announcementBarEnabled: z92.boolean().optional(),
|
|
24648
|
+
announcementBarText: z92.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
|
|
24572
24649
|
commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
|
|
24573
|
-
confirmed:
|
|
24650
|
+
confirmed: z92.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
|
|
24574
24651
|
});
|
|
24575
24652
|
var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
|
|
24576
24653
|
if (value.commerceCorrection && value.confirmed !== true) {
|
|
24577
24654
|
ctx.addIssue({
|
|
24578
|
-
code:
|
|
24655
|
+
code: z92.ZodIssueCode.custom,
|
|
24579
24656
|
path: [
|
|
24580
24657
|
"confirmed"
|
|
24581
24658
|
],
|
|
@@ -24584,7 +24661,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
24584
24661
|
}
|
|
24585
24662
|
if (value.announcementBarEnabled && !value.announcementBarText) {
|
|
24586
24663
|
ctx.addIssue({
|
|
24587
|
-
code:
|
|
24664
|
+
code: z92.ZodIssueCode.custom,
|
|
24588
24665
|
path: [
|
|
24589
24666
|
"announcementBarText"
|
|
24590
24667
|
],
|
|
@@ -24593,7 +24670,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
24593
24670
|
}
|
|
24594
24671
|
if (!value.announcementBarEnabled && value.announcementBarText) {
|
|
24595
24672
|
ctx.addIssue({
|
|
24596
|
-
code:
|
|
24673
|
+
code: z92.ZodIssueCode.custom,
|
|
24597
24674
|
path: [
|
|
24598
24675
|
"announcementBarText"
|
|
24599
24676
|
],
|
|
@@ -24607,91 +24684,91 @@ function parseShopifyInput(rawInput) {
|
|
|
24607
24684
|
return parsed.data;
|
|
24608
24685
|
}
|
|
24609
24686
|
__name(parseShopifyInput, "parseShopifyInput");
|
|
24610
|
-
var McpCampaignConfig =
|
|
24687
|
+
var McpCampaignConfig = z92.object({
|
|
24611
24688
|
/** ALWAYS in US dollars, whatever the ad account's currency is. ProductMaker
|
|
24612
24689
|
* converts to the account currency server-side. Do NOT pre-convert: on a COP
|
|
24613
24690
|
* account the user's "60.000 al día" is `dailyBudgetUsd: 15`, not 60000. */
|
|
24614
|
-
dailyBudgetUsd:
|
|
24691
|
+
dailyBudgetUsd: z92.number().positive().optional(),
|
|
24615
24692
|
/** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
|
|
24616
24693
|
* normalizes at validation). Meta accepts max 1 (single-country ad set).
|
|
24617
24694
|
* TikTok takes only the first entry. */
|
|
24618
|
-
targetCountries:
|
|
24619
|
-
campaignName:
|
|
24695
|
+
targetCountries: z92.array(CountryIso2Schema).max(1).optional(),
|
|
24696
|
+
campaignName: z92.string().trim().min(1).max(100).optional()
|
|
24620
24697
|
});
|
|
24621
24698
|
var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
|
|
24622
|
-
var MetaInput =
|
|
24623
|
-
taskId:
|
|
24699
|
+
var MetaInput = z92.object({
|
|
24700
|
+
taskId: z92.string().min(1),
|
|
24624
24701
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
24625
|
-
portfolioId:
|
|
24702
|
+
portfolioId: z92.string().trim().min(1),
|
|
24626
24703
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
24627
|
-
pageId:
|
|
24704
|
+
pageId: z92.string().trim().min(1),
|
|
24628
24705
|
adAccountId: McpAdAccountId,
|
|
24629
|
-
pixelId:
|
|
24630
|
-
landingUrl:
|
|
24706
|
+
pixelId: z92.string().min(1).optional(),
|
|
24707
|
+
landingUrl: z92.string().url().optional(),
|
|
24631
24708
|
/** Select which angles to publish by 0-based index. Omit to publish all
|
|
24632
24709
|
* successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
|
|
24633
|
-
angleIndexes:
|
|
24710
|
+
angleIndexes: z92.array(z92.number().int().nonnegative()).optional(),
|
|
24634
24711
|
campaignConfig: McpCampaignConfig.optional(),
|
|
24635
24712
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
24636
24713
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
24637
24714
|
* (Meta's primary-text limit). */
|
|
24638
|
-
primaryText:
|
|
24715
|
+
primaryText: z92.string().trim().min(1).max(500).optional(),
|
|
24639
24716
|
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
24640
24717
|
* (wa.me) instead of a landing page. */
|
|
24641
|
-
phoneNumber:
|
|
24718
|
+
phoneNumber: z92.string().min(8).max(32).optional()
|
|
24642
24719
|
});
|
|
24643
|
-
var GroupedTaskSource =
|
|
24644
|
-
type:
|
|
24645
|
-
taskId:
|
|
24646
|
-
angleIndex:
|
|
24647
|
-
videoVariant:
|
|
24720
|
+
var GroupedTaskSource = z92.object({
|
|
24721
|
+
type: z92.literal("task"),
|
|
24722
|
+
taskId: z92.string().min(1),
|
|
24723
|
+
angleIndex: z92.number().int().min(0).optional(),
|
|
24724
|
+
videoVariant: z92.enum([
|
|
24648
24725
|
"with_subtitles",
|
|
24649
24726
|
"without_subtitles"
|
|
24650
24727
|
]).optional(),
|
|
24651
|
-
imageVariantIndex:
|
|
24652
|
-
});
|
|
24653
|
-
var GroupedMediaSource =
|
|
24654
|
-
type:
|
|
24655
|
-
url:
|
|
24656
|
-
path:
|
|
24657
|
-
thumbnailUrl:
|
|
24658
|
-
thumbnailPath:
|
|
24728
|
+
imageVariantIndex: z92.number().int().min(0).optional()
|
|
24729
|
+
});
|
|
24730
|
+
var GroupedMediaSource = z92.object({
|
|
24731
|
+
type: z92.literal("media"),
|
|
24732
|
+
url: z92.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
|
|
24733
|
+
path: z92.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".'),
|
|
24734
|
+
thumbnailUrl: z92.string().url().optional(),
|
|
24735
|
+
thumbnailPath: z92.string().min(1).optional()
|
|
24659
24736
|
}).refine((value) => Boolean(value.url) !== Boolean(value.path), {
|
|
24660
24737
|
message: "media source needs exactly one of `url` or `path`"
|
|
24661
24738
|
}).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
|
|
24662
24739
|
message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
|
|
24663
24740
|
});
|
|
24664
|
-
var GroupedUploadedAssetSource =
|
|
24665
|
-
type:
|
|
24741
|
+
var GroupedUploadedAssetSource = z92.object({
|
|
24742
|
+
type: z92.literal("asset"),
|
|
24666
24743
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
24667
|
-
assetId:
|
|
24668
|
-
thumbnailAssetId:
|
|
24744
|
+
assetId: z92.string().uuid(),
|
|
24745
|
+
thumbnailAssetId: z92.string().uuid().optional()
|
|
24669
24746
|
});
|
|
24670
|
-
var GroupedCreative =
|
|
24671
|
-
type:
|
|
24747
|
+
var GroupedCreative = z92.object({
|
|
24748
|
+
type: z92.enum([
|
|
24672
24749
|
"image",
|
|
24673
24750
|
"video"
|
|
24674
24751
|
]),
|
|
24675
|
-
source:
|
|
24752
|
+
source: z92.union([
|
|
24676
24753
|
GroupedTaskSource,
|
|
24677
24754
|
GroupedMediaSource,
|
|
24678
24755
|
GroupedUploadedAssetSource
|
|
24679
24756
|
]),
|
|
24680
|
-
title:
|
|
24681
|
-
description:
|
|
24757
|
+
title: z92.string().max(120).optional(),
|
|
24758
|
+
description: z92.string().max(500).optional(),
|
|
24682
24759
|
cta: MetaCtaType.optional(),
|
|
24683
|
-
creativeId:
|
|
24760
|
+
creativeId: z92.string().min(1).optional()
|
|
24684
24761
|
});
|
|
24685
|
-
var GroupedCampaignConfigBase =
|
|
24762
|
+
var GroupedCampaignConfigBase = z92.object({
|
|
24686
24763
|
campaignType: MetaCampaignType.default("sales"),
|
|
24687
24764
|
optimizationMode: MetaOptimizationMode.default("advantage_plus"),
|
|
24688
24765
|
budgetMode: MetaBudgetMode.optional(),
|
|
24689
|
-
campaignDailyBudget:
|
|
24690
|
-
adSets:
|
|
24691
|
-
tempId:
|
|
24692
|
-
name:
|
|
24693
|
-
dailyBudget:
|
|
24694
|
-
creativeIds:
|
|
24766
|
+
campaignDailyBudget: z92.number().int().positive().optional(),
|
|
24767
|
+
adSets: z92.array(z92.object({
|
|
24768
|
+
tempId: z92.string().min(1).max(80),
|
|
24769
|
+
name: z92.string().min(1).max(100),
|
|
24770
|
+
dailyBudget: z92.number().int().positive().optional(),
|
|
24771
|
+
creativeIds: z92.array(z92.string().min(1)).min(1)
|
|
24695
24772
|
})).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
|
|
24696
24773
|
/**
|
|
24697
24774
|
* Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
|
|
@@ -24699,17 +24776,17 @@ var GroupedCampaignConfigBase = z91.object({
|
|
|
24699
24776
|
* opaque `invalid_literal` and made the WhatsApp destination — supported by
|
|
24700
24777
|
* the API since #849 — unreachable from this tool.
|
|
24701
24778
|
*/
|
|
24702
|
-
destination:
|
|
24703
|
-
|
|
24704
|
-
type:
|
|
24705
|
-
landingUrl:
|
|
24779
|
+
destination: z92.discriminatedUnion("type", [
|
|
24780
|
+
z92.object({
|
|
24781
|
+
type: z92.literal("landing"),
|
|
24782
|
+
landingUrl: z92.string().url()
|
|
24706
24783
|
}),
|
|
24707
|
-
|
|
24708
|
-
type:
|
|
24709
|
-
phoneNumber:
|
|
24784
|
+
z92.object({
|
|
24785
|
+
type: z92.literal("whatsapp"),
|
|
24786
|
+
phoneNumber: z92.string().min(8).max(32)
|
|
24710
24787
|
})
|
|
24711
24788
|
]),
|
|
24712
|
-
saveAsDefault:
|
|
24789
|
+
saveAsDefault: z92.boolean().default(false),
|
|
24713
24790
|
budgetPolicy: MetaBudgetPolicy.optional()
|
|
24714
24791
|
});
|
|
24715
24792
|
function resolveBudgetMode(value) {
|
|
@@ -24723,7 +24800,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
24723
24800
|
const budgetMode = resolveBudgetMode(value);
|
|
24724
24801
|
if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
|
|
24725
24802
|
ctx.addIssue({
|
|
24726
|
-
code:
|
|
24803
|
+
code: z92.ZodIssueCode.custom,
|
|
24727
24804
|
path: [
|
|
24728
24805
|
"campaignDailyBudget"
|
|
24729
24806
|
],
|
|
@@ -24734,7 +24811,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
24734
24811
|
value.adSets.forEach((adSet, index) => {
|
|
24735
24812
|
if (adSet.dailyBudget === void 0) {
|
|
24736
24813
|
ctx.addIssue({
|
|
24737
|
-
code:
|
|
24814
|
+
code: z92.ZodIssueCode.custom,
|
|
24738
24815
|
path: [
|
|
24739
24816
|
"adSets",
|
|
24740
24817
|
index,
|
|
@@ -24749,28 +24826,28 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
24749
24826
|
...value,
|
|
24750
24827
|
budgetMode: resolveBudgetMode(value)
|
|
24751
24828
|
}));
|
|
24752
|
-
var PublishCreativesToMetaInputBase =
|
|
24753
|
-
creatives:
|
|
24829
|
+
var PublishCreativesToMetaInputBase = z92.object({
|
|
24830
|
+
creatives: z92.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
|
|
24754
24831
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
24755
|
-
portfolioId:
|
|
24832
|
+
portfolioId: z92.string().trim().min(1),
|
|
24756
24833
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
24757
|
-
pageId:
|
|
24834
|
+
pageId: z92.string().trim().min(1),
|
|
24758
24835
|
adAccountId: McpAdAccountId,
|
|
24759
|
-
pixelId:
|
|
24836
|
+
pixelId: z92.string().min(1).optional(),
|
|
24760
24837
|
/** Required unless `campaignConfig.destination` is whatsapp — see the
|
|
24761
24838
|
* superRefine below. Mirrors the API's `FacebookCreateCampaignFromTasksBodySchema`. */
|
|
24762
|
-
landingUrl:
|
|
24839
|
+
landingUrl: z92.string().url().optional(),
|
|
24763
24840
|
/** ISO-2 code or resolvable country name — mirrors the API contract
|
|
24764
24841
|
* (CountryIso2Schema), which normalizes names to alpha-2 at validation. */
|
|
24765
24842
|
targetCountry: CountryIso2Schema,
|
|
24766
|
-
campaignName:
|
|
24843
|
+
campaignName: z92.string().trim().min(1).max(100),
|
|
24767
24844
|
campaignConfig: GroupedCampaignConfig.optional()
|
|
24768
24845
|
});
|
|
24769
24846
|
var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
|
|
24770
24847
|
const destination = value.campaignConfig?.destination;
|
|
24771
24848
|
if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl) {
|
|
24772
24849
|
ctx.addIssue({
|
|
24773
|
-
code:
|
|
24850
|
+
code: z92.ZodIssueCode.custom,
|
|
24774
24851
|
path: [
|
|
24775
24852
|
"landingUrl"
|
|
24776
24853
|
],
|
|
@@ -24779,7 +24856,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
24779
24856
|
}
|
|
24780
24857
|
if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
|
|
24781
24858
|
ctx.addIssue({
|
|
24782
|
-
code:
|
|
24859
|
+
code: z92.ZodIssueCode.custom,
|
|
24783
24860
|
path: [
|
|
24784
24861
|
"campaignConfig",
|
|
24785
24862
|
"destination",
|
|
@@ -24798,16 +24875,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
24798
24875
|
}
|
|
24799
24876
|
return value;
|
|
24800
24877
|
});
|
|
24801
|
-
var PresignUploadResponseSchema =
|
|
24802
|
-
uploadUrl:
|
|
24878
|
+
var PresignUploadResponseSchema = z92.object({
|
|
24879
|
+
uploadUrl: z92.string().url().refine((value) => {
|
|
24803
24880
|
const url = new URL(value);
|
|
24804
24881
|
return !url.username && !url.password && url.protocol === "https:";
|
|
24805
24882
|
}, "presigned upload URL must be HTTPS without embedded credentials"),
|
|
24806
|
-
publicUrl:
|
|
24883
|
+
publicUrl: z92.string().url().refine((value) => {
|
|
24807
24884
|
const url = new URL(value);
|
|
24808
24885
|
return !url.username && !url.password;
|
|
24809
24886
|
}, "public media URL must not contain embedded credentials"),
|
|
24810
|
-
stagingAssetId:
|
|
24887
|
+
stagingAssetId: z92.string().uuid()
|
|
24811
24888
|
});
|
|
24812
24889
|
async function uploadResolvedMedia(api, media, assetRole) {
|
|
24813
24890
|
if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
|
|
@@ -24832,16 +24909,16 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
|
|
|
24832
24909
|
return uploadResolvedMedia(api, media, assetRole);
|
|
24833
24910
|
}
|
|
24834
24911
|
__name(resolveAndUploadMedia, "resolveAndUploadMedia");
|
|
24835
|
-
var TikTokInput =
|
|
24836
|
-
taskId:
|
|
24837
|
-
advertiserId:
|
|
24838
|
-
pixelId:
|
|
24839
|
-
landingUrl:
|
|
24840
|
-
angleIndexes:
|
|
24912
|
+
var TikTokInput = z92.object({
|
|
24913
|
+
taskId: z92.string().min(1),
|
|
24914
|
+
advertiserId: z92.string().min(1),
|
|
24915
|
+
pixelId: z92.string().min(1).optional(),
|
|
24916
|
+
landingUrl: z92.string().url().optional(),
|
|
24917
|
+
angleIndexes: z92.array(z92.number().int().nonnegative()).optional(),
|
|
24841
24918
|
campaignConfig: McpCampaignConfig.optional(),
|
|
24842
24919
|
/** Override the ad's description (TikTok's body copy). If omitted,
|
|
24843
24920
|
* ProductMaker uses the auto-generated copy attached to the task. */
|
|
24844
|
-
primaryText:
|
|
24921
|
+
primaryText: z92.string().trim().min(1).max(500).optional()
|
|
24845
24922
|
});
|
|
24846
24923
|
function registerPublishTools(server, api, opts = {}) {
|
|
24847
24924
|
const transport = opts.transport ?? "http";
|
|
@@ -25193,39 +25270,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
|
|
|
25193
25270
|
|
|
25194
25271
|
// src/tools/meta-upload.ts
|
|
25195
25272
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
25196
|
-
import { z as
|
|
25273
|
+
import { z as z93 } from "zod";
|
|
25197
25274
|
var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
|
|
25198
|
-
var UploadSessionInputBase =
|
|
25199
|
-
mediaKind:
|
|
25275
|
+
var UploadSessionInputBase = z93.object({
|
|
25276
|
+
mediaKind: z93.enum([
|
|
25200
25277
|
"image",
|
|
25201
25278
|
"video",
|
|
25202
25279
|
"mixed"
|
|
25203
25280
|
]).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."),
|
|
25204
|
-
assetRole:
|
|
25281
|
+
assetRole: z93.enum([
|
|
25205
25282
|
"media",
|
|
25206
25283
|
"thumbnail"
|
|
25207
25284
|
]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
|
|
25208
|
-
uploadPurpose:
|
|
25285
|
+
uploadPurpose: z93.enum([
|
|
25209
25286
|
"product_reference",
|
|
25210
25287
|
"creative",
|
|
25211
25288
|
"generic"
|
|
25212
25289
|
]).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."),
|
|
25213
|
-
maxFiles:
|
|
25290
|
+
maxFiles: z93.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
25214
25291
|
});
|
|
25215
|
-
var OpenAiFileReference =
|
|
25216
|
-
download_url:
|
|
25217
|
-
file_id:
|
|
25218
|
-
mime_type:
|
|
25219
|
-
file_name:
|
|
25292
|
+
var OpenAiFileReference = z93.object({
|
|
25293
|
+
download_url: z93.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."),
|
|
25294
|
+
file_id: z93.string().min(1),
|
|
25295
|
+
mime_type: z93.string().min(1).optional(),
|
|
25296
|
+
file_name: z93.string().min(1).optional()
|
|
25220
25297
|
});
|
|
25221
25298
|
var UploadSessionToolInputShape = {
|
|
25222
25299
|
...UploadSessionInputBase.shape,
|
|
25223
|
-
files:
|
|
25300
|
+
files: z93.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.")
|
|
25224
25301
|
};
|
|
25225
|
-
var UploadSessionToolInput =
|
|
25302
|
+
var UploadSessionToolInput = z93.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
25226
25303
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
25227
25304
|
ctx.addIssue({
|
|
25228
|
-
code:
|
|
25305
|
+
code: z93.ZodIssueCode.custom,
|
|
25229
25306
|
path: [
|
|
25230
25307
|
"mediaKind"
|
|
25231
25308
|
],
|
|
@@ -25234,7 +25311,7 @@ var UploadSessionToolInput = z92.object(UploadSessionToolInputShape).superRefine
|
|
|
25234
25311
|
}
|
|
25235
25312
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
25236
25313
|
ctx.addIssue({
|
|
25237
|
-
code:
|
|
25314
|
+
code: z93.ZodIssueCode.custom,
|
|
25238
25315
|
path: [
|
|
25239
25316
|
"maxFiles"
|
|
25240
25317
|
],
|
|
@@ -25243,7 +25320,7 @@ var UploadSessionToolInput = z92.object(UploadSessionToolInputShape).superRefine
|
|
|
25243
25320
|
}
|
|
25244
25321
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
|
|
25245
25322
|
ctx.addIssue({
|
|
25246
|
-
code:
|
|
25323
|
+
code: z93.ZodIssueCode.custom,
|
|
25247
25324
|
path: [
|
|
25248
25325
|
"maxFiles"
|
|
25249
25326
|
],
|
|
@@ -25251,38 +25328,38 @@ var UploadSessionToolInput = z92.object(UploadSessionToolInputShape).superRefine
|
|
|
25251
25328
|
});
|
|
25252
25329
|
}
|
|
25253
25330
|
});
|
|
25254
|
-
var UploadSessionResponse =
|
|
25255
|
-
sessionId:
|
|
25256
|
-
uploadPageUrl:
|
|
25257
|
-
mediaKind:
|
|
25331
|
+
var UploadSessionResponse = z93.object({
|
|
25332
|
+
sessionId: z93.string().uuid(),
|
|
25333
|
+
uploadPageUrl: z93.string().url(),
|
|
25334
|
+
mediaKind: z93.enum([
|
|
25258
25335
|
"image",
|
|
25259
25336
|
"video",
|
|
25260
25337
|
"mixed"
|
|
25261
25338
|
]),
|
|
25262
|
-
assetRole:
|
|
25339
|
+
assetRole: z93.enum([
|
|
25263
25340
|
"media",
|
|
25264
25341
|
"thumbnail"
|
|
25265
25342
|
]),
|
|
25266
|
-
maxFiles:
|
|
25267
|
-
expiresAt:
|
|
25343
|
+
maxFiles: z93.number().int().positive(),
|
|
25344
|
+
expiresAt: z93.string().datetime()
|
|
25268
25345
|
});
|
|
25269
|
-
var UploadStatusInput =
|
|
25270
|
-
sessionId:
|
|
25346
|
+
var UploadStatusInput = z93.object({
|
|
25347
|
+
sessionId: z93.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
25271
25348
|
});
|
|
25272
|
-
var UniversalUploadStatusResponse =
|
|
25273
|
-
|
|
25274
|
-
status:
|
|
25275
|
-
assets:
|
|
25349
|
+
var UniversalUploadStatusResponse = z93.discriminatedUnion("status", [
|
|
25350
|
+
z93.object({
|
|
25351
|
+
status: z93.literal("pending"),
|
|
25352
|
+
assets: z93.array(z93.never()).length(0)
|
|
25276
25353
|
}),
|
|
25277
|
-
|
|
25278
|
-
status:
|
|
25279
|
-
assets:
|
|
25280
|
-
assetId:
|
|
25281
|
-
mediaKind:
|
|
25354
|
+
z93.object({
|
|
25355
|
+
status: z93.literal("uploaded"),
|
|
25356
|
+
assets: z93.array(z93.object({
|
|
25357
|
+
assetId: z93.string().uuid(),
|
|
25358
|
+
mediaKind: z93.enum([
|
|
25282
25359
|
"image",
|
|
25283
25360
|
"video"
|
|
25284
25361
|
]),
|
|
25285
|
-
assetRole:
|
|
25362
|
+
assetRole: z93.enum([
|
|
25286
25363
|
"media",
|
|
25287
25364
|
"thumbnail"
|
|
25288
25365
|
])
|
|
@@ -25290,13 +25367,13 @@ var UniversalUploadStatusResponse = z92.discriminatedUnion("status", [
|
|
|
25290
25367
|
})
|
|
25291
25368
|
]);
|
|
25292
25369
|
var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
|
|
25293
|
-
uploadPurpose:
|
|
25370
|
+
uploadPurpose: z93.enum([
|
|
25294
25371
|
"product_reference",
|
|
25295
25372
|
"creative",
|
|
25296
25373
|
"generic"
|
|
25297
25374
|
]),
|
|
25298
|
-
checkToolName:
|
|
25299
|
-
resolveEndpoint:
|
|
25375
|
+
checkToolName: z93.literal("check_media_upload"),
|
|
25376
|
+
resolveEndpoint: z93.string().url()
|
|
25300
25377
|
});
|
|
25301
25378
|
function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
|
|
25302
25379
|
const url = new URL(uploadPageUrl);
|
|
@@ -25387,15 +25464,15 @@ function registerMediaUploadTools(server, api) {
|
|
|
25387
25464
|
__name(registerMediaUploadTools, "registerMediaUploadTools");
|
|
25388
25465
|
|
|
25389
25466
|
// src/tools/campaigns.ts
|
|
25390
|
-
import { z as
|
|
25467
|
+
import { z as z94 } from "zod";
|
|
25391
25468
|
var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
|
|
25392
25469
|
var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
|
|
25393
|
-
var MetaStatusInput =
|
|
25394
|
-
campaignId:
|
|
25470
|
+
var MetaStatusInput = z94.object({
|
|
25471
|
+
campaignId: z94.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
|
|
25395
25472
|
});
|
|
25396
|
-
var TikTokStatusInput =
|
|
25397
|
-
campaignId:
|
|
25398
|
-
advertiserId:
|
|
25473
|
+
var TikTokStatusInput = z94.object({
|
|
25474
|
+
campaignId: z94.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
|
|
25475
|
+
advertiserId: z94.string().min(1).describe("The same advertiserId used to publish the campaign.")
|
|
25399
25476
|
});
|
|
25400
25477
|
function registerCampaignTools(server, api) {
|
|
25401
25478
|
server.registerTool("get_meta_campaign_status", {
|
|
@@ -25500,10 +25577,10 @@ function renderTikTokStatusMarkdown(r) {
|
|
|
25500
25577
|
__name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
|
|
25501
25578
|
|
|
25502
25579
|
// ../../packages/product-economics/src/product-costing.ts
|
|
25503
|
-
import { z as
|
|
25580
|
+
import { z as z96 } from "zod";
|
|
25504
25581
|
|
|
25505
25582
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
25506
|
-
import { z as
|
|
25583
|
+
import { z as z95 } from "zod";
|
|
25507
25584
|
|
|
25508
25585
|
// ../../packages/product-economics/src/product-costing-shipping-references.json
|
|
25509
25586
|
var product_costing_shipping_references_default = {
|
|
@@ -25567,21 +25644,21 @@ var product_costing_shipping_references_default = {
|
|
|
25567
25644
|
};
|
|
25568
25645
|
|
|
25569
25646
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
25570
|
-
var ShippingReferenceSchema =
|
|
25571
|
-
reference:
|
|
25572
|
-
min:
|
|
25573
|
-
max:
|
|
25574
|
-
updatedAt:
|
|
25575
|
-
confidence:
|
|
25647
|
+
var ShippingReferenceSchema = z95.object({
|
|
25648
|
+
reference: z95.number().positive(),
|
|
25649
|
+
min: z95.number().nonnegative(),
|
|
25650
|
+
max: z95.number().positive(),
|
|
25651
|
+
updatedAt: z95.string().date(),
|
|
25652
|
+
confidence: z95.enum([
|
|
25576
25653
|
"high",
|
|
25577
25654
|
"medium",
|
|
25578
25655
|
"medium-low"
|
|
25579
25656
|
]),
|
|
25580
|
-
sources:
|
|
25657
|
+
sources: z95.array(z95.string().url().startsWith("https://")).min(1).max(3)
|
|
25581
25658
|
}).superRefine(({ reference, min, max }, context) => {
|
|
25582
25659
|
if (min > reference || reference > max) {
|
|
25583
25660
|
context.addIssue({
|
|
25584
|
-
code:
|
|
25661
|
+
code: z95.ZodIssueCode.custom,
|
|
25585
25662
|
message: "shipping_reference_outside_range",
|
|
25586
25663
|
path: [
|
|
25587
25664
|
"reference"
|
|
@@ -25589,7 +25666,7 @@ var ShippingReferenceSchema = z94.object({
|
|
|
25589
25666
|
});
|
|
25590
25667
|
}
|
|
25591
25668
|
});
|
|
25592
|
-
var SHIPPING_REFERENCES =
|
|
25669
|
+
var SHIPPING_REFERENCES = z95.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
|
|
25593
25670
|
var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
|
|
25594
25671
|
var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
|
|
25595
25672
|
"MX",
|
|
@@ -25771,18 +25848,18 @@ function getProductCostingCountryName(country) {
|
|
|
25771
25848
|
__name(getProductCostingCountryName, "getProductCostingCountryName");
|
|
25772
25849
|
|
|
25773
25850
|
// ../../packages/product-economics/src/product-costing.ts
|
|
25774
|
-
var ProductCostingInputSchema =
|
|
25775
|
-
country:
|
|
25776
|
-
supplierCost:
|
|
25777
|
-
shippingCost:
|
|
25778
|
-
returnRate:
|
|
25779
|
-
cancellationRate:
|
|
25780
|
-
adsManagerCpa:
|
|
25781
|
-
desiredMargin:
|
|
25851
|
+
var ProductCostingInputSchema = z96.object({
|
|
25852
|
+
country: z96.string().refine(isProductCostingCountryCode, "unsupported_country"),
|
|
25853
|
+
supplierCost: z96.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
|
|
25854
|
+
shippingCost: z96.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
|
|
25855
|
+
returnRate: z96.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
25856
|
+
cancellationRate: z96.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
25857
|
+
adsManagerCpa: z96.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
|
|
25858
|
+
desiredMargin: z96.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
|
|
25782
25859
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
25783
25860
|
if (returnRate + cancellationRate >= 1) {
|
|
25784
25861
|
context.addIssue({
|
|
25785
|
-
code:
|
|
25862
|
+
code: z96.ZodIssueCode.custom,
|
|
25786
25863
|
message: "delivery_rate_positive",
|
|
25787
25864
|
path: [
|
|
25788
25865
|
"cancellationRate"
|
|
@@ -25879,15 +25956,15 @@ function calculateProductCosting(rawInput) {
|
|
|
25879
25956
|
__name(calculateProductCosting, "calculateProductCosting");
|
|
25880
25957
|
|
|
25881
25958
|
// src/tools/product-costing.ts
|
|
25882
|
-
import { z as
|
|
25959
|
+
import { z as z97 } from "zod";
|
|
25883
25960
|
var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
|
|
25884
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
25885
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
25886
|
-
var ProductCostingToolInput =
|
|
25887
|
-
country:
|
|
25961
|
+
var optionalAmount = /* @__PURE__ */ __name((description) => z97.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
|
|
25962
|
+
var optionalPercent = /* @__PURE__ */ __name((description) => z97.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
|
|
25963
|
+
var ProductCostingToolInput = z97.object({
|
|
25964
|
+
country: z97.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
25888
25965
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
25889
25966
|
}).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
|
|
25890
|
-
supplierCost:
|
|
25967
|
+
supplierCost: z97.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."),
|
|
25891
25968
|
supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
|
|
25892
25969
|
shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
|
|
25893
25970
|
shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
|
|
@@ -26050,7 +26127,7 @@ function formatPercent(value) {
|
|
|
26050
26127
|
__name(formatPercent, "formatPercent");
|
|
26051
26128
|
|
|
26052
26129
|
// src/tools/product-research.ts
|
|
26053
|
-
import { z as
|
|
26130
|
+
import { z as z98 } from "zod";
|
|
26054
26131
|
|
|
26055
26132
|
// src/tools/product-research-idempotency.ts
|
|
26056
26133
|
var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
|
|
@@ -26421,17 +26498,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
|
|
|
26421
26498
|
]);
|
|
26422
26499
|
var POLL_INTERVAL_MS = 5e3;
|
|
26423
26500
|
var MAX_WAIT_SECONDS = 120;
|
|
26424
|
-
var FindInput =
|
|
26501
|
+
var FindInput = z98.object({
|
|
26425
26502
|
targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
|
|
26426
26503
|
categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
|
|
26427
|
-
confirmed:
|
|
26428
|
-
waitSeconds:
|
|
26504
|
+
confirmed: z98.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
|
|
26505
|
+
waitSeconds: z98.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
|
|
26429
26506
|
});
|
|
26430
|
-
var GetInput =
|
|
26431
|
-
runId:
|
|
26507
|
+
var GetInput = z98.object({
|
|
26508
|
+
runId: z98.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
26432
26509
|
});
|
|
26433
|
-
var ListInput =
|
|
26434
|
-
limit:
|
|
26510
|
+
var ListInput = z98.object({
|
|
26511
|
+
limit: z98.number().int().min(1).max(20).default(10)
|
|
26435
26512
|
});
|
|
26436
26513
|
function textResult(text2) {
|
|
26437
26514
|
return {
|
|
@@ -26570,17 +26647,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
26570
26647
|
__name(registerProductResearchTools, "registerProductResearchTools");
|
|
26571
26648
|
|
|
26572
26649
|
// src/tools/dropshipping-projects.ts
|
|
26573
|
-
import { z as
|
|
26650
|
+
import { z as z99 } from "zod";
|
|
26574
26651
|
var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
|
|
26575
26652
|
var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
|
|
26576
26653
|
var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
|
|
26577
|
-
var ProjectId =
|
|
26578
|
-
var DropshippingProjectStatus =
|
|
26654
|
+
var ProjectId = z99.string().uuid();
|
|
26655
|
+
var DropshippingProjectStatus = z99.enum([
|
|
26579
26656
|
"active",
|
|
26580
26657
|
"completed",
|
|
26581
26658
|
"archived"
|
|
26582
26659
|
]);
|
|
26583
|
-
var DropshippingProjectPhase =
|
|
26660
|
+
var DropshippingProjectPhase = z99.enum([
|
|
26584
26661
|
"research",
|
|
26585
26662
|
"costing",
|
|
26586
26663
|
"media",
|
|
@@ -26589,21 +26666,21 @@ var DropshippingProjectPhase = z98.enum([
|
|
|
26589
26666
|
"advertising",
|
|
26590
26667
|
"complete"
|
|
26591
26668
|
]);
|
|
26592
|
-
var DropshippingRewardMilestone =
|
|
26669
|
+
var DropshippingRewardMilestone = z99.enum([
|
|
26593
26670
|
"product_selected",
|
|
26594
26671
|
"costing_saved",
|
|
26595
26672
|
"product_media_ready",
|
|
26596
26673
|
"creatives_completed",
|
|
26597
26674
|
"campaign_created"
|
|
26598
26675
|
]);
|
|
26599
|
-
var TargetCountry =
|
|
26676
|
+
var TargetCountry = z99.enum([
|
|
26600
26677
|
"CO",
|
|
26601
26678
|
"MX",
|
|
26602
26679
|
"PE",
|
|
26603
26680
|
"EC",
|
|
26604
26681
|
"CL"
|
|
26605
26682
|
]);
|
|
26606
|
-
var ResearchCategory =
|
|
26683
|
+
var ResearchCategory = z99.enum([
|
|
26607
26684
|
"auto",
|
|
26608
26685
|
"automotive",
|
|
26609
26686
|
"kitchen",
|
|
@@ -26618,7 +26695,7 @@ var ResearchCategory = z98.enum([
|
|
|
26618
26695
|
"garden",
|
|
26619
26696
|
"cleaning"
|
|
26620
26697
|
]);
|
|
26621
|
-
var HttpUrl3 =
|
|
26698
|
+
var HttpUrl3 = z99.string().url().max(2e3).refine((value) => {
|
|
26622
26699
|
try {
|
|
26623
26700
|
return [
|
|
26624
26701
|
"http:",
|
|
@@ -26628,45 +26705,45 @@ var HttpUrl3 = z98.string().url().max(2e3).refine((value) => {
|
|
|
26628
26705
|
return false;
|
|
26629
26706
|
}
|
|
26630
26707
|
}, "URL must use HTTP(S)");
|
|
26631
|
-
var ResearchCandidateOrigin =
|
|
26632
|
-
type:
|
|
26708
|
+
var ResearchCandidateOrigin = z99.object({
|
|
26709
|
+
type: z99.literal("research_candidate"),
|
|
26633
26710
|
runId: ProjectId,
|
|
26634
|
-
candidateSourceId:
|
|
26711
|
+
candidateSourceId: z99.string().min(1).max(160)
|
|
26635
26712
|
});
|
|
26636
|
-
var TaskOrigin =
|
|
26637
|
-
type:
|
|
26713
|
+
var TaskOrigin = z99.object({
|
|
26714
|
+
type: z99.literal("task"),
|
|
26638
26715
|
taskId: ProjectId
|
|
26639
26716
|
});
|
|
26640
|
-
var ManualOrigin =
|
|
26641
|
-
type:
|
|
26717
|
+
var ManualOrigin = z99.object({
|
|
26718
|
+
type: z99.literal("manual"),
|
|
26642
26719
|
clientRequestId: ProjectId,
|
|
26643
|
-
country:
|
|
26720
|
+
country: z99.string().min(2).max(3).optional()
|
|
26644
26721
|
});
|
|
26645
|
-
var StartProjectInput =
|
|
26646
|
-
origin:
|
|
26722
|
+
var StartProjectInput = z99.object({
|
|
26723
|
+
origin: z99.discriminatedUnion("type", [
|
|
26647
26724
|
ResearchCandidateOrigin,
|
|
26648
26725
|
TaskOrigin,
|
|
26649
26726
|
ManualOrigin
|
|
26650
26727
|
]),
|
|
26651
|
-
productName:
|
|
26728
|
+
productName: z99.string().trim().min(1).max(240).optional(),
|
|
26652
26729
|
productUrl: HttpUrl3.optional(),
|
|
26653
|
-
country:
|
|
26654
|
-
languageCode:
|
|
26730
|
+
country: z99.string().min(2).max(3).optional(),
|
|
26731
|
+
languageCode: z99.string().min(2).max(16).optional()
|
|
26655
26732
|
}).strict();
|
|
26656
|
-
var CostProjectInput =
|
|
26733
|
+
var CostProjectInput = z99.object({
|
|
26657
26734
|
projectId: ProjectId,
|
|
26658
|
-
version:
|
|
26659
|
-
country:
|
|
26735
|
+
version: z99.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
|
|
26736
|
+
country: z99.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
26660
26737
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
26661
26738
|
}).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
|
|
26662
|
-
supplierCost:
|
|
26663
|
-
shippingCost:
|
|
26664
|
-
returnRate:
|
|
26665
|
-
cancellationRate:
|
|
26666
|
-
adsManagerCpa:
|
|
26667
|
-
desiredMargin:
|
|
26668
|
-
});
|
|
26669
|
-
var GuideInput =
|
|
26739
|
+
supplierCost: z99.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."),
|
|
26740
|
+
shippingCost: z99.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
|
|
26741
|
+
returnRate: z99.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."),
|
|
26742
|
+
cancellationRate: z99.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."),
|
|
26743
|
+
adsManagerCpa: z99.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
26744
|
+
desiredMargin: z99.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
|
|
26745
|
+
});
|
|
26746
|
+
var GuideInput = z99.object({
|
|
26670
26747
|
projectId: ProjectId.optional()
|
|
26671
26748
|
}).strict();
|
|
26672
26749
|
var NEXT_ACTION_KINDS = [
|
|
@@ -26684,29 +26761,29 @@ var NEXT_ACTION_KINDS = [
|
|
|
26684
26761
|
"repair_meta_campaign",
|
|
26685
26762
|
"review_paused_campaign"
|
|
26686
26763
|
];
|
|
26687
|
-
var DropshippingProjectNextAction =
|
|
26688
|
-
kind:
|
|
26689
|
-
href:
|
|
26764
|
+
var DropshippingProjectNextAction = z99.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z99.object({
|
|
26765
|
+
kind: z99.literal(kind),
|
|
26766
|
+
href: z99.string().min(1)
|
|
26690
26767
|
})));
|
|
26691
|
-
var CostingInputSchema =
|
|
26692
|
-
country:
|
|
26693
|
-
supplierCost:
|
|
26694
|
-
shippingCost:
|
|
26695
|
-
returnRate:
|
|
26696
|
-
cancellationRate:
|
|
26697
|
-
adsManagerCpa:
|
|
26698
|
-
desiredMargin:
|
|
26768
|
+
var CostingInputSchema = z99.object({
|
|
26769
|
+
country: z99.string().min(2).max(3),
|
|
26770
|
+
supplierCost: z99.number().finite().positive(),
|
|
26771
|
+
shippingCost: z99.number().finite().nonnegative(),
|
|
26772
|
+
returnRate: z99.number().finite().min(0).lt(1),
|
|
26773
|
+
cancellationRate: z99.number().finite().min(0).lt(1),
|
|
26774
|
+
adsManagerCpa: z99.number().finite().nonnegative(),
|
|
26775
|
+
desiredMargin: z99.number().finite().min(0).lt(1)
|
|
26699
26776
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
26700
26777
|
if (returnRate + cancellationRate >= 1) context.addIssue({
|
|
26701
|
-
code:
|
|
26778
|
+
code: z99.ZodIssueCode.custom,
|
|
26702
26779
|
path: [
|
|
26703
26780
|
"cancellationRate"
|
|
26704
26781
|
]
|
|
26705
26782
|
});
|
|
26706
26783
|
});
|
|
26707
|
-
var FiniteCostingNumber =
|
|
26708
|
-
var CostingResultSchema =
|
|
26709
|
-
country:
|
|
26784
|
+
var FiniteCostingNumber = z99.number().finite();
|
|
26785
|
+
var CostingResultSchema = z99.object({
|
|
26786
|
+
country: z99.string().min(2).max(3),
|
|
26710
26787
|
deliveryRate: FiniteCostingNumber,
|
|
26711
26788
|
adjustedShippingCost: FiniteCostingNumber,
|
|
26712
26789
|
adjustedCpa: FiniteCostingNumber,
|
|
@@ -26719,45 +26796,45 @@ var CostingResultSchema = z98.object({
|
|
|
26719
26796
|
estimatedProfit: FiniteCostingNumber,
|
|
26720
26797
|
actualMargin: FiniteCostingNumber,
|
|
26721
26798
|
breakEvenAdsManagerCpa: FiniteCostingNumber,
|
|
26722
|
-
wasPriceAutoAdjusted:
|
|
26723
|
-
profitabilityStatus:
|
|
26724
|
-
});
|
|
26725
|
-
var RewardProgressSchema =
|
|
26726
|
-
campaignKey:
|
|
26727
|
-
totalCredits:
|
|
26728
|
-
earnedCredits:
|
|
26729
|
-
milestones:
|
|
26799
|
+
wasPriceAutoAdjusted: z99.boolean(),
|
|
26800
|
+
profitabilityStatus: z99.literal("healthy")
|
|
26801
|
+
});
|
|
26802
|
+
var RewardProgressSchema = z99.object({
|
|
26803
|
+
campaignKey: z99.literal("dropshipping-launch-v1"),
|
|
26804
|
+
totalCredits: z99.number().int().positive(),
|
|
26805
|
+
earnedCredits: z99.number().int().nonnegative(),
|
|
26806
|
+
milestones: z99.array(z99.object({
|
|
26730
26807
|
milestone: DropshippingRewardMilestone,
|
|
26731
|
-
credits:
|
|
26732
|
-
available:
|
|
26733
|
-
earned:
|
|
26808
|
+
credits: z99.number().int().positive(),
|
|
26809
|
+
available: z99.boolean().optional(),
|
|
26810
|
+
earned: z99.boolean(),
|
|
26734
26811
|
grantId: ProjectId.nullable(),
|
|
26735
|
-
grantedAt:
|
|
26812
|
+
grantedAt: z99.string().datetime().nullable()
|
|
26736
26813
|
})).length(DropshippingRewardMilestone.options.length)
|
|
26737
26814
|
});
|
|
26738
|
-
var ProjectResponseSchema =
|
|
26815
|
+
var ProjectResponseSchema = z99.object({
|
|
26739
26816
|
id: ProjectId,
|
|
26740
26817
|
taskId: ProjectId.nullable(),
|
|
26741
26818
|
status: DropshippingProjectStatus,
|
|
26742
|
-
originKey:
|
|
26819
|
+
originKey: z99.string().min(1),
|
|
26743
26820
|
researchRunId: ProjectId.nullable(),
|
|
26744
|
-
candidateSourceId:
|
|
26745
|
-
productName:
|
|
26821
|
+
candidateSourceId: z99.string().nullable(),
|
|
26822
|
+
productName: z99.string().nullable(),
|
|
26746
26823
|
productUrl: HttpUrl3.nullable(),
|
|
26747
26824
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
26748
|
-
targetCountry:
|
|
26749
|
-
languageCode:
|
|
26750
|
-
hasReferenceImage:
|
|
26751
|
-
hasWinnerReferenceImage:
|
|
26825
|
+
targetCountry: z99.string().nullable(),
|
|
26826
|
+
languageCode: z99.string().nullable(),
|
|
26827
|
+
hasReferenceImage: z99.boolean(),
|
|
26828
|
+
hasWinnerReferenceImage: z99.boolean(),
|
|
26752
26829
|
costingInput: CostingInputSchema.nullable(),
|
|
26753
26830
|
costingResult: CostingResultSchema.nullable(),
|
|
26754
|
-
costingVersion:
|
|
26755
|
-
version:
|
|
26831
|
+
costingVersion: z99.number().int().positive().nullable(),
|
|
26832
|
+
version: z99.number().int().positive(),
|
|
26756
26833
|
phase: DropshippingProjectPhase,
|
|
26757
26834
|
nextAction: DropshippingProjectNextAction.nullable(),
|
|
26758
26835
|
rewards: RewardProgressSchema,
|
|
26759
|
-
createdAt:
|
|
26760
|
-
updatedAt:
|
|
26836
|
+
createdAt: z99.string().datetime(),
|
|
26837
|
+
updatedAt: z99.string().datetime()
|
|
26761
26838
|
}).passthrough();
|
|
26762
26839
|
var NEXT_ACTION_GUIDANCE = {
|
|
26763
26840
|
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.",
|
|
@@ -26877,58 +26954,58 @@ function registerDropshippingProjectTools(server, api) {
|
|
|
26877
26954
|
__name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
|
|
26878
26955
|
|
|
26879
26956
|
// src/tools/daily-control.ts
|
|
26880
|
-
import { z as
|
|
26957
|
+
import { z as z100 } from "zod";
|
|
26881
26958
|
var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
|
|
26882
26959
|
var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
|
|
26883
26960
|
var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
|
|
26884
|
-
var ProviderCampaignIdentifier =
|
|
26885
|
-
var DateOnly =
|
|
26886
|
-
var DailyControlInput =
|
|
26961
|
+
var ProviderCampaignIdentifier = z100.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
|
|
26962
|
+
var DateOnly = z100.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
26963
|
+
var DailyControlInput = z100.object({
|
|
26887
26964
|
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."),
|
|
26888
|
-
days:
|
|
26889
|
-
projectId:
|
|
26965
|
+
days: z100.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
26966
|
+
projectId: z100.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
|
|
26890
26967
|
}).strict();
|
|
26891
|
-
var LinkCampaignInput =
|
|
26892
|
-
projectId:
|
|
26893
|
-
provider:
|
|
26968
|
+
var LinkCampaignInput = z100.object({
|
|
26969
|
+
projectId: z100.string().uuid(),
|
|
26970
|
+
provider: z100.enum([
|
|
26894
26971
|
"meta",
|
|
26895
26972
|
"tiktok"
|
|
26896
26973
|
]),
|
|
26897
26974
|
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."),
|
|
26898
26975
|
campaignId: ProviderCampaignIdentifier
|
|
26899
26976
|
}).strict();
|
|
26900
|
-
var ReportReturnsInput =
|
|
26901
|
-
projectId:
|
|
26977
|
+
var ReportReturnsInput = z100.object({
|
|
26978
|
+
projectId: z100.string().uuid(),
|
|
26902
26979
|
date: DateOnly,
|
|
26903
|
-
returnedOrders:
|
|
26904
|
-
note:
|
|
26980
|
+
returnedOrders: z100.number().int().min(0).max(1e5),
|
|
26981
|
+
note: z100.string().trim().max(280).optional()
|
|
26905
26982
|
}).strict();
|
|
26906
|
-
var DailyControlStatusMirror = DailyControlStatusEnum.or(
|
|
26907
|
-
var DailyControlLightMirror = DailyControlLightEnum.or(
|
|
26908
|
-
var DailyControlSourceMirror = DailyControlSourceEnum.or(
|
|
26909
|
-
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(
|
|
26910
|
-
var DailyControlDayMirror =
|
|
26911
|
-
date:
|
|
26912
|
-
returnedOrders:
|
|
26983
|
+
var DailyControlStatusMirror = DailyControlStatusEnum.or(z100.string());
|
|
26984
|
+
var DailyControlLightMirror = DailyControlLightEnum.or(z100.string());
|
|
26985
|
+
var DailyControlSourceMirror = DailyControlSourceEnum.or(z100.string());
|
|
26986
|
+
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z100.string());
|
|
26987
|
+
var DailyControlDayMirror = z100.object({
|
|
26988
|
+
date: z100.string(),
|
|
26989
|
+
returnedOrders: z100.number(),
|
|
26913
26990
|
returnedSource: DailyControlSourceMirror,
|
|
26914
26991
|
cancelledSource: DailyControlSourceMirror,
|
|
26915
|
-
hasEstimates:
|
|
26992
|
+
hasEstimates: z100.boolean(),
|
|
26916
26993
|
light: DailyControlLightMirror
|
|
26917
26994
|
}).passthrough();
|
|
26918
|
-
var DailyControlProductMirror =
|
|
26919
|
-
projectId:
|
|
26920
|
-
productName:
|
|
26995
|
+
var DailyControlProductMirror = z100.object({
|
|
26996
|
+
projectId: z100.string().uuid(),
|
|
26997
|
+
productName: z100.string().nullable(),
|
|
26921
26998
|
status: DailyControlStatusMirror,
|
|
26922
|
-
statusMessage:
|
|
26923
|
-
days:
|
|
26999
|
+
statusMessage: z100.string().nullable(),
|
|
27000
|
+
days: z100.array(DailyControlDayMirror),
|
|
26924
27001
|
verdict: DailyControlVerdictMirror.nullable(),
|
|
26925
|
-
rationale:
|
|
27002
|
+
rationale: z100.string().nullable()
|
|
26926
27003
|
}).passthrough();
|
|
26927
|
-
var DailyControlResponseMirror =
|
|
26928
|
-
since:
|
|
26929
|
-
until:
|
|
26930
|
-
products:
|
|
26931
|
-
archivedProjectSpend:
|
|
27004
|
+
var DailyControlResponseMirror = z100.object({
|
|
27005
|
+
since: z100.string(),
|
|
27006
|
+
until: z100.string(),
|
|
27007
|
+
products: z100.array(DailyControlProductMirror),
|
|
27008
|
+
archivedProjectSpend: z100.array(z100.unknown())
|
|
26932
27009
|
}).passthrough();
|
|
26933
27010
|
var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
|
|
26934
27011
|
function withWarnings(response) {
|
|
@@ -27003,7 +27080,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
|
|
|
27003
27080
|
// src/tools/product-control.ts
|
|
27004
27081
|
import { readFile, stat } from "fs/promises";
|
|
27005
27082
|
import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
|
|
27006
|
-
import { z as
|
|
27083
|
+
import { z as z101 } from "zod";
|
|
27007
27084
|
var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
|
|
27008
27085
|
var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
|
|
27009
27086
|
var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
|
|
@@ -27016,36 +27093,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
|
|
|
27016
27093
|
var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
|
|
27017
27094
|
var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
|
|
27018
27095
|
var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
|
|
27019
|
-
var DateOnly2 =
|
|
27096
|
+
var DateOnly2 = z101.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
27020
27097
|
var IMPORT_BATCH_MAX2 = 50;
|
|
27021
|
-
var ProductControlListInput =
|
|
27022
|
-
days:
|
|
27098
|
+
var ProductControlListInput = z101.object({
|
|
27099
|
+
days: z101.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
27023
27100
|
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."),
|
|
27024
|
-
shopDomain:
|
|
27101
|
+
shopDomain: z101.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
27025
27102
|
}).strict();
|
|
27026
|
-
var ImportableProductsInput =
|
|
27027
|
-
q:
|
|
27028
|
-
after:
|
|
27029
|
-
shopDomain:
|
|
27103
|
+
var ImportableProductsInput = z101.object({
|
|
27104
|
+
q: z101.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
|
|
27105
|
+
after: z101.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
|
|
27106
|
+
shopDomain: z101.string().min(1).optional()
|
|
27030
27107
|
}).strict();
|
|
27031
|
-
var ImportProductControlsInput =
|
|
27032
|
-
shopifyProductIds:
|
|
27108
|
+
var ImportProductControlsInput = z101.object({
|
|
27109
|
+
shopifyProductIds: z101.array(z101.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."),
|
|
27033
27110
|
// Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
|
|
27034
27111
|
// sin decir a cuál archivaría el producto bajo la tienda equivocada.
|
|
27035
|
-
shopDomain:
|
|
27112
|
+
shopDomain: z101.string().min(1)
|
|
27036
27113
|
}).strict();
|
|
27037
|
-
var SetProductCostingInput =
|
|
27038
|
-
shopDomain:
|
|
27039
|
-
shopifyProductId:
|
|
27040
|
-
targetCountry:
|
|
27041
|
-
supplierCost:
|
|
27042
|
-
shippingCost:
|
|
27043
|
-
returnRate:
|
|
27044
|
-
cancellationRate:
|
|
27114
|
+
var SetProductCostingInput = z101.object({
|
|
27115
|
+
shopDomain: z101.string().min(1),
|
|
27116
|
+
shopifyProductId: z101.string().min(1).max(64),
|
|
27117
|
+
targetCountry: z101.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
|
|
27118
|
+
supplierCost: z101.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
|
|
27119
|
+
shippingCost: z101.number().finite().nonnegative(),
|
|
27120
|
+
returnRate: z101.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
|
|
27121
|
+
cancellationRate: z101.number().finite().min(0).lt(1)
|
|
27045
27122
|
}).strict();
|
|
27046
|
-
var Count =
|
|
27047
|
-
var ReportProductCountsInput =
|
|
27048
|
-
productControlId:
|
|
27123
|
+
var Count = z101.number().int().min(0).max(1e5).nullable().optional();
|
|
27124
|
+
var ReportProductCountsInput = z101.object({
|
|
27125
|
+
productControlId: z101.string().uuid().describe("El identificador que devuelve get_product_control."),
|
|
27049
27126
|
date: DateOnly2,
|
|
27050
27127
|
orders: Count.describe("Pedidos que entraron ese d\xEDa."),
|
|
27051
27128
|
cancelledOrders: Count,
|
|
@@ -27055,36 +27132,36 @@ var ReportProductCountsInput = z100.object({
|
|
|
27055
27132
|
}).strict();
|
|
27056
27133
|
var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
|
|
27057
27134
|
var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
|
|
27058
|
-
var ImportOrdersFileInput =
|
|
27135
|
+
var ImportOrdersFileInput = z101.object({
|
|
27059
27136
|
/** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
|
|
27060
|
-
path:
|
|
27061
|
-
operationId:
|
|
27137
|
+
path: z101.string().min(1),
|
|
27138
|
+
operationId: z101.string().uuid().optional(),
|
|
27062
27139
|
/** Solo mirar: devuelve el resumen y no escribe nada. */
|
|
27063
|
-
dryRun:
|
|
27140
|
+
dryRun: z101.boolean().optional()
|
|
27064
27141
|
}).strict();
|
|
27065
|
-
var CreateOperationInput =
|
|
27066
|
-
countryCode:
|
|
27067
|
-
label:
|
|
27142
|
+
var CreateOperationInput = z101.object({
|
|
27143
|
+
countryCode: z101.string().length(2),
|
|
27144
|
+
label: z101.string().trim().min(1).max(60).optional()
|
|
27068
27145
|
}).strict();
|
|
27069
|
-
var MergeProductsInput =
|
|
27070
|
-
sourceId:
|
|
27071
|
-
targetId:
|
|
27146
|
+
var MergeProductsInput = z101.object({
|
|
27147
|
+
sourceId: z101.string().uuid(),
|
|
27148
|
+
targetId: z101.string().uuid()
|
|
27072
27149
|
}).strict();
|
|
27073
|
-
var SetMonthlyExpenseInput =
|
|
27074
|
-
month:
|
|
27150
|
+
var SetMonthlyExpenseInput = z101.object({
|
|
27151
|
+
month: z101.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
27075
27152
|
label: SaveMonthlyExpenseSchema.shape.label,
|
|
27076
|
-
amount:
|
|
27077
|
-
operationId:
|
|
27153
|
+
amount: z101.number().finite().min(0),
|
|
27154
|
+
operationId: z101.string().uuid().optional()
|
|
27078
27155
|
}).strict();
|
|
27079
|
-
var SetAdSpendInput =
|
|
27080
|
-
month:
|
|
27081
|
-
operationId:
|
|
27156
|
+
var SetAdSpendInput = z101.object({
|
|
27157
|
+
month: z101.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
27158
|
+
operationId: z101.string().uuid().optional(),
|
|
27082
27159
|
/** null RETIRA la corrección; cero afirma que no pautó. */
|
|
27083
|
-
amount:
|
|
27160
|
+
amount: z101.number().finite().min(0).nullable()
|
|
27084
27161
|
}).strict();
|
|
27085
|
-
var GetFinancesInput =
|
|
27086
|
-
month:
|
|
27087
|
-
operationId:
|
|
27162
|
+
var GetFinancesInput = z101.object({
|
|
27163
|
+
month: z101.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."),
|
|
27164
|
+
operationId: z101.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
|
|
27088
27165
|
}).strict();
|
|
27089
27166
|
function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
27090
27167
|
server.registerTool("get_product_control", {
|
|
@@ -27281,27 +27358,27 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
|
27281
27358
|
__name(registerProductControlTools, "registerProductControlTools");
|
|
27282
27359
|
|
|
27283
27360
|
// src/tools/market-study-estimate.ts
|
|
27284
|
-
import { z as
|
|
27361
|
+
import { z as z102 } from "zod";
|
|
27285
27362
|
var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
|
|
27286
|
-
var ProductTaskOutputEnum =
|
|
27363
|
+
var ProductTaskOutputEnum = z102.enum([
|
|
27287
27364
|
"landing",
|
|
27288
27365
|
"video",
|
|
27289
27366
|
"image"
|
|
27290
27367
|
]);
|
|
27291
|
-
var EstimateMarketStudyInput =
|
|
27292
|
-
kind:
|
|
27368
|
+
var EstimateMarketStudyInput = z102.object({
|
|
27369
|
+
kind: z102.enum([
|
|
27293
27370
|
"video",
|
|
27294
27371
|
"product_task"
|
|
27295
27372
|
]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
|
|
27296
|
-
videoAngleCount:
|
|
27297
|
-
durationSeconds:
|
|
27373
|
+
videoAngleCount: z102.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
|
|
27374
|
+
durationSeconds: z102.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
|
|
27298
27375
|
videoStructure: VideoStructureEnum.default("single_take"),
|
|
27299
27376
|
videoQuality: VideoQualityEnum.default("economy"),
|
|
27300
27377
|
videoResolution: VideoResolutionEnum.default("480p"),
|
|
27301
|
-
productImageCount:
|
|
27378
|
+
productImageCount: z102.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
|
|
27302
27379
|
outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
|
|
27303
|
-
generateAiMusic:
|
|
27304
|
-
replicateWinnerWhenFound:
|
|
27380
|
+
generateAiMusic: z102.boolean().optional(),
|
|
27381
|
+
replicateWinnerWhenFound: z102.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.")
|
|
27305
27382
|
}).strict();
|
|
27306
27383
|
function buildMarketStudyEstimateRequests(input) {
|
|
27307
27384
|
const quotesVideo = input.kind === "video" || (input.outputs ?? [
|