@productmaker/mcp 11.2.0 → 11.2.1

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.
Files changed (3) hide show
  1. package/dist/http.js +830 -789
  2. package/dist/stdio.js +819 -778
  3. package/package.json +1 -1
package/dist/stdio.js CHANGED
@@ -7536,6 +7536,12 @@ var ResultAngle = Angle.extend({
7536
7536
  });
7537
7537
  var MVPResult = z39.object({
7538
7538
  taskId: z39.string().uuid(),
7539
+ /** Read-only identity derived from validated persisted request context.
7540
+ * Optional for older APIs and content-only tasks; absence never implies a service. */
7541
+ subjectKind: z39.enum([
7542
+ "product",
7543
+ "service"
7544
+ ]).optional(),
7539
7545
  product: Product,
7540
7546
  // READ contract, NOT a generation cap. The generator writes exactly 3 angles
7541
7547
  // (`replaceAngles` renumbers positions 0..2), but a duplicated angles run
@@ -8336,6 +8342,10 @@ var VideoRegenerateEstimationOptions = z40.object({
8336
8342
  sceneCount: z40.number().int().positive().optional()
8337
8343
  });
8338
8344
  var ImageCreativeEstimationOptions = z40.object({
8345
+ subject: z40.enum([
8346
+ "product",
8347
+ "service"
8348
+ ]).optional(),
8339
8349
  nVariants: z40.number().int().positive().optional(),
8340
8350
  generateAdCopy: z40.boolean().optional(),
8341
8351
  /** Literal model name (e.g. 'gpt-image/1.5', 'nano-banana-2'). Defaults to the premium ad-creative model. */
@@ -9233,6 +9243,7 @@ var VideoMixQaJobSchema = z46.object({
9233
9243
  // jobId for retry uniqueness) but the worker only reads mixSceneTaskId.
9234
9244
  externalId: z46.string().min(1).optional()
9235
9245
  });
9246
+ var BrandExtractLocaleSchema = z46.string().regex(/^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8})?$/, "invalid locale");
9236
9247
  var BrandExtractJobSchema = z46.object({
9237
9248
  brandId: z46.string().uuid(),
9238
9249
  // Generation is part of the durable paid-spend identity. Default 1 keeps
@@ -9248,7 +9259,10 @@ var BrandExtractJobSchema = z46.object({
9248
9259
  "shopify_sync"
9249
9260
  ]).default("url_extract"),
9250
9261
  shopifyShopId: z46.string().optional(),
9251
- documents: z46.array(BrandExtractDocumentSchema).max(3).default([])
9262
+ documents: z46.array(BrandExtractDocumentSchema).max(3).default([]),
9263
+ // Requesting user's UI locale (BCP-47, e.g. "es", "en-US"). Fallback for the
9264
+ // brand kit's output language when the brand's own text is inconclusive.
9265
+ locale: BrandExtractLocaleSchema.optional()
9252
9266
  });
9253
9267
 
9254
9268
  // ../../packages/types/src/chat-parse.ts
@@ -21588,19 +21602,46 @@ var DropiFinancialSyncResultSchema = z103.object({
21588
21602
  }))
21589
21603
  });
21590
21604
 
21591
- // ../../packages/types/src/service-website-capture.ts
21605
+ // ../../packages/types/src/service-image.ts
21592
21606
  import { z as z104 } from "zod";
21607
+ var ServiceImageIntentSchema = z104.enum([
21608
+ "user_brief",
21609
+ "delegate_to_ai"
21610
+ ]);
21611
+ var ServiceImageInputSchema = z104.object({
21612
+ instruction: z104.string().trim().max(4e3).default(""),
21613
+ intent: ServiceImageIntentSchema.default("user_brief")
21614
+ }).strict().refine((value) => value.intent === "delegate_to_ai" || value.instruction.length > 0, {
21615
+ message: "Cu\xE9ntanos qu\xE9 servicio quieres promocionar.",
21616
+ path: [
21617
+ "instruction"
21618
+ ]
21619
+ });
21620
+ var ServiceImageContextSchema = z104.object({
21621
+ kind: z104.literal("service_image"),
21622
+ version: z104.literal(1),
21623
+ instruction: z104.string().max(4e3),
21624
+ intent: ServiceImageIntentSchema,
21625
+ businessName: z104.string().max(300),
21626
+ description: z104.string().max(2e4),
21627
+ brandCard: z104.string().max(2e4),
21628
+ palette: z104.array(z104.string()).max(20),
21629
+ referenceKeys: z104.array(z104.string()).max(10)
21630
+ }).strict();
21631
+
21632
+ // ../../packages/types/src/service-website-capture.ts
21633
+ import { z as z105 } from "zod";
21593
21634
  var WEBSITE_CAPTURE_MAX_RESEARCH_BYTES = 1024 * 1024;
21594
21635
  var WEBSITE_CAPTURE_MAX_FILES = 100;
21595
21636
  var WEBSITE_CAPTURE_MAX_FILE_BYTES = 8 * 1024 * 1024;
21596
21637
  var WEBSITE_CAPTURE_MAX_BUNDLE_BYTES = 30 * 1024 * 1024;
