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