@productmaker/mcp 8.11.2 → 8.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/http.js +759 -682
- package/dist/stdio.js +748 -671
- package/package.json +1 -1
package/dist/stdio.js
CHANGED
|
@@ -173,6 +173,14 @@ var FrankensteinSourceUploadPresignResponseSchema = z2.object({
|
|
|
173
173
|
|
|
174
174
|
// ../../packages/types/src/product-context-limits.ts
|
|
175
175
|
var PRODUCT_CONTEXT_MAX_CHARS = 3e3;
|
|
176
|
+
function canonicalizeLineBreaks(value) {
|
|
177
|
+
return value.replace(/\r\n?/g, "\n");
|
|
178
|
+
}
|
|
179
|
+
__name(canonicalizeLineBreaks, "canonicalizeLineBreaks");
|
|
180
|
+
function canonicalizeProductContext(value) {
|
|
181
|
+
return canonicalizeLineBreaks(value).trim();
|
|
182
|
+
}
|
|
183
|
+
__name(canonicalizeProductContext, "canonicalizeProductContext");
|
|
176
184
|
|
|
177
185
|
// ../../packages/types/src/video-creation.ts
|
|
178
186
|
var VideoCreationAspectRatio = z3.enum([
|
|
@@ -204,7 +212,7 @@ var FrankensteinVideoRequestBaseSchema = z3.object({
|
|
|
204
212
|
generateAiMusic: z3.boolean().default(false),
|
|
205
213
|
title: z3.string().trim().min(1).max(300).optional(),
|
|
206
214
|
primaryAngle: z3.string().trim().max(500).optional(),
|
|
207
|
-
productContext: z3.string().
|
|
215
|
+
productContext: z3.string().transform(canonicalizeProductContext).pipe(z3.string().max(PRODUCT_CONTEXT_MAX_CHARS)).optional(),
|
|
208
216
|
productLabel: z3.string().trim().max(120).optional(),
|
|
209
217
|
buyerPersona: z3.string().trim().max(500).optional(),
|
|
210
218
|
cta: z3.string().trim().max(300).optional(),
|
|
@@ -4274,7 +4282,7 @@ var IngestOptions = z22.object({
|
|
|
4274
4282
|
* per task. Length only, never `.uuid()` — Actor.id is a CUID. */
|
|
4275
4283
|
actorId: z22.string().min(1).max(120).optional(),
|
|
4276
4284
|
isCombo: z22.boolean().default(false),
|
|
4277
|
-
productContext: z22.string().transform(
|
|
4285
|
+
productContext: z22.string().transform(canonicalizeProductContext).pipe(z22.string().max(PRODUCT_CONTEXT_MAX_CHARS)).optional(),
|
|
4278
4286
|
creativeDirection: z22.string().transform((value) => value.trim()).pipe(z22.string().max(500)).optional(),
|
|
4279
4287
|
/** Exact copy the user pinned. Rendered VERBATIM on the image creatives this task
|
|
4280
4288
|
* produces and on the landing hero — never on video, which steers via scriptNotes.
|
|
@@ -5835,7 +5843,12 @@ var ShopifyPublishErrorResponse = z29.discriminatedUnion("code", [
|
|
|
5835
5843
|
* variants, another app rewrote the product, landing too large).
|
|
5836
5844
|
* `message` carries the seller's next step; never a 500.
|
|
5837
5845
|
*/
|
|
5838
|
-
"SHOPIFY_PUBLISH_VERIFICATION_FAILED"
|
|
5846
|
+
"SHOPIFY_PUBLISH_VERIFICATION_FAILED",
|
|
5847
|
+
/**
|
|
5848
|
+
* The seller's store is frozen/paused/closed on Shopify's side (402/423
|
|
5849
|
+
* "Unavailable Shop"). 409; `message` says to reactivate it in Shopify.
|
|
5850
|
+
*/
|
|
5851
|
+
"SHOPIFY_SHOP_UNAVAILABLE"
|
|
5839
5852
|
]),
|
|
5840
5853
|
message: z29.string().optional(),
|
|
5841
5854
|
authUrl: z29.string().url().optional(),
|
|
@@ -12106,7 +12119,11 @@ var VideoRegenerationEngineSchema = z58.enum([
|
|
|
12106
12119
|
"free_text",
|
|
12107
12120
|
"free_image",
|
|
12108
12121
|
"single_call",
|
|
12109
|
-
"multi_shot"
|
|
12122
|
+
"multi_shot",
|
|
12123
|
+
// Voice-only script edit: TTS of the new script in the video's own voice,
|
|
12124
|
+
// muxed over the delivered video. Only for voiceover-only renders (no shot
|
|
12125
|
+
// with on-camera lipsync), so no frame is regenerated.
|
|
12126
|
+
"voiceover"
|
|
12110
12127
|
]);
|
|
12111
12128
|
var VideoRegenerationRouteFingerprintSchema = z58.string().trim().min(1).max(128);
|
|
12112
12129
|
var RegenerateEditRequestSchema = z58.object({
|
|
@@ -14304,6 +14321,8 @@ var ProductControlDailyCountsSchema = z69.object({
|
|
|
14304
14321
|
var ProductControlRowSchema = z69.object({
|
|
14305
14322
|
/** `null` hasta que la vendedora toca el producto por primera vez. */
|
|
14306
14323
|
productControlId: z69.string().nullable(),
|
|
14324
|
+
/** La operación a la que pertenece; opcional para payloads anteriores. */
|
|
14325
|
+
operationId: z69.string().nullable().optional(),
|
|
14307
14326
|
shopId: z69.string(),
|
|
14308
14327
|
shopDomain: z69.string(),
|
|
14309
14328
|
/** Nulo cuando el producto NO vive en Shopify: importado del archivo de un
|
|
@@ -14500,9 +14519,7 @@ var SaveProductCatalogSchema = z69.object({
|
|
|
14500
14519
|
"tiktok"
|
|
14501
14520
|
]).nullable().optional()
|
|
14502
14521
|
}).strict();
|
|
14503
|
-
var
|
|
14504
|
-
shopDomain: z69.string().min(1),
|
|
14505
|
-
shopifyProductId: z69.string().min(1),
|
|
14522
|
+
var ProductControlCampaignFieldsSchema = z69.object({
|
|
14506
14523
|
provider: z69.enum([
|
|
14507
14524
|
"meta",
|
|
14508
14525
|
"tiktok"
|
|
@@ -14510,6 +14527,15 @@ var LinkProductControlCampaignSchema = z69.object({
|
|
|
14510
14527
|
accountId: z69.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/),
|
|
14511
14528
|
campaignId: z69.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/)
|
|
14512
14529
|
}).strict();
|
|
14530
|
+
var LinkProductControlCampaignSchema = z69.union([
|
|
14531
|
+
ProductControlCampaignFieldsSchema.extend({
|
|
14532
|
+
productControlId: z69.string().uuid()
|
|
14533
|
+
}).strict(),
|
|
14534
|
+
ProductControlCampaignFieldsSchema.extend({
|
|
14535
|
+
shopDomain: z69.string().min(1),
|
|
14536
|
+
shopifyProductId: z69.string().min(1)
|
|
14537
|
+
}).strict()
|
|
14538
|
+
]);
|
|
14513
14539
|
var ReportProductControlReturnsSchema = z69.object({
|
|
14514
14540
|
returnedOrders: z69.number().int().min(0).max(1e5),
|
|
14515
14541
|
note: z69.string().trim().max(280).optional()
|
|
@@ -17552,6 +17578,53 @@ var RegenerateVideoScriptCapabilityRequest = z79.object({
|
|
|
17552
17578
|
]).optional().describe("Elecci\xF3n expl\xEDcita del usuario: market usa el estudio de mercado disponible; guided usa la narrativa elegida. Omitir conserva el comportamiento existente.")
|
|
17553
17579
|
}).strict();
|
|
17554
17580
|
|
|
17581
|
+
// ../../packages/types/src/dropi-financial.ts
|
|
17582
|
+
import { z as z80 } from "zod";
|
|
17583
|
+
var ConnectDropiFinancialSchema = z80.object({
|
|
17584
|
+
integrationKey: z80.string().trim().min(1).max(4096).regex(/^[\x21-\x7e]+$/)
|
|
17585
|
+
}).strict();
|
|
17586
|
+
var SyncDropiFinancialSchema = z80.object({
|
|
17587
|
+
operationId: z80.string().uuid().optional(),
|
|
17588
|
+
since: z80.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
|
|
17589
|
+
until: z80.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional()
|
|
17590
|
+
}).strict();
|
|
17591
|
+
var DropiFinancialStatusSchema = z80.object({
|
|
17592
|
+
enabled: z80.boolean(),
|
|
17593
|
+
connected: z80.boolean(),
|
|
17594
|
+
countryCode: z80.literal("CO"),
|
|
17595
|
+
environment: z80.enum([
|
|
17596
|
+
"sandbox",
|
|
17597
|
+
"production"
|
|
17598
|
+
]),
|
|
17599
|
+
lastSyncAt: z80.string().nullable(),
|
|
17600
|
+
lastError: z80.string().nullable(),
|
|
17601
|
+
historyNext: z80.string().nullable(),
|
|
17602
|
+
historyUntil: z80.string().nullable(),
|
|
17603
|
+
changesThrough: z80.string().nullable(),
|
|
17604
|
+
manualNext: z80.string().nullable(),
|
|
17605
|
+
manual: z80.object({
|
|
17606
|
+
since: z80.string(),
|
|
17607
|
+
until: z80.string(),
|
|
17608
|
+
next: z80.string().nullable()
|
|
17609
|
+
}).nullable(),
|
|
17610
|
+
retentionSince: z80.string()
|
|
17611
|
+
});
|
|
17612
|
+
var DropiFinancialSyncResultSchema = z80.object({
|
|
17613
|
+
orders: z80.number().int().nonnegative(),
|
|
17614
|
+
written: z80.number().int().nonnegative(),
|
|
17615
|
+
updated: z80.number().int().nonnegative(),
|
|
17616
|
+
pending: z80.boolean(),
|
|
17617
|
+
next: z80.string().nullable(),
|
|
17618
|
+
historyNext: z80.string().nullable(),
|
|
17619
|
+
changesThrough: z80.string().nullable(),
|
|
17620
|
+
since: z80.string(),
|
|
17621
|
+
until: z80.string(),
|
|
17622
|
+
unmatched: z80.array(z80.object({
|
|
17623
|
+
externalProductId: z80.string(),
|
|
17624
|
+
orders: z80.number().int().nonnegative()
|
|
17625
|
+
}))
|
|
17626
|
+
});
|
|
17627
|
+
|
|
17555
17628
|
// src/response-body.ts
|
|
17556
17629
|
var ResponseBodyTooLargeError = class extends Error {
|
|
17557
17630
|
static {
|
|
@@ -17794,7 +17867,7 @@ var ApiClient = class {
|
|
|
17794
17867
|
};
|
|
17795
17868
|
|
|
17796
17869
|
// src/index.ts
|
|
17797
|
-
var MCP_VERSION = "8.11.
|
|
17870
|
+
var MCP_VERSION = "8.11.4";
|
|
17798
17871
|
|
|
17799
17872
|
// src/meta-upload-app.ts
|
|
17800
17873
|
import { readFileSync } from "fs";
|
|
@@ -17866,7 +17939,7 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
|
|
|
17866
17939
|
__name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
|
|
17867
17940
|
|
|
17868
17941
|
// src/tools/tasks.ts
|
|
17869
|
-
import { z as
|
|
17942
|
+
import { z as z85 } from "zod";
|
|
17870
17943
|
|
|
17871
17944
|
// src/resolve-image.ts
|
|
17872
17945
|
import { lookup as dnsLookup } from "dns/promises";
|
|
@@ -18427,9 +18500,9 @@ async function resolveMediaRef(ref, opts) {
|
|
|
18427
18500
|
__name(resolveMediaRef, "resolveMediaRef");
|
|
18428
18501
|
|
|
18429
18502
|
// src/tools/shared.ts
|
|
18430
|
-
import { z as
|
|
18431
|
-
var Lang =
|
|
18432
|
-
var Country =
|
|
18503
|
+
import { z as z81 } from "zod";
|
|
18504
|
+
var Lang = z81.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);
|
|
18505
|
+
var Country = z81.string().min(2).max(3);
|
|
18433
18506
|
var LandingStrategyEnum = LandingStrategySchema;
|
|
18434
18507
|
var LandingImageFormatEnum = LandingImageFormatSchema;
|
|
18435
18508
|
var VideoPresetEnum = VideoPreset.extract([
|
|
@@ -18533,7 +18606,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
|
|
|
18533
18606
|
return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
|
|
18534
18607
|
}
|
|
18535
18608
|
__name(animationStyleApplies, "animationStyleApplies");
|
|
18536
|
-
var VideoTierEnum =
|
|
18609
|
+
var VideoTierEnum = z81.enum([
|
|
18537
18610
|
"basic"
|
|
18538
18611
|
]);
|
|
18539
18612
|
function resolveVideoTier(_tier) {
|
|
@@ -18591,10 +18664,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
|
|
|
18591
18664
|
var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
|
|
18592
18665
|
var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
|
|
18593
18666
|
var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
|
|
18594
|
-
var ImageRefSchema =
|
|
18595
|
-
url:
|
|
18596
|
-
path:
|
|
18597
|
-
assetId:
|
|
18667
|
+
var ImageRefSchema = z81.object({
|
|
18668
|
+
url: z81.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.'),
|
|
18669
|
+
path: z81.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`.'),
|
|
18670
|
+
assetId: z81.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.")
|
|
18598
18671
|
}).refine((v) => [
|
|
18599
18672
|
v.url,
|
|
18600
18673
|
v.path,
|
|
@@ -18602,11 +18675,11 @@ var ImageRefSchema = z80.object({
|
|
|
18602
18675
|
].filter(Boolean).length === 1, {
|
|
18603
18676
|
message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
|
|
18604
18677
|
});
|
|
18605
|
-
var ImagesInput =
|
|
18678
|
+
var ImagesInput = z81.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
|
|
18606
18679
|
const assetCount = images.filter((image) => Boolean(image.assetId)).length;
|
|
18607
18680
|
if (assetCount > 0 && assetCount !== images.length) {
|
|
18608
18681
|
ctx.addIssue({
|
|
18609
|
-
code:
|
|
18682
|
+
code: z81.ZodIssueCode.custom,
|
|
18610
18683
|
message: "all image entries must use assetId, or all must use URL/path sources"
|
|
18611
18684
|
});
|
|
18612
18685
|
}
|
|
@@ -18679,14 +18752,14 @@ async function submitCreative(api, opts) {
|
|
|
18679
18752
|
});
|
|
18680
18753
|
}
|
|
18681
18754
|
__name(submitCreative, "submitCreative");
|
|
18682
|
-
var ResearchTargetCountryEnum =
|
|
18755
|
+
var ResearchTargetCountryEnum = z81.enum([
|
|
18683
18756
|
"CO",
|
|
18684
18757
|
"MX",
|
|
18685
18758
|
"PE",
|
|
18686
18759
|
"EC",
|
|
18687
18760
|
"CL"
|
|
18688
18761
|
]);
|
|
18689
|
-
var ResearchCategoryEnum =
|
|
18762
|
+
var ResearchCategoryEnum = z81.enum([
|
|
18690
18763
|
"auto",
|
|
18691
18764
|
"automotive",
|
|
18692
18765
|
"kitchen",
|
|
@@ -18823,6 +18896,7 @@ var McpErrorCode = {
|
|
|
18823
18896
|
SHOPIFY_SCOPE_UPGRADE_REQUIRED: "SHOPIFY_SCOPE_UPGRADE_REQUIRED",
|
|
18824
18897
|
SHOPIFY_PUBLISH_FAILED: "SHOPIFY_PUBLISH_FAILED",
|
|
18825
18898
|
SHOPIFY_NO_PUBLISHED_THEME: "SHOPIFY_NO_PUBLISHED_THEME",
|
|
18899
|
+
SHOPIFY_SHOP_UNAVAILABLE: "SHOPIFY_SHOP_UNAVAILABLE",
|
|
18826
18900
|
SHOPIFY_THEME_STRUCTURE_UNSUPPORTED: "SHOPIFY_THEME_STRUCTURE_UNSUPPORTED",
|
|
18827
18901
|
SHOPIFY_PUBLISH_INPUT_REQUIRED: "SHOPIFY_PUBLISH_INPUT_REQUIRED",
|
|
18828
18902
|
SHOPIFY_PUBLISH_CONTEXT_CHANGED: "SHOPIFY_PUBLISH_CONTEXT_CHANGED",
|
|
@@ -18905,6 +18979,7 @@ var CODE_MESSAGES = {
|
|
|
18905
18979
|
SHOPIFY_PUBLISH_VERIFICATION_FAILED: "Shopify did not keep what the publish wrote (offer variants, template or inventory), or the landing is too large. Read the error's reason to the user; retry the publish once, and if it repeats follow the step in the reason (map packs to existing variants, check apps that edit products, or trim the landing in the editor).",
|
|
18906
18980
|
SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE: "The selected Shopify product cannot carry the confirmed offer (missing quantity options/prices) or no longer exists. Read the error's message to the user, then retry with publicationMode:'new' to create a fresh product, or ask the user to pick a different existing product.",
|
|
18907
18981
|
SHOPIFY_THEME_SETUP_REQUIRED: "The store's Shopify theme is missing the ProductMaker 'Code Landing' app block \u2014 publishing now would create a product whose page renders blank. Send the user the themeEditorDeepLink (in error data) to open the Shopify theme editor, have them confirm the Code Landing block is added and press Save, then retry publishing. This is a one-time step per store; nothing was published.",
|
|
18982
|
+
SHOPIFY_SHOP_UNAVAILABLE: "The user's Shopify store is unavailable (frozen, paused or closed on Shopify's side), so nothing was published. Ask the user to reactivate the store in Shopify (usually by settling the plan/billing) or reconnect it at https://productmaker.app/integrations, then retry. Retrying before that will fail the same way.",
|
|
18908
18983
|
SHOPIFY_NO_PUBLISHED_THEME: "The Shopify store has no published theme, so there is nowhere to place the landing. Ask the user to publish a theme (Online Store > Themes > Publish) and retry.",
|
|
18909
18984
|
SHOPIFY_THEME_STRUCTURE_UNSUPPORTED: "The active Shopify theme contains an HTML structure ProductMaker cannot process safely. Ask the user to restore a valid layout/theme.liquid or contact ProductMaker support to correct the theme, then retry.",
|
|
18910
18985
|
// Meta — high-frequency
|
|
@@ -19096,6 +19171,7 @@ var INVALID_PARAM_CODES = /* @__PURE__ */ new Set([
|
|
|
19096
19171
|
McpErrorCode.SHOPIFY_SCOPE_UPGRADE_REQUIRED,
|
|
19097
19172
|
McpErrorCode.SHOPIFY_NOT_CONNECTED,
|
|
19098
19173
|
McpErrorCode.SHOPIFY_NO_PUBLISHED_THEME,
|
|
19174
|
+
McpErrorCode.SHOPIFY_SHOP_UNAVAILABLE,
|
|
19099
19175
|
McpErrorCode.SHOPIFY_THEME_STRUCTURE_UNSUPPORTED,
|
|
19100
19176
|
McpErrorCode.SHOPIFY_PUBLISH_INPUT_REQUIRED,
|
|
19101
19177
|
McpErrorCode.SHOPIFY_PUBLISH_CONTEXT_CHANGED,
|
|
@@ -19138,6 +19214,7 @@ var PASSTHROUGH_CODES = /* @__PURE__ */ new Set([
|
|
|
19138
19214
|
McpErrorCode.SHOPIFY_SCOPE_UPGRADE_REQUIRED,
|
|
19139
19215
|
McpErrorCode.SHOPIFY_PUBLISH_FAILED,
|
|
19140
19216
|
McpErrorCode.SHOPIFY_NO_PUBLISHED_THEME,
|
|
19217
|
+
McpErrorCode.SHOPIFY_SHOP_UNAVAILABLE,
|
|
19141
19218
|
McpErrorCode.SHOPIFY_THEME_STRUCTURE_UNSUPPORTED,
|
|
19142
19219
|
// Meta
|
|
19143
19220
|
McpErrorCode.META_NO_FB_PAGE,
|
|
@@ -19905,29 +19982,29 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
|
|
|
19905
19982
|
__name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
|
|
19906
19983
|
|
|
19907
19984
|
// src/tools/media-presentation.ts
|
|
19908
|
-
import { z as
|
|
19909
|
-
var HttpsPresentationUrlSchema =
|
|
19985
|
+
import { z as z82 } from "zod";
|
|
19986
|
+
var HttpsPresentationUrlSchema = z82.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
|
|
19910
19987
|
var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
|
|
19911
19988
|
const hostname = new URL(value).hostname.toLowerCase();
|
|
19912
19989
|
return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
|
|
19913
19990
|
}, "preview URL must be owned by ProductMaker");
|
|
19914
|
-
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) =>
|
|
19915
|
-
var PresentationImageSchema =
|
|
19916
|
-
kind:
|
|
19991
|
+
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z82.number().int().positive().max(maximum), "positiveIntAtMost");
|
|
19992
|
+
var PresentationImageSchema = z82.object({
|
|
19993
|
+
kind: z82.literal("image"),
|
|
19917
19994
|
url: HttpsPresentationUrlSchema,
|
|
19918
|
-
mimeType:
|
|
19995
|
+
mimeType: z82.enum([
|
|
19919
19996
|
"image/jpeg",
|
|
19920
19997
|
"image/png"
|
|
19921
19998
|
]),
|
|
19922
19999
|
byteSize: positiveIntAtMost(5 * 1024 * 1024),
|
|
19923
20000
|
width: positiveIntAtMost(16384),
|
|
19924
20001
|
height: positiveIntAtMost(16384),
|
|
19925
|
-
alt:
|
|
20002
|
+
alt: z82.string().trim().min(1).max(240)
|
|
19926
20003
|
}).strict();
|
|
19927
20004
|
var McpMediaPresentationSchema = PresentationImageSchema;
|
|
19928
|
-
var GalleryImageSchema =
|
|
20005
|
+
var GalleryImageSchema = z82.object({
|
|
19929
20006
|
url: ProductMakerPreviewUrlSchema,
|
|
19930
|
-
alt:
|
|
20007
|
+
alt: z82.string().trim().min(1).max(240)
|
|
19931
20008
|
});
|
|
19932
20009
|
var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
19933
20010
|
async function imageBlocks(image, transport) {
|
|
@@ -20048,7 +20125,7 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
|
|
|
20048
20125
|
__name(buildMcpImageGalleryContent, "buildMcpImageGalleryContent");
|
|
20049
20126
|
|
|
20050
20127
|
// src/tools/animated-video.ts
|
|
20051
|
-
import { z as
|
|
20128
|
+
import { z as z83 } from "zod";
|
|
20052
20129
|
|
|
20053
20130
|
// src/tools/paid-confirmation.ts
|
|
20054
20131
|
function describeMarketStudyChoice(enabled) {
|
|
@@ -20261,44 +20338,44 @@ function describeAnimatedVideoPrices() {
|
|
|
20261
20338
|
return MOTION_GRAPHICS_DURATIONS.map((d) => `${d} s = ${creditsFor(d)} cr\xE9ditos (US$${usdFor(d)})`).join(", ");
|
|
20262
20339
|
}
|
|
20263
20340
|
__name(describeAnimatedVideoPrices, "describeAnimatedVideoPrices");
|
|
20264
|
-
var DurationInput =
|
|
20265
|
-
var CreateAnimatedVideoInput =
|
|
20341
|
+
var DurationInput = z83.union(MOTION_GRAPHICS_DURATIONS.map((d) => z83.literal(d)));
|
|
20342
|
+
var CreateAnimatedVideoInput = z83.object({
|
|
20266
20343
|
// Plain text, not `.url()`: users type «cal.com», and the web accepts it.
|
|
20267
20344
|
// normalizeWebAddress (shared with the web) adds https:// and refuses
|
|
20268
20345
|
// anything that is not a public http(s) address.
|
|
20269
|
-
landingUrl:
|
|
20346
|
+
landingUrl: z83.string().trim().min(1).describe("Enlace p\xFAblico de la p\xE1gina del servicio, como lo dio el usuario (\xABcal.com\xBB o \xABhttps://cal.com\xBB). El video sale de lo que muestra esa p\xE1gina: su marca, colores y mensajes."),
|
|
20270
20347
|
format: MotionGraphicsFormatSchema.describe('Formato: "vertical" (9:16, Reels/TikTok), "square" (1:1, feed) u "horizontal" (16:9, YouTube/web). Si el usuario no lo dijo, PREG\xDANTALE.'),
|
|
20271
20348
|
durationSec: DurationInput.describe(`Duraci\xF3n en segundos: ${MOTION_GRAPHICS_DURATIONS.join(", ")}. Fija el precio (ver la descripci\xF3n de la herramienta). Si el usuario no la dijo, PREG\xDANTALE.`),
|
|
20272
20349
|
language: MotionGraphicsLanguageSchema.describe('Idioma de los textos del video: "es", "en" o "pt".'),
|
|
20273
|
-
notes:
|
|
20350
|
+
notes: z83.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).")
|
|
20274
20351
|
}).strict();
|
|
20275
20352
|
var FORMAT_LABELS = {
|
|
20276
20353
|
vertical: "vertical 9:16",
|
|
20277
20354
|
square: "cuadrado 1:1",
|
|
20278
20355
|
horizontal: "horizontal 16:9"
|
|
20279
20356
|
};
|
|
20280
|
-
var AnimatedVideoResultSchema =
|
|
20281
|
-
status:
|
|
20357
|
+
var AnimatedVideoResultSchema = z83.object({
|
|
20358
|
+
status: z83.enum([
|
|
20282
20359
|
"pending",
|
|
20283
20360
|
"done",
|
|
20284
20361
|
"error"
|
|
20285
20362
|
]),
|
|
20286
|
-
serviceMode:
|
|
20287
|
-
finalMp4Url:
|
|
20288
|
-
error:
|
|
20289
|
-
motionGraphics:
|
|
20363
|
+
serviceMode: z83.literal("motion_graphics"),
|
|
20364
|
+
finalMp4Url: z83.string().optional(),
|
|
20365
|
+
error: z83.string().optional(),
|
|
20366
|
+
motionGraphics: z83.object({
|
|
20290
20367
|
stage: MotionGraphicsStageSchema,
|
|
20291
20368
|
format: MotionGraphicsFormatSchema,
|
|
20292
|
-
durationSec:
|
|
20293
|
-
width:
|
|
20294
|
-
height:
|
|
20369
|
+
durationSec: z83.number(),
|
|
20370
|
+
width: z83.number().optional(),
|
|
20371
|
+
height: z83.number().optional(),
|
|
20295
20372
|
language: MotionGraphicsLanguageSchema.optional(),
|
|
20296
|
-
queuedAt:
|
|
20297
|
-
jobsAhead:
|
|
20298
|
-
stageStartedAt:
|
|
20299
|
-
renderProgress:
|
|
20300
|
-
activity:
|
|
20301
|
-
previewUrl:
|
|
20373
|
+
queuedAt: z83.string().optional(),
|
|
20374
|
+
jobsAhead: z83.number().int().nonnegative().optional(),
|
|
20375
|
+
stageStartedAt: z83.string().optional(),
|
|
20376
|
+
renderProgress: z83.number().optional(),
|
|
20377
|
+
activity: z83.array(MotionGraphicsActivitySchema).optional().catch(void 0),
|
|
20378
|
+
previewUrl: z83.string().optional()
|
|
20302
20379
|
}).passthrough()
|
|
20303
20380
|
}).passthrough();
|
|
20304
20381
|
function parseAnimatedVideoResult(value) {
|
|
@@ -20460,10 +20537,10 @@ function registerAnimatedVideoTools(server, api) {
|
|
|
20460
20537
|
__name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
|
|
20461
20538
|
|
|
20462
20539
|
// src/tools/winning-product-image.ts
|
|
20463
|
-
import { z as
|
|
20464
|
-
var WinnerReferenceInput =
|
|
20465
|
-
runId:
|
|
20466
|
-
candidateSourceId:
|
|
20540
|
+
import { z as z84 } from "zod";
|
|
20541
|
+
var WinnerReferenceInput = z84.object({
|
|
20542
|
+
runId: z84.string().uuid(),
|
|
20543
|
+
candidateSourceId: z84.string().trim().min(1).max(160)
|
|
20467
20544
|
}).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
|
|
20468
20545
|
async function resolveWinnerImages(api, winnerReference, images) {
|
|
20469
20546
|
if (!winnerReference) return images;
|
|
@@ -20500,60 +20577,60 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
|
|
|
20500
20577
|
var createServiceVideoGuidance = getProductMakerCapabilityModelGuidance("create_service_video");
|
|
20501
20578
|
var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
|
|
20502
20579
|
var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
|
|
20503
|
-
var CreateProductTaskInput =
|
|
20580
|
+
var CreateProductTaskInput = z85.object({
|
|
20504
20581
|
images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
|
|
20505
20582
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
20506
|
-
projectId:
|
|
20507
|
-
productUrl:
|
|
20583
|
+
projectId: z85.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
|
|
20584
|
+
productUrl: z85.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."),
|
|
20508
20585
|
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.'),
|
|
20509
20586
|
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.'),
|
|
20510
|
-
price:
|
|
20511
|
-
compareAtPrice:
|
|
20512
|
-
offer:
|
|
20513
|
-
paymentMethods:
|
|
20514
|
-
productContext:
|
|
20515
|
-
productLabel:
|
|
20587
|
+
price: z85.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.'),
|
|
20588
|
+
compareAtPrice: z85.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".'),
|
|
20589
|
+
offer: z85.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.'),
|
|
20590
|
+
paymentMethods: z85.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.'),
|
|
20591
|
+
productContext: z85.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."),
|
|
20592
|
+
productLabel: z85.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.'),
|
|
20516
20593
|
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.'),
|
|
20517
20594
|
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.'),
|
|
20518
|
-
durationSeconds:
|
|
20519
|
-
|
|
20520
|
-
|
|
20595
|
+
durationSeconds: z85.union([
|
|
20596
|
+
z85.literal(15),
|
|
20597
|
+
z85.literal(30)
|
|
20521
20598
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
20522
|
-
pauseForAngleReview:
|
|
20523
|
-
aiDecidesAll:
|
|
20599
|
+
pauseForAngleReview: z85.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."),
|
|
20600
|
+
aiDecidesAll: z85.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."),
|
|
20524
20601
|
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.'),
|
|
20525
20602
|
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.'),
|
|
20526
20603
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
20527
20604
|
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).'),
|
|
20528
|
-
videoAngleCount:
|
|
20605
|
+
videoAngleCount: z85.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."),
|
|
20529
20606
|
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.'),
|
|
20530
|
-
outputs:
|
|
20607
|
+
outputs: z85.array(z85.enum([
|
|
20531
20608
|
"landing",
|
|
20532
20609
|
"video",
|
|
20533
20610
|
"image"
|
|
20534
20611
|
])).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}`),
|
|
20535
|
-
competitorScanEnabled:
|
|
20536
|
-
replicateWinnerWhenFound:
|
|
20537
|
-
brandId:
|
|
20538
|
-
actorId:
|
|
20612
|
+
competitorScanEnabled: z85.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."),
|
|
20613
|
+
replicateWinnerWhenFound: z85.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."),
|
|
20614
|
+
brandId: z85.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."),
|
|
20615
|
+
actorId: z85.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."),
|
|
20539
20616
|
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.'),
|
|
20540
|
-
creativeDirection:
|
|
20541
|
-
headline:
|
|
20542
|
-
subheadline:
|
|
20617
|
+
creativeDirection: z85.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.'),
|
|
20618
|
+
headline: z85.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."),
|
|
20619
|
+
subheadline: z85.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."),
|
|
20543
20620
|
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".'),
|
|
20544
20621
|
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".')
|
|
20545
20622
|
}).strict();
|
|
20546
|
-
var CreateServiceVideoInput =
|
|
20547
|
-
landingUrl:
|
|
20548
|
-
additionalContext:
|
|
20623
|
+
var CreateServiceVideoInput = z85.object({
|
|
20624
|
+
landingUrl: z85.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
|
|
20625
|
+
additionalContext: z85.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
|
|
20549
20626
|
language: Lang.describe("Idioma del video: es, en o pt."),
|
|
20550
|
-
voiceId:
|
|
20551
|
-
brandId:
|
|
20552
|
-
reviewMode:
|
|
20627
|
+
voiceId: z85.string().trim().min(1).optional().describe('Opcional. Voz de ElevenLabs para toda la narraci\xF3n. Usa "auto" para que la IA la alinee con el presentador o env\xEDa un ID concreto de la lista de voces de la web.'),
|
|
20628
|
+
brandId: z85.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
|
|
20629
|
+
reviewMode: z85.enum([
|
|
20553
20630
|
"automatic",
|
|
20554
20631
|
"guided"
|
|
20555
20632
|
]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
|
|
20556
|
-
videoPreset:
|
|
20633
|
+
videoPreset: z85.enum([
|
|
20557
20634
|
"auto",
|
|
20558
20635
|
"ugc_dynamic",
|
|
20559
20636
|
"ugc_how_to",
|
|
@@ -20563,128 +20640,128 @@ var CreateServiceVideoInput = z84.object({
|
|
|
20563
20640
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
20564
20641
|
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.')
|
|
20565
20642
|
}).strict();
|
|
20566
|
-
var GetTaskStatusInput =
|
|
20567
|
-
taskId:
|
|
20568
|
-
waitSeconds:
|
|
20643
|
+
var GetTaskStatusInput = z85.object({
|
|
20644
|
+
taskId: z85.string().min(1),
|
|
20645
|
+
waitSeconds: z85.number().int().min(0).max(120).optional()
|
|
20569
20646
|
});
|
|
20570
|
-
var ListTasksInput =
|
|
20571
|
-
limit:
|
|
20572
|
-
offset:
|
|
20573
|
-
search:
|
|
20647
|
+
var ListTasksInput = z85.object({
|
|
20648
|
+
limit: z85.number().int().min(1).max(50).optional(),
|
|
20649
|
+
offset: z85.number().int().min(0).optional(),
|
|
20650
|
+
search: z85.string().optional()
|
|
20574
20651
|
});
|
|
20575
20652
|
var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
|
|
20576
20653
|
var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
|
|
20577
|
-
var EditTaskDraftInput =
|
|
20578
|
-
taskId:
|
|
20579
|
-
angleIndex:
|
|
20580
|
-
angle:
|
|
20581
|
-
angle:
|
|
20582
|
-
buyerPersona:
|
|
20583
|
-
actor:
|
|
20584
|
-
actorId:
|
|
20585
|
-
gender:
|
|
20654
|
+
var EditTaskDraftInput = z85.object({
|
|
20655
|
+
taskId: z85.string().min(1),
|
|
20656
|
+
angleIndex: z85.number().int().min(0),
|
|
20657
|
+
angle: z85.object({
|
|
20658
|
+
angle: z85.string().min(1).max(480),
|
|
20659
|
+
buyerPersona: z85.string().min(1).max(360),
|
|
20660
|
+
actor: z85.string().min(1).max(360).optional(),
|
|
20661
|
+
actorId: z85.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."),
|
|
20662
|
+
gender: z85.enum([
|
|
20586
20663
|
"female",
|
|
20587
20664
|
"male"
|
|
20588
20665
|
]).optional(),
|
|
20589
|
-
scriptNotes:
|
|
20666
|
+
scriptNotes: z85.string().max(2e3).optional()
|
|
20590
20667
|
})
|
|
20591
20668
|
});
|
|
20592
|
-
var PendingActionPayload =
|
|
20593
|
-
|
|
20594
|
-
kind:
|
|
20669
|
+
var PendingActionPayload = z85.discriminatedUnion("kind", [
|
|
20670
|
+
z85.object({
|
|
20671
|
+
kind: z85.literal("product_reference_set_approval"),
|
|
20595
20672
|
scope: ProductReferenceScopeEnum.optional(),
|
|
20596
|
-
scopeKey:
|
|
20597
|
-
scopeSnapshotId:
|
|
20598
|
-
expectedScopeHash:
|
|
20673
|
+
scopeKey: z85.string().min(1).max(120).optional(),
|
|
20674
|
+
scopeSnapshotId: z85.string().uuid().optional(),
|
|
20675
|
+
expectedScopeHash: z85.string().min(1).max(128).optional(),
|
|
20599
20676
|
decision: ProductReferenceResolutionDecisionEnum,
|
|
20600
20677
|
reason: ProductReferenceRejectionReasonEnum.optional(),
|
|
20601
|
-
affectedRefKeys:
|
|
20602
|
-
affectedPhotoNumbers:
|
|
20603
|
-
recoveryAction:
|
|
20678
|
+
affectedRefKeys: z85.array(z85.string().min(1).max(200)).min(1).optional(),
|
|
20679
|
+
affectedPhotoNumbers: z85.array(z85.number().int().positive()).min(1).optional(),
|
|
20680
|
+
recoveryAction: z85.enum([
|
|
20604
20681
|
"remove",
|
|
20605
20682
|
"replace",
|
|
20606
20683
|
"upload",
|
|
20607
20684
|
"return_to_selection"
|
|
20608
20685
|
]).optional()
|
|
20609
20686
|
}),
|
|
20610
|
-
|
|
20611
|
-
kind:
|
|
20612
|
-
selectedPhotoNumbers:
|
|
20687
|
+
z85.object({
|
|
20688
|
+
kind: z85.literal("product_reference_confirmation"),
|
|
20689
|
+
selectedPhotoNumbers: z85.array(z85.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."),
|
|
20613
20690
|
userChoice: ProductReferenceUserChoiceEnum.optional(),
|
|
20614
|
-
confirmedProductNames:
|
|
20691
|
+
confirmedProductNames: z85.array(z85.string().min(1).max(120)).min(2).max(8).optional(),
|
|
20615
20692
|
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."),
|
|
20616
20693
|
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."),
|
|
20617
|
-
useMultiSceneShowcase:
|
|
20694
|
+
useMultiSceneShowcase: z85.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
|
|
20618
20695
|
}),
|
|
20619
|
-
|
|
20620
|
-
kind:
|
|
20696
|
+
z85.object({
|
|
20697
|
+
kind: z85.literal("angle_review_approval"),
|
|
20621
20698
|
// All edits are optional — empty action body just approves the
|
|
20622
20699
|
// backend-generated draft as-is. Field shapes mirror the angle-review
|
|
20623
20700
|
// request contracts in @packages/types/wizard.ts; the handler routes to
|
|
20624
20701
|
// the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
|
|
20625
|
-
customAngle:
|
|
20702
|
+
customAngle: z85.string().min(1).max(480).optional(),
|
|
20626
20703
|
// Keep the shared MCP action within the strictest downstream contract:
|
|
20627
20704
|
// autopilot/image resume endpoints cap these fields at 1500 characters.
|
|
20628
|
-
painPoints:
|
|
20629
|
-
benefits:
|
|
20705
|
+
painPoints: z85.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
20706
|
+
benefits: z85.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
20630
20707
|
// Same policy as the two fields above: the strictest downstream contract
|
|
20631
20708
|
// wins. The image endpoint caps each feature at 240 while landing/video
|
|
20632
20709
|
// accept 300, and this single action routes to whichever the task is — so
|
|
20633
20710
|
// accepting 300 here turns a 250-character feature on an image task into
|
|
20634
20711
|
// an opaque HTTP 400 after the model already believed it had been saved.
|
|
20635
|
-
features:
|
|
20636
|
-
buyerPersona:
|
|
20712
|
+
features: z85.array(z85.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
|
|
20713
|
+
buyerPersona: z85.string().min(1).max(360).optional(),
|
|
20637
20714
|
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.'),
|
|
20638
|
-
actor:
|
|
20639
|
-
actorId:
|
|
20640
|
-
creativeDirection:
|
|
20641
|
-
selectedAngleNumbers:
|
|
20642
|
-
angleEdits:
|
|
20643
|
-
angleNumber:
|
|
20644
|
-
narrativeSelection:
|
|
20715
|
+
actor: z85.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."),
|
|
20716
|
+
actorId: z85.string().max(120).nullable().optional(),
|
|
20717
|
+
creativeDirection: z85.string().max(2e3).optional(),
|
|
20718
|
+
selectedAngleNumbers: z85.array(z85.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."),
|
|
20719
|
+
angleEdits: z85.array(z85.object({
|
|
20720
|
+
angleNumber: z85.number().int().positive(),
|
|
20721
|
+
narrativeSelection: z85.enum([
|
|
20645
20722
|
"market",
|
|
20646
20723
|
"guided"
|
|
20647
20724
|
]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
|
|
20648
|
-
angle:
|
|
20649
|
-
buyerPersona:
|
|
20725
|
+
angle: z85.string().min(1).max(480).optional(),
|
|
20726
|
+
buyerPersona: z85.string().min(1).max(360).optional(),
|
|
20650
20727
|
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.'),
|
|
20651
|
-
actor:
|
|
20652
|
-
actorId:
|
|
20653
|
-
creativeDirection:
|
|
20728
|
+
actor: z85.string().min(1).max(360).optional(),
|
|
20729
|
+
actorId: z85.string().max(120).nullable().optional(),
|
|
20730
|
+
creativeDirection: z85.string().max(2e3).optional()
|
|
20654
20731
|
}).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)."),
|
|
20655
|
-
gapDurationSeconds:
|
|
20656
|
-
|
|
20657
|
-
|
|
20732
|
+
gapDurationSeconds: z85.union([
|
|
20733
|
+
z85.literal(15),
|
|
20734
|
+
z85.literal(30)
|
|
20658
20735
|
]).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.")
|
|
20659
20736
|
}),
|
|
20660
|
-
|
|
20661
|
-
kind:
|
|
20662
|
-
angleId:
|
|
20663
|
-
angleNumber:
|
|
20664
|
-
content:
|
|
20665
|
-
creativeDirection:
|
|
20666
|
-
actor:
|
|
20737
|
+
z85.object({
|
|
20738
|
+
kind: z85.literal("service_angle_approval"),
|
|
20739
|
+
angleId: z85.string().uuid().optional(),
|
|
20740
|
+
angleNumber: z85.number().int().positive().optional(),
|
|
20741
|
+
content: z85.string().min(1).max(480).optional(),
|
|
20742
|
+
creativeDirection: z85.string().min(1).max(1500).optional(),
|
|
20743
|
+
actor: z85.string().min(1).max(360).optional()
|
|
20667
20744
|
}),
|
|
20668
|
-
|
|
20669
|
-
kind:
|
|
20670
|
-
voiceovers:
|
|
20671
|
-
visualDirections:
|
|
20672
|
-
voiceoversByScene:
|
|
20673
|
-
visualDirectionsByScene:
|
|
20745
|
+
z85.object({
|
|
20746
|
+
kind: z85.literal("service_script_approval"),
|
|
20747
|
+
voiceovers: z85.record(z85.string(), z85.string().min(1).max(600)).optional(),
|
|
20748
|
+
visualDirections: z85.record(z85.string(), z85.string().min(1).max(1200)).optional(),
|
|
20749
|
+
voiceoversByScene: z85.record(z85.string(), z85.string().min(1).max(600)).optional(),
|
|
20750
|
+
visualDirectionsByScene: z85.record(z85.string(), z85.string().min(1).max(1200)).optional()
|
|
20674
20751
|
})
|
|
20675
20752
|
]);
|
|
20676
|
-
var ResolvePendingActionInput =
|
|
20677
|
-
taskId:
|
|
20753
|
+
var ResolvePendingActionInput = z85.object({
|
|
20754
|
+
taskId: z85.string().min(1),
|
|
20678
20755
|
action: PendingActionPayload
|
|
20679
20756
|
}).strict();
|
|
20680
20757
|
function resolveVariantConfirmVideoTier(action) {
|
|
20681
20758
|
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
20682
20759
|
}
|
|
20683
20760
|
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
20684
|
-
var StatusForResolveSchema =
|
|
20761
|
+
var StatusForResolveSchema = z85.object({
|
|
20685
20762
|
// Metadata used to select the backend resume contract. Older API responses
|
|
20686
20763
|
// may omit these fields, so the resolver keeps the generic fallback.
|
|
20687
|
-
kind:
|
|
20764
|
+
kind: z85.enum([
|
|
20688
20765
|
"autopilot",
|
|
20689
20766
|
"video",
|
|
20690
20767
|
"image",
|
|
@@ -20692,18 +20769,18 @@ var StatusForResolveSchema = z84.object({
|
|
|
20692
20769
|
"mix",
|
|
20693
20770
|
"service"
|
|
20694
20771
|
]).optional(),
|
|
20695
|
-
selectedOutputs:
|
|
20772
|
+
selectedOutputs: z85.array(z85.enum([
|
|
20696
20773
|
"landing",
|
|
20697
20774
|
"video",
|
|
20698
20775
|
"image"
|
|
20699
20776
|
])).optional(),
|
|
20700
|
-
videoAngleCount:
|
|
20701
|
-
ugcFormat:
|
|
20777
|
+
videoAngleCount: z85.number().int().min(1).max(3).optional(),
|
|
20778
|
+
ugcFormat: z85.enum([
|
|
20702
20779
|
"single_8s",
|
|
20703
20780
|
"single_15s",
|
|
20704
20781
|
"double_30s"
|
|
20705
20782
|
]).optional(),
|
|
20706
|
-
videoStyle:
|
|
20783
|
+
videoStyle: z85.enum([
|
|
20707
20784
|
"ugc",
|
|
20708
20785
|
"cartoon_3d",
|
|
20709
20786
|
"product_only",
|
|
@@ -20713,13 +20790,13 @@ var StatusForResolveSchema = z84.object({
|
|
|
20713
20790
|
videoQuality: VideoQualityEnum.optional(),
|
|
20714
20791
|
videoRouteId: VideoRouteIdEnum.optional(),
|
|
20715
20792
|
videoModel: TaskVideoModelEnum.optional(),
|
|
20716
|
-
videoTier:
|
|
20793
|
+
videoTier: z85.enum([
|
|
20717
20794
|
"legacy",
|
|
20718
20795
|
"standard",
|
|
20719
20796
|
"pro",
|
|
20720
20797
|
"single_call"
|
|
20721
20798
|
]).optional(),
|
|
20722
|
-
videoResolution:
|
|
20799
|
+
videoResolution: z85.enum([
|
|
20723
20800
|
"480p",
|
|
20724
20801
|
"720p"
|
|
20725
20802
|
]).optional(),
|
|
@@ -20727,60 +20804,60 @@ var StatusForResolveSchema = z84.object({
|
|
|
20727
20804
|
// A task created before a narrative was blocked/hidden must still parse,
|
|
20728
20805
|
// or resolve_pending_action could never approve it.
|
|
20729
20806
|
narrativeStyle: NarrativeStyle.optional(),
|
|
20730
|
-
pauseForVideoScriptReview:
|
|
20731
|
-
pendingUserAction:
|
|
20732
|
-
kind:
|
|
20733
|
-
candidateGrouping:
|
|
20734
|
-
selectedImageUrls:
|
|
20735
|
-
proposedProductNames:
|
|
20807
|
+
pauseForVideoScriptReview: z85.boolean().optional(),
|
|
20808
|
+
pendingUserAction: z85.object({
|
|
20809
|
+
kind: z85.string(),
|
|
20810
|
+
candidateGrouping: z85.string().optional(),
|
|
20811
|
+
selectedImageUrls: z85.array(z85.string()).optional(),
|
|
20812
|
+
proposedProductNames: z85.array(z85.string()).optional(),
|
|
20736
20813
|
// Adaptive reference questions are server-owned. Echo only the evidence
|
|
20737
20814
|
// identity and the choices shown by the current snapshot; never accept a
|
|
20738
20815
|
// client-supplied reference set as authorization.
|
|
20739
|
-
options:
|
|
20740
|
-
mode:
|
|
20816
|
+
options: z85.array(ProductReferenceUserChoiceEnum).max(4).optional(),
|
|
20817
|
+
mode: z85.enum([
|
|
20741
20818
|
"question",
|
|
20742
20819
|
"visual_recovery"
|
|
20743
20820
|
]).optional(),
|
|
20744
20821
|
/** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
|
|
20745
|
-
canKeepSelection:
|
|
20746
|
-
decisionKey:
|
|
20747
|
-
questionOrdinal:
|
|
20748
|
-
questionCeiling:
|
|
20749
|
-
|
|
20750
|
-
|
|
20822
|
+
canKeepSelection: z85.boolean().optional(),
|
|
20823
|
+
decisionKey: z85.string().optional(),
|
|
20824
|
+
questionOrdinal: z85.number().int().min(1).max(5).optional(),
|
|
20825
|
+
questionCeiling: z85.union([
|
|
20826
|
+
z85.literal(3),
|
|
20827
|
+
z85.literal(5)
|
|
20751
20828
|
]).optional(),
|
|
20752
|
-
referenceEvidenceVersion:
|
|
20753
|
-
expectedEvidenceHash:
|
|
20754
|
-
question:
|
|
20755
|
-
prompt:
|
|
20756
|
-
helpText:
|
|
20757
|
-
options:
|
|
20829
|
+
referenceEvidenceVersion: z85.number().int().positive().optional(),
|
|
20830
|
+
expectedEvidenceHash: z85.string().optional(),
|
|
20831
|
+
question: z85.object({
|
|
20832
|
+
prompt: z85.string().min(1).max(240),
|
|
20833
|
+
helpText: z85.string().min(1).max(300).optional(),
|
|
20834
|
+
options: z85.array(z85.object({
|
|
20758
20835
|
value: ProductReferenceUserChoiceEnum,
|
|
20759
|
-
label:
|
|
20760
|
-
description:
|
|
20836
|
+
label: z85.string().min(1).max(120),
|
|
20837
|
+
description: z85.string().min(1).max(240).optional()
|
|
20761
20838
|
})).min(2).max(4)
|
|
20762
20839
|
}).optional(),
|
|
20763
20840
|
scope: ProductReferenceScopeEnum.optional(),
|
|
20764
|
-
scopeKey:
|
|
20765
|
-
scopeSnapshotId:
|
|
20766
|
-
scopeHash:
|
|
20767
|
-
baseReferenceSetHash:
|
|
20768
|
-
phase:
|
|
20841
|
+
scopeKey: z85.string().optional(),
|
|
20842
|
+
scopeSnapshotId: z85.string().uuid().optional(),
|
|
20843
|
+
scopeHash: z85.string().optional(),
|
|
20844
|
+
baseReferenceSetHash: z85.string().optional(),
|
|
20845
|
+
phase: z85.enum([
|
|
20769
20846
|
"preparation",
|
|
20770
20847
|
"final"
|
|
20771
20848
|
]).optional(),
|
|
20772
|
-
selectedRefKeys:
|
|
20773
|
-
allowedDecisions:
|
|
20774
|
-
previews:
|
|
20775
|
-
refKey:
|
|
20849
|
+
selectedRefKeys: z85.array(z85.string().min(1).max(200)).optional(),
|
|
20850
|
+
allowedDecisions: z85.array(ProductReferenceResolutionDecisionEnum).optional(),
|
|
20851
|
+
previews: z85.array(z85.object({
|
|
20852
|
+
refKey: z85.string().min(1).max(200)
|
|
20776
20853
|
}).passthrough()).optional(),
|
|
20777
|
-
customAngleDraft:
|
|
20778
|
-
painPointsDraft:
|
|
20779
|
-
benefitsDraft:
|
|
20780
|
-
featuresDraft:
|
|
20781
|
-
angleOptions:
|
|
20782
|
-
index:
|
|
20783
|
-
angle:
|
|
20854
|
+
customAngleDraft: z85.string().optional(),
|
|
20855
|
+
painPointsDraft: z85.string().optional(),
|
|
20856
|
+
benefitsDraft: z85.string().optional(),
|
|
20857
|
+
featuresDraft: z85.array(z85.string()).optional(),
|
|
20858
|
+
angleOptions: z85.array(z85.object({
|
|
20859
|
+
index: z85.number().int().nonnegative(),
|
|
20860
|
+
angle: z85.string().min(1)
|
|
20784
20861
|
}).passthrough()).min(1).max(5).optional(),
|
|
20785
20862
|
// Recommendation consumed only when the caller explicitly sends
|
|
20786
20863
|
// gapDurationSeconds: 30 in the angle approval action.
|
|
@@ -20790,17 +20867,17 @@ var StatusForResolveSchema = z84.object({
|
|
|
20790
20867
|
// keys. `actorId` (the saved custom actor the picker stored) was silently
|
|
20791
20868
|
// dropped here, so the approval handler below could not echo it back on the
|
|
20792
20869
|
// PATCH — the selection looked accepted and reached no render.
|
|
20793
|
-
angles:
|
|
20794
|
-
id:
|
|
20795
|
-
content:
|
|
20796
|
-
creativeDirection:
|
|
20797
|
-
actor:
|
|
20798
|
-
actorId:
|
|
20870
|
+
angles: z85.array(z85.object({
|
|
20871
|
+
id: z85.string().uuid(),
|
|
20872
|
+
content: z85.string(),
|
|
20873
|
+
creativeDirection: z85.string(),
|
|
20874
|
+
actor: z85.string(),
|
|
20875
|
+
actorId: z85.string().nullable().optional()
|
|
20799
20876
|
}).passthrough()).optional(),
|
|
20800
|
-
panels:
|
|
20801
|
-
beatId:
|
|
20802
|
-
voiceover:
|
|
20803
|
-
visualDirection:
|
|
20877
|
+
panels: z85.array(z85.object({
|
|
20878
|
+
beatId: z85.string(),
|
|
20879
|
+
voiceover: z85.string(),
|
|
20880
|
+
visualDirection: z85.string()
|
|
20804
20881
|
}).passthrough()).optional()
|
|
20805
20882
|
}).optional()
|
|
20806
20883
|
}).passthrough();
|
|
@@ -21147,8 +21224,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
21147
21224
|
server.registerTool("verify_landing_commerce", {
|
|
21148
21225
|
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.",
|
|
21149
21226
|
inputSchema: {
|
|
21150
|
-
taskId:
|
|
21151
|
-
editId:
|
|
21227
|
+
taskId: z85.string().uuid(),
|
|
21228
|
+
editId: z85.string().uuid()
|
|
21152
21229
|
},
|
|
21153
21230
|
annotations: OVERWRITES_EXTERNAL
|
|
21154
21231
|
}, async (input) => {
|
|
@@ -21787,7 +21864,7 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
21787
21864
|
__name(registerTaskTools, "registerTaskTools");
|
|
21788
21865
|
|
|
21789
21866
|
// src/tools/creatives.ts
|
|
21790
|
-
import { z as
|
|
21867
|
+
import { z as z86 } from "zod";
|
|
21791
21868
|
var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
|
|
21792
21869
|
var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
|
|
21793
21870
|
var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
|
|
@@ -21798,71 +21875,71 @@ var CreativeRefs = {
|
|
|
21798
21875
|
images: ImagesInput,
|
|
21799
21876
|
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.'),
|
|
21800
21877
|
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.'),
|
|
21801
|
-
price:
|
|
21802
|
-
offer:
|
|
21803
|
-
compareAtPrice:
|
|
21804
|
-
productContext:
|
|
21805
|
-
productLabel:
|
|
21806
|
-
buyerPersona:
|
|
21807
|
-
isCombo:
|
|
21808
|
-
competitorScanEnabled:
|
|
21809
|
-
brandId:
|
|
21878
|
+
price: z86.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.'),
|
|
21879
|
+
offer: z86.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.'),
|
|
21880
|
+
compareAtPrice: z86.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
|
|
21881
|
+
productContext: z86.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."),
|
|
21882
|
+
productLabel: z86.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.'),
|
|
21883
|
+
buyerPersona: z86.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.'),
|
|
21884
|
+
isCombo: z86.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
|
|
21885
|
+
competitorScanEnabled: z86.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."),
|
|
21886
|
+
brandId: z86.string().uuid().optional().describe("Opcional. ID de una marca del usuario; si se env\xEDa, el sistema usa su voz, colores y persona para enriquecer el creativo.")
|
|
21810
21887
|
};
|
|
21811
|
-
var VideoPresenter =
|
|
21812
|
-
|
|
21813
|
-
mode:
|
|
21888
|
+
var VideoPresenter = z86.discriminatedUnion("mode", [
|
|
21889
|
+
z86.object({
|
|
21890
|
+
mode: z86.literal("none")
|
|
21814
21891
|
}).strict(),
|
|
21815
|
-
|
|
21816
|
-
mode:
|
|
21817
|
-
actorId:
|
|
21892
|
+
z86.object({
|
|
21893
|
+
mode: z86.literal("saved_actor"),
|
|
21894
|
+
actorId: z86.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
|
|
21818
21895
|
}).strict(),
|
|
21819
|
-
|
|
21820
|
-
mode:
|
|
21821
|
-
description:
|
|
21896
|
+
z86.object({
|
|
21897
|
+
mode: z86.literal("described"),
|
|
21898
|
+
description: z86.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
|
|
21822
21899
|
}).strict()
|
|
21823
21900
|
]);
|
|
21824
|
-
var VideoCreativeSetup =
|
|
21825
|
-
|
|
21826
|
-
mode:
|
|
21901
|
+
var VideoCreativeSetup = z86.discriminatedUnion("mode", [
|
|
21902
|
+
z86.object({
|
|
21903
|
+
mode: z86.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
|
|
21827
21904
|
}).strict(),
|
|
21828
|
-
|
|
21829
|
-
mode:
|
|
21905
|
+
z86.object({
|
|
21906
|
+
mode: z86.literal("guided"),
|
|
21830
21907
|
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.'),
|
|
21831
|
-
buyerPersona:
|
|
21908
|
+
buyerPersona: z86.string().trim().min(1).max(360),
|
|
21832
21909
|
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.'),
|
|
21833
21910
|
presenter: VideoPresenter,
|
|
21834
|
-
creativeDirection:
|
|
21911
|
+
creativeDirection: z86.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
|
|
21835
21912
|
}).strict()
|
|
21836
21913
|
]);
|
|
21837
|
-
var VideoInput =
|
|
21914
|
+
var VideoInput = z86.object({
|
|
21838
21915
|
images: CreativeRefs.images.optional(),
|
|
21839
21916
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
21840
|
-
title:
|
|
21841
|
-
primaryAngle:
|
|
21917
|
+
title: z86.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
|
|
21918
|
+
primaryAngle: z86.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".'),
|
|
21842
21919
|
language: CreativeRefs.language,
|
|
21843
21920
|
country: CreativeRefs.country,
|
|
21844
|
-
aspectRatio:
|
|
21921
|
+
aspectRatio: z86.enum([
|
|
21845
21922
|
"9:16",
|
|
21846
21923
|
"16:9",
|
|
21847
21924
|
"Auto"
|
|
21848
21925
|
]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
|
|
21849
|
-
durationSeconds:
|
|
21850
|
-
videoAngleCount:
|
|
21926
|
+
durationSeconds: z86.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."),
|
|
21927
|
+
videoAngleCount: z86.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."),
|
|
21851
21928
|
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.'),
|
|
21852
21929
|
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."),
|
|
21853
21930
|
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.'),
|
|
21854
21931
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
|
|
21855
21932
|
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.'),
|
|
21856
|
-
features:
|
|
21933
|
+
features: z86.array(z86.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
|
|
21857
21934
|
price: CreativeRefs.price,
|
|
21858
21935
|
offer: CreativeRefs.offer,
|
|
21859
21936
|
productContext: CreativeRefs.productContext,
|
|
21860
21937
|
productLabel: CreativeRefs.productLabel,
|
|
21861
|
-
cta:
|
|
21862
|
-
scriptNotes:
|
|
21938
|
+
cta: z86.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.'),
|
|
21939
|
+
scriptNotes: z86.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.'),
|
|
21863
21940
|
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.'),
|
|
21864
21941
|
competitorScanEnabled: CreativeRefs.competitorScanEnabled,
|
|
21865
|
-
replicateWinnerWhenFound:
|
|
21942
|
+
replicateWinnerWhenFound: z86.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."),
|
|
21866
21943
|
brandId: CreativeRefs.brandId
|
|
21867
21944
|
}).strict();
|
|
21868
21945
|
var FreeVideoQualityEnum = VideoQualityEnum;
|
|
@@ -21880,7 +21957,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
|
|
|
21880
21957
|
length: 29
|
|
21881
21958
|
}, (_, index) => index + 2)
|
|
21882
21959
|
};
|
|
21883
|
-
var FreeVideoModelIdEnum =
|
|
21960
|
+
var FreeVideoModelIdEnum = z86.enum([
|
|
21884
21961
|
"grok-imagine-video-1-5-preview",
|
|
21885
21962
|
"minimax-h3/reference-to-video",
|
|
21886
21963
|
"wan/3-0-video",
|
|
@@ -21891,65 +21968,65 @@ var FREE_SELECTABLE_MODEL_IDS = [
|
|
|
21891
21968
|
"minimax-h3/reference-to-video",
|
|
21892
21969
|
"wan/3-0-video"
|
|
21893
21970
|
];
|
|
21894
|
-
var FreeVideoInput =
|
|
21971
|
+
var FreeVideoInput = z86.object({
|
|
21895
21972
|
images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
|
|
21896
|
-
rawPrompt:
|
|
21973
|
+
rawPrompt: z86.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."),
|
|
21897
21974
|
language: CreativeRefs.language,
|
|
21898
21975
|
quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
|
|
21899
21976
|
// Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
|
|
21900
21977
|
// parsed ONLY so the handler can reject it with a message naming its
|
|
21901
21978
|
// replacement — dropping it silently would turn a caller's explicit
|
|
21902
21979
|
// Pro++ pick into a quiet fallback to Wan.
|
|
21903
|
-
freeProModel:
|
|
21980
|
+
freeProModel: z86.enum([
|
|
21904
21981
|
"wan",
|
|
21905
21982
|
"seedance"
|
|
21906
21983
|
]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
|
|
21907
21984
|
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.'),
|
|
21908
|
-
durationSeconds:
|
|
21985
|
+
durationSeconds: z86.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."),
|
|
21909
21986
|
videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
|
|
21910
|
-
generateAiMusic:
|
|
21911
|
-
addSubtitles:
|
|
21912
|
-
idempotencyKey:
|
|
21987
|
+
generateAiMusic: z86.boolean().default(false).describe("Opcional. Agrega m\xFAsica instrumental IA debajo del audio nativo. Default false."),
|
|
21988
|
+
addSubtitles: z86.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
|
|
21989
|
+
idempotencyKey: z86.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.")
|
|
21913
21990
|
}).strict();
|
|
21914
21991
|
var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
|
|
21915
|
-
var ImageCreativeSetup =
|
|
21916
|
-
|
|
21917
|
-
mode:
|
|
21992
|
+
var ImageCreativeSetup = z86.discriminatedUnion("mode", [
|
|
21993
|
+
z86.object({
|
|
21994
|
+
mode: z86.literal("automatic")
|
|
21918
21995
|
}).strict(),
|
|
21919
|
-
|
|
21920
|
-
mode:
|
|
21921
|
-
creativeArchetype:
|
|
21996
|
+
z86.object({
|
|
21997
|
+
mode: z86.literal("guided"),
|
|
21998
|
+
creativeArchetype: z86.union([
|
|
21922
21999
|
ImageCreativeArchetypeEnum,
|
|
21923
|
-
|
|
22000
|
+
z86.literal("ai_decides")
|
|
21924
22001
|
]),
|
|
21925
|
-
visualTreatment:
|
|
22002
|
+
visualTreatment: z86.union([
|
|
21926
22003
|
ImageCreativeVisualTreatmentEnum,
|
|
21927
|
-
|
|
22004
|
+
z86.literal("ai_decides")
|
|
21928
22005
|
]),
|
|
21929
22006
|
aspectRatio: ImageCreativeAspectRatioEnum,
|
|
21930
|
-
nVariants:
|
|
21931
|
-
|
|
21932
|
-
|
|
21933
|
-
|
|
21934
|
-
|
|
21935
|
-
|
|
22007
|
+
nVariants: z86.union([
|
|
22008
|
+
z86.literal(1),
|
|
22009
|
+
z86.literal(2),
|
|
22010
|
+
z86.literal(3),
|
|
22011
|
+
z86.literal(4),
|
|
22012
|
+
z86.literal(6)
|
|
21936
22013
|
]),
|
|
21937
|
-
imageModel:
|
|
21938
|
-
styleMix:
|
|
21939
|
-
generateAdCopy:
|
|
21940
|
-
competitorScanEnabled:
|
|
21941
|
-
productContext:
|
|
21942
|
-
creativeDirection:
|
|
21943
|
-
brandColors:
|
|
21944
|
-
headline:
|
|
21945
|
-
subheadline:
|
|
22014
|
+
imageModel: z86.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.'),
|
|
22015
|
+
styleMix: z86.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
|
|
22016
|
+
generateAdCopy: z86.boolean(),
|
|
22017
|
+
competitorScanEnabled: z86.boolean(),
|
|
22018
|
+
productContext: z86.string().trim().min(1).max(3e3).nullable(),
|
|
22019
|
+
creativeDirection: z86.string().trim().min(1).max(500).nullable(),
|
|
22020
|
+
brandColors: z86.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.'),
|
|
22021
|
+
headline: z86.string().trim().min(1).max(120).nullable(),
|
|
22022
|
+
subheadline: z86.string().trim().min(1).max(160).nullable()
|
|
21946
22023
|
}).strict()
|
|
21947
22024
|
]).superRefine((setup, context) => {
|
|
21948
22025
|
if (setup.mode !== "guided") return;
|
|
21949
22026
|
const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
|
|
21950
22027
|
if (needsStyleMix && setup.styleMix === null) {
|
|
21951
22028
|
context.addIssue({
|
|
21952
|
-
code:
|
|
22029
|
+
code: z86.ZodIssueCode.custom,
|
|
21953
22030
|
path: [
|
|
21954
22031
|
"styleMix"
|
|
21955
22032
|
],
|
|
@@ -21958,7 +22035,7 @@ var ImageCreativeSetup = z85.discriminatedUnion("mode", [
|
|
|
21958
22035
|
}
|
|
21959
22036
|
if (!needsStyleMix && setup.styleMix !== null) {
|
|
21960
22037
|
context.addIssue({
|
|
21961
|
-
code:
|
|
22038
|
+
code: z86.ZodIssueCode.custom,
|
|
21962
22039
|
path: [
|
|
21963
22040
|
"styleMix"
|
|
21964
22041
|
],
|
|
@@ -21967,7 +22044,7 @@ var ImageCreativeSetup = z85.discriminatedUnion("mode", [
|
|
|
21967
22044
|
}
|
|
21968
22045
|
if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
|
|
21969
22046
|
context.addIssue({
|
|
21970
|
-
code:
|
|
22047
|
+
code: z86.ZodIssueCode.custom,
|
|
21971
22048
|
path: [
|
|
21972
22049
|
"aspectRatio"
|
|
21973
22050
|
],
|
|
@@ -21975,54 +22052,54 @@ var ImageCreativeSetup = z85.discriminatedUnion("mode", [
|
|
|
21975
22052
|
});
|
|
21976
22053
|
}
|
|
21977
22054
|
});
|
|
21978
|
-
var LandingCreativeSetup =
|
|
21979
|
-
|
|
21980
|
-
mode:
|
|
22055
|
+
var LandingCreativeSetup = z86.discriminatedUnion("mode", [
|
|
22056
|
+
z86.object({
|
|
22057
|
+
mode: z86.literal("automatic")
|
|
21981
22058
|
}).strict(),
|
|
21982
|
-
|
|
21983
|
-
mode:
|
|
22059
|
+
z86.object({
|
|
22060
|
+
mode: z86.literal("guided"),
|
|
21984
22061
|
landingStrategy: LandingStrategyEnum,
|
|
21985
22062
|
landingImageFormat: LandingImageFormatEnum,
|
|
21986
|
-
competitorScanEnabled:
|
|
21987
|
-
paymentMethods:
|
|
21988
|
-
productContext:
|
|
21989
|
-
creativeDirection:
|
|
21990
|
-
headline:
|
|
21991
|
-
subheadline:
|
|
22063
|
+
competitorScanEnabled: z86.boolean(),
|
|
22064
|
+
paymentMethods: z86.string().trim().min(1).max(240).nullable(),
|
|
22065
|
+
productContext: z86.string().trim().min(1).max(3e3).nullable(),
|
|
22066
|
+
creativeDirection: z86.string().trim().min(1).max(500).nullable(),
|
|
22067
|
+
headline: z86.string().trim().min(1).max(120).nullable(),
|
|
22068
|
+
subheadline: z86.string().trim().min(1).max(160).nullable()
|
|
21992
22069
|
}).strict()
|
|
21993
22070
|
]);
|
|
21994
|
-
var ImageInput =
|
|
22071
|
+
var ImageInput = z86.object({
|
|
21995
22072
|
images: CreativeRefs.images.optional(),
|
|
21996
22073
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
21997
|
-
productTitle:
|
|
21998
|
-
primaryAngle:
|
|
22074
|
+
productTitle: z86.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
|
|
22075
|
+
primaryAngle: z86.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.'),
|
|
21999
22076
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
22000
22077
|
language: CreativeRefs.language,
|
|
22001
22078
|
country: CreativeRefs.country,
|
|
22002
22079
|
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."),
|
|
22003
22080
|
imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
|
|
22004
|
-
features:
|
|
22081
|
+
features: z86.array(z86.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
|
|
22005
22082
|
price: CreativeRefs.price,
|
|
22006
|
-
omitPrice:
|
|
22083
|
+
omitPrice: z86.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."),
|
|
22007
22084
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
22008
22085
|
offer: CreativeRefs.offer,
|
|
22009
22086
|
productLabel: CreativeRefs.productLabel,
|
|
22010
22087
|
isCombo: CreativeRefs.isCombo,
|
|
22011
22088
|
brandId: CreativeRefs.brandId
|
|
22012
22089
|
});
|
|
22013
|
-
var EditImageCreativeInput =
|
|
22014
|
-
taskId:
|
|
22015
|
-
variantIndex:
|
|
22016
|
-
clientRequestId:
|
|
22017
|
-
instruction:
|
|
22090
|
+
var EditImageCreativeInput = z86.object({
|
|
22091
|
+
taskId: z86.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
|
|
22092
|
+
variantIndex: z86.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
|
|
22093
|
+
clientRequestId: z86.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."),
|
|
22094
|
+
instruction: z86.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".')
|
|
22018
22095
|
});
|
|
22019
|
-
var LandingInput =
|
|
22096
|
+
var LandingInput = z86.object({
|
|
22020
22097
|
images: CreativeRefs.images.optional(),
|
|
22021
22098
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
22022
22099
|
language: CreativeRefs.language,
|
|
22023
22100
|
country: CreativeRefs.country,
|
|
22024
22101
|
creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
|
|
22025
|
-
salesAngle:
|
|
22102
|
+
salesAngle: z86.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.'),
|
|
22026
22103
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
22027
22104
|
price: CreativeRefs.price,
|
|
22028
22105
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
@@ -22301,8 +22378,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
22301
22378
|
server.registerTool("get_image_edit_status", {
|
|
22302
22379
|
description: imageEditStatusGuidance.summary,
|
|
22303
22380
|
inputSchema: {
|
|
22304
|
-
taskId:
|
|
22305
|
-
operationId:
|
|
22381
|
+
taskId: z86.string().uuid(),
|
|
22382
|
+
operationId: z86.string().uuid()
|
|
22306
22383
|
},
|
|
22307
22384
|
annotations: READS_INTERNAL
|
|
22308
22385
|
}, async (input) => {
|
|
@@ -22359,10 +22436,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
22359
22436
|
__name(registerCreativeTools, "registerCreativeTools");
|
|
22360
22437
|
|
|
22361
22438
|
// src/tools/creative-variants.ts
|
|
22362
|
-
import { z as
|
|
22439
|
+
import { z as z87 } from "zod";
|
|
22363
22440
|
var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
|
|
22364
22441
|
var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
|
|
22365
|
-
var LandingSectionKeyEnum =
|
|
22442
|
+
var LandingSectionKeyEnum = z87.enum([
|
|
22366
22443
|
"problem_hook",
|
|
22367
22444
|
"problem_cost",
|
|
22368
22445
|
"solution_mechanism",
|
|
@@ -22402,24 +22479,24 @@ var LandingSectionKeyEnum = z86.enum([
|
|
|
22402
22479
|
"lifestyle_fit",
|
|
22403
22480
|
"join_lifestyle"
|
|
22404
22481
|
]);
|
|
22405
|
-
var CreativeVariantKindEnum =
|
|
22482
|
+
var CreativeVariantKindEnum = z87.enum([
|
|
22406
22483
|
"video",
|
|
22407
22484
|
"image",
|
|
22408
22485
|
"landing"
|
|
22409
22486
|
]);
|
|
22410
|
-
var EstimateCreativeVariantInputBase =
|
|
22411
|
-
sourceTaskId:
|
|
22487
|
+
var EstimateCreativeVariantInputBase = z87.object({
|
|
22488
|
+
sourceTaskId: z87.string().uuid().describe("ID de la tarea original completada."),
|
|
22412
22489
|
kind: CreativeVariantKindEnum,
|
|
22413
22490
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
|
|
22414
22491
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
|
|
22415
|
-
nVariants:
|
|
22492
|
+
nVariants: z87.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
22416
22493
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
|
|
22417
|
-
instructions:
|
|
22494
|
+
instructions: z87.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.")
|
|
22418
22495
|
}).strict();
|
|
22419
22496
|
var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
22420
22497
|
if (input.kind === "video" && input.nVariants !== void 0) {
|
|
22421
22498
|
ctx.addIssue({
|
|
22422
|
-
code:
|
|
22499
|
+
code: z87.ZodIssueCode.custom,
|
|
22423
22500
|
path: [
|
|
22424
22501
|
"nVariants"
|
|
22425
22502
|
],
|
|
@@ -22429,7 +22506,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
22429
22506
|
if (input.kind !== "video") {
|
|
22430
22507
|
if (input.videoPreset !== void 0) {
|
|
22431
22508
|
ctx.addIssue({
|
|
22432
|
-
code:
|
|
22509
|
+
code: z87.ZodIssueCode.custom,
|
|
22433
22510
|
path: [
|
|
22434
22511
|
"videoPreset"
|
|
22435
22512
|
],
|
|
@@ -22438,7 +22515,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
22438
22515
|
}
|
|
22439
22516
|
if (input.videoResolution !== void 0) {
|
|
22440
22517
|
ctx.addIssue({
|
|
22441
|
-
code:
|
|
22518
|
+
code: z87.ZodIssueCode.custom,
|
|
22442
22519
|
path: [
|
|
22443
22520
|
"videoResolution"
|
|
22444
22521
|
],
|
|
@@ -22448,7 +22525,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
22448
22525
|
}
|
|
22449
22526
|
if (input.kind !== "image" && input.nVariants !== void 0) {
|
|
22450
22527
|
ctx.addIssue({
|
|
22451
|
-
code:
|
|
22528
|
+
code: z87.ZodIssueCode.custom,
|
|
22452
22529
|
path: [
|
|
22453
22530
|
"nVariants"
|
|
22454
22531
|
],
|
|
@@ -22458,7 +22535,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
22458
22535
|
if (input.kind !== "landing") {
|
|
22459
22536
|
if (input.sectionKey !== void 0) {
|
|
22460
22537
|
ctx.addIssue({
|
|
22461
|
-
code:
|
|
22538
|
+
code: z87.ZodIssueCode.custom,
|
|
22462
22539
|
path: [
|
|
22463
22540
|
"sectionKey"
|
|
22464
22541
|
],
|
|
@@ -22467,7 +22544,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
22467
22544
|
}
|
|
22468
22545
|
if (input.instructions !== void 0) {
|
|
22469
22546
|
ctx.addIssue({
|
|
22470
|
-
code:
|
|
22547
|
+
code: z87.ZodIssueCode.custom,
|
|
22471
22548
|
path: [
|
|
22472
22549
|
"instructions"
|
|
22473
22550
|
],
|
|
@@ -22476,31 +22553,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
22476
22553
|
}
|
|
22477
22554
|
}
|
|
22478
22555
|
});
|
|
22479
|
-
var CreateCreativeVariantInputBase =
|
|
22480
|
-
sourceTaskId:
|
|
22556
|
+
var CreateCreativeVariantInputBase = z87.object({
|
|
22557
|
+
sourceTaskId: z87.string().uuid().describe("ID de la tarea original completada."),
|
|
22481
22558
|
kind: CreativeVariantKindEnum,
|
|
22482
|
-
confirm:
|
|
22483
|
-
clientRequestId:
|
|
22484
|
-
angle:
|
|
22485
|
-
buyerPersona:
|
|
22486
|
-
scriptNotes:
|
|
22487
|
-
creativeDirection:
|
|
22559
|
+
confirm: z87.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
|
|
22560
|
+
clientRequestId: z87.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."),
|
|
22561
|
+
angle: z87.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
|
|
22562
|
+
buyerPersona: z87.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
|
|
22563
|
+
scriptNotes: z87.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
|
|
22564
|
+
creativeDirection: z87.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
|
|
22488
22565
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
|
|
22489
22566
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
|
|
22490
|
-
generateAiMusic:
|
|
22491
|
-
nVariants:
|
|
22567
|
+
generateAiMusic: z87.boolean().optional().describe("Opcional para video."),
|
|
22568
|
+
nVariants: z87.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
22492
22569
|
imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
|
|
22493
22570
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
|
|
22494
22571
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
|
|
22495
22572
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
|
|
22496
|
-
styleMix:
|
|
22573
|
+
styleMix: z87.boolean().optional().describe("Opcional para imagen."),
|
|
22497
22574
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
|
|
22498
|
-
instructions:
|
|
22575
|
+
instructions: z87.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.")
|
|
22499
22576
|
}).strict();
|
|
22500
22577
|
var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
22501
22578
|
if ((input.kind === "video" || input.kind === "image") && !input.angle) {
|
|
22502
22579
|
ctx.addIssue({
|
|
22503
|
-
code:
|
|
22580
|
+
code: z87.ZodIssueCode.custom,
|
|
22504
22581
|
path: [
|
|
22505
22582
|
"angle"
|
|
22506
22583
|
],
|
|
@@ -22509,7 +22586,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
22509
22586
|
}
|
|
22510
22587
|
if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
|
|
22511
22588
|
ctx.addIssue({
|
|
22512
|
-
code:
|
|
22589
|
+
code: z87.ZodIssueCode.custom,
|
|
22513
22590
|
path: [
|
|
22514
22591
|
"instructions"
|
|
22515
22592
|
],
|
|
@@ -22555,7 +22632,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
22555
22632
|
for (const field of fieldsByKind[input.kind]) {
|
|
22556
22633
|
if (input[field] !== void 0) {
|
|
22557
22634
|
ctx.addIssue({
|
|
22558
|
-
code:
|
|
22635
|
+
code: z87.ZodIssueCode.custom,
|
|
22559
22636
|
path: [
|
|
22560
22637
|
field
|
|
22561
22638
|
],
|
|
@@ -22688,13 +22765,13 @@ function registerCreativeVariantTools(server, api) {
|
|
|
22688
22765
|
__name(registerCreativeVariantTools, "registerCreativeVariantTools");
|
|
22689
22766
|
|
|
22690
22767
|
// src/tools/script-review.ts
|
|
22691
|
-
import { z as
|
|
22768
|
+
import { z as z88 } from "zod";
|
|
22692
22769
|
var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
|
|
22693
22770
|
var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
|
|
22694
22771
|
var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
|
|
22695
|
-
var GetVideoScriptInput =
|
|
22696
|
-
taskId:
|
|
22697
|
-
angleKey:
|
|
22772
|
+
var GetVideoScriptInput = z88.object({
|
|
22773
|
+
taskId: z88.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
|
|
22774
|
+
angleKey: z88.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.')
|
|
22698
22775
|
}).strict();
|
|
22699
22776
|
var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
|
|
22700
22777
|
var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
|
|
@@ -22777,7 +22854,7 @@ function registerScriptReviewTools(server, api) {
|
|
|
22777
22854
|
__name(registerScriptReviewTools, "registerScriptReviewTools");
|
|
22778
22855
|
|
|
22779
22856
|
// src/tools/connections.ts
|
|
22780
|
-
import { z as
|
|
22857
|
+
import { z as z89 } from "zod";
|
|
22781
22858
|
var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
|
|
22782
22859
|
var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
|
|
22783
22860
|
var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
|
|
@@ -22786,7 +22863,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
|
|
|
22786
22863
|
function registerConnectionTools(server, api) {
|
|
22787
22864
|
server.registerTool("list_shopify_shops", {
|
|
22788
22865
|
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.",
|
|
22789
|
-
inputSchema:
|
|
22866
|
+
inputSchema: z89.object({}).shape,
|
|
22790
22867
|
annotations: READS_INTERNAL
|
|
22791
22868
|
}, async () => {
|
|
22792
22869
|
try {
|
|
@@ -22798,10 +22875,10 @@ function registerConnectionTools(server, api) {
|
|
|
22798
22875
|
});
|
|
22799
22876
|
server.registerTool("list_shopify_products", {
|
|
22800
22877
|
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.',
|
|
22801
|
-
inputSchema:
|
|
22802
|
-
shopDomain:
|
|
22803
|
-
query:
|
|
22804
|
-
taskId:
|
|
22878
|
+
inputSchema: z89.object({
|
|
22879
|
+
shopDomain: z89.string().min(3).max(120),
|
|
22880
|
+
query: z89.string().trim().max(120).optional(),
|
|
22881
|
+
taskId: z89.string().uuid().optional()
|
|
22805
22882
|
}).shape,
|
|
22806
22883
|
annotations: READS_EXTERNAL
|
|
22807
22884
|
}, async ({ shopDomain, query, taskId }) => {
|
|
@@ -22819,7 +22896,7 @@ function registerConnectionTools(server, api) {
|
|
|
22819
22896
|
});
|
|
22820
22897
|
server.registerTool("list_meta_ad_accounts", {
|
|
22821
22898
|
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.",
|
|
22822
|
-
inputSchema:
|
|
22899
|
+
inputSchema: z89.object({}).shape,
|
|
22823
22900
|
annotations: READS_EXTERNAL
|
|
22824
22901
|
}, async () => {
|
|
22825
22902
|
try {
|
|
@@ -22831,7 +22908,7 @@ function registerConnectionTools(server, api) {
|
|
|
22831
22908
|
});
|
|
22832
22909
|
server.registerTool("list_meta_destinations", {
|
|
22833
22910
|
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.",
|
|
22834
|
-
inputSchema:
|
|
22911
|
+
inputSchema: z89.object({}).shape,
|
|
22835
22912
|
annotations: READS_EXTERNAL,
|
|
22836
22913
|
_meta: {
|
|
22837
22914
|
"openai/widgetAccessible": true
|
|
@@ -22846,7 +22923,7 @@ function registerConnectionTools(server, api) {
|
|
|
22846
22923
|
});
|
|
22847
22924
|
server.registerTool("list_tiktok_advertisers", {
|
|
22848
22925
|
description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
|
|
22849
|
-
inputSchema:
|
|
22926
|
+
inputSchema: z89.object({}).shape,
|
|
22850
22927
|
annotations: READS_EXTERNAL
|
|
22851
22928
|
}, async () => {
|
|
22852
22929
|
try {
|
|
@@ -22860,12 +22937,12 @@ function registerConnectionTools(server, api) {
|
|
|
22860
22937
|
__name(registerConnectionTools, "registerConnectionTools");
|
|
22861
22938
|
|
|
22862
22939
|
// src/tools/actors.ts
|
|
22863
|
-
import { z as
|
|
22940
|
+
import { z as z90 } from "zod";
|
|
22864
22941
|
var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
|
|
22865
22942
|
function registerActorTools(server, api) {
|
|
22866
22943
|
server.registerTool("list_actors", {
|
|
22867
22944
|
description: listActorsGuidance.summary + " Devuelve id, nombre, descripci\xF3n, g\xE9nero y voz. Usa el `id` como `actorId` al crear o editar una tarea. Solo aparecen los personajes listos para usar; si la lista est\xE1 vac\xEDa, dile al usuario que cree uno en productmaker.app antes de intentar asignarlo. No modifica nada.",
|
|
22868
|
-
inputSchema:
|
|
22945
|
+
inputSchema: z90.object({}).shape,
|
|
22869
22946
|
annotations: READS_INTERNAL
|
|
22870
22947
|
}, async () => {
|
|
22871
22948
|
try {
|
|
@@ -22888,7 +22965,7 @@ function registerActorTools(server, api) {
|
|
|
22888
22965
|
__name(registerActorTools, "registerActorTools");
|
|
22889
22966
|
|
|
22890
22967
|
// src/tools/publish.ts
|
|
22891
|
-
import { z as
|
|
22968
|
+
import { z as z91 } from "zod";
|
|
22892
22969
|
|
|
22893
22970
|
// src/tools/meta-publish-attempt-id.ts
|
|
22894
22971
|
var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
|
|
@@ -22927,40 +23004,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
|
|
|
22927
23004
|
var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
|
|
22928
23005
|
var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
|
|
22929
23006
|
var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
|
|
22930
|
-
var ShopifyInput =
|
|
22931
|
-
taskId:
|
|
22932
|
-
shopDomain:
|
|
23007
|
+
var ShopifyInput = z91.object({
|
|
23008
|
+
taskId: z91.string().min(1),
|
|
23009
|
+
shopDomain: z91.string().min(1),
|
|
22933
23010
|
/** Override: number of landing images to include. Default = ALL images the
|
|
22934
23011
|
* task generated (the MCP fetches /v1/results first to count). Bounded
|
|
22935
23012
|
* generously here; the backend validates each index against
|
|
22936
23013
|
* landing.images.length and rejects out-of-range. */
|
|
22937
|
-
numLandingImages:
|
|
22938
|
-
variantIndex:
|
|
23014
|
+
numLandingImages: z91.number().int().min(1).max(20).optional(),
|
|
23015
|
+
variantIndex: z91.number().int().min(0).optional(),
|
|
22939
23016
|
/** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
|
|
22940
23017
|
* When true, the landing renders variant-picker pills; when false, it ships
|
|
22941
23018
|
* a single-option product page. Defaults to false. */
|
|
22942
|
-
showVariantPicker:
|
|
23019
|
+
showVariantPicker: z91.boolean().optional(),
|
|
22943
23020
|
/** Default `auto` updates the product previously published for this task and
|
|
22944
23021
|
* shop. Use `existing` with targetProductId to choose another product, or
|
|
22945
23022
|
* `new` only when the user explicitly wants a duplicate/new listing. */
|
|
22946
|
-
publicationMode:
|
|
23023
|
+
publicationMode: z91.enum([
|
|
22947
23024
|
"auto",
|
|
22948
23025
|
"existing",
|
|
22949
23026
|
"new"
|
|
22950
23027
|
]).optional(),
|
|
22951
23028
|
/** Shopify product GID, numeric id, or admin product URL. Required when
|
|
22952
23029
|
* publicationMode is `existing`. */
|
|
22953
|
-
targetProductId:
|
|
23030
|
+
targetProductId: z91.string().trim().min(1).max(300).optional(),
|
|
22954
23031
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
22955
|
-
announcementBarEnabled:
|
|
22956
|
-
announcementBarText:
|
|
23032
|
+
announcementBarEnabled: z91.boolean().optional(),
|
|
23033
|
+
announcementBarText: z91.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
|
|
22957
23034
|
commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
|
|
22958
|
-
confirmed:
|
|
23035
|
+
confirmed: z91.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
|
|
22959
23036
|
});
|
|
22960
23037
|
var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
|
|
22961
23038
|
if (value.commerceCorrection && value.confirmed !== true) {
|
|
22962
23039
|
ctx.addIssue({
|
|
22963
|
-
code:
|
|
23040
|
+
code: z91.ZodIssueCode.custom,
|
|
22964
23041
|
path: [
|
|
22965
23042
|
"confirmed"
|
|
22966
23043
|
],
|
|
@@ -22969,7 +23046,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
22969
23046
|
}
|
|
22970
23047
|
if (value.announcementBarEnabled && !value.announcementBarText) {
|
|
22971
23048
|
ctx.addIssue({
|
|
22972
|
-
code:
|
|
23049
|
+
code: z91.ZodIssueCode.custom,
|
|
22973
23050
|
path: [
|
|
22974
23051
|
"announcementBarText"
|
|
22975
23052
|
],
|
|
@@ -22978,7 +23055,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
22978
23055
|
}
|
|
22979
23056
|
if (!value.announcementBarEnabled && value.announcementBarText) {
|
|
22980
23057
|
ctx.addIssue({
|
|
22981
|
-
code:
|
|
23058
|
+
code: z91.ZodIssueCode.custom,
|
|
22982
23059
|
path: [
|
|
22983
23060
|
"announcementBarText"
|
|
22984
23061
|
],
|
|
@@ -22992,91 +23069,91 @@ function parseShopifyInput(rawInput) {
|
|
|
22992
23069
|
return parsed.data;
|
|
22993
23070
|
}
|
|
22994
23071
|
__name(parseShopifyInput, "parseShopifyInput");
|
|
22995
|
-
var McpCampaignConfig =
|
|
23072
|
+
var McpCampaignConfig = z91.object({
|
|
22996
23073
|
/** ALWAYS in US dollars, whatever the ad account's currency is. ProductMaker
|
|
22997
23074
|
* converts to the account currency server-side. Do NOT pre-convert: on a COP
|
|
22998
23075
|
* account the user's "60.000 al día" is `dailyBudgetUsd: 15`, not 60000. */
|
|
22999
|
-
dailyBudgetUsd:
|
|
23076
|
+
dailyBudgetUsd: z91.number().positive().optional(),
|
|
23000
23077
|
/** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
|
|
23001
23078
|
* normalizes at validation). Meta accepts max 1 (single-country ad set).
|
|
23002
23079
|
* TikTok takes only the first entry. */
|
|
23003
|
-
targetCountries:
|
|
23004
|
-
campaignName:
|
|
23080
|
+
targetCountries: z91.array(CountryIso2Schema).max(1).optional(),
|
|
23081
|
+
campaignName: z91.string().trim().min(1).max(100).optional()
|
|
23005
23082
|
});
|
|
23006
23083
|
var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
|
|
23007
|
-
var MetaInput =
|
|
23008
|
-
taskId:
|
|
23084
|
+
var MetaInput = z91.object({
|
|
23085
|
+
taskId: z91.string().min(1),
|
|
23009
23086
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
23010
|
-
portfolioId:
|
|
23087
|
+
portfolioId: z91.string().trim().min(1),
|
|
23011
23088
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
23012
|
-
pageId:
|
|
23089
|
+
pageId: z91.string().trim().min(1),
|
|
23013
23090
|
adAccountId: McpAdAccountId,
|
|
23014
|
-
pixelId:
|
|
23015
|
-
landingUrl:
|
|
23091
|
+
pixelId: z91.string().min(1).optional(),
|
|
23092
|
+
landingUrl: z91.string().url().optional(),
|
|
23016
23093
|
/** Select which angles to publish by 0-based index. Omit to publish all
|
|
23017
23094
|
* successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
|
|
23018
|
-
angleIndexes:
|
|
23095
|
+
angleIndexes: z91.array(z91.number().int().nonnegative()).optional(),
|
|
23019
23096
|
campaignConfig: McpCampaignConfig.optional(),
|
|
23020
23097
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
23021
23098
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
23022
23099
|
* (Meta's primary-text limit). */
|
|
23023
|
-
primaryText:
|
|
23100
|
+
primaryText: z91.string().trim().min(1).max(500).optional(),
|
|
23024
23101
|
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
23025
23102
|
* (wa.me) instead of a landing page. */
|
|
23026
|
-
phoneNumber:
|
|
23103
|
+
phoneNumber: z91.string().min(8).max(32).optional()
|
|
23027
23104
|
});
|
|
23028
|
-
var GroupedTaskSource =
|
|
23029
|
-
type:
|
|
23030
|
-
taskId:
|
|
23031
|
-
angleIndex:
|
|
23032
|
-
videoVariant:
|
|
23105
|
+
var GroupedTaskSource = z91.object({
|
|
23106
|
+
type: z91.literal("task"),
|
|
23107
|
+
taskId: z91.string().min(1),
|
|
23108
|
+
angleIndex: z91.number().int().min(0).optional(),
|
|
23109
|
+
videoVariant: z91.enum([
|
|
23033
23110
|
"with_subtitles",
|
|
23034
23111
|
"without_subtitles"
|
|
23035
23112
|
]).optional(),
|
|
23036
|
-
imageVariantIndex:
|
|
23037
|
-
});
|
|
23038
|
-
var GroupedMediaSource =
|
|
23039
|
-
type:
|
|
23040
|
-
url:
|
|
23041
|
-
path:
|
|
23042
|
-
thumbnailUrl:
|
|
23043
|
-
thumbnailPath:
|
|
23113
|
+
imageVariantIndex: z91.number().int().min(0).optional()
|
|
23114
|
+
});
|
|
23115
|
+
var GroupedMediaSource = z91.object({
|
|
23116
|
+
type: z91.literal("media"),
|
|
23117
|
+
url: z91.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
|
|
23118
|
+
path: z91.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".'),
|
|
23119
|
+
thumbnailUrl: z91.string().url().optional(),
|
|
23120
|
+
thumbnailPath: z91.string().min(1).optional()
|
|
23044
23121
|
}).refine((value) => Boolean(value.url) !== Boolean(value.path), {
|
|
23045
23122
|
message: "media source needs exactly one of `url` or `path`"
|
|
23046
23123
|
}).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
|
|
23047
23124
|
message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
|
|
23048
23125
|
});
|
|
23049
|
-
var GroupedUploadedAssetSource =
|
|
23050
|
-
type:
|
|
23126
|
+
var GroupedUploadedAssetSource = z91.object({
|
|
23127
|
+
type: z91.literal("asset"),
|
|
23051
23128
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
23052
|
-
assetId:
|
|
23053
|
-
thumbnailAssetId:
|
|
23129
|
+
assetId: z91.string().uuid(),
|
|
23130
|
+
thumbnailAssetId: z91.string().uuid().optional()
|
|
23054
23131
|
});
|
|
23055
|
-
var GroupedCreative =
|
|
23056
|
-
type:
|
|
23132
|
+
var GroupedCreative = z91.object({
|
|
23133
|
+
type: z91.enum([
|
|
23057
23134
|
"image",
|
|
23058
23135
|
"video"
|
|
23059
23136
|
]),
|
|
23060
|
-
source:
|
|
23137
|
+
source: z91.union([
|
|
23061
23138
|
GroupedTaskSource,
|
|
23062
23139
|
GroupedMediaSource,
|
|
23063
23140
|
GroupedUploadedAssetSource
|
|
23064
23141
|
]),
|
|
23065
|
-
title:
|
|
23066
|
-
description:
|
|
23142
|
+
title: z91.string().max(120).optional(),
|
|
23143
|
+
description: z91.string().max(500).optional(),
|
|
23067
23144
|
cta: MetaCtaType.optional(),
|
|
23068
|
-
creativeId:
|
|
23145
|
+
creativeId: z91.string().min(1).optional()
|
|
23069
23146
|
});
|
|
23070
|
-
var GroupedCampaignConfigBase =
|
|
23147
|
+
var GroupedCampaignConfigBase = z91.object({
|
|
23071
23148
|
campaignType: MetaCampaignType.default("sales"),
|
|
23072
23149
|
optimizationMode: MetaOptimizationMode.default("advantage_plus"),
|
|
23073
23150
|
budgetMode: MetaBudgetMode.optional(),
|
|
23074
|
-
campaignDailyBudget:
|
|
23075
|
-
adSets:
|
|
23076
|
-
tempId:
|
|
23077
|
-
name:
|
|
23078
|
-
dailyBudget:
|
|
23079
|
-
creativeIds:
|
|
23151
|
+
campaignDailyBudget: z91.number().int().positive().optional(),
|
|
23152
|
+
adSets: z91.array(z91.object({
|
|
23153
|
+
tempId: z91.string().min(1).max(80),
|
|
23154
|
+
name: z91.string().min(1).max(100),
|
|
23155
|
+
dailyBudget: z91.number().int().positive().optional(),
|
|
23156
|
+
creativeIds: z91.array(z91.string().min(1)).min(1)
|
|
23080
23157
|
})).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
|
|
23081
23158
|
/**
|
|
23082
23159
|
* Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
|
|
@@ -23084,17 +23161,17 @@ var GroupedCampaignConfigBase = z90.object({
|
|
|
23084
23161
|
* opaque `invalid_literal` and made the WhatsApp destination — supported by
|
|
23085
23162
|
* the API since #849 — unreachable from this tool.
|
|
23086
23163
|
*/
|
|
23087
|
-
destination:
|
|
23088
|
-
|
|
23089
|
-
type:
|
|
23090
|
-
landingUrl:
|
|
23164
|
+
destination: z91.discriminatedUnion("type", [
|
|
23165
|
+
z91.object({
|
|
23166
|
+
type: z91.literal("landing"),
|
|
23167
|
+
landingUrl: z91.string().url()
|
|
23091
23168
|
}),
|
|
23092
|
-
|
|
23093
|
-
type:
|
|
23094
|
-
phoneNumber:
|
|
23169
|
+
z91.object({
|
|
23170
|
+
type: z91.literal("whatsapp"),
|
|
23171
|
+
phoneNumber: z91.string().min(8).max(32)
|
|
23095
23172
|
})
|
|
23096
23173
|
]),
|
|
23097
|
-
saveAsDefault:
|
|
23174
|
+
saveAsDefault: z91.boolean().default(false),
|
|
23098
23175
|
budgetPolicy: MetaBudgetPolicy.optional()
|
|
23099
23176
|
});
|
|
23100
23177
|
function resolveBudgetMode(value) {
|
|
@@ -23108,7 +23185,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
23108
23185
|
const budgetMode = resolveBudgetMode(value);
|
|
23109
23186
|
if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
|
|
23110
23187
|
ctx.addIssue({
|
|
23111
|
-
code:
|
|
23188
|
+
code: z91.ZodIssueCode.custom,
|
|
23112
23189
|
path: [
|
|
23113
23190
|
"campaignDailyBudget"
|
|
23114
23191
|
],
|
|
@@ -23119,7 +23196,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
23119
23196
|
value.adSets.forEach((adSet, index) => {
|
|
23120
23197
|
if (adSet.dailyBudget === void 0) {
|
|
23121
23198
|
ctx.addIssue({
|
|
23122
|
-
code:
|
|
23199
|
+
code: z91.ZodIssueCode.custom,
|
|
23123
23200
|
path: [
|
|
23124
23201
|
"adSets",
|
|
23125
23202
|
index,
|
|
@@ -23134,28 +23211,28 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
23134
23211
|
...value,
|
|
23135
23212
|
budgetMode: resolveBudgetMode(value)
|
|
23136
23213
|
}));
|
|
23137
|
-
var PublishCreativesToMetaInputBase =
|
|
23138
|
-
creatives:
|
|
23214
|
+
var PublishCreativesToMetaInputBase = z91.object({
|
|
23215
|
+
creatives: z91.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
|
|
23139
23216
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
23140
|
-
portfolioId:
|
|
23217
|
+
portfolioId: z91.string().trim().min(1),
|
|
23141
23218
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
23142
|
-
pageId:
|
|
23219
|
+
pageId: z91.string().trim().min(1),
|
|
23143
23220
|
adAccountId: McpAdAccountId,
|
|
23144
|
-
pixelId:
|
|
23221
|
+
pixelId: z91.string().min(1).optional(),
|
|
23145
23222
|
/** Required unless `campaignConfig.destination` is whatsapp — see the
|
|
23146
23223
|
* superRefine below. Mirrors the API's `FacebookCreateCampaignFromTasksBodySchema`. */
|
|
23147
|
-
landingUrl:
|
|
23224
|
+
landingUrl: z91.string().url().optional(),
|
|
23148
23225
|
/** ISO-2 code or resolvable country name — mirrors the API contract
|
|
23149
23226
|
* (CountryIso2Schema), which normalizes names to alpha-2 at validation. */
|
|
23150
23227
|
targetCountry: CountryIso2Schema,
|
|
23151
|
-
campaignName:
|
|
23228
|
+
campaignName: z91.string().trim().min(1).max(100),
|
|
23152
23229
|
campaignConfig: GroupedCampaignConfig.optional()
|
|
23153
23230
|
});
|
|
23154
23231
|
var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
|
|
23155
23232
|
const destination = value.campaignConfig?.destination;
|
|
23156
23233
|
if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl) {
|
|
23157
23234
|
ctx.addIssue({
|
|
23158
|
-
code:
|
|
23235
|
+
code: z91.ZodIssueCode.custom,
|
|
23159
23236
|
path: [
|
|
23160
23237
|
"landingUrl"
|
|
23161
23238
|
],
|
|
@@ -23164,7 +23241,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
23164
23241
|
}
|
|
23165
23242
|
if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
|
|
23166
23243
|
ctx.addIssue({
|
|
23167
|
-
code:
|
|
23244
|
+
code: z91.ZodIssueCode.custom,
|
|
23168
23245
|
path: [
|
|
23169
23246
|
"campaignConfig",
|
|
23170
23247
|
"destination",
|
|
@@ -23183,16 +23260,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
23183
23260
|
}
|
|
23184
23261
|
return value;
|
|
23185
23262
|
});
|
|
23186
|
-
var PresignUploadResponseSchema =
|
|
23187
|
-
uploadUrl:
|
|
23263
|
+
var PresignUploadResponseSchema = z91.object({
|
|
23264
|
+
uploadUrl: z91.string().url().refine((value) => {
|
|
23188
23265
|
const url = new URL(value);
|
|
23189
23266
|
return !url.username && !url.password && url.protocol === "https:";
|
|
23190
23267
|
}, "presigned upload URL must be HTTPS without embedded credentials"),
|
|
23191
|
-
publicUrl:
|
|
23268
|
+
publicUrl: z91.string().url().refine((value) => {
|
|
23192
23269
|
const url = new URL(value);
|
|
23193
23270
|
return !url.username && !url.password;
|
|
23194
23271
|
}, "public media URL must not contain embedded credentials"),
|
|
23195
|
-
stagingAssetId:
|
|
23272
|
+
stagingAssetId: z91.string().uuid()
|
|
23196
23273
|
});
|
|
23197
23274
|
async function uploadResolvedMedia(api, media, assetRole) {
|
|
23198
23275
|
if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
|
|
@@ -23217,16 +23294,16 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
|
|
|
23217
23294
|
return uploadResolvedMedia(api, media, assetRole);
|
|
23218
23295
|
}
|
|
23219
23296
|
__name(resolveAndUploadMedia, "resolveAndUploadMedia");
|
|
23220
|
-
var TikTokInput =
|
|
23221
|
-
taskId:
|
|
23222
|
-
advertiserId:
|
|
23223
|
-
pixelId:
|
|
23224
|
-
landingUrl:
|
|
23225
|
-
angleIndexes:
|
|
23297
|
+
var TikTokInput = z91.object({
|
|
23298
|
+
taskId: z91.string().min(1),
|
|
23299
|
+
advertiserId: z91.string().min(1),
|
|
23300
|
+
pixelId: z91.string().min(1).optional(),
|
|
23301
|
+
landingUrl: z91.string().url().optional(),
|
|
23302
|
+
angleIndexes: z91.array(z91.number().int().nonnegative()).optional(),
|
|
23226
23303
|
campaignConfig: McpCampaignConfig.optional(),
|
|
23227
23304
|
/** Override the ad's description (TikTok's body copy). If omitted,
|
|
23228
23305
|
* ProductMaker uses the auto-generated copy attached to the task. */
|
|
23229
|
-
primaryText:
|
|
23306
|
+
primaryText: z91.string().trim().min(1).max(500).optional()
|
|
23230
23307
|
});
|
|
23231
23308
|
function registerPublishTools(server, api, opts = {}) {
|
|
23232
23309
|
const transport = opts.transport ?? "http";
|
|
@@ -23578,39 +23655,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
|
|
|
23578
23655
|
|
|
23579
23656
|
// src/tools/meta-upload.ts
|
|
23580
23657
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
23581
|
-
import { z as
|
|
23658
|
+
import { z as z92 } from "zod";
|
|
23582
23659
|
var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
|
|
23583
|
-
var UploadSessionInputBase =
|
|
23584
|
-
mediaKind:
|
|
23660
|
+
var UploadSessionInputBase = z92.object({
|
|
23661
|
+
mediaKind: z92.enum([
|
|
23585
23662
|
"image",
|
|
23586
23663
|
"video",
|
|
23587
23664
|
"mixed"
|
|
23588
23665
|
]).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."),
|
|
23589
|
-
assetRole:
|
|
23666
|
+
assetRole: z92.enum([
|
|
23590
23667
|
"media",
|
|
23591
23668
|
"thumbnail"
|
|
23592
23669
|
]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
|
|
23593
|
-
uploadPurpose:
|
|
23670
|
+
uploadPurpose: z92.enum([
|
|
23594
23671
|
"product_reference",
|
|
23595
23672
|
"creative",
|
|
23596
23673
|
"generic"
|
|
23597
23674
|
]).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."),
|
|
23598
|
-
maxFiles:
|
|
23675
|
+
maxFiles: z92.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
23599
23676
|
});
|
|
23600
|
-
var OpenAiFileReference =
|
|
23601
|
-
download_url:
|
|
23602
|
-
file_id:
|
|
23603
|
-
mime_type:
|
|
23604
|
-
file_name:
|
|
23677
|
+
var OpenAiFileReference = z92.object({
|
|
23678
|
+
download_url: z92.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."),
|
|
23679
|
+
file_id: z92.string().min(1),
|
|
23680
|
+
mime_type: z92.string().min(1).optional(),
|
|
23681
|
+
file_name: z92.string().min(1).optional()
|
|
23605
23682
|
});
|
|
23606
23683
|
var UploadSessionToolInputShape = {
|
|
23607
23684
|
...UploadSessionInputBase.shape,
|
|
23608
|
-
files:
|
|
23685
|
+
files: z92.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.")
|
|
23609
23686
|
};
|
|
23610
|
-
var UploadSessionToolInput =
|
|
23687
|
+
var UploadSessionToolInput = z92.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
23611
23688
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
23612
23689
|
ctx.addIssue({
|
|
23613
|
-
code:
|
|
23690
|
+
code: z92.ZodIssueCode.custom,
|
|
23614
23691
|
path: [
|
|
23615
23692
|
"mediaKind"
|
|
23616
23693
|
],
|
|
@@ -23619,7 +23696,7 @@ var UploadSessionToolInput = z91.object(UploadSessionToolInputShape).superRefine
|
|
|
23619
23696
|
}
|
|
23620
23697
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
23621
23698
|
ctx.addIssue({
|
|
23622
|
-
code:
|
|
23699
|
+
code: z92.ZodIssueCode.custom,
|
|
23623
23700
|
path: [
|
|
23624
23701
|
"maxFiles"
|
|
23625
23702
|
],
|
|
@@ -23628,7 +23705,7 @@ var UploadSessionToolInput = z91.object(UploadSessionToolInputShape).superRefine
|
|
|
23628
23705
|
}
|
|
23629
23706
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
|
|
23630
23707
|
ctx.addIssue({
|
|
23631
|
-
code:
|
|
23708
|
+
code: z92.ZodIssueCode.custom,
|
|
23632
23709
|
path: [
|
|
23633
23710
|
"maxFiles"
|
|
23634
23711
|
],
|
|
@@ -23636,38 +23713,38 @@ var UploadSessionToolInput = z91.object(UploadSessionToolInputShape).superRefine
|
|
|
23636
23713
|
});
|
|
23637
23714
|
}
|
|
23638
23715
|
});
|
|
23639
|
-
var UploadSessionResponse =
|
|
23640
|
-
sessionId:
|
|
23641
|
-
uploadPageUrl:
|
|
23642
|
-
mediaKind:
|
|
23716
|
+
var UploadSessionResponse = z92.object({
|
|
23717
|
+
sessionId: z92.string().uuid(),
|
|
23718
|
+
uploadPageUrl: z92.string().url(),
|
|
23719
|
+
mediaKind: z92.enum([
|
|
23643
23720
|
"image",
|
|
23644
23721
|
"video",
|
|
23645
23722
|
"mixed"
|
|
23646
23723
|
]),
|
|
23647
|
-
assetRole:
|
|
23724
|
+
assetRole: z92.enum([
|
|
23648
23725
|
"media",
|
|
23649
23726
|
"thumbnail"
|
|
23650
23727
|
]),
|
|
23651
|
-
maxFiles:
|
|
23652
|
-
expiresAt:
|
|
23728
|
+
maxFiles: z92.number().int().positive(),
|
|
23729
|
+
expiresAt: z92.string().datetime()
|
|
23653
23730
|
});
|
|
23654
|
-
var UploadStatusInput =
|
|
23655
|
-
sessionId:
|
|
23731
|
+
var UploadStatusInput = z92.object({
|
|
23732
|
+
sessionId: z92.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
23656
23733
|
});
|
|
23657
|
-
var UniversalUploadStatusResponse =
|
|
23658
|
-
|
|
23659
|
-
status:
|
|
23660
|
-
assets:
|
|
23734
|
+
var UniversalUploadStatusResponse = z92.discriminatedUnion("status", [
|
|
23735
|
+
z92.object({
|
|
23736
|
+
status: z92.literal("pending"),
|
|
23737
|
+
assets: z92.array(z92.never()).length(0)
|
|
23661
23738
|
}),
|
|
23662
|
-
|
|
23663
|
-
status:
|
|
23664
|
-
assets:
|
|
23665
|
-
assetId:
|
|
23666
|
-
mediaKind:
|
|
23739
|
+
z92.object({
|
|
23740
|
+
status: z92.literal("uploaded"),
|
|
23741
|
+
assets: z92.array(z92.object({
|
|
23742
|
+
assetId: z92.string().uuid(),
|
|
23743
|
+
mediaKind: z92.enum([
|
|
23667
23744
|
"image",
|
|
23668
23745
|
"video"
|
|
23669
23746
|
]),
|
|
23670
|
-
assetRole:
|
|
23747
|
+
assetRole: z92.enum([
|
|
23671
23748
|
"media",
|
|
23672
23749
|
"thumbnail"
|
|
23673
23750
|
])
|
|
@@ -23675,13 +23752,13 @@ var UniversalUploadStatusResponse = z91.discriminatedUnion("status", [
|
|
|
23675
23752
|
})
|
|
23676
23753
|
]);
|
|
23677
23754
|
var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
|
|
23678
|
-
uploadPurpose:
|
|
23755
|
+
uploadPurpose: z92.enum([
|
|
23679
23756
|
"product_reference",
|
|
23680
23757
|
"creative",
|
|
23681
23758
|
"generic"
|
|
23682
23759
|
]),
|
|
23683
|
-
checkToolName:
|
|
23684
|
-
resolveEndpoint:
|
|
23760
|
+
checkToolName: z92.literal("check_media_upload"),
|
|
23761
|
+
resolveEndpoint: z92.string().url()
|
|
23685
23762
|
});
|
|
23686
23763
|
function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
|
|
23687
23764
|
const url = new URL(uploadPageUrl);
|
|
@@ -23772,15 +23849,15 @@ function registerMediaUploadTools(server, api) {
|
|
|
23772
23849
|
__name(registerMediaUploadTools, "registerMediaUploadTools");
|
|
23773
23850
|
|
|
23774
23851
|
// src/tools/campaigns.ts
|
|
23775
|
-
import { z as
|
|
23852
|
+
import { z as z93 } from "zod";
|
|
23776
23853
|
var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
|
|
23777
23854
|
var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
|
|
23778
|
-
var MetaStatusInput =
|
|
23779
|
-
campaignId:
|
|
23855
|
+
var MetaStatusInput = z93.object({
|
|
23856
|
+
campaignId: z93.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
|
|
23780
23857
|
});
|
|
23781
|
-
var TikTokStatusInput =
|
|
23782
|
-
campaignId:
|
|
23783
|
-
advertiserId:
|
|
23858
|
+
var TikTokStatusInput = z93.object({
|
|
23859
|
+
campaignId: z93.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
|
|
23860
|
+
advertiserId: z93.string().min(1).describe("The same advertiserId used to publish the campaign.")
|
|
23784
23861
|
});
|
|
23785
23862
|
function registerCampaignTools(server, api) {
|
|
23786
23863
|
server.registerTool("get_meta_campaign_status", {
|
|
@@ -23885,10 +23962,10 @@ function renderTikTokStatusMarkdown(r) {
|
|
|
23885
23962
|
__name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
|
|
23886
23963
|
|
|
23887
23964
|
// ../../packages/product-economics/src/product-costing.ts
|
|
23888
|
-
import { z as
|
|
23965
|
+
import { z as z95 } from "zod";
|
|
23889
23966
|
|
|
23890
23967
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
23891
|
-
import { z as
|
|
23968
|
+
import { z as z94 } from "zod";
|
|
23892
23969
|
|
|
23893
23970
|
// ../../packages/product-economics/src/product-costing-shipping-references.json
|
|
23894
23971
|
var product_costing_shipping_references_default = {
|
|
@@ -23952,21 +24029,21 @@ var product_costing_shipping_references_default = {
|
|
|
23952
24029
|
};
|
|
23953
24030
|
|
|
23954
24031
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
23955
|
-
var ShippingReferenceSchema =
|
|
23956
|
-
reference:
|
|
23957
|
-
min:
|
|
23958
|
-
max:
|
|
23959
|
-
updatedAt:
|
|
23960
|
-
confidence:
|
|
24032
|
+
var ShippingReferenceSchema = z94.object({
|
|
24033
|
+
reference: z94.number().positive(),
|
|
24034
|
+
min: z94.number().nonnegative(),
|
|
24035
|
+
max: z94.number().positive(),
|
|
24036
|
+
updatedAt: z94.string().date(),
|
|
24037
|
+
confidence: z94.enum([
|
|
23961
24038
|
"high",
|
|
23962
24039
|
"medium",
|
|
23963
24040
|
"medium-low"
|
|
23964
24041
|
]),
|
|
23965
|
-
sources:
|
|
24042
|
+
sources: z94.array(z94.string().url().startsWith("https://")).min(1).max(3)
|
|
23966
24043
|
}).superRefine(({ reference, min, max }, context) => {
|
|
23967
24044
|
if (min > reference || reference > max) {
|
|
23968
24045
|
context.addIssue({
|
|
23969
|
-
code:
|
|
24046
|
+
code: z94.ZodIssueCode.custom,
|
|
23970
24047
|
message: "shipping_reference_outside_range",
|
|
23971
24048
|
path: [
|
|
23972
24049
|
"reference"
|
|
@@ -23974,7 +24051,7 @@ var ShippingReferenceSchema = z93.object({
|
|
|
23974
24051
|
});
|
|
23975
24052
|
}
|
|
23976
24053
|
});
|
|
23977
|
-
var SHIPPING_REFERENCES =
|
|
24054
|
+
var SHIPPING_REFERENCES = z94.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
|
|
23978
24055
|
var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
|
|
23979
24056
|
var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
|
|
23980
24057
|
"MX",
|
|
@@ -24156,18 +24233,18 @@ function getProductCostingCountryName(country) {
|
|
|
24156
24233
|
__name(getProductCostingCountryName, "getProductCostingCountryName");
|
|
24157
24234
|
|
|
24158
24235
|
// ../../packages/product-economics/src/product-costing.ts
|
|
24159
|
-
var ProductCostingInputSchema =
|
|
24160
|
-
country:
|
|
24161
|
-
supplierCost:
|
|
24162
|
-
shippingCost:
|
|
24163
|
-
returnRate:
|
|
24164
|
-
cancellationRate:
|
|
24165
|
-
adsManagerCpa:
|
|
24166
|
-
desiredMargin:
|
|
24236
|
+
var ProductCostingInputSchema = z95.object({
|
|
24237
|
+
country: z95.string().refine(isProductCostingCountryCode, "unsupported_country"),
|
|
24238
|
+
supplierCost: z95.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
|
|
24239
|
+
shippingCost: z95.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
|
|
24240
|
+
returnRate: z95.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
24241
|
+
cancellationRate: z95.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
24242
|
+
adsManagerCpa: z95.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
|
|
24243
|
+
desiredMargin: z95.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
|
|
24167
24244
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
24168
24245
|
if (returnRate + cancellationRate >= 1) {
|
|
24169
24246
|
context.addIssue({
|
|
24170
|
-
code:
|
|
24247
|
+
code: z95.ZodIssueCode.custom,
|
|
24171
24248
|
message: "delivery_rate_positive",
|
|
24172
24249
|
path: [
|
|
24173
24250
|
"cancellationRate"
|
|
@@ -24264,15 +24341,15 @@ function calculateProductCosting(rawInput) {
|
|
|
24264
24341
|
__name(calculateProductCosting, "calculateProductCosting");
|
|
24265
24342
|
|
|
24266
24343
|
// src/tools/product-costing.ts
|
|
24267
|
-
import { z as
|
|
24344
|
+
import { z as z96 } from "zod";
|
|
24268
24345
|
var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
|
|
24269
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
24270
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
24271
|
-
var ProductCostingToolInput =
|
|
24272
|
-
country:
|
|
24346
|
+
var optionalAmount = /* @__PURE__ */ __name((description) => z96.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
|
|
24347
|
+
var optionalPercent = /* @__PURE__ */ __name((description) => z96.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
|
|
24348
|
+
var ProductCostingToolInput = z96.object({
|
|
24349
|
+
country: z96.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
24273
24350
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
24274
24351
|
}).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
|
|
24275
|
-
supplierCost:
|
|
24352
|
+
supplierCost: z96.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."),
|
|
24276
24353
|
supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
|
|
24277
24354
|
shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
|
|
24278
24355
|
shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
|
|
@@ -24435,7 +24512,7 @@ function formatPercent(value) {
|
|
|
24435
24512
|
__name(formatPercent, "formatPercent");
|
|
24436
24513
|
|
|
24437
24514
|
// src/tools/product-research.ts
|
|
24438
|
-
import { z as
|
|
24515
|
+
import { z as z97 } from "zod";
|
|
24439
24516
|
|
|
24440
24517
|
// src/tools/product-research-idempotency.ts
|
|
24441
24518
|
var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
|
|
@@ -24806,17 +24883,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
|
|
|
24806
24883
|
]);
|
|
24807
24884
|
var POLL_INTERVAL_MS = 5e3;
|
|
24808
24885
|
var MAX_WAIT_SECONDS = 120;
|
|
24809
|
-
var FindInput =
|
|
24886
|
+
var FindInput = z97.object({
|
|
24810
24887
|
targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
|
|
24811
24888
|
categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
|
|
24812
|
-
confirmed:
|
|
24813
|
-
waitSeconds:
|
|
24889
|
+
confirmed: z97.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
|
|
24890
|
+
waitSeconds: z97.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
|
|
24814
24891
|
});
|
|
24815
|
-
var GetInput =
|
|
24816
|
-
runId:
|
|
24892
|
+
var GetInput = z97.object({
|
|
24893
|
+
runId: z97.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
24817
24894
|
});
|
|
24818
|
-
var ListInput =
|
|
24819
|
-
limit:
|
|
24895
|
+
var ListInput = z97.object({
|
|
24896
|
+
limit: z97.number().int().min(1).max(20).default(10)
|
|
24820
24897
|
});
|
|
24821
24898
|
function textResult(text2) {
|
|
24822
24899
|
return {
|
|
@@ -24955,17 +25032,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
24955
25032
|
__name(registerProductResearchTools, "registerProductResearchTools");
|
|
24956
25033
|
|
|
24957
25034
|
// src/tools/dropshipping-projects.ts
|
|
24958
|
-
import { z as
|
|
25035
|
+
import { z as z98 } from "zod";
|
|
24959
25036
|
var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
|
|
24960
25037
|
var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
|
|
24961
25038
|
var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
|
|
24962
|
-
var ProjectId =
|
|
24963
|
-
var DropshippingProjectStatus =
|
|
25039
|
+
var ProjectId = z98.string().uuid();
|
|
25040
|
+
var DropshippingProjectStatus = z98.enum([
|
|
24964
25041
|
"active",
|
|
24965
25042
|
"completed",
|
|
24966
25043
|
"archived"
|
|
24967
25044
|
]);
|
|
24968
|
-
var DropshippingProjectPhase =
|
|
25045
|
+
var DropshippingProjectPhase = z98.enum([
|
|
24969
25046
|
"research",
|
|
24970
25047
|
"costing",
|
|
24971
25048
|
"media",
|
|
@@ -24974,21 +25051,21 @@ var DropshippingProjectPhase = z97.enum([
|
|
|
24974
25051
|
"advertising",
|
|
24975
25052
|
"complete"
|
|
24976
25053
|
]);
|
|
24977
|
-
var DropshippingRewardMilestone =
|
|
25054
|
+
var DropshippingRewardMilestone = z98.enum([
|
|
24978
25055
|
"product_selected",
|
|
24979
25056
|
"costing_saved",
|
|
24980
25057
|
"product_media_ready",
|
|
24981
25058
|
"creatives_completed",
|
|
24982
25059
|
"campaign_created"
|
|
24983
25060
|
]);
|
|
24984
|
-
var TargetCountry =
|
|
25061
|
+
var TargetCountry = z98.enum([
|
|
24985
25062
|
"CO",
|
|
24986
25063
|
"MX",
|
|
24987
25064
|
"PE",
|
|
24988
25065
|
"EC",
|
|
24989
25066
|
"CL"
|
|
24990
25067
|
]);
|
|
24991
|
-
var ResearchCategory =
|
|
25068
|
+
var ResearchCategory = z98.enum([
|
|
24992
25069
|
"auto",
|
|
24993
25070
|
"automotive",
|
|
24994
25071
|
"kitchen",
|
|
@@ -25003,7 +25080,7 @@ var ResearchCategory = z97.enum([
|
|
|
25003
25080
|
"garden",
|
|
25004
25081
|
"cleaning"
|
|
25005
25082
|
]);
|
|
25006
|
-
var HttpUrl3 =
|
|
25083
|
+
var HttpUrl3 = z98.string().url().max(2e3).refine((value) => {
|
|
25007
25084
|
try {
|
|
25008
25085
|
return [
|
|
25009
25086
|
"http:",
|
|
@@ -25013,45 +25090,45 @@ var HttpUrl3 = z97.string().url().max(2e3).refine((value) => {
|
|
|
25013
25090
|
return false;
|
|
25014
25091
|
}
|
|
25015
25092
|
}, "URL must use HTTP(S)");
|
|
25016
|
-
var ResearchCandidateOrigin =
|
|
25017
|
-
type:
|
|
25093
|
+
var ResearchCandidateOrigin = z98.object({
|
|
25094
|
+
type: z98.literal("research_candidate"),
|
|
25018
25095
|
runId: ProjectId,
|
|
25019
|
-
candidateSourceId:
|
|
25096
|
+
candidateSourceId: z98.string().min(1).max(160)
|
|
25020
25097
|
});
|
|
25021
|
-
var TaskOrigin =
|
|
25022
|
-
type:
|
|
25098
|
+
var TaskOrigin = z98.object({
|
|
25099
|
+
type: z98.literal("task"),
|
|
25023
25100
|
taskId: ProjectId
|
|
25024
25101
|
});
|
|
25025
|
-
var ManualOrigin =
|
|
25026
|
-
type:
|
|
25102
|
+
var ManualOrigin = z98.object({
|
|
25103
|
+
type: z98.literal("manual"),
|
|
25027
25104
|
clientRequestId: ProjectId,
|
|
25028
|
-
country:
|
|
25105
|
+
country: z98.string().min(2).max(3).optional()
|
|
25029
25106
|
});
|
|
25030
|
-
var StartProjectInput =
|
|
25031
|
-
origin:
|
|
25107
|
+
var StartProjectInput = z98.object({
|
|
25108
|
+
origin: z98.discriminatedUnion("type", [
|
|
25032
25109
|
ResearchCandidateOrigin,
|
|
25033
25110
|
TaskOrigin,
|
|
25034
25111
|
ManualOrigin
|
|
25035
25112
|
]),
|
|
25036
|
-
productName:
|
|
25113
|
+
productName: z98.string().trim().min(1).max(240).optional(),
|
|
25037
25114
|
productUrl: HttpUrl3.optional(),
|
|
25038
|
-
country:
|
|
25039
|
-
languageCode:
|
|
25115
|
+
country: z98.string().min(2).max(3).optional(),
|
|
25116
|
+
languageCode: z98.string().min(2).max(16).optional()
|
|
25040
25117
|
}).strict();
|
|
25041
|
-
var CostProjectInput =
|
|
25118
|
+
var CostProjectInput = z98.object({
|
|
25042
25119
|
projectId: ProjectId,
|
|
25043
|
-
version:
|
|
25044
|
-
country:
|
|
25120
|
+
version: z98.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
|
|
25121
|
+
country: z98.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
25045
25122
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
25046
25123
|
}).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
|
|
25047
|
-
supplierCost:
|
|
25048
|
-
shippingCost:
|
|
25049
|
-
returnRate:
|
|
25050
|
-
cancellationRate:
|
|
25051
|
-
adsManagerCpa:
|
|
25052
|
-
desiredMargin:
|
|
25053
|
-
});
|
|
25054
|
-
var GuideInput =
|
|
25124
|
+
supplierCost: z98.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."),
|
|
25125
|
+
shippingCost: z98.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
|
|
25126
|
+
returnRate: z98.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."),
|
|
25127
|
+
cancellationRate: z98.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."),
|
|
25128
|
+
adsManagerCpa: z98.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
25129
|
+
desiredMargin: z98.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
|
|
25130
|
+
});
|
|
25131
|
+
var GuideInput = z98.object({
|
|
25055
25132
|
projectId: ProjectId.optional()
|
|
25056
25133
|
}).strict();
|
|
25057
25134
|
var NEXT_ACTION_KINDS = [
|
|
@@ -25069,29 +25146,29 @@ var NEXT_ACTION_KINDS = [
|
|
|
25069
25146
|
"repair_meta_campaign",
|
|
25070
25147
|
"review_paused_campaign"
|
|
25071
25148
|
];
|
|
25072
|
-
var DropshippingProjectNextAction =
|
|
25073
|
-
kind:
|
|
25074
|
-
href:
|
|
25149
|
+
var DropshippingProjectNextAction = z98.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z98.object({
|
|
25150
|
+
kind: z98.literal(kind),
|
|
25151
|
+
href: z98.string().min(1)
|
|
25075
25152
|
})));
|
|
25076
|
-
var CostingInputSchema =
|
|
25077
|
-
country:
|
|
25078
|
-
supplierCost:
|
|
25079
|
-
shippingCost:
|
|
25080
|
-
returnRate:
|
|
25081
|
-
cancellationRate:
|
|
25082
|
-
adsManagerCpa:
|
|
25083
|
-
desiredMargin:
|
|
25153
|
+
var CostingInputSchema = z98.object({
|
|
25154
|
+
country: z98.string().min(2).max(3),
|
|
25155
|
+
supplierCost: z98.number().finite().positive(),
|
|
25156
|
+
shippingCost: z98.number().finite().nonnegative(),
|
|
25157
|
+
returnRate: z98.number().finite().min(0).lt(1),
|
|
25158
|
+
cancellationRate: z98.number().finite().min(0).lt(1),
|
|
25159
|
+
adsManagerCpa: z98.number().finite().nonnegative(),
|
|
25160
|
+
desiredMargin: z98.number().finite().min(0).lt(1)
|
|
25084
25161
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
25085
25162
|
if (returnRate + cancellationRate >= 1) context.addIssue({
|
|
25086
|
-
code:
|
|
25163
|
+
code: z98.ZodIssueCode.custom,
|
|
25087
25164
|
path: [
|
|
25088
25165
|
"cancellationRate"
|
|
25089
25166
|
]
|
|
25090
25167
|
});
|
|
25091
25168
|
});
|
|
25092
|
-
var FiniteCostingNumber =
|
|
25093
|
-
var CostingResultSchema =
|
|
25094
|
-
country:
|
|
25169
|
+
var FiniteCostingNumber = z98.number().finite();
|
|
25170
|
+
var CostingResultSchema = z98.object({
|
|
25171
|
+
country: z98.string().min(2).max(3),
|
|
25095
25172
|
deliveryRate: FiniteCostingNumber,
|
|
25096
25173
|
adjustedShippingCost: FiniteCostingNumber,
|
|
25097
25174
|
adjustedCpa: FiniteCostingNumber,
|
|
@@ -25104,45 +25181,45 @@ var CostingResultSchema = z97.object({
|
|
|
25104
25181
|
estimatedProfit: FiniteCostingNumber,
|
|
25105
25182
|
actualMargin: FiniteCostingNumber,
|
|
25106
25183
|
breakEvenAdsManagerCpa: FiniteCostingNumber,
|
|
25107
|
-
wasPriceAutoAdjusted:
|
|
25108
|
-
profitabilityStatus:
|
|
25109
|
-
});
|
|
25110
|
-
var RewardProgressSchema =
|
|
25111
|
-
campaignKey:
|
|
25112
|
-
totalCredits:
|
|
25113
|
-
earnedCredits:
|
|
25114
|
-
milestones:
|
|
25184
|
+
wasPriceAutoAdjusted: z98.boolean(),
|
|
25185
|
+
profitabilityStatus: z98.literal("healthy")
|
|
25186
|
+
});
|
|
25187
|
+
var RewardProgressSchema = z98.object({
|
|
25188
|
+
campaignKey: z98.literal("dropshipping-launch-v1"),
|
|
25189
|
+
totalCredits: z98.number().int().positive(),
|
|
25190
|
+
earnedCredits: z98.number().int().nonnegative(),
|
|
25191
|
+
milestones: z98.array(z98.object({
|
|
25115
25192
|
milestone: DropshippingRewardMilestone,
|
|
25116
|
-
credits:
|
|
25117
|
-
available:
|
|
25118
|
-
earned:
|
|
25193
|
+
credits: z98.number().int().positive(),
|
|
25194
|
+
available: z98.boolean().optional(),
|
|
25195
|
+
earned: z98.boolean(),
|
|
25119
25196
|
grantId: ProjectId.nullable(),
|
|
25120
|
-
grantedAt:
|
|
25197
|
+
grantedAt: z98.string().datetime().nullable()
|
|
25121
25198
|
})).length(DropshippingRewardMilestone.options.length)
|
|
25122
25199
|
});
|
|
25123
|
-
var ProjectResponseSchema =
|
|
25200
|
+
var ProjectResponseSchema = z98.object({
|
|
25124
25201
|
id: ProjectId,
|
|
25125
25202
|
taskId: ProjectId.nullable(),
|
|
25126
25203
|
status: DropshippingProjectStatus,
|
|
25127
|
-
originKey:
|
|
25204
|
+
originKey: z98.string().min(1),
|
|
25128
25205
|
researchRunId: ProjectId.nullable(),
|
|
25129
|
-
candidateSourceId:
|
|
25130
|
-
productName:
|
|
25206
|
+
candidateSourceId: z98.string().nullable(),
|
|
25207
|
+
productName: z98.string().nullable(),
|
|
25131
25208
|
productUrl: HttpUrl3.nullable(),
|
|
25132
25209
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
25133
|
-
targetCountry:
|
|
25134
|
-
languageCode:
|
|
25135
|
-
hasReferenceImage:
|
|
25136
|
-
hasWinnerReferenceImage:
|
|
25210
|
+
targetCountry: z98.string().nullable(),
|
|
25211
|
+
languageCode: z98.string().nullable(),
|
|
25212
|
+
hasReferenceImage: z98.boolean(),
|
|
25213
|
+
hasWinnerReferenceImage: z98.boolean(),
|
|
25137
25214
|
costingInput: CostingInputSchema.nullable(),
|
|
25138
25215
|
costingResult: CostingResultSchema.nullable(),
|
|
25139
|
-
costingVersion:
|
|
25140
|
-
version:
|
|
25216
|
+
costingVersion: z98.number().int().positive().nullable(),
|
|
25217
|
+
version: z98.number().int().positive(),
|
|
25141
25218
|
phase: DropshippingProjectPhase,
|
|
25142
25219
|
nextAction: DropshippingProjectNextAction.nullable(),
|
|
25143
25220
|
rewards: RewardProgressSchema,
|
|
25144
|
-
createdAt:
|
|
25145
|
-
updatedAt:
|
|
25221
|
+
createdAt: z98.string().datetime(),
|
|
25222
|
+
updatedAt: z98.string().datetime()
|
|
25146
25223
|
}).passthrough();
|
|
25147
25224
|
var NEXT_ACTION_GUIDANCE = {
|
|
25148
25225
|
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.",
|
|
@@ -25262,58 +25339,58 @@ function registerDropshippingProjectTools(server, api) {
|
|
|
25262
25339
|
__name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
|
|
25263
25340
|
|
|
25264
25341
|
// src/tools/daily-control.ts
|
|
25265
|
-
import { z as
|
|
25342
|
+
import { z as z99 } from "zod";
|
|
25266
25343
|
var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
|
|
25267
25344
|
var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
|
|
25268
25345
|
var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
|
|
25269
|
-
var ProviderCampaignIdentifier =
|
|
25270
|
-
var DateOnly =
|
|
25271
|
-
var DailyControlInput =
|
|
25346
|
+
var ProviderCampaignIdentifier = z99.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
|
|
25347
|
+
var DateOnly = z99.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
25348
|
+
var DailyControlInput = z99.object({
|
|
25272
25349
|
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."),
|
|
25273
|
-
days:
|
|
25274
|
-
projectId:
|
|
25350
|
+
days: z99.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
25351
|
+
projectId: z99.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
|
|
25275
25352
|
}).strict();
|
|
25276
|
-
var LinkCampaignInput =
|
|
25277
|
-
projectId:
|
|
25278
|
-
provider:
|
|
25353
|
+
var LinkCampaignInput = z99.object({
|
|
25354
|
+
projectId: z99.string().uuid(),
|
|
25355
|
+
provider: z99.enum([
|
|
25279
25356
|
"meta",
|
|
25280
25357
|
"tiktok"
|
|
25281
25358
|
]),
|
|
25282
25359
|
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."),
|
|
25283
25360
|
campaignId: ProviderCampaignIdentifier
|
|
25284
25361
|
}).strict();
|
|
25285
|
-
var ReportReturnsInput =
|
|
25286
|
-
projectId:
|
|
25362
|
+
var ReportReturnsInput = z99.object({
|
|
25363
|
+
projectId: z99.string().uuid(),
|
|
25287
25364
|
date: DateOnly,
|
|
25288
|
-
returnedOrders:
|
|
25289
|
-
note:
|
|
25365
|
+
returnedOrders: z99.number().int().min(0).max(1e5),
|
|
25366
|
+
note: z99.string().trim().max(280).optional()
|
|
25290
25367
|
}).strict();
|
|
25291
|
-
var DailyControlStatusMirror = DailyControlStatusEnum.or(
|
|
25292
|
-
var DailyControlLightMirror = DailyControlLightEnum.or(
|
|
25293
|
-
var DailyControlSourceMirror = DailyControlSourceEnum.or(
|
|
25294
|
-
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(
|
|
25295
|
-
var DailyControlDayMirror =
|
|
25296
|
-
date:
|
|
25297
|
-
returnedOrders:
|
|
25368
|
+
var DailyControlStatusMirror = DailyControlStatusEnum.or(z99.string());
|
|
25369
|
+
var DailyControlLightMirror = DailyControlLightEnum.or(z99.string());
|
|
25370
|
+
var DailyControlSourceMirror = DailyControlSourceEnum.or(z99.string());
|
|
25371
|
+
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z99.string());
|
|
25372
|
+
var DailyControlDayMirror = z99.object({
|
|
25373
|
+
date: z99.string(),
|
|
25374
|
+
returnedOrders: z99.number(),
|
|
25298
25375
|
returnedSource: DailyControlSourceMirror,
|
|
25299
25376
|
cancelledSource: DailyControlSourceMirror,
|
|
25300
|
-
hasEstimates:
|
|
25377
|
+
hasEstimates: z99.boolean(),
|
|
25301
25378
|
light: DailyControlLightMirror
|
|
25302
25379
|
}).passthrough();
|
|
25303
|
-
var DailyControlProductMirror =
|
|
25304
|
-
projectId:
|
|
25305
|
-
productName:
|
|
25380
|
+
var DailyControlProductMirror = z99.object({
|
|
25381
|
+
projectId: z99.string().uuid(),
|
|
25382
|
+
productName: z99.string().nullable(),
|
|
25306
25383
|
status: DailyControlStatusMirror,
|
|
25307
|
-
statusMessage:
|
|
25308
|
-
days:
|
|
25384
|
+
statusMessage: z99.string().nullable(),
|
|
25385
|
+
days: z99.array(DailyControlDayMirror),
|
|
25309
25386
|
verdict: DailyControlVerdictMirror.nullable(),
|
|
25310
|
-
rationale:
|
|
25387
|
+
rationale: z99.string().nullable()
|
|
25311
25388
|
}).passthrough();
|
|
25312
|
-
var DailyControlResponseMirror =
|
|
25313
|
-
since:
|
|
25314
|
-
until:
|
|
25315
|
-
products:
|
|
25316
|
-
archivedProjectSpend:
|
|
25389
|
+
var DailyControlResponseMirror = z99.object({
|
|
25390
|
+
since: z99.string(),
|
|
25391
|
+
until: z99.string(),
|
|
25392
|
+
products: z99.array(DailyControlProductMirror),
|
|
25393
|
+
archivedProjectSpend: z99.array(z99.unknown())
|
|
25317
25394
|
}).passthrough();
|
|
25318
25395
|
var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
|
|
25319
25396
|
function withWarnings(response) {
|
|
@@ -25388,7 +25465,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
|
|
|
25388
25465
|
// src/tools/product-control.ts
|
|
25389
25466
|
import { readFile, stat } from "fs/promises";
|
|
25390
25467
|
import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
|
|
25391
|
-
import { z as
|
|
25468
|
+
import { z as z100 } from "zod";
|
|
25392
25469
|
var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
|
|
25393
25470
|
var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
|
|
25394
25471
|
var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
|
|
@@ -25401,36 +25478,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
|
|
|
25401
25478
|
var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
|
|
25402
25479
|
var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
|
|
25403
25480
|
var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
|
|
25404
|
-
var DateOnly2 =
|
|
25481
|
+
var DateOnly2 = z100.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
25405
25482
|
var IMPORT_BATCH_MAX2 = 50;
|
|
25406
|
-
var ProductControlListInput =
|
|
25407
|
-
days:
|
|
25483
|
+
var ProductControlListInput = z100.object({
|
|
25484
|
+
days: z100.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
25408
25485
|
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."),
|
|
25409
|
-
shopDomain:
|
|
25486
|
+
shopDomain: z100.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
25410
25487
|
}).strict();
|
|
25411
|
-
var ImportableProductsInput =
|
|
25412
|
-
q:
|
|
25413
|
-
after:
|
|
25414
|
-
shopDomain:
|
|
25488
|
+
var ImportableProductsInput = z100.object({
|
|
25489
|
+
q: z100.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
|
|
25490
|
+
after: z100.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
|
|
25491
|
+
shopDomain: z100.string().min(1).optional()
|
|
25415
25492
|
}).strict();
|
|
25416
|
-
var ImportProductControlsInput =
|
|
25417
|
-
shopifyProductIds:
|
|
25493
|
+
var ImportProductControlsInput = z100.object({
|
|
25494
|
+
shopifyProductIds: z100.array(z100.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."),
|
|
25418
25495
|
// Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
|
|
25419
25496
|
// sin decir a cuál archivaría el producto bajo la tienda equivocada.
|
|
25420
|
-
shopDomain:
|
|
25497
|
+
shopDomain: z100.string().min(1)
|
|
25421
25498
|
}).strict();
|
|
25422
|
-
var SetProductCostingInput =
|
|
25423
|
-
shopDomain:
|
|
25424
|
-
shopifyProductId:
|
|
25425
|
-
targetCountry:
|
|
25426
|
-
supplierCost:
|
|
25427
|
-
shippingCost:
|
|
25428
|
-
returnRate:
|
|
25429
|
-
cancellationRate:
|
|
25499
|
+
var SetProductCostingInput = z100.object({
|
|
25500
|
+
shopDomain: z100.string().min(1),
|
|
25501
|
+
shopifyProductId: z100.string().min(1).max(64),
|
|
25502
|
+
targetCountry: z100.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
|
|
25503
|
+
supplierCost: z100.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
|
|
25504
|
+
shippingCost: z100.number().finite().nonnegative(),
|
|
25505
|
+
returnRate: z100.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
|
|
25506
|
+
cancellationRate: z100.number().finite().min(0).lt(1)
|
|
25430
25507
|
}).strict();
|
|
25431
|
-
var Count =
|
|
25432
|
-
var ReportProductCountsInput =
|
|
25433
|
-
productControlId:
|
|
25508
|
+
var Count = z100.number().int().min(0).max(1e5).nullable().optional();
|
|
25509
|
+
var ReportProductCountsInput = z100.object({
|
|
25510
|
+
productControlId: z100.string().uuid().describe("El identificador que devuelve get_product_control."),
|
|
25434
25511
|
date: DateOnly2,
|
|
25435
25512
|
orders: Count.describe("Pedidos que entraron ese d\xEDa."),
|
|
25436
25513
|
cancelledOrders: Count,
|
|
@@ -25440,36 +25517,36 @@ var ReportProductCountsInput = z99.object({
|
|
|
25440
25517
|
}).strict();
|
|
25441
25518
|
var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
|
|
25442
25519
|
var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
|
|
25443
|
-
var ImportOrdersFileInput =
|
|
25520
|
+
var ImportOrdersFileInput = z100.object({
|
|
25444
25521
|
/** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
|
|
25445
|
-
path:
|
|
25446
|
-
operationId:
|
|
25522
|
+
path: z100.string().min(1),
|
|
25523
|
+
operationId: z100.string().uuid().optional(),
|
|
25447
25524
|
/** Solo mirar: devuelve el resumen y no escribe nada. */
|
|
25448
|
-
dryRun:
|
|
25525
|
+
dryRun: z100.boolean().optional()
|
|
25449
25526
|
}).strict();
|
|
25450
|
-
var CreateOperationInput =
|
|
25451
|
-
countryCode:
|
|
25452
|
-
label:
|
|
25527
|
+
var CreateOperationInput = z100.object({
|
|
25528
|
+
countryCode: z100.string().length(2),
|
|
25529
|
+
label: z100.string().trim().min(1).max(60).optional()
|
|
25453
25530
|
}).strict();
|
|
25454
|
-
var MergeProductsInput =
|
|
25455
|
-
sourceId:
|
|
25456
|
-
targetId:
|
|
25531
|
+
var MergeProductsInput = z100.object({
|
|
25532
|
+
sourceId: z100.string().uuid(),
|
|
25533
|
+
targetId: z100.string().uuid()
|
|
25457
25534
|
}).strict();
|
|
25458
|
-
var SetMonthlyExpenseInput =
|
|
25459
|
-
month:
|
|
25535
|
+
var SetMonthlyExpenseInput = z100.object({
|
|
25536
|
+
month: z100.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
25460
25537
|
label: SaveMonthlyExpenseSchema.shape.label,
|
|
25461
|
-
amount:
|
|
25462
|
-
operationId:
|
|
25538
|
+
amount: z100.number().finite().min(0),
|
|
25539
|
+
operationId: z100.string().uuid().optional()
|
|
25463
25540
|
}).strict();
|
|
25464
|
-
var SetAdSpendInput =
|
|
25465
|
-
month:
|
|
25466
|
-
operationId:
|
|
25541
|
+
var SetAdSpendInput = z100.object({
|
|
25542
|
+
month: z100.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
25543
|
+
operationId: z100.string().uuid().optional(),
|
|
25467
25544
|
/** null RETIRA la corrección; cero afirma que no pautó. */
|
|
25468
|
-
amount:
|
|
25545
|
+
amount: z100.number().finite().min(0).nullable()
|
|
25469
25546
|
}).strict();
|
|
25470
|
-
var GetFinancesInput =
|
|
25471
|
-
month:
|
|
25472
|
-
operationId:
|
|
25547
|
+
var GetFinancesInput = z100.object({
|
|
25548
|
+
month: z100.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."),
|
|
25549
|
+
operationId: z100.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
|
|
25473
25550
|
}).strict();
|
|
25474
25551
|
function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
25475
25552
|
server.registerTool("get_product_control", {
|
|
@@ -25666,27 +25743,27 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
|
25666
25743
|
__name(registerProductControlTools, "registerProductControlTools");
|
|
25667
25744
|
|
|
25668
25745
|
// src/tools/market-study-estimate.ts
|
|
25669
|
-
import { z as
|
|
25746
|
+
import { z as z101 } from "zod";
|
|
25670
25747
|
var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
|
|
25671
|
-
var ProductTaskOutputEnum =
|
|
25748
|
+
var ProductTaskOutputEnum = z101.enum([
|
|
25672
25749
|
"landing",
|
|
25673
25750
|
"video",
|
|
25674
25751
|
"image"
|
|
25675
25752
|
]);
|
|
25676
|
-
var EstimateMarketStudyInput =
|
|
25677
|
-
kind:
|
|
25753
|
+
var EstimateMarketStudyInput = z101.object({
|
|
25754
|
+
kind: z101.enum([
|
|
25678
25755
|
"video",
|
|
25679
25756
|
"product_task"
|
|
25680
25757
|
]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
|
|
25681
|
-
videoAngleCount:
|
|
25682
|
-
durationSeconds:
|
|
25758
|
+
videoAngleCount: z101.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
|
|
25759
|
+
durationSeconds: z101.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
|
|
25683
25760
|
videoStructure: VideoStructureEnum.default("single_take"),
|
|
25684
25761
|
videoQuality: VideoQualityEnum.default("economy"),
|
|
25685
25762
|
videoResolution: VideoResolutionEnum.default("480p"),
|
|
25686
|
-
productImageCount:
|
|
25763
|
+
productImageCount: z101.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
|
|
25687
25764
|
outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
|
|
25688
|
-
generateAiMusic:
|
|
25689
|
-
replicateWinnerWhenFound:
|
|
25765
|
+
generateAiMusic: z101.boolean().optional(),
|
|
25766
|
+
replicateWinnerWhenFound: z101.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.")
|
|
25690
25767
|
}).strict();
|
|
25691
25768
|
function buildMarketStudyEstimateRequests(input) {
|
|
25692
25769
|
const quotesVideo = input.kind === "video" || (input.outputs ?? [
|