@productmaker/mcp 11.3.2 → 11.3.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 +4 -0
- package/dist/http.js +925 -742
- package/dist/stdio.js +914 -731
- package/package.json +1 -1
package/dist/stdio.js
CHANGED
|
@@ -21368,8 +21368,33 @@ var ServicePageGenerateRequestSchema = z100.object({
|
|
|
21368
21368
|
instruction: ServicePageEditInstructionSchema.optional(),
|
|
21369
21369
|
attachmentRefs: ServicePageAttachmentRefsSchema.optional()
|
|
21370
21370
|
}).strict();
|
|
21371
|
+
var SERVICE_PAGE_CREATION_MAX_ATTEMPTS = 3;
|
|
21372
|
+
var ServicePageCreationMarkerSchema = z100.object({
|
|
21373
|
+
rootOperationId: z100.string().uuid().optional(),
|
|
21374
|
+
attempt: z100.number().int().min(1).max(SERVICE_PAGE_CREATION_MAX_ATTEMPTS)
|
|
21375
|
+
}).strict();
|
|
21376
|
+
var ServicePageCreationEstimateRequestSchema = z100.object({
|
|
21377
|
+
textCharacters: z100.number().int().min(0).max(1e6),
|
|
21378
|
+
documentBytes: z100.number().int().min(0).max(1e8),
|
|
21379
|
+
imageCount: z100.number().int().min(0).max(50),
|
|
21380
|
+
instagram: z100.boolean()
|
|
21381
|
+
}).strict();
|
|
21382
|
+
var ServicePageCreationEstimateResponseSchema = z100.object({
|
|
21383
|
+
estimatedMinCostCredits: z100.number().int().nonnegative(),
|
|
21384
|
+
estimatedMaxCostCredits: z100.number().int().nonnegative()
|
|
21385
|
+
}).strict();
|
|
21386
|
+
var ServicePageCreationStatusSchema = z100.object({
|
|
21387
|
+
status: z100.enum([
|
|
21388
|
+
"idle",
|
|
21389
|
+
"running",
|
|
21390
|
+
"failed"
|
|
21391
|
+
]),
|
|
21392
|
+
errorCode: z100.string().max(64).optional()
|
|
21393
|
+
}).strict();
|
|
21371
21394
|
var ServicePageFactExtractionRequestSchema = ServicePageGenerateRequestSchema.omit({
|
|
21372
21395
|
instruction: true
|
|
21396
|
+
}).extend({
|
|
21397
|
+
continueWith: z100.literal("generation").optional()
|
|
21373
21398
|
});
|
|
21374
21399
|
var ServicePageOperationStatusSchema = z100.enum([
|
|
21375
21400
|
"queued",
|
|
@@ -22014,6 +22039,159 @@ var WebsiteCaptureResearchSchema = z107.object({
|
|
|
22014
22039
|
})
|
|
22015
22040
|
});
|
|
22016
22041
|
|
|
22042
|
+
// ../../packages/types/src/demo-mode.ts
|
|
22043
|
+
import { z as z108 } from "zod";
|
|
22044
|
+
var DEMO_MODE_FLOWS = [
|
|
22045
|
+
"brand",
|
|
22046
|
+
"servicePage",
|
|
22047
|
+
"motion",
|
|
22048
|
+
"image"
|
|
22049
|
+
];
|
|
22050
|
+
var DemoModeFlowSchema = z108.enum(DEMO_MODE_FLOWS);
|
|
22051
|
+
var DEMO_MODE_STEPS = [
|
|
22052
|
+
"running",
|
|
22053
|
+
"research",
|
|
22054
|
+
"design",
|
|
22055
|
+
"render_0",
|
|
22056
|
+
"render_33",
|
|
22057
|
+
"render_66",
|
|
22058
|
+
"render_100",
|
|
22059
|
+
"review",
|
|
22060
|
+
"final",
|
|
22061
|
+
"watchdog"
|
|
22062
|
+
];
|
|
22063
|
+
var DemoModeStepSchema = z108.enum(DEMO_MODE_STEPS);
|
|
22064
|
+
var DEMO_MODE_WAIT_SECONDS = {
|
|
22065
|
+
min: 30,
|
|
22066
|
+
max: 450,
|
|
22067
|
+
default: 150
|
|
22068
|
+
};
|
|
22069
|
+
var centsSchema = z108.number().int().min(0).max(1e5);
|
|
22070
|
+
var emailSchema = z108.string().trim().toLowerCase().email();
|
|
22071
|
+
var DemoModeTemplatesSchema = z108.object({
|
|
22072
|
+
brandId: z108.string().uuid(),
|
|
22073
|
+
servicePageId: z108.string().uuid(),
|
|
22074
|
+
motionTaskId: z108.string().uuid(),
|
|
22075
|
+
imageTaskId: z108.string().uuid()
|
|
22076
|
+
});
|
|
22077
|
+
var DemoModeEditableSchema = z108.object({
|
|
22078
|
+
enabled: z108.boolean(),
|
|
22079
|
+
emails: z108.array(emailSchema).max(50).transform((list) => [
|
|
22080
|
+
...new Set(list)
|
|
22081
|
+
]),
|
|
22082
|
+
waitSeconds: z108.number().int().min(DEMO_MODE_WAIT_SECONDS.min).max(DEMO_MODE_WAIT_SECONDS.max),
|
|
22083
|
+
chargeCents: z108.object({
|
|
22084
|
+
brand: centsSchema,
|
|
22085
|
+
servicePage: centsSchema,
|
|
22086
|
+
motion: centsSchema,
|
|
22087
|
+
image: centsSchema
|
|
22088
|
+
}),
|
|
22089
|
+
templates: DemoModeTemplatesSchema
|
|
22090
|
+
});
|
|
22091
|
+
var nullableString = z108.string().nullable();
|
|
22092
|
+
var DemoModeSnapshotSchema = z108.object({
|
|
22093
|
+
brand: z108.object({
|
|
22094
|
+
/** Columnas de identidad de `Brand` listas para un `update` (sin id/userId/slug/estado/fechas). */
|
|
22095
|
+
identity: z108.record(z108.unknown()),
|
|
22096
|
+
productSamples: z108.array(z108.object({
|
|
22097
|
+
name: z108.string(),
|
|
22098
|
+
priceCents: z108.number().int().nullable(),
|
|
22099
|
+
currency: nullableString,
|
|
22100
|
+
imageKey: z108.string(),
|
|
22101
|
+
productUrl: nullableString,
|
|
22102
|
+
position: z108.number().int()
|
|
22103
|
+
})),
|
|
22104
|
+
personas: z108.array(z108.object({
|
|
22105
|
+
name: z108.string(),
|
|
22106
|
+
demographics: nullableString,
|
|
22107
|
+
painPoints: nullableString,
|
|
22108
|
+
motivations: nullableString,
|
|
22109
|
+
objections: nullableString,
|
|
22110
|
+
gender: nullableString,
|
|
22111
|
+
isDefault: z108.boolean()
|
|
22112
|
+
}))
|
|
22113
|
+
}),
|
|
22114
|
+
servicePage: z108.object({
|
|
22115
|
+
facts: z108.unknown(),
|
|
22116
|
+
review: z108.unknown(),
|
|
22117
|
+
artifact: z108.unknown()
|
|
22118
|
+
}),
|
|
22119
|
+
motion: z108.object({
|
|
22120
|
+
outputs: MotionGraphicsOutputsSchema,
|
|
22121
|
+
/**
|
|
22122
|
+
* La captura REAL de la web de la plantilla (nunca una fabricada por la
|
|
22123
|
+
* demo). Null cuando la plantilla no tiene ninguna: la captura demo nunca
|
|
22124
|
+
* va live, así que el servicio usa `DEMO_MODE_PLACEHOLDER_CAPTURE`.
|
|
22125
|
+
*/
|
|
22126
|
+
capture: z108.object({
|
|
22127
|
+
bundleKey: z108.string(),
|
|
22128
|
+
sha256: z108.string(),
|
|
22129
|
+
uploadBytes: z108.number().int().nullable(),
|
|
22130
|
+
previewKey: nullableString
|
|
22131
|
+
}).nullable()
|
|
22132
|
+
}),
|
|
22133
|
+
image: z108.object({
|
|
22134
|
+
provider: z108.string(),
|
|
22135
|
+
model: z108.string(),
|
|
22136
|
+
prompt: z108.string(),
|
|
22137
|
+
imageUrl: z108.string(),
|
|
22138
|
+
width: z108.number().int(),
|
|
22139
|
+
height: z108.number().int(),
|
|
22140
|
+
adCopy: nullableString,
|
|
22141
|
+
rawResponse: z108.unknown()
|
|
22142
|
+
})
|
|
22143
|
+
});
|
|
22144
|
+
var DemoModeConfigSchema = DemoModeEditableSchema.extend({
|
|
22145
|
+
snapshot: DemoModeSnapshotSchema.nullable(),
|
|
22146
|
+
snapshotAt: z108.string().datetime().nullable()
|
|
22147
|
+
});
|
|
22148
|
+
var DemoModeAdminViewSchema = DemoModeEditableSchema.extend({
|
|
22149
|
+
// Sin configurar, la API devuelve ids vacíos ("" no es uuid): la vista los
|
|
22150
|
+
// admite; el PUT sí exige uuid (`DemoModeEditableSchema`).
|
|
22151
|
+
templates: z108.object({
|
|
22152
|
+
brandId: z108.string(),
|
|
22153
|
+
servicePageId: z108.string(),
|
|
22154
|
+
motionTaskId: z108.string(),
|
|
22155
|
+
imageTaskId: z108.string()
|
|
22156
|
+
}),
|
|
22157
|
+
snapshotAt: z108.string().nullable()
|
|
22158
|
+
});
|
|
22159
|
+
var DEMO_MODE_TEMPLATE_PROBLEMS = [
|
|
22160
|
+
"not_found",
|
|
22161
|
+
"brand_not_ready",
|
|
22162
|
+
"no_artifact",
|
|
22163
|
+
"artifact_invalid",
|
|
22164
|
+
"task_not_done",
|
|
22165
|
+
"no_video",
|
|
22166
|
+
"no_creative"
|
|
22167
|
+
];
|
|
22168
|
+
var DemoModeTemplateVerdictSchema = z108.discriminatedUnion("ok", [
|
|
22169
|
+
z108.object({
|
|
22170
|
+
ok: z108.literal(true)
|
|
22171
|
+
}),
|
|
22172
|
+
z108.object({
|
|
22173
|
+
ok: z108.literal(false),
|
|
22174
|
+
problem: z108.enum(DEMO_MODE_TEMPLATE_PROBLEMS)
|
|
22175
|
+
})
|
|
22176
|
+
]);
|
|
22177
|
+
var DemoModeValidationSchema = z108.object({
|
|
22178
|
+
brandId: DemoModeTemplateVerdictSchema,
|
|
22179
|
+
servicePageId: DemoModeTemplateVerdictSchema,
|
|
22180
|
+
motionTaskId: DemoModeTemplateVerdictSchema,
|
|
22181
|
+
imageTaskId: DemoModeTemplateVerdictSchema
|
|
22182
|
+
});
|
|
22183
|
+
var DemoModeJobSchema = z108.object({
|
|
22184
|
+
flow: DemoModeFlowSchema,
|
|
22185
|
+
step: DemoModeStepSchema,
|
|
22186
|
+
/** brandId | servicePageOperationId | taskId según el flujo. */
|
|
22187
|
+
targetId: z108.string().uuid(),
|
|
22188
|
+
userId: z108.string().min(1),
|
|
22189
|
+
/** Solo marca: la generación de extracción que el guion completa. */
|
|
22190
|
+
generation: z108.number().int().positive().optional(),
|
|
22191
|
+
/** Solo `final`/`watchdog`: la parte del snapshot de ESTE flujo, congelada al empezar. */
|
|
22192
|
+
result: z108.unknown().optional()
|
|
22193
|
+
});
|
|
22194
|
+
|
|
22017
22195
|
// src/response-body.ts
|
|
22018
22196
|
var ResponseBodyTooLargeError = class extends Error {
|
|
22019
22197
|
static {
|
|
@@ -22256,7 +22434,7 @@ var ApiClient = class {
|
|
|
22256
22434
|
};
|
|
22257
22435
|
|
|
22258
22436
|
// src/index.ts
|
|
22259
|
-
var MCP_VERSION = "11.3.
|
|
22437
|
+
var MCP_VERSION = "11.3.3";
|
|
22260
22438
|
|
|
22261
22439
|
// src/meta-upload-app.ts
|
|
22262
22440
|
import { readFileSync } from "fs";
|
|
@@ -22328,7 +22506,7 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
|
|
|
22328
22506
|
__name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
|
|
22329
22507
|
|
|
22330
22508
|
// src/tools/tasks.ts
|
|
22331
|
-
import { z as
|
|
22509
|
+
import { z as z113 } from "zod";
|
|
22332
22510
|
|
|
22333
22511
|
// src/resolve-image.ts
|
|
22334
22512
|
import { lookup as dnsLookup } from "dns/promises";
|
|
@@ -22889,9 +23067,9 @@ async function resolveMediaRef(ref, opts) {
|
|
|
22889
23067
|
__name(resolveMediaRef, "resolveMediaRef");
|
|
22890
23068
|
|
|
22891
23069
|
// src/tools/shared.ts
|
|
22892
|
-
import { z as
|
|
22893
|
-
var Lang =
|
|
22894
|
-
var Country =
|
|
23070
|
+
import { z as z109 } from "zod";
|
|
23071
|
+
var Lang = z109.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);
|
|
23072
|
+
var Country = z109.string().min(2).max(3);
|
|
22895
23073
|
var LandingStrategyEnum = LandingStrategySchema;
|
|
22896
23074
|
var LandingImageFormatEnum = LandingImageFormatSchema;
|
|
22897
23075
|
var VideoPresetEnum = VideoPreset.extract([
|
|
@@ -22995,7 +23173,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
|
|
|
22995
23173
|
return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
|
|
22996
23174
|
}
|
|
22997
23175
|
__name(animationStyleApplies, "animationStyleApplies");
|
|
22998
|
-
var VideoTierEnum =
|
|
23176
|
+
var VideoTierEnum = z109.enum([
|
|
22999
23177
|
"basic"
|
|
23000
23178
|
]);
|
|
23001
23179
|
function resolveVideoTier(_tier) {
|
|
@@ -23053,10 +23231,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
|
|
|
23053
23231
|
var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
|
|
23054
23232
|
var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
|
|
23055
23233
|
var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
|
|
23056
|
-
var ImageRefSchema =
|
|
23057
|
-
url:
|
|
23058
|
-
path:
|
|
23059
|
-
assetId:
|
|
23234
|
+
var ImageRefSchema = z109.object({
|
|
23235
|
+
url: z109.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.'),
|
|
23236
|
+
path: z109.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`.'),
|
|
23237
|
+
assetId: z109.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.")
|
|
23060
23238
|
}).refine((v) => [
|
|
23061
23239
|
v.url,
|
|
23062
23240
|
v.path,
|
|
@@ -23064,11 +23242,11 @@ var ImageRefSchema = z108.object({
|
|
|
23064
23242
|
].filter(Boolean).length === 1, {
|
|
23065
23243
|
message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
|
|
23066
23244
|
});
|
|
23067
|
-
var ImagesInput =
|
|
23245
|
+
var ImagesInput = z109.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
|
|
23068
23246
|
const assetCount = images.filter((image) => Boolean(image.assetId)).length;
|
|
23069
23247
|
if (assetCount > 0 && assetCount !== images.length) {
|
|
23070
23248
|
ctx.addIssue({
|
|
23071
|
-
code:
|
|
23249
|
+
code: z109.ZodIssueCode.custom,
|
|
23072
23250
|
message: "all image entries must use assetId, or all must use URL/path sources"
|
|
23073
23251
|
});
|
|
23074
23252
|
}
|
|
@@ -23118,16 +23296,24 @@ async function submitCreative(api, opts) {
|
|
|
23118
23296
|
...img,
|
|
23119
23297
|
filename: `image-${i}.png`
|
|
23120
23298
|
}));
|
|
23121
|
-
const r = await api.postMultipart(
|
|
23122
|
-
|
|
23123
|
-
|
|
23124
|
-
|
|
23125
|
-
|
|
23126
|
-
|
|
23127
|
-
|
|
23128
|
-
|
|
23129
|
-
|
|
23130
|
-
|
|
23299
|
+
const r = await api.postMultipart(
|
|
23300
|
+
opts.path,
|
|
23301
|
+
{
|
|
23302
|
+
images: parts
|
|
23303
|
+
},
|
|
23304
|
+
// assetIds stays an array so postMultipart appends one `assetIds` field per
|
|
23305
|
+
// id: `flatten` would comma-join them into a single non-UUID value and the
|
|
23306
|
+
// API rejects every multi-photo upload with "assetId must be a valid UUID".
|
|
23307
|
+
{
|
|
23308
|
+
...flatten(rest),
|
|
23309
|
+
...assetIds ? {
|
|
23310
|
+
assetIds
|
|
23311
|
+
} : {}
|
|
23312
|
+
},
|
|
23313
|
+
opts.idempotencyKey ? {
|
|
23314
|
+
idempotencyKey: opts.idempotencyKey
|
|
23315
|
+
} : void 0
|
|
23316
|
+
);
|
|
23131
23317
|
const taskId = r.taskId ?? r.jobId;
|
|
23132
23318
|
return asText({
|
|
23133
23319
|
taskId,
|
|
@@ -23141,14 +23327,14 @@ async function submitCreative(api, opts) {
|
|
|
23141
23327
|
});
|
|
23142
23328
|
}
|
|
23143
23329
|
__name(submitCreative, "submitCreative");
|
|
23144
|
-
var ResearchTargetCountryEnum =
|
|
23330
|
+
var ResearchTargetCountryEnum = z109.enum([
|
|
23145
23331
|
"CO",
|
|
23146
23332
|
"MX",
|
|
23147
23333
|
"PE",
|
|
23148
23334
|
"EC",
|
|
23149
23335
|
"CL"
|
|
23150
23336
|
]);
|
|
23151
|
-
var ResearchCategoryEnum =
|
|
23337
|
+
var ResearchCategoryEnum = z109.enum([
|
|
23152
23338
|
"auto",
|
|
23153
23339
|
"automotive",
|
|
23154
23340
|
"kitchen",
|
|
@@ -24513,29 +24699,29 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
|
|
|
24513
24699
|
__name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
|
|
24514
24700
|
|
|
24515
24701
|
// src/tools/media-presentation.ts
|
|
24516
|
-
import { z as
|
|
24517
|
-
var HttpsPresentationUrlSchema =
|
|
24702
|
+
import { z as z110 } from "zod";
|
|
24703
|
+
var HttpsPresentationUrlSchema = z110.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
|
|
24518
24704
|
var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
|
|
24519
24705
|
const hostname = new URL(value).hostname.toLowerCase();
|
|
24520
24706
|
return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
|
|
24521
24707
|
}, "preview URL must be owned by ProductMaker");
|
|
24522
|
-
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) =>
|
|
24523
|
-
var PresentationImageSchema =
|
|
24524
|
-
kind:
|
|
24708
|
+
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z110.number().int().positive().max(maximum), "positiveIntAtMost");
|
|
24709
|
+
var PresentationImageSchema = z110.object({
|
|
24710
|
+
kind: z110.literal("image"),
|
|
24525
24711
|
url: HttpsPresentationUrlSchema,
|
|
24526
|
-
mimeType:
|
|
24712
|
+
mimeType: z110.enum([
|
|
24527
24713
|
"image/jpeg",
|
|
24528
24714
|
"image/png"
|
|
24529
24715
|
]),
|
|
24530
24716
|
byteSize: positiveIntAtMost(5 * 1024 * 1024),
|
|
24531
24717
|
width: positiveIntAtMost(16384),
|
|
24532
24718
|
height: positiveIntAtMost(16384),
|
|
24533
|
-
alt:
|
|
24719
|
+
alt: z110.string().trim().min(1).max(240)
|
|
24534
24720
|
}).strict();
|
|
24535
24721
|
var McpMediaPresentationSchema = PresentationImageSchema;
|
|
24536
|
-
var GalleryImageSchema =
|
|
24722
|
+
var GalleryImageSchema = z110.object({
|
|
24537
24723
|
url: ProductMakerPreviewUrlSchema,
|
|
24538
|
-
alt:
|
|
24724
|
+
alt: z110.string().trim().min(1).max(240)
|
|
24539
24725
|
});
|
|
24540
24726
|
var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
24541
24727
|
async function imageBlocks(image, transport) {
|
|
@@ -24592,12 +24778,12 @@ async function buildMcpMediaPresentationContent(rawPresentation, transport = "ht
|
|
|
24592
24778
|
];
|
|
24593
24779
|
}
|
|
24594
24780
|
__name(buildMcpMediaPresentationContent, "buildMcpMediaPresentationContent");
|
|
24595
|
-
var OwnedImagePreviewSchema =
|
|
24781
|
+
var OwnedImagePreviewSchema = z110.object({
|
|
24596
24782
|
url: HttpsPresentationUrlSchema.refine((value) => {
|
|
24597
24783
|
const url = new URL(value);
|
|
24598
24784
|
return !url.username && !url.password && !isPrivateHost(url.hostname);
|
|
24599
24785
|
}, "Preview URL must be public HTTPS without credentials"),
|
|
24600
|
-
alt:
|
|
24786
|
+
alt: z110.string().trim().min(1).max(240)
|
|
24601
24787
|
});
|
|
24602
24788
|
async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
|
|
24603
24789
|
const preview2 = OwnedImagePreviewSchema.safeParse(rawPreview);
|
|
@@ -24680,7 +24866,7 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
|
|
|
24680
24866
|
__name(buildMcpImageGalleryContent, "buildMcpImageGalleryContent");
|
|
24681
24867
|
|
|
24682
24868
|
// src/tools/animated-video.ts
|
|
24683
|
-
import { z as
|
|
24869
|
+
import { z as z111 } from "zod";
|
|
24684
24870
|
|
|
24685
24871
|
// src/tools/paid-confirmation.ts
|
|
24686
24872
|
function describeMarketStudyChoice(enabled) {
|
|
@@ -24930,27 +25116,27 @@ function hookVariantsLabel(count) {
|
|
|
24930
25116
|
return count === 1 ? "1 versi\xF3n del gancho" : `${count} versiones del gancho`;
|
|
24931
25117
|
}
|
|
24932
25118
|
__name(hookVariantsLabel, "hookVariantsLabel");
|
|
24933
|
-
var DurationInput =
|
|
24934
|
-
var CreateAnimatedVideoInput =
|
|
24935
|
-
action:
|
|
25119
|
+
var DurationInput = z111.union(MOTION_GRAPHICS_DURATIONS.map((d) => z111.literal(d)));
|
|
25120
|
+
var CreateAnimatedVideoInput = z111.object({
|
|
25121
|
+
action: z111.enum([
|
|
24936
25122
|
"prepare",
|
|
24937
25123
|
"status",
|
|
24938
25124
|
"cancel",
|
|
24939
25125
|
"generate"
|
|
24940
25126
|
]).default("prepare").describe("prepare inicia una captura gratuita; status consulta websiteCaptureId; cancel la cancela; generate requiere captura ready y confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrar vista previa y precio."),
|
|
24941
|
-
websiteCaptureId:
|
|
24942
|
-
generationRequestId:
|
|
24943
|
-
confirmed:
|
|
25127
|
+
websiteCaptureId: z111.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
|
|
25128
|
+
generationRequestId: z111.string().uuid().optional().describe("Identidad opcional de una generaci\xF3n confirmada. Repite el mismo UUID al recuperar una respuesta perdida; usa otro \xFAnicamente cuando el usuario pida y confirme otro video, nunca por un error de transporte."),
|
|
25129
|
+
confirmed: z111.boolean().optional().describe("Solo true despu\xE9s de que el usuario confirme esta captura, formato, duraci\xF3n, idioma y precio. Obligatorio para generate; preparar no genera ni cobra."),
|
|
24944
25130
|
// Plain text, not `.url()`: users type «cal.com», and the web accepts it.
|
|
24945
25131
|
// normalizeWebAddress (shared with the web) adds https:// and refuses
|
|
24946
25132
|
// anything that is not a public http(s) address.
|
|
24947
|
-
landingUrl:
|
|
25133
|
+
landingUrl: z111.string().trim().min(1).optional().describe("Enlace p\xFAblico de la p\xE1gina del servicio, como lo dio el usuario (\xABcal.com\xBB o \xABhttps://cal.com\xBB). El video sale de lo que muestra esa p\xE1gina: su marca, colores y mensajes."),
|
|
24948
25134
|
format: MotionGraphicsFormatSchema.optional().describe('Formato: "vertical" (9:16, Reels/TikTok), "square" (1:1, feed) u "horizontal" (16:9, YouTube/web). Si el usuario no lo dijo, PREG\xDANTALE.'),
|
|
24949
25135
|
durationSec: DurationInput.optional().describe(`Duraci\xF3n en segundos: ${MOTION_GRAPHICS_DURATIONS.join(", ")}. Fija el precio (ver la descripci\xF3n de la herramienta). Si el usuario no la dijo, PREG\xDANTALE.`),
|
|
24950
25136
|
language: MotionGraphicsLanguageSchema.optional().describe('Idioma de los textos del video: "es", "en" o "pt".'),
|
|
24951
|
-
notes:
|
|
25137
|
+
notes: z111.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)."),
|
|
24952
25138
|
hookVariants: MotionGraphicsHookVariantsSchema.optional().describe(`Opcional. Versiones del gancho: el mismo video con distintas aperturas para probar cu\xE1l funciona mejor, de 1 a ${MOTION_GRAPHICS_HOOK_VARIANTS_MAX} (por defecto 1). Cada versi\xF3n extra tiene precio (ver la descripci\xF3n de la herramienta); \xFAsalo solo si el usuario lo pide.`),
|
|
24953
|
-
music:
|
|
25139
|
+
music: z111.boolean().optional().describe("Opcional. M\xFAsica de fondo (por defecto true). false hace el video sin m\xFAsica, m\xE1s crudo, estilo UGC: quedan la voz y los efectos de sonido. Mismo precio. \xDAsalo solo si el usuario lo pide.")
|
|
24954
25140
|
}).strict();
|
|
24955
25141
|
function captureNextAction(capture) {
|
|
24956
25142
|
if (capture.status === "ready") return "Muestra la vista previa al usuario y confirma formato, duraci\xF3n, idioma y precio. Solo despu\xE9s llama create_animated_video con action=generate, este websiteCaptureId y confirmed=true.";
|
|
@@ -24983,43 +25169,43 @@ var FORMAT_LABELS = {
|
|
|
24983
25169
|
square: "cuadrado 1:1",
|
|
24984
25170
|
horizontal: "horizontal 16:9"
|
|
24985
25171
|
};
|
|
24986
|
-
var AnimatedVideoResultSchema =
|
|
24987
|
-
status:
|
|
25172
|
+
var AnimatedVideoResultSchema = z111.object({
|
|
25173
|
+
status: z111.enum([
|
|
24988
25174
|
"pending",
|
|
24989
25175
|
"done",
|
|
24990
25176
|
"error"
|
|
24991
25177
|
]),
|
|
24992
|
-
serviceMode:
|
|
24993
|
-
finalMp4Url:
|
|
24994
|
-
error:
|
|
24995
|
-
motionGraphics:
|
|
25178
|
+
serviceMode: z111.literal("motion_graphics"),
|
|
25179
|
+
finalMp4Url: z111.string().optional(),
|
|
25180
|
+
error: z111.string().optional(),
|
|
25181
|
+
motionGraphics: z111.object({
|
|
24996
25182
|
stage: MotionGraphicsStageSchema,
|
|
24997
25183
|
format: MotionGraphicsFormatSchema,
|
|
24998
|
-
durationSec:
|
|
24999
|
-
width:
|
|
25000
|
-
height:
|
|
25184
|
+
durationSec: z111.number(),
|
|
25185
|
+
width: z111.number().optional(),
|
|
25186
|
+
height: z111.number().optional(),
|
|
25001
25187
|
language: MotionGraphicsLanguageSchema.optional(),
|
|
25002
|
-
queuedAt:
|
|
25003
|
-
jobsAhead:
|
|
25004
|
-
stageStartedAt:
|
|
25005
|
-
renderProgress:
|
|
25188
|
+
queuedAt: z111.string().optional(),
|
|
25189
|
+
jobsAhead: z111.number().int().nonnegative().optional(),
|
|
25190
|
+
stageStartedAt: z111.string().optional(),
|
|
25191
|
+
renderProgress: z111.number().optional(),
|
|
25006
25192
|
// AI clip fields (absent on a video paid before clips, or from an API
|
|
25007
25193
|
// that predates them). Lenient: an unreadable value is dropped
|
|
25008
25194
|
// instead of hiding the status.
|
|
25009
|
-
clipCount:
|
|
25010
|
-
clipsUsed:
|
|
25011
|
-
clipPriceCents:
|
|
25012
|
-
clipsRefunded:
|
|
25195
|
+
clipCount: z111.number().int().nonnegative().optional().catch(void 0),
|
|
25196
|
+
clipsUsed: z111.number().int().nonnegative().optional().catch(void 0),
|
|
25197
|
+
clipPriceCents: z111.number().finite().nonnegative().optional().catch(void 0),
|
|
25198
|
+
clipsRefunded: z111.number().int().nonnegative().optional().catch(void 0),
|
|
25013
25199
|
// Hook versions (absent from an API or a video before them): the
|
|
25014
25200
|
// count ordered and, once done, the signed URLs of the EXTRA versions
|
|
25015
25201
|
// (hook 2, hook 3); `finalMp4Url` is hook 1.
|
|
25016
|
-
hookVariants:
|
|
25017
|
-
variantUrls:
|
|
25202
|
+
hookVariants: z111.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
|
|
25203
|
+
variantUrls: z111.array(z111.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
|
|
25018
25204
|
// Extra hook versions given back, as the task recorded it once the
|
|
25019
25205
|
// refunds landed (absent until then, and from an API before it).
|
|
25020
|
-
variantsRefunded:
|
|
25021
|
-
activity:
|
|
25022
|
-
previewUrl:
|
|
25206
|
+
variantsRefunded: z111.number().int().nonnegative().optional().catch(void 0),
|
|
25207
|
+
activity: z111.array(MotionGraphicsActivitySchema).optional().catch(void 0),
|
|
25208
|
+
previewUrl: z111.string().optional()
|
|
25023
25209
|
}).passthrough()
|
|
25024
25210
|
}).passthrough();
|
|
25025
25211
|
function parseAnimatedVideoResult(value) {
|
|
@@ -25275,10 +25461,10 @@ function registerAnimatedVideoTools(server, api) {
|
|
|
25275
25461
|
__name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
|
|
25276
25462
|
|
|
25277
25463
|
// src/tools/winning-product-image.ts
|
|
25278
|
-
import { z as
|
|
25279
|
-
var WinnerReferenceInput =
|
|
25280
|
-
runId:
|
|
25281
|
-
candidateSourceId:
|
|
25464
|
+
import { z as z112 } from "zod";
|
|
25465
|
+
var WinnerReferenceInput = z112.object({
|
|
25466
|
+
runId: z112.string().uuid(),
|
|
25467
|
+
candidateSourceId: z112.string().trim().min(1).max(160)
|
|
25282
25468
|
}).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
|
|
25283
25469
|
async function resolveWinnerImages(api, winnerReference, images) {
|
|
25284
25470
|
if (!winnerReference) return images;
|
|
@@ -25315,62 +25501,62 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
|
|
|
25315
25501
|
var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
|
|
25316
25502
|
var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
|
|
25317
25503
|
var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
|
|
25318
|
-
var CreateProductTaskInput =
|
|
25504
|
+
var CreateProductTaskInput = z113.object({
|
|
25319
25505
|
images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
|
|
25320
25506
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
25321
|
-
projectId:
|
|
25322
|
-
productUrl:
|
|
25507
|
+
projectId: z113.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
|
|
25508
|
+
productUrl: z113.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."),
|
|
25323
25509
|
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.'),
|
|
25324
25510
|
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.'),
|
|
25325
|
-
price:
|
|
25326
|
-
compareAtPrice:
|
|
25327
|
-
offer:
|
|
25328
|
-
paymentMethods:
|
|
25329
|
-
productContext:
|
|
25330
|
-
productLabel:
|
|
25511
|
+
price: z113.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.'),
|
|
25512
|
+
compareAtPrice: z113.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".'),
|
|
25513
|
+
offer: z113.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.'),
|
|
25514
|
+
paymentMethods: z113.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.'),
|
|
25515
|
+
productContext: z113.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."),
|
|
25516
|
+
productLabel: z113.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.'),
|
|
25331
25517
|
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.'),
|
|
25332
25518
|
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.'),
|
|
25333
|
-
durationSeconds:
|
|
25334
|
-
|
|
25335
|
-
|
|
25519
|
+
durationSeconds: z113.union([
|
|
25520
|
+
z113.literal(15),
|
|
25521
|
+
z113.literal(30)
|
|
25336
25522
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
25337
|
-
pauseForAngleReview:
|
|
25338
|
-
aiDecidesAll:
|
|
25523
|
+
pauseForAngleReview: z113.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."),
|
|
25524
|
+
aiDecidesAll: z113.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."),
|
|
25339
25525
|
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.'),
|
|
25340
25526
|
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.'),
|
|
25341
25527
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
25342
25528
|
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).'),
|
|
25343
|
-
videoAngleCount:
|
|
25529
|
+
videoAngleCount: z113.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."),
|
|
25344
25530
|
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.'),
|
|
25345
|
-
outputs:
|
|
25531
|
+
outputs: z113.array(z113.enum([
|
|
25346
25532
|
"landing",
|
|
25347
25533
|
"video",
|
|
25348
25534
|
"image"
|
|
25349
25535
|
])).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}`),
|
|
25350
|
-
includeInitialLandingGif:
|
|
25351
|
-
competitorScanEnabled:
|
|
25536
|
+
includeInitialLandingGif: z113.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
|
|
25537
|
+
competitorScanEnabled: z113.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."),
|
|
25352
25538
|
generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, efectos y m\xFAsica sobre cada video entregado (variante with_ai_edit; se cobra al entregar, por video). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro"; false/omitido = sin edici\xF3n.'),
|
|
25353
|
-
replicateWinnerWhenFound:
|
|
25354
|
-
brandId:
|
|
25355
|
-
actorId:
|
|
25539
|
+
replicateWinnerWhenFound: z113.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."),
|
|
25540
|
+
brandId: z113.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."),
|
|
25541
|
+
actorId: z113.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."),
|
|
25356
25542
|
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.'),
|
|
25357
|
-
creativeDirection:
|
|
25358
|
-
headline:
|
|
25359
|
-
subheadline:
|
|
25543
|
+
creativeDirection: z113.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.'),
|
|
25544
|
+
headline: z113.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."),
|
|
25545
|
+
subheadline: z113.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."),
|
|
25360
25546
|
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".'),
|
|
25361
25547
|
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".')
|
|
25362
25548
|
}).strict();
|
|
25363
|
-
var CreateServiceVideoInput =
|
|
25364
|
-
landingUrl:
|
|
25365
|
-
additionalContext:
|
|
25549
|
+
var CreateServiceVideoInput = z113.object({
|
|
25550
|
+
landingUrl: z113.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
|
|
25551
|
+
additionalContext: z113.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
|
|
25366
25552
|
language: Lang.describe("Idioma del video: es, en o pt."),
|
|
25367
|
-
voiceId:
|
|
25368
|
-
brandId:
|
|
25369
|
-
reviewMode:
|
|
25553
|
+
voiceId: z113.string().trim().min(1).pipe(VoiceId).optional().describe('Opcional. Voz para toda la narraci\xF3n. Usa "auto" para que la IA la alinee con el presentador. Las voces del banco compartido fueron retiradas.'),
|
|
25554
|
+
brandId: z113.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
|
|
25555
|
+
reviewMode: z113.enum([
|
|
25370
25556
|
"automatic",
|
|
25371
25557
|
"guided"
|
|
25372
25558
|
]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
|
|
25373
|
-
videoPreset:
|
|
25559
|
+
videoPreset: z113.enum([
|
|
25374
25560
|
"auto",
|
|
25375
25561
|
"ugc_dynamic",
|
|
25376
25562
|
"ugc_how_to",
|
|
@@ -25380,128 +25566,128 @@ var CreateServiceVideoInput = z112.object({
|
|
|
25380
25566
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
25381
25567
|
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.')
|
|
25382
25568
|
}).strict();
|
|
25383
|
-
var GetTaskStatusInput =
|
|
25384
|
-
taskId:
|
|
25385
|
-
waitSeconds:
|
|
25569
|
+
var GetTaskStatusInput = z113.object({
|
|
25570
|
+
taskId: z113.string().min(1),
|
|
25571
|
+
waitSeconds: z113.number().int().min(0).max(120).optional()
|
|
25386
25572
|
});
|
|
25387
|
-
var ListTasksInput =
|
|
25388
|
-
limit:
|
|
25389
|
-
offset:
|
|
25390
|
-
search:
|
|
25573
|
+
var ListTasksInput = z113.object({
|
|
25574
|
+
limit: z113.number().int().min(1).max(50).optional(),
|
|
25575
|
+
offset: z113.number().int().min(0).optional(),
|
|
25576
|
+
search: z113.string().optional()
|
|
25391
25577
|
});
|
|
25392
25578
|
var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
|
|
25393
25579
|
var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
|
|
25394
|
-
var EditTaskDraftInput =
|
|
25395
|
-
taskId:
|
|
25396
|
-
angleIndex:
|
|
25397
|
-
angle:
|
|
25398
|
-
angle:
|
|
25399
|
-
buyerPersona:
|
|
25400
|
-
actor:
|
|
25401
|
-
actorId:
|
|
25402
|
-
gender:
|
|
25580
|
+
var EditTaskDraftInput = z113.object({
|
|
25581
|
+
taskId: z113.string().min(1),
|
|
25582
|
+
angleIndex: z113.number().int().min(0),
|
|
25583
|
+
angle: z113.object({
|
|
25584
|
+
angle: z113.string().min(1).max(480),
|
|
25585
|
+
buyerPersona: z113.string().min(1).max(360),
|
|
25586
|
+
actor: z113.string().min(1).max(360).optional(),
|
|
25587
|
+
actorId: z113.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."),
|
|
25588
|
+
gender: z113.enum([
|
|
25403
25589
|
"female",
|
|
25404
25590
|
"male"
|
|
25405
25591
|
]).optional(),
|
|
25406
|
-
scriptNotes:
|
|
25592
|
+
scriptNotes: z113.string().max(2e3).optional()
|
|
25407
25593
|
})
|
|
25408
25594
|
});
|
|
25409
|
-
var PendingActionPayload =
|
|
25410
|
-
|
|
25411
|
-
kind:
|
|
25595
|
+
var PendingActionPayload = z113.discriminatedUnion("kind", [
|
|
25596
|
+
z113.object({
|
|
25597
|
+
kind: z113.literal("product_reference_set_approval"),
|
|
25412
25598
|
scope: ProductReferenceScopeEnum.optional(),
|
|
25413
|
-
scopeKey:
|
|
25414
|
-
scopeSnapshotId:
|
|
25415
|
-
expectedScopeHash:
|
|
25599
|
+
scopeKey: z113.string().min(1).max(120).optional(),
|
|
25600
|
+
scopeSnapshotId: z113.string().uuid().optional(),
|
|
25601
|
+
expectedScopeHash: z113.string().min(1).max(128).optional(),
|
|
25416
25602
|
decision: ProductReferenceResolutionDecisionEnum,
|
|
25417
25603
|
reason: ProductReferenceRejectionReasonEnum.optional(),
|
|
25418
|
-
affectedRefKeys:
|
|
25419
|
-
affectedPhotoNumbers:
|
|
25420
|
-
recoveryAction:
|
|
25604
|
+
affectedRefKeys: z113.array(z113.string().min(1).max(200)).min(1).optional(),
|
|
25605
|
+
affectedPhotoNumbers: z113.array(z113.number().int().positive()).min(1).optional(),
|
|
25606
|
+
recoveryAction: z113.enum([
|
|
25421
25607
|
"remove",
|
|
25422
25608
|
"replace",
|
|
25423
25609
|
"upload",
|
|
25424
25610
|
"return_to_selection"
|
|
25425
25611
|
]).optional()
|
|
25426
25612
|
}),
|
|
25427
|
-
|
|
25428
|
-
kind:
|
|
25429
|
-
selectedPhotoNumbers:
|
|
25613
|
+
z113.object({
|
|
25614
|
+
kind: z113.literal("product_reference_confirmation"),
|
|
25615
|
+
selectedPhotoNumbers: z113.array(z113.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."),
|
|
25430
25616
|
userChoice: ProductReferenceUserChoiceEnum.optional(),
|
|
25431
|
-
confirmedProductNames:
|
|
25617
|
+
confirmedProductNames: z113.array(z113.string().min(1).max(120)).min(2).max(8).optional(),
|
|
25432
25618
|
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."),
|
|
25433
25619
|
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."),
|
|
25434
|
-
useMultiSceneShowcase:
|
|
25620
|
+
useMultiSceneShowcase: z113.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
|
|
25435
25621
|
}),
|
|
25436
|
-
|
|
25437
|
-
kind:
|
|
25622
|
+
z113.object({
|
|
25623
|
+
kind: z113.literal("angle_review_approval"),
|
|
25438
25624
|
// All edits are optional — empty action body just approves the
|
|
25439
25625
|
// backend-generated draft as-is. Field shapes mirror the angle-review
|
|
25440
25626
|
// request contracts in @packages/types/wizard.ts; the handler routes to
|
|
25441
25627
|
// the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
|
|
25442
|
-
customAngle:
|
|
25628
|
+
customAngle: z113.string().min(1).max(480).optional(),
|
|
25443
25629
|
// Keep the shared MCP action within the strictest downstream contract:
|
|
25444
25630
|
// autopilot/image resume endpoints cap these fields at 1500 characters.
|
|
25445
|
-
painPoints:
|
|
25446
|
-
benefits:
|
|
25631
|
+
painPoints: z113.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
25632
|
+
benefits: z113.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
25447
25633
|
// Same policy as the two fields above: the strictest downstream contract
|
|
25448
25634
|
// wins. The image endpoint caps each feature at 240 while landing/video
|
|
25449
25635
|
// accept 300, and this single action routes to whichever the task is — so
|
|
25450
25636
|
// accepting 300 here turns a 250-character feature on an image task into
|
|
25451
25637
|
// an opaque HTTP 400 after the model already believed it had been saved.
|
|
25452
|
-
features:
|
|
25453
|
-
buyerPersona:
|
|
25638
|
+
features: z113.array(z113.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
|
|
25639
|
+
buyerPersona: z113.string().min(1).max(360).optional(),
|
|
25454
25640
|
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.'),
|
|
25455
|
-
actor:
|
|
25456
|
-
actorId:
|
|
25457
|
-
creativeDirection:
|
|
25458
|
-
selectedAngleNumbers:
|
|
25459
|
-
angleEdits:
|
|
25460
|
-
angleNumber:
|
|
25461
|
-
narrativeSelection:
|
|
25641
|
+
actor: z113.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."),
|
|
25642
|
+
actorId: z113.string().max(120).nullable().optional(),
|
|
25643
|
+
creativeDirection: z113.string().max(2e3).optional(),
|
|
25644
|
+
selectedAngleNumbers: z113.array(z113.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."),
|
|
25645
|
+
angleEdits: z113.array(z113.object({
|
|
25646
|
+
angleNumber: z113.number().int().positive(),
|
|
25647
|
+
narrativeSelection: z113.enum([
|
|
25462
25648
|
"market",
|
|
25463
25649
|
"guided"
|
|
25464
25650
|
]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
|
|
25465
|
-
angle:
|
|
25466
|
-
buyerPersona:
|
|
25651
|
+
angle: z113.string().min(1).max(480).optional(),
|
|
25652
|
+
buyerPersona: z113.string().min(1).max(360).optional(),
|
|
25467
25653
|
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.'),
|
|
25468
|
-
actor:
|
|
25469
|
-
actorId:
|
|
25470
|
-
creativeDirection:
|
|
25654
|
+
actor: z113.string().min(1).max(360).optional(),
|
|
25655
|
+
actorId: z113.string().max(120).nullable().optional(),
|
|
25656
|
+
creativeDirection: z113.string().max(2e3).optional()
|
|
25471
25657
|
}).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)."),
|
|
25472
|
-
gapDurationSeconds:
|
|
25473
|
-
|
|
25474
|
-
|
|
25658
|
+
gapDurationSeconds: z113.union([
|
|
25659
|
+
z113.literal(15),
|
|
25660
|
+
z113.literal(30)
|
|
25475
25661
|
]).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.")
|
|
25476
25662
|
}),
|
|
25477
|
-
|
|
25478
|
-
kind:
|
|
25479
|
-
angleId:
|
|
25480
|
-
angleNumber:
|
|
25481
|
-
content:
|
|
25482
|
-
creativeDirection:
|
|
25483
|
-
actor:
|
|
25663
|
+
z113.object({
|
|
25664
|
+
kind: z113.literal("service_angle_approval"),
|
|
25665
|
+
angleId: z113.string().uuid().optional(),
|
|
25666
|
+
angleNumber: z113.number().int().positive().optional(),
|
|
25667
|
+
content: z113.string().min(1).max(480).optional(),
|
|
25668
|
+
creativeDirection: z113.string().min(1).max(1500).optional(),
|
|
25669
|
+
actor: z113.string().min(1).max(360).optional()
|
|
25484
25670
|
}),
|
|
25485
|
-
|
|
25486
|
-
kind:
|
|
25487
|
-
voiceovers:
|
|
25488
|
-
visualDirections:
|
|
25489
|
-
voiceoversByScene:
|
|
25490
|
-
visualDirectionsByScene:
|
|
25671
|
+
z113.object({
|
|
25672
|
+
kind: z113.literal("service_script_approval"),
|
|
25673
|
+
voiceovers: z113.record(z113.string(), z113.string().min(1).max(600)).optional(),
|
|
25674
|
+
visualDirections: z113.record(z113.string(), z113.string().min(1).max(1200)).optional(),
|
|
25675
|
+
voiceoversByScene: z113.record(z113.string(), z113.string().min(1).max(600)).optional(),
|
|
25676
|
+
visualDirectionsByScene: z113.record(z113.string(), z113.string().min(1).max(1200)).optional()
|
|
25491
25677
|
})
|
|
25492
25678
|
]);
|
|
25493
|
-
var ResolvePendingActionInput =
|
|
25494
|
-
taskId:
|
|
25679
|
+
var ResolvePendingActionInput = z113.object({
|
|
25680
|
+
taskId: z113.string().min(1),
|
|
25495
25681
|
action: PendingActionPayload
|
|
25496
25682
|
}).strict();
|
|
25497
25683
|
function resolveVariantConfirmVideoTier(action) {
|
|
25498
25684
|
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
25499
25685
|
}
|
|
25500
25686
|
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
25501
|
-
var StatusForResolveSchema =
|
|
25687
|
+
var StatusForResolveSchema = z113.object({
|
|
25502
25688
|
// Metadata used to select the backend resume contract. Older API responses
|
|
25503
25689
|
// may omit these fields, so the resolver keeps the generic fallback.
|
|
25504
|
-
kind:
|
|
25690
|
+
kind: z113.enum([
|
|
25505
25691
|
"autopilot",
|
|
25506
25692
|
"video",
|
|
25507
25693
|
"image",
|
|
@@ -25509,18 +25695,18 @@ var StatusForResolveSchema = z112.object({
|
|
|
25509
25695
|
"mix",
|
|
25510
25696
|
"service"
|
|
25511
25697
|
]).optional(),
|
|
25512
|
-
selectedOutputs:
|
|
25698
|
+
selectedOutputs: z113.array(z113.enum([
|
|
25513
25699
|
"landing",
|
|
25514
25700
|
"video",
|
|
25515
25701
|
"image"
|
|
25516
25702
|
])).optional(),
|
|
25517
|
-
videoAngleCount:
|
|
25518
|
-
ugcFormat:
|
|
25703
|
+
videoAngleCount: z113.number().int().min(1).max(3).optional(),
|
|
25704
|
+
ugcFormat: z113.enum([
|
|
25519
25705
|
"single_8s",
|
|
25520
25706
|
"single_15s",
|
|
25521
25707
|
"double_30s"
|
|
25522
25708
|
]).optional(),
|
|
25523
|
-
videoStyle:
|
|
25709
|
+
videoStyle: z113.enum([
|
|
25524
25710
|
"ugc",
|
|
25525
25711
|
"cartoon_3d",
|
|
25526
25712
|
"product_only",
|
|
@@ -25530,13 +25716,13 @@ var StatusForResolveSchema = z112.object({
|
|
|
25530
25716
|
videoQuality: VideoQualityEnum.optional(),
|
|
25531
25717
|
videoRouteId: VideoRouteIdEnum.optional(),
|
|
25532
25718
|
videoModel: TaskVideoModelEnum.optional(),
|
|
25533
|
-
videoTier:
|
|
25719
|
+
videoTier: z113.enum([
|
|
25534
25720
|
"legacy",
|
|
25535
25721
|
"standard",
|
|
25536
25722
|
"pro",
|
|
25537
25723
|
"single_call"
|
|
25538
25724
|
]).optional(),
|
|
25539
|
-
videoResolution:
|
|
25725
|
+
videoResolution: z113.enum([
|
|
25540
25726
|
"480p",
|
|
25541
25727
|
"720p"
|
|
25542
25728
|
]).optional(),
|
|
@@ -25544,60 +25730,60 @@ var StatusForResolveSchema = z112.object({
|
|
|
25544
25730
|
// A task created before a narrative was blocked/hidden must still parse,
|
|
25545
25731
|
// or resolve_pending_action could never approve it.
|
|
25546
25732
|
narrativeStyle: NarrativeStyle.optional(),
|
|
25547
|
-
pauseForVideoScriptReview:
|
|
25548
|
-
pendingUserAction:
|
|
25549
|
-
kind:
|
|
25550
|
-
candidateGrouping:
|
|
25551
|
-
selectedImageUrls:
|
|
25552
|
-
proposedProductNames:
|
|
25733
|
+
pauseForVideoScriptReview: z113.boolean().optional(),
|
|
25734
|
+
pendingUserAction: z113.object({
|
|
25735
|
+
kind: z113.string(),
|
|
25736
|
+
candidateGrouping: z113.string().optional(),
|
|
25737
|
+
selectedImageUrls: z113.array(z113.string()).optional(),
|
|
25738
|
+
proposedProductNames: z113.array(z113.string()).optional(),
|
|
25553
25739
|
// Adaptive reference questions are server-owned. Echo only the evidence
|
|
25554
25740
|
// identity and the choices shown by the current snapshot; never accept a
|
|
25555
25741
|
// client-supplied reference set as authorization.
|
|
25556
|
-
options:
|
|
25557
|
-
mode:
|
|
25742
|
+
options: z113.array(ProductReferenceUserChoiceEnum).max(4).optional(),
|
|
25743
|
+
mode: z113.enum([
|
|
25558
25744
|
"question",
|
|
25559
25745
|
"visual_recovery"
|
|
25560
25746
|
]).optional(),
|
|
25561
25747
|
/** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
|
|
25562
|
-
canKeepSelection:
|
|
25563
|
-
decisionKey:
|
|
25564
|
-
questionOrdinal:
|
|
25565
|
-
questionCeiling:
|
|
25566
|
-
|
|
25567
|
-
|
|
25748
|
+
canKeepSelection: z113.boolean().optional(),
|
|
25749
|
+
decisionKey: z113.string().optional(),
|
|
25750
|
+
questionOrdinal: z113.number().int().min(1).max(5).optional(),
|
|
25751
|
+
questionCeiling: z113.union([
|
|
25752
|
+
z113.literal(3),
|
|
25753
|
+
z113.literal(5)
|
|
25568
25754
|
]).optional(),
|
|
25569
|
-
referenceEvidenceVersion:
|
|
25570
|
-
expectedEvidenceHash:
|
|
25571
|
-
question:
|
|
25572
|
-
prompt:
|
|
25573
|
-
helpText:
|
|
25574
|
-
options:
|
|
25755
|
+
referenceEvidenceVersion: z113.number().int().positive().optional(),
|
|
25756
|
+
expectedEvidenceHash: z113.string().optional(),
|
|
25757
|
+
question: z113.object({
|
|
25758
|
+
prompt: z113.string().min(1).max(240),
|
|
25759
|
+
helpText: z113.string().min(1).max(300).optional(),
|
|
25760
|
+
options: z113.array(z113.object({
|
|
25575
25761
|
value: ProductReferenceUserChoiceEnum,
|
|
25576
|
-
label:
|
|
25577
|
-
description:
|
|
25762
|
+
label: z113.string().min(1).max(120),
|
|
25763
|
+
description: z113.string().min(1).max(240).optional()
|
|
25578
25764
|
})).min(2).max(4)
|
|
25579
25765
|
}).optional(),
|
|
25580
25766
|
scope: ProductReferenceScopeEnum.optional(),
|
|
25581
|
-
scopeKey:
|
|
25582
|
-
scopeSnapshotId:
|
|
25583
|
-
scopeHash:
|
|
25584
|
-
baseReferenceSetHash:
|
|
25585
|
-
phase:
|
|
25767
|
+
scopeKey: z113.string().optional(),
|
|
25768
|
+
scopeSnapshotId: z113.string().uuid().optional(),
|
|
25769
|
+
scopeHash: z113.string().optional(),
|
|
25770
|
+
baseReferenceSetHash: z113.string().optional(),
|
|
25771
|
+
phase: z113.enum([
|
|
25586
25772
|
"preparation",
|
|
25587
25773
|
"final"
|
|
25588
25774
|
]).optional(),
|
|
25589
|
-
selectedRefKeys:
|
|
25590
|
-
allowedDecisions:
|
|
25591
|
-
previews:
|
|
25592
|
-
refKey:
|
|
25775
|
+
selectedRefKeys: z113.array(z113.string().min(1).max(200)).optional(),
|
|
25776
|
+
allowedDecisions: z113.array(ProductReferenceResolutionDecisionEnum).optional(),
|
|
25777
|
+
previews: z113.array(z113.object({
|
|
25778
|
+
refKey: z113.string().min(1).max(200)
|
|
25593
25779
|
}).passthrough()).optional(),
|
|
25594
|
-
customAngleDraft:
|
|
25595
|
-
painPointsDraft:
|
|
25596
|
-
benefitsDraft:
|
|
25597
|
-
featuresDraft:
|
|
25598
|
-
angleOptions:
|
|
25599
|
-
index:
|
|
25600
|
-
angle:
|
|
25780
|
+
customAngleDraft: z113.string().optional(),
|
|
25781
|
+
painPointsDraft: z113.string().optional(),
|
|
25782
|
+
benefitsDraft: z113.string().optional(),
|
|
25783
|
+
featuresDraft: z113.array(z113.string()).optional(),
|
|
25784
|
+
angleOptions: z113.array(z113.object({
|
|
25785
|
+
index: z113.number().int().nonnegative(),
|
|
25786
|
+
angle: z113.string().min(1)
|
|
25601
25787
|
}).passthrough()).min(1).max(5).optional(),
|
|
25602
25788
|
// Recommendation consumed only when the caller explicitly sends
|
|
25603
25789
|
// gapDurationSeconds: 30 in the angle approval action.
|
|
@@ -25607,17 +25793,17 @@ var StatusForResolveSchema = z112.object({
|
|
|
25607
25793
|
// keys. `actorId` (the saved custom actor the picker stored) was silently
|
|
25608
25794
|
// dropped here, so the approval handler below could not echo it back on the
|
|
25609
25795
|
// PATCH — the selection looked accepted and reached no render.
|
|
25610
|
-
angles:
|
|
25611
|
-
id:
|
|
25612
|
-
content:
|
|
25613
|
-
creativeDirection:
|
|
25614
|
-
actor:
|
|
25615
|
-
actorId:
|
|
25796
|
+
angles: z113.array(z113.object({
|
|
25797
|
+
id: z113.string().uuid(),
|
|
25798
|
+
content: z113.string(),
|
|
25799
|
+
creativeDirection: z113.string(),
|
|
25800
|
+
actor: z113.string(),
|
|
25801
|
+
actorId: z113.string().nullable().optional()
|
|
25616
25802
|
}).passthrough()).optional(),
|
|
25617
|
-
panels:
|
|
25618
|
-
beatId:
|
|
25619
|
-
voiceover:
|
|
25620
|
-
visualDirection:
|
|
25803
|
+
panels: z113.array(z113.object({
|
|
25804
|
+
beatId: z113.string(),
|
|
25805
|
+
voiceover: z113.string(),
|
|
25806
|
+
visualDirection: z113.string()
|
|
25621
25807
|
}).passthrough()).optional()
|
|
25622
25808
|
}).optional()
|
|
25623
25809
|
}).passthrough();
|
|
@@ -25969,8 +26155,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
25969
26155
|
server.registerTool("verify_landing_commerce", {
|
|
25970
26156
|
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.",
|
|
25971
26157
|
inputSchema: {
|
|
25972
|
-
taskId:
|
|
25973
|
-
editId:
|
|
26158
|
+
taskId: z113.string().uuid(),
|
|
26159
|
+
editId: z113.string().uuid()
|
|
25974
26160
|
},
|
|
25975
26161
|
annotations: OVERWRITES_EXTERNAL
|
|
25976
26162
|
}, async (input) => {
|
|
@@ -26616,25 +26802,25 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
26616
26802
|
__name(registerTaskTools, "registerTaskTools");
|
|
26617
26803
|
|
|
26618
26804
|
// src/tools/brands.ts
|
|
26619
|
-
import { z as
|
|
26805
|
+
import { z as z114 } from "zod";
|
|
26620
26806
|
var guidance2 = getProductMakerCapabilityModelGuidance("create_brand");
|
|
26621
26807
|
var BRAND_START_REPLAY_WINDOW_MS = 15 * 60 * 1e3;
|
|
26622
26808
|
var BRAND_NOTES_MAX_CHARS = 2e4;
|
|
26623
|
-
var CreateBrandInput =
|
|
26624
|
-
action:
|
|
26809
|
+
var CreateBrandInput = z114.object({
|
|
26810
|
+
action: z114.enum([
|
|
26625
26811
|
"start",
|
|
26626
26812
|
"status",
|
|
26627
26813
|
"list"
|
|
26628
26814
|
]).default("start").describe("start cotiza (sin confirmed) o inicia (confirmed=true) el an\xE1lisis; status consulta brandId hasta ready o failed; list muestra las marcas que el usuario ya tiene."),
|
|
26629
|
-
sourceUrl:
|
|
26630
|
-
businessNotes:
|
|
26631
|
-
language:
|
|
26815
|
+
sourceUrl: z114.string().trim().min(1).max(500).optional().describe("Instagram, Facebook, TikTok o web p\xFAblica del negocio, como la dio el usuario (\xAB@sanlucasbarberia\xBB, \xABinstagram.com/sanlucasbarberia\xBB, \xABmibarberia.com\xBB). Obligatorio para start."),
|
|
26816
|
+
businessNotes: z114.string().trim().max(BRAND_NOTES_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cuente de su negocio en el chat (servicios y precios, WhatsApp, ciudad o zona, horarios). Se guarda como documento del negocio y llega tal cual a la marca y a su landing. Copia sus palabras; no inventes datos."),
|
|
26817
|
+
language: z114.enum([
|
|
26632
26818
|
"es",
|
|
26633
26819
|
"en",
|
|
26634
26820
|
"pt"
|
|
26635
26821
|
]).optional().describe("Idioma de la conversaci\xF3n. Solo se usa si la p\xE1gina del negocio no deja claro su idioma."),
|
|
26636
|
-
confirmed:
|
|
26637
|
-
brandId:
|
|
26822
|
+
confirmed: z114.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, start solo cotiza y no cobra."),
|
|
26823
|
+
brandId: z114.string().uuid().optional().describe("ID de la marca. Obligatorio para status; no lo inventes.")
|
|
26638
26824
|
}).strict();
|
|
26639
26825
|
function normalizeBrandSourceUrl(raw) {
|
|
26640
26826
|
const value = raw.trim();
|
|
@@ -26874,24 +27060,24 @@ __name(registerBrandTools, "registerBrandTools");
|
|
|
26874
27060
|
|
|
26875
27061
|
// src/tools/service-landing.ts
|
|
26876
27062
|
import { createHash as createHash3 } from "crypto";
|
|
26877
|
-
import { z as
|
|
27063
|
+
import { z as z115 } from "zod";
|
|
26878
27064
|
var guidance3 = getProductMakerCapabilityModelGuidance("create_service_landing");
|
|
26879
27065
|
var SERVICE_LANDING_KEY_NAMESPACE = "6f1d8c2a-3b4e-5f60-8a7b-9c0d1e2f3a4b";
|
|
26880
27066
|
var SERVICE_LANDING_INFO_MAX_CHARS = 2e4;
|
|
26881
|
-
var CreateServiceLandingInput =
|
|
26882
|
-
action:
|
|
27067
|
+
var CreateServiceLandingInput = z115.object({
|
|
27068
|
+
action: z115.enum([
|
|
26883
27069
|
"prepare",
|
|
26884
27070
|
"build",
|
|
26885
27071
|
"status",
|
|
26886
27072
|
"publish"
|
|
26887
27073
|
]).default("prepare").describe("prepare (gratis) crea o retoma la landing de la marca y da el precio; build (pagado, confirmed=true) lee los datos del negocio y luego crea la p\xE1gina; status sigue el avance; publish la publica y devuelve su enlace."),
|
|
26888
|
-
brandId:
|
|
26889
|
-
servicePageId:
|
|
26890
|
-
businessInfo:
|
|
26891
|
-
confirmed:
|
|
26892
|
-
maxCredits:
|
|
26893
|
-
operationId:
|
|
26894
|
-
slug:
|
|
27074
|
+
brandId: z115.string().uuid().optional().describe("ID de la marca (de create_brand). Obligatorio para prepare. Nunca un taskId de producto."),
|
|
27075
|
+
servicePageId: z115.string().uuid().optional().describe("ID de la landing que devolvi\xF3 prepare. Obligatorio para build, status y publish."),
|
|
27076
|
+
businessInfo: z115.string().trim().max(SERVICE_LANDING_INFO_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cont\xF3 del negocio y no estaba en su marca: servicios y precios, WhatsApp o tel\xE9fono, ciudad o zona, horarios. Copia sus palabras; no inventes datos."),
|
|
27077
|
+
confirmed: z115.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio total y que el usuario acepte. Obligatorio para build."),
|
|
27078
|
+
maxCredits: z115.number().int().positive().optional().describe("El total en cr\xE9ditos que el usuario acept\xF3 (el que devolvi\xF3 prepare). Obligatorio para build: ninguna etapa se inicia si su precio supera este total."),
|
|
27079
|
+
operationId: z115.string().uuid().optional().describe("Opcional en status: la operaci\xF3n que devolvi\xF3 build."),
|
|
27080
|
+
slug: z115.string().trim().toLowerCase().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(64).optional().describe("Opcional en publish: la direcci\xF3n corta de la p\xE1gina (ej. sanlucas-barberia). Si falta se usa la sugerida desde el nombre del negocio.")
|
|
26895
27081
|
}).strict();
|
|
26896
27082
|
var SERVICE_LANDING_MAX_BUILD_ATTEMPTS = 10;
|
|
26897
27083
|
function serviceKey(...parts) {
|
|
@@ -27113,9 +27299,6 @@ function registerServiceLandingTools(server, api) {
|
|
|
27113
27299
|
let operation2 = null;
|
|
27114
27300
|
if (input.operationId) {
|
|
27115
27301
|
operation2 = await api.getJson(`/v1/service-pages/operations/${encodeURIComponent(input.operationId)}`);
|
|
27116
|
-
if (operation2.recoverable && (operation2.status === "failed" || operation2.status === "requires_reconciliation")) {
|
|
27117
|
-
operation2 = await api.postJson(`${pagePath(input.servicePageId)}/operations/${encodeURIComponent(operation2.opId)}/recover`, {});
|
|
27118
|
-
}
|
|
27119
27302
|
if (operation2.status === "queued" || operation2.status === "running") {
|
|
27120
27303
|
return asText({
|
|
27121
27304
|
servicePageId: input.servicePageId,
|
|
@@ -27132,7 +27315,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
27132
27315
|
status: "in_review",
|
|
27133
27316
|
// Unknown on purpose: the charge is exactly what is being
|
|
27134
27317
|
// confirmed. Settlement only charges a completed step.
|
|
27135
|
-
nextAction: "Esta etapa qued\xF3 en revisi\xF3n por un problema temporal:
|
|
27318
|
+
nextAction: "Esta etapa qued\xF3 en revisi\xF3n por un problema temporal: el servidor est\xE1 confirmando si se complet\xF3 y la resuelve solo. Si no se completa, se devuelve lo cobrado. Dile al usuario que sus datos est\xE1n guardados; vuelve a llamar action=status con el mismo operationId en unos minutos (si no se complet\xF3, pasa a fallida y la reintentas con build). No inicies otra etapa mientras tanto."
|
|
27136
27319
|
});
|
|
27137
27320
|
}
|
|
27138
27321
|
if (operation2.status !== "succeeded") {
|
|
@@ -27227,7 +27410,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
27227
27410
|
__name(registerServiceLandingTools, "registerServiceLandingTools");
|
|
27228
27411
|
|
|
27229
27412
|
// src/tools/service-images.ts
|
|
27230
|
-
import { z as
|
|
27413
|
+
import { z as z116 } from "zod";
|
|
27231
27414
|
var guidance4 = getProductMakerCapabilityModelGuidance("create_service_images");
|
|
27232
27415
|
var SERVICE_IMAGE_FORMATS = [
|
|
27233
27416
|
"4:5",
|
|
@@ -27240,23 +27423,23 @@ var LANGUAGE_TAGS = {
|
|
|
27240
27423
|
en: "en-US",
|
|
27241
27424
|
pt: "pt-BR"
|
|
27242
27425
|
};
|
|
27243
|
-
var CreateServiceImagesInput =
|
|
27244
|
-
brandId:
|
|
27245
|
-
instruction:
|
|
27246
|
-
delegateToAi:
|
|
27247
|
-
format:
|
|
27248
|
-
count:
|
|
27249
|
-
quality:
|
|
27426
|
+
var CreateServiceImagesInput = z116.object({
|
|
27427
|
+
brandId: z116.string().uuid().optional().describe("ID de la marca (de create_brand). Recomendado: da nombre, colores, tono y servicios. Nunca un taskId de producto."),
|
|
27428
|
+
instruction: z116.string().trim().max(4e3).optional().describe("Qu\xE9 servicio o promoci\xF3n mostrar, con las palabras del usuario (ej. \xABcorte + barba a $35.000 los martes\xBB). Si el usuario deja que la IA decida, om\xEDtelo y usa delegateToAi=true."),
|
|
27429
|
+
delegateToAi: z116.boolean().optional().describe("true si el usuario prefiere que la IA elija qu\xE9 mostrar a partir de su marca."),
|
|
27430
|
+
format: z116.enum(SERVICE_IMAGE_FORMATS).optional().describe('Formato: "4:5" (feed, por defecto), "9:16" (historias/reels) o "1:1" (cuadrado).'),
|
|
27431
|
+
count: z116.number().int().min(1).max(SERVICE_IMAGE_MAX_COUNT).optional().describe("Cu\xE1ntas im\xE1genes, de 1 a 3 (por defecto 1)."),
|
|
27432
|
+
quality: z116.enum([
|
|
27250
27433
|
"standard",
|
|
27251
27434
|
"high"
|
|
27252
27435
|
]).optional().describe('Calidad: "standard" (por defecto) o "high" (m\xE1s cara; no disponible en 4:5).'),
|
|
27253
|
-
language:
|
|
27436
|
+
language: z116.enum([
|
|
27254
27437
|
"es",
|
|
27255
27438
|
"en",
|
|
27256
27439
|
"pt"
|
|
27257
27440
|
]).optional().describe("Idioma de los textos de la imagen (por defecto es)."),
|
|
27258
|
-
adCopy:
|
|
27259
|
-
confirmed:
|
|
27441
|
+
adCopy: z116.boolean().optional().describe("Opcional. true agrega textos para el anuncio (titular y descripci\xF3n). Por defecto false."),
|
|
27442
|
+
confirmed: z116.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, solo cotiza y no cobra.")
|
|
27260
27443
|
}).strict();
|
|
27261
27444
|
function serviceImageModel(quality) {
|
|
27262
27445
|
return quality === "high" ? AD_CREATIVE_MODELS.PREMIUM : AD_CREATIVE_MODELS.STANDARD;
|
|
@@ -27367,7 +27550,7 @@ function registerServiceImageTools(server, api, options = {}) {
|
|
|
27367
27550
|
nextAction: "Dile al usuario que est\xE1s creando sus im\xE1genes. Llama get_task_status con este taskId (waitSeconds=45) hasta done (trae las im\xE1genes) o error."
|
|
27368
27551
|
});
|
|
27369
27552
|
} catch (error) {
|
|
27370
|
-
if (error instanceof
|
|
27553
|
+
if (error instanceof z116.ZodError) throw invalidInputFromZod(error);
|
|
27371
27554
|
throw translateError(error);
|
|
27372
27555
|
}
|
|
27373
27556
|
});
|
|
@@ -27375,7 +27558,7 @@ function registerServiceImageTools(server, api, options = {}) {
|
|
|
27375
27558
|
__name(registerServiceImageTools, "registerServiceImageTools");
|
|
27376
27559
|
|
|
27377
27560
|
// src/tools/creatives.ts
|
|
27378
|
-
import { z as
|
|
27561
|
+
import { z as z117 } from "zod";
|
|
27379
27562
|
var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
|
|
27380
27563
|
var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
|
|
27381
27564
|
var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
|
|
@@ -27386,72 +27569,72 @@ var CreativeRefs = {
|
|
|
27386
27569
|
images: ImagesInput,
|
|
27387
27570
|
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.'),
|
|
27388
27571
|
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.'),
|
|
27389
|
-
price:
|
|
27390
|
-
offer:
|
|
27391
|
-
compareAtPrice:
|
|
27392
|
-
productContext:
|
|
27393
|
-
productLabel:
|
|
27394
|
-
buyerPersona:
|
|
27395
|
-
isCombo:
|
|
27396
|
-
competitorScanEnabled:
|
|
27397
|
-
brandId:
|
|
27572
|
+
price: z117.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.'),
|
|
27573
|
+
offer: z117.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.'),
|
|
27574
|
+
compareAtPrice: z117.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
|
|
27575
|
+
productContext: z117.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."),
|
|
27576
|
+
productLabel: z117.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.'),
|
|
27577
|
+
buyerPersona: z117.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.'),
|
|
27578
|
+
isCombo: z117.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
|
|
27579
|
+
competitorScanEnabled: z117.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."),
|
|
27580
|
+
brandId: z117.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.")
|
|
27398
27581
|
};
|
|
27399
|
-
var VideoPresenter =
|
|
27400
|
-
|
|
27401
|
-
mode:
|
|
27582
|
+
var VideoPresenter = z117.discriminatedUnion("mode", [
|
|
27583
|
+
z117.object({
|
|
27584
|
+
mode: z117.literal("none")
|
|
27402
27585
|
}).strict(),
|
|
27403
|
-
|
|
27404
|
-
mode:
|
|
27405
|
-
actorId:
|
|
27586
|
+
z117.object({
|
|
27587
|
+
mode: z117.literal("saved_actor"),
|
|
27588
|
+
actorId: z117.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
|
|
27406
27589
|
}).strict(),
|
|
27407
|
-
|
|
27408
|
-
mode:
|
|
27409
|
-
description:
|
|
27590
|
+
z117.object({
|
|
27591
|
+
mode: z117.literal("described"),
|
|
27592
|
+
description: z117.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
|
|
27410
27593
|
}).strict()
|
|
27411
27594
|
]);
|
|
27412
|
-
var VideoCreativeSetup =
|
|
27413
|
-
|
|
27414
|
-
mode:
|
|
27595
|
+
var VideoCreativeSetup = z117.discriminatedUnion("mode", [
|
|
27596
|
+
z117.object({
|
|
27597
|
+
mode: z117.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
|
|
27415
27598
|
}).strict(),
|
|
27416
|
-
|
|
27417
|
-
mode:
|
|
27599
|
+
z117.object({
|
|
27600
|
+
mode: z117.literal("guided"),
|
|
27418
27601
|
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.'),
|
|
27419
|
-
buyerPersona:
|
|
27602
|
+
buyerPersona: z117.string().trim().min(1).max(360),
|
|
27420
27603
|
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.'),
|
|
27421
27604
|
presenter: VideoPresenter,
|
|
27422
|
-
creativeDirection:
|
|
27605
|
+
creativeDirection: z117.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
|
|
27423
27606
|
}).strict()
|
|
27424
27607
|
]);
|
|
27425
|
-
var VideoInput =
|
|
27608
|
+
var VideoInput = z117.object({
|
|
27426
27609
|
images: CreativeRefs.images.optional(),
|
|
27427
27610
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
27428
|
-
title:
|
|
27429
|
-
primaryAngle:
|
|
27611
|
+
title: z117.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
|
|
27612
|
+
primaryAngle: z117.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".'),
|
|
27430
27613
|
language: CreativeRefs.language,
|
|
27431
27614
|
country: CreativeRefs.country,
|
|
27432
|
-
aspectRatio:
|
|
27615
|
+
aspectRatio: z117.enum([
|
|
27433
27616
|
"9:16",
|
|
27434
27617
|
"16:9",
|
|
27435
27618
|
"Auto"
|
|
27436
27619
|
]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
|
|
27437
27620
|
generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, efectos y m\xFAsica sobre cada video entregado (variante with_ai_edit; se cobra al entregar, por video). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro"; false/omitido = sin edici\xF3n.'),
|
|
27438
|
-
durationSeconds:
|
|
27439
|
-
videoAngleCount:
|
|
27621
|
+
durationSeconds: z117.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."),
|
|
27622
|
+
videoAngleCount: z117.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."),
|
|
27440
27623
|
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.'),
|
|
27441
27624
|
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."),
|
|
27442
27625
|
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.'),
|
|
27443
27626
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
|
|
27444
27627
|
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.'),
|
|
27445
|
-
features:
|
|
27628
|
+
features: z117.array(z117.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
|
|
27446
27629
|
price: CreativeRefs.price,
|
|
27447
27630
|
offer: CreativeRefs.offer,
|
|
27448
27631
|
productContext: CreativeRefs.productContext,
|
|
27449
27632
|
productLabel: CreativeRefs.productLabel,
|
|
27450
|
-
cta:
|
|
27451
|
-
scriptNotes:
|
|
27633
|
+
cta: z117.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.'),
|
|
27634
|
+
scriptNotes: z117.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.'),
|
|
27452
27635
|
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.'),
|
|
27453
27636
|
competitorScanEnabled: CreativeRefs.competitorScanEnabled,
|
|
27454
|
-
replicateWinnerWhenFound:
|
|
27637
|
+
replicateWinnerWhenFound: z117.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."),
|
|
27455
27638
|
brandId: CreativeRefs.brandId
|
|
27456
27639
|
}).strict();
|
|
27457
27640
|
var FreeVideoQualityEnum = VideoQualityEnum;
|
|
@@ -27469,7 +27652,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
|
|
|
27469
27652
|
length: 29
|
|
27470
27653
|
}, (_, index) => index + 2)
|
|
27471
27654
|
};
|
|
27472
|
-
var FreeVideoModelIdEnum =
|
|
27655
|
+
var FreeVideoModelIdEnum = z117.enum([
|
|
27473
27656
|
"grok-imagine-video-1-5-preview",
|
|
27474
27657
|
"minimax-h3/reference-to-video",
|
|
27475
27658
|
"wan/3-0-video",
|
|
@@ -27480,66 +27663,66 @@ var FREE_SELECTABLE_MODEL_IDS = [
|
|
|
27480
27663
|
"minimax-h3/reference-to-video",
|
|
27481
27664
|
"wan/3-0-video"
|
|
27482
27665
|
];
|
|
27483
|
-
var FreeVideoInput =
|
|
27666
|
+
var FreeVideoInput = z117.object({
|
|
27484
27667
|
images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
|
|
27485
|
-
rawPrompt:
|
|
27668
|
+
rawPrompt: z117.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."),
|
|
27486
27669
|
language: CreativeRefs.language,
|
|
27487
27670
|
quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
|
|
27488
27671
|
// Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
|
|
27489
27672
|
// parsed ONLY so the handler can reject it with a message naming its
|
|
27490
27673
|
// replacement — dropping it silently would turn a caller's explicit
|
|
27491
27674
|
// Pro++ pick into a quiet fallback to Wan.
|
|
27492
|
-
freeProModel:
|
|
27675
|
+
freeProModel: z117.enum([
|
|
27493
27676
|
"wan",
|
|
27494
27677
|
"seedance"
|
|
27495
27678
|
]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
|
|
27496
27679
|
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.'),
|
|
27497
|
-
durationSeconds:
|
|
27680
|
+
durationSeconds: z117.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."),
|
|
27498
27681
|
videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
|
|
27499
|
-
generateAiMusic:
|
|
27682
|
+
generateAiMusic: z117.boolean().default(false).describe('Opcional. Agrega m\xFAsica instrumental IA debajo del audio nativo. Default false. Equivale a generateAiEdit (nivel "pro"): la Edici\xF3n con IA trae su propia m\xFAsica.'),
|
|
27500
27683
|
generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, gr\xE1ficos y m\xFAsica sobre el video ya entregado (variante with_ai_edit; se cobra al entregar). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro". Default sin edici\xF3n.'),
|
|
27501
|
-
addSubtitles:
|
|
27502
|
-
idempotencyKey:
|
|
27684
|
+
addSubtitles: z117.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
|
|
27685
|
+
idempotencyKey: z117.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.")
|
|
27503
27686
|
}).strict();
|
|
27504
27687
|
var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
|
|
27505
|
-
var ImageCreativeSetup =
|
|
27506
|
-
|
|
27507
|
-
mode:
|
|
27688
|
+
var ImageCreativeSetup = z117.discriminatedUnion("mode", [
|
|
27689
|
+
z117.object({
|
|
27690
|
+
mode: z117.literal("automatic")
|
|
27508
27691
|
}).strict(),
|
|
27509
|
-
|
|
27510
|
-
mode:
|
|
27511
|
-
creativeArchetype:
|
|
27692
|
+
z117.object({
|
|
27693
|
+
mode: z117.literal("guided"),
|
|
27694
|
+
creativeArchetype: z117.union([
|
|
27512
27695
|
ImageCreativeArchetypeEnum,
|
|
27513
|
-
|
|
27696
|
+
z117.literal("ai_decides")
|
|
27514
27697
|
]),
|
|
27515
|
-
visualTreatment:
|
|
27698
|
+
visualTreatment: z117.union([
|
|
27516
27699
|
ImageCreativeVisualTreatmentEnum,
|
|
27517
|
-
|
|
27700
|
+
z117.literal("ai_decides")
|
|
27518
27701
|
]),
|
|
27519
27702
|
aspectRatio: ImageCreativeAspectRatioEnum,
|
|
27520
|
-
nVariants:
|
|
27521
|
-
|
|
27522
|
-
|
|
27523
|
-
|
|
27524
|
-
|
|
27525
|
-
|
|
27703
|
+
nVariants: z117.union([
|
|
27704
|
+
z117.literal(1),
|
|
27705
|
+
z117.literal(2),
|
|
27706
|
+
z117.literal(3),
|
|
27707
|
+
z117.literal(4),
|
|
27708
|
+
z117.literal(6)
|
|
27526
27709
|
]),
|
|
27527
|
-
imageModel:
|
|
27528
|
-
styleMix:
|
|
27529
|
-
generateAdCopy:
|
|
27530
|
-
competitorScanEnabled:
|
|
27531
|
-
productContext:
|
|
27532
|
-
creativeDirection:
|
|
27533
|
-
brandColors:
|
|
27534
|
-
headline:
|
|
27535
|
-
subheadline:
|
|
27710
|
+
imageModel: z117.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.'),
|
|
27711
|
+
styleMix: z117.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
|
|
27712
|
+
generateAdCopy: z117.boolean(),
|
|
27713
|
+
competitorScanEnabled: z117.boolean(),
|
|
27714
|
+
productContext: z117.string().trim().min(1).max(3e3).nullable(),
|
|
27715
|
+
creativeDirection: z117.string().trim().min(1).max(500).nullable(),
|
|
27716
|
+
brandColors: z117.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.'),
|
|
27717
|
+
headline: z117.string().trim().min(1).max(120).nullable(),
|
|
27718
|
+
subheadline: z117.string().trim().min(1).max(160).nullable()
|
|
27536
27719
|
}).strict()
|
|
27537
27720
|
]).superRefine((setup, context) => {
|
|
27538
27721
|
if (setup.mode !== "guided") return;
|
|
27539
27722
|
const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
|
|
27540
27723
|
if (needsStyleMix && setup.styleMix === null) {
|
|
27541
27724
|
context.addIssue({
|
|
27542
|
-
code:
|
|
27725
|
+
code: z117.ZodIssueCode.custom,
|
|
27543
27726
|
path: [
|
|
27544
27727
|
"styleMix"
|
|
27545
27728
|
],
|
|
@@ -27548,7 +27731,7 @@ var ImageCreativeSetup = z116.discriminatedUnion("mode", [
|
|
|
27548
27731
|
}
|
|
27549
27732
|
if (!needsStyleMix && setup.styleMix !== null) {
|
|
27550
27733
|
context.addIssue({
|
|
27551
|
-
code:
|
|
27734
|
+
code: z117.ZodIssueCode.custom,
|
|
27552
27735
|
path: [
|
|
27553
27736
|
"styleMix"
|
|
27554
27737
|
],
|
|
@@ -27557,7 +27740,7 @@ var ImageCreativeSetup = z116.discriminatedUnion("mode", [
|
|
|
27557
27740
|
}
|
|
27558
27741
|
if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
|
|
27559
27742
|
context.addIssue({
|
|
27560
|
-
code:
|
|
27743
|
+
code: z117.ZodIssueCode.custom,
|
|
27561
27744
|
path: [
|
|
27562
27745
|
"aspectRatio"
|
|
27563
27746
|
],
|
|
@@ -27565,55 +27748,55 @@ var ImageCreativeSetup = z116.discriminatedUnion("mode", [
|
|
|
27565
27748
|
});
|
|
27566
27749
|
}
|
|
27567
27750
|
});
|
|
27568
|
-
var LandingCreativeSetup =
|
|
27569
|
-
|
|
27570
|
-
mode:
|
|
27751
|
+
var LandingCreativeSetup = z117.discriminatedUnion("mode", [
|
|
27752
|
+
z117.object({
|
|
27753
|
+
mode: z117.literal("automatic")
|
|
27571
27754
|
}).strict(),
|
|
27572
|
-
|
|
27573
|
-
mode:
|
|
27755
|
+
z117.object({
|
|
27756
|
+
mode: z117.literal("guided"),
|
|
27574
27757
|
landingStrategy: LandingStrategyEnum,
|
|
27575
27758
|
landingImageFormat: LandingImageFormatEnum,
|
|
27576
|
-
competitorScanEnabled:
|
|
27577
|
-
paymentMethods:
|
|
27578
|
-
productContext:
|
|
27579
|
-
creativeDirection:
|
|
27580
|
-
headline:
|
|
27581
|
-
subheadline:
|
|
27759
|
+
competitorScanEnabled: z117.boolean(),
|
|
27760
|
+
paymentMethods: z117.string().trim().min(1).max(240).nullable(),
|
|
27761
|
+
productContext: z117.string().trim().min(1).max(3e3).nullable(),
|
|
27762
|
+
creativeDirection: z117.string().trim().min(1).max(500).nullable(),
|
|
27763
|
+
headline: z117.string().trim().min(1).max(120).nullable(),
|
|
27764
|
+
subheadline: z117.string().trim().min(1).max(160).nullable()
|
|
27582
27765
|
}).strict()
|
|
27583
27766
|
]);
|
|
27584
|
-
var ImageInput =
|
|
27767
|
+
var ImageInput = z117.object({
|
|
27585
27768
|
images: CreativeRefs.images.optional(),
|
|
27586
27769
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
27587
|
-
productTitle:
|
|
27588
|
-
primaryAngle:
|
|
27770
|
+
productTitle: z117.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
|
|
27771
|
+
primaryAngle: z117.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.'),
|
|
27589
27772
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
27590
27773
|
language: CreativeRefs.language,
|
|
27591
27774
|
country: CreativeRefs.country,
|
|
27592
27775
|
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."),
|
|
27593
27776
|
imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
|
|
27594
|
-
features:
|
|
27777
|
+
features: z117.array(z117.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
|
|
27595
27778
|
price: CreativeRefs.price,
|
|
27596
|
-
omitPrice:
|
|
27779
|
+
omitPrice: z117.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."),
|
|
27597
27780
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
27598
27781
|
offer: CreativeRefs.offer,
|
|
27599
27782
|
productLabel: CreativeRefs.productLabel,
|
|
27600
27783
|
isCombo: CreativeRefs.isCombo,
|
|
27601
27784
|
brandId: CreativeRefs.brandId
|
|
27602
27785
|
});
|
|
27603
|
-
var EditImageCreativeInput =
|
|
27604
|
-
taskId:
|
|
27605
|
-
variantIndex:
|
|
27606
|
-
clientRequestId:
|
|
27607
|
-
instruction:
|
|
27786
|
+
var EditImageCreativeInput = z117.object({
|
|
27787
|
+
taskId: z117.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
|
|
27788
|
+
variantIndex: z117.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
|
|
27789
|
+
clientRequestId: z117.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."),
|
|
27790
|
+
instruction: z117.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".')
|
|
27608
27791
|
});
|
|
27609
|
-
var LandingInput =
|
|
27610
|
-
includeInitialLandingGif:
|
|
27792
|
+
var LandingInput = z117.object({
|
|
27793
|
+
includeInitialLandingGif: z117.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
|
|
27611
27794
|
images: CreativeRefs.images.optional(),
|
|
27612
27795
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
27613
27796
|
language: CreativeRefs.language,
|
|
27614
27797
|
country: CreativeRefs.country,
|
|
27615
27798
|
creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
|
|
27616
|
-
salesAngle:
|
|
27799
|
+
salesAngle: z117.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.'),
|
|
27617
27800
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
27618
27801
|
price: CreativeRefs.price,
|
|
27619
27802
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
@@ -27895,8 +28078,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
27895
28078
|
server.registerTool("get_image_edit_status", {
|
|
27896
28079
|
description: imageEditStatusGuidance.summary,
|
|
27897
28080
|
inputSchema: {
|
|
27898
|
-
taskId:
|
|
27899
|
-
operationId:
|
|
28081
|
+
taskId: z117.string().uuid(),
|
|
28082
|
+
operationId: z117.string().uuid()
|
|
27900
28083
|
},
|
|
27901
28084
|
annotations: READS_INTERNAL
|
|
27902
28085
|
}, async (input) => {
|
|
@@ -27953,10 +28136,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
27953
28136
|
__name(registerCreativeTools, "registerCreativeTools");
|
|
27954
28137
|
|
|
27955
28138
|
// src/tools/creative-variants.ts
|
|
27956
|
-
import { z as
|
|
28139
|
+
import { z as z118 } from "zod";
|
|
27957
28140
|
var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
|
|
27958
28141
|
var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
|
|
27959
|
-
var LandingSectionKeyEnum =
|
|
28142
|
+
var LandingSectionKeyEnum = z118.enum([
|
|
27960
28143
|
"problem_hook",
|
|
27961
28144
|
"problem_cost",
|
|
27962
28145
|
"solution_mechanism",
|
|
@@ -27996,24 +28179,24 @@ var LandingSectionKeyEnum = z117.enum([
|
|
|
27996
28179
|
"lifestyle_fit",
|
|
27997
28180
|
"join_lifestyle"
|
|
27998
28181
|
]);
|
|
27999
|
-
var CreativeVariantKindEnum =
|
|
28182
|
+
var CreativeVariantKindEnum = z118.enum([
|
|
28000
28183
|
"video",
|
|
28001
28184
|
"image",
|
|
28002
28185
|
"landing"
|
|
28003
28186
|
]);
|
|
28004
|
-
var EstimateCreativeVariantInputBase =
|
|
28005
|
-
sourceTaskId:
|
|
28187
|
+
var EstimateCreativeVariantInputBase = z118.object({
|
|
28188
|
+
sourceTaskId: z118.string().uuid().describe("ID de la tarea original completada."),
|
|
28006
28189
|
kind: CreativeVariantKindEnum,
|
|
28007
28190
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
|
|
28008
28191
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
|
|
28009
|
-
nVariants:
|
|
28192
|
+
nVariants: z118.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
28010
28193
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
|
|
28011
|
-
instructions:
|
|
28194
|
+
instructions: z118.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.")
|
|
28012
28195
|
}).strict();
|
|
28013
28196
|
var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
28014
28197
|
if (input.kind === "video" && input.nVariants !== void 0) {
|
|
28015
28198
|
ctx.addIssue({
|
|
28016
|
-
code:
|
|
28199
|
+
code: z118.ZodIssueCode.custom,
|
|
28017
28200
|
path: [
|
|
28018
28201
|
"nVariants"
|
|
28019
28202
|
],
|
|
@@ -28023,7 +28206,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28023
28206
|
if (input.kind !== "video") {
|
|
28024
28207
|
if (input.videoPreset !== void 0) {
|
|
28025
28208
|
ctx.addIssue({
|
|
28026
|
-
code:
|
|
28209
|
+
code: z118.ZodIssueCode.custom,
|
|
28027
28210
|
path: [
|
|
28028
28211
|
"videoPreset"
|
|
28029
28212
|
],
|
|
@@ -28032,7 +28215,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28032
28215
|
}
|
|
28033
28216
|
if (input.videoResolution !== void 0) {
|
|
28034
28217
|
ctx.addIssue({
|
|
28035
|
-
code:
|
|
28218
|
+
code: z118.ZodIssueCode.custom,
|
|
28036
28219
|
path: [
|
|
28037
28220
|
"videoResolution"
|
|
28038
28221
|
],
|
|
@@ -28042,7 +28225,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28042
28225
|
}
|
|
28043
28226
|
if (input.kind !== "image" && input.nVariants !== void 0) {
|
|
28044
28227
|
ctx.addIssue({
|
|
28045
|
-
code:
|
|
28228
|
+
code: z118.ZodIssueCode.custom,
|
|
28046
28229
|
path: [
|
|
28047
28230
|
"nVariants"
|
|
28048
28231
|
],
|
|
@@ -28052,7 +28235,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28052
28235
|
if (input.kind !== "landing") {
|
|
28053
28236
|
if (input.sectionKey !== void 0) {
|
|
28054
28237
|
ctx.addIssue({
|
|
28055
|
-
code:
|
|
28238
|
+
code: z118.ZodIssueCode.custom,
|
|
28056
28239
|
path: [
|
|
28057
28240
|
"sectionKey"
|
|
28058
28241
|
],
|
|
@@ -28061,7 +28244,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28061
28244
|
}
|
|
28062
28245
|
if (input.instructions !== void 0) {
|
|
28063
28246
|
ctx.addIssue({
|
|
28064
|
-
code:
|
|
28247
|
+
code: z118.ZodIssueCode.custom,
|
|
28065
28248
|
path: [
|
|
28066
28249
|
"instructions"
|
|
28067
28250
|
],
|
|
@@ -28070,31 +28253,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28070
28253
|
}
|
|
28071
28254
|
}
|
|
28072
28255
|
});
|
|
28073
|
-
var CreateCreativeVariantInputBase =
|
|
28074
|
-
sourceTaskId:
|
|
28256
|
+
var CreateCreativeVariantInputBase = z118.object({
|
|
28257
|
+
sourceTaskId: z118.string().uuid().describe("ID de la tarea original completada."),
|
|
28075
28258
|
kind: CreativeVariantKindEnum,
|
|
28076
|
-
confirm:
|
|
28077
|
-
clientRequestId:
|
|
28078
|
-
angle:
|
|
28079
|
-
buyerPersona:
|
|
28080
|
-
scriptNotes:
|
|
28081
|
-
creativeDirection:
|
|
28259
|
+
confirm: z118.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
|
|
28260
|
+
clientRequestId: z118.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."),
|
|
28261
|
+
angle: z118.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
|
|
28262
|
+
buyerPersona: z118.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
|
|
28263
|
+
scriptNotes: z118.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
|
|
28264
|
+
creativeDirection: z118.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
|
|
28082
28265
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
|
|
28083
28266
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
|
|
28084
|
-
generateAiMusic:
|
|
28085
|
-
nVariants:
|
|
28267
|
+
generateAiMusic: z118.boolean().optional().describe("Opcional para video."),
|
|
28268
|
+
nVariants: z118.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
28086
28269
|
imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
|
|
28087
28270
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
|
|
28088
28271
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
|
|
28089
28272
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
|
|
28090
|
-
styleMix:
|
|
28273
|
+
styleMix: z118.boolean().optional().describe("Opcional para imagen."),
|
|
28091
28274
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
|
|
28092
|
-
instructions:
|
|
28275
|
+
instructions: z118.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.")
|
|
28093
28276
|
}).strict();
|
|
28094
28277
|
var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
28095
28278
|
if ((input.kind === "video" || input.kind === "image") && !input.angle) {
|
|
28096
28279
|
ctx.addIssue({
|
|
28097
|
-
code:
|
|
28280
|
+
code: z118.ZodIssueCode.custom,
|
|
28098
28281
|
path: [
|
|
28099
28282
|
"angle"
|
|
28100
28283
|
],
|
|
@@ -28103,7 +28286,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
28103
28286
|
}
|
|
28104
28287
|
if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
|
|
28105
28288
|
ctx.addIssue({
|
|
28106
|
-
code:
|
|
28289
|
+
code: z118.ZodIssueCode.custom,
|
|
28107
28290
|
path: [
|
|
28108
28291
|
"instructions"
|
|
28109
28292
|
],
|
|
@@ -28149,7 +28332,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
28149
28332
|
for (const field of fieldsByKind[input.kind]) {
|
|
28150
28333
|
if (input[field] !== void 0) {
|
|
28151
28334
|
ctx.addIssue({
|
|
28152
|
-
code:
|
|
28335
|
+
code: z118.ZodIssueCode.custom,
|
|
28153
28336
|
path: [
|
|
28154
28337
|
field
|
|
28155
28338
|
],
|
|
@@ -28282,13 +28465,13 @@ function registerCreativeVariantTools(server, api) {
|
|
|
28282
28465
|
__name(registerCreativeVariantTools, "registerCreativeVariantTools");
|
|
28283
28466
|
|
|
28284
28467
|
// src/tools/script-review.ts
|
|
28285
|
-
import { z as
|
|
28468
|
+
import { z as z119 } from "zod";
|
|
28286
28469
|
var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
|
|
28287
28470
|
var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
|
|
28288
28471
|
var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
|
|
28289
|
-
var GetVideoScriptInput =
|
|
28290
|
-
taskId:
|
|
28291
|
-
angleKey:
|
|
28472
|
+
var GetVideoScriptInput = z119.object({
|
|
28473
|
+
taskId: z119.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
|
|
28474
|
+
angleKey: z119.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.')
|
|
28292
28475
|
}).strict();
|
|
28293
28476
|
var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
|
|
28294
28477
|
var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
|
|
@@ -28371,7 +28554,7 @@ function registerScriptReviewTools(server, api) {
|
|
|
28371
28554
|
__name(registerScriptReviewTools, "registerScriptReviewTools");
|
|
28372
28555
|
|
|
28373
28556
|
// src/tools/connections.ts
|
|
28374
|
-
import { z as
|
|
28557
|
+
import { z as z120 } from "zod";
|
|
28375
28558
|
var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
|
|
28376
28559
|
var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
|
|
28377
28560
|
var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
|
|
@@ -28380,7 +28563,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
|
|
|
28380
28563
|
function registerConnectionTools(server, api) {
|
|
28381
28564
|
server.registerTool("list_shopify_shops", {
|
|
28382
28565
|
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.",
|
|
28383
|
-
inputSchema:
|
|
28566
|
+
inputSchema: z120.object({}).shape,
|
|
28384
28567
|
annotations: READS_INTERNAL
|
|
28385
28568
|
}, async () => {
|
|
28386
28569
|
try {
|
|
@@ -28392,10 +28575,10 @@ function registerConnectionTools(server, api) {
|
|
|
28392
28575
|
});
|
|
28393
28576
|
server.registerTool("list_shopify_products", {
|
|
28394
28577
|
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.',
|
|
28395
|
-
inputSchema:
|
|
28396
|
-
shopDomain:
|
|
28397
|
-
query:
|
|
28398
|
-
taskId:
|
|
28578
|
+
inputSchema: z120.object({
|
|
28579
|
+
shopDomain: z120.string().min(3).max(120),
|
|
28580
|
+
query: z120.string().trim().max(120).optional(),
|
|
28581
|
+
taskId: z120.string().uuid().optional()
|
|
28399
28582
|
}).shape,
|
|
28400
28583
|
annotations: READS_EXTERNAL
|
|
28401
28584
|
}, async ({ shopDomain, query, taskId }) => {
|
|
@@ -28413,7 +28596,7 @@ function registerConnectionTools(server, api) {
|
|
|
28413
28596
|
});
|
|
28414
28597
|
server.registerTool("list_meta_ad_accounts", {
|
|
28415
28598
|
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.",
|
|
28416
|
-
inputSchema:
|
|
28599
|
+
inputSchema: z120.object({}).shape,
|
|
28417
28600
|
annotations: READS_EXTERNAL
|
|
28418
28601
|
}, async () => {
|
|
28419
28602
|
try {
|
|
@@ -28425,7 +28608,7 @@ function registerConnectionTools(server, api) {
|
|
|
28425
28608
|
});
|
|
28426
28609
|
server.registerTool("list_meta_destinations", {
|
|
28427
28610
|
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.",
|
|
28428
|
-
inputSchema:
|
|
28611
|
+
inputSchema: z120.object({}).shape,
|
|
28429
28612
|
annotations: READS_EXTERNAL,
|
|
28430
28613
|
_meta: {
|
|
28431
28614
|
"openai/widgetAccessible": true
|
|
@@ -28440,7 +28623,7 @@ function registerConnectionTools(server, api) {
|
|
|
28440
28623
|
});
|
|
28441
28624
|
server.registerTool("list_tiktok_advertisers", {
|
|
28442
28625
|
description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
|
|
28443
|
-
inputSchema:
|
|
28626
|
+
inputSchema: z120.object({}).shape,
|
|
28444
28627
|
annotations: READS_EXTERNAL
|
|
28445
28628
|
}, async () => {
|
|
28446
28629
|
try {
|
|
@@ -28454,7 +28637,7 @@ function registerConnectionTools(server, api) {
|
|
|
28454
28637
|
__name(registerConnectionTools, "registerConnectionTools");
|
|
28455
28638
|
|
|
28456
28639
|
// src/tools/actors.ts
|
|
28457
|
-
import { z as
|
|
28640
|
+
import { z as z121 } from "zod";
|
|
28458
28641
|
var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
|
|
28459
28642
|
var actorVoiceGuidance = {
|
|
28460
28643
|
capabilities: getProductMakerCapabilityModelGuidance("get_actor_voice_capabilities"),
|
|
@@ -28494,7 +28677,7 @@ function sanitizeVoiceResult(value) {
|
|
|
28494
28677
|
__name(sanitizeVoiceResult, "sanitizeVoiceResult");
|
|
28495
28678
|
function registerActorTools(server, api) {
|
|
28496
28679
|
const actor = {
|
|
28497
|
-
actorId:
|
|
28680
|
+
actorId: z121.string().min(1).max(64)
|
|
28498
28681
|
};
|
|
28499
28682
|
const safe = /* @__PURE__ */ __name(async (request) => {
|
|
28500
28683
|
try {
|
|
@@ -28523,8 +28706,8 @@ function registerActorTools(server, api) {
|
|
|
28523
28706
|
inputSchema: {
|
|
28524
28707
|
...actor,
|
|
28525
28708
|
draft: ActorVoiceDraftSchema,
|
|
28526
|
-
requestKey:
|
|
28527
|
-
acceptedQuoteId:
|
|
28709
|
+
requestKey: z121.string().trim().min(1).max(128),
|
|
28710
|
+
acceptedQuoteId: z121.string().trim().min(1).max(128)
|
|
28528
28711
|
},
|
|
28529
28712
|
annotations: CREATES_PAID
|
|
28530
28713
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews`, body)));
|
|
@@ -28532,7 +28715,7 @@ function registerActorTools(server, api) {
|
|
|
28532
28715
|
description: actorVoiceGuidance.get.summary,
|
|
28533
28716
|
inputSchema: {
|
|
28534
28717
|
...actor,
|
|
28535
|
-
candidateId:
|
|
28718
|
+
candidateId: z121.string().min(1).max(64)
|
|
28536
28719
|
},
|
|
28537
28720
|
// Polling can resume the first paid submission of an accepted quote.
|
|
28538
28721
|
// The immutable candidate/operation key keeps recovery idempotent.
|
|
@@ -28545,16 +28728,16 @@ function registerActorTools(server, api) {
|
|
|
28545
28728
|
description: actorVoiceGuidance.approve.summary,
|
|
28546
28729
|
inputSchema: {
|
|
28547
28730
|
...actor,
|
|
28548
|
-
candidateId:
|
|
28549
|
-
expectedRevision:
|
|
28550
|
-
expectedApprovedRevision:
|
|
28731
|
+
candidateId: z121.string().min(1).max(64),
|
|
28732
|
+
expectedRevision: z121.number().int().positive(),
|
|
28733
|
+
expectedApprovedRevision: z121.number().int().positive().nullable().optional()
|
|
28551
28734
|
},
|
|
28552
28735
|
// Replaces the selected voice and withdraws the old catalog grants.
|
|
28553
28736
|
annotations: OVERWRITES_INTERNAL
|
|
28554
28737
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/approve`, body)));
|
|
28555
28738
|
server.registerTool("list_actors", {
|
|
28556
28739
|
description: listActorsGuidance.summary + " Devuelve id, nombre, descripci\xF3n, g\xE9nero y voz privada del personaje. Cuando el personaje tiene una voz personalizada, `voice.identityId` y `voice.revision` identifican la versi\xF3n aprobada \u2014 conserva la revisi\xF3n al llamar `approve_actor_voice` (expectedApprovedRevision) para reemplazarla. Los IDs de proveedor nunca se exponen por MCP. Usa el `id` como `actorId` al crear o editar una tarea. Solo aparecen los personajes listos para usar; si la lista est\xE1 vac\xEDa, dile al usuario que cree uno en productmaker.app antes de intentar asignarlo. No modifica nada.",
|
|
28557
|
-
inputSchema:
|
|
28740
|
+
inputSchema: z121.object({}).shape,
|
|
28558
28741
|
annotations: READS_INTERNAL
|
|
28559
28742
|
}, async () => {
|
|
28560
28743
|
try {
|
|
@@ -28587,7 +28770,7 @@ function registerActorTools(server, api) {
|
|
|
28587
28770
|
__name(registerActorTools, "registerActorTools");
|
|
28588
28771
|
|
|
28589
28772
|
// src/tools/publish.ts
|
|
28590
|
-
import { z as
|
|
28773
|
+
import { z as z122 } from "zod";
|
|
28591
28774
|
|
|
28592
28775
|
// src/tools/meta-publish-attempt-id.ts
|
|
28593
28776
|
var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
|
|
@@ -28626,40 +28809,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
|
|
|
28626
28809
|
var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
|
|
28627
28810
|
var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
|
|
28628
28811
|
var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
|
|
28629
|
-
var ShopifyInput =
|
|
28630
|
-
taskId:
|
|
28631
|
-
shopDomain:
|
|
28812
|
+
var ShopifyInput = z122.object({
|
|
28813
|
+
taskId: z122.string().min(1),
|
|
28814
|
+
shopDomain: z122.string().min(1),
|
|
28632
28815
|
/** Override: number of landing images to include. Default = ALL images the
|
|
28633
28816
|
* task generated (the MCP fetches /v1/results first to count). Bounded
|
|
28634
28817
|
* generously here; the backend validates each index against
|
|
28635
28818
|
* landing.images.length and rejects out-of-range. */
|
|
28636
|
-
numLandingImages:
|
|
28637
|
-
variantIndex:
|
|
28819
|
+
numLandingImages: z122.number().int().min(1).max(20).optional(),
|
|
28820
|
+
variantIndex: z122.number().int().min(0).optional(),
|
|
28638
28821
|
/** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
|
|
28639
28822
|
* When true, the landing renders variant-picker pills; when false, it ships
|
|
28640
28823
|
* a single-option product page. Defaults to false. */
|
|
28641
|
-
showVariantPicker:
|
|
28824
|
+
showVariantPicker: z122.boolean().optional(),
|
|
28642
28825
|
/** Default `auto` updates the product previously published for this task and
|
|
28643
28826
|
* shop. Use `existing` with targetProductId to choose another product, or
|
|
28644
28827
|
* `new` only when the user explicitly wants a duplicate/new listing. */
|
|
28645
|
-
publicationMode:
|
|
28828
|
+
publicationMode: z122.enum([
|
|
28646
28829
|
"auto",
|
|
28647
28830
|
"existing",
|
|
28648
28831
|
"new"
|
|
28649
28832
|
]).optional(),
|
|
28650
28833
|
/** Shopify product GID, numeric id, or admin product URL. Required when
|
|
28651
28834
|
* publicationMode is `existing`. */
|
|
28652
|
-
targetProductId:
|
|
28835
|
+
targetProductId: z122.string().trim().min(1).max(300).optional(),
|
|
28653
28836
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
28654
|
-
announcementBarEnabled:
|
|
28655
|
-
announcementBarText:
|
|
28837
|
+
announcementBarEnabled: z122.boolean().optional(),
|
|
28838
|
+
announcementBarText: z122.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
|
|
28656
28839
|
commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
|
|
28657
|
-
confirmed:
|
|
28840
|
+
confirmed: z122.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
|
|
28658
28841
|
});
|
|
28659
28842
|
var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
|
|
28660
28843
|
if (value.commerceCorrection && value.confirmed !== true) {
|
|
28661
28844
|
ctx.addIssue({
|
|
28662
|
-
code:
|
|
28845
|
+
code: z122.ZodIssueCode.custom,
|
|
28663
28846
|
path: [
|
|
28664
28847
|
"confirmed"
|
|
28665
28848
|
],
|
|
@@ -28668,7 +28851,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
28668
28851
|
}
|
|
28669
28852
|
if (value.announcementBarEnabled && !value.announcementBarText) {
|
|
28670
28853
|
ctx.addIssue({
|
|
28671
|
-
code:
|
|
28854
|
+
code: z122.ZodIssueCode.custom,
|
|
28672
28855
|
path: [
|
|
28673
28856
|
"announcementBarText"
|
|
28674
28857
|
],
|
|
@@ -28677,7 +28860,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
28677
28860
|
}
|
|
28678
28861
|
if (!value.announcementBarEnabled && value.announcementBarText) {
|
|
28679
28862
|
ctx.addIssue({
|
|
28680
|
-
code:
|
|
28863
|
+
code: z122.ZodIssueCode.custom,
|
|
28681
28864
|
path: [
|
|
28682
28865
|
"announcementBarText"
|
|
28683
28866
|
],
|
|
@@ -28691,91 +28874,91 @@ function parseShopifyInput(rawInput) {
|
|
|
28691
28874
|
return parsed.data;
|
|
28692
28875
|
}
|
|
28693
28876
|
__name(parseShopifyInput, "parseShopifyInput");
|
|
28694
|
-
var McpCampaignConfig =
|
|
28877
|
+
var McpCampaignConfig = z122.object({
|
|
28695
28878
|
/** ALWAYS in US dollars, whatever the ad account's currency is. ProductMaker
|
|
28696
28879
|
* converts to the account currency server-side. Do NOT pre-convert: on a COP
|
|
28697
28880
|
* account the user's "60.000 al día" is `dailyBudgetUsd: 15`, not 60000. */
|
|
28698
|
-
dailyBudgetUsd:
|
|
28881
|
+
dailyBudgetUsd: z122.number().positive().optional(),
|
|
28699
28882
|
/** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
|
|
28700
28883
|
* normalizes at validation). Meta accepts max 1 (single-country ad set).
|
|
28701
28884
|
* TikTok takes only the first entry. */
|
|
28702
|
-
targetCountries:
|
|
28703
|
-
campaignName:
|
|
28885
|
+
targetCountries: z122.array(CountryIso2Schema).max(1).optional(),
|
|
28886
|
+
campaignName: z122.string().trim().min(1).max(100).optional()
|
|
28704
28887
|
});
|
|
28705
28888
|
var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
|
|
28706
|
-
var MetaInput =
|
|
28707
|
-
taskId:
|
|
28889
|
+
var MetaInput = z122.object({
|
|
28890
|
+
taskId: z122.string().min(1),
|
|
28708
28891
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
28709
|
-
portfolioId:
|
|
28892
|
+
portfolioId: z122.string().trim().min(1),
|
|
28710
28893
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
28711
|
-
pageId:
|
|
28894
|
+
pageId: z122.string().trim().min(1),
|
|
28712
28895
|
adAccountId: McpAdAccountId,
|
|
28713
|
-
pixelId:
|
|
28714
|
-
landingUrl:
|
|
28896
|
+
pixelId: z122.string().min(1).optional(),
|
|
28897
|
+
landingUrl: z122.string().url().optional(),
|
|
28715
28898
|
/** Select which angles to publish by 0-based index. Omit to publish all
|
|
28716
28899
|
* successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
|
|
28717
|
-
angleIndexes:
|
|
28900
|
+
angleIndexes: z122.array(z122.number().int().nonnegative()).optional(),
|
|
28718
28901
|
campaignConfig: McpCampaignConfig.optional(),
|
|
28719
28902
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
28720
28903
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
28721
28904
|
* (Meta's primary-text limit). */
|
|
28722
|
-
primaryText:
|
|
28905
|
+
primaryText: z122.string().trim().min(1).max(500).optional(),
|
|
28723
28906
|
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
28724
28907
|
* (wa.me) instead of a landing page. */
|
|
28725
|
-
phoneNumber:
|
|
28908
|
+
phoneNumber: z122.string().min(8).max(32).optional()
|
|
28726
28909
|
});
|
|
28727
|
-
var GroupedTaskSource =
|
|
28728
|
-
type:
|
|
28729
|
-
taskId:
|
|
28730
|
-
angleIndex:
|
|
28731
|
-
videoVariant:
|
|
28910
|
+
var GroupedTaskSource = z122.object({
|
|
28911
|
+
type: z122.literal("task"),
|
|
28912
|
+
taskId: z122.string().min(1),
|
|
28913
|
+
angleIndex: z122.number().int().min(0).optional(),
|
|
28914
|
+
videoVariant: z122.enum([
|
|
28732
28915
|
"with_subtitles",
|
|
28733
28916
|
"without_subtitles"
|
|
28734
28917
|
]).optional(),
|
|
28735
|
-
imageVariantIndex:
|
|
28736
|
-
});
|
|
28737
|
-
var GroupedMediaSource =
|
|
28738
|
-
type:
|
|
28739
|
-
url:
|
|
28740
|
-
path:
|
|
28741
|
-
thumbnailUrl:
|
|
28742
|
-
thumbnailPath:
|
|
28918
|
+
imageVariantIndex: z122.number().int().min(0).optional()
|
|
28919
|
+
});
|
|
28920
|
+
var GroupedMediaSource = z122.object({
|
|
28921
|
+
type: z122.literal("media"),
|
|
28922
|
+
url: z122.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
|
|
28923
|
+
path: z122.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".'),
|
|
28924
|
+
thumbnailUrl: z122.string().url().optional(),
|
|
28925
|
+
thumbnailPath: z122.string().min(1).optional()
|
|
28743
28926
|
}).refine((value) => Boolean(value.url) !== Boolean(value.path), {
|
|
28744
28927
|
message: "media source needs exactly one of `url` or `path`"
|
|
28745
28928
|
}).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
|
|
28746
28929
|
message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
|
|
28747
28930
|
});
|
|
28748
|
-
var GroupedUploadedAssetSource =
|
|
28749
|
-
type:
|
|
28931
|
+
var GroupedUploadedAssetSource = z122.object({
|
|
28932
|
+
type: z122.literal("asset"),
|
|
28750
28933
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
28751
|
-
assetId:
|
|
28752
|
-
thumbnailAssetId:
|
|
28934
|
+
assetId: z122.string().uuid(),
|
|
28935
|
+
thumbnailAssetId: z122.string().uuid().optional()
|
|
28753
28936
|
});
|
|
28754
|
-
var GroupedCreative =
|
|
28755
|
-
type:
|
|
28937
|
+
var GroupedCreative = z122.object({
|
|
28938
|
+
type: z122.enum([
|
|
28756
28939
|
"image",
|
|
28757
28940
|
"video"
|
|
28758
28941
|
]),
|
|
28759
|
-
source:
|
|
28942
|
+
source: z122.union([
|
|
28760
28943
|
GroupedTaskSource,
|
|
28761
28944
|
GroupedMediaSource,
|
|
28762
28945
|
GroupedUploadedAssetSource
|
|
28763
28946
|
]),
|
|
28764
|
-
title:
|
|
28765
|
-
description:
|
|
28947
|
+
title: z122.string().max(120).optional(),
|
|
28948
|
+
description: z122.string().max(500).optional(),
|
|
28766
28949
|
cta: MetaCtaType.optional(),
|
|
28767
|
-
creativeId:
|
|
28950
|
+
creativeId: z122.string().min(1).optional()
|
|
28768
28951
|
});
|
|
28769
|
-
var GroupedCampaignConfigBase =
|
|
28952
|
+
var GroupedCampaignConfigBase = z122.object({
|
|
28770
28953
|
campaignType: MetaCampaignType.default("sales"),
|
|
28771
28954
|
optimizationMode: MetaOptimizationMode.default("advantage_plus"),
|
|
28772
28955
|
budgetMode: MetaBudgetMode.optional(),
|
|
28773
|
-
campaignDailyBudget:
|
|
28774
|
-
adSets:
|
|
28775
|
-
tempId:
|
|
28776
|
-
name:
|
|
28777
|
-
dailyBudget:
|
|
28778
|
-
creativeIds:
|
|
28956
|
+
campaignDailyBudget: z122.number().int().positive().optional(),
|
|
28957
|
+
adSets: z122.array(z122.object({
|
|
28958
|
+
tempId: z122.string().min(1).max(80),
|
|
28959
|
+
name: z122.string().min(1).max(100),
|
|
28960
|
+
dailyBudget: z122.number().int().positive().optional(),
|
|
28961
|
+
creativeIds: z122.array(z122.string().min(1)).min(1)
|
|
28779
28962
|
})).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
|
|
28780
28963
|
/**
|
|
28781
28964
|
* Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
|
|
@@ -28783,17 +28966,17 @@ var GroupedCampaignConfigBase = z121.object({
|
|
|
28783
28966
|
* opaque `invalid_literal` and made the WhatsApp destination — supported by
|
|
28784
28967
|
* the API since #849 — unreachable from this tool.
|
|
28785
28968
|
*/
|
|
28786
|
-
destination:
|
|
28787
|
-
|
|
28788
|
-
type:
|
|
28789
|
-
landingUrl:
|
|
28969
|
+
destination: z122.discriminatedUnion("type", [
|
|
28970
|
+
z122.object({
|
|
28971
|
+
type: z122.literal("landing"),
|
|
28972
|
+
landingUrl: z122.string().url()
|
|
28790
28973
|
}),
|
|
28791
|
-
|
|
28792
|
-
type:
|
|
28793
|
-
phoneNumber:
|
|
28974
|
+
z122.object({
|
|
28975
|
+
type: z122.literal("whatsapp"),
|
|
28976
|
+
phoneNumber: z122.string().min(8).max(32)
|
|
28794
28977
|
})
|
|
28795
28978
|
]),
|
|
28796
|
-
saveAsDefault:
|
|
28979
|
+
saveAsDefault: z122.boolean().default(false),
|
|
28797
28980
|
budgetPolicy: MetaBudgetPolicy.optional()
|
|
28798
28981
|
});
|
|
28799
28982
|
function resolveBudgetMode(value) {
|
|
@@ -28807,7 +28990,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
28807
28990
|
const budgetMode = resolveBudgetMode(value);
|
|
28808
28991
|
if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
|
|
28809
28992
|
ctx.addIssue({
|
|
28810
|
-
code:
|
|
28993
|
+
code: z122.ZodIssueCode.custom,
|
|
28811
28994
|
path: [
|
|
28812
28995
|
"campaignDailyBudget"
|
|
28813
28996
|
],
|
|
@@ -28818,7 +29001,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
28818
29001
|
value.adSets.forEach((adSet, index) => {
|
|
28819
29002
|
if (adSet.dailyBudget === void 0) {
|
|
28820
29003
|
ctx.addIssue({
|
|
28821
|
-
code:
|
|
29004
|
+
code: z122.ZodIssueCode.custom,
|
|
28822
29005
|
path: [
|
|
28823
29006
|
"adSets",
|
|
28824
29007
|
index,
|
|
@@ -28833,28 +29016,28 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
28833
29016
|
...value,
|
|
28834
29017
|
budgetMode: resolveBudgetMode(value)
|
|
28835
29018
|
}));
|
|
28836
|
-
var PublishCreativesToMetaInputBase =
|
|
28837
|
-
creatives:
|
|
29019
|
+
var PublishCreativesToMetaInputBase = z122.object({
|
|
29020
|
+
creatives: z122.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
|
|
28838
29021
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
28839
|
-
portfolioId:
|
|
29022
|
+
portfolioId: z122.string().trim().min(1),
|
|
28840
29023
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
28841
|
-
pageId:
|
|
29024
|
+
pageId: z122.string().trim().min(1),
|
|
28842
29025
|
adAccountId: McpAdAccountId,
|
|
28843
|
-
pixelId:
|
|
29026
|
+
pixelId: z122.string().min(1).optional(),
|
|
28844
29027
|
/** Required unless `campaignConfig.destination` is whatsapp — see the
|
|
28845
29028
|
* superRefine below. Mirrors the API's `FacebookCreateCampaignFromTasksBodySchema`. */
|
|
28846
|
-
landingUrl:
|
|
29029
|
+
landingUrl: z122.string().url().optional(),
|
|
28847
29030
|
/** ISO-2 code or resolvable country name — mirrors the API contract
|
|
28848
29031
|
* (CountryIso2Schema), which normalizes names to alpha-2 at validation. */
|
|
28849
29032
|
targetCountry: CountryIso2Schema,
|
|
28850
|
-
campaignName:
|
|
29033
|
+
campaignName: z122.string().trim().min(1).max(100),
|
|
28851
29034
|
campaignConfig: GroupedCampaignConfig.optional()
|
|
28852
29035
|
});
|
|
28853
29036
|
var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
|
|
28854
29037
|
const destination = value.campaignConfig?.destination;
|
|
28855
29038
|
if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl) {
|
|
28856
29039
|
ctx.addIssue({
|
|
28857
|
-
code:
|
|
29040
|
+
code: z122.ZodIssueCode.custom,
|
|
28858
29041
|
path: [
|
|
28859
29042
|
"landingUrl"
|
|
28860
29043
|
],
|
|
@@ -28863,7 +29046,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
28863
29046
|
}
|
|
28864
29047
|
if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
|
|
28865
29048
|
ctx.addIssue({
|
|
28866
|
-
code:
|
|
29049
|
+
code: z122.ZodIssueCode.custom,
|
|
28867
29050
|
path: [
|
|
28868
29051
|
"campaignConfig",
|
|
28869
29052
|
"destination",
|
|
@@ -28882,16 +29065,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
28882
29065
|
}
|
|
28883
29066
|
return value;
|
|
28884
29067
|
});
|
|
28885
|
-
var PresignUploadResponseSchema =
|
|
28886
|
-
uploadUrl:
|
|
29068
|
+
var PresignUploadResponseSchema = z122.object({
|
|
29069
|
+
uploadUrl: z122.string().url().refine((value) => {
|
|
28887
29070
|
const url = new URL(value);
|
|
28888
29071
|
return !url.username && !url.password && url.protocol === "https:";
|
|
28889
29072
|
}, "presigned upload URL must be HTTPS without embedded credentials"),
|
|
28890
|
-
publicUrl:
|
|
29073
|
+
publicUrl: z122.string().url().refine((value) => {
|
|
28891
29074
|
const url = new URL(value);
|
|
28892
29075
|
return !url.username && !url.password;
|
|
28893
29076
|
}, "public media URL must not contain embedded credentials"),
|
|
28894
|
-
stagingAssetId:
|
|
29077
|
+
stagingAssetId: z122.string().uuid()
|
|
28895
29078
|
});
|
|
28896
29079
|
async function uploadResolvedMedia(api, media, assetRole) {
|
|
28897
29080
|
if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
|
|
@@ -28916,16 +29099,16 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
|
|
|
28916
29099
|
return uploadResolvedMedia(api, media, assetRole);
|
|
28917
29100
|
}
|
|
28918
29101
|
__name(resolveAndUploadMedia, "resolveAndUploadMedia");
|
|
28919
|
-
var TikTokInput =
|
|
28920
|
-
taskId:
|
|
28921
|
-
advertiserId:
|
|
28922
|
-
pixelId:
|
|
28923
|
-
landingUrl:
|
|
28924
|
-
angleIndexes:
|
|
29102
|
+
var TikTokInput = z122.object({
|
|
29103
|
+
taskId: z122.string().min(1),
|
|
29104
|
+
advertiserId: z122.string().min(1),
|
|
29105
|
+
pixelId: z122.string().min(1).optional(),
|
|
29106
|
+
landingUrl: z122.string().url().optional(),
|
|
29107
|
+
angleIndexes: z122.array(z122.number().int().nonnegative()).optional(),
|
|
28925
29108
|
campaignConfig: McpCampaignConfig.optional(),
|
|
28926
29109
|
/** Override the ad's description (TikTok's body copy). If omitted,
|
|
28927
29110
|
* ProductMaker uses the auto-generated copy attached to the task. */
|
|
28928
|
-
primaryText:
|
|
29111
|
+
primaryText: z122.string().trim().min(1).max(500).optional()
|
|
28929
29112
|
});
|
|
28930
29113
|
function registerPublishTools(server, api, opts = {}) {
|
|
28931
29114
|
const transport = opts.transport ?? "http";
|
|
@@ -29277,39 +29460,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
|
|
|
29277
29460
|
|
|
29278
29461
|
// src/tools/meta-upload.ts
|
|
29279
29462
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
29280
|
-
import { z as
|
|
29463
|
+
import { z as z123 } from "zod";
|
|
29281
29464
|
var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
|
|
29282
|
-
var UploadSessionInputBase =
|
|
29283
|
-
mediaKind:
|
|
29465
|
+
var UploadSessionInputBase = z123.object({
|
|
29466
|
+
mediaKind: z123.enum([
|
|
29284
29467
|
"image",
|
|
29285
29468
|
"video",
|
|
29286
29469
|
"mixed"
|
|
29287
29470
|
]).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."),
|
|
29288
|
-
assetRole:
|
|
29471
|
+
assetRole: z123.enum([
|
|
29289
29472
|
"media",
|
|
29290
29473
|
"thumbnail"
|
|
29291
29474
|
]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
|
|
29292
|
-
uploadPurpose:
|
|
29475
|
+
uploadPurpose: z123.enum([
|
|
29293
29476
|
"product_reference",
|
|
29294
29477
|
"creative",
|
|
29295
29478
|
"generic"
|
|
29296
29479
|
]).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."),
|
|
29297
|
-
maxFiles:
|
|
29480
|
+
maxFiles: z123.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
29298
29481
|
});
|
|
29299
|
-
var OpenAiFileReference =
|
|
29300
|
-
download_url:
|
|
29301
|
-
file_id:
|
|
29302
|
-
mime_type:
|
|
29303
|
-
file_name:
|
|
29482
|
+
var OpenAiFileReference = z123.object({
|
|
29483
|
+
download_url: z123.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."),
|
|
29484
|
+
file_id: z123.string().min(1),
|
|
29485
|
+
mime_type: z123.string().min(1).optional(),
|
|
29486
|
+
file_name: z123.string().min(1).optional()
|
|
29304
29487
|
});
|
|
29305
29488
|
var UploadSessionToolInputShape = {
|
|
29306
29489
|
...UploadSessionInputBase.shape,
|
|
29307
|
-
files:
|
|
29490
|
+
files: z123.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.")
|
|
29308
29491
|
};
|
|
29309
|
-
var UploadSessionToolInput =
|
|
29492
|
+
var UploadSessionToolInput = z123.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
29310
29493
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
29311
29494
|
ctx.addIssue({
|
|
29312
|
-
code:
|
|
29495
|
+
code: z123.ZodIssueCode.custom,
|
|
29313
29496
|
path: [
|
|
29314
29497
|
"mediaKind"
|
|
29315
29498
|
],
|
|
@@ -29318,7 +29501,7 @@ var UploadSessionToolInput = z122.object(UploadSessionToolInputShape).superRefin
|
|
|
29318
29501
|
}
|
|
29319
29502
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
29320
29503
|
ctx.addIssue({
|
|
29321
|
-
code:
|
|
29504
|
+
code: z123.ZodIssueCode.custom,
|
|
29322
29505
|
path: [
|
|
29323
29506
|
"maxFiles"
|
|
29324
29507
|
],
|
|
@@ -29327,7 +29510,7 @@ var UploadSessionToolInput = z122.object(UploadSessionToolInputShape).superRefin
|
|
|
29327
29510
|
}
|
|
29328
29511
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
|
|
29329
29512
|
ctx.addIssue({
|
|
29330
|
-
code:
|
|
29513
|
+
code: z123.ZodIssueCode.custom,
|
|
29331
29514
|
path: [
|
|
29332
29515
|
"maxFiles"
|
|
29333
29516
|
],
|
|
@@ -29335,38 +29518,38 @@ var UploadSessionToolInput = z122.object(UploadSessionToolInputShape).superRefin
|
|
|
29335
29518
|
});
|
|
29336
29519
|
}
|
|
29337
29520
|
});
|
|
29338
|
-
var UploadSessionResponse =
|
|
29339
|
-
sessionId:
|
|
29340
|
-
uploadPageUrl:
|
|
29341
|
-
mediaKind:
|
|
29521
|
+
var UploadSessionResponse = z123.object({
|
|
29522
|
+
sessionId: z123.string().uuid(),
|
|
29523
|
+
uploadPageUrl: z123.string().url(),
|
|
29524
|
+
mediaKind: z123.enum([
|
|
29342
29525
|
"image",
|
|
29343
29526
|
"video",
|
|
29344
29527
|
"mixed"
|
|
29345
29528
|
]),
|
|
29346
|
-
assetRole:
|
|
29529
|
+
assetRole: z123.enum([
|
|
29347
29530
|
"media",
|
|
29348
29531
|
"thumbnail"
|
|
29349
29532
|
]),
|
|
29350
|
-
maxFiles:
|
|
29351
|
-
expiresAt:
|
|
29533
|
+
maxFiles: z123.number().int().positive(),
|
|
29534
|
+
expiresAt: z123.string().datetime()
|
|
29352
29535
|
});
|
|
29353
|
-
var UploadStatusInput =
|
|
29354
|
-
sessionId:
|
|
29536
|
+
var UploadStatusInput = z123.object({
|
|
29537
|
+
sessionId: z123.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
29355
29538
|
});
|
|
29356
|
-
var UniversalUploadStatusResponse =
|
|
29357
|
-
|
|
29358
|
-
status:
|
|
29359
|
-
assets:
|
|
29539
|
+
var UniversalUploadStatusResponse = z123.discriminatedUnion("status", [
|
|
29540
|
+
z123.object({
|
|
29541
|
+
status: z123.literal("pending"),
|
|
29542
|
+
assets: z123.array(z123.never()).length(0)
|
|
29360
29543
|
}),
|
|
29361
|
-
|
|
29362
|
-
status:
|
|
29363
|
-
assets:
|
|
29364
|
-
assetId:
|
|
29365
|
-
mediaKind:
|
|
29544
|
+
z123.object({
|
|
29545
|
+
status: z123.literal("uploaded"),
|
|
29546
|
+
assets: z123.array(z123.object({
|
|
29547
|
+
assetId: z123.string().uuid(),
|
|
29548
|
+
mediaKind: z123.enum([
|
|
29366
29549
|
"image",
|
|
29367
29550
|
"video"
|
|
29368
29551
|
]),
|
|
29369
|
-
assetRole:
|
|
29552
|
+
assetRole: z123.enum([
|
|
29370
29553
|
"media",
|
|
29371
29554
|
"thumbnail"
|
|
29372
29555
|
])
|
|
@@ -29374,13 +29557,13 @@ var UniversalUploadStatusResponse = z122.discriminatedUnion("status", [
|
|
|
29374
29557
|
})
|
|
29375
29558
|
]);
|
|
29376
29559
|
var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
|
|
29377
|
-
uploadPurpose:
|
|
29560
|
+
uploadPurpose: z123.enum([
|
|
29378
29561
|
"product_reference",
|
|
29379
29562
|
"creative",
|
|
29380
29563
|
"generic"
|
|
29381
29564
|
]),
|
|
29382
|
-
checkToolName:
|
|
29383
|
-
resolveEndpoint:
|
|
29565
|
+
checkToolName: z123.literal("check_media_upload"),
|
|
29566
|
+
resolveEndpoint: z123.string().url()
|
|
29384
29567
|
});
|
|
29385
29568
|
function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
|
|
29386
29569
|
const url = new URL(uploadPageUrl);
|
|
@@ -29471,15 +29654,15 @@ function registerMediaUploadTools(server, api) {
|
|
|
29471
29654
|
__name(registerMediaUploadTools, "registerMediaUploadTools");
|
|
29472
29655
|
|
|
29473
29656
|
// src/tools/campaigns.ts
|
|
29474
|
-
import { z as
|
|
29657
|
+
import { z as z124 } from "zod";
|
|
29475
29658
|
var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
|
|
29476
29659
|
var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
|
|
29477
|
-
var MetaStatusInput =
|
|
29478
|
-
campaignId:
|
|
29660
|
+
var MetaStatusInput = z124.object({
|
|
29661
|
+
campaignId: z124.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
|
|
29479
29662
|
});
|
|
29480
|
-
var TikTokStatusInput =
|
|
29481
|
-
campaignId:
|
|
29482
|
-
advertiserId:
|
|
29663
|
+
var TikTokStatusInput = z124.object({
|
|
29664
|
+
campaignId: z124.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
|
|
29665
|
+
advertiserId: z124.string().min(1).describe("The same advertiserId used to publish the campaign.")
|
|
29483
29666
|
});
|
|
29484
29667
|
function registerCampaignTools(server, api) {
|
|
29485
29668
|
server.registerTool("get_meta_campaign_status", {
|
|
@@ -29584,10 +29767,10 @@ function renderTikTokStatusMarkdown(r) {
|
|
|
29584
29767
|
__name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
|
|
29585
29768
|
|
|
29586
29769
|
// ../../packages/product-economics/src/product-costing.ts
|
|
29587
|
-
import { z as
|
|
29770
|
+
import { z as z126 } from "zod";
|
|
29588
29771
|
|
|
29589
29772
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
29590
|
-
import { z as
|
|
29773
|
+
import { z as z125 } from "zod";
|
|
29591
29774
|
|
|
29592
29775
|
// ../../packages/product-economics/src/product-costing-shipping-references.json
|
|
29593
29776
|
var product_costing_shipping_references_default = {
|
|
@@ -29651,21 +29834,21 @@ var product_costing_shipping_references_default = {
|
|
|
29651
29834
|
};
|
|
29652
29835
|
|
|
29653
29836
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
29654
|
-
var ShippingReferenceSchema =
|
|
29655
|
-
reference:
|
|
29656
|
-
min:
|
|
29657
|
-
max:
|
|
29658
|
-
updatedAt:
|
|
29659
|
-
confidence:
|
|
29837
|
+
var ShippingReferenceSchema = z125.object({
|
|
29838
|
+
reference: z125.number().positive(),
|
|
29839
|
+
min: z125.number().nonnegative(),
|
|
29840
|
+
max: z125.number().positive(),
|
|
29841
|
+
updatedAt: z125.string().date(),
|
|
29842
|
+
confidence: z125.enum([
|
|
29660
29843
|
"high",
|
|
29661
29844
|
"medium",
|
|
29662
29845
|
"medium-low"
|
|
29663
29846
|
]),
|
|
29664
|
-
sources:
|
|
29847
|
+
sources: z125.array(z125.string().url().startsWith("https://")).min(1).max(3)
|
|
29665
29848
|
}).superRefine(({ reference, min, max }, context) => {
|
|
29666
29849
|
if (min > reference || reference > max) {
|
|
29667
29850
|
context.addIssue({
|
|
29668
|
-
code:
|
|
29851
|
+
code: z125.ZodIssueCode.custom,
|
|
29669
29852
|
message: "shipping_reference_outside_range",
|
|
29670
29853
|
path: [
|
|
29671
29854
|
"reference"
|
|
@@ -29673,7 +29856,7 @@ var ShippingReferenceSchema = z124.object({
|
|
|
29673
29856
|
});
|
|
29674
29857
|
}
|
|
29675
29858
|
});
|
|
29676
|
-
var SHIPPING_REFERENCES =
|
|
29859
|
+
var SHIPPING_REFERENCES = z125.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
|
|
29677
29860
|
var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
|
|
29678
29861
|
var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
|
|
29679
29862
|
"MX",
|
|
@@ -29855,18 +30038,18 @@ function getProductCostingCountryName(country) {
|
|
|
29855
30038
|
__name(getProductCostingCountryName, "getProductCostingCountryName");
|
|
29856
30039
|
|
|
29857
30040
|
// ../../packages/product-economics/src/product-costing.ts
|
|
29858
|
-
var ProductCostingInputSchema =
|
|
29859
|
-
country:
|
|
29860
|
-
supplierCost:
|
|
29861
|
-
shippingCost:
|
|
29862
|
-
returnRate:
|
|
29863
|
-
cancellationRate:
|
|
29864
|
-
adsManagerCpa:
|
|
29865
|
-
desiredMargin:
|
|
30041
|
+
var ProductCostingInputSchema = z126.object({
|
|
30042
|
+
country: z126.string().refine(isProductCostingCountryCode, "unsupported_country"),
|
|
30043
|
+
supplierCost: z126.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
|
|
30044
|
+
shippingCost: z126.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
|
|
30045
|
+
returnRate: z126.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
30046
|
+
cancellationRate: z126.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
30047
|
+
adsManagerCpa: z126.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
|
|
30048
|
+
desiredMargin: z126.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
|
|
29866
30049
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
29867
30050
|
if (returnRate + cancellationRate >= 1) {
|
|
29868
30051
|
context.addIssue({
|
|
29869
|
-
code:
|
|
30052
|
+
code: z126.ZodIssueCode.custom,
|
|
29870
30053
|
message: "delivery_rate_positive",
|
|
29871
30054
|
path: [
|
|
29872
30055
|
"cancellationRate"
|
|
@@ -29963,15 +30146,15 @@ function calculateProductCosting(rawInput) {
|
|
|
29963
30146
|
__name(calculateProductCosting, "calculateProductCosting");
|
|
29964
30147
|
|
|
29965
30148
|
// src/tools/product-costing.ts
|
|
29966
|
-
import { z as
|
|
30149
|
+
import { z as z127 } from "zod";
|
|
29967
30150
|
var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
|
|
29968
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
29969
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
29970
|
-
var ProductCostingToolInput =
|
|
29971
|
-
country:
|
|
30151
|
+
var optionalAmount = /* @__PURE__ */ __name((description) => z127.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
|
|
30152
|
+
var optionalPercent = /* @__PURE__ */ __name((description) => z127.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
|
|
30153
|
+
var ProductCostingToolInput = z127.object({
|
|
30154
|
+
country: z127.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
29972
30155
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
29973
30156
|
}).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
|
|
29974
|
-
supplierCost:
|
|
30157
|
+
supplierCost: z127.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."),
|
|
29975
30158
|
supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
|
|
29976
30159
|
shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
|
|
29977
30160
|
shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
|
|
@@ -30134,7 +30317,7 @@ function formatPercent(value) {
|
|
|
30134
30317
|
__name(formatPercent, "formatPercent");
|
|
30135
30318
|
|
|
30136
30319
|
// src/tools/product-research.ts
|
|
30137
|
-
import { z as
|
|
30320
|
+
import { z as z128 } from "zod";
|
|
30138
30321
|
|
|
30139
30322
|
// src/tools/product-research-idempotency.ts
|
|
30140
30323
|
var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
|
|
@@ -30505,17 +30688,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
|
|
|
30505
30688
|
]);
|
|
30506
30689
|
var POLL_INTERVAL_MS = 5e3;
|
|
30507
30690
|
var MAX_WAIT_SECONDS = 120;
|
|
30508
|
-
var FindInput =
|
|
30691
|
+
var FindInput = z128.object({
|
|
30509
30692
|
targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
|
|
30510
30693
|
categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
|
|
30511
|
-
confirmed:
|
|
30512
|
-
waitSeconds:
|
|
30694
|
+
confirmed: z128.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
|
|
30695
|
+
waitSeconds: z128.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
|
|
30513
30696
|
});
|
|
30514
|
-
var GetInput =
|
|
30515
|
-
runId:
|
|
30697
|
+
var GetInput = z128.object({
|
|
30698
|
+
runId: z128.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
30516
30699
|
});
|
|
30517
|
-
var ListInput =
|
|
30518
|
-
limit:
|
|
30700
|
+
var ListInput = z128.object({
|
|
30701
|
+
limit: z128.number().int().min(1).max(20).default(10)
|
|
30519
30702
|
});
|
|
30520
30703
|
function textResult(text2) {
|
|
30521
30704
|
return {
|
|
@@ -30654,17 +30837,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
30654
30837
|
__name(registerProductResearchTools, "registerProductResearchTools");
|
|
30655
30838
|
|
|
30656
30839
|
// src/tools/dropshipping-projects.ts
|
|
30657
|
-
import { z as
|
|
30840
|
+
import { z as z129 } from "zod";
|
|
30658
30841
|
var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
|
|
30659
30842
|
var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
|
|
30660
30843
|
var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
|
|
30661
|
-
var ProjectId =
|
|
30662
|
-
var DropshippingProjectStatus =
|
|
30844
|
+
var ProjectId = z129.string().uuid();
|
|
30845
|
+
var DropshippingProjectStatus = z129.enum([
|
|
30663
30846
|
"active",
|
|
30664
30847
|
"completed",
|
|
30665
30848
|
"archived"
|
|
30666
30849
|
]);
|
|
30667
|
-
var DropshippingProjectPhase =
|
|
30850
|
+
var DropshippingProjectPhase = z129.enum([
|
|
30668
30851
|
"research",
|
|
30669
30852
|
"costing",
|
|
30670
30853
|
"media",
|
|
@@ -30673,21 +30856,21 @@ var DropshippingProjectPhase = z128.enum([
|
|
|
30673
30856
|
"advertising",
|
|
30674
30857
|
"complete"
|
|
30675
30858
|
]);
|
|
30676
|
-
var DropshippingRewardMilestone =
|
|
30859
|
+
var DropshippingRewardMilestone = z129.enum([
|
|
30677
30860
|
"product_selected",
|
|
30678
30861
|
"costing_saved",
|
|
30679
30862
|
"product_media_ready",
|
|
30680
30863
|
"creatives_completed",
|
|
30681
30864
|
"campaign_created"
|
|
30682
30865
|
]);
|
|
30683
|
-
var TargetCountry =
|
|
30866
|
+
var TargetCountry = z129.enum([
|
|
30684
30867
|
"CO",
|
|
30685
30868
|
"MX",
|
|
30686
30869
|
"PE",
|
|
30687
30870
|
"EC",
|
|
30688
30871
|
"CL"
|
|
30689
30872
|
]);
|
|
30690
|
-
var ResearchCategory =
|
|
30873
|
+
var ResearchCategory = z129.enum([
|
|
30691
30874
|
"auto",
|
|
30692
30875
|
"automotive",
|
|
30693
30876
|
"kitchen",
|
|
@@ -30702,7 +30885,7 @@ var ResearchCategory = z128.enum([
|
|
|
30702
30885
|
"garden",
|
|
30703
30886
|
"cleaning"
|
|
30704
30887
|
]);
|
|
30705
|
-
var HttpUrl3 =
|
|
30888
|
+
var HttpUrl3 = z129.string().url().max(2e3).refine((value) => {
|
|
30706
30889
|
try {
|
|
30707
30890
|
return [
|
|
30708
30891
|
"http:",
|
|
@@ -30712,45 +30895,45 @@ var HttpUrl3 = z128.string().url().max(2e3).refine((value) => {
|
|
|
30712
30895
|
return false;
|
|
30713
30896
|
}
|
|
30714
30897
|
}, "URL must use HTTP(S)");
|
|
30715
|
-
var ResearchCandidateOrigin =
|
|
30716
|
-
type:
|
|
30898
|
+
var ResearchCandidateOrigin = z129.object({
|
|
30899
|
+
type: z129.literal("research_candidate"),
|
|
30717
30900
|
runId: ProjectId,
|
|
30718
|
-
candidateSourceId:
|
|
30901
|
+
candidateSourceId: z129.string().min(1).max(160)
|
|
30719
30902
|
});
|
|
30720
|
-
var TaskOrigin =
|
|
30721
|
-
type:
|
|
30903
|
+
var TaskOrigin = z129.object({
|
|
30904
|
+
type: z129.literal("task"),
|
|
30722
30905
|
taskId: ProjectId
|
|
30723
30906
|
});
|
|
30724
|
-
var ManualOrigin =
|
|
30725
|
-
type:
|
|
30907
|
+
var ManualOrigin = z129.object({
|
|
30908
|
+
type: z129.literal("manual"),
|
|
30726
30909
|
clientRequestId: ProjectId,
|
|
30727
|
-
country:
|
|
30910
|
+
country: z129.string().min(2).max(3).optional()
|
|
30728
30911
|
});
|
|
30729
|
-
var StartProjectInput =
|
|
30730
|
-
origin:
|
|
30912
|
+
var StartProjectInput = z129.object({
|
|
30913
|
+
origin: z129.discriminatedUnion("type", [
|
|
30731
30914
|
ResearchCandidateOrigin,
|
|
30732
30915
|
TaskOrigin,
|
|
30733
30916
|
ManualOrigin
|
|
30734
30917
|
]),
|
|
30735
|
-
productName:
|
|
30918
|
+
productName: z129.string().trim().min(1).max(240).optional(),
|
|
30736
30919
|
productUrl: HttpUrl3.optional(),
|
|
30737
|
-
country:
|
|
30738
|
-
languageCode:
|
|
30920
|
+
country: z129.string().min(2).max(3).optional(),
|
|
30921
|
+
languageCode: z129.string().min(2).max(16).optional()
|
|
30739
30922
|
}).strict();
|
|
30740
|
-
var CostProjectInput =
|
|
30923
|
+
var CostProjectInput = z129.object({
|
|
30741
30924
|
projectId: ProjectId,
|
|
30742
|
-
version:
|
|
30743
|
-
country:
|
|
30925
|
+
version: z129.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
|
|
30926
|
+
country: z129.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
30744
30927
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
30745
30928
|
}).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
|
|
30746
|
-
supplierCost:
|
|
30747
|
-
shippingCost:
|
|
30748
|
-
returnRate:
|
|
30749
|
-
cancellationRate:
|
|
30750
|
-
adsManagerCpa:
|
|
30751
|
-
desiredMargin:
|
|
30752
|
-
});
|
|
30753
|
-
var GuideInput =
|
|
30929
|
+
supplierCost: z129.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."),
|
|
30930
|
+
shippingCost: z129.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
|
|
30931
|
+
returnRate: z129.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."),
|
|
30932
|
+
cancellationRate: z129.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."),
|
|
30933
|
+
adsManagerCpa: z129.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
30934
|
+
desiredMargin: z129.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
|
|
30935
|
+
});
|
|
30936
|
+
var GuideInput = z129.object({
|
|
30754
30937
|
projectId: ProjectId.optional()
|
|
30755
30938
|
}).strict();
|
|
30756
30939
|
var NEXT_ACTION_KINDS = [
|
|
@@ -30768,29 +30951,29 @@ var NEXT_ACTION_KINDS = [
|
|
|
30768
30951
|
"repair_meta_campaign",
|
|
30769
30952
|
"review_paused_campaign"
|
|
30770
30953
|
];
|
|
30771
|
-
var DropshippingProjectNextAction =
|
|
30772
|
-
kind:
|
|
30773
|
-
href:
|
|
30954
|
+
var DropshippingProjectNextAction = z129.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z129.object({
|
|
30955
|
+
kind: z129.literal(kind),
|
|
30956
|
+
href: z129.string().min(1)
|
|
30774
30957
|
})));
|
|
30775
|
-
var CostingInputSchema =
|
|
30776
|
-
country:
|
|
30777
|
-
supplierCost:
|
|
30778
|
-
shippingCost:
|
|
30779
|
-
returnRate:
|
|
30780
|
-
cancellationRate:
|
|
30781
|
-
adsManagerCpa:
|
|
30782
|
-
desiredMargin:
|
|
30958
|
+
var CostingInputSchema = z129.object({
|
|
30959
|
+
country: z129.string().min(2).max(3),
|
|
30960
|
+
supplierCost: z129.number().finite().positive(),
|
|
30961
|
+
shippingCost: z129.number().finite().nonnegative(),
|
|
30962
|
+
returnRate: z129.number().finite().min(0).lt(1),
|
|
30963
|
+
cancellationRate: z129.number().finite().min(0).lt(1),
|
|
30964
|
+
adsManagerCpa: z129.number().finite().nonnegative(),
|
|
30965
|
+
desiredMargin: z129.number().finite().min(0).lt(1)
|
|
30783
30966
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
30784
30967
|
if (returnRate + cancellationRate >= 1) context.addIssue({
|
|
30785
|
-
code:
|
|
30968
|
+
code: z129.ZodIssueCode.custom,
|
|
30786
30969
|
path: [
|
|
30787
30970
|
"cancellationRate"
|
|
30788
30971
|
]
|
|
30789
30972
|
});
|
|
30790
30973
|
});
|
|
30791
|
-
var FiniteCostingNumber =
|
|
30792
|
-
var CostingResultSchema =
|
|
30793
|
-
country:
|
|
30974
|
+
var FiniteCostingNumber = z129.number().finite();
|
|
30975
|
+
var CostingResultSchema = z129.object({
|
|
30976
|
+
country: z129.string().min(2).max(3),
|
|
30794
30977
|
deliveryRate: FiniteCostingNumber,
|
|
30795
30978
|
adjustedShippingCost: FiniteCostingNumber,
|
|
30796
30979
|
adjustedCpa: FiniteCostingNumber,
|
|
@@ -30803,45 +30986,45 @@ var CostingResultSchema = z128.object({
|
|
|
30803
30986
|
estimatedProfit: FiniteCostingNumber,
|
|
30804
30987
|
actualMargin: FiniteCostingNumber,
|
|
30805
30988
|
breakEvenAdsManagerCpa: FiniteCostingNumber,
|
|
30806
|
-
wasPriceAutoAdjusted:
|
|
30807
|
-
profitabilityStatus:
|
|
30808
|
-
});
|
|
30809
|
-
var RewardProgressSchema =
|
|
30810
|
-
campaignKey:
|
|
30811
|
-
totalCredits:
|
|
30812
|
-
earnedCredits:
|
|
30813
|
-
milestones:
|
|
30989
|
+
wasPriceAutoAdjusted: z129.boolean(),
|
|
30990
|
+
profitabilityStatus: z129.literal("healthy")
|
|
30991
|
+
});
|
|
30992
|
+
var RewardProgressSchema = z129.object({
|
|
30993
|
+
campaignKey: z129.literal("dropshipping-launch-v1"),
|
|
30994
|
+
totalCredits: z129.number().int().positive(),
|
|
30995
|
+
earnedCredits: z129.number().int().nonnegative(),
|
|
30996
|
+
milestones: z129.array(z129.object({
|
|
30814
30997
|
milestone: DropshippingRewardMilestone,
|
|
30815
|
-
credits:
|
|
30816
|
-
available:
|
|
30817
|
-
earned:
|
|
30998
|
+
credits: z129.number().int().positive(),
|
|
30999
|
+
available: z129.boolean().optional(),
|
|
31000
|
+
earned: z129.boolean(),
|
|
30818
31001
|
grantId: ProjectId.nullable(),
|
|
30819
|
-
grantedAt:
|
|
31002
|
+
grantedAt: z129.string().datetime().nullable()
|
|
30820
31003
|
})).length(DropshippingRewardMilestone.options.length)
|
|
30821
31004
|
});
|
|
30822
|
-
var ProjectResponseSchema =
|
|
31005
|
+
var ProjectResponseSchema = z129.object({
|
|
30823
31006
|
id: ProjectId,
|
|
30824
31007
|
taskId: ProjectId.nullable(),
|
|
30825
31008
|
status: DropshippingProjectStatus,
|
|
30826
|
-
originKey:
|
|
31009
|
+
originKey: z129.string().min(1),
|
|
30827
31010
|
researchRunId: ProjectId.nullable(),
|
|
30828
|
-
candidateSourceId:
|
|
30829
|
-
productName:
|
|
31011
|
+
candidateSourceId: z129.string().nullable(),
|
|
31012
|
+
productName: z129.string().nullable(),
|
|
30830
31013
|
productUrl: HttpUrl3.nullable(),
|
|
30831
31014
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
30832
|
-
targetCountry:
|
|
30833
|
-
languageCode:
|
|
30834
|
-
hasReferenceImage:
|
|
30835
|
-
hasWinnerReferenceImage:
|
|
31015
|
+
targetCountry: z129.string().nullable(),
|
|
31016
|
+
languageCode: z129.string().nullable(),
|
|
31017
|
+
hasReferenceImage: z129.boolean(),
|
|
31018
|
+
hasWinnerReferenceImage: z129.boolean(),
|
|
30836
31019
|
costingInput: CostingInputSchema.nullable(),
|
|
30837
31020
|
costingResult: CostingResultSchema.nullable(),
|
|
30838
|
-
costingVersion:
|
|
30839
|
-
version:
|
|
31021
|
+
costingVersion: z129.number().int().positive().nullable(),
|
|
31022
|
+
version: z129.number().int().positive(),
|
|
30840
31023
|
phase: DropshippingProjectPhase,
|
|
30841
31024
|
nextAction: DropshippingProjectNextAction.nullable(),
|
|
30842
31025
|
rewards: RewardProgressSchema,
|
|
30843
|
-
createdAt:
|
|
30844
|
-
updatedAt:
|
|
31026
|
+
createdAt: z129.string().datetime(),
|
|
31027
|
+
updatedAt: z129.string().datetime()
|
|
30845
31028
|
}).passthrough();
|
|
30846
31029
|
var NEXT_ACTION_GUIDANCE = {
|
|
30847
31030
|
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.",
|
|
@@ -30961,58 +31144,58 @@ function registerDropshippingProjectTools(server, api) {
|
|
|
30961
31144
|
__name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
|
|
30962
31145
|
|
|
30963
31146
|
// src/tools/daily-control.ts
|
|
30964
|
-
import { z as
|
|
31147
|
+
import { z as z130 } from "zod";
|
|
30965
31148
|
var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
|
|
30966
31149
|
var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
|
|
30967
31150
|
var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
|
|
30968
|
-
var ProviderCampaignIdentifier =
|
|
30969
|
-
var DateOnly =
|
|
30970
|
-
var DailyControlInput =
|
|
31151
|
+
var ProviderCampaignIdentifier = z130.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
|
|
31152
|
+
var DateOnly = z130.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
31153
|
+
var DailyControlInput = z130.object({
|
|
30971
31154
|
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."),
|
|
30972
|
-
days:
|
|
30973
|
-
projectId:
|
|
31155
|
+
days: z130.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
31156
|
+
projectId: z130.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
|
|
30974
31157
|
}).strict();
|
|
30975
|
-
var LinkCampaignInput =
|
|
30976
|
-
projectId:
|
|
30977
|
-
provider:
|
|
31158
|
+
var LinkCampaignInput = z130.object({
|
|
31159
|
+
projectId: z130.string().uuid(),
|
|
31160
|
+
provider: z130.enum([
|
|
30978
31161
|
"meta",
|
|
30979
31162
|
"tiktok"
|
|
30980
31163
|
]),
|
|
30981
31164
|
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."),
|
|
30982
31165
|
campaignId: ProviderCampaignIdentifier
|
|
30983
31166
|
}).strict();
|
|
30984
|
-
var ReportReturnsInput =
|
|
30985
|
-
projectId:
|
|
31167
|
+
var ReportReturnsInput = z130.object({
|
|
31168
|
+
projectId: z130.string().uuid(),
|
|
30986
31169
|
date: DateOnly,
|
|
30987
|
-
returnedOrders:
|
|
30988
|
-
note:
|
|
31170
|
+
returnedOrders: z130.number().int().min(0).max(1e5),
|
|
31171
|
+
note: z130.string().trim().max(280).optional()
|
|
30989
31172
|
}).strict();
|
|
30990
|
-
var DailyControlStatusMirror = DailyControlStatusEnum.or(
|
|
30991
|
-
var DailyControlLightMirror = DailyControlLightEnum.or(
|
|
30992
|
-
var DailyControlSourceMirror = DailyControlSourceEnum.or(
|
|
30993
|
-
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(
|
|
30994
|
-
var DailyControlDayMirror =
|
|
30995
|
-
date:
|
|
30996
|
-
returnedOrders:
|
|
31173
|
+
var DailyControlStatusMirror = DailyControlStatusEnum.or(z130.string());
|
|
31174
|
+
var DailyControlLightMirror = DailyControlLightEnum.or(z130.string());
|
|
31175
|
+
var DailyControlSourceMirror = DailyControlSourceEnum.or(z130.string());
|
|
31176
|
+
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z130.string());
|
|
31177
|
+
var DailyControlDayMirror = z130.object({
|
|
31178
|
+
date: z130.string(),
|
|
31179
|
+
returnedOrders: z130.number(),
|
|
30997
31180
|
returnedSource: DailyControlSourceMirror,
|
|
30998
31181
|
cancelledSource: DailyControlSourceMirror,
|
|
30999
|
-
hasEstimates:
|
|
31182
|
+
hasEstimates: z130.boolean(),
|
|
31000
31183
|
light: DailyControlLightMirror
|
|
31001
31184
|
}).passthrough();
|
|
31002
|
-
var DailyControlProductMirror =
|
|
31003
|
-
projectId:
|
|
31004
|
-
productName:
|
|
31185
|
+
var DailyControlProductMirror = z130.object({
|
|
31186
|
+
projectId: z130.string().uuid(),
|
|
31187
|
+
productName: z130.string().nullable(),
|
|
31005
31188
|
status: DailyControlStatusMirror,
|
|
31006
|
-
statusMessage:
|
|
31007
|
-
days:
|
|
31189
|
+
statusMessage: z130.string().nullable(),
|
|
31190
|
+
days: z130.array(DailyControlDayMirror),
|
|
31008
31191
|
verdict: DailyControlVerdictMirror.nullable(),
|
|
31009
|
-
rationale:
|
|
31192
|
+
rationale: z130.string().nullable()
|
|
31010
31193
|
}).passthrough();
|
|
31011
|
-
var DailyControlResponseMirror =
|
|
31012
|
-
since:
|
|
31013
|
-
until:
|
|
31014
|
-
products:
|
|
31015
|
-
archivedProjectSpend:
|
|
31194
|
+
var DailyControlResponseMirror = z130.object({
|
|
31195
|
+
since: z130.string(),
|
|
31196
|
+
until: z130.string(),
|
|
31197
|
+
products: z130.array(DailyControlProductMirror),
|
|
31198
|
+
archivedProjectSpend: z130.array(z130.unknown())
|
|
31016
31199
|
}).passthrough();
|
|
31017
31200
|
var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
|
|
31018
31201
|
function withWarnings(response) {
|
|
@@ -31087,7 +31270,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
|
|
|
31087
31270
|
// src/tools/product-control.ts
|
|
31088
31271
|
import { readFile, stat } from "fs/promises";
|
|
31089
31272
|
import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
|
|
31090
|
-
import { z as
|
|
31273
|
+
import { z as z131 } from "zod";
|
|
31091
31274
|
var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
|
|
31092
31275
|
var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
|
|
31093
31276
|
var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
|
|
@@ -31100,36 +31283,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
|
|
|
31100
31283
|
var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
|
|
31101
31284
|
var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
|
|
31102
31285
|
var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
|
|
31103
|
-
var DateOnly2 =
|
|
31286
|
+
var DateOnly2 = z131.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
31104
31287
|
var IMPORT_BATCH_MAX2 = 50;
|
|
31105
|
-
var ProductControlListInput =
|
|
31106
|
-
days:
|
|
31288
|
+
var ProductControlListInput = z131.object({
|
|
31289
|
+
days: z131.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
31107
31290
|
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."),
|
|
31108
|
-
shopDomain:
|
|
31291
|
+
shopDomain: z131.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
31109
31292
|
}).strict();
|
|
31110
|
-
var ImportableProductsInput =
|
|
31111
|
-
q:
|
|
31112
|
-
after:
|
|
31113
|
-
shopDomain:
|
|
31293
|
+
var ImportableProductsInput = z131.object({
|
|
31294
|
+
q: z131.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
|
|
31295
|
+
after: z131.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
|
|
31296
|
+
shopDomain: z131.string().min(1).optional()
|
|
31114
31297
|
}).strict();
|
|
31115
|
-
var ImportProductControlsInput =
|
|
31116
|
-
shopifyProductIds:
|
|
31298
|
+
var ImportProductControlsInput = z131.object({
|
|
31299
|
+
shopifyProductIds: z131.array(z131.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."),
|
|
31117
31300
|
// Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
|
|
31118
31301
|
// sin decir a cuál archivaría el producto bajo la tienda equivocada.
|
|
31119
|
-
shopDomain:
|
|
31302
|
+
shopDomain: z131.string().min(1)
|
|
31120
31303
|
}).strict();
|
|
31121
|
-
var SetProductCostingInput =
|
|
31122
|
-
shopDomain:
|
|
31123
|
-
shopifyProductId:
|
|
31124
|
-
targetCountry:
|
|
31125
|
-
supplierCost:
|
|
31126
|
-
shippingCost:
|
|
31127
|
-
returnRate:
|
|
31128
|
-
cancellationRate:
|
|
31304
|
+
var SetProductCostingInput = z131.object({
|
|
31305
|
+
shopDomain: z131.string().min(1),
|
|
31306
|
+
shopifyProductId: z131.string().min(1).max(64),
|
|
31307
|
+
targetCountry: z131.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
|
|
31308
|
+
supplierCost: z131.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
|
|
31309
|
+
shippingCost: z131.number().finite().nonnegative(),
|
|
31310
|
+
returnRate: z131.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
|
|
31311
|
+
cancellationRate: z131.number().finite().min(0).lt(1)
|
|
31129
31312
|
}).strict();
|
|
31130
|
-
var Count =
|
|
31131
|
-
var ReportProductCountsInput =
|
|
31132
|
-
productControlId:
|
|
31313
|
+
var Count = z131.number().int().min(0).max(1e5).nullable().optional();
|
|
31314
|
+
var ReportProductCountsInput = z131.object({
|
|
31315
|
+
productControlId: z131.string().uuid().describe("El identificador que devuelve get_product_control."),
|
|
31133
31316
|
date: DateOnly2,
|
|
31134
31317
|
orders: Count.describe("Pedidos que entraron ese d\xEDa."),
|
|
31135
31318
|
cancelledOrders: Count,
|
|
@@ -31139,36 +31322,36 @@ var ReportProductCountsInput = z130.object({
|
|
|
31139
31322
|
}).strict();
|
|
31140
31323
|
var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
|
|
31141
31324
|
var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
|
|
31142
|
-
var ImportOrdersFileInput =
|
|
31325
|
+
var ImportOrdersFileInput = z131.object({
|
|
31143
31326
|
/** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
|
|
31144
|
-
path:
|
|
31145
|
-
operationId:
|
|
31327
|
+
path: z131.string().min(1),
|
|
31328
|
+
operationId: z131.string().uuid().optional(),
|
|
31146
31329
|
/** Solo mirar: devuelve el resumen y no escribe nada. */
|
|
31147
|
-
dryRun:
|
|
31330
|
+
dryRun: z131.boolean().optional()
|
|
31148
31331
|
}).strict();
|
|
31149
|
-
var CreateOperationInput =
|
|
31150
|
-
countryCode:
|
|
31151
|
-
label:
|
|
31332
|
+
var CreateOperationInput = z131.object({
|
|
31333
|
+
countryCode: z131.string().length(2),
|
|
31334
|
+
label: z131.string().trim().min(1).max(60).optional()
|
|
31152
31335
|
}).strict();
|
|
31153
|
-
var MergeProductsInput =
|
|
31154
|
-
sourceId:
|
|
31155
|
-
targetId:
|
|
31336
|
+
var MergeProductsInput = z131.object({
|
|
31337
|
+
sourceId: z131.string().uuid(),
|
|
31338
|
+
targetId: z131.string().uuid()
|
|
31156
31339
|
}).strict();
|
|
31157
|
-
var SetMonthlyExpenseInput =
|
|
31158
|
-
month:
|
|
31340
|
+
var SetMonthlyExpenseInput = z131.object({
|
|
31341
|
+
month: z131.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
31159
31342
|
label: SaveMonthlyExpenseSchema.shape.label,
|
|
31160
|
-
amount:
|
|
31161
|
-
operationId:
|
|
31343
|
+
amount: z131.number().finite().min(0),
|
|
31344
|
+
operationId: z131.string().uuid().optional()
|
|
31162
31345
|
}).strict();
|
|
31163
|
-
var SetAdSpendInput =
|
|
31164
|
-
month:
|
|
31165
|
-
operationId:
|
|
31346
|
+
var SetAdSpendInput = z131.object({
|
|
31347
|
+
month: z131.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
31348
|
+
operationId: z131.string().uuid().optional(),
|
|
31166
31349
|
/** null RETIRA la corrección; cero afirma que no pautó. */
|
|
31167
|
-
amount:
|
|
31350
|
+
amount: z131.number().finite().min(0).nullable()
|
|
31168
31351
|
}).strict();
|
|
31169
|
-
var GetFinancesInput =
|
|
31170
|
-
month:
|
|
31171
|
-
operationId:
|
|
31352
|
+
var GetFinancesInput = z131.object({
|
|
31353
|
+
month: z131.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."),
|
|
31354
|
+
operationId: z131.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
|
|
31172
31355
|
}).strict();
|
|
31173
31356
|
function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
31174
31357
|
server.registerTool("get_product_control", {
|
|
@@ -31360,28 +31543,28 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
|
31360
31543
|
__name(registerProductControlTools, "registerProductControlTools");
|
|
31361
31544
|
|
|
31362
31545
|
// src/tools/market-study-estimate.ts
|
|
31363
|
-
import { z as
|
|
31546
|
+
import { z as z132 } from "zod";
|
|
31364
31547
|
var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
|
|
31365
|
-
var ProductTaskOutputEnum =
|
|
31548
|
+
var ProductTaskOutputEnum = z132.enum([
|
|
31366
31549
|
"landing",
|
|
31367
31550
|
"video",
|
|
31368
31551
|
"image"
|
|
31369
31552
|
]);
|
|
31370
|
-
var EstimateMarketStudyInput =
|
|
31371
|
-
kind:
|
|
31553
|
+
var EstimateMarketStudyInput = z132.object({
|
|
31554
|
+
kind: z132.enum([
|
|
31372
31555
|
"video",
|
|
31373
31556
|
"product_task"
|
|
31374
31557
|
]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
|
|
31375
|
-
videoAngleCount:
|
|
31376
|
-
durationSeconds:
|
|
31558
|
+
videoAngleCount: z132.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
|
|
31559
|
+
durationSeconds: z132.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
|
|
31377
31560
|
videoStructure: VideoStructureEnum.default("single_take"),
|
|
31378
31561
|
videoQuality: VideoQualityEnum.default("economy"),
|
|
31379
31562
|
videoResolution: VideoResolutionEnum.default("480p"),
|
|
31380
|
-
productImageCount:
|
|
31563
|
+
productImageCount: z132.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
|
|
31381
31564
|
outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
|
|
31382
|
-
generateAiMusic:
|
|
31565
|
+
generateAiMusic: z132.boolean().optional(),
|
|
31383
31566
|
generateAiEdit: AiEditRequestSchema.optional(),
|
|
31384
|
-
replicateWinnerWhenFound:
|
|
31567
|
+
replicateWinnerWhenFound: z132.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.")
|
|
31385
31568
|
}).strict();
|
|
31386
31569
|
function buildMarketStudyEstimateRequests(input) {
|
|
31387
31570
|
const quotesVideo = input.kind === "video" || (input.outputs ?? [
|