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