21597
- var WebsiteCaptureCauseSchema = z104.enum([
21638
+ var WebsiteCaptureCauseSchema = z105.enum([
21598
21639
  "site_blocked",
21599
21640
  "site_unreachable",
21600
21641
  "not_enough_content",
21601
21642
  "internal"
21602
21643
  ]);
21603
- var WebsiteCaptureStatusSchema = z104.enum([
21644
+ var WebsiteCaptureStatusSchema = z105.enum([
21604
21645
  "queued",
21605
21646
  "capturing",
21606
21647
  "ready",
@@ -21622,128 +21663,128 @@ function normalizeWebsiteCaptureUrl(value) {
21622
21663
  }
21623
21664
  }
21624
21665
  __name(normalizeWebsiteCaptureUrl, "normalizeWebsiteCaptureUrl");
21625
- var WebsiteCaptureRequestSchema = z104.object({
21626
- url: z104.string().trim().max(2048).url().refine((value) => normalizeWebsiteCaptureUrl(value) !== null, "Use an HTTP(S) URL without credentials").transform((value) => normalizeWebsiteCaptureUrl(value)),
21666
+ var WebsiteCaptureRequestSchema = z105.object({
21667
+ url: z105.string().trim().max(2048).url().refine((value) => normalizeWebsiteCaptureUrl(value) !== null, "Use an HTTP(S) URL without credentials").transform((value) => normalizeWebsiteCaptureUrl(value)),
21627
21668
  language: MotionGraphicsLanguageSchema
21628
21669
  }).strict();
21629
- var WebsiteCaptureResponseSchema = z104.object({
21630
- captureId: z104.string().uuid(),
21670
+ var WebsiteCaptureResponseSchema = z105.object({
21671
+ captureId: z105.string().uuid(),
21631
21672
  status: WebsiteCaptureStatusSchema,
21632
- expiresAt: z104.string().datetime(),
21633
- previewUrl: z104.string().url().optional(),
21673
+ expiresAt: z105.string().datetime(),
21674
+ previewUrl: z105.string().url().optional(),
21634
21675
  cause: WebsiteCaptureCauseSchema.optional()
21635
21676
  });
21636
21677
  var WebsiteCaptureJobSchema = WebsiteCaptureRequestSchema.extend({
21637
- captureId: z104.string().uuid(),
21638
- attempt: z104.number().int().positive(),
21639
- leaseUntil: z104.string().datetime()
21678
+ captureId: z105.string().uuid(),
21679
+ attempt: z105.number().int().positive(),
21680
+ leaseUntil: z105.string().datetime()
21640
21681
  });
21641
- var WebsiteCaptureClaimResponseSchema = z104.object({
21682
+ var WebsiteCaptureClaimResponseSchema = z105.object({
21642
21683
  capture: WebsiteCaptureJobSchema.nullable()
21643
21684
  });
21644
21685
  var attempt = {
21645
- attempt: z104.number().int().positive()
21686
+ attempt: z105.number().int().positive()
21646
21687
  };
21647
- var digest = z104.string().regex(/^[a-f0-9]{64}$/);
21648
- var WebsiteCaptureUploadRequestSchema = z104.object({
21688
+ var digest = z105.string().regex(/^[a-f0-9]{64}$/);
21689
+ var WebsiteCaptureUploadRequestSchema = z105.object({
21649
21690
  ...attempt,
21650
- contentLength: z104.number().int().positive().max(WEBSITE_CAPTURE_MAX_BUNDLE_BYTES),
21691
+ contentLength: z105.number().int().positive().max(WEBSITE_CAPTURE_MAX_BUNDLE_BYTES),
21651
21692
  sha256: digest
21652
21693
  }).strict();
21653
- var WebsiteCaptureDoneRequestSchema = z104.object({
21694
+ var WebsiteCaptureDoneRequestSchema = z105.object({
21654
21695
  ...attempt,
21655
21696
  sha256: digest
21656
21697
  }).strict();
21657
- var WebsiteCaptureFailedRequestSchema = z104.object({
21698
+ var WebsiteCaptureFailedRequestSchema = z105.object({
21658
21699
  ...attempt,
21659
21700
  cause: WebsiteCaptureCauseSchema
21660
21701
  }).strict();
21661
- var WebsiteCaptureBundleSchema = z104.object({
21662
- version: z104.literal(1),
21663
- files: z104.array(z104.object({
21664
- path: z104.string().max(140).regex(/^research\/(?:page\.json|(?:desktop|mobile)-[1-9]\d*\.jpg|logo\.(?:png|svg)|image-[1-9]\d*\.(?:png|jpg|jpeg|webp|svg|avif)|font-[1-9]\d*\.(?:woff2?|ttf|otf))$/),
21665
- base64: z104.string().max(Math.ceil(WEBSITE_CAPTURE_MAX_FILE_BYTES / 3) * 4).regex(/^[A-Za-z0-9+/]*={0,2}$/).refine((value) => value.length % 4 === 0),
21702
+ var WebsiteCaptureBundleSchema = z105.object({
21703
+ version: z105.literal(1),
21704
+ files: z105.array(z105.object({
21705
+ path: z105.string().max(140).regex(/^research\/(?:page\.json|(?:desktop|mobile)-[1-9]\d*\.jpg|logo\.(?:png|svg)|image-[1-9]\d*\.(?:png|jpg|jpeg|webp|svg|avif)|font-[1-9]\d*\.(?:woff2?|ttf|otf))$/),
21706
+ base64: z105.string().max(Math.ceil(WEBSITE_CAPTURE_MAX_FILE_BYTES / 3) * 4).regex(/^[A-Za-z0-9+/]*={0,2}$/).refine((value) => value.length % 4 === 0),
21666
21707
  sha256: digest
21667
21708
  }).strict()).min(1).max(WEBSITE_CAPTURE_MAX_FILES)
21668
21709
  }).strict().refine((bundle) => new Set(bundle.files.map((file) => file.path)).size === bundle.files.length, "Duplicate capture file");
21669
- var WebsiteCaptureScreenshotSchema = z104.object({
21670
- file: z104.string(),
21671
- scrollTop: z104.number()
21672
- });
21673
- var WebsiteCaptureAccessSchema = z104.object({
21674
- publicContentText: z104.string().max(8e3),
21675
- passwordGate: z104.boolean(),
21676
- challengeGate: z104.boolean(),
21677
- blockingOverlay: z104.boolean()
21678
- });
21679
- var WebsiteCaptureResearchSchema = z104.object({
21680
- requestedUrl: z104.string().url(),
21681
- capturedAt: z104.string().datetime(),
21682
- locale: z104.string(),
21683
- bodyTextTruncated: z104.boolean(),
21684
- finalUrl: z104.string().url(),
21685
- lang: z104.string().nullable(),
21686
- title: z104.string(),
21687
- description: z104.string(),
21688
- openGraph: z104.object({
21689
- title: z104.string(),
21690
- description: z104.string(),
21691
- image: z104.string(),
21692
- siteName: z104.string()
21710
+ var WebsiteCaptureScreenshotSchema = z105.object({
21711
+ file: z105.string(),
21712
+ scrollTop: z105.number()
21713
+ });
21714
+ var WebsiteCaptureAccessSchema = z105.object({
21715
+ publicContentText: z105.string().max(8e3),
21716
+ passwordGate: z105.boolean(),
21717
+ challengeGate: z105.boolean(),
21718
+ blockingOverlay: z105.boolean()
21719
+ });
21720
+ var WebsiteCaptureResearchSchema = z105.object({
21721
+ requestedUrl: z105.string().url(),
21722
+ capturedAt: z105.string().datetime(),
21723
+ locale: z105.string(),
21724
+ bodyTextTruncated: z105.boolean(),
21725
+ finalUrl: z105.string().url(),
21726
+ lang: z105.string().nullable(),
21727
+ title: z105.string(),
21728
+ description: z105.string(),
21729
+ openGraph: z105.object({
21730
+ title: z105.string(),
21731
+ description: z105.string(),
21732
+ image: z105.string(),
21733
+ siteName: z105.string()
21693
21734
  }),
21694
- themeColor: z104.string(),
21695
- headings: z104.object({
21696
- h1: z104.array(z104.string()),
21697
- h2: z104.array(z104.string()),
21698
- h3: z104.array(z104.string())
21735
+ themeColor: z105.string(),
21736
+ headings: z105.object({
21737
+ h1: z105.array(z105.string()),
21738
+ h2: z105.array(z105.string()),
21739
+ h3: z105.array(z105.string())
21699
21740
  }),
21700
- callsToAction: z104.array(z104.string()),
21701
- listItems: z104.array(z104.string()),
21702
- bodyText: z104.string(),
21741
+ callsToAction: z105.array(z105.string()),
21742
+ listItems: z105.array(z105.string()),
21743
+ bodyText: z105.string(),
21703
21744
  access: WebsiteCaptureAccessSchema.optional(),
21704
- consent: z104.object({
21705
- pressed: z104.string().nullable(),
21706
- removed: z104.number().nonnegative()
21745
+ consent: z105.object({
21746
+ pressed: z105.string().nullable(),
21747
+ removed: z105.number().nonnegative()
21707
21748
  }).optional(),
21708
- overlaysDismissed: z104.number().int().nonnegative().optional(),
21709
- style: z104.object({
21710
- bodyBackground: z104.string(),
21711
- bodyColor: z104.string(),
21712
- bodyFont: z104.string(),
21713
- headingFont: z104.string().nullable(),
21714
- headingColor: z104.string().nullable(),
21715
- actionColors: z104.array(z104.object({
21716
- color: z104.string(),
21717
- uses: z104.number()
21749
+ overlaysDismissed: z105.number().int().nonnegative().optional(),
21750
+ style: z105.object({
21751
+ bodyBackground: z105.string(),
21752
+ bodyColor: z105.string(),
21753
+ bodyFont: z105.string(),
21754
+ headingFont: z105.string().nullable(),
21755
+ headingColor: z105.string().nullable(),
21756
+ actionColors: z105.array(z105.object({
21757
+ color: z105.string(),
21758
+ uses: z105.number()
21718
21759
  }))
21719
21760
  }),
21720
- images: z104.array(z104.object({
21721
- file: z104.string(),
21722
- src: z104.string(),
21723
- alt: z104.string(),
21724
- width: z104.number().nullable(),
21725
- height: z104.number().nullable(),
21726
- isOpenGraph: z104.boolean()
21761
+ images: z105.array(z105.object({
21762
+ file: z105.string(),
21763
+ src: z105.string(),
21764
+ alt: z105.string(),
21765
+ width: z105.number().nullable(),
21766
+ height: z105.number().nullable(),
21767
+ isOpenGraph: z105.boolean()
21727
21768
  })),
21728
- logo: z104.object({
21729
- file: z104.literal("logo.png"),
21730
- svg: z104.literal("logo.svg").optional(),
21731
- width: z104.number(),
21732
- height: z104.number()
21769
+ logo: z105.object({
21770
+ file: z105.literal("logo.png"),
21771
+ svg: z105.literal("logo.svg").optional(),
21772
+ width: z105.number(),
21773
+ height: z105.number()
21733
21774
  }).nullable(),
21734
- fonts: z104.array(z104.object({
21735
- family: z104.string(),
21736
- weight: z104.string(),
21737
- style: z104.string(),
21738
- unicodeRange: z104.string().nullable(),
21739
- file: z104.string().optional()
21775
+ fonts: z105.array(z105.object({
21776
+ family: z105.string(),
21777
+ weight: z105.string(),
21778
+ style: z105.string(),
21779
+ unicodeRange: z105.string().nullable(),
21780
+ file: z105.string().optional()
21740
21781
  }).transform((font) => ({
21741
21782
  ...font,
21742
21783
  file: font.file
21743
21784
  }))),
21744
- screenshots: z104.object({
21745
- desktop: z104.array(WebsiteCaptureScreenshotSchema),
21746
- mobile: z104.array(WebsiteCaptureScreenshotSchema)
21785
+ screenshots: z105.object({
21786
+ desktop: z105.array(WebsiteCaptureScreenshotSchema),
21787
+ mobile: z105.array(WebsiteCaptureScreenshotSchema)
21747
21788
  })
21748
21789
  });
21749
21790
 
@@ -21989,7 +22030,7 @@ var ApiClient = class {
21989
22030
  };
21990
22031
 
21991
22032
  // src/index.ts
21992
- var MCP_VERSION = "11.2.0";
22033
+ var MCP_VERSION = "11.2.1";
21993
22034
 
21994
22035
  // src/meta-upload-app.ts
21995
22036
  import { readFileSync } from "fs";
@@ -22061,7 +22102,7 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
22061
22102
  __name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
22062
22103
 
22063
22104
  // src/tools/tasks.ts
22064
- import { z as z109 } from "zod";
22105
+ import { z as z110 } from "zod";
22065
22106
 
22066
22107
  // src/resolve-image.ts
22067
22108
  import { lookup as dnsLookup } from "dns/promises";
@@ -22622,9 +22663,9 @@ async function resolveMediaRef(ref, opts) {
22622
22663
  __name(resolveMediaRef, "resolveMediaRef");
22623
22664
 
22624
22665
  // src/tools/shared.ts
22625
- import { z as z105 } from "zod";
22626
- var Lang = z105.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);
22627
- var Country = z105.string().min(2).max(3);
22666
+ import { z as z106 } from "zod";
22667
+ var Lang = z106.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);
22668
+ var Country = z106.string().min(2).max(3);
22628
22669
  var LandingStrategyEnum = LandingStrategySchema;
22629
22670
  var LandingImageFormatEnum = LandingImageFormatSchema;
22630
22671
  var VideoPresetEnum = VideoPreset.extract([
@@ -22728,7 +22769,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
22728
22769
  return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
22729
22770
  }
22730
22771
  __name(animationStyleApplies, "animationStyleApplies");
22731
- var VideoTierEnum = z105.enum([
22772
+ var VideoTierEnum = z106.enum([
22732
22773
  "basic"
22733
22774
  ]);
22734
22775
  function resolveVideoTier(_tier) {
@@ -22786,10 +22827,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
22786
22827
  var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
22787
22828
  var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
22788
22829
  var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
22789
- var ImageRefSchema = z105.object({
22790
- url: z105.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.'),
22791
- path: z105.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`.'),
22792
- assetId: z105.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.")
22830
+ var ImageRefSchema = z106.object({
22831
+ url: z106.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.'),
22832
+ path: z106.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`.'),
22833
+ assetId: z106.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.")
22793
22834
  }).refine((v) => [
22794
22835
  v.url,
22795
22836
  v.path,
@@ -22797,11 +22838,11 @@ var ImageRefSchema = z105.object({
22797
22838
  ].filter(Boolean).length === 1, {
22798
22839
  message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
22799
22840
  });
22800
- var ImagesInput = z105.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
22841
+ var ImagesInput = z106.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
22801
22842
  const assetCount = images.filter((image) => Boolean(image.assetId)).length;
22802
22843
  if (assetCount > 0 && assetCount !== images.length) {
22803
22844
  ctx.addIssue({
22804
- code: z105.ZodIssueCode.custom,
22845
+ code: z106.ZodIssueCode.custom,
22805
22846
  message: "all image entries must use assetId, or all must use URL/path sources"
22806
22847
  });
22807
22848
  }
@@ -22874,14 +22915,14 @@ async function submitCreative(api, opts) {
22874
22915
  });
22875
22916
  }
22876
22917
  __name(submitCreative, "submitCreative");
22877
- var ResearchTargetCountryEnum = z105.enum([
22918
+ var ResearchTargetCountryEnum = z106.enum([
22878
22919
  "CO",
22879
22920
  "MX",
22880
22921
  "PE",
22881
22922
  "EC",
22882
22923
  "CL"
22883
22924
  ]);
22884
- var ResearchCategoryEnum = z105.enum([
22925
+ var ResearchCategoryEnum = z106.enum([
22885
22926
  "auto",
22886
22927
  "automotive",
22887
22928
  "kitchen",
@@ -24246,29 +24287,29 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
24246
24287
  __name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
24247
24288
 
24248
24289
  // src/tools/media-presentation.ts
24249
- import { z as z106 } from "zod";
24250
- var HttpsPresentationUrlSchema = z106.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
24290
+ import { z as z107 } from "zod";
24291
+ var HttpsPresentationUrlSchema = z107.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
24251
24292
  var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
24252
24293
  const hostname = new URL(value).hostname.toLowerCase();
24253
24294
  return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
24254
24295
  }, "preview URL must be owned by ProductMaker");
24255
- var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z106.number().int().positive().max(maximum), "positiveIntAtMost");
24256
- var PresentationImageSchema = z106.object({
24257
- kind: z106.literal("image"),
24296
+ var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z107.number().int().positive().max(maximum), "positiveIntAtMost");
24297
+ var PresentationImageSchema = z107.object({
24298
+ kind: z107.literal("image"),
24258
24299
  url: HttpsPresentationUrlSchema,
24259
- mimeType: z106.enum([
24300
+ mimeType: z107.enum([
24260
24301
  "image/jpeg",
24261
24302
  "image/png"
24262
24303
  ]),
24263
24304
  byteSize: positiveIntAtMost(5 * 1024 * 1024),
24264
24305
  width: positiveIntAtMost(16384),
24265
24306
  height: positiveIntAtMost(16384),
24266
- alt: z106.string().trim().min(1).max(240)
24307
+ alt: z107.string().trim().min(1).max(240)
24267
24308
  }).strict();
24268
24309
  var McpMediaPresentationSchema = PresentationImageSchema;
24269
- var GalleryImageSchema = z106.object({
24310
+ var GalleryImageSchema = z107.object({
24270
24311
  url: ProductMakerPreviewUrlSchema,
24271
- alt: z106.string().trim().min(1).max(240)
24312
+ alt: z107.string().trim().min(1).max(240)
24272
24313
  });
24273
24314
  var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
24274
24315
  async function imageBlocks(image, transport) {
@@ -24325,12 +24366,12 @@ async function buildMcpMediaPresentationContent(rawPresentation, transport = "ht
24325
24366
  ];
24326
24367
  }
24327
24368
  __name(buildMcpMediaPresentationContent, "buildMcpMediaPresentationContent");
24328
- var OwnedImagePreviewSchema = z106.object({
24369
+ var OwnedImagePreviewSchema = z107.object({
24329
24370
  url: HttpsPresentationUrlSchema.refine((value) => {
24330
24371
  const url = new URL(value);
24331
24372
  return !url.username && !url.password && !isPrivateHost(url.hostname);
24332
24373
  }, "Preview URL must be public HTTPS without credentials"),
24333
- alt: z106.string().trim().min(1).max(240)
24374
+ alt: z107.string().trim().min(1).max(240)
24334
24375
  });
24335
24376
  async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
24336
24377
  const preview2 = OwnedImagePreviewSchema.safeParse(rawPreview);
@@ -24413,7 +24454,7 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
24413
24454
  __name(buildMcpImageGalleryContent, "buildMcpImageGalleryContent");
24414
24455
 
24415
24456
  // src/tools/animated-video.ts
24416
- import { z as z107 } from "zod";
24457
+ import { z as z108 } from "zod";
24417
24458
 
24418
24459
  // src/tools/paid-confirmation.ts
24419
24460
  function describeMarketStudyChoice(enabled) {
@@ -24663,27 +24704,27 @@ function hookVariantsLabel(count) {
24663
24704
  return count === 1 ? "1 versi\xF3n del gancho" : `${count} versiones del gancho`;
24664
24705
  }
24665
24706
  __name(hookVariantsLabel, "hookVariantsLabel");
24666
- var DurationInput = z107.union(MOTION_GRAPHICS_DURATIONS.map((d) => z107.literal(d)));
24667
- var CreateAnimatedVideoInput = z107.object({
24668
- action: z107.enum([
24707
+ var DurationInput = z108.union(MOTION_GRAPHICS_DURATIONS.map((d) => z108.literal(d)));
24708
+ var CreateAnimatedVideoInput = z108.object({
24709
+ action: z108.enum([
24669
24710
  "prepare",
24670
24711
  "status",
24671
24712
  "cancel",
24672
24713
  "generate"
24673
24714
  ]).default("prepare").describe("prepare inicia una captura gratuita; status consulta websiteCaptureId; cancel la cancela; generate requiere captura ready y confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrar vista previa y precio."),
24674
- websiteCaptureId: z107.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
24675
- generationRequestId: z107.string().uuid().optional().describe("Identidad opcional de una generaci\xF3n confirmada. Repite el mismo UUID al recuperar una respuesta perdida; usa otro \xFAnicamente cuando el usuario pida y confirme otro video, nunca por un error de transporte."),
24676
- confirmed: z107.boolean().optional().describe("Solo true despu\xE9s de que el usuario confirme esta captura, formato, duraci\xF3n, idioma y precio. Obligatorio para generate; preparar no genera ni cobra."),
24715
+ websiteCaptureId: z108.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
24716
+ generationRequestId: z108.string().uuid().optional().describe("Identidad opcional de una generaci\xF3n confirmada. Repite el mismo UUID al recuperar una respuesta perdida; usa otro \xFAnicamente cuando el usuario pida y confirme otro video, nunca por un error de transporte."),
24717
+ confirmed: z108.boolean().optional().describe("Solo true despu\xE9s de que el usuario confirme esta captura, formato, duraci\xF3n, idioma y precio. Obligatorio para generate; preparar no genera ni cobra."),
24677
24718
  // Plain text, not `.url()`: users type «cal.com», and the web accepts it.
24678
24719
  // normalizeWebAddress (shared with the web) adds https:// and refuses
24679
24720
  // anything that is not a public http(s) address.
24680
- landingUrl: z107.string().trim().min(1).optional().describe("Enlace p\xFAblico de la p\xE1gina del servicio, como lo dio el usuario (\xABcal.com\xBB o \xABhttps://cal.com\xBB). El video sale de lo que muestra esa p\xE1gina: su marca, colores y mensajes."),
24721
+ landingUrl: z108.string().trim().min(1).optional().describe("Enlace p\xFAblico de la p\xE1gina del servicio, como lo dio el usuario (\xABcal.com\xBB o \xABhttps://cal.com\xBB). El video sale de lo que muestra esa p\xE1gina: su marca, colores y mensajes."),
24681
24722
  format: MotionGraphicsFormatSchema.optional().describe('Formato: "vertical" (9:16, Reels/TikTok), "square" (1:1, feed) u "horizontal" (16:9, YouTube/web). Si el usuario no lo dijo, PREG\xDANTALE.'),
24682
24723
  durationSec: DurationInput.optional().describe(`Duraci\xF3n en segundos: ${MOTION_GRAPHICS_DURATIONS.join(", ")}. Fija el precio (ver la descripci\xF3n de la herramienta). Si el usuario no la dijo, PREG\xDANTALE.`),
24683
24724
  language: MotionGraphicsLanguageSchema.optional().describe('Idioma de los textos del video: "es", "en" o "pt".'),
24684
- notes: z107.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)."),
24725
+ notes: z108.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)."),
24685
24726
  hookVariants: MotionGraphicsHookVariantsSchema.optional().describe(`Opcional. Versiones del gancho: el mismo video con distintas aperturas para probar cu\xE1l funciona mejor, de 1 a ${MOTION_GRAPHICS_HOOK_VARIANTS_MAX} (por defecto 1). Cada versi\xF3n extra tiene precio (ver la descripci\xF3n de la herramienta); \xFAsalo solo si el usuario lo pide.`),
24686
- music: z107.boolean().optional().describe("Opcional. M\xFAsica de fondo (por defecto true). false hace el video sin m\xFAsica, m\xE1s crudo, estilo UGC: quedan la voz y los efectos de sonido. Mismo precio. \xDAsalo solo si el usuario lo pide.")
24727
+ music: z108.boolean().optional().describe("Opcional. M\xFAsica de fondo (por defecto true). false hace el video sin m\xFAsica, m\xE1s crudo, estilo UGC: quedan la voz y los efectos de sonido. Mismo precio. \xDAsalo solo si el usuario lo pide.")
24687
24728
  }).strict();
24688
24729
  function captureNextAction(capture) {
24689
24730
  if (capture.status === "ready") return "Muestra la vista previa al usuario y confirma formato, duraci\xF3n, idioma y precio. Solo despu\xE9s llama create_animated_video con action=generate, este websiteCaptureId y confirmed=true.";
@@ -24716,43 +24757,43 @@ var FORMAT_LABELS = {
24716
24757
  square: "cuadrado 1:1",
24717
24758
  horizontal: "horizontal 16:9"
24718
24759
  };
24719
- var AnimatedVideoResultSchema = z107.object({
24720
- status: z107.enum([
24760
+ var AnimatedVideoResultSchema = z108.object({
24761
+ status: z108.enum([
24721
24762
  "pending",
24722
24763
  "done",
24723
24764
  "error"
24724
24765
  ]),
24725
- serviceMode: z107.literal("motion_graphics"),
24726
- finalMp4Url: z107.string().optional(),
24727
- error: z107.string().optional(),
24728
- motionGraphics: z107.object({
24766
+ serviceMode: z108.literal("motion_graphics"),
24767
+ finalMp4Url: z108.string().optional(),
24768
+ error: z108.string().optional(),
24769
+ motionGraphics: z108.object({
24729
24770
  stage: MotionGraphicsStageSchema,
24730
24771
  format: MotionGraphicsFormatSchema,
24731
- durationSec: z107.number(),
24732
- width: z107.number().optional(),
24733
- height: z107.number().optional(),
24772
+ durationSec: z108.number(),
24773
+ width: z108.number().optional(),
24774
+ height: z108.number().optional(),
24734
24775
  language: MotionGraphicsLanguageSchema.optional(),
24735
- queuedAt: z107.string().optional(),
24736
- jobsAhead: z107.number().int().nonnegative().optional(),
24737
- stageStartedAt: z107.string().optional(),
24738
- renderProgress: z107.number().optional(),
24776
+ queuedAt: z108.string().optional(),
24777
+ jobsAhead: z108.number().int().nonnegative().optional(),
24778
+ stageStartedAt: z108.string().optional(),
24779
+ renderProgress: z108.number().optional(),
24739
24780
  // AI clip fields (absent on a video paid before clips, or from an API
24740
24781
  // that predates them). Lenient: an unreadable value is dropped
24741
24782
  // instead of hiding the status.
24742
- clipCount: z107.number().int().nonnegative().optional().catch(void 0),
24743
- clipsUsed: z107.number().int().nonnegative().optional().catch(void 0),
24744
- clipPriceCents: z107.number().finite().nonnegative().optional().catch(void 0),
24745
- clipsRefunded: z107.number().int().nonnegative().optional().catch(void 0),
24783
+ clipCount: z108.number().int().nonnegative().optional().catch(void 0),
24784
+ clipsUsed: z108.number().int().nonnegative().optional().catch(void 0),
24785
+ clipPriceCents: z108.number().finite().nonnegative().optional().catch(void 0),
24786
+ clipsRefunded: z108.number().int().nonnegative().optional().catch(void 0),
24746
24787
  // Hook versions (absent from an API or a video before them): the
24747
24788
  // count ordered and, once done, the signed URLs of the EXTRA versions
24748
24789
  // (hook 2, hook 3); `finalMp4Url` is hook 1.
24749
- hookVariants: z107.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
24750
- variantUrls: z107.array(z107.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
24790
+ hookVariants: z108.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
24791
+ variantUrls: z108.array(z108.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
24751
24792
  // Extra hook versions given back, as the task recorded it once the
24752
24793
  // refunds landed (absent until then, and from an API before it).
24753
- variantsRefunded: z107.number().int().nonnegative().optional().catch(void 0),
24754
- activity: z107.array(MotionGraphicsActivitySchema).optional().catch(void 0),
24755
- previewUrl: z107.string().optional()
24794
+ variantsRefunded: z108.number().int().nonnegative().optional().catch(void 0),
24795
+ activity: z108.array(MotionGraphicsActivitySchema).optional().catch(void 0),
24796
+ previewUrl: z108.string().optional()
24756
24797
  }).passthrough()
24757
24798
  }).passthrough();
24758
24799
  function parseAnimatedVideoResult(value) {
@@ -25008,10 +25049,10 @@ function registerAnimatedVideoTools(server, api) {
25008
25049
  __name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
25009
25050
 
25010
25051
  // src/tools/winning-product-image.ts
25011
- import { z as z108 } from "zod";
25012
- var WinnerReferenceInput = z108.object({
25013
- runId: z108.string().uuid(),
25014
- candidateSourceId: z108.string().trim().min(1).max(160)
25052
+ import { z as z109 } from "zod";
25053
+ var WinnerReferenceInput = z109.object({
25054
+ runId: z109.string().uuid(),
25055
+ candidateSourceId: z109.string().trim().min(1).max(160)
25015
25056
  }).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
25016
25057
  async function resolveWinnerImages(api, winnerReference, images) {
25017
25058
  if (!winnerReference) return images;
@@ -25048,62 +25089,62 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
25048
25089
  var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
25049
25090
  var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
25050
25091
  var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
25051
- var CreateProductTaskInput = z109.object({
25092
+ var CreateProductTaskInput = z110.object({
25052
25093
  images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
25053
25094
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
25054
- projectId: z109.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
25055
- productUrl: z109.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."),
25095
+ projectId: z110.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
25096
+ productUrl: z110.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."),
25056
25097
  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.'),
25057
25098
  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.'),
25058
- price: z109.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.'),
25059
- compareAtPrice: z109.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".'),
25060
- offer: z109.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.'),
25061
- paymentMethods: z109.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.'),
25062
- productContext: z109.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."),
25063
- productLabel: z109.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.'),
25099
+ price: z110.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.'),
25100
+ compareAtPrice: z110.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".'),
25101
+ offer: z110.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.'),
25102
+ paymentMethods: z110.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.'),
25103
+ productContext: z110.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."),
25104
+ productLabel: z110.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.'),
25064
25105
  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.'),
25065
25106
  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.'),
25066
- durationSeconds: z109.union([
25067
- z109.literal(15),
25068
- z109.literal(30)
25107
+ durationSeconds: z110.union([
25108
+ z110.literal(15),
25109
+ z110.literal(30)
25069
25110
  ]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
25070
- pauseForAngleReview: z109.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."),
25071
- aiDecidesAll: z109.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."),
25111
+ pauseForAngleReview: z110.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."),
25112
+ aiDecidesAll: z110.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."),
25072
25113
  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.'),
25073
25114
  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.'),
25074
25115
  videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
25075
25116
  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).'),
25076
- videoAngleCount: z109.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."),
25117
+ videoAngleCount: z110.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."),
25077
25118
  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.'),
25078
- outputs: z109.array(z109.enum([
25119
+ outputs: z110.array(z110.enum([
25079
25120
  "landing",
25080
25121
  "video",
25081
25122
  "image"
25082
25123
  ])).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}`),
25083
- includeInitialLandingGif: z109.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
25084
- competitorScanEnabled: z109.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."),
25124
+ includeInitialLandingGif: z110.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
25125
+ competitorScanEnabled: z110.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."),
25085
25126
  generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, efectos y m\xFAsica sobre cada video entregado (variante with_ai_edit; se cobra al entregar, por video). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro"; false/omitido = sin edici\xF3n.'),
25086
- replicateWinnerWhenFound: z109.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."),
25087
- brandId: z109.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."),
25088
- actorId: z109.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."),
25127
+ replicateWinnerWhenFound: z110.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."),
25128
+ brandId: z110.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."),
25129
+ actorId: z110.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."),
25089
25130
  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.'),
25090
- creativeDirection: z109.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.'),
25091
- headline: z109.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."),
25092
- subheadline: z109.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."),
25131
+ creativeDirection: z110.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.'),
25132
+ headline: z110.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."),
25133
+ subheadline: z110.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."),
25093
25134
  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".'),
25094
25135
  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".')
25095
25136
  }).strict();
25096
- var CreateServiceVideoInput = z109.object({
25097
- landingUrl: z109.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
25098
- additionalContext: z109.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
25137
+ var CreateServiceVideoInput = z110.object({
25138
+ landingUrl: z110.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
25139
+ additionalContext: z110.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
25099
25140
  language: Lang.describe("Idioma del video: es, en o pt."),
25100
- voiceId: z109.string().trim().min(1).pipe(VoiceId).optional().describe('Opcional. Voz para toda la narraci\xF3n. Usa "auto" para que la IA la alinee con el presentador. Las voces del banco compartido fueron retiradas.'),
25101
- brandId: z109.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
25102
- reviewMode: z109.enum([
25141
+ voiceId: z110.string().trim().min(1).pipe(VoiceId).optional().describe('Opcional. Voz para toda la narraci\xF3n. Usa "auto" para que la IA la alinee con el presentador. Las voces del banco compartido fueron retiradas.'),
25142
+ brandId: z110.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
25143
+ reviewMode: z110.enum([
25103
25144
  "automatic",
25104
25145
  "guided"
25105
25146
  ]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
25106
- videoPreset: z109.enum([
25147
+ videoPreset: z110.enum([
25107
25148
  "auto",
25108
25149
  "ugc_dynamic",
25109
25150
  "ugc_how_to",
@@ -25113,128 +25154,128 @@ var CreateServiceVideoInput = z109.object({
25113
25154
  videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
25114
25155
  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.')
25115
25156
  }).strict();
25116
- var GetTaskStatusInput = z109.object({
25117
- taskId: z109.string().min(1),
25118
- waitSeconds: z109.number().int().min(0).max(120).optional()
25157
+ var GetTaskStatusInput = z110.object({
25158
+ taskId: z110.string().min(1),
25159
+ waitSeconds: z110.number().int().min(0).max(120).optional()
25119
25160
  });
25120
- var ListTasksInput = z109.object({
25121
- limit: z109.number().int().min(1).max(50).optional(),
25122
- offset: z109.number().int().min(0).optional(),
25123
- search: z109.string().optional()
25161
+ var ListTasksInput = z110.object({
25162
+ limit: z110.number().int().min(1).max(50).optional(),
25163
+ offset: z110.number().int().min(0).optional(),
25164
+ search: z110.string().optional()
25124
25165
  });
25125
25166
  var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
25126
25167
  var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
25127
- var EditTaskDraftInput = z109.object({
25128
- taskId: z109.string().min(1),
25129
- angleIndex: z109.number().int().min(0),
25130
- angle: z109.object({
25131
- angle: z109.string().min(1).max(480),
25132
- buyerPersona: z109.string().min(1).max(360),
25133
- actor: z109.string().min(1).max(360).optional(),
25134
- actorId: z109.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."),
25135
- gender: z109.enum([
25168
+ var EditTaskDraftInput = z110.object({
25169
+ taskId: z110.string().min(1),
25170
+ angleIndex: z110.number().int().min(0),
25171
+ angle: z110.object({
25172
+ angle: z110.string().min(1).max(480),
25173
+ buyerPersona: z110.string().min(1).max(360),
25174
+ actor: z110.string().min(1).max(360).optional(),
25175
+ actorId: z110.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."),
25176
+ gender: z110.enum([
25136
25177
  "female",
25137
25178
  "male"
25138
25179
  ]).optional(),
25139
- scriptNotes: z109.string().max(2e3).optional()
25180
+ scriptNotes: z110.string().max(2e3).optional()
25140
25181
  })
25141
25182
  });
25142
- var PendingActionPayload = z109.discriminatedUnion("kind", [
25143
- z109.object({
25144
- kind: z109.literal("product_reference_set_approval"),
25183
+ var PendingActionPayload = z110.discriminatedUnion("kind", [
25184
+ z110.object({
25185
+ kind: z110.literal("product_reference_set_approval"),
25145
25186
  scope: ProductReferenceScopeEnum.optional(),
25146
- scopeKey: z109.string().min(1).max(120).optional(),
25147
- scopeSnapshotId: z109.string().uuid().optional(),
25148
- expectedScopeHash: z109.string().min(1).max(128).optional(),
25187
+ scopeKey: z110.string().min(1).max(120).optional(),
25188
+ scopeSnapshotId: z110.string().uuid().optional(),
25189
+ expectedScopeHash: z110.string().min(1).max(128).optional(),
25149
25190
  decision: ProductReferenceResolutionDecisionEnum,
25150
25191
  reason: ProductReferenceRejectionReasonEnum.optional(),
25151
- affectedRefKeys: z109.array(z109.string().min(1).max(200)).min(1).optional(),
25152
- affectedPhotoNumbers: z109.array(z109.number().int().positive()).min(1).optional(),
25153
- recoveryAction: z109.enum([
25192
+ affectedRefKeys: z110.array(z110.string().min(1).max(200)).min(1).optional(),
25193
+ affectedPhotoNumbers: z110.array(z110.number().int().positive()).min(1).optional(),
25194
+ recoveryAction: z110.enum([
25154
25195
  "remove",
25155
25196
  "replace",
25156
25197
  "upload",
25157
25198
  "return_to_selection"
25158
25199
  ]).optional()
25159
25200
  }),
25160
- z109.object({
25161
- kind: z109.literal("product_reference_confirmation"),
25162
- selectedPhotoNumbers: z109.array(z109.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."),
25201
+ z110.object({
25202
+ kind: z110.literal("product_reference_confirmation"),
25203
+ selectedPhotoNumbers: z110.array(z110.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."),
25163
25204
  userChoice: ProductReferenceUserChoiceEnum.optional(),
25164
- confirmedProductNames: z109.array(z109.string().min(1).max(120)).min(2).max(8).optional(),
25205
+ confirmedProductNames: z110.array(z110.string().min(1).max(120)).min(2).max(8).optional(),
25165
25206
  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."),
25166
25207
  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."),
25167
- useMultiSceneShowcase: z109.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
25208
+ useMultiSceneShowcase: z110.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
25168
25209
  }),
25169
- z109.object({
25170
- kind: z109.literal("angle_review_approval"),
25210
+ z110.object({
25211
+ kind: z110.literal("angle_review_approval"),
25171
25212
  // All edits are optional — empty action body just approves the
25172
25213
  // backend-generated draft as-is. Field shapes mirror the angle-review
25173
25214
  // request contracts in @packages/types/wizard.ts; the handler routes to
25174
25215
  // the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
25175
- customAngle: z109.string().min(1).max(480).optional(),
25216
+ customAngle: z110.string().min(1).max(480).optional(),
25176
25217
  // Keep the shared MCP action within the strictest downstream contract:
25177
25218
  // autopilot/image resume endpoints cap these fields at 1500 characters.
25178
- painPoints: z109.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
25179
- benefits: z109.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
25219
+ painPoints: z110.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
25220
+ benefits: z110.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
25180
25221
  // Same policy as the two fields above: the strictest downstream contract
25181
25222
  // wins. The image endpoint caps each feature at 240 while landing/video
25182
25223
  // accept 300, and this single action routes to whichever the task is — so
25183
25224
  // accepting 300 here turns a 250-character feature on an image task into
25184
25225
  // an opaque HTTP 400 after the model already believed it had been saved.
25185
- features: z109.array(z109.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
25186
- buyerPersona: z109.string().min(1).max(360).optional(),
25226
+ features: z110.array(z110.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
25227
+ buyerPersona: z110.string().min(1).max(360).optional(),
25187
25228
  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.'),
25188
- actor: z109.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."),
25189
- actorId: z109.string().max(120).nullable().optional(),
25190
- creativeDirection: z109.string().max(2e3).optional(),
25191
- selectedAngleNumbers: z109.array(z109.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."),
25192
- angleEdits: z109.array(z109.object({
25193
- angleNumber: z109.number().int().positive(),
25194
- narrativeSelection: z109.enum([
25229
+ actor: z110.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."),
25230
+ actorId: z110.string().max(120).nullable().optional(),
25231
+ creativeDirection: z110.string().max(2e3).optional(),
25232
+ selectedAngleNumbers: z110.array(z110.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."),
25233
+ angleEdits: z110.array(z110.object({
25234
+ angleNumber: z110.number().int().positive(),
25235
+ narrativeSelection: z110.enum([
25195
25236
  "market",
25196
25237
  "guided"
25197
25238
  ]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
25198
- angle: z109.string().min(1).max(480).optional(),
25199
- buyerPersona: z109.string().min(1).max(360).optional(),
25239
+ angle: z110.string().min(1).max(480).optional(),
25240
+ buyerPersona: z110.string().min(1).max(360).optional(),
25200
25241
  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.'),
25201
- actor: z109.string().min(1).max(360).optional(),
25202
- actorId: z109.string().max(120).nullable().optional(),
25203
- creativeDirection: z109.string().max(2e3).optional()
25242
+ actor: z110.string().min(1).max(360).optional(),
25243
+ actorId: z110.string().max(120).nullable().optional(),
25244
+ creativeDirection: z110.string().max(2e3).optional()
25204
25245
  }).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)."),
25205
- gapDurationSeconds: z109.union([
25206
- z109.literal(15),
25207
- z109.literal(30)
25246
+ gapDurationSeconds: z110.union([
25247
+ z110.literal(15),
25248
+ z110.literal(30)
25208
25249
  ]).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.")
25209
25250
  }),
25210
- z109.object({
25211
- kind: z109.literal("service_angle_approval"),
25212
- angleId: z109.string().uuid().optional(),
25213
- angleNumber: z109.number().int().positive().optional(),
25214
- content: z109.string().min(1).max(480).optional(),
25215
- creativeDirection: z109.string().min(1).max(1500).optional(),
25216
- actor: z109.string().min(1).max(360).optional()
25251
+ z110.object({
25252
+ kind: z110.literal("service_angle_approval"),
25253
+ angleId: z110.string().uuid().optional(),
25254
+ angleNumber: z110.number().int().positive().optional(),
25255
+ content: z110.string().min(1).max(480).optional(),
25256
+ creativeDirection: z110.string().min(1).max(1500).optional(),
25257
+ actor: z110.string().min(1).max(360).optional()
25217
25258
  }),
25218
- z109.object({
25219
- kind: z109.literal("service_script_approval"),
25220
- voiceovers: z109.record(z109.string(), z109.string().min(1).max(600)).optional(),
25221
- visualDirections: z109.record(z109.string(), z109.string().min(1).max(1200)).optional(),
25222
- voiceoversByScene: z109.record(z109.string(), z109.string().min(1).max(600)).optional(),
25223
- visualDirectionsByScene: z109.record(z109.string(), z109.string().min(1).max(1200)).optional()
25259
+ z110.object({
25260
+ kind: z110.literal("service_script_approval"),
25261
+ voiceovers: z110.record(z110.string(), z110.string().min(1).max(600)).optional(),
25262
+ visualDirections: z110.record(z110.string(), z110.string().min(1).max(1200)).optional(),
25263
+ voiceoversByScene: z110.record(z110.string(), z110.string().min(1).max(600)).optional(),
25264
+ visualDirectionsByScene: z110.record(z110.string(), z110.string().min(1).max(1200)).optional()
25224
25265
  })
25225
25266
  ]);
25226
- var ResolvePendingActionInput = z109.object({
25227
- taskId: z109.string().min(1),
25267
+ var ResolvePendingActionInput = z110.object({
25268
+ taskId: z110.string().min(1),
25228
25269
  action: PendingActionPayload
25229
25270
  }).strict();
25230
25271
  function resolveVariantConfirmVideoTier(action) {
25231
25272
  return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
25232
25273
  }
25233
25274
  __name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
25234
- var StatusForResolveSchema = z109.object({
25275
+ var StatusForResolveSchema = z110.object({
25235
25276
  // Metadata used to select the backend resume contract. Older API responses
25236
25277
  // may omit these fields, so the resolver keeps the generic fallback.
25237
- kind: z109.enum([
25278
+ kind: z110.enum([
25238
25279
  "autopilot",
25239
25280
  "video",
25240
25281
  "image",
@@ -25242,18 +25283,18 @@ var StatusForResolveSchema = z109.object({
25242
25283
  "mix",
25243
25284
  "service"
25244
25285
  ]).optional(),
25245
- selectedOutputs: z109.array(z109.enum([
25286
+ selectedOutputs: z110.array(z110.enum([
25246
25287
  "landing",
25247
25288
  "video",
25248
25289
  "image"
25249
25290
  ])).optional(),
25250
- videoAngleCount: z109.number().int().min(1).max(3).optional(),
25251
- ugcFormat: z109.enum([
25291
+ videoAngleCount: z110.number().int().min(1).max(3).optional(),
25292
+ ugcFormat: z110.enum([
25252
25293
  "single_8s",
25253
25294
  "single_15s",
25254
25295
  "double_30s"
25255
25296
  ]).optional(),
25256
- videoStyle: z109.enum([
25297
+ videoStyle: z110.enum([
25257
25298
  "ugc",
25258
25299
  "cartoon_3d",
25259
25300
  "product_only",
@@ -25263,13 +25304,13 @@ var StatusForResolveSchema = z109.object({
25263
25304
  videoQuality: VideoQualityEnum.optional(),
25264
25305
  videoRouteId: VideoRouteIdEnum.optional(),
25265
25306
  videoModel: TaskVideoModelEnum.optional(),
25266
- videoTier: z109.enum([
25307
+ videoTier: z110.enum([
25267
25308
  "legacy",
25268
25309
  "standard",
25269
25310
  "pro",
25270
25311
  "single_call"
25271
25312
  ]).optional(),
25272
- videoResolution: z109.enum([
25313
+ videoResolution: z110.enum([
25273
25314
  "480p",
25274
25315
  "720p"
25275
25316
  ]).optional(),
@@ -25277,60 +25318,60 @@ var StatusForResolveSchema = z109.object({
25277
25318
  // A task created before a narrative was blocked/hidden must still parse,
25278
25319
  // or resolve_pending_action could never approve it.
25279
25320
  narrativeStyle: NarrativeStyle.optional(),
25280
- pauseForVideoScriptReview: z109.boolean().optional(),
25281
- pendingUserAction: z109.object({
25282
- kind: z109.string(),
25283
- candidateGrouping: z109.string().optional(),
25284
- selectedImageUrls: z109.array(z109.string()).optional(),
25285
- proposedProductNames: z109.array(z109.string()).optional(),
25321
+ pauseForVideoScriptReview: z110.boolean().optional(),
25322
+ pendingUserAction: z110.object({
25323
+ kind: z110.string(),
25324
+ candidateGrouping: z110.string().optional(),
25325
+ selectedImageUrls: z110.array(z110.string()).optional(),
25326
+ proposedProductNames: z110.array(z110.string()).optional(),
25286
25327
  // Adaptive reference questions are server-owned. Echo only the evidence
25287
25328
  // identity and the choices shown by the current snapshot; never accept a
25288
25329
  // client-supplied reference set as authorization.
25289
- options: z109.array(ProductReferenceUserChoiceEnum).max(4).optional(),
25290
- mode: z109.enum([
25330
+ options: z110.array(ProductReferenceUserChoiceEnum).max(4).optional(),
25331
+ mode: z110.enum([
25291
25332
  "question",
25292
25333
  "visual_recovery"
25293
25334
  ]).optional(),
25294
25335
  /** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
25295
- canKeepSelection: z109.boolean().optional(),
25296
- decisionKey: z109.string().optional(),
25297
- questionOrdinal: z109.number().int().min(1).max(5).optional(),
25298
- questionCeiling: z109.union([
25299
- z109.literal(3),
25300
- z109.literal(5)
25336
+ canKeepSelection: z110.boolean().optional(),
25337
+ decisionKey: z110.string().optional(),
25338
+ questionOrdinal: z110.number().int().min(1).max(5).optional(),
25339
+ questionCeiling: z110.union([
25340
+ z110.literal(3),
25341
+ z110.literal(5)
25301
25342
  ]).optional(),
25302
- referenceEvidenceVersion: z109.number().int().positive().optional(),
25303
- expectedEvidenceHash: z109.string().optional(),
25304
- question: z109.object({
25305
- prompt: z109.string().min(1).max(240),
25306
- helpText: z109.string().min(1).max(300).optional(),
25307
- options: z109.array(z109.object({
25343
+ referenceEvidenceVersion: z110.number().int().positive().optional(),
25344
+ expectedEvidenceHash: z110.string().optional(),
25345
+ question: z110.object({
25346
+ prompt: z110.string().min(1).max(240),
25347
+ helpText: z110.string().min(1).max(300).optional(),
25348
+ options: z110.array(z110.object({
25308
25349
  value: ProductReferenceUserChoiceEnum,
25309
- label: z109.string().min(1).max(120),
25310
- description: z109.string().min(1).max(240).optional()
25350
+ label: z110.string().min(1).max(120),
25351
+ description: z110.string().min(1).max(240).optional()
25311
25352
  })).min(2).max(4)
25312
25353
  }).optional(),
25313
25354
  scope: ProductReferenceScopeEnum.optional(),
25314
- scopeKey: z109.string().optional(),
25315
- scopeSnapshotId: z109.string().uuid().optional(),
25316
- scopeHash: z109.string().optional(),
25317
- baseReferenceSetHash: z109.string().optional(),
25318
- phase: z109.enum([
25355
+ scopeKey: z110.string().optional(),
25356
+ scopeSnapshotId: z110.string().uuid().optional(),
25357
+ scopeHash: z110.string().optional(),
25358
+ baseReferenceSetHash: z110.string().optional(),
25359
+ phase: z110.enum([
25319
25360
  "preparation",
25320
25361
  "final"
25321
25362
  ]).optional(),
25322
- selectedRefKeys: z109.array(z109.string().min(1).max(200)).optional(),
25323
- allowedDecisions: z109.array(ProductReferenceResolutionDecisionEnum).optional(),
25324
- previews: z109.array(z109.object({
25325
- refKey: z109.string().min(1).max(200)
25363
+ selectedRefKeys: z110.array(z110.string().min(1).max(200)).optional(),
25364
+ allowedDecisions: z110.array(ProductReferenceResolutionDecisionEnum).optional(),
25365
+ previews: z110.array(z110.object({
25366
+ refKey: z110.string().min(1).max(200)
25326
25367
  }).passthrough()).optional(),
25327
- customAngleDraft: z109.string().optional(),
25328
- painPointsDraft: z109.string().optional(),
25329
- benefitsDraft: z109.string().optional(),
25330
- featuresDraft: z109.array(z109.string()).optional(),
25331
- angleOptions: z109.array(z109.object({
25332
- index: z109.number().int().nonnegative(),
25333
- angle: z109.string().min(1)
25368
+ customAngleDraft: z110.string().optional(),
25369
+ painPointsDraft: z110.string().optional(),
25370
+ benefitsDraft: z110.string().optional(),
25371
+ featuresDraft: z110.array(z110.string()).optional(),
25372
+ angleOptions: z110.array(z110.object({
25373
+ index: z110.number().int().nonnegative(),
25374
+ angle: z110.string().min(1)
25334
25375
  }).passthrough()).min(1).max(5).optional(),
25335
25376
  // Recommendation consumed only when the caller explicitly sends
25336
25377
  // gapDurationSeconds: 30 in the angle approval action.
@@ -25340,17 +25381,17 @@ var StatusForResolveSchema = z109.object({
25340
25381
  // keys. `actorId` (the saved custom actor the picker stored) was silently
25341
25382
  // dropped here, so the approval handler below could not echo it back on the
25342
25383
  // PATCH — the selection looked accepted and reached no render.
25343
- angles: z109.array(z109.object({
25344
- id: z109.string().uuid(),
25345
- content: z109.string(),
25346
- creativeDirection: z109.string(),
25347
- actor: z109.string(),
25348
- actorId: z109.string().nullable().optional()
25384
+ angles: z110.array(z110.object({
25385
+ id: z110.string().uuid(),
25386
+ content: z110.string(),
25387
+ creativeDirection: z110.string(),
25388
+ actor: z110.string(),
25389
+ actorId: z110.string().nullable().optional()
25349
25390
  }).passthrough()).optional(),
25350
- panels: z109.array(z109.object({
25351
- beatId: z109.string(),
25352
- voiceover: z109.string(),
25353
- visualDirection: z109.string()
25391
+ panels: z110.array(z110.object({
25392
+ beatId: z110.string(),
25393
+ voiceover: z110.string(),
25394
+ visualDirection: z110.string()
25354
25395
  }).passthrough()).optional()
25355
25396
  }).optional()
25356
25397
  }).passthrough();
@@ -25702,8 +25743,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
25702
25743
  server.registerTool("verify_landing_commerce", {
25703
25744
  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.",
25704
25745
  inputSchema: {
25705
- taskId: z109.string().uuid(),
25706
- editId: z109.string().uuid()
25746
+ taskId: z110.string().uuid(),
25747
+ editId: z110.string().uuid()
25707
25748
  },
25708
25749
  annotations: OVERWRITES_EXTERNAL
25709
25750
  }, async (input) => {
@@ -26343,7 +26384,7 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
26343
26384
  __name(registerTaskTools, "registerTaskTools");
26344
26385
 
26345
26386
  // src/tools/creatives.ts
26346
- import { z as z110 } from "zod";
26387
+ import { z as z111 } from "zod";
26347
26388
  var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
26348
26389
  var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
26349
26390
  var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
@@ -26354,72 +26395,72 @@ var CreativeRefs = {
26354
26395
  images: ImagesInput,
26355
26396
  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.'),
26356
26397
  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.'),
26357
- price: z110.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.'),
26358
- offer: z110.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.'),
26359
- compareAtPrice: z110.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
26360
- productContext: z110.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."),
26361
- productLabel: z110.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.'),
26362
- buyerPersona: z110.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.'),
26363
- isCombo: z110.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
26364
- competitorScanEnabled: z110.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."),
26365
- brandId: z110.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.")
26398
+ price: z111.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.'),
26399
+ offer: z111.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.'),
26400
+ compareAtPrice: z111.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
26401
+ productContext: z111.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."),
26402
+ productLabel: z111.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.'),
26403
+ buyerPersona: z111.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.'),
26404
+ isCombo: z111.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
26405
+ competitorScanEnabled: z111.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."),
26406
+ brandId: z111.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.")
26366
26407
  };
26367
- var VideoPresenter = z110.discriminatedUnion("mode", [
26368
- z110.object({
26369
- mode: z110.literal("none")
26408
+ var VideoPresenter = z111.discriminatedUnion("mode", [
26409
+ z111.object({
26410
+ mode: z111.literal("none")
26370
26411
  }).strict(),
26371
- z110.object({
26372
- mode: z110.literal("saved_actor"),
26373
- actorId: z110.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
26412
+ z111.object({
26413
+ mode: z111.literal("saved_actor"),
26414
+ actorId: z111.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
26374
26415
  }).strict(),
26375
- z110.object({
26376
- mode: z110.literal("described"),
26377
- description: z110.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
26416
+ z111.object({
26417
+ mode: z111.literal("described"),
26418
+ description: z111.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
26378
26419
  }).strict()
26379
26420
  ]);
26380
- var VideoCreativeSetup = z110.discriminatedUnion("mode", [
26381
- z110.object({
26382
- mode: z110.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
26421
+ var VideoCreativeSetup = z111.discriminatedUnion("mode", [
26422
+ z111.object({
26423
+ mode: z111.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
26383
26424
  }).strict(),
26384
- z110.object({
26385
- mode: z110.literal("guided"),
26425
+ z111.object({
26426
+ mode: z111.literal("guided"),
26386
26427
  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.'),
26387
- buyerPersona: z110.string().trim().min(1).max(360),
26428
+ buyerPersona: z111.string().trim().min(1).max(360),
26388
26429
  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.'),
26389
26430
  presenter: VideoPresenter,
26390
- creativeDirection: z110.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
26431
+ creativeDirection: z111.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
26391
26432
  }).strict()
26392
26433
  ]);
26393
- var VideoInput = z110.object({
26434
+ var VideoInput = z111.object({
26394
26435
  images: CreativeRefs.images.optional(),
26395
26436
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
26396
- title: z110.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
26397
- primaryAngle: z110.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".'),
26437
+ title: z111.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
26438
+ primaryAngle: z111.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".'),
26398
26439
  language: CreativeRefs.language,
26399
26440
  country: CreativeRefs.country,
26400
- aspectRatio: z110.enum([
26441
+ aspectRatio: z111.enum([
26401
26442
  "9:16",
26402
26443
  "16:9",
26403
26444
  "Auto"
26404
26445
  ]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
26405
26446
  generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, efectos y m\xFAsica sobre cada video entregado (variante with_ai_edit; se cobra al entregar, por video). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro"; false/omitido = sin edici\xF3n.'),
26406
- durationSeconds: z110.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."),
26407
- videoAngleCount: z110.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."),
26447
+ durationSeconds: z111.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."),
26448
+ videoAngleCount: z111.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."),
26408
26449
  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.'),
26409
26450
  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."),
26410
26451
  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.'),
26411
26452
  videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
26412
26453
  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.'),
26413
- features: z110.array(z110.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
26454
+ features: z111.array(z111.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
26414
26455
  price: CreativeRefs.price,
26415
26456
  offer: CreativeRefs.offer,
26416
26457
  productContext: CreativeRefs.productContext,
26417
26458
  productLabel: CreativeRefs.productLabel,
26418
- cta: z110.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.'),
26419
- scriptNotes: z110.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.'),
26459
+ cta: z111.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.'),
26460
+ scriptNotes: z111.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.'),
26420
26461
  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.'),
26421
26462
  competitorScanEnabled: CreativeRefs.competitorScanEnabled,
26422
- replicateWinnerWhenFound: z110.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."),
26463
+ replicateWinnerWhenFound: z111.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."),
26423
26464
  brandId: CreativeRefs.brandId
26424
26465
  }).strict();
26425
26466
  var FreeVideoQualityEnum = VideoQualityEnum;
@@ -26437,7 +26478,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
26437
26478
  length: 29
26438
26479
  }, (_, index) => index + 2)
26439
26480
  };
26440
- var FreeVideoModelIdEnum = z110.enum([
26481
+ var FreeVideoModelIdEnum = z111.enum([
26441
26482
  "grok-imagine-video-1-5-preview",
26442
26483
  "minimax-h3/reference-to-video",
26443
26484
  "wan/3-0-video",
@@ -26448,66 +26489,66 @@ var FREE_SELECTABLE_MODEL_IDS = [
26448
26489
  "minimax-h3/reference-to-video",
26449
26490
  "wan/3-0-video"
26450
26491
  ];
26451
- var FreeVideoInput = z110.object({
26492
+ var FreeVideoInput = z111.object({
26452
26493
  images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
26453
- rawPrompt: z110.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."),
26494
+ rawPrompt: z111.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."),
26454
26495
  language: CreativeRefs.language,
26455
26496
  quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
26456
26497
  // Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
26457
26498
  // parsed ONLY so the handler can reject it with a message naming its
26458
26499
  // replacement — dropping it silently would turn a caller's explicit
26459
26500
  // Pro++ pick into a quiet fallback to Wan.
26460
- freeProModel: z110.enum([
26501
+ freeProModel: z111.enum([
26461
26502
  "wan",
26462
26503
  "seedance"
26463
26504
  ]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
26464
26505
  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.'),
26465
- durationSeconds: z110.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."),
26506
+ durationSeconds: z111.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."),
26466
26507
  videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
26467
- generateAiMusic: z110.boolean().default(false).describe('Opcional. Agrega m\xFAsica instrumental IA debajo del audio nativo. Default false. Equivale a generateAiEdit (nivel "pro"): la Edici\xF3n con IA trae su propia m\xFAsica.'),
26508
+ generateAiMusic: z111.boolean().default(false).describe('Opcional. Agrega m\xFAsica instrumental IA debajo del audio nativo. Default false. Equivale a generateAiEdit (nivel "pro"): la Edici\xF3n con IA trae su propia m\xFAsica.'),
26468
26509
  generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, gr\xE1ficos y m\xFAsica sobre el video ya entregado (variante with_ai_edit; se cobra al entregar). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro". Default sin edici\xF3n.'),
26469
- addSubtitles: z110.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
26470
- idempotencyKey: z110.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.")
26510
+ addSubtitles: z111.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
26511
+ idempotencyKey: z111.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.")
26471
26512
  }).strict();
26472
26513
  var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
26473
- var ImageCreativeSetup = z110.discriminatedUnion("mode", [
26474
- z110.object({
26475
- mode: z110.literal("automatic")
26514
+ var ImageCreativeSetup = z111.discriminatedUnion("mode", [
26515
+ z111.object({
26516
+ mode: z111.literal("automatic")
26476
26517
  }).strict(),
26477
- z110.object({
26478
- mode: z110.literal("guided"),
26479
- creativeArchetype: z110.union([
26518
+ z111.object({
26519
+ mode: z111.literal("guided"),
26520
+ creativeArchetype: z111.union([
26480
26521
  ImageCreativeArchetypeEnum,
26481
- z110.literal("ai_decides")
26522
+ z111.literal("ai_decides")
26482
26523
  ]),
26483
- visualTreatment: z110.union([
26524
+ visualTreatment: z111.union([
26484
26525
  ImageCreativeVisualTreatmentEnum,
26485
- z110.literal("ai_decides")
26526
+ z111.literal("ai_decides")
26486
26527
  ]),
26487
26528
  aspectRatio: ImageCreativeAspectRatioEnum,
26488
- nVariants: z110.union([
26489
- z110.literal(1),
26490
- z110.literal(2),
26491
- z110.literal(3),
26492
- z110.literal(4),
26493
- z110.literal(6)
26529
+ nVariants: z111.union([
26530
+ z111.literal(1),
26531
+ z111.literal(2),
26532
+ z111.literal(3),
26533
+ z111.literal(4),
26534
+ z111.literal(6)
26494
26535
  ]),
26495
- imageModel: z110.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.'),
26496
- styleMix: z110.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
26497
- generateAdCopy: z110.boolean(),
26498
- competitorScanEnabled: z110.boolean(),
26499
- productContext: z110.string().trim().min(1).max(3e3).nullable(),
26500
- creativeDirection: z110.string().trim().min(1).max(500).nullable(),
26501
- brandColors: z110.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.'),
26502
- headline: z110.string().trim().min(1).max(120).nullable(),
26503
- subheadline: z110.string().trim().min(1).max(160).nullable()
26536
+ imageModel: z111.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.'),
26537
+ styleMix: z111.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
26538
+ generateAdCopy: z111.boolean(),
26539
+ competitorScanEnabled: z111.boolean(),
26540
+ productContext: z111.string().trim().min(1).max(3e3).nullable(),
26541
+ creativeDirection: z111.string().trim().min(1).max(500).nullable(),
26542
+ brandColors: z111.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.'),
26543
+ headline: z111.string().trim().min(1).max(120).nullable(),
26544
+ subheadline: z111.string().trim().min(1).max(160).nullable()
26504
26545
  }).strict()
26505
26546
  ]).superRefine((setup, context) => {
26506
26547
  if (setup.mode !== "guided") return;
26507
26548
  const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
26508
26549
  if (needsStyleMix && setup.styleMix === null) {
26509
26550
  context.addIssue({
26510
- code: z110.ZodIssueCode.custom,
26551
+ code: z111.ZodIssueCode.custom,
26511
26552
  path: [
26512
26553
  "styleMix"
26513
26554
  ],
@@ -26516,7 +26557,7 @@ var ImageCreativeSetup = z110.discriminatedUnion("mode", [
26516
26557
  }
26517
26558
  if (!needsStyleMix && setup.styleMix !== null) {
26518
26559
  context.addIssue({
26519
- code: z110.ZodIssueCode.custom,
26560
+ code: z111.ZodIssueCode.custom,
26520
26561
  path: [
26521
26562
  "styleMix"
26522
26563
  ],
@@ -26525,7 +26566,7 @@ var ImageCreativeSetup = z110.discriminatedUnion("mode", [
26525
26566
  }
26526
26567
  if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
26527
26568
  context.addIssue({
26528
- code: z110.ZodIssueCode.custom,
26569
+ code: z111.ZodIssueCode.custom,
26529
26570
  path: [
26530
26571
  "aspectRatio"
26531
26572
  ],
@@ -26533,55 +26574,55 @@ var ImageCreativeSetup = z110.discriminatedUnion("mode", [
26533
26574
  });
26534
26575
  }
26535
26576
  });
26536
- var LandingCreativeSetup = z110.discriminatedUnion("mode", [
26537
- z110.object({
26538
- mode: z110.literal("automatic")
26577
+ var LandingCreativeSetup = z111.discriminatedUnion("mode", [
26578
+ z111.object({
26579
+ mode: z111.literal("automatic")
26539
26580
  }).strict(),
26540
- z110.object({
26541
- mode: z110.literal("guided"),
26581
+ z111.object({
26582
+ mode: z111.literal("guided"),
26542
26583
  landingStrategy: LandingStrategyEnum,
26543
26584
  landingImageFormat: LandingImageFormatEnum,
26544
- competitorScanEnabled: z110.boolean(),
26545
- paymentMethods: z110.string().trim().min(1).max(240).nullable(),
26546
- productContext: z110.string().trim().min(1).max(3e3).nullable(),
26547
- creativeDirection: z110.string().trim().min(1).max(500).nullable(),
26548
- headline: z110.string().trim().min(1).max(120).nullable(),
26549
- subheadline: z110.string().trim().min(1).max(160).nullable()
26585
+ competitorScanEnabled: z111.boolean(),
26586
+ paymentMethods: z111.string().trim().min(1).max(240).nullable(),
26587
+ productContext: z111.string().trim().min(1).max(3e3).nullable(),
26588
+ creativeDirection: z111.string().trim().min(1).max(500).nullable(),
26589
+ headline: z111.string().trim().min(1).max(120).nullable(),
26590
+ subheadline: z111.string().trim().min(1).max(160).nullable()
26550
26591
  }).strict()
26551
26592
  ]);
26552
- var ImageInput = z110.object({
26593
+ var ImageInput = z111.object({
26553
26594
  images: CreativeRefs.images.optional(),
26554
26595
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
26555
- productTitle: z110.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
26556
- primaryAngle: z110.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.'),
26596
+ productTitle: z111.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
26597
+ primaryAngle: z111.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.'),
26557
26598
  buyerPersona: CreativeRefs.buyerPersona,
26558
26599
  language: CreativeRefs.language,
26559
26600
  country: CreativeRefs.country,
26560
26601
  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."),
26561
26602
  imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
26562
- features: z110.array(z110.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
26603
+ features: z111.array(z111.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
26563
26604
  price: CreativeRefs.price,
26564
- omitPrice: z110.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."),
26605
+ omitPrice: z111.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."),
26565
26606
  compareAtPrice: CreativeRefs.compareAtPrice,
26566
26607
  offer: CreativeRefs.offer,
26567
26608
  productLabel: CreativeRefs.productLabel,
26568
26609
  isCombo: CreativeRefs.isCombo,
26569
26610
  brandId: CreativeRefs.brandId
26570
26611
  });
26571
- var EditImageCreativeInput = z110.object({
26572
- taskId: z110.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
26573
- variantIndex: z110.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
26574
- clientRequestId: z110.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."),
26575
- instruction: z110.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".')
26612
+ var EditImageCreativeInput = z111.object({
26613
+ taskId: z111.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
26614
+ variantIndex: z111.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
26615
+ clientRequestId: z111.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."),
26616
+ instruction: z111.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".')
26576
26617
  });
26577
- var LandingInput = z110.object({
26578
- includeInitialLandingGif: z110.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
26618
+ var LandingInput = z111.object({
26619
+ includeInitialLandingGif: z111.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
26579
26620
  images: CreativeRefs.images.optional(),
26580
26621
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
26581
26622
  language: CreativeRefs.language,
26582
26623
  country: CreativeRefs.country,
26583
26624
  creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
26584
- salesAngle: z110.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.'),
26625
+ salesAngle: z111.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.'),
26585
26626
  buyerPersona: CreativeRefs.buyerPersona,
26586
26627
  price: CreativeRefs.price,
26587
26628
  compareAtPrice: CreativeRefs.compareAtPrice,
@@ -26863,8 +26904,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
26863
26904
  server.registerTool("get_image_edit_status", {
26864
26905
  description: imageEditStatusGuidance.summary,
26865
26906
  inputSchema: {
26866
- taskId: z110.string().uuid(),
26867
- operationId: z110.string().uuid()
26907
+ taskId: z111.string().uuid(),
26908
+ operationId: z111.string().uuid()
26868
26909
  },
26869
26910
  annotations: READS_INTERNAL
26870
26911
  }, async (input) => {
@@ -26921,10 +26962,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
26921
26962
  __name(registerCreativeTools, "registerCreativeTools");
26922
26963
 
26923
26964
  // src/tools/creative-variants.ts
26924
- import { z as z111 } from "zod";
26965
+ import { z as z112 } from "zod";
26925
26966
  var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
26926
26967
  var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
26927
- var LandingSectionKeyEnum = z111.enum([
26968
+ var LandingSectionKeyEnum = z112.enum([
26928
26969
  "problem_hook",
26929
26970
  "problem_cost",
26930
26971
  "solution_mechanism",
@@ -26964,24 +27005,24 @@ var LandingSectionKeyEnum = z111.enum([
26964
27005
  "lifestyle_fit",
26965
27006
  "join_lifestyle"
26966
27007
  ]);
26967
- var CreativeVariantKindEnum = z111.enum([
27008
+ var CreativeVariantKindEnum = z112.enum([
26968
27009
  "video",
26969
27010
  "image",
26970
27011
  "landing"
26971
27012
  ]);
26972
- var EstimateCreativeVariantInputBase = z111.object({
26973
- sourceTaskId: z111.string().uuid().describe("ID de la tarea original completada."),
27013
+ var EstimateCreativeVariantInputBase = z112.object({
27014
+ sourceTaskId: z112.string().uuid().describe("ID de la tarea original completada."),
26974
27015
  kind: CreativeVariantKindEnum,
26975
27016
  videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
26976
27017
  videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
26977
- nVariants: z111.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
27018
+ nVariants: z112.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
26978
27019
  sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
26979
- instructions: z111.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.")
27020
+ instructions: z112.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.")
26980
27021
  }).strict();
26981
27022
  var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
26982
27023
  if (input.kind === "video" && input.nVariants !== void 0) {
26983
27024
  ctx.addIssue({
26984
- code: z111.ZodIssueCode.custom,
27025
+ code: z112.ZodIssueCode.custom,
26985
27026
  path: [
26986
27027
  "nVariants"
26987
27028
  ],
@@ -26991,7 +27032,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
26991
27032
  if (input.kind !== "video") {
26992
27033
  if (input.videoPreset !== void 0) {
26993
27034
  ctx.addIssue({
26994
- code: z111.ZodIssueCode.custom,
27035
+ code: z112.ZodIssueCode.custom,
26995
27036
  path: [
26996
27037
  "videoPreset"
26997
27038
  ],
@@ -27000,7 +27041,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
27000
27041
  }
27001
27042
  if (input.videoResolution !== void 0) {
27002
27043
  ctx.addIssue({
27003
- code: z111.ZodIssueCode.custom,
27044
+ code: z112.ZodIssueCode.custom,
27004
27045
  path: [
27005
27046
  "videoResolution"
27006
27047
  ],
@@ -27010,7 +27051,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
27010
27051
  }
27011
27052
  if (input.kind !== "image" && input.nVariants !== void 0) {
27012
27053
  ctx.addIssue({
27013
- code: z111.ZodIssueCode.custom,
27054
+ code: z112.ZodIssueCode.custom,
27014
27055
  path: [
27015
27056
  "nVariants"
27016
27057
  ],
@@ -27020,7 +27061,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
27020
27061
  if (input.kind !== "landing") {
27021
27062
  if (input.sectionKey !== void 0) {
27022
27063
  ctx.addIssue({
27023
- code: z111.ZodIssueCode.custom,
27064
+ code: z112.ZodIssueCode.custom,
27024
27065
  path: [
27025
27066
  "sectionKey"
27026
27067
  ],
@@ -27029,7 +27070,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
27029
27070
  }
27030
27071
  if (input.instructions !== void 0) {
27031
27072
  ctx.addIssue({
27032
- code: z111.ZodIssueCode.custom,
27073
+ code: z112.ZodIssueCode.custom,
27033
27074
  path: [
27034
27075
  "instructions"
27035
27076
  ],
@@ -27038,31 +27079,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
27038
27079
  }
27039
27080
  }
27040
27081
  });
27041
- var CreateCreativeVariantInputBase = z111.object({
27042
- sourceTaskId: z111.string().uuid().describe("ID de la tarea original completada."),
27082
+ var CreateCreativeVariantInputBase = z112.object({
27083
+ sourceTaskId: z112.string().uuid().describe("ID de la tarea original completada."),
27043
27084
  kind: CreativeVariantKindEnum,
27044
- confirm: z111.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
27045
- clientRequestId: z111.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."),
27046
- angle: z111.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
27047
- buyerPersona: z111.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
27048
- scriptNotes: z111.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
27049
- creativeDirection: z111.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
27085
+ confirm: z112.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
27086
+ clientRequestId: z112.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."),
27087
+ angle: z112.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
27088
+ buyerPersona: z112.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
27089
+ scriptNotes: z112.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
27090
+ creativeDirection: z112.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
27050
27091
  videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
27051
27092
  videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
27052
- generateAiMusic: z111.boolean().optional().describe("Opcional para video."),
27053
- nVariants: z111.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
27093
+ generateAiMusic: z112.boolean().optional().describe("Opcional para video."),
27094
+ nVariants: z112.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
27054
27095
  imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
27055
27096
  creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
27056
27097
  visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
27057
27098
  aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
27058
- styleMix: z111.boolean().optional().describe("Opcional para imagen."),
27099
+ styleMix: z112.boolean().optional().describe("Opcional para imagen."),
27059
27100
  sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
27060
- instructions: z111.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.")
27101
+ instructions: z112.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.")
27061
27102
  }).strict();
27062
27103
  var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
27063
27104
  if ((input.kind === "video" || input.kind === "image") && !input.angle) {
27064
27105
  ctx.addIssue({
27065
- code: z111.ZodIssueCode.custom,
27106
+ code: z112.ZodIssueCode.custom,
27066
27107
  path: [
27067
27108
  "angle"
27068
27109
  ],
@@ -27071,7 +27112,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
27071
27112
  }
27072
27113
  if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
27073
27114
  ctx.addIssue({
27074
- code: z111.ZodIssueCode.custom,
27115
+ code: z112.ZodIssueCode.custom,
27075
27116
  path: [
27076
27117
  "instructions"
27077
27118
  ],
@@ -27117,7 +27158,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
27117
27158
  for (const field of fieldsByKind[input.kind]) {
27118
27159
  if (input[field] !== void 0) {
27119
27160
  ctx.addIssue({
27120
- code: z111.ZodIssueCode.custom,
27161
+ code: z112.ZodIssueCode.custom,
27121
27162
  path: [
27122
27163
  field
27123
27164
  ],
@@ -27250,13 +27291,13 @@ function registerCreativeVariantTools(server, api) {
27250
27291
  __name(registerCreativeVariantTools, "registerCreativeVariantTools");
27251
27292
 
27252
27293
  // src/tools/script-review.ts
27253
- import { z as z112 } from "zod";
27294
+ import { z as z113 } from "zod";
27254
27295
  var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
27255
27296
  var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
27256
27297
  var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
27257
- var GetVideoScriptInput = z112.object({
27258
- taskId: z112.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
27259
- angleKey: z112.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.')
27298
+ var GetVideoScriptInput = z113.object({
27299
+ taskId: z113.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
27300
+ angleKey: z113.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.')
27260
27301
  }).strict();
27261
27302
  var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
27262
27303
  var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
@@ -27339,7 +27380,7 @@ function registerScriptReviewTools(server, api) {
27339
27380
  __name(registerScriptReviewTools, "registerScriptReviewTools");
27340
27381
 
27341
27382
  // src/tools/connections.ts
27342
- import { z as z113 } from "zod";
27383
+ import { z as z114 } from "zod";
27343
27384
  var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
27344
27385
  var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
27345
27386
  var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
@@ -27348,7 +27389,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
27348
27389
  function registerConnectionTools(server, api) {
27349
27390
  server.registerTool("list_shopify_shops", {
27350
27391
  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.",
27351
- inputSchema: z113.object({}).shape,
27392
+ inputSchema: z114.object({}).shape,
27352
27393
  annotations: READS_INTERNAL
27353
27394
  }, async () => {
27354
27395
  try {
@@ -27360,10 +27401,10 @@ function registerConnectionTools(server, api) {
27360
27401
  });
27361
27402
  server.registerTool("list_shopify_products", {
27362
27403
  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.',
27363
- inputSchema: z113.object({
27364
- shopDomain: z113.string().min(3).max(120),
27365
- query: z113.string().trim().max(120).optional(),
27366
- taskId: z113.string().uuid().optional()
27404
+ inputSchema: z114.object({
27405
+ shopDomain: z114.string().min(3).max(120),
27406
+ query: z114.string().trim().max(120).optional(),
27407
+ taskId: z114.string().uuid().optional()
27367
27408
  }).shape,
27368
27409
  annotations: READS_EXTERNAL
27369
27410
  }, async ({ shopDomain, query, taskId }) => {
@@ -27381,7 +27422,7 @@ function registerConnectionTools(server, api) {
27381
27422
  });
27382
27423
  server.registerTool("list_meta_ad_accounts", {
27383
27424
  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.",
27384
- inputSchema: z113.object({}).shape,
27425
+ inputSchema: z114.object({}).shape,
27385
27426
  annotations: READS_EXTERNAL
27386
27427
  }, async () => {
27387
27428
  try {
@@ -27393,7 +27434,7 @@ function registerConnectionTools(server, api) {
27393
27434
  });
27394
27435
  server.registerTool("list_meta_destinations", {
27395
27436
  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.",
27396
- inputSchema: z113.object({}).shape,
27437
+ inputSchema: z114.object({}).shape,
27397
27438
  annotations: READS_EXTERNAL,
27398
27439
  _meta: {
27399
27440
  "openai/widgetAccessible": true
@@ -27408,7 +27449,7 @@ function registerConnectionTools(server, api) {
27408
27449
  });
27409
27450
  server.registerTool("list_tiktok_advertisers", {
27410
27451
  description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
27411
- inputSchema: z113.object({}).shape,
27452
+ inputSchema: z114.object({}).shape,
27412
27453
  annotations: READS_EXTERNAL
27413
27454
  }, async () => {
27414
27455
  try {
@@ -27422,7 +27463,7 @@ function registerConnectionTools(server, api) {
27422
27463
  __name(registerConnectionTools, "registerConnectionTools");
27423
27464
 
27424
27465
  // src/tools/actors.ts
27425
- import { z as z114 } from "zod";
27466
+ import { z as z115 } from "zod";
27426
27467
  var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
27427
27468
  var actorVoiceGuidance = {
27428
27469
  capabilities: getProductMakerCapabilityModelGuidance("get_actor_voice_capabilities"),
@@ -27462,7 +27503,7 @@ function sanitizeVoiceResult(value) {
27462
27503
  __name(sanitizeVoiceResult, "sanitizeVoiceResult");
27463
27504
  function registerActorTools(server, api) {
27464
27505
  const actor = {
27465
- actorId: z114.string().min(1).max(64)
27506
+ actorId: z115.string().min(1).max(64)
27466
27507
  };
27467
27508
  const safe = /* @__PURE__ */ __name(async (request) => {
27468
27509
  try {
@@ -27491,8 +27532,8 @@ function registerActorTools(server, api) {
27491
27532
  inputSchema: {
27492
27533
  ...actor,
27493
27534
  draft: ActorVoiceDraftSchema,
27494
- requestKey: z114.string().trim().min(1).max(128),
27495
- acceptedQuoteId: z114.string().trim().min(1).max(128)
27535
+ requestKey: z115.string().trim().min(1).max(128),
27536
+ acceptedQuoteId: z115.string().trim().min(1).max(128)
27496
27537
  },
27497
27538
  annotations: CREATES_PAID
27498
27539
  }, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews`, body)));
@@ -27500,7 +27541,7 @@ function registerActorTools(server, api) {
27500
27541
  description: actorVoiceGuidance.get.summary,
27501
27542
  inputSchema: {
27502
27543
  ...actor,
27503
- candidateId: z114.string().min(1).max(64)
27544
+ candidateId: z115.string().min(1).max(64)
27504
27545
  },
27505
27546
  annotations: READS_INTERNAL
27506
27547
  }, async ({ actorId, candidateId }) => safe(api.getJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews/${encodeURIComponent(candidateId)}`)));
@@ -27508,15 +27549,15 @@ function registerActorTools(server, api) {
27508
27549
  description: actorVoiceGuidance.approve.summary,
27509
27550
  inputSchema: {
27510
27551
  ...actor,
27511
- candidateId: z114.string().min(1).max(64),
27512
- expectedRevision: z114.number().int().positive(),
27513
- expectedApprovedRevision: z114.number().int().positive().nullable().optional()
27552
+ candidateId: z115.string().min(1).max(64),
27553
+ expectedRevision: z115.number().int().positive(),
27554
+ expectedApprovedRevision: z115.number().int().positive().nullable().optional()
27514
27555
  },
27515
27556
  annotations: CREATES_INTERNAL
27516
27557
  }, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/approve`, body)));
27517
27558
  server.registerTool("list_actors", {
27518
27559
  description: listActorsGuidance.summary + " Devuelve id, nombre, descripci\xF3n, g\xE9nero y voz privada del personaje. Cuando el personaje tiene una voz personalizada, `voice.identityId` y `voice.revision` identifican la versi\xF3n aprobada \u2014 conserva la revisi\xF3n al llamar `approve_actor_voice` (expectedApprovedRevision) para reemplazarla. Los IDs de proveedor nunca se exponen por MCP. Usa el `id` como `actorId` al crear o editar una tarea. Solo aparecen los personajes listos para usar; si la lista est\xE1 vac\xEDa, dile al usuario que cree uno en productmaker.app antes de intentar asignarlo. No modifica nada.",
27519
- inputSchema: z114.object({}).shape,
27560
+ inputSchema: z115.object({}).shape,
27520
27561
  annotations: READS_INTERNAL
27521
27562
  }, async () => {
27522
27563
  try {
@@ -27549,7 +27590,7 @@ function registerActorTools(server, api) {
27549
27590
  __name(registerActorTools, "registerActorTools");
27550
27591
 
27551
27592
  // src/tools/publish.ts
27552
- import { z as z115 } from "zod";
27593
+ import { z as z116 } from "zod";
27553
27594
 
27554
27595
  // src/tools/meta-publish-attempt-id.ts
27555
27596
  var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
@@ -27588,40 +27629,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
27588
27629
  var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
27589
27630
  var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
27590
27631
  var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
27591
- var ShopifyInput = z115.object({
27592
- taskId: z115.string().min(1),
27593
- shopDomain: z115.string().min(1),
27632
+ var ShopifyInput = z116.object({
27633
+ taskId: z116.string().min(1),
27634
+ shopDomain: z116.string().min(1),
27594
27635
  /** Override: number of landing images to include. Default = ALL images the
27595
27636
  * task generated (the MCP fetches /v1/results first to count). Bounded
27596
27637
  * generously here; the backend validates each index against
27597
27638
  * landing.images.length and rejects out-of-range. */
27598
- numLandingImages: z115.number().int().min(1).max(20).optional(),
27599
- variantIndex: z115.number().int().min(0).optional(),
27639
+ numLandingImages: z116.number().int().min(1).max(20).optional(),
27640
+ variantIndex: z116.number().int().min(0).optional(),
27600
27641
  /** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
27601
27642
  * When true, the landing renders variant-picker pills; when false, it ships
27602
27643
  * a single-option product page. Defaults to false. */
27603
- showVariantPicker: z115.boolean().optional(),
27644
+ showVariantPicker: z116.boolean().optional(),
27604
27645
  /** Default `auto` updates the product previously published for this task and
27605
27646
  * shop. Use `existing` with targetProductId to choose another product, or
27606
27647
  * `new` only when the user explicitly wants a duplicate/new listing. */
27607
- publicationMode: z115.enum([
27648
+ publicationMode: z116.enum([
27608
27649
  "auto",
27609
27650
  "existing",
27610
27651
  "new"
27611
27652
  ]).optional(),
27612
27653
  /** Shopify product GID, numeric id, or admin product URL. Required when
27613
27654
  * publicationMode is `existing`. */
27614
- targetProductId: z115.string().trim().min(1).max(300).optional(),
27655
+ targetProductId: z116.string().trim().min(1).max(300).optional(),
27615
27656
  /** Add an announcement bar text above add-to-cart (optional). */
27616
- announcementBarEnabled: z115.boolean().optional(),
27617
- announcementBarText: z115.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
27657
+ announcementBarEnabled: z116.boolean().optional(),
27658
+ announcementBarText: z116.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
27618
27659
  commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
27619
- confirmed: z115.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
27660
+ confirmed: z116.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
27620
27661
  });
27621
27662
  var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
27622
27663
  if (value.commerceCorrection && value.confirmed !== true) {
27623
27664
  ctx.addIssue({
27624
- code: z115.ZodIssueCode.custom,
27665
+ code: z116.ZodIssueCode.custom,
27625
27666
  path: [
27626
27667
  "confirmed"
27627
27668
  ],
@@ -27630,7 +27671,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
27630
27671
  }
27631
27672
  if (value.announcementBarEnabled && !value.announcementBarText) {
27632
27673
  ctx.addIssue({
27633
- code: z115.ZodIssueCode.custom,
27674
+ code: z116.ZodIssueCode.custom,
27634
27675
  path: [
27635
27676
  "announcementBarText"
27636
27677
  ],
@@ -27639,7 +27680,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
27639
27680
  }
27640
27681
  if (!value.announcementBarEnabled && value.announcementBarText) {
27641
27682
  ctx.addIssue({
27642
- code: z115.ZodIssueCode.custom,
27683
+ code: z116.ZodIssueCode.custom,
27643
27684
  path: [
27644
27685
  "announcementBarText"
27645
27686
  ],
@@ -27653,91 +27694,91 @@ function parseShopifyInput(rawInput) {
27653
27694
  return parsed.data;
27654
27695
  }
27655
27696
  __name(parseShopifyInput, "parseShopifyInput");
27656
- var McpCampaignConfig = z115.object({
27697
+ var McpCampaignConfig = z116.object({
27657
27698
  /** ALWAYS in US dollars, whatever the ad account's currency is. ProductMaker
27658
27699
  * converts to the account currency server-side. Do NOT pre-convert: on a COP
27659
27700
  * account the user's "60.000 al día" is `dailyBudgetUsd: 15`, not 60000. */
27660
- dailyBudgetUsd: z115.number().positive().optional(),
27701
+ dailyBudgetUsd: z116.number().positive().optional(),
27661
27702
  /** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
27662
27703
  * normalizes at validation). Meta accepts max 1 (single-country ad set).
27663
27704
  * TikTok takes only the first entry. */
27664
- targetCountries: z115.array(CountryIso2Schema).max(1).optional(),
27665
- campaignName: z115.string().trim().min(1).max(100).optional()
27705
+ targetCountries: z116.array(CountryIso2Schema).max(1).optional(),
27706
+ campaignName: z116.string().trim().min(1).max(100).optional()
27666
27707
  });
27667
27708
  var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
27668
- var MetaInput = z115.object({
27669
- taskId: z115.string().min(1),
27709
+ var MetaInput = z116.object({
27710
+ taskId: z116.string().min(1),
27670
27711
  /** Exact Meta Business portfolio selected from `list_meta_destinations`. */
27671
- portfolioId: z115.string().trim().min(1),
27712
+ portfolioId: z116.string().trim().min(1),
27672
27713
  /** Exact Facebook Page selected from `list_meta_destinations`. */
27673
- pageId: z115.string().trim().min(1),
27714
+ pageId: z116.string().trim().min(1),
27674
27715
  adAccountId: McpAdAccountId,
27675
- pixelId: z115.string().min(1).optional(),
27676
- landingUrl: z115.string().url().optional(),
27716
+ pixelId: z116.string().min(1).optional(),
27717
+ landingUrl: z116.string().url().optional(),
27677
27718
  /** Select which angles to publish by 0-based index. Omit to publish all
27678
27719
  * successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
27679
- angleIndexes: z115.array(z115.number().int().nonnegative()).optional(),
27720
+ angleIndexes: z116.array(z116.number().int().nonnegative()).optional(),
27680
27721
  campaignConfig: McpCampaignConfig.optional(),
27681
27722
  /** Override the ad's primary text (body copy). If omitted, ProductMaker
27682
27723
  * uses the auto-generated copy attached to the task. Capped at 500 chars
27683
27724
  * (Meta's primary-text limit). */
27684
- primaryText: z115.string().trim().min(1).max(500).optional(),
27725
+ primaryText: z116.string().trim().min(1).max(500).optional(),
27685
27726
  /** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
27686
27727
  * (wa.me) instead of a landing page. */
27687
- phoneNumber: z115.string().min(8).max(32).optional()
27728
+ phoneNumber: z116.string().min(8).max(32).optional()
27688
27729
  });
27689
- var GroupedTaskSource = z115.object({
27690
- type: z115.literal("task"),
27691
- taskId: z115.string().min(1),
27692
- angleIndex: z115.number().int().min(0).optional(),
27693
- videoVariant: z115.enum([
27730
+ var GroupedTaskSource = z116.object({
27731
+ type: z116.literal("task"),
27732
+ taskId: z116.string().min(1),
27733
+ angleIndex: z116.number().int().min(0).optional(),
27734
+ videoVariant: z116.enum([
27694
27735
  "with_subtitles",
27695
27736
  "without_subtitles"
27696
27737
  ]).optional(),
27697
- imageVariantIndex: z115.number().int().min(0).optional()
27698
- });
27699
- var GroupedMediaSource = z115.object({
27700
- type: z115.literal("media"),
27701
- url: z115.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
27702
- path: z115.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".'),
27703
- thumbnailUrl: z115.string().url().optional(),
27704
- thumbnailPath: z115.string().min(1).optional()
27738
+ imageVariantIndex: z116.number().int().min(0).optional()
27739
+ });
27740
+ var GroupedMediaSource = z116.object({
27741
+ type: z116.literal("media"),
27742
+ url: z116.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
27743
+ path: z116.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".'),
27744
+ thumbnailUrl: z116.string().url().optional(),
27745
+ thumbnailPath: z116.string().min(1).optional()
27705
27746
  }).refine((value) => Boolean(value.url) !== Boolean(value.path), {
27706
27747
  message: "media source needs exactly one of `url` or `path`"
27707
27748
  }).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
27708
27749
  message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
27709
27750
  });
27710
- var GroupedUploadedAssetSource = z115.object({
27711
- type: z115.literal("asset"),
27751
+ var GroupedUploadedAssetSource = z116.object({
27752
+ type: z116.literal("asset"),
27712
27753
  /** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
27713
- assetId: z115.string().uuid(),
27714
- thumbnailAssetId: z115.string().uuid().optional()
27754
+ assetId: z116.string().uuid(),
27755
+ thumbnailAssetId: z116.string().uuid().optional()
27715
27756
  });
27716
- var GroupedCreative = z115.object({
27717
- type: z115.enum([
27757
+ var GroupedCreative = z116.object({
27758
+ type: z116.enum([
27718
27759
  "image",
27719
27760
  "video"
27720
27761
  ]),
27721
- source: z115.union([
27762
+ source: z116.union([
27722
27763
  GroupedTaskSource,
27723
27764
  GroupedMediaSource,
27724
27765
  GroupedUploadedAssetSource
27725
27766
  ]),
27726
- title: z115.string().max(120).optional(),
27727
- description: z115.string().max(500).optional(),
27767
+ title: z116.string().max(120).optional(),
27768
+ description: z116.string().max(500).optional(),
27728
27769
  cta: MetaCtaType.optional(),
27729
- creativeId: z115.string().min(1).optional()
27770
+ creativeId: z116.string().min(1).optional()
27730
27771
  });
27731
- var GroupedCampaignConfigBase = z115.object({
27772
+ var GroupedCampaignConfigBase = z116.object({
27732
27773
  campaignType: MetaCampaignType.default("sales"),
27733
27774
  optimizationMode: MetaOptimizationMode.default("advantage_plus"),
27734
27775
  budgetMode: MetaBudgetMode.optional(),
27735
- campaignDailyBudget: z115.number().int().positive().optional(),
27736
- adSets: z115.array(z115.object({
27737
- tempId: z115.string().min(1).max(80),
27738
- name: z115.string().min(1).max(100),
27739
- dailyBudget: z115.number().int().positive().optional(),
27740
- creativeIds: z115.array(z115.string().min(1)).min(1)
27776
+ campaignDailyBudget: z116.number().int().positive().optional(),
27777
+ adSets: z116.array(z116.object({
27778
+ tempId: z116.string().min(1).max(80),
27779
+ name: z116.string().min(1).max(100),
27780
+ dailyBudget: z116.number().int().positive().optional(),
27781
+ creativeIds: z116.array(z116.string().min(1)).min(1)
27741
27782
  })).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
27742
27783
  /**
27743
27784
  * Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
@@ -27745,17 +27786,17 @@ var GroupedCampaignConfigBase = z115.object({
27745
27786
  * opaque `invalid_literal` and made the WhatsApp destination — supported by
27746
27787
  * the API since #849 — unreachable from this tool.
27747
27788
  */
27748
- destination: z115.discriminatedUnion("type", [
27749
- z115.object({
27750
- type: z115.literal("landing"),
27751
- landingUrl: z115.string().url()
27789
+ destination: z116.discriminatedUnion("type", [
27790
+ z116.object({
27791
+ type: z116.literal("landing"),
27792
+ landingUrl: z116.string().url()
27752
27793
  }),
27753
- z115.object({
27754
- type: z115.literal("whatsapp"),
27755
- phoneNumber: z115.string().min(8).max(32)
27794
+ z116.object({
27795
+ type: z116.literal("whatsapp"),
27796
+ phoneNumber: z116.string().min(8).max(32)
27756
27797
  })
27757
27798
  ]),
27758
- saveAsDefault: z115.boolean().default(false),
27799
+ saveAsDefault: z116.boolean().default(false),
27759
27800
  budgetPolicy: MetaBudgetPolicy.optional()
27760
27801
  });
27761
27802
  function resolveBudgetMode(value) {
@@ -27769,7 +27810,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
27769
27810
  const budgetMode = resolveBudgetMode(value);
27770
27811
  if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
27771
27812
  ctx.addIssue({
27772
- code: z115.ZodIssueCode.custom,
27813
+ code: z116.ZodIssueCode.custom,
27773
27814
  path: [
27774
27815
  "campaignDailyBudget"
27775
27816
  ],
@@ -27780,7 +27821,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
27780
27821
  value.adSets.forEach((adSet, index) => {
27781
27822
  if (adSet.dailyBudget === void 0) {
27782
27823
  ctx.addIssue({
27783
- code: z115.ZodIssueCode.custom,
27824
+ code: z116.ZodIssueCode.custom,
27784
27825
  path: [
27785
27826
  "adSets",
27786
27827
  index,
@@ -27795,28 +27836,28 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
27795
27836
  ...value,
27796
27837
  budgetMode: resolveBudgetMode(value)
27797
27838
  }));
27798
- var PublishCreativesToMetaInputBase = z115.object({
27799
- creatives: z115.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
27839
+ var PublishCreativesToMetaInputBase = z116.object({
27840
+ creatives: z116.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
27800
27841
  /** Exact Meta Business portfolio selected from `list_meta_destinations`. */
27801
- portfolioId: z115.string().trim().min(1),
27842
+ portfolioId: z116.string().trim().min(1),
27802
27843
  /** Exact Facebook Page selected from `list_meta_destinations`. */
27803
- pageId: z115.string().trim().min(1),
27844
+ pageId: z116.string().trim().min(1),
27804
27845
  adAccountId: McpAdAccountId,
27805
- pixelId: z115.string().min(1).optional(),
27846
+ pixelId: z116.string().min(1).optional(),
27806
27847
  /** Required unless `campaignConfig.destination` is whatsapp — see the
27807
27848
  * superRefine below. Mirrors the API's `FacebookCreateCampaignFromTasksBodySchema`. */
27808
- landingUrl: z115.string().url().optional(),
27849
+ landingUrl: z116.string().url().optional(),
27809
27850
  /** ISO-2 code or resolvable country name — mirrors the API contract
27810
27851
  * (CountryIso2Schema), which normalizes names to alpha-2 at validation. */
27811
27852
  targetCountry: CountryIso2Schema,
27812
- campaignName: z115.string().trim().min(1).max(100),
27853
+ campaignName: z116.string().trim().min(1).max(100),
27813
27854
  campaignConfig: GroupedCampaignConfig.optional()
27814
27855
  });
27815
27856
  var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
27816
27857
  const destination = value.campaignConfig?.destination;
27817
27858
  if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl) {
27818
27859
  ctx.addIssue({
27819
- code: z115.ZodIssueCode.custom,
27860
+ code: z116.ZodIssueCode.custom,
27820
27861
  path: [
27821
27862
  "landingUrl"
27822
27863
  ],
@@ -27825,7 +27866,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
27825
27866
  }
27826
27867
  if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
27827
27868
  ctx.addIssue({
27828
- code: z115.ZodIssueCode.custom,
27869
+ code: z116.ZodIssueCode.custom,
27829
27870
  path: [
27830
27871
  "campaignConfig",
27831
27872
  "destination",
@@ -27844,16 +27885,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
27844
27885
  }
27845
27886
  return value;
27846
27887
  });
27847
- var PresignUploadResponseSchema = z115.object({
27848
- uploadUrl: z115.string().url().refine((value) => {
27888
+ var PresignUploadResponseSchema = z116.object({
27889
+ uploadUrl: z116.string().url().refine((value) => {
27849
27890
  const url = new URL(value);
27850
27891
  return !url.username && !url.password && url.protocol === "https:";
27851
27892
  }, "presigned upload URL must be HTTPS without embedded credentials"),
27852
- publicUrl: z115.string().url().refine((value) => {
27893
+ publicUrl: z116.string().url().refine((value) => {
27853
27894
  const url = new URL(value);
27854
27895
  return !url.username && !url.password;
27855
27896
  }, "public media URL must not contain embedded credentials"),
27856
- stagingAssetId: z115.string().uuid()
27897
+ stagingAssetId: z116.string().uuid()
27857
27898
  });
27858
27899
  async function uploadResolvedMedia(api, media, assetRole) {
27859
27900
  if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
@@ -27878,16 +27919,16 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
27878
27919
  return uploadResolvedMedia(api, media, assetRole);
27879
27920
  }
27880
27921
  __name(resolveAndUploadMedia, "resolveAndUploadMedia");
27881
- var TikTokInput = z115.object({
27882
- taskId: z115.string().min(1),
27883
- advertiserId: z115.string().min(1),
27884
- pixelId: z115.string().min(1).optional(),
27885
- landingUrl: z115.string().url().optional(),
27886
- angleIndexes: z115.array(z115.number().int().nonnegative()).optional(),
27922
+ var TikTokInput = z116.object({
27923
+ taskId: z116.string().min(1),
27924
+ advertiserId: z116.string().min(1),
27925
+ pixelId: z116.string().min(1).optional(),
27926
+ landingUrl: z116.string().url().optional(),
27927
+ angleIndexes: z116.array(z116.number().int().nonnegative()).optional(),
27887
27928
  campaignConfig: McpCampaignConfig.optional(),
27888
27929
  /** Override the ad's description (TikTok's body copy). If omitted,
27889
27930
  * ProductMaker uses the auto-generated copy attached to the task. */
27890
- primaryText: z115.string().trim().min(1).max(500).optional()
27931
+ primaryText: z116.string().trim().min(1).max(500).optional()
27891
27932
  });
27892
27933
  function registerPublishTools(server, api, opts = {}) {
27893
27934
  const transport = opts.transport ?? "http";
@@ -28239,39 +28280,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
28239
28280
 
28240
28281
  // src/tools/meta-upload.ts
28241
28282
  import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
28242
- import { z as z116 } from "zod";
28283
+ import { z as z117 } from "zod";
28243
28284
  var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
28244
- var UploadSessionInputBase = z116.object({
28245
- mediaKind: z116.enum([
28285
+ var UploadSessionInputBase = z117.object({
28286
+ mediaKind: z117.enum([
28246
28287
  "image",
28247
28288
  "video",
28248
28289
  "mixed"
28249
28290
  ]).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."),
28250
- assetRole: z116.enum([
28291
+ assetRole: z117.enum([
28251
28292
  "media",
28252
28293
  "thumbnail"
28253
28294
  ]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
28254
- uploadPurpose: z116.enum([
28295
+ uploadPurpose: z117.enum([
28255
28296
  "product_reference",
28256
28297
  "creative",
28257
28298
  "generic"
28258
28299
  ]).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."),
28259
- maxFiles: z116.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
28300
+ maxFiles: z117.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
28260
28301
  });
28261
- var OpenAiFileReference = z116.object({
28262
- download_url: z116.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."),
28263
- file_id: z116.string().min(1),
28264
- mime_type: z116.string().min(1).optional(),
28265
- file_name: z116.string().min(1).optional()
28302
+ var OpenAiFileReference = z117.object({
28303
+ download_url: z117.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."),
28304
+ file_id: z117.string().min(1),
28305
+ mime_type: z117.string().min(1).optional(),
28306
+ file_name: z117.string().min(1).optional()
28266
28307
  });
28267
28308
  var UploadSessionToolInputShape = {
28268
28309
  ...UploadSessionInputBase.shape,
28269
- files: z116.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.")
28310
+ files: z117.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.")
28270
28311
  };
28271
- var UploadSessionToolInput = z116.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
28312
+ var UploadSessionToolInput = z117.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
28272
28313
  if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
28273
28314
  ctx.addIssue({
28274
- code: z116.ZodIssueCode.custom,
28315
+ code: z117.ZodIssueCode.custom,
28275
28316
  path: [
28276
28317
  "mediaKind"
28277
28318
  ],
@@ -28280,7 +28321,7 @@ var UploadSessionToolInput = z116.object(UploadSessionToolInputShape).superRefin
28280
28321
  }
28281
28322
  if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
28282
28323
  ctx.addIssue({
28283
- code: z116.ZodIssueCode.custom,
28324
+ code: z117.ZodIssueCode.custom,
28284
28325
  path: [
28285
28326
  "maxFiles"
28286
28327
  ],
@@ -28289,7 +28330,7 @@ var UploadSessionToolInput = z116.object(UploadSessionToolInputShape).superRefin
28289
28330
  }
28290
28331
  if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
28291
28332
  ctx.addIssue({
28292
- code: z116.ZodIssueCode.custom,
28333
+ code: z117.ZodIssueCode.custom,
28293
28334
  path: [
28294
28335
  "maxFiles"
28295
28336
  ],
@@ -28297,38 +28338,38 @@ var UploadSessionToolInput = z116.object(UploadSessionToolInputShape).superRefin
28297
28338
  });
28298
28339
  }
28299
28340
  });
28300
- var UploadSessionResponse = z116.object({
28301
- sessionId: z116.string().uuid(),
28302
- uploadPageUrl: z116.string().url(),
28303
- mediaKind: z116.enum([
28341
+ var UploadSessionResponse = z117.object({
28342
+ sessionId: z117.string().uuid(),
28343
+ uploadPageUrl: z117.string().url(),
28344
+ mediaKind: z117.enum([
28304
28345
  "image",
28305
28346
  "video",
28306
28347
  "mixed"
28307
28348
  ]),
28308
- assetRole: z116.enum([
28349
+ assetRole: z117.enum([
28309
28350
  "media",
28310
28351
  "thumbnail"
28311
28352
  ]),
28312
- maxFiles: z116.number().int().positive(),
28313
- expiresAt: z116.string().datetime()
28353
+ maxFiles: z117.number().int().positive(),
28354
+ expiresAt: z117.string().datetime()
28314
28355
  });
28315
- var UploadStatusInput = z116.object({
28316
- sessionId: z116.string().uuid().describe("The sessionId returned by request_media_upload.")
28356
+ var UploadStatusInput = z117.object({
28357
+ sessionId: z117.string().uuid().describe("The sessionId returned by request_media_upload.")
28317
28358
  });
28318
- var UniversalUploadStatusResponse = z116.discriminatedUnion("status", [
28319
- z116.object({
28320
- status: z116.literal("pending"),
28321
- assets: z116.array(z116.never()).length(0)
28359
+ var UniversalUploadStatusResponse = z117.discriminatedUnion("status", [
28360
+ z117.object({
28361
+ status: z117.literal("pending"),
28362
+ assets: z117.array(z117.never()).length(0)
28322
28363
  }),
28323
- z116.object({
28324
- status: z116.literal("uploaded"),
28325
- assets: z116.array(z116.object({
28326
- assetId: z116.string().uuid(),
28327
- mediaKind: z116.enum([
28364
+ z117.object({
28365
+ status: z117.literal("uploaded"),
28366
+ assets: z117.array(z117.object({
28367
+ assetId: z117.string().uuid(),
28368
+ mediaKind: z117.enum([
28328
28369
  "image",
28329
28370
  "video"
28330
28371
  ]),
28331
- assetRole: z116.enum([
28372
+ assetRole: z117.enum([
28332
28373
  "media",
28333
28374
  "thumbnail"
28334
28375
  ])
@@ -28336,13 +28377,13 @@ var UniversalUploadStatusResponse = z116.discriminatedUnion("status", [
28336
28377
  })
28337
28378
  ]);
28338
28379
  var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
28339
- uploadPurpose: z116.enum([
28380
+ uploadPurpose: z117.enum([
28340
28381
  "product_reference",
28341
28382
  "creative",
28342
28383
  "generic"
28343
28384
  ]),
28344
- checkToolName: z116.literal("check_media_upload"),
28345
- resolveEndpoint: z116.string().url()
28385
+ checkToolName: z117.literal("check_media_upload"),
28386
+ resolveEndpoint: z117.string().url()
28346
28387
  });
28347
28388
  function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
28348
28389
  const url = new URL(uploadPageUrl);
@@ -28433,15 +28474,15 @@ function registerMediaUploadTools(server, api) {
28433
28474
  __name(registerMediaUploadTools, "registerMediaUploadTools");
28434
28475
 
28435
28476
  // src/tools/campaigns.ts
28436
- import { z as z117 } from "zod";
28477
+ import { z as z118 } from "zod";
28437
28478
  var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
28438
28479
  var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
28439
- var MetaStatusInput = z117.object({
28440
- campaignId: z117.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
28480
+ var MetaStatusInput = z118.object({
28481
+ campaignId: z118.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
28441
28482
  });
28442
- var TikTokStatusInput = z117.object({
28443
- campaignId: z117.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
28444
- advertiserId: z117.string().min(1).describe("The same advertiserId used to publish the campaign.")
28483
+ var TikTokStatusInput = z118.object({
28484
+ campaignId: z118.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
28485
+ advertiserId: z118.string().min(1).describe("The same advertiserId used to publish the campaign.")
28445
28486
  });
28446
28487
  function registerCampaignTools(server, api) {
28447
28488
  server.registerTool("get_meta_campaign_status", {
@@ -28546,10 +28587,10 @@ function renderTikTokStatusMarkdown(r) {
28546
28587
  __name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
28547
28588
 
28548
28589
  // ../../packages/product-economics/src/product-costing.ts
28549
- import { z as z119 } from "zod";
28590
+ import { z as z120 } from "zod";
28550
28591
 
28551
28592
  // ../../packages/product-economics/src/product-costing-countries.ts
28552
- import { z as z118 } from "zod";
28593
+ import { z as z119 } from "zod";
28553
28594
 
28554
28595
  // ../../packages/product-economics/src/product-costing-shipping-references.json
28555
28596
  var product_costing_shipping_references_default = {
@@ -28613,21 +28654,21 @@ var product_costing_shipping_references_default = {
28613
28654
  };
28614
28655
 
28615
28656
  // ../../packages/product-economics/src/product-costing-countries.ts
28616
- var ShippingReferenceSchema = z118.object({
28617
- reference: z118.number().positive(),
28618
- min: z118.number().nonnegative(),
28619
- max: z118.number().positive(),
28620
- updatedAt: z118.string().date(),
28621
- confidence: z118.enum([
28657
+ var ShippingReferenceSchema = z119.object({
28658
+ reference: z119.number().positive(),
28659
+ min: z119.number().nonnegative(),
28660
+ max: z119.number().positive(),
28661
+ updatedAt: z119.string().date(),
28662
+ confidence: z119.enum([
28622
28663
  "high",
28623
28664
  "medium",
28624
28665
  "medium-low"
28625
28666
  ]),
28626
- sources: z118.array(z118.string().url().startsWith("https://")).min(1).max(3)
28667
+ sources: z119.array(z119.string().url().startsWith("https://")).min(1).max(3)
28627
28668
  }).superRefine(({ reference, min, max }, context) => {
28628
28669
  if (min > reference || reference > max) {
28629
28670
  context.addIssue({
28630
- code: z118.ZodIssueCode.custom,
28671
+ code: z119.ZodIssueCode.custom,
28631
28672
  message: "shipping_reference_outside_range",
28632
28673
  path: [
28633
28674
  "reference"
@@ -28635,7 +28676,7 @@ var ShippingReferenceSchema = z118.object({
28635
28676
  });
28636
28677
  }
28637
28678
  });
28638
- var SHIPPING_REFERENCES = z118.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
28679
+ var SHIPPING_REFERENCES = z119.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
28639
28680
  var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
28640
28681
  var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
28641
28682
  "MX",
@@ -28817,18 +28858,18 @@ function getProductCostingCountryName(country) {
28817
28858
  __name(getProductCostingCountryName, "getProductCostingCountryName");
28818
28859
 
28819
28860
  // ../../packages/product-economics/src/product-costing.ts
28820
- var ProductCostingInputSchema = z119.object({
28821
- country: z119.string().refine(isProductCostingCountryCode, "unsupported_country"),
28822
- supplierCost: z119.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
28823
- shippingCost: z119.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
28824
- returnRate: z119.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
28825
- cancellationRate: z119.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
28826
- adsManagerCpa: z119.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
28827
- desiredMargin: z119.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
28861
+ var ProductCostingInputSchema = z120.object({
28862
+ country: z120.string().refine(isProductCostingCountryCode, "unsupported_country"),
28863
+ supplierCost: z120.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
28864
+ shippingCost: z120.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
28865
+ returnRate: z120.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
28866
+ cancellationRate: z120.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
28867
+ adsManagerCpa: z120.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
28868
+ desiredMargin: z120.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
28828
28869
  }).superRefine(({ returnRate, cancellationRate }, context) => {
28829
28870
  if (returnRate + cancellationRate >= 1) {
28830
28871
  context.addIssue({
28831
- code: z119.ZodIssueCode.custom,
28872
+ code: z120.ZodIssueCode.custom,
28832
28873
  message: "delivery_rate_positive",
28833
28874
  path: [
28834
28875
  "cancellationRate"
@@ -28925,15 +28966,15 @@ function calculateProductCosting(rawInput) {
28925
28966
  __name(calculateProductCosting, "calculateProductCosting");
28926
28967
 
28927
28968
  // src/tools/product-costing.ts
28928
- import { z as z120 } from "zod";
28969
+ import { z as z121 } from "zod";
28929
28970
  var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
28930
- var optionalAmount = /* @__PURE__ */ __name((description) => z120.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
28931
- var optionalPercent = /* @__PURE__ */ __name((description) => z120.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
28932
- var ProductCostingToolInput = z120.object({
28933
- country: z120.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
28971
+ var optionalAmount = /* @__PURE__ */ __name((description) => z121.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
28972
+ var optionalPercent = /* @__PURE__ */ __name((description) => z121.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
28973
+ var ProductCostingToolInput = z121.object({
28974
+ country: z121.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
28934
28975
  message: "Pa\xEDs no soportado por ProductMaker."
28935
28976
  }).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
28936
- supplierCost: z120.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."),
28977
+ supplierCost: z121.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."),
28937
28978
  supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
28938
28979
  shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
28939
28980
  shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
@@ -29096,7 +29137,7 @@ function formatPercent(value) {
29096
29137
  __name(formatPercent, "formatPercent");
29097
29138
 
29098
29139
  // src/tools/product-research.ts
29099
- import { z as z121 } from "zod";
29140
+ import { z as z122 } from "zod";
29100
29141
 
29101
29142
  // src/tools/product-research-idempotency.ts
29102
29143
  var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
@@ -29467,17 +29508,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
29467
29508
  ]);
29468
29509
  var POLL_INTERVAL_MS = 5e3;
29469
29510
  var MAX_WAIT_SECONDS = 120;
29470
- var FindInput = z121.object({
29511
+ var FindInput = z122.object({
29471
29512
  targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
29472
29513
  categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
29473
- confirmed: z121.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
29474
- waitSeconds: z121.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
29514
+ confirmed: z122.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
29515
+ waitSeconds: z122.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
29475
29516
  });
29476
- var GetInput = z121.object({
29477
- runId: z121.string().uuid().describe("ID del run devuelto por find_winning_products.")
29517
+ var GetInput = z122.object({
29518
+ runId: z122.string().uuid().describe("ID del run devuelto por find_winning_products.")
29478
29519
  });
29479
- var ListInput = z121.object({
29480
- limit: z121.number().int().min(1).max(20).default(10)
29520
+ var ListInput = z122.object({
29521
+ limit: z122.number().int().min(1).max(20).default(10)
29481
29522
  });
29482
29523
  function textResult(text2) {
29483
29524
  return {
@@ -29616,17 +29657,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
29616
29657
  __name(registerProductResearchTools, "registerProductResearchTools");
29617
29658
 
29618
29659
  // src/tools/dropshipping-projects.ts
29619
- import { z as z122 } from "zod";
29660
+ import { z as z123 } from "zod";
29620
29661
  var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
29621
29662
  var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
29622
29663
  var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
29623
- var ProjectId = z122.string().uuid();
29624
- var DropshippingProjectStatus = z122.enum([
29664
+ var ProjectId = z123.string().uuid();
29665
+ var DropshippingProjectStatus = z123.enum([
29625
29666
  "active",
29626
29667
  "completed",
29627
29668
  "archived"
29628
29669
  ]);
29629
- var DropshippingProjectPhase = z122.enum([
29670
+ var DropshippingProjectPhase = z123.enum([
29630
29671
  "research",
29631
29672
  "costing",
29632
29673
  "media",
@@ -29635,21 +29676,21 @@ var DropshippingProjectPhase = z122.enum([
29635
29676
  "advertising",
29636
29677
  "complete"
29637
29678
  ]);
29638
- var DropshippingRewardMilestone = z122.enum([
29679
+ var DropshippingRewardMilestone = z123.enum([
29639
29680
  "product_selected",
29640
29681
  "costing_saved",
29641
29682
  "product_media_ready",
29642
29683
  "creatives_completed",
29643
29684
  "campaign_created"
29644
29685
  ]);
29645
- var TargetCountry = z122.enum([
29686
+ var TargetCountry = z123.enum([
29646
29687
  "CO",
29647
29688
  "MX",
29648
29689
  "PE",
29649
29690
  "EC",
29650
29691
  "CL"
29651
29692
  ]);
29652
- var ResearchCategory = z122.enum([
29693
+ var ResearchCategory = z123.enum([
29653
29694
  "auto",
29654
29695
  "automotive",
29655
29696
  "kitchen",
@@ -29664,7 +29705,7 @@ var ResearchCategory = z122.enum([
29664
29705
  "garden",
29665
29706
  "cleaning"
29666
29707
  ]);
29667
- var HttpUrl3 = z122.string().url().max(2e3).refine((value) => {
29708
+ var HttpUrl3 = z123.string().url().max(2e3).refine((value) => {
29668
29709
  try {
29669
29710
  return [
29670
29711
  "http:",
@@ -29674,45 +29715,45 @@ var HttpUrl3 = z122.string().url().max(2e3).refine((value) => {
29674
29715
  return false;
29675
29716
  }
29676
29717
  }, "URL must use HTTP(S)");
29677
- var ResearchCandidateOrigin = z122.object({
29678
- type: z122.literal("research_candidate"),
29718
+ var ResearchCandidateOrigin = z123.object({
29719
+ type: z123.literal("research_candidate"),
29679
29720
  runId: ProjectId,
29680
- candidateSourceId: z122.string().min(1).max(160)
29721
+ candidateSourceId: z123.string().min(1).max(160)
29681
29722
  });
29682
- var TaskOrigin = z122.object({
29683
- type: z122.literal("task"),
29723
+ var TaskOrigin = z123.object({
29724
+ type: z123.literal("task"),
29684
29725
  taskId: ProjectId
29685
29726
  });
29686
- var ManualOrigin = z122.object({
29687
- type: z122.literal("manual"),
29727
+ var ManualOrigin = z123.object({
29728
+ type: z123.literal("manual"),
29688
29729
  clientRequestId: ProjectId,
29689
- country: z122.string().min(2).max(3).optional()
29730
+ country: z123.string().min(2).max(3).optional()
29690
29731
  });
29691
- var StartProjectInput = z122.object({
29692
- origin: z122.discriminatedUnion("type", [
29732
+ var StartProjectInput = z123.object({
29733
+ origin: z123.discriminatedUnion("type", [
29693
29734
  ResearchCandidateOrigin,
29694
29735
  TaskOrigin,
29695
29736
  ManualOrigin
29696
29737
  ]),
29697
- productName: z122.string().trim().min(1).max(240).optional(),
29738
+ productName: z123.string().trim().min(1).max(240).optional(),
29698
29739
  productUrl: HttpUrl3.optional(),
29699
- country: z122.string().min(2).max(3).optional(),
29700
- languageCode: z122.string().min(2).max(16).optional()
29740
+ country: z123.string().min(2).max(3).optional(),
29741
+ languageCode: z123.string().min(2).max(16).optional()
29701
29742
  }).strict();
29702
- var CostProjectInput = z122.object({
29743
+ var CostProjectInput = z123.object({
29703
29744
  projectId: ProjectId,
29704
- version: z122.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
29705
- country: z122.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
29745
+ version: z123.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
29746
+ country: z123.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
29706
29747
  message: "Pa\xEDs no soportado por ProductMaker."
29707
29748
  }).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
29708
- supplierCost: z122.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."),
29709
- shippingCost: z122.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
29710
- returnRate: z122.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."),
29711
- cancellationRate: z122.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."),
29712
- adsManagerCpa: z122.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
29713
- desiredMargin: z122.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
29714
- });
29715
- var GuideInput = z122.object({
29749
+ supplierCost: z123.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."),
29750
+ shippingCost: z123.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
29751
+ returnRate: z123.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."),
29752
+ cancellationRate: z123.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."),
29753
+ adsManagerCpa: z123.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
29754
+ desiredMargin: z123.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
29755
+ });
29756
+ var GuideInput = z123.object({
29716
29757
  projectId: ProjectId.optional()
29717
29758
  }).strict();
29718
29759
  var NEXT_ACTION_KINDS = [
@@ -29730,29 +29771,29 @@ var NEXT_ACTION_KINDS = [
29730
29771
  "repair_meta_campaign",
29731
29772
  "review_paused_campaign"
29732
29773
  ];
29733
- var DropshippingProjectNextAction = z122.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z122.object({
29734
- kind: z122.literal(kind),
29735
- href: z122.string().min(1)
29774
+ var DropshippingProjectNextAction = z123.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z123.object({
29775
+ kind: z123.literal(kind),
29776
+ href: z123.string().min(1)
29736
29777
  })));
29737
- var CostingInputSchema = z122.object({
29738
- country: z122.string().min(2).max(3),
29739
- supplierCost: z122.number().finite().positive(),
29740
- shippingCost: z122.number().finite().nonnegative(),
29741
- returnRate: z122.number().finite().min(0).lt(1),
29742
- cancellationRate: z122.number().finite().min(0).lt(1),
29743
- adsManagerCpa: z122.number().finite().nonnegative(),
29744
- desiredMargin: z122.number().finite().min(0).lt(1)
29778
+ var CostingInputSchema = z123.object({
29779
+ country: z123.string().min(2).max(3),
29780
+ supplierCost: z123.number().finite().positive(),
29781
+ shippingCost: z123.number().finite().nonnegative(),
29782
+ returnRate: z123.number().finite().min(0).lt(1),
29783
+ cancellationRate: z123.number().finite().min(0).lt(1),
29784
+ adsManagerCpa: z123.number().finite().nonnegative(),
29785
+ desiredMargin: z123.number().finite().min(0).lt(1)
29745
29786
  }).superRefine(({ returnRate, cancellationRate }, context) => {
29746
29787
  if (returnRate + cancellationRate >= 1) context.addIssue({
29747
- code: z122.ZodIssueCode.custom,
29788
+ code: z123.ZodIssueCode.custom,
29748
29789
  path: [
29749
29790
  "cancellationRate"
29750
29791
  ]
29751
29792
  });
29752
29793
  });
29753
- var FiniteCostingNumber = z122.number().finite();
29754
- var CostingResultSchema = z122.object({
29755
- country: z122.string().min(2).max(3),
29794
+ var FiniteCostingNumber = z123.number().finite();
29795
+ var CostingResultSchema = z123.object({
29796
+ country: z123.string().min(2).max(3),
29756
29797
  deliveryRate: FiniteCostingNumber,
29757
29798
  adjustedShippingCost: FiniteCostingNumber,
29758
29799
  adjustedCpa: FiniteCostingNumber,
@@ -29765,45 +29806,45 @@ var CostingResultSchema = z122.object({
29765
29806
  estimatedProfit: FiniteCostingNumber,
29766
29807
  actualMargin: FiniteCostingNumber,
29767
29808
  breakEvenAdsManagerCpa: FiniteCostingNumber,
29768
- wasPriceAutoAdjusted: z122.boolean(),
29769
- profitabilityStatus: z122.literal("healthy")
29770
- });
29771
- var RewardProgressSchema = z122.object({
29772
- campaignKey: z122.literal("dropshipping-launch-v1"),
29773
- totalCredits: z122.number().int().positive(),
29774
- earnedCredits: z122.number().int().nonnegative(),
29775
- milestones: z122.array(z122.object({
29809
+ wasPriceAutoAdjusted: z123.boolean(),
29810
+ profitabilityStatus: z123.literal("healthy")
29811
+ });
29812
+ var RewardProgressSchema = z123.object({
29813
+ campaignKey: z123.literal("dropshipping-launch-v1"),
29814
+ totalCredits: z123.number().int().positive(),
29815
+ earnedCredits: z123.number().int().nonnegative(),
29816
+ milestones: z123.array(z123.object({
29776
29817
  milestone: DropshippingRewardMilestone,
29777
- credits: z122.number().int().positive(),
29778
- available: z122.boolean().optional(),
29779
- earned: z122.boolean(),
29818
+ credits: z123.number().int().positive(),
29819
+ available: z123.boolean().optional(),
29820
+ earned: z123.boolean(),
29780
29821
  grantId: ProjectId.nullable(),
29781
- grantedAt: z122.string().datetime().nullable()
29822
+ grantedAt: z123.string().datetime().nullable()
29782
29823
  })).length(DropshippingRewardMilestone.options.length)
29783
29824
  });
29784
- var ProjectResponseSchema = z122.object({
29825
+ var ProjectResponseSchema = z123.object({
29785
29826
  id: ProjectId,
29786
29827
  taskId: ProjectId.nullable(),
29787
29828
  status: DropshippingProjectStatus,
29788
- originKey: z122.string().min(1),
29829
+ originKey: z123.string().min(1),
29789
29830
  researchRunId: ProjectId.nullable(),
29790
- candidateSourceId: z122.string().nullable(),
29791
- productName: z122.string().nullable(),
29831
+ candidateSourceId: z123.string().nullable(),
29832
+ productName: z123.string().nullable(),
29792
29833
  productUrl: HttpUrl3.nullable(),
29793
29834
  referenceImageUrl: HttpUrl3.nullable(),
29794
- targetCountry: z122.string().nullable(),
29795
- languageCode: z122.string().nullable(),
29796
- hasReferenceImage: z122.boolean(),
29797
- hasWinnerReferenceImage: z122.boolean(),
29835
+ targetCountry: z123.string().nullable(),
29836
+ languageCode: z123.string().nullable(),
29837
+ hasReferenceImage: z123.boolean(),
29838
+ hasWinnerReferenceImage: z123.boolean(),
29798
29839
  costingInput: CostingInputSchema.nullable(),
29799
29840
  costingResult: CostingResultSchema.nullable(),
29800
- costingVersion: z122.number().int().positive().nullable(),
29801
- version: z122.number().int().positive(),
29841
+ costingVersion: z123.number().int().positive().nullable(),
29842
+ version: z123.number().int().positive(),
29802
29843
  phase: DropshippingProjectPhase,
29803
29844
  nextAction: DropshippingProjectNextAction.nullable(),
29804
29845
  rewards: RewardProgressSchema,
29805
- createdAt: z122.string().datetime(),
29806
- updatedAt: z122.string().datetime()
29846
+ createdAt: z123.string().datetime(),
29847
+ updatedAt: z123.string().datetime()
29807
29848
  }).passthrough();
29808
29849
  var NEXT_ACTION_GUIDANCE = {
29809
29850
  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.",
@@ -29923,58 +29964,58 @@ function registerDropshippingProjectTools(server, api) {
29923
29964
  __name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
29924
29965
 
29925
29966
  // src/tools/daily-control.ts
29926
- import { z as z123 } from "zod";
29967
+ import { z as z124 } from "zod";
29927
29968
  var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
29928
29969
  var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
29929
29970
  var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
29930
- var ProviderCampaignIdentifier = z123.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
29931
- var DateOnly = z123.string().regex(/^\d{4}-\d{2}-\d{2}$/);
29932
- var DailyControlInput = z123.object({
29971
+ var ProviderCampaignIdentifier = z124.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
29972
+ var DateOnly = z124.string().regex(/^\d{4}-\d{2}-\d{2}$/);
29973
+ var DailyControlInput = z124.object({
29933
29974
  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."),
29934
- days: z123.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
29935
- projectId: z123.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
29975
+ days: z124.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
29976
+ projectId: z124.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
29936
29977
  }).strict();
29937
- var LinkCampaignInput = z123.object({
29938
- projectId: z123.string().uuid(),
29939
- provider: z123.enum([
29978
+ var LinkCampaignInput = z124.object({
29979
+ projectId: z124.string().uuid(),
29980
+ provider: z124.enum([
29940
29981
  "meta",
29941
29982
  "tiktok"
29942
29983
  ]),
29943
29984
  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."),
29944
29985
  campaignId: ProviderCampaignIdentifier
29945
29986
  }).strict();
29946
- var ReportReturnsInput = z123.object({
29947
- projectId: z123.string().uuid(),
29987
+ var ReportReturnsInput = z124.object({
29988
+ projectId: z124.string().uuid(),
29948
29989
  date: DateOnly,
29949
- returnedOrders: z123.number().int().min(0).max(1e5),
29950
- note: z123.string().trim().max(280).optional()
29990
+ returnedOrders: z124.number().int().min(0).max(1e5),
29991
+ note: z124.string().trim().max(280).optional()
29951
29992
  }).strict();
29952
- var DailyControlStatusMirror = DailyControlStatusEnum.or(z123.string());
29953
- var DailyControlLightMirror = DailyControlLightEnum.or(z123.string());
29954
- var DailyControlSourceMirror = DailyControlSourceEnum.or(z123.string());
29955
- var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z123.string());
29956
- var DailyControlDayMirror = z123.object({
29957
- date: z123.string(),
29958
- returnedOrders: z123.number(),
29993
+ var DailyControlStatusMirror = DailyControlStatusEnum.or(z124.string());
29994
+ var DailyControlLightMirror = DailyControlLightEnum.or(z124.string());
29995
+ var DailyControlSourceMirror = DailyControlSourceEnum.or(z124.string());
29996
+ var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z124.string());
29997
+ var DailyControlDayMirror = z124.object({
29998
+ date: z124.string(),
29999
+ returnedOrders: z124.number(),
29959
30000
  returnedSource: DailyControlSourceMirror,
29960
30001
  cancelledSource: DailyControlSourceMirror,
29961
- hasEstimates: z123.boolean(),
30002
+ hasEstimates: z124.boolean(),
29962
30003
  light: DailyControlLightMirror
29963
30004
  }).passthrough();
29964
- var DailyControlProductMirror = z123.object({
29965
- projectId: z123.string().uuid(),
29966
- productName: z123.string().nullable(),
30005
+ var DailyControlProductMirror = z124.object({
30006
+ projectId: z124.string().uuid(),
30007
+ productName: z124.string().nullable(),
29967
30008
  status: DailyControlStatusMirror,
29968
- statusMessage: z123.string().nullable(),
29969
- days: z123.array(DailyControlDayMirror),
30009
+ statusMessage: z124.string().nullable(),
30010
+ days: z124.array(DailyControlDayMirror),
29970
30011
  verdict: DailyControlVerdictMirror.nullable(),
29971
- rationale: z123.string().nullable()
30012
+ rationale: z124.string().nullable()
29972
30013
  }).passthrough();
29973
- var DailyControlResponseMirror = z123.object({
29974
- since: z123.string(),
29975
- until: z123.string(),
29976
- products: z123.array(DailyControlProductMirror),
29977
- archivedProjectSpend: z123.array(z123.unknown())
30014
+ var DailyControlResponseMirror = z124.object({
30015
+ since: z124.string(),
30016
+ until: z124.string(),
30017
+ products: z124.array(DailyControlProductMirror),
30018
+ archivedProjectSpend: z124.array(z124.unknown())
29978
30019
  }).passthrough();
29979
30020
  var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
29980
30021
  function withWarnings(response) {
@@ -30049,7 +30090,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
30049
30090
  // src/tools/product-control.ts
30050
30091
  import { readFile, stat } from "fs/promises";
30051
30092
  import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
30052
- import { z as z124 } from "zod";
30093
+ import { z as z125 } from "zod";
30053
30094
  var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
30054
30095
  var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
30055
30096
  var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
@@ -30062,36 +30103,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
30062
30103
  var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
30063
30104
  var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
30064
30105
  var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
30065
- var DateOnly2 = z124.string().regex(/^\d{4}-\d{2}-\d{2}$/);
30106
+ var DateOnly2 = z125.string().regex(/^\d{4}-\d{2}-\d{2}$/);
30066
30107
  var IMPORT_BATCH_MAX2 = 50;
30067
- var ProductControlListInput = z124.object({
30068
- days: z124.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
30108
+ var ProductControlListInput = z125.object({
30109
+ days: z125.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
30069
30110
  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."),
30070
- shopDomain: z124.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
30111
+ shopDomain: z125.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
30071
30112
  }).strict();
30072
- var ImportableProductsInput = z124.object({
30073
- q: z124.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
30074
- after: z124.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
30075
- shopDomain: z124.string().min(1).optional()
30113
+ var ImportableProductsInput = z125.object({
30114
+ q: z125.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
30115
+ after: z125.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
30116
+ shopDomain: z125.string().min(1).optional()
30076
30117
  }).strict();
30077
- var ImportProductControlsInput = z124.object({
30078
- shopifyProductIds: z124.array(z124.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."),
30118
+ var ImportProductControlsInput = z125.object({
30119
+ shopifyProductIds: z125.array(z125.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."),
30079
30120
  // Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
30080
30121
  // sin decir a cuál archivaría el producto bajo la tienda equivocada.
30081
- shopDomain: z124.string().min(1)
30122
+ shopDomain: z125.string().min(1)
30082
30123
  }).strict();
30083
- var SetProductCostingInput = z124.object({
30084
- shopDomain: z124.string().min(1),
30085
- shopifyProductId: z124.string().min(1).max(64),
30086
- targetCountry: z124.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
30087
- supplierCost: z124.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
30088
- shippingCost: z124.number().finite().nonnegative(),
30089
- returnRate: z124.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
30090
- cancellationRate: z124.number().finite().min(0).lt(1)
30124
+ var SetProductCostingInput = z125.object({
30125
+ shopDomain: z125.string().min(1),
30126
+ shopifyProductId: z125.string().min(1).max(64),
30127
+ targetCountry: z125.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
30128
+ supplierCost: z125.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
30129
+ shippingCost: z125.number().finite().nonnegative(),
30130
+ returnRate: z125.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
30131
+ cancellationRate: z125.number().finite().min(0).lt(1)
30091
30132
  }).strict();
30092
- var Count = z124.number().int().min(0).max(1e5).nullable().optional();
30093
- var ReportProductCountsInput = z124.object({
30094
- productControlId: z124.string().uuid().describe("El identificador que devuelve get_product_control."),
30133
+ var Count = z125.number().int().min(0).max(1e5).nullable().optional();
30134
+ var ReportProductCountsInput = z125.object({
30135
+ productControlId: z125.string().uuid().describe("El identificador que devuelve get_product_control."),
30095
30136
  date: DateOnly2,
30096
30137
  orders: Count.describe("Pedidos que entraron ese d\xEDa."),
30097
30138
  cancelledOrders: Count,
@@ -30101,36 +30142,36 @@ var ReportProductCountsInput = z124.object({
30101
30142
  }).strict();
30102
30143
  var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
30103
30144
  var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
30104
- var ImportOrdersFileInput = z124.object({
30145
+ var ImportOrdersFileInput = z125.object({
30105
30146
  /** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
30106
- path: z124.string().min(1),
30107
- operationId: z124.string().uuid().optional(),
30147
+ path: z125.string().min(1),
30148
+ operationId: z125.string().uuid().optional(),
30108
30149
  /** Solo mirar: devuelve el resumen y no escribe nada. */
30109
- dryRun: z124.boolean().optional()
30150
+ dryRun: z125.boolean().optional()
30110
30151
  }).strict();
30111
- var CreateOperationInput = z124.object({
30112
- countryCode: z124.string().length(2),
30113
- label: z124.string().trim().min(1).max(60).optional()
30152
+ var CreateOperationInput = z125.object({
30153
+ countryCode: z125.string().length(2),
30154
+ label: z125.string().trim().min(1).max(60).optional()
30114
30155
  }).strict();
30115
- var MergeProductsInput = z124.object({
30116
- sourceId: z124.string().uuid(),
30117
- targetId: z124.string().uuid()
30156
+ var MergeProductsInput = z125.object({
30157
+ sourceId: z125.string().uuid(),
30158
+ targetId: z125.string().uuid()
30118
30159
  }).strict();
30119
- var SetMonthlyExpenseInput = z124.object({
30120
- month: z124.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
30160
+ var SetMonthlyExpenseInput = z125.object({
30161
+ month: z125.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
30121
30162
  label: SaveMonthlyExpenseSchema.shape.label,
30122
- amount: z124.number().finite().min(0),
30123
- operationId: z124.string().uuid().optional()
30163
+ amount: z125.number().finite().min(0),
30164
+ operationId: z125.string().uuid().optional()
30124
30165
  }).strict();
30125
- var SetAdSpendInput = z124.object({
30126
- month: z124.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
30127
- operationId: z124.string().uuid().optional(),
30166
+ var SetAdSpendInput = z125.object({
30167
+ month: z125.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
30168
+ operationId: z125.string().uuid().optional(),
30128
30169
  /** null RETIRA la corrección; cero afirma que no pautó. */
30129
- amount: z124.number().finite().min(0).nullable()
30170
+ amount: z125.number().finite().min(0).nullable()
30130
30171
  }).strict();
30131
- var GetFinancesInput = z124.object({
30132
- month: z124.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."),
30133
- operationId: z124.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
30172
+ var GetFinancesInput = z125.object({
30173
+ month: z125.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."),
30174
+ operationId: z125.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
30134
30175
  }).strict();
30135
30176
  function registerProductControlTools(server, api, { transport = "http" } = {}) {
30136
30177
  server.registerTool("get_product_control", {
@@ -30320,28 +30361,28 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
30320
30361
  __name(registerProductControlTools, "registerProductControlTools");
30321
30362
 
30322
30363
  // src/tools/market-study-estimate.ts
30323
- import { z as z125 } from "zod";
30364
+ import { z as z126 } from "zod";
30324
30365
  var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
30325
- var ProductTaskOutputEnum = z125.enum([
30366
+ var ProductTaskOutputEnum = z126.enum([
30326
30367
  "landing",
30327
30368
  "video",
30328
30369
  "image"
30329
30370
  ]);
30330
- var EstimateMarketStudyInput = z125.object({
30331
- kind: z125.enum([
30371
+ var EstimateMarketStudyInput = z126.object({
30372
+ kind: z126.enum([
30332
30373
  "video",
30333
30374
  "product_task"
30334
30375
  ]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
30335
- videoAngleCount: z125.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
30336
- durationSeconds: z125.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
30376
+ videoAngleCount: z126.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
30377
+ durationSeconds: z126.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
30337
30378
  videoStructure: VideoStructureEnum.default("single_take"),
30338
30379
  videoQuality: VideoQualityEnum.default("economy"),
30339
30380
  videoResolution: VideoResolutionEnum.default("480p"),
30340
- productImageCount: z125.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
30381
+ productImageCount: z126.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
30341
30382
  outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
30342
- generateAiMusic: z125.boolean().optional(),
30383
+ generateAiMusic: z126.boolean().optional(),
30343
30384
  generateAiEdit: AiEditRequestSchema.optional(),
30344
- replicateWinnerWhenFound: z125.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.")
30385
+ replicateWinnerWhenFound: z126.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.")
30345
30386
  }).strict();
30346
30387
  function buildMarketStudyEstimateRequests(input) {
30347
30388
  const quotesVideo = input.kind === "video" || (input.outputs ?? [