@productmaker/mcp 11.2.0 → 11.2.2

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 +833 -789
  2. package/dist/stdio.js +822 -778
  3. package/package.json +1 -1
package/dist/http.js CHANGED
@@ -7514,6 +7514,12 @@ var ResultAngle = Angle.extend({
7514
7514
  });
7515
7515
  var MVPResult = z39.object({
7516
7516
  taskId: z39.string().uuid(),
7517
+ /** Read-only identity derived from validated persisted request context.
7518
+ * Optional for older APIs and content-only tasks; absence never implies a service. */
7519
+ subjectKind: z39.enum([
7520
+ "product",
7521
+ "service"
7522
+ ]).optional(),
7517
7523
  product: Product,
7518
7524
  // READ contract, NOT a generation cap. The generator writes exactly 3 angles
7519
7525
  // (`replaceAngles` renumbers positions 0..2), but a duplicated angles run
@@ -8314,6 +8320,10 @@ var VideoRegenerateEstimationOptions = z40.object({
8314
8320
  sceneCount: z40.number().int().positive().optional()
8315
8321
  });
8316
8322
  var ImageCreativeEstimationOptions = z40.object({
8323
+ subject: z40.enum([
8324
+ "product",
8325
+ "service"
8326
+ ]).optional(),
8317
8327
  nVariants: z40.number().int().positive().optional(),
8318
8328
  generateAdCopy: z40.boolean().optional(),
8319
8329
  /** Literal model name (e.g. 'gpt-image/1.5', 'nano-banana-2'). Defaults to the premium ad-creative model. */
@@ -9211,6 +9221,7 @@ var VideoMixQaJobSchema = z46.object({
9211
9221
  // jobId for retry uniqueness) but the worker only reads mixSceneTaskId.
9212
9222
  externalId: z46.string().min(1).optional()
9213
9223
  });
9224
+ var BrandExtractLocaleSchema = z46.string().regex(/^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8})?$/, "invalid locale");
9214
9225
  var BrandExtractJobSchema = z46.object({
9215
9226
  brandId: z46.string().uuid(),
9216
9227
  // Generation is part of the durable paid-spend identity. Default 1 keeps
@@ -9226,7 +9237,10 @@ var BrandExtractJobSchema = z46.object({
9226
9237
  "shopify_sync"
9227
9238
  ]).default("url_extract"),
9228
9239
  shopifyShopId: z46.string().optional(),
9229
- documents: z46.array(BrandExtractDocumentSchema).max(3).default([])
9240
+ documents: z46.array(BrandExtractDocumentSchema).max(3).default([]),
9241
+ // Requesting user's UI locale (BCP-47, e.g. "es", "en-US"). Fallback for the
9242
+ // brand kit's output language when the brand's own text is inconclusive.
9243
+ locale: BrandExtractLocaleSchema.optional()
9230
9244
  });
9231
9245
 
9232
9246
  // ../../packages/types/src/chat-parse.ts
@@ -21820,19 +21834,46 @@ var DropiFinancialSyncResultSchema = z103.object({
21820
21834
  }))
21821
21835
  });
21822
21836
 
21823
- // ../../packages/types/src/service-website-capture.ts
21837
+ // ../../packages/types/src/service-image.ts
21824
21838
  import { z as z104 } from "zod";
21839
+ var ServiceImageIntentSchema = z104.enum([
21840
+ "user_brief",
21841
+ "delegate_to_ai"
21842
+ ]);
21843
+ var ServiceImageInputSchema = z104.object({
21844
+ instruction: z104.string().trim().max(4e3).default(""),
21845
+ intent: ServiceImageIntentSchema.default("user_brief")
21846
+ }).strict().refine((value) => value.intent === "delegate_to_ai" || value.instruction.length > 0, {
21847
+ message: "Cu\xE9ntanos qu\xE9 servicio quieres promocionar.",
21848
+ path: [
21849
+ "instruction"
21850
+ ]
21851
+ });
21852
+ var ServiceImageContextSchema = z104.object({
21853
+ kind: z104.literal("service_image"),
21854
+ version: z104.literal(1),
21855
+ instruction: z104.string().max(4e3),
21856
+ intent: ServiceImageIntentSchema,
21857
+ businessName: z104.string().max(300),
21858
+ description: z104.string().max(2e4),
21859
+ brandCard: z104.string().max(2e4),
21860
+ palette: z104.array(z104.string()).max(20),
21861
+ referenceKeys: z104.array(z104.string()).max(10)
21862
+ }).strict();
21863
+
21864
+ // ../../packages/types/src/service-website-capture.ts
21865
+ import { z as z105 } from "zod";
21825
21866
  var WEBSITE_CAPTURE_MAX_RESEARCH_BYTES = 1024 * 1024;
21826
21867
  var WEBSITE_CAPTURE_MAX_FILES = 100;
21827
21868
  var WEBSITE_CAPTURE_MAX_FILE_BYTES = 8 * 1024 * 1024;
21828
21869
  var WEBSITE_CAPTURE_MAX_BUNDLE_BYTES = 30 * 1024 * 1024;
21829
- var WebsiteCaptureCauseSchema = z104.enum([
21870
+ var WebsiteCaptureCauseSchema = z105.enum([
21830
21871
  "site_blocked",
21831
21872
  "site_unreachable",
21832
21873
  "not_enough_content",
21833
21874
  "internal"
21834
21875
  ]);
21835
- var WebsiteCaptureStatusSchema = z104.enum([
21876
+ var WebsiteCaptureStatusSchema = z105.enum([
21836
21877
  "queued",
21837
21878
  "capturing",
21838
21879
  "ready",
@@ -21854,128 +21895,131 @@ function normalizeWebsiteCaptureUrl(value) {
21854
21895
  }
21855
21896
  }
21856
21897
  __name(normalizeWebsiteCaptureUrl, "normalizeWebsiteCaptureUrl");
21857
- var WebsiteCaptureRequestSchema = z104.object({
21858
- url: z104.string().trim().max(2048).url().refine((value) => normalizeWebsiteCaptureUrl(value) !== null, "Use an HTTP(S) URL without credentials").transform((value) => normalizeWebsiteCaptureUrl(value)),
21898
+ var WebsiteCaptureRequestSchema = z105.object({
21899
+ url: z105.string().trim().max(2048).url().refine((value) => normalizeWebsiteCaptureUrl(value) !== null, "Use an HTTP(S) URL without credentials").transform((value) => normalizeWebsiteCaptureUrl(value)),
21859
21900
  language: MotionGraphicsLanguageSchema
21860
21901
  }).strict();
21861
- var WebsiteCaptureResponseSchema = z104.object({
21862
- captureId: z104.string().uuid(),
21902
+ var WebsiteCaptureResponseSchema = z105.object({
21903
+ captureId: z105.string().uuid(),
21863
21904
  status: WebsiteCaptureStatusSchema,
21864
- expiresAt: z104.string().datetime(),
21865
- previewUrl: z104.string().url().optional(),
21905
+ expiresAt: z105.string().datetime(),
21906
+ previewUrl: z105.string().url().optional(),
21866
21907
  cause: WebsiteCaptureCauseSchema.optional()
21867
21908
  });
21868
21909
  var WebsiteCaptureJobSchema = WebsiteCaptureRequestSchema.extend({
21869
- captureId: z104.string().uuid(),
21870
- attempt: z104.number().int().positive(),
21871
- leaseUntil: z104.string().datetime()
21910
+ captureId: z105.string().uuid(),
21911
+ attempt: z105.number().int().positive(),
21912
+ leaseUntil: z105.string().datetime()
21872
21913
  });
21873
- var WebsiteCaptureClaimResponseSchema = z104.object({
21914
+ var WebsiteCaptureClaimResponseSchema = z105.object({
21874
21915
  capture: WebsiteCaptureJobSchema.nullable()
21875
21916
  });
21876
21917
  var attempt = {
21877
- attempt: z104.number().int().positive()
21918
+ attempt: z105.number().int().positive()
21878
21919
  };
21879
- var digest = z104.string().regex(/^[a-f0-9]{64}$/);
21880
- var WebsiteCaptureUploadRequestSchema = z104.object({
21920
+ var digest = z105.string().regex(/^[a-f0-9]{64}$/);
21921
+ var WebsiteCaptureUploadRequestSchema = z105.object({
21881
21922
  ...attempt,
21882
- contentLength: z104.number().int().positive().max(WEBSITE_CAPTURE_MAX_BUNDLE_BYTES),
21923
+ contentLength: z105.number().int().positive().max(WEBSITE_CAPTURE_MAX_BUNDLE_BYTES),
21883
21924
  sha256: digest
21884
21925
  }).strict();
21885
- var WebsiteCaptureDoneRequestSchema = z104.object({
21926
+ var WebsiteCaptureDoneRequestSchema = z105.object({
21886
21927
  ...attempt,
21887
21928
  sha256: digest
21888
21929
  }).strict();
21889
- var WebsiteCaptureFailedRequestSchema = z104.object({
21930
+ var WebsiteCaptureFailedRequestSchema = z105.object({
21890
21931
  ...attempt,
21891
21932
  cause: WebsiteCaptureCauseSchema
21892
21933
  }).strict();
21893
- var WebsiteCaptureBundleSchema = z104.object({
21894
- version: z104.literal(1),
21895
- files: z104.array(z104.object({
21896
- 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))$/),
21897
- 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),
21934
+ var WebsiteCaptureBundleSchema = z105.object({
21935
+ version: z105.literal(1),
21936
+ files: z105.array(z105.object({
21937
+ 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))$/),
21938
+ 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),
21898
21939
  sha256: digest
21899
21940
  }).strict()).min(1).max(WEBSITE_CAPTURE_MAX_FILES)
21900
21941
  }).strict().refine((bundle) => new Set(bundle.files.map((file) => file.path)).size === bundle.files.length, "Duplicate capture file");
21901
- var WebsiteCaptureScreenshotSchema = z104.object({
21902
- file: z104.string(),
21903
- scrollTop: z104.number()
21904
- });
21905
- var WebsiteCaptureAccessSchema = z104.object({
21906
- publicContentText: z104.string().max(8e3),
21907
- passwordGate: z104.boolean(),
21908
- challengeGate: z104.boolean(),
21909
- blockingOverlay: z104.boolean()
21910
- });
21911
- var WebsiteCaptureResearchSchema = z104.object({
21912
- requestedUrl: z104.string().url(),
21913
- capturedAt: z104.string().datetime(),
21914
- locale: z104.string(),
21915
- bodyTextTruncated: z104.boolean(),
21916
- finalUrl: z104.string().url(),
21917
- lang: z104.string().nullable(),
21918
- title: z104.string(),
21919
- description: z104.string(),
21920
- openGraph: z104.object({
21921
- title: z104.string(),
21922
- description: z104.string(),
21923
- image: z104.string(),
21924
- siteName: z104.string()
21942
+ var WebsiteCaptureScreenshotSchema = z105.object({
21943
+ file: z105.string(),
21944
+ scrollTop: z105.number()
21945
+ });
21946
+ var WebsiteCaptureAccessSchema = z105.object({
21947
+ publicContentText: z105.string().max(8e3),
21948
+ passwordGate: z105.boolean(),
21949
+ challengeGate: z105.boolean(),
21950
+ blockingOverlay: z105.boolean(),
21951
+ // Decoded, substantial images visible outside access walls and page chrome.
21952
+ // Optional for compatibility with already captured text-led research.
21953
+ publicImageUrls: z105.array(z105.string().url().max(8192)).max(20).optional()
21954
+ });
21955
+ var WebsiteCaptureResearchSchema = z105.object({
21956
+ requestedUrl: z105.string().url(),
21957
+ capturedAt: z105.string().datetime(),
21958
+ locale: z105.string(),
21959
+ bodyTextTruncated: z105.boolean(),
21960
+ finalUrl: z105.string().url(),
21961
+ lang: z105.string().nullable(),
21962
+ title: z105.string(),
21963
+ description: z105.string(),
21964
+ openGraph: z105.object({
21965
+ title: z105.string(),
21966
+ description: z105.string(),
21967
+ image: z105.string(),
21968
+ siteName: z105.string()
21925
21969
  }),
21926
- themeColor: z104.string(),
21927
- headings: z104.object({
21928
- h1: z104.array(z104.string()),
21929
- h2: z104.array(z104.string()),
21930
- h3: z104.array(z104.string())
21970
+ themeColor: z105.string(),
21971
+ headings: z105.object({
21972
+ h1: z105.array(z105.string()),
21973
+ h2: z105.array(z105.string()),
21974
+ h3: z105.array(z105.string())
21931
21975
  }),
21932
- callsToAction: z104.array(z104.string()),
21933
- listItems: z104.array(z104.string()),
21934
- bodyText: z104.string(),
21976
+ callsToAction: z105.array(z105.string()),
21977
+ listItems: z105.array(z105.string()),
21978
+ bodyText: z105.string(),
21935
21979
  access: WebsiteCaptureAccessSchema.optional(),
21936
- consent: z104.object({
21937
- pressed: z104.string().nullable(),
21938
- removed: z104.number().nonnegative()
21980
+ consent: z105.object({
21981
+ pressed: z105.string().nullable(),
21982
+ removed: z105.number().nonnegative()
21939
21983
  }).optional(),
21940
- overlaysDismissed: z104.number().int().nonnegative().optional(),
21941
- style: z104.object({
21942
- bodyBackground: z104.string(),
21943
- bodyColor: z104.string(),
21944
- bodyFont: z104.string(),
21945
- headingFont: z104.string().nullable(),
21946
- headingColor: z104.string().nullable(),
21947
- actionColors: z104.array(z104.object({
21948
- color: z104.string(),
21949
- uses: z104.number()
21984
+ overlaysDismissed: z105.number().int().nonnegative().optional(),
21985
+ style: z105.object({
21986
+ bodyBackground: z105.string(),
21987
+ bodyColor: z105.string(),
21988
+ bodyFont: z105.string(),
21989
+ headingFont: z105.string().nullable(),
21990
+ headingColor: z105.string().nullable(),
21991
+ actionColors: z105.array(z105.object({
21992
+ color: z105.string(),
21993
+ uses: z105.number()
21950
21994
  }))
21951
21995
  }),
21952
- images: z104.array(z104.object({
21953
- file: z104.string(),
21954
- src: z104.string(),
21955
- alt: z104.string(),
21956
- width: z104.number().nullable(),
21957
- height: z104.number().nullable(),
21958
- isOpenGraph: z104.boolean()
21996
+ images: z105.array(z105.object({
21997
+ file: z105.string(),
21998
+ src: z105.string(),
21999
+ alt: z105.string(),
22000
+ width: z105.number().nullable(),
22001
+ height: z105.number().nullable(),
22002
+ isOpenGraph: z105.boolean()
21959
22003
  })),
21960
- logo: z104.object({
21961
- file: z104.literal("logo.png"),
21962
- svg: z104.literal("logo.svg").optional(),
21963
- width: z104.number(),
21964
- height: z104.number()
22004
+ logo: z105.object({
22005
+ file: z105.literal("logo.png"),
22006
+ svg: z105.literal("logo.svg").optional(),
22007
+ width: z105.number(),
22008
+ height: z105.number()
21965
22009
  }).nullable(),
21966
- fonts: z104.array(z104.object({
21967
- family: z104.string(),
21968
- weight: z104.string(),
21969
- style: z104.string(),
21970
- unicodeRange: z104.string().nullable(),
21971
- file: z104.string().optional()
22010
+ fonts: z105.array(z105.object({
22011
+ family: z105.string(),
22012
+ weight: z105.string(),
22013
+ style: z105.string(),
22014
+ unicodeRange: z105.string().nullable(),
22015
+ file: z105.string().optional()
21972
22016
  }).transform((font) => ({
21973
22017
  ...font,
21974
22018
  file: font.file
21975
22019
  }))),
21976
- screenshots: z104.object({
21977
- desktop: z104.array(WebsiteCaptureScreenshotSchema),
21978
- mobile: z104.array(WebsiteCaptureScreenshotSchema)
22020
+ screenshots: z105.object({
22021
+ desktop: z105.array(WebsiteCaptureScreenshotSchema),
22022
+ mobile: z105.array(WebsiteCaptureScreenshotSchema)
21979
22023
  })
21980
22024
  });
21981
22025
 
@@ -22488,23 +22532,23 @@ import { InsufficientScopeError, InvalidTokenError } from "@modelcontextprotocol
22488
22532
  import { createRemoteJWKSet as createRemoteJWKSet2, jwtVerify as jwtVerify2 } from "jose";
22489
22533
 
22490
22534
  // src/auth/oauth-config.ts
22491
- import { z as z105 } from "zod";
22535
+ import { z as z106 } from "zod";
22492
22536
  var MCP_RESOURCE = new URL("https://mcp.productmaker.app/mcp");
22493
22537
  var MCP_SCOPE = "mcp:access";
22494
22538
  var REFRESH_SCOPE = "offline_access";
22495
22539
  var STATIC_CLIENT_ISSUER = new URL(MCP_RESOURCE.origin);
22496
- var oauthEnvSchema = z105.object({
22497
- MCP_REMOTE_AUTH_MODE: z105.literal("oauth"),
22498
- MCP_AUTH0_ISSUER: z105.string().trim().min(1),
22499
- MCP_AUTH0_AUDIENCE: z105.string().trim().refine((value) => value === MCP_RESOURCE.href, {
22540
+ var oauthEnvSchema = z106.object({
22541
+ MCP_REMOTE_AUTH_MODE: z106.literal("oauth"),
22542
+ MCP_AUTH0_ISSUER: z106.string().trim().min(1),
22543
+ MCP_AUTH0_AUDIENCE: z106.string().trim().refine((value) => value === MCP_RESOURCE.href, {
22500
22544
  message: `must equal ${MCP_RESOURCE.href}`
22501
22545
  }),
22502
- MCP_AUTH0_CLIENT_ID: z105.string().trim().min(1),
22503
- MCP_AUTH0_CLIENT_SECRET: z105.string().trim().min(1),
22504
- PM_API_AUDIENCE: z105.string().trim().min(1),
22505
- AUTH0_AUDIENCE: z105.string().trim().min(1),
22506
- MCP_STATIC_CLIENT_ID: z105.string().trim().min(1).optional(),
22507
- MCP_STATIC_CLIENT_SECRET: z105.string().trim().min(1).optional()
22546
+ MCP_AUTH0_CLIENT_ID: z106.string().trim().min(1),
22547
+ MCP_AUTH0_CLIENT_SECRET: z106.string().trim().min(1),
22548
+ PM_API_AUDIENCE: z106.string().trim().min(1),
22549
+ AUTH0_AUDIENCE: z106.string().trim().min(1),
22550
+ MCP_STATIC_CLIENT_ID: z106.string().trim().min(1).optional(),
22551
+ MCP_STATIC_CLIENT_SECRET: z106.string().trim().min(1).optional()
22508
22552
  });
22509
22553
  function formatZodIssues(error) {
22510
22554
  return error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ");
@@ -23658,7 +23702,7 @@ var ApiClient = class {
23658
23702
  };
23659
23703
 
23660
23704
  // src/index.ts
23661
- var MCP_VERSION = "11.2.0";
23705
+ var MCP_VERSION = "11.2.2";
23662
23706
 
23663
23707
  // src/meta-upload-app.ts
23664
23708
  import { readFileSync } from "fs";
@@ -23730,7 +23774,7 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
23730
23774
  __name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
23731
23775
 
23732
23776
  // src/tools/tasks.ts
23733
- import { z as z110 } from "zod";
23777
+ import { z as z111 } from "zod";
23734
23778
 
23735
23779
  // src/resolve-image.ts
23736
23780
  import { lookup as dnsLookup } from "dns/promises";
@@ -24291,9 +24335,9 @@ async function resolveMediaRef(ref, opts) {
24291
24335
  __name(resolveMediaRef, "resolveMediaRef");
24292
24336
 
24293
24337
  // src/tools/shared.ts
24294
- import { z as z106 } from "zod";
24295
- 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);
24296
- var Country = z106.string().min(2).max(3);
24338
+ import { z as z107 } from "zod";
24339
+ var Lang = z107.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);
24340
+ var Country = z107.string().min(2).max(3);
24297
24341
  var LandingStrategyEnum = LandingStrategySchema;
24298
24342
  var LandingImageFormatEnum = LandingImageFormatSchema;
24299
24343
  var VideoPresetEnum = VideoPreset.extract([
@@ -24397,7 +24441,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
24397
24441
  return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
24398
24442
  }
24399
24443
  __name(animationStyleApplies, "animationStyleApplies");
24400
- var VideoTierEnum = z106.enum([
24444
+ var VideoTierEnum = z107.enum([
24401
24445
  "basic"
24402
24446
  ]);
24403
24447
  function resolveVideoTier(_tier) {
@@ -24455,10 +24499,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
24455
24499
  var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
24456
24500
  var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
24457
24501
  var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
24458
- var ImageRefSchema = z106.object({
24459
- 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.'),
24460
- 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`.'),
24461
- 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.")
24502
+ var ImageRefSchema = z107.object({
24503
+ url: z107.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.'),
24504
+ path: z107.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`.'),
24505
+ assetId: z107.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.")
24462
24506
  }).refine((v) => [
24463
24507
  v.url,
24464
24508
  v.path,
@@ -24466,11 +24510,11 @@ var ImageRefSchema = z106.object({
24466
24510
  ].filter(Boolean).length === 1, {
24467
24511
  message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
24468
24512
  });
24469
- var ImagesInput = z106.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
24513
+ var ImagesInput = z107.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
24470
24514
  const assetCount = images.filter((image) => Boolean(image.assetId)).length;
24471
24515
  if (assetCount > 0 && assetCount !== images.length) {
24472
24516
  ctx.addIssue({
24473
- code: z106.ZodIssueCode.custom,
24517
+ code: z107.ZodIssueCode.custom,
24474
24518
  message: "all image entries must use assetId, or all must use URL/path sources"
24475
24519
  });
24476
24520
  }
@@ -24543,14 +24587,14 @@ async function submitCreative(api, opts) {
24543
24587
  });
24544
24588
  }
24545
24589
  __name(submitCreative, "submitCreative");
24546
- var ResearchTargetCountryEnum = z106.enum([
24590
+ var ResearchTargetCountryEnum = z107.enum([
24547
24591
  "CO",
24548
24592
  "MX",
24549
24593
  "PE",
24550
24594
  "EC",
24551
24595
  "CL"
24552
24596
  ]);
24553
- var ResearchCategoryEnum = z106.enum([
24597
+ var ResearchCategoryEnum = z107.enum([
24554
24598
  "auto",
24555
24599
  "automotive",
24556
24600
  "kitchen",
@@ -25862,29 +25906,29 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
25862
25906
  __name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
25863
25907
 
25864
25908
  // src/tools/media-presentation.ts
25865
- import { z as z107 } from "zod";
25866
- var HttpsPresentationUrlSchema = z107.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
25909
+ import { z as z108 } from "zod";
25910
+ var HttpsPresentationUrlSchema = z108.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
25867
25911
  var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
25868
25912
  const hostname = new URL(value).hostname.toLowerCase();
25869
25913
  return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
25870
25914
  }, "preview URL must be owned by ProductMaker");
25871
- var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z107.number().int().positive().max(maximum), "positiveIntAtMost");
25872
- var PresentationImageSchema = z107.object({
25873
- kind: z107.literal("image"),
25915
+ var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z108.number().int().positive().max(maximum), "positiveIntAtMost");
25916
+ var PresentationImageSchema = z108.object({
25917
+ kind: z108.literal("image"),
25874
25918
  url: HttpsPresentationUrlSchema,
25875
- mimeType: z107.enum([
25919
+ mimeType: z108.enum([
25876
25920
  "image/jpeg",
25877
25921
  "image/png"
25878
25922
  ]),
25879
25923
  byteSize: positiveIntAtMost(5 * 1024 * 1024),
25880
25924
  width: positiveIntAtMost(16384),
25881
25925
  height: positiveIntAtMost(16384),
25882
- alt: z107.string().trim().min(1).max(240)
25926
+ alt: z108.string().trim().min(1).max(240)
25883
25927
  }).strict();
25884
25928
  var McpMediaPresentationSchema = PresentationImageSchema;
25885
- var GalleryImageSchema = z107.object({
25929
+ var GalleryImageSchema = z108.object({
25886
25930
  url: ProductMakerPreviewUrlSchema,
25887
- alt: z107.string().trim().min(1).max(240)
25931
+ alt: z108.string().trim().min(1).max(240)
25888
25932
  });
25889
25933
  var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
25890
25934
  async function imageBlocks(image, transport) {
@@ -25941,12 +25985,12 @@ async function buildMcpMediaPresentationContent(rawPresentation, transport = "ht
25941
25985
  ];
25942
25986
  }
25943
25987
  __name(buildMcpMediaPresentationContent, "buildMcpMediaPresentationContent");
25944
- var OwnedImagePreviewSchema = z107.object({
25988
+ var OwnedImagePreviewSchema = z108.object({
25945
25989
  url: HttpsPresentationUrlSchema.refine((value) => {
25946
25990
  const url = new URL(value);
25947
25991
  return !url.username && !url.password && !isPrivateHost(url.hostname);
25948
25992
  }, "Preview URL must be public HTTPS without credentials"),
25949
- alt: z107.string().trim().min(1).max(240)
25993
+ alt: z108.string().trim().min(1).max(240)
25950
25994
  });
25951
25995
  async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
25952
25996
  const preview2 = OwnedImagePreviewSchema.safeParse(rawPreview);
@@ -26029,7 +26073,7 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
26029
26073
  __name(buildMcpImageGalleryContent, "buildMcpImageGalleryContent");
26030
26074
 
26031
26075
  // src/tools/animated-video.ts
26032
- import { z as z108 } from "zod";
26076
+ import { z as z109 } from "zod";
26033
26077
 
26034
26078
  // src/tools/paid-confirmation.ts
26035
26079
  function describeMarketStudyChoice(enabled) {
@@ -26279,27 +26323,27 @@ function hookVariantsLabel(count) {
26279
26323
  return count === 1 ? "1 versi\xF3n del gancho" : `${count} versiones del gancho`;
26280
26324
  }
26281
26325
  __name(hookVariantsLabel, "hookVariantsLabel");
26282
- var DurationInput = z108.union(MOTION_GRAPHICS_DURATIONS.map((d) => z108.literal(d)));
26283
- var CreateAnimatedVideoInput = z108.object({
26284
- action: z108.enum([
26326
+ var DurationInput = z109.union(MOTION_GRAPHICS_DURATIONS.map((d) => z109.literal(d)));
26327
+ var CreateAnimatedVideoInput = z109.object({
26328
+ action: z109.enum([
26285
26329
  "prepare",
26286
26330
  "status",
26287
26331
  "cancel",
26288
26332
  "generate"
26289
26333
  ]).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."),
26290
- websiteCaptureId: z108.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
26291
- 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."),
26292
- 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."),
26334
+ websiteCaptureId: z109.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
26335
+ generationRequestId: z109.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."),
26336
+ confirmed: z109.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."),
26293
26337
  // Plain text, not `.url()`: users type «cal.com», and the web accepts it.
26294
26338
  // normalizeWebAddress (shared with the web) adds https:// and refuses
26295
26339
  // anything that is not a public http(s) address.
26296
- 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."),
26340
+ landingUrl: z109.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."),
26297
26341
  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.'),
26298
26342
  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.`),
26299
26343
  language: MotionGraphicsLanguageSchema.optional().describe('Idioma de los textos del video: "es", "en" o "pt".'),
26300
- 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)."),
26344
+ notes: z109.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)."),
26301
26345
  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.`),
26302
- 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.")
26346
+ music: z109.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.")
26303
26347
  }).strict();
26304
26348
  function captureNextAction(capture) {
26305
26349
  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.";
@@ -26332,43 +26376,43 @@ var FORMAT_LABELS = {
26332
26376
  square: "cuadrado 1:1",
26333
26377
  horizontal: "horizontal 16:9"
26334
26378
  };
26335
- var AnimatedVideoResultSchema = z108.object({
26336
- status: z108.enum([
26379
+ var AnimatedVideoResultSchema = z109.object({
26380
+ status: z109.enum([
26337
26381
  "pending",
26338
26382
  "done",
26339
26383
  "error"
26340
26384
  ]),
26341
- serviceMode: z108.literal("motion_graphics"),
26342
- finalMp4Url: z108.string().optional(),
26343
- error: z108.string().optional(),
26344
- motionGraphics: z108.object({
26385
+ serviceMode: z109.literal("motion_graphics"),
26386
+ finalMp4Url: z109.string().optional(),
26387
+ error: z109.string().optional(),
26388
+ motionGraphics: z109.object({
26345
26389
  stage: MotionGraphicsStageSchema,
26346
26390
  format: MotionGraphicsFormatSchema,
26347
- durationSec: z108.number(),
26348
- width: z108.number().optional(),
26349
- height: z108.number().optional(),
26391
+ durationSec: z109.number(),
26392
+ width: z109.number().optional(),
26393
+ height: z109.number().optional(),
26350
26394
  language: MotionGraphicsLanguageSchema.optional(),
26351
- queuedAt: z108.string().optional(),
26352
- jobsAhead: z108.number().int().nonnegative().optional(),
26353
- stageStartedAt: z108.string().optional(),
26354
- renderProgress: z108.number().optional(),
26395
+ queuedAt: z109.string().optional(),
26396
+ jobsAhead: z109.number().int().nonnegative().optional(),
26397
+ stageStartedAt: z109.string().optional(),
26398
+ renderProgress: z109.number().optional(),
26355
26399
  // AI clip fields (absent on a video paid before clips, or from an API
26356
26400
  // that predates them). Lenient: an unreadable value is dropped
26357
26401
  // instead of hiding the status.
26358
- clipCount: z108.number().int().nonnegative().optional().catch(void 0),
26359
- clipsUsed: z108.number().int().nonnegative().optional().catch(void 0),
26360
- clipPriceCents: z108.number().finite().nonnegative().optional().catch(void 0),
26361
- clipsRefunded: z108.number().int().nonnegative().optional().catch(void 0),
26402
+ clipCount: z109.number().int().nonnegative().optional().catch(void 0),
26403
+ clipsUsed: z109.number().int().nonnegative().optional().catch(void 0),
26404
+ clipPriceCents: z109.number().finite().nonnegative().optional().catch(void 0),
26405
+ clipsRefunded: z109.number().int().nonnegative().optional().catch(void 0),
26362
26406
  // Hook versions (absent from an API or a video before them): the
26363
26407
  // count ordered and, once done, the signed URLs of the EXTRA versions
26364
26408
  // (hook 2, hook 3); `finalMp4Url` is hook 1.
26365
- hookVariants: z108.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
26366
- variantUrls: z108.array(z108.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
26409
+ hookVariants: z109.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
26410
+ variantUrls: z109.array(z109.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
26367
26411
  // Extra hook versions given back, as the task recorded it once the
26368
26412
  // refunds landed (absent until then, and from an API before it).
26369
- variantsRefunded: z108.number().int().nonnegative().optional().catch(void 0),
26370
- activity: z108.array(MotionGraphicsActivitySchema).optional().catch(void 0),
26371
- previewUrl: z108.string().optional()
26413
+ variantsRefunded: z109.number().int().nonnegative().optional().catch(void 0),
26414
+ activity: z109.array(MotionGraphicsActivitySchema).optional().catch(void 0),
26415
+ previewUrl: z109.string().optional()
26372
26416
  }).passthrough()
26373
26417
  }).passthrough();
26374
26418
  function parseAnimatedVideoResult(value) {
@@ -26624,10 +26668,10 @@ function registerAnimatedVideoTools(server, api) {
26624
26668
  __name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
26625
26669
 
26626
26670
  // src/tools/winning-product-image.ts
26627
- import { z as z109 } from "zod";
26628
- var WinnerReferenceInput = z109.object({
26629
- runId: z109.string().uuid(),
26630
- candidateSourceId: z109.string().trim().min(1).max(160)
26671
+ import { z as z110 } from "zod";
26672
+ var WinnerReferenceInput = z110.object({
26673
+ runId: z110.string().uuid(),
26674
+ candidateSourceId: z110.string().trim().min(1).max(160)
26631
26675
  }).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
26632
26676
  async function resolveWinnerImages(api, winnerReference, images) {
26633
26677
  if (!winnerReference) return images;
@@ -26664,62 +26708,62 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
26664
26708
  var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
26665
26709
  var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
26666
26710
  var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
26667
- var CreateProductTaskInput = z110.object({
26711
+ var CreateProductTaskInput = z111.object({
26668
26712
  images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
26669
26713
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
26670
- 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."),
26671
- 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."),
26714
+ projectId: z111.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
26715
+ productUrl: z111.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."),
26672
26716
  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.'),
26673
26717
  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.'),
26674
- 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.'),
26675
- 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".'),
26676
- 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.'),
26677
- 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.'),
26678
- 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."),
26679
- 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.'),
26718
+ price: z111.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.'),
26719
+ compareAtPrice: z111.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".'),
26720
+ offer: z111.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.'),
26721
+ paymentMethods: z111.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.'),
26722
+ productContext: z111.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."),
26723
+ productLabel: z111.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.'),
26680
26724
  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.'),
26681
26725
  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.'),
26682
- durationSeconds: z110.union([
26683
- z110.literal(15),
26684
- z110.literal(30)
26726
+ durationSeconds: z111.union([
26727
+ z111.literal(15),
26728
+ z111.literal(30)
26685
26729
  ]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
26686
- 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."),
26687
- 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."),
26730
+ pauseForAngleReview: z111.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."),
26731
+ aiDecidesAll: z111.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."),
26688
26732
  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.'),
26689
26733
  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.'),
26690
26734
  videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
26691
26735
  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).'),
26692
- 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."),
26736
+ videoAngleCount: z111.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."),
26693
26737
  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.'),
26694
- outputs: z110.array(z110.enum([
26738
+ outputs: z111.array(z111.enum([
26695
26739
  "landing",
26696
26740
  "video",
26697
26741
  "image"
26698
26742
  ])).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}`),
26699
- 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."),
26700
- 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."),
26743
+ 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."),
26744
+ competitorScanEnabled: z111.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."),
26701
26745
  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.'),
26702
- 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."),
26703
- 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."),
26704
- 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."),
26746
+ replicateWinnerWhenFound: z111.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."),
26747
+ 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 los outputs generados."),
26748
+ actorId: z111.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."),
26705
26749
  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.'),
26706
- 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.'),
26707
- 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."),
26708
- 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."),
26750
+ creativeDirection: z111.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.'),
26751
+ headline: z111.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."),
26752
+ subheadline: z111.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."),
26709
26753
  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".'),
26710
26754
  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".')
26711
26755
  }).strict();
26712
- var CreateServiceVideoInput = z110.object({
26713
- 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."),
26714
- 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.'),
26756
+ var CreateServiceVideoInput = z111.object({
26757
+ landingUrl: z111.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
26758
+ additionalContext: z111.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
26715
26759
  language: Lang.describe("Idioma del video: es, en o pt."),
26716
- 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.'),
26717
- brandId: z110.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
26718
- reviewMode: z110.enum([
26760
+ voiceId: z111.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.'),
26761
+ brandId: z111.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
26762
+ reviewMode: z111.enum([
26719
26763
  "automatic",
26720
26764
  "guided"
26721
26765
  ]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
26722
- videoPreset: z110.enum([
26766
+ videoPreset: z111.enum([
26723
26767
  "auto",
26724
26768
  "ugc_dynamic",
26725
26769
  "ugc_how_to",
@@ -26729,128 +26773,128 @@ var CreateServiceVideoInput = z110.object({
26729
26773
  videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
26730
26774
  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.')
26731
26775
  }).strict();
26732
- var GetTaskStatusInput = z110.object({
26733
- taskId: z110.string().min(1),
26734
- waitSeconds: z110.number().int().min(0).max(120).optional()
26776
+ var GetTaskStatusInput = z111.object({
26777
+ taskId: z111.string().min(1),
26778
+ waitSeconds: z111.number().int().min(0).max(120).optional()
26735
26779
  });
26736
- var ListTasksInput = z110.object({
26737
- limit: z110.number().int().min(1).max(50).optional(),
26738
- offset: z110.number().int().min(0).optional(),
26739
- search: z110.string().optional()
26780
+ var ListTasksInput = z111.object({
26781
+ limit: z111.number().int().min(1).max(50).optional(),
26782
+ offset: z111.number().int().min(0).optional(),
26783
+ search: z111.string().optional()
26740
26784
  });
26741
26785
  var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
26742
26786
  var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
26743
- var EditTaskDraftInput = z110.object({
26744
- taskId: z110.string().min(1),
26745
- angleIndex: z110.number().int().min(0),
26746
- angle: z110.object({
26747
- angle: z110.string().min(1).max(480),
26748
- buyerPersona: z110.string().min(1).max(360),
26749
- actor: z110.string().min(1).max(360).optional(),
26750
- 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."),
26751
- gender: z110.enum([
26787
+ var EditTaskDraftInput = z111.object({
26788
+ taskId: z111.string().min(1),
26789
+ angleIndex: z111.number().int().min(0),
26790
+ angle: z111.object({
26791
+ angle: z111.string().min(1).max(480),
26792
+ buyerPersona: z111.string().min(1).max(360),
26793
+ actor: z111.string().min(1).max(360).optional(),
26794
+ actorId: z111.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."),
26795
+ gender: z111.enum([
26752
26796
  "female",
26753
26797
  "male"
26754
26798
  ]).optional(),
26755
- scriptNotes: z110.string().max(2e3).optional()
26799
+ scriptNotes: z111.string().max(2e3).optional()
26756
26800
  })
26757
26801
  });
26758
- var PendingActionPayload = z110.discriminatedUnion("kind", [
26759
- z110.object({
26760
- kind: z110.literal("product_reference_set_approval"),
26802
+ var PendingActionPayload = z111.discriminatedUnion("kind", [
26803
+ z111.object({
26804
+ kind: z111.literal("product_reference_set_approval"),
26761
26805
  scope: ProductReferenceScopeEnum.optional(),
26762
- scopeKey: z110.string().min(1).max(120).optional(),
26763
- scopeSnapshotId: z110.string().uuid().optional(),
26764
- expectedScopeHash: z110.string().min(1).max(128).optional(),
26806
+ scopeKey: z111.string().min(1).max(120).optional(),
26807
+ scopeSnapshotId: z111.string().uuid().optional(),
26808
+ expectedScopeHash: z111.string().min(1).max(128).optional(),
26765
26809
  decision: ProductReferenceResolutionDecisionEnum,
26766
26810
  reason: ProductReferenceRejectionReasonEnum.optional(),
26767
- affectedRefKeys: z110.array(z110.string().min(1).max(200)).min(1).optional(),
26768
- affectedPhotoNumbers: z110.array(z110.number().int().positive()).min(1).optional(),
26769
- recoveryAction: z110.enum([
26811
+ affectedRefKeys: z111.array(z111.string().min(1).max(200)).min(1).optional(),
26812
+ affectedPhotoNumbers: z111.array(z111.number().int().positive()).min(1).optional(),
26813
+ recoveryAction: z111.enum([
26770
26814
  "remove",
26771
26815
  "replace",
26772
26816
  "upload",
26773
26817
  "return_to_selection"
26774
26818
  ]).optional()
26775
26819
  }),
26776
- z110.object({
26777
- kind: z110.literal("product_reference_confirmation"),
26778
- 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."),
26820
+ z111.object({
26821
+ kind: z111.literal("product_reference_confirmation"),
26822
+ selectedPhotoNumbers: z111.array(z111.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."),
26779
26823
  userChoice: ProductReferenceUserChoiceEnum.optional(),
26780
- confirmedProductNames: z110.array(z110.string().min(1).max(120)).min(2).max(8).optional(),
26824
+ confirmedProductNames: z111.array(z111.string().min(1).max(120)).min(2).max(8).optional(),
26781
26825
  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."),
26782
26826
  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."),
26783
- useMultiSceneShowcase: z110.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
26827
+ useMultiSceneShowcase: z111.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
26784
26828
  }),
26785
- z110.object({
26786
- kind: z110.literal("angle_review_approval"),
26829
+ z111.object({
26830
+ kind: z111.literal("angle_review_approval"),
26787
26831
  // All edits are optional — empty action body just approves the
26788
26832
  // backend-generated draft as-is. Field shapes mirror the angle-review
26789
26833
  // request contracts in @packages/types/wizard.ts; the handler routes to
26790
26834
  // the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
26791
- customAngle: z110.string().min(1).max(480).optional(),
26835
+ customAngle: z111.string().min(1).max(480).optional(),
26792
26836
  // Keep the shared MCP action within the strictest downstream contract:
26793
26837
  // autopilot/image resume endpoints cap these fields at 1500 characters.
26794
- painPoints: z110.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
26795
- benefits: z110.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
26838
+ painPoints: z111.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
26839
+ benefits: z111.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
26796
26840
  // Same policy as the two fields above: the strictest downstream contract
26797
26841
  // wins. The image endpoint caps each feature at 240 while landing/video
26798
26842
  // accept 300, and this single action routes to whichever the task is — so
26799
26843
  // accepting 300 here turns a 250-character feature on an image task into
26800
26844
  // an opaque HTTP 400 after the model already believed it had been saved.
26801
- features: z110.array(z110.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
26802
- buyerPersona: z110.string().min(1).max(360).optional(),
26845
+ features: z111.array(z111.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
26846
+ buyerPersona: z111.string().min(1).max(360).optional(),
26803
26847
  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.'),
26804
- 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."),
26805
- actorId: z110.string().max(120).nullable().optional(),
26806
- creativeDirection: z110.string().max(2e3).optional(),
26807
- 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."),
26808
- angleEdits: z110.array(z110.object({
26809
- angleNumber: z110.number().int().positive(),
26810
- narrativeSelection: z110.enum([
26848
+ actor: z111.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."),
26849
+ actorId: z111.string().max(120).nullable().optional(),
26850
+ creativeDirection: z111.string().max(2e3).optional(),
26851
+ selectedAngleNumbers: z111.array(z111.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."),
26852
+ angleEdits: z111.array(z111.object({
26853
+ angleNumber: z111.number().int().positive(),
26854
+ narrativeSelection: z111.enum([
26811
26855
  "market",
26812
26856
  "guided"
26813
26857
  ]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
26814
- angle: z110.string().min(1).max(480).optional(),
26815
- buyerPersona: z110.string().min(1).max(360).optional(),
26858
+ angle: z111.string().min(1).max(480).optional(),
26859
+ buyerPersona: z111.string().min(1).max(360).optional(),
26816
26860
  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.'),
26817
- actor: z110.string().min(1).max(360).optional(),
26818
- actorId: z110.string().max(120).nullable().optional(),
26819
- creativeDirection: z110.string().max(2e3).optional()
26861
+ actor: z111.string().min(1).max(360).optional(),
26862
+ actorId: z111.string().max(120).nullable().optional(),
26863
+ creativeDirection: z111.string().max(2e3).optional()
26820
26864
  }).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)."),
26821
- gapDurationSeconds: z110.union([
26822
- z110.literal(15),
26823
- z110.literal(30)
26865
+ gapDurationSeconds: z111.union([
26866
+ z111.literal(15),
26867
+ z111.literal(30)
26824
26868
  ]).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.")
26825
26869
  }),
26826
- z110.object({
26827
- kind: z110.literal("service_angle_approval"),
26828
- angleId: z110.string().uuid().optional(),
26829
- angleNumber: z110.number().int().positive().optional(),
26830
- content: z110.string().min(1).max(480).optional(),
26831
- creativeDirection: z110.string().min(1).max(1500).optional(),
26832
- actor: z110.string().min(1).max(360).optional()
26870
+ z111.object({
26871
+ kind: z111.literal("service_angle_approval"),
26872
+ angleId: z111.string().uuid().optional(),
26873
+ angleNumber: z111.number().int().positive().optional(),
26874
+ content: z111.string().min(1).max(480).optional(),
26875
+ creativeDirection: z111.string().min(1).max(1500).optional(),
26876
+ actor: z111.string().min(1).max(360).optional()
26833
26877
  }),
26834
- z110.object({
26835
- kind: z110.literal("service_script_approval"),
26836
- voiceovers: z110.record(z110.string(), z110.string().min(1).max(600)).optional(),
26837
- visualDirections: z110.record(z110.string(), z110.string().min(1).max(1200)).optional(),
26838
- voiceoversByScene: z110.record(z110.string(), z110.string().min(1).max(600)).optional(),
26839
- visualDirectionsByScene: z110.record(z110.string(), z110.string().min(1).max(1200)).optional()
26878
+ z111.object({
26879
+ kind: z111.literal("service_script_approval"),
26880
+ voiceovers: z111.record(z111.string(), z111.string().min(1).max(600)).optional(),
26881
+ visualDirections: z111.record(z111.string(), z111.string().min(1).max(1200)).optional(),
26882
+ voiceoversByScene: z111.record(z111.string(), z111.string().min(1).max(600)).optional(),
26883
+ visualDirectionsByScene: z111.record(z111.string(), z111.string().min(1).max(1200)).optional()
26840
26884
  })
26841
26885
  ]);
26842
- var ResolvePendingActionInput = z110.object({
26843
- taskId: z110.string().min(1),
26886
+ var ResolvePendingActionInput = z111.object({
26887
+ taskId: z111.string().min(1),
26844
26888
  action: PendingActionPayload
26845
26889
  }).strict();
26846
26890
  function resolveVariantConfirmVideoTier(action) {
26847
26891
  return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
26848
26892
  }
26849
26893
  __name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
26850
- var StatusForResolveSchema = z110.object({
26894
+ var StatusForResolveSchema = z111.object({
26851
26895
  // Metadata used to select the backend resume contract. Older API responses
26852
26896
  // may omit these fields, so the resolver keeps the generic fallback.
26853
- kind: z110.enum([
26897
+ kind: z111.enum([
26854
26898
  "autopilot",
26855
26899
  "video",
26856
26900
  "image",
@@ -26858,18 +26902,18 @@ var StatusForResolveSchema = z110.object({
26858
26902
  "mix",
26859
26903
  "service"
26860
26904
  ]).optional(),
26861
- selectedOutputs: z110.array(z110.enum([
26905
+ selectedOutputs: z111.array(z111.enum([
26862
26906
  "landing",
26863
26907
  "video",
26864
26908
  "image"
26865
26909
  ])).optional(),
26866
- videoAngleCount: z110.number().int().min(1).max(3).optional(),
26867
- ugcFormat: z110.enum([
26910
+ videoAngleCount: z111.number().int().min(1).max(3).optional(),
26911
+ ugcFormat: z111.enum([
26868
26912
  "single_8s",
26869
26913
  "single_15s",
26870
26914
  "double_30s"
26871
26915
  ]).optional(),
26872
- videoStyle: z110.enum([
26916
+ videoStyle: z111.enum([
26873
26917
  "ugc",
26874
26918
  "cartoon_3d",
26875
26919
  "product_only",
@@ -26879,13 +26923,13 @@ var StatusForResolveSchema = z110.object({
26879
26923
  videoQuality: VideoQualityEnum.optional(),
26880
26924
  videoRouteId: VideoRouteIdEnum.optional(),
26881
26925
  videoModel: TaskVideoModelEnum.optional(),
26882
- videoTier: z110.enum([
26926
+ videoTier: z111.enum([
26883
26927
  "legacy",
26884
26928
  "standard",
26885
26929
  "pro",
26886
26930
  "single_call"
26887
26931
  ]).optional(),
26888
- videoResolution: z110.enum([
26932
+ videoResolution: z111.enum([
26889
26933
  "480p",
26890
26934
  "720p"
26891
26935
  ]).optional(),
@@ -26893,60 +26937,60 @@ var StatusForResolveSchema = z110.object({
26893
26937
  // A task created before a narrative was blocked/hidden must still parse,
26894
26938
  // or resolve_pending_action could never approve it.
26895
26939
  narrativeStyle: NarrativeStyle.optional(),
26896
- pauseForVideoScriptReview: z110.boolean().optional(),
26897
- pendingUserAction: z110.object({
26898
- kind: z110.string(),
26899
- candidateGrouping: z110.string().optional(),
26900
- selectedImageUrls: z110.array(z110.string()).optional(),
26901
- proposedProductNames: z110.array(z110.string()).optional(),
26940
+ pauseForVideoScriptReview: z111.boolean().optional(),
26941
+ pendingUserAction: z111.object({
26942
+ kind: z111.string(),
26943
+ candidateGrouping: z111.string().optional(),
26944
+ selectedImageUrls: z111.array(z111.string()).optional(),
26945
+ proposedProductNames: z111.array(z111.string()).optional(),
26902
26946
  // Adaptive reference questions are server-owned. Echo only the evidence
26903
26947
  // identity and the choices shown by the current snapshot; never accept a
26904
26948
  // client-supplied reference set as authorization.
26905
- options: z110.array(ProductReferenceUserChoiceEnum).max(4).optional(),
26906
- mode: z110.enum([
26949
+ options: z111.array(ProductReferenceUserChoiceEnum).max(4).optional(),
26950
+ mode: z111.enum([
26907
26951
  "question",
26908
26952
  "visual_recovery"
26909
26953
  ]).optional(),
26910
26954
  /** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
26911
- canKeepSelection: z110.boolean().optional(),
26912
- decisionKey: z110.string().optional(),
26913
- questionOrdinal: z110.number().int().min(1).max(5).optional(),
26914
- questionCeiling: z110.union([
26915
- z110.literal(3),
26916
- z110.literal(5)
26955
+ canKeepSelection: z111.boolean().optional(),
26956
+ decisionKey: z111.string().optional(),
26957
+ questionOrdinal: z111.number().int().min(1).max(5).optional(),
26958
+ questionCeiling: z111.union([
26959
+ z111.literal(3),
26960
+ z111.literal(5)
26917
26961
  ]).optional(),
26918
- referenceEvidenceVersion: z110.number().int().positive().optional(),
26919
- expectedEvidenceHash: z110.string().optional(),
26920
- question: z110.object({
26921
- prompt: z110.string().min(1).max(240),
26922
- helpText: z110.string().min(1).max(300).optional(),
26923
- options: z110.array(z110.object({
26962
+ referenceEvidenceVersion: z111.number().int().positive().optional(),
26963
+ expectedEvidenceHash: z111.string().optional(),
26964
+ question: z111.object({
26965
+ prompt: z111.string().min(1).max(240),
26966
+ helpText: z111.string().min(1).max(300).optional(),
26967
+ options: z111.array(z111.object({
26924
26968
  value: ProductReferenceUserChoiceEnum,
26925
- label: z110.string().min(1).max(120),
26926
- description: z110.string().min(1).max(240).optional()
26969
+ label: z111.string().min(1).max(120),
26970
+ description: z111.string().min(1).max(240).optional()
26927
26971
  })).min(2).max(4)
26928
26972
  }).optional(),
26929
26973
  scope: ProductReferenceScopeEnum.optional(),
26930
- scopeKey: z110.string().optional(),
26931
- scopeSnapshotId: z110.string().uuid().optional(),
26932
- scopeHash: z110.string().optional(),
26933
- baseReferenceSetHash: z110.string().optional(),
26934
- phase: z110.enum([
26974
+ scopeKey: z111.string().optional(),
26975
+ scopeSnapshotId: z111.string().uuid().optional(),
26976
+ scopeHash: z111.string().optional(),
26977
+ baseReferenceSetHash: z111.string().optional(),
26978
+ phase: z111.enum([
26935
26979
  "preparation",
26936
26980
  "final"
26937
26981
  ]).optional(),
26938
- selectedRefKeys: z110.array(z110.string().min(1).max(200)).optional(),
26939
- allowedDecisions: z110.array(ProductReferenceResolutionDecisionEnum).optional(),
26940
- previews: z110.array(z110.object({
26941
- refKey: z110.string().min(1).max(200)
26982
+ selectedRefKeys: z111.array(z111.string().min(1).max(200)).optional(),
26983
+ allowedDecisions: z111.array(ProductReferenceResolutionDecisionEnum).optional(),
26984
+ previews: z111.array(z111.object({
26985
+ refKey: z111.string().min(1).max(200)
26942
26986
  }).passthrough()).optional(),
26943
- customAngleDraft: z110.string().optional(),
26944
- painPointsDraft: z110.string().optional(),
26945
- benefitsDraft: z110.string().optional(),
26946
- featuresDraft: z110.array(z110.string()).optional(),
26947
- angleOptions: z110.array(z110.object({
26948
- index: z110.number().int().nonnegative(),
26949
- angle: z110.string().min(1)
26987
+ customAngleDraft: z111.string().optional(),
26988
+ painPointsDraft: z111.string().optional(),
26989
+ benefitsDraft: z111.string().optional(),
26990
+ featuresDraft: z111.array(z111.string()).optional(),
26991
+ angleOptions: z111.array(z111.object({
26992
+ index: z111.number().int().nonnegative(),
26993
+ angle: z111.string().min(1)
26950
26994
  }).passthrough()).min(1).max(5).optional(),
26951
26995
  // Recommendation consumed only when the caller explicitly sends
26952
26996
  // gapDurationSeconds: 30 in the angle approval action.
@@ -26956,17 +27000,17 @@ var StatusForResolveSchema = z110.object({
26956
27000
  // keys. `actorId` (the saved custom actor the picker stored) was silently
26957
27001
  // dropped here, so the approval handler below could not echo it back on the
26958
27002
  // PATCH — the selection looked accepted and reached no render.
26959
- angles: z110.array(z110.object({
26960
- id: z110.string().uuid(),
26961
- content: z110.string(),
26962
- creativeDirection: z110.string(),
26963
- actor: z110.string(),
26964
- actorId: z110.string().nullable().optional()
27003
+ angles: z111.array(z111.object({
27004
+ id: z111.string().uuid(),
27005
+ content: z111.string(),
27006
+ creativeDirection: z111.string(),
27007
+ actor: z111.string(),
27008
+ actorId: z111.string().nullable().optional()
26965
27009
  }).passthrough()).optional(),
26966
- panels: z110.array(z110.object({
26967
- beatId: z110.string(),
26968
- voiceover: z110.string(),
26969
- visualDirection: z110.string()
27010
+ panels: z111.array(z111.object({
27011
+ beatId: z111.string(),
27012
+ voiceover: z111.string(),
27013
+ visualDirection: z111.string()
26970
27014
  }).passthrough()).optional()
26971
27015
  }).optional()
26972
27016
  }).passthrough();
@@ -27318,8 +27362,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
27318
27362
  server.registerTool("verify_landing_commerce", {
27319
27363
  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.",
27320
27364
  inputSchema: {
27321
- taskId: z110.string().uuid(),
27322
- editId: z110.string().uuid()
27365
+ taskId: z111.string().uuid(),
27366
+ editId: z111.string().uuid()
27323
27367
  },
27324
27368
  annotations: OVERWRITES_EXTERNAL
27325
27369
  }, async (input) => {
@@ -27959,7 +28003,7 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
27959
28003
  __name(registerTaskTools, "registerTaskTools");
27960
28004
 
27961
28005
  // src/tools/creatives.ts
27962
- import { z as z111 } from "zod";
28006
+ import { z as z112 } from "zod";
27963
28007
  var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
27964
28008
  var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
27965
28009
  var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
@@ -27970,72 +28014,72 @@ var CreativeRefs = {
27970
28014
  images: ImagesInput,
27971
28015
  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.'),
27972
28016
  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.'),
27973
- 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.'),
27974
- 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.'),
27975
- 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".'),
27976
- 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."),
27977
- 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.'),
27978
- 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.'),
27979
- isCombo: z111.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
27980
- 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."),
27981
- 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.")
28017
+ price: z112.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.'),
28018
+ offer: z112.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.'),
28019
+ compareAtPrice: z112.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
28020
+ productContext: z112.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."),
28021
+ productLabel: z112.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.'),
28022
+ buyerPersona: z112.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.'),
28023
+ isCombo: z112.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
28024
+ competitorScanEnabled: z112.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."),
28025
+ brandId: z112.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.")
27982
28026
  };
27983
- var VideoPresenter = z111.discriminatedUnion("mode", [
27984
- z111.object({
27985
- mode: z111.literal("none")
28027
+ var VideoPresenter = z112.discriminatedUnion("mode", [
28028
+ z112.object({
28029
+ mode: z112.literal("none")
27986
28030
  }).strict(),
27987
- z111.object({
27988
- mode: z111.literal("saved_actor"),
27989
- actorId: z111.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
28031
+ z112.object({
28032
+ mode: z112.literal("saved_actor"),
28033
+ actorId: z112.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
27990
28034
  }).strict(),
27991
- z111.object({
27992
- mode: z111.literal("described"),
27993
- description: z111.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
28035
+ z112.object({
28036
+ mode: z112.literal("described"),
28037
+ description: z112.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
27994
28038
  }).strict()
27995
28039
  ]);
27996
- var VideoCreativeSetup = z111.discriminatedUnion("mode", [
27997
- z111.object({
27998
- mode: z111.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
28040
+ var VideoCreativeSetup = z112.discriminatedUnion("mode", [
28041
+ z112.object({
28042
+ mode: z112.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
27999
28043
  }).strict(),
28000
- z111.object({
28001
- mode: z111.literal("guided"),
28044
+ z112.object({
28045
+ mode: z112.literal("guided"),
28002
28046
  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.'),
28003
- buyerPersona: z111.string().trim().min(1).max(360),
28047
+ buyerPersona: z112.string().trim().min(1).max(360),
28004
28048
  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.'),
28005
28049
  presenter: VideoPresenter,
28006
- 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.")
28050
+ creativeDirection: z112.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
28007
28051
  }).strict()
28008
28052
  ]);
28009
- var VideoInput = z111.object({
28053
+ var VideoInput = z112.object({
28010
28054
  images: CreativeRefs.images.optional(),
28011
28055
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
28012
- title: z111.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
28013
- 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".'),
28056
+ title: z112.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
28057
+ primaryAngle: z112.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".'),
28014
28058
  language: CreativeRefs.language,
28015
28059
  country: CreativeRefs.country,
28016
- aspectRatio: z111.enum([
28060
+ aspectRatio: z112.enum([
28017
28061
  "9:16",
28018
28062
  "16:9",
28019
28063
  "Auto"
28020
28064
  ]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
28021
28065
  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.'),
28022
- 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."),
28023
- 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."),
28066
+ durationSeconds: z112.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."),
28067
+ videoAngleCount: z112.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."),
28024
28068
  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.'),
28025
28069
  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."),
28026
28070
  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.'),
28027
28071
  videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
28028
28072
  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.'),
28029
- 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"].'),
28073
+ features: z112.array(z112.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
28030
28074
  price: CreativeRefs.price,
28031
28075
  offer: CreativeRefs.offer,
28032
28076
  productContext: CreativeRefs.productContext,
28033
28077
  productLabel: CreativeRefs.productLabel,
28034
- 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.'),
28035
- 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.'),
28078
+ cta: z112.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.'),
28079
+ scriptNotes: z112.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.'),
28036
28080
  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.'),
28037
28081
  competitorScanEnabled: CreativeRefs.competitorScanEnabled,
28038
- 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."),
28082
+ replicateWinnerWhenFound: z112.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."),
28039
28083
  brandId: CreativeRefs.brandId
28040
28084
  }).strict();
28041
28085
  var FreeVideoQualityEnum = VideoQualityEnum;
@@ -28053,7 +28097,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
28053
28097
  length: 29
28054
28098
  }, (_, index) => index + 2)
28055
28099
  };
28056
- var FreeVideoModelIdEnum = z111.enum([
28100
+ var FreeVideoModelIdEnum = z112.enum([
28057
28101
  "grok-imagine-video-1-5-preview",
28058
28102
  "minimax-h3/reference-to-video",
28059
28103
  "wan/3-0-video",
@@ -28064,66 +28108,66 @@ var FREE_SELECTABLE_MODEL_IDS = [
28064
28108
  "minimax-h3/reference-to-video",
28065
28109
  "wan/3-0-video"
28066
28110
  ];
28067
- var FreeVideoInput = z111.object({
28111
+ var FreeVideoInput = z112.object({
28068
28112
  images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
28069
- 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."),
28113
+ rawPrompt: z112.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."),
28070
28114
  language: CreativeRefs.language,
28071
28115
  quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
28072
28116
  // Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
28073
28117
  // parsed ONLY so the handler can reject it with a message naming its
28074
28118
  // replacement — dropping it silently would turn a caller's explicit
28075
28119
  // Pro++ pick into a quiet fallback to Wan.
28076
- freeProModel: z111.enum([
28120
+ freeProModel: z112.enum([
28077
28121
  "wan",
28078
28122
  "seedance"
28079
28123
  ]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
28080
28124
  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.'),
28081
- 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."),
28125
+ durationSeconds: z112.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."),
28082
28126
  videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
28083
- 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.'),
28127
+ generateAiMusic: z112.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.'),
28084
28128
  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.'),
28085
- addSubtitles: z111.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
28086
- 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.")
28129
+ addSubtitles: z112.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
28130
+ idempotencyKey: z112.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.")
28087
28131
  }).strict();
28088
28132
  var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
28089
- var ImageCreativeSetup = z111.discriminatedUnion("mode", [
28090
- z111.object({
28091
- mode: z111.literal("automatic")
28133
+ var ImageCreativeSetup = z112.discriminatedUnion("mode", [
28134
+ z112.object({
28135
+ mode: z112.literal("automatic")
28092
28136
  }).strict(),
28093
- z111.object({
28094
- mode: z111.literal("guided"),
28095
- creativeArchetype: z111.union([
28137
+ z112.object({
28138
+ mode: z112.literal("guided"),
28139
+ creativeArchetype: z112.union([
28096
28140
  ImageCreativeArchetypeEnum,
28097
- z111.literal("ai_decides")
28141
+ z112.literal("ai_decides")
28098
28142
  ]),
28099
- visualTreatment: z111.union([
28143
+ visualTreatment: z112.union([
28100
28144
  ImageCreativeVisualTreatmentEnum,
28101
- z111.literal("ai_decides")
28145
+ z112.literal("ai_decides")
28102
28146
  ]),
28103
28147
  aspectRatio: ImageCreativeAspectRatioEnum,
28104
- nVariants: z111.union([
28105
- z111.literal(1),
28106
- z111.literal(2),
28107
- z111.literal(3),
28108
- z111.literal(4),
28109
- z111.literal(6)
28148
+ nVariants: z112.union([
28149
+ z112.literal(1),
28150
+ z112.literal(2),
28151
+ z112.literal(3),
28152
+ z112.literal(4),
28153
+ z112.literal(6)
28110
28154
  ]),
28111
- 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.'),
28112
- 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."),
28113
- generateAdCopy: z111.boolean(),
28114
- competitorScanEnabled: z111.boolean(),
28115
- productContext: z111.string().trim().min(1).max(3e3).nullable(),
28116
- creativeDirection: z111.string().trim().min(1).max(500).nullable(),
28117
- 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.'),
28118
- headline: z111.string().trim().min(1).max(120).nullable(),
28119
- subheadline: z111.string().trim().min(1).max(160).nullable()
28155
+ imageModel: z112.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.'),
28156
+ styleMix: z112.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
28157
+ generateAdCopy: z112.boolean(),
28158
+ competitorScanEnabled: z112.boolean(),
28159
+ productContext: z112.string().trim().min(1).max(3e3).nullable(),
28160
+ creativeDirection: z112.string().trim().min(1).max(500).nullable(),
28161
+ brandColors: z112.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.'),
28162
+ headline: z112.string().trim().min(1).max(120).nullable(),
28163
+ subheadline: z112.string().trim().min(1).max(160).nullable()
28120
28164
  }).strict()
28121
28165
  ]).superRefine((setup, context) => {
28122
28166
  if (setup.mode !== "guided") return;
28123
28167
  const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
28124
28168
  if (needsStyleMix && setup.styleMix === null) {
28125
28169
  context.addIssue({
28126
- code: z111.ZodIssueCode.custom,
28170
+ code: z112.ZodIssueCode.custom,
28127
28171
  path: [
28128
28172
  "styleMix"
28129
28173
  ],
@@ -28132,7 +28176,7 @@ var ImageCreativeSetup = z111.discriminatedUnion("mode", [
28132
28176
  }
28133
28177
  if (!needsStyleMix && setup.styleMix !== null) {
28134
28178
  context.addIssue({
28135
- code: z111.ZodIssueCode.custom,
28179
+ code: z112.ZodIssueCode.custom,
28136
28180
  path: [
28137
28181
  "styleMix"
28138
28182
  ],
@@ -28141,7 +28185,7 @@ var ImageCreativeSetup = z111.discriminatedUnion("mode", [
28141
28185
  }
28142
28186
  if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
28143
28187
  context.addIssue({
28144
- code: z111.ZodIssueCode.custom,
28188
+ code: z112.ZodIssueCode.custom,
28145
28189
  path: [
28146
28190
  "aspectRatio"
28147
28191
  ],
@@ -28149,55 +28193,55 @@ var ImageCreativeSetup = z111.discriminatedUnion("mode", [
28149
28193
  });
28150
28194
  }
28151
28195
  });
28152
- var LandingCreativeSetup = z111.discriminatedUnion("mode", [
28153
- z111.object({
28154
- mode: z111.literal("automatic")
28196
+ var LandingCreativeSetup = z112.discriminatedUnion("mode", [
28197
+ z112.object({
28198
+ mode: z112.literal("automatic")
28155
28199
  }).strict(),
28156
- z111.object({
28157
- mode: z111.literal("guided"),
28200
+ z112.object({
28201
+ mode: z112.literal("guided"),
28158
28202
  landingStrategy: LandingStrategyEnum,
28159
28203
  landingImageFormat: LandingImageFormatEnum,
28160
- competitorScanEnabled: z111.boolean(),
28161
- paymentMethods: z111.string().trim().min(1).max(240).nullable(),
28162
- productContext: z111.string().trim().min(1).max(3e3).nullable(),
28163
- creativeDirection: z111.string().trim().min(1).max(500).nullable(),
28164
- headline: z111.string().trim().min(1).max(120).nullable(),
28165
- subheadline: z111.string().trim().min(1).max(160).nullable()
28204
+ competitorScanEnabled: z112.boolean(),
28205
+ paymentMethods: z112.string().trim().min(1).max(240).nullable(),
28206
+ productContext: z112.string().trim().min(1).max(3e3).nullable(),
28207
+ creativeDirection: z112.string().trim().min(1).max(500).nullable(),
28208
+ headline: z112.string().trim().min(1).max(120).nullable(),
28209
+ subheadline: z112.string().trim().min(1).max(160).nullable()
28166
28210
  }).strict()
28167
28211
  ]);
28168
- var ImageInput = z111.object({
28212
+ var ImageInput = z112.object({
28169
28213
  images: CreativeRefs.images.optional(),
28170
28214
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
28171
- productTitle: z111.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
28172
- 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.'),
28215
+ productTitle: z112.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
28216
+ primaryAngle: z112.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.'),
28173
28217
  buyerPersona: CreativeRefs.buyerPersona,
28174
28218
  language: CreativeRefs.language,
28175
28219
  country: CreativeRefs.country,
28176
28220
  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."),
28177
28221
  imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
28178
- features: z111.array(z111.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
28222
+ features: z112.array(z112.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
28179
28223
  price: CreativeRefs.price,
28180
- 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."),
28224
+ omitPrice: z112.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."),
28181
28225
  compareAtPrice: CreativeRefs.compareAtPrice,
28182
28226
  offer: CreativeRefs.offer,
28183
28227
  productLabel: CreativeRefs.productLabel,
28184
28228
  isCombo: CreativeRefs.isCombo,
28185
28229
  brandId: CreativeRefs.brandId
28186
28230
  });
28187
- var EditImageCreativeInput = z111.object({
28188
- taskId: z111.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
28189
- variantIndex: z111.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
28190
- 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."),
28191
- 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".')
28231
+ var EditImageCreativeInput = z112.object({
28232
+ taskId: z112.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
28233
+ variantIndex: z112.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
28234
+ clientRequestId: z112.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."),
28235
+ instruction: z112.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".')
28192
28236
  });
28193
- var LandingInput = z111.object({
28194
- 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."),
28237
+ var LandingInput = z112.object({
28238
+ includeInitialLandingGif: z112.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."),
28195
28239
  images: CreativeRefs.images.optional(),
28196
28240
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
28197
28241
  language: CreativeRefs.language,
28198
28242
  country: CreativeRefs.country,
28199
28243
  creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
28200
- 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.'),
28244
+ salesAngle: z112.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.'),
28201
28245
  buyerPersona: CreativeRefs.buyerPersona,
28202
28246
  price: CreativeRefs.price,
28203
28247
  compareAtPrice: CreativeRefs.compareAtPrice,
@@ -28479,8 +28523,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
28479
28523
  server.registerTool("get_image_edit_status", {
28480
28524
  description: imageEditStatusGuidance.summary,
28481
28525
  inputSchema: {
28482
- taskId: z111.string().uuid(),
28483
- operationId: z111.string().uuid()
28526
+ taskId: z112.string().uuid(),
28527
+ operationId: z112.string().uuid()
28484
28528
  },
28485
28529
  annotations: READS_INTERNAL
28486
28530
  }, async (input) => {
@@ -28537,10 +28581,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
28537
28581
  __name(registerCreativeTools, "registerCreativeTools");
28538
28582
 
28539
28583
  // src/tools/creative-variants.ts
28540
- import { z as z112 } from "zod";
28584
+ import { z as z113 } from "zod";
28541
28585
  var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
28542
28586
  var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
28543
- var LandingSectionKeyEnum = z112.enum([
28587
+ var LandingSectionKeyEnum = z113.enum([
28544
28588
  "problem_hook",
28545
28589
  "problem_cost",
28546
28590
  "solution_mechanism",
@@ -28580,24 +28624,24 @@ var LandingSectionKeyEnum = z112.enum([
28580
28624
  "lifestyle_fit",
28581
28625
  "join_lifestyle"
28582
28626
  ]);
28583
- var CreativeVariantKindEnum = z112.enum([
28627
+ var CreativeVariantKindEnum = z113.enum([
28584
28628
  "video",
28585
28629
  "image",
28586
28630
  "landing"
28587
28631
  ]);
28588
- var EstimateCreativeVariantInputBase = z112.object({
28589
- sourceTaskId: z112.string().uuid().describe("ID de la tarea original completada."),
28632
+ var EstimateCreativeVariantInputBase = z113.object({
28633
+ sourceTaskId: z113.string().uuid().describe("ID de la tarea original completada."),
28590
28634
  kind: CreativeVariantKindEnum,
28591
28635
  videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
28592
28636
  videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
28593
- nVariants: z112.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
28637
+ nVariants: z113.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
28594
28638
  sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
28595
- 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.")
28639
+ instructions: z113.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.")
28596
28640
  }).strict();
28597
28641
  var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
28598
28642
  if (input.kind === "video" && input.nVariants !== void 0) {
28599
28643
  ctx.addIssue({
28600
- code: z112.ZodIssueCode.custom,
28644
+ code: z113.ZodIssueCode.custom,
28601
28645
  path: [
28602
28646
  "nVariants"
28603
28647
  ],
@@ -28607,7 +28651,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
28607
28651
  if (input.kind !== "video") {
28608
28652
  if (input.videoPreset !== void 0) {
28609
28653
  ctx.addIssue({
28610
- code: z112.ZodIssueCode.custom,
28654
+ code: z113.ZodIssueCode.custom,
28611
28655
  path: [
28612
28656
  "videoPreset"
28613
28657
  ],
@@ -28616,7 +28660,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
28616
28660
  }
28617
28661
  if (input.videoResolution !== void 0) {
28618
28662
  ctx.addIssue({
28619
- code: z112.ZodIssueCode.custom,
28663
+ code: z113.ZodIssueCode.custom,
28620
28664
  path: [
28621
28665
  "videoResolution"
28622
28666
  ],
@@ -28626,7 +28670,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
28626
28670
  }
28627
28671
  if (input.kind !== "image" && input.nVariants !== void 0) {
28628
28672
  ctx.addIssue({
28629
- code: z112.ZodIssueCode.custom,
28673
+ code: z113.ZodIssueCode.custom,
28630
28674
  path: [
28631
28675
  "nVariants"
28632
28676
  ],
@@ -28636,7 +28680,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
28636
28680
  if (input.kind !== "landing") {
28637
28681
  if (input.sectionKey !== void 0) {
28638
28682
  ctx.addIssue({
28639
- code: z112.ZodIssueCode.custom,
28683
+ code: z113.ZodIssueCode.custom,
28640
28684
  path: [
28641
28685
  "sectionKey"
28642
28686
  ],
@@ -28645,7 +28689,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
28645
28689
  }
28646
28690
  if (input.instructions !== void 0) {
28647
28691
  ctx.addIssue({
28648
- code: z112.ZodIssueCode.custom,
28692
+ code: z113.ZodIssueCode.custom,
28649
28693
  path: [
28650
28694
  "instructions"
28651
28695
  ],
@@ -28654,31 +28698,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
28654
28698
  }
28655
28699
  }
28656
28700
  });
28657
- var CreateCreativeVariantInputBase = z112.object({
28658
- sourceTaskId: z112.string().uuid().describe("ID de la tarea original completada."),
28701
+ var CreateCreativeVariantInputBase = z113.object({
28702
+ sourceTaskId: z113.string().uuid().describe("ID de la tarea original completada."),
28659
28703
  kind: CreativeVariantKindEnum,
28660
- confirm: z112.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
28661
- 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."),
28662
- angle: z112.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
28663
- buyerPersona: z112.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
28664
- scriptNotes: z112.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
28665
- creativeDirection: z112.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
28704
+ confirm: z113.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
28705
+ clientRequestId: z113.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."),
28706
+ angle: z113.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
28707
+ buyerPersona: z113.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
28708
+ scriptNotes: z113.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
28709
+ creativeDirection: z113.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
28666
28710
  videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
28667
28711
  videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
28668
- generateAiMusic: z112.boolean().optional().describe("Opcional para video."),
28669
- nVariants: z112.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
28712
+ generateAiMusic: z113.boolean().optional().describe("Opcional para video."),
28713
+ nVariants: z113.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
28670
28714
  imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
28671
28715
  creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
28672
28716
  visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
28673
28717
  aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
28674
- styleMix: z112.boolean().optional().describe("Opcional para imagen."),
28718
+ styleMix: z113.boolean().optional().describe("Opcional para imagen."),
28675
28719
  sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
28676
- 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.")
28720
+ instructions: z113.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.")
28677
28721
  }).strict();
28678
28722
  var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
28679
28723
  if ((input.kind === "video" || input.kind === "image") && !input.angle) {
28680
28724
  ctx.addIssue({
28681
- code: z112.ZodIssueCode.custom,
28725
+ code: z113.ZodIssueCode.custom,
28682
28726
  path: [
28683
28727
  "angle"
28684
28728
  ],
@@ -28687,7 +28731,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
28687
28731
  }
28688
28732
  if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
28689
28733
  ctx.addIssue({
28690
- code: z112.ZodIssueCode.custom,
28734
+ code: z113.ZodIssueCode.custom,
28691
28735
  path: [
28692
28736
  "instructions"
28693
28737
  ],
@@ -28733,7 +28777,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
28733
28777
  for (const field of fieldsByKind[input.kind]) {
28734
28778
  if (input[field] !== void 0) {
28735
28779
  ctx.addIssue({
28736
- code: z112.ZodIssueCode.custom,
28780
+ code: z113.ZodIssueCode.custom,
28737
28781
  path: [
28738
28782
  field
28739
28783
  ],
@@ -28866,13 +28910,13 @@ function registerCreativeVariantTools(server, api) {
28866
28910
  __name(registerCreativeVariantTools, "registerCreativeVariantTools");
28867
28911
 
28868
28912
  // src/tools/script-review.ts
28869
- import { z as z113 } from "zod";
28913
+ import { z as z114 } from "zod";
28870
28914
  var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
28871
28915
  var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
28872
28916
  var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
28873
- var GetVideoScriptInput = z113.object({
28874
- taskId: z113.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
28875
- 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.')
28917
+ var GetVideoScriptInput = z114.object({
28918
+ taskId: z114.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
28919
+ angleKey: z114.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.')
28876
28920
  }).strict();
28877
28921
  var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
28878
28922
  var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
@@ -28955,7 +28999,7 @@ function registerScriptReviewTools(server, api) {
28955
28999
  __name(registerScriptReviewTools, "registerScriptReviewTools");
28956
29000
 
28957
29001
  // src/tools/connections.ts
28958
- import { z as z114 } from "zod";
29002
+ import { z as z115 } from "zod";
28959
29003
  var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
28960
29004
  var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
28961
29005
  var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
@@ -28964,7 +29008,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
28964
29008
  function registerConnectionTools(server, api) {
28965
29009
  server.registerTool("list_shopify_shops", {
28966
29010
  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.",
28967
- inputSchema: z114.object({}).shape,
29011
+ inputSchema: z115.object({}).shape,
28968
29012
  annotations: READS_INTERNAL
28969
29013
  }, async () => {
28970
29014
  try {
@@ -28976,10 +29020,10 @@ function registerConnectionTools(server, api) {
28976
29020
  });
28977
29021
  server.registerTool("list_shopify_products", {
28978
29022
  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.',
28979
- inputSchema: z114.object({
28980
- shopDomain: z114.string().min(3).max(120),
28981
- query: z114.string().trim().max(120).optional(),
28982
- taskId: z114.string().uuid().optional()
29023
+ inputSchema: z115.object({
29024
+ shopDomain: z115.string().min(3).max(120),
29025
+ query: z115.string().trim().max(120).optional(),
29026
+ taskId: z115.string().uuid().optional()
28983
29027
  }).shape,
28984
29028
  annotations: READS_EXTERNAL
28985
29029
  }, async ({ shopDomain, query, taskId }) => {
@@ -28997,7 +29041,7 @@ function registerConnectionTools(server, api) {
28997
29041
  });
28998
29042
  server.registerTool("list_meta_ad_accounts", {
28999
29043
  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.",
29000
- inputSchema: z114.object({}).shape,
29044
+ inputSchema: z115.object({}).shape,
29001
29045
  annotations: READS_EXTERNAL
29002
29046
  }, async () => {
29003
29047
  try {
@@ -29009,7 +29053,7 @@ function registerConnectionTools(server, api) {
29009
29053
  });
29010
29054
  server.registerTool("list_meta_destinations", {
29011
29055
  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.",
29012
- inputSchema: z114.object({}).shape,
29056
+ inputSchema: z115.object({}).shape,
29013
29057
  annotations: READS_EXTERNAL,
29014
29058
  _meta: {
29015
29059
  "openai/widgetAccessible": true
@@ -29024,7 +29068,7 @@ function registerConnectionTools(server, api) {
29024
29068
  });
29025
29069
  server.registerTool("list_tiktok_advertisers", {
29026
29070
  description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
29027
- inputSchema: z114.object({}).shape,
29071
+ inputSchema: z115.object({}).shape,
29028
29072
  annotations: READS_EXTERNAL
29029
29073
  }, async () => {
29030
29074
  try {
@@ -29038,7 +29082,7 @@ function registerConnectionTools(server, api) {
29038
29082
  __name(registerConnectionTools, "registerConnectionTools");
29039
29083
 
29040
29084
  // src/tools/actors.ts
29041
- import { z as z115 } from "zod";
29085
+ import { z as z116 } from "zod";
29042
29086
  var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
29043
29087
  var actorVoiceGuidance = {
29044
29088
  capabilities: getProductMakerCapabilityModelGuidance("get_actor_voice_capabilities"),
@@ -29078,7 +29122,7 @@ function sanitizeVoiceResult(value) {
29078
29122
  __name(sanitizeVoiceResult, "sanitizeVoiceResult");
29079
29123
  function registerActorTools(server, api) {
29080
29124
  const actor = {
29081
- actorId: z115.string().min(1).max(64)
29125
+ actorId: z116.string().min(1).max(64)
29082
29126
  };
29083
29127
  const safe = /* @__PURE__ */ __name(async (request) => {
29084
29128
  try {
@@ -29107,8 +29151,8 @@ function registerActorTools(server, api) {
29107
29151
  inputSchema: {
29108
29152
  ...actor,
29109
29153
  draft: ActorVoiceDraftSchema,
29110
- requestKey: z115.string().trim().min(1).max(128),
29111
- acceptedQuoteId: z115.string().trim().min(1).max(128)
29154
+ requestKey: z116.string().trim().min(1).max(128),
29155
+ acceptedQuoteId: z116.string().trim().min(1).max(128)
29112
29156
  },
29113
29157
  annotations: CREATES_PAID
29114
29158
  }, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews`, body)));
@@ -29116,7 +29160,7 @@ function registerActorTools(server, api) {
29116
29160
  description: actorVoiceGuidance.get.summary,
29117
29161
  inputSchema: {
29118
29162
  ...actor,
29119
- candidateId: z115.string().min(1).max(64)
29163
+ candidateId: z116.string().min(1).max(64)
29120
29164
  },
29121
29165
  annotations: READS_INTERNAL
29122
29166
  }, async ({ actorId, candidateId }) => safe(api.getJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews/${encodeURIComponent(candidateId)}`)));
@@ -29124,15 +29168,15 @@ function registerActorTools(server, api) {
29124
29168
  description: actorVoiceGuidance.approve.summary,
29125
29169
  inputSchema: {
29126
29170
  ...actor,
29127
- candidateId: z115.string().min(1).max(64),
29128
- expectedRevision: z115.number().int().positive(),
29129
- expectedApprovedRevision: z115.number().int().positive().nullable().optional()
29171
+ candidateId: z116.string().min(1).max(64),
29172
+ expectedRevision: z116.number().int().positive(),
29173
+ expectedApprovedRevision: z116.number().int().positive().nullable().optional()
29130
29174
  },
29131
29175
  annotations: CREATES_INTERNAL
29132
29176
  }, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/approve`, body)));
29133
29177
  server.registerTool("list_actors", {
29134
29178
  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.",
29135
- inputSchema: z115.object({}).shape,
29179
+ inputSchema: z116.object({}).shape,
29136
29180
  annotations: READS_INTERNAL
29137
29181
  }, async () => {
29138
29182
  try {
@@ -29165,7 +29209,7 @@ function registerActorTools(server, api) {
29165
29209
  __name(registerActorTools, "registerActorTools");
29166
29210
 
29167
29211
  // src/tools/publish.ts
29168
- import { z as z116 } from "zod";
29212
+ import { z as z117 } from "zod";
29169
29213
 
29170
29214
  // src/tools/meta-publish-attempt-id.ts
29171
29215
  var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
@@ -29204,40 +29248,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
29204
29248
  var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
29205
29249
  var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
29206
29250
  var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
29207
- var ShopifyInput = z116.object({
29208
- taskId: z116.string().min(1),
29209
- shopDomain: z116.string().min(1),
29251
+ var ShopifyInput = z117.object({
29252
+ taskId: z117.string().min(1),
29253
+ shopDomain: z117.string().min(1),
29210
29254
  /** Override: number of landing images to include. Default = ALL images the
29211
29255
  * task generated (the MCP fetches /v1/results first to count). Bounded
29212
29256
  * generously here; the backend validates each index against
29213
29257
  * landing.images.length and rejects out-of-range. */
29214
- numLandingImages: z116.number().int().min(1).max(20).optional(),
29215
- variantIndex: z116.number().int().min(0).optional(),
29258
+ numLandingImages: z117.number().int().min(1).max(20).optional(),
29259
+ variantIndex: z117.number().int().min(0).optional(),
29216
29260
  /** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
29217
29261
  * When true, the landing renders variant-picker pills; when false, it ships
29218
29262
  * a single-option product page. Defaults to false. */
29219
- showVariantPicker: z116.boolean().optional(),
29263
+ showVariantPicker: z117.boolean().optional(),
29220
29264
  /** Default `auto` updates the product previously published for this task and
29221
29265
  * shop. Use `existing` with targetProductId to choose another product, or
29222
29266
  * `new` only when the user explicitly wants a duplicate/new listing. */
29223
- publicationMode: z116.enum([
29267
+ publicationMode: z117.enum([
29224
29268
  "auto",
29225
29269
  "existing",
29226
29270
  "new"
29227
29271
  ]).optional(),
29228
29272
  /** Shopify product GID, numeric id, or admin product URL. Required when
29229
29273
  * publicationMode is `existing`. */
29230
- targetProductId: z116.string().trim().min(1).max(300).optional(),
29274
+ targetProductId: z117.string().trim().min(1).max(300).optional(),
29231
29275
  /** Add an announcement bar text above add-to-cart (optional). */
29232
- announcementBarEnabled: z116.boolean().optional(),
29233
- announcementBarText: z116.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
29276
+ announcementBarEnabled: z117.boolean().optional(),
29277
+ announcementBarText: z117.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
29234
29278
  commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
29235
- confirmed: z116.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
29279
+ confirmed: z117.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
29236
29280
  });
29237
29281
  var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
29238
29282
  if (value.commerceCorrection && value.confirmed !== true) {
29239
29283
  ctx.addIssue({
29240
- code: z116.ZodIssueCode.custom,
29284
+ code: z117.ZodIssueCode.custom,
29241
29285
  path: [
29242
29286
  "confirmed"
29243
29287
  ],
@@ -29246,7 +29290,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
29246
29290
  }
29247
29291
  if (value.announcementBarEnabled && !value.announcementBarText) {
29248
29292
  ctx.addIssue({
29249
- code: z116.ZodIssueCode.custom,
29293
+ code: z117.ZodIssueCode.custom,
29250
29294
  path: [
29251
29295
  "announcementBarText"
29252
29296
  ],
@@ -29255,7 +29299,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
29255
29299
  }
29256
29300
  if (!value.announcementBarEnabled && value.announcementBarText) {
29257
29301
  ctx.addIssue({
29258
- code: z116.ZodIssueCode.custom,
29302
+ code: z117.ZodIssueCode.custom,
29259
29303
  path: [
29260
29304
  "announcementBarText"
29261
29305
  ],
@@ -29269,91 +29313,91 @@ function parseShopifyInput(rawInput) {
29269
29313
  return parsed.data;
29270
29314
  }
29271
29315
  __name(parseShopifyInput, "parseShopifyInput");
29272
- var McpCampaignConfig = z116.object({
29316
+ var McpCampaignConfig = z117.object({
29273
29317
  /** ALWAYS in US dollars, whatever the ad account's currency is. ProductMaker
29274
29318
  * converts to the account currency server-side. Do NOT pre-convert: on a COP
29275
29319
  * account the user's "60.000 al día" is `dailyBudgetUsd: 15`, not 60000. */
29276
- dailyBudgetUsd: z116.number().positive().optional(),
29320
+ dailyBudgetUsd: z117.number().positive().optional(),
29277
29321
  /** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
29278
29322
  * normalizes at validation). Meta accepts max 1 (single-country ad set).
29279
29323
  * TikTok takes only the first entry. */
29280
- targetCountries: z116.array(CountryIso2Schema).max(1).optional(),
29281
- campaignName: z116.string().trim().min(1).max(100).optional()
29324
+ targetCountries: z117.array(CountryIso2Schema).max(1).optional(),
29325
+ campaignName: z117.string().trim().min(1).max(100).optional()
29282
29326
  });
29283
29327
  var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
29284
- var MetaInput = z116.object({
29285
- taskId: z116.string().min(1),
29328
+ var MetaInput = z117.object({
29329
+ taskId: z117.string().min(1),
29286
29330
  /** Exact Meta Business portfolio selected from `list_meta_destinations`. */
29287
- portfolioId: z116.string().trim().min(1),
29331
+ portfolioId: z117.string().trim().min(1),
29288
29332
  /** Exact Facebook Page selected from `list_meta_destinations`. */
29289
- pageId: z116.string().trim().min(1),
29333
+ pageId: z117.string().trim().min(1),
29290
29334
  adAccountId: McpAdAccountId,
29291
- pixelId: z116.string().min(1).optional(),
29292
- landingUrl: z116.string().url().optional(),
29335
+ pixelId: z117.string().min(1).optional(),
29336
+ landingUrl: z117.string().url().optional(),
29293
29337
  /** Select which angles to publish by 0-based index. Omit to publish all
29294
29338
  * successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
29295
- angleIndexes: z116.array(z116.number().int().nonnegative()).optional(),
29339
+ angleIndexes: z117.array(z117.number().int().nonnegative()).optional(),
29296
29340
  campaignConfig: McpCampaignConfig.optional(),
29297
29341
  /** Override the ad's primary text (body copy). If omitted, ProductMaker
29298
29342
  * uses the auto-generated copy attached to the task. Capped at 500 chars
29299
29343
  * (Meta's primary-text limit). */
29300
- primaryText: z116.string().trim().min(1).max(500).optional(),
29344
+ primaryText: z117.string().trim().min(1).max(500).optional(),
29301
29345
  /** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
29302
29346
  * (wa.me) instead of a landing page. */
29303
- phoneNumber: z116.string().min(8).max(32).optional()
29347
+ phoneNumber: z117.string().min(8).max(32).optional()
29304
29348
  });
29305
- var GroupedTaskSource = z116.object({
29306
- type: z116.literal("task"),
29307
- taskId: z116.string().min(1),
29308
- angleIndex: z116.number().int().min(0).optional(),
29309
- videoVariant: z116.enum([
29349
+ var GroupedTaskSource = z117.object({
29350
+ type: z117.literal("task"),
29351
+ taskId: z117.string().min(1),
29352
+ angleIndex: z117.number().int().min(0).optional(),
29353
+ videoVariant: z117.enum([
29310
29354
  "with_subtitles",
29311
29355
  "without_subtitles"
29312
29356
  ]).optional(),
29313
- imageVariantIndex: z116.number().int().min(0).optional()
29314
- });
29315
- var GroupedMediaSource = z116.object({
29316
- type: z116.literal("media"),
29317
- 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."),
29318
- 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".'),
29319
- thumbnailUrl: z116.string().url().optional(),
29320
- thumbnailPath: z116.string().min(1).optional()
29357
+ imageVariantIndex: z117.number().int().min(0).optional()
29358
+ });
29359
+ var GroupedMediaSource = z117.object({
29360
+ type: z117.literal("media"),
29361
+ url: z117.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
29362
+ path: z117.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".'),
29363
+ thumbnailUrl: z117.string().url().optional(),
29364
+ thumbnailPath: z117.string().min(1).optional()
29321
29365
  }).refine((value) => Boolean(value.url) !== Boolean(value.path), {
29322
29366
  message: "media source needs exactly one of `url` or `path`"
29323
29367
  }).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
29324
29368
  message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
29325
29369
  });
29326
- var GroupedUploadedAssetSource = z116.object({
29327
- type: z116.literal("asset"),
29370
+ var GroupedUploadedAssetSource = z117.object({
29371
+ type: z117.literal("asset"),
29328
29372
  /** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
29329
- assetId: z116.string().uuid(),
29330
- thumbnailAssetId: z116.string().uuid().optional()
29373
+ assetId: z117.string().uuid(),
29374
+ thumbnailAssetId: z117.string().uuid().optional()
29331
29375
  });
29332
- var GroupedCreative = z116.object({
29333
- type: z116.enum([
29376
+ var GroupedCreative = z117.object({
29377
+ type: z117.enum([
29334
29378
  "image",
29335
29379
  "video"
29336
29380
  ]),
29337
- source: z116.union([
29381
+ source: z117.union([
29338
29382
  GroupedTaskSource,
29339
29383
  GroupedMediaSource,
29340
29384
  GroupedUploadedAssetSource
29341
29385
  ]),
29342
- title: z116.string().max(120).optional(),
29343
- description: z116.string().max(500).optional(),
29386
+ title: z117.string().max(120).optional(),
29387
+ description: z117.string().max(500).optional(),
29344
29388
  cta: MetaCtaType.optional(),
29345
- creativeId: z116.string().min(1).optional()
29389
+ creativeId: z117.string().min(1).optional()
29346
29390
  });
29347
- var GroupedCampaignConfigBase = z116.object({
29391
+ var GroupedCampaignConfigBase = z117.object({
29348
29392
  campaignType: MetaCampaignType.default("sales"),
29349
29393
  optimizationMode: MetaOptimizationMode.default("advantage_plus"),
29350
29394
  budgetMode: MetaBudgetMode.optional(),
29351
- campaignDailyBudget: z116.number().int().positive().optional(),
29352
- adSets: z116.array(z116.object({
29353
- tempId: z116.string().min(1).max(80),
29354
- name: z116.string().min(1).max(100),
29355
- dailyBudget: z116.number().int().positive().optional(),
29356
- creativeIds: z116.array(z116.string().min(1)).min(1)
29395
+ campaignDailyBudget: z117.number().int().positive().optional(),
29396
+ adSets: z117.array(z117.object({
29397
+ tempId: z117.string().min(1).max(80),
29398
+ name: z117.string().min(1).max(100),
29399
+ dailyBudget: z117.number().int().positive().optional(),
29400
+ creativeIds: z117.array(z117.string().min(1)).min(1)
29357
29401
  })).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
29358
29402
  /**
29359
29403
  * Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
@@ -29361,17 +29405,17 @@ var GroupedCampaignConfigBase = z116.object({
29361
29405
  * opaque `invalid_literal` and made the WhatsApp destination — supported by
29362
29406
  * the API since #849 — unreachable from this tool.
29363
29407
  */
29364
- destination: z116.discriminatedUnion("type", [
29365
- z116.object({
29366
- type: z116.literal("landing"),
29367
- landingUrl: z116.string().url()
29408
+ destination: z117.discriminatedUnion("type", [
29409
+ z117.object({
29410
+ type: z117.literal("landing"),
29411
+ landingUrl: z117.string().url()
29368
29412
  }),
29369
- z116.object({
29370
- type: z116.literal("whatsapp"),
29371
- phoneNumber: z116.string().min(8).max(32)
29413
+ z117.object({
29414
+ type: z117.literal("whatsapp"),
29415
+ phoneNumber: z117.string().min(8).max(32)
29372
29416
  })
29373
29417
  ]),
29374
- saveAsDefault: z116.boolean().default(false),
29418
+ saveAsDefault: z117.boolean().default(false),
29375
29419
  budgetPolicy: MetaBudgetPolicy.optional()
29376
29420
  });
29377
29421
  function resolveBudgetMode(value) {
@@ -29385,7 +29429,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
29385
29429
  const budgetMode = resolveBudgetMode(value);
29386
29430
  if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
29387
29431
  ctx.addIssue({
29388
- code: z116.ZodIssueCode.custom,
29432
+ code: z117.ZodIssueCode.custom,
29389
29433
  path: [
29390
29434
  "campaignDailyBudget"
29391
29435
  ],
@@ -29396,7 +29440,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
29396
29440
  value.adSets.forEach((adSet, index) => {
29397
29441
  if (adSet.dailyBudget === void 0) {
29398
29442
  ctx.addIssue({
29399
- code: z116.ZodIssueCode.custom,
29443
+ code: z117.ZodIssueCode.custom,
29400
29444
  path: [
29401
29445
  "adSets",
29402
29446
  index,
@@ -29411,28 +29455,28 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
29411
29455
  ...value,
29412
29456
  budgetMode: resolveBudgetMode(value)
29413
29457
  }));
29414
- var PublishCreativesToMetaInputBase = z116.object({
29415
- creatives: z116.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
29458
+ var PublishCreativesToMetaInputBase = z117.object({
29459
+ creatives: z117.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
29416
29460
  /** Exact Meta Business portfolio selected from `list_meta_destinations`. */
29417
- portfolioId: z116.string().trim().min(1),
29461
+ portfolioId: z117.string().trim().min(1),
29418
29462
  /** Exact Facebook Page selected from `list_meta_destinations`. */
29419
- pageId: z116.string().trim().min(1),
29463
+ pageId: z117.string().trim().min(1),
29420
29464
  adAccountId: McpAdAccountId,
29421
- pixelId: z116.string().min(1).optional(),
29465
+ pixelId: z117.string().min(1).optional(),
29422
29466
  /** Required unless `campaignConfig.destination` is whatsapp — see the
29423
29467
  * superRefine below. Mirrors the API's `FacebookCreateCampaignFromTasksBodySchema`. */
29424
- landingUrl: z116.string().url().optional(),
29468
+ landingUrl: z117.string().url().optional(),
29425
29469
  /** ISO-2 code or resolvable country name — mirrors the API contract
29426
29470
  * (CountryIso2Schema), which normalizes names to alpha-2 at validation. */
29427
29471
  targetCountry: CountryIso2Schema,
29428
- campaignName: z116.string().trim().min(1).max(100),
29472
+ campaignName: z117.string().trim().min(1).max(100),
29429
29473
  campaignConfig: GroupedCampaignConfig.optional()
29430
29474
  });
29431
29475
  var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
29432
29476
  const destination = value.campaignConfig?.destination;
29433
29477
  if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl) {
29434
29478
  ctx.addIssue({
29435
- code: z116.ZodIssueCode.custom,
29479
+ code: z117.ZodIssueCode.custom,
29436
29480
  path: [
29437
29481
  "landingUrl"
29438
29482
  ],
@@ -29441,7 +29485,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
29441
29485
  }
29442
29486
  if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
29443
29487
  ctx.addIssue({
29444
- code: z116.ZodIssueCode.custom,
29488
+ code: z117.ZodIssueCode.custom,
29445
29489
  path: [
29446
29490
  "campaignConfig",
29447
29491
  "destination",
@@ -29460,16 +29504,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
29460
29504
  }
29461
29505
  return value;
29462
29506
  });
29463
- var PresignUploadResponseSchema = z116.object({
29464
- uploadUrl: z116.string().url().refine((value) => {
29507
+ var PresignUploadResponseSchema = z117.object({
29508
+ uploadUrl: z117.string().url().refine((value) => {
29465
29509
  const url = new URL(value);
29466
29510
  return !url.username && !url.password && url.protocol === "https:";
29467
29511
  }, "presigned upload URL must be HTTPS without embedded credentials"),
29468
- publicUrl: z116.string().url().refine((value) => {
29512
+ publicUrl: z117.string().url().refine((value) => {
29469
29513
  const url = new URL(value);
29470
29514
  return !url.username && !url.password;
29471
29515
  }, "public media URL must not contain embedded credentials"),
29472
- stagingAssetId: z116.string().uuid()
29516
+ stagingAssetId: z117.string().uuid()
29473
29517
  });
29474
29518
  async function uploadResolvedMedia(api, media, assetRole) {
29475
29519
  if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
@@ -29494,16 +29538,16 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
29494
29538
  return uploadResolvedMedia(api, media, assetRole);
29495
29539
  }
29496
29540
  __name(resolveAndUploadMedia, "resolveAndUploadMedia");
29497
- var TikTokInput = z116.object({
29498
- taskId: z116.string().min(1),
29499
- advertiserId: z116.string().min(1),
29500
- pixelId: z116.string().min(1).optional(),
29501
- landingUrl: z116.string().url().optional(),
29502
- angleIndexes: z116.array(z116.number().int().nonnegative()).optional(),
29541
+ var TikTokInput = z117.object({
29542
+ taskId: z117.string().min(1),
29543
+ advertiserId: z117.string().min(1),
29544
+ pixelId: z117.string().min(1).optional(),
29545
+ landingUrl: z117.string().url().optional(),
29546
+ angleIndexes: z117.array(z117.number().int().nonnegative()).optional(),
29503
29547
  campaignConfig: McpCampaignConfig.optional(),
29504
29548
  /** Override the ad's description (TikTok's body copy). If omitted,
29505
29549
  * ProductMaker uses the auto-generated copy attached to the task. */
29506
- primaryText: z116.string().trim().min(1).max(500).optional()
29550
+ primaryText: z117.string().trim().min(1).max(500).optional()
29507
29551
  });
29508
29552
  function registerPublishTools(server, api, opts = {}) {
29509
29553
  const transport = opts.transport ?? "http";
@@ -29855,39 +29899,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
29855
29899
 
29856
29900
  // src/tools/meta-upload.ts
29857
29901
  import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
29858
- import { z as z117 } from "zod";
29902
+ import { z as z118 } from "zod";
29859
29903
  var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
29860
- var UploadSessionInputBase = z117.object({
29861
- mediaKind: z117.enum([
29904
+ var UploadSessionInputBase = z118.object({
29905
+ mediaKind: z118.enum([
29862
29906
  "image",
29863
29907
  "video",
29864
29908
  "mixed"
29865
29909
  ]).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."),
29866
- assetRole: z117.enum([
29910
+ assetRole: z118.enum([
29867
29911
  "media",
29868
29912
  "thumbnail"
29869
29913
  ]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
29870
- uploadPurpose: z117.enum([
29914
+ uploadPurpose: z118.enum([
29871
29915
  "product_reference",
29872
29916
  "creative",
29873
29917
  "generic"
29874
29918
  ]).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."),
29875
- maxFiles: z117.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
29919
+ maxFiles: z118.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
29876
29920
  });
29877
- var OpenAiFileReference = z117.object({
29878
- 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."),
29879
- file_id: z117.string().min(1),
29880
- mime_type: z117.string().min(1).optional(),
29881
- file_name: z117.string().min(1).optional()
29921
+ var OpenAiFileReference = z118.object({
29922
+ download_url: z118.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."),
29923
+ file_id: z118.string().min(1),
29924
+ mime_type: z118.string().min(1).optional(),
29925
+ file_name: z118.string().min(1).optional()
29882
29926
  });
29883
29927
  var UploadSessionToolInputShape = {
29884
29928
  ...UploadSessionInputBase.shape,
29885
- 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.")
29929
+ files: z118.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.")
29886
29930
  };
29887
- var UploadSessionToolInput = z117.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
29931
+ var UploadSessionToolInput = z118.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
29888
29932
  if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
29889
29933
  ctx.addIssue({
29890
- code: z117.ZodIssueCode.custom,
29934
+ code: z118.ZodIssueCode.custom,
29891
29935
  path: [
29892
29936
  "mediaKind"
29893
29937
  ],
@@ -29896,7 +29940,7 @@ var UploadSessionToolInput = z117.object(UploadSessionToolInputShape).superRefin
29896
29940
  }
29897
29941
  if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
29898
29942
  ctx.addIssue({
29899
- code: z117.ZodIssueCode.custom,
29943
+ code: z118.ZodIssueCode.custom,
29900
29944
  path: [
29901
29945
  "maxFiles"
29902
29946
  ],
@@ -29905,7 +29949,7 @@ var UploadSessionToolInput = z117.object(UploadSessionToolInputShape).superRefin
29905
29949
  }
29906
29950
  if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
29907
29951
  ctx.addIssue({
29908
- code: z117.ZodIssueCode.custom,
29952
+ code: z118.ZodIssueCode.custom,
29909
29953
  path: [
29910
29954
  "maxFiles"
29911
29955
  ],
@@ -29913,38 +29957,38 @@ var UploadSessionToolInput = z117.object(UploadSessionToolInputShape).superRefin
29913
29957
  });
29914
29958
  }
29915
29959
  });
29916
- var UploadSessionResponse = z117.object({
29917
- sessionId: z117.string().uuid(),
29918
- uploadPageUrl: z117.string().url(),
29919
- mediaKind: z117.enum([
29960
+ var UploadSessionResponse = z118.object({
29961
+ sessionId: z118.string().uuid(),
29962
+ uploadPageUrl: z118.string().url(),
29963
+ mediaKind: z118.enum([
29920
29964
  "image",
29921
29965
  "video",
29922
29966
  "mixed"
29923
29967
  ]),
29924
- assetRole: z117.enum([
29968
+ assetRole: z118.enum([
29925
29969
  "media",
29926
29970
  "thumbnail"
29927
29971
  ]),
29928
- maxFiles: z117.number().int().positive(),
29929
- expiresAt: z117.string().datetime()
29972
+ maxFiles: z118.number().int().positive(),
29973
+ expiresAt: z118.string().datetime()
29930
29974
  });
29931
- var UploadStatusInput = z117.object({
29932
- sessionId: z117.string().uuid().describe("The sessionId returned by request_media_upload.")
29975
+ var UploadStatusInput = z118.object({
29976
+ sessionId: z118.string().uuid().describe("The sessionId returned by request_media_upload.")
29933
29977
  });
29934
- var UniversalUploadStatusResponse = z117.discriminatedUnion("status", [
29935
- z117.object({
29936
- status: z117.literal("pending"),
29937
- assets: z117.array(z117.never()).length(0)
29978
+ var UniversalUploadStatusResponse = z118.discriminatedUnion("status", [
29979
+ z118.object({
29980
+ status: z118.literal("pending"),
29981
+ assets: z118.array(z118.never()).length(0)
29938
29982
  }),
29939
- z117.object({
29940
- status: z117.literal("uploaded"),
29941
- assets: z117.array(z117.object({
29942
- assetId: z117.string().uuid(),
29943
- mediaKind: z117.enum([
29983
+ z118.object({
29984
+ status: z118.literal("uploaded"),
29985
+ assets: z118.array(z118.object({
29986
+ assetId: z118.string().uuid(),
29987
+ mediaKind: z118.enum([
29944
29988
  "image",
29945
29989
  "video"
29946
29990
  ]),
29947
- assetRole: z117.enum([
29991
+ assetRole: z118.enum([
29948
29992
  "media",
29949
29993
  "thumbnail"
29950
29994
  ])
@@ -29952,13 +29996,13 @@ var UniversalUploadStatusResponse = z117.discriminatedUnion("status", [
29952
29996
  })
29953
29997
  ]);
29954
29998
  var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
29955
- uploadPurpose: z117.enum([
29999
+ uploadPurpose: z118.enum([
29956
30000
  "product_reference",
29957
30001
  "creative",
29958
30002
  "generic"
29959
30003
  ]),
29960
- checkToolName: z117.literal("check_media_upload"),
29961
- resolveEndpoint: z117.string().url()
30004
+ checkToolName: z118.literal("check_media_upload"),
30005
+ resolveEndpoint: z118.string().url()
29962
30006
  });
29963
30007
  function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
29964
30008
  const url = new URL(uploadPageUrl);
@@ -30049,15 +30093,15 @@ function registerMediaUploadTools(server, api) {
30049
30093
  __name(registerMediaUploadTools, "registerMediaUploadTools");
30050
30094
 
30051
30095
  // src/tools/campaigns.ts
30052
- import { z as z118 } from "zod";
30096
+ import { z as z119 } from "zod";
30053
30097
  var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
30054
30098
  var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
30055
- var MetaStatusInput = z118.object({
30056
- campaignId: z118.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
30099
+ var MetaStatusInput = z119.object({
30100
+ campaignId: z119.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
30057
30101
  });
30058
- var TikTokStatusInput = z118.object({
30059
- campaignId: z118.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
30060
- advertiserId: z118.string().min(1).describe("The same advertiserId used to publish the campaign.")
30102
+ var TikTokStatusInput = z119.object({
30103
+ campaignId: z119.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
30104
+ advertiserId: z119.string().min(1).describe("The same advertiserId used to publish the campaign.")
30061
30105
  });
30062
30106
  function registerCampaignTools(server, api) {
30063
30107
  server.registerTool("get_meta_campaign_status", {
@@ -30162,10 +30206,10 @@ function renderTikTokStatusMarkdown(r) {
30162
30206
  __name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
30163
30207
 
30164
30208
  // ../../packages/product-economics/src/product-costing.ts
30165
- import { z as z120 } from "zod";
30209
+ import { z as z121 } from "zod";
30166
30210
 
30167
30211
  // ../../packages/product-economics/src/product-costing-countries.ts
30168
- import { z as z119 } from "zod";
30212
+ import { z as z120 } from "zod";
30169
30213
 
30170
30214
  // ../../packages/product-economics/src/product-costing-shipping-references.json
30171
30215
  var product_costing_shipping_references_default = {
@@ -30229,21 +30273,21 @@ var product_costing_shipping_references_default = {
30229
30273
  };
30230
30274
 
30231
30275
  // ../../packages/product-economics/src/product-costing-countries.ts
30232
- var ShippingReferenceSchema = z119.object({
30233
- reference: z119.number().positive(),
30234
- min: z119.number().nonnegative(),
30235
- max: z119.number().positive(),
30236
- updatedAt: z119.string().date(),
30237
- confidence: z119.enum([
30276
+ var ShippingReferenceSchema = z120.object({
30277
+ reference: z120.number().positive(),
30278
+ min: z120.number().nonnegative(),
30279
+ max: z120.number().positive(),
30280
+ updatedAt: z120.string().date(),
30281
+ confidence: z120.enum([
30238
30282
  "high",
30239
30283
  "medium",
30240
30284
  "medium-low"
30241
30285
  ]),
30242
- sources: z119.array(z119.string().url().startsWith("https://")).min(1).max(3)
30286
+ sources: z120.array(z120.string().url().startsWith("https://")).min(1).max(3)
30243
30287
  }).superRefine(({ reference, min, max }, context) => {
30244
30288
  if (min > reference || reference > max) {
30245
30289
  context.addIssue({
30246
- code: z119.ZodIssueCode.custom,
30290
+ code: z120.ZodIssueCode.custom,
30247
30291
  message: "shipping_reference_outside_range",
30248
30292
  path: [
30249
30293
  "reference"
@@ -30251,7 +30295,7 @@ var ShippingReferenceSchema = z119.object({
30251
30295
  });
30252
30296
  }
30253
30297
  });
30254
- var SHIPPING_REFERENCES = z119.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
30298
+ var SHIPPING_REFERENCES = z120.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
30255
30299
  var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
30256
30300
  var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
30257
30301
  "MX",
@@ -30433,18 +30477,18 @@ function getProductCostingCountryName(country) {
30433
30477
  __name(getProductCostingCountryName, "getProductCostingCountryName");
30434
30478
 
30435
30479
  // ../../packages/product-economics/src/product-costing.ts
30436
- var ProductCostingInputSchema = z120.object({
30437
- country: z120.string().refine(isProductCostingCountryCode, "unsupported_country"),
30438
- supplierCost: z120.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
30439
- shippingCost: z120.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
30440
- returnRate: z120.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
30441
- cancellationRate: z120.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
30442
- adsManagerCpa: z120.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
30443
- desiredMargin: z120.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
30480
+ var ProductCostingInputSchema = z121.object({
30481
+ country: z121.string().refine(isProductCostingCountryCode, "unsupported_country"),
30482
+ supplierCost: z121.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
30483
+ shippingCost: z121.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
30484
+ returnRate: z121.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
30485
+ cancellationRate: z121.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
30486
+ adsManagerCpa: z121.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
30487
+ desiredMargin: z121.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
30444
30488
  }).superRefine(({ returnRate, cancellationRate }, context) => {
30445
30489
  if (returnRate + cancellationRate >= 1) {
30446
30490
  context.addIssue({
30447
- code: z120.ZodIssueCode.custom,
30491
+ code: z121.ZodIssueCode.custom,
30448
30492
  message: "delivery_rate_positive",
30449
30493
  path: [
30450
30494
  "cancellationRate"
@@ -30541,15 +30585,15 @@ function calculateProductCosting(rawInput) {
30541
30585
  __name(calculateProductCosting, "calculateProductCosting");
30542
30586
 
30543
30587
  // src/tools/product-costing.ts
30544
- import { z as z121 } from "zod";
30588
+ import { z as z122 } from "zod";
30545
30589
  var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
30546
- var optionalAmount = /* @__PURE__ */ __name((description) => z121.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
30547
- var optionalPercent = /* @__PURE__ */ __name((description) => z121.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
30548
- var ProductCostingToolInput = z121.object({
30549
- country: z121.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
30590
+ var optionalAmount = /* @__PURE__ */ __name((description) => z122.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
30591
+ var optionalPercent = /* @__PURE__ */ __name((description) => z122.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
30592
+ var ProductCostingToolInput = z122.object({
30593
+ country: z122.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
30550
30594
  message: "Pa\xEDs no soportado por ProductMaker."
30551
30595
  }).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
30552
- 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."),
30596
+ supplierCost: z122.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."),
30553
30597
  supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
30554
30598
  shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
30555
30599
  shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
@@ -30712,7 +30756,7 @@ function formatPercent(value) {
30712
30756
  __name(formatPercent, "formatPercent");
30713
30757
 
30714
30758
  // src/tools/product-research.ts
30715
- import { z as z122 } from "zod";
30759
+ import { z as z123 } from "zod";
30716
30760
 
30717
30761
  // src/tools/product-research-idempotency.ts
30718
30762
  var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
@@ -31083,17 +31127,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
31083
31127
  ]);
31084
31128
  var POLL_INTERVAL_MS = 5e3;
31085
31129
  var MAX_WAIT_SECONDS = 120;
31086
- var FindInput = z122.object({
31130
+ var FindInput = z123.object({
31087
31131
  targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
31088
31132
  categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
31089
- 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.`),
31090
- 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.")
31133
+ confirmed: z123.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
31134
+ waitSeconds: z123.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
31091
31135
  });
31092
- var GetInput = z122.object({
31093
- runId: z122.string().uuid().describe("ID del run devuelto por find_winning_products.")
31136
+ var GetInput = z123.object({
31137
+ runId: z123.string().uuid().describe("ID del run devuelto por find_winning_products.")
31094
31138
  });
31095
- var ListInput = z122.object({
31096
- limit: z122.number().int().min(1).max(20).default(10)
31139
+ var ListInput = z123.object({
31140
+ limit: z123.number().int().min(1).max(20).default(10)
31097
31141
  });
31098
31142
  function textResult(text2) {
31099
31143
  return {
@@ -31232,17 +31276,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
31232
31276
  __name(registerProductResearchTools, "registerProductResearchTools");
31233
31277
 
31234
31278
  // src/tools/dropshipping-projects.ts
31235
- import { z as z123 } from "zod";
31279
+ import { z as z124 } from "zod";
31236
31280
  var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
31237
31281
  var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
31238
31282
  var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
31239
- var ProjectId = z123.string().uuid();
31240
- var DropshippingProjectStatus = z123.enum([
31283
+ var ProjectId = z124.string().uuid();
31284
+ var DropshippingProjectStatus = z124.enum([
31241
31285
  "active",
31242
31286
  "completed",
31243
31287
  "archived"
31244
31288
  ]);
31245
- var DropshippingProjectPhase = z123.enum([
31289
+ var DropshippingProjectPhase = z124.enum([
31246
31290
  "research",
31247
31291
  "costing",
31248
31292
  "media",
@@ -31251,21 +31295,21 @@ var DropshippingProjectPhase = z123.enum([
31251
31295
  "advertising",
31252
31296
  "complete"
31253
31297
  ]);
31254
- var DropshippingRewardMilestone = z123.enum([
31298
+ var DropshippingRewardMilestone = z124.enum([
31255
31299
  "product_selected",
31256
31300
  "costing_saved",
31257
31301
  "product_media_ready",
31258
31302
  "creatives_completed",
31259
31303
  "campaign_created"
31260
31304
  ]);
31261
- var TargetCountry = z123.enum([
31305
+ var TargetCountry = z124.enum([
31262
31306
  "CO",
31263
31307
  "MX",
31264
31308
  "PE",
31265
31309
  "EC",
31266
31310
  "CL"
31267
31311
  ]);
31268
- var ResearchCategory = z123.enum([
31312
+ var ResearchCategory = z124.enum([
31269
31313
  "auto",
31270
31314
  "automotive",
31271
31315
  "kitchen",
@@ -31280,7 +31324,7 @@ var ResearchCategory = z123.enum([
31280
31324
  "garden",
31281
31325
  "cleaning"
31282
31326
  ]);
31283
- var HttpUrl3 = z123.string().url().max(2e3).refine((value) => {
31327
+ var HttpUrl3 = z124.string().url().max(2e3).refine((value) => {
31284
31328
  try {
31285
31329
  return [
31286
31330
  "http:",
@@ -31290,45 +31334,45 @@ var HttpUrl3 = z123.string().url().max(2e3).refine((value) => {
31290
31334
  return false;
31291
31335
  }
31292
31336
  }, "URL must use HTTP(S)");
31293
- var ResearchCandidateOrigin = z123.object({
31294
- type: z123.literal("research_candidate"),
31337
+ var ResearchCandidateOrigin = z124.object({
31338
+ type: z124.literal("research_candidate"),
31295
31339
  runId: ProjectId,
31296
- candidateSourceId: z123.string().min(1).max(160)
31340
+ candidateSourceId: z124.string().min(1).max(160)
31297
31341
  });
31298
- var TaskOrigin = z123.object({
31299
- type: z123.literal("task"),
31342
+ var TaskOrigin = z124.object({
31343
+ type: z124.literal("task"),
31300
31344
  taskId: ProjectId
31301
31345
  });
31302
- var ManualOrigin = z123.object({
31303
- type: z123.literal("manual"),
31346
+ var ManualOrigin = z124.object({
31347
+ type: z124.literal("manual"),
31304
31348
  clientRequestId: ProjectId,
31305
- country: z123.string().min(2).max(3).optional()
31349
+ country: z124.string().min(2).max(3).optional()
31306
31350
  });
31307
- var StartProjectInput = z123.object({
31308
- origin: z123.discriminatedUnion("type", [
31351
+ var StartProjectInput = z124.object({
31352
+ origin: z124.discriminatedUnion("type", [
31309
31353
  ResearchCandidateOrigin,
31310
31354
  TaskOrigin,
31311
31355
  ManualOrigin
31312
31356
  ]),
31313
- productName: z123.string().trim().min(1).max(240).optional(),
31357
+ productName: z124.string().trim().min(1).max(240).optional(),
31314
31358
  productUrl: HttpUrl3.optional(),
31315
- country: z123.string().min(2).max(3).optional(),
31316
- languageCode: z123.string().min(2).max(16).optional()
31359
+ country: z124.string().min(2).max(3).optional(),
31360
+ languageCode: z124.string().min(2).max(16).optional()
31317
31361
  }).strict();
31318
- var CostProjectInput = z123.object({
31362
+ var CostProjectInput = z124.object({
31319
31363
  projectId: ProjectId,
31320
- version: z123.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
31321
- country: z123.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
31364
+ version: z124.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
31365
+ country: z124.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
31322
31366
  message: "Pa\xEDs no soportado por ProductMaker."
31323
31367
  }).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
31324
- 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."),
31325
- 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."),
31326
- 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."),
31327
- 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."),
31328
- adsManagerCpa: z123.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
31329
- 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.")
31330
- });
31331
- var GuideInput = z123.object({
31368
+ supplierCost: z124.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."),
31369
+ shippingCost: z124.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
31370
+ returnRate: z124.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."),
31371
+ cancellationRate: z124.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."),
31372
+ adsManagerCpa: z124.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
31373
+ desiredMargin: z124.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
31374
+ });
31375
+ var GuideInput = z124.object({
31332
31376
  projectId: ProjectId.optional()
31333
31377
  }).strict();
31334
31378
  var NEXT_ACTION_KINDS = [
@@ -31346,29 +31390,29 @@ var NEXT_ACTION_KINDS = [
31346
31390
  "repair_meta_campaign",
31347
31391
  "review_paused_campaign"
31348
31392
  ];
31349
- var DropshippingProjectNextAction = z123.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z123.object({
31350
- kind: z123.literal(kind),
31351
- href: z123.string().min(1)
31393
+ var DropshippingProjectNextAction = z124.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z124.object({
31394
+ kind: z124.literal(kind),
31395
+ href: z124.string().min(1)
31352
31396
  })));
31353
- var CostingInputSchema = z123.object({
31354
- country: z123.string().min(2).max(3),
31355
- supplierCost: z123.number().finite().positive(),
31356
- shippingCost: z123.number().finite().nonnegative(),
31357
- returnRate: z123.number().finite().min(0).lt(1),
31358
- cancellationRate: z123.number().finite().min(0).lt(1),
31359
- adsManagerCpa: z123.number().finite().nonnegative(),
31360
- desiredMargin: z123.number().finite().min(0).lt(1)
31397
+ var CostingInputSchema = z124.object({
31398
+ country: z124.string().min(2).max(3),
31399
+ supplierCost: z124.number().finite().positive(),
31400
+ shippingCost: z124.number().finite().nonnegative(),
31401
+ returnRate: z124.number().finite().min(0).lt(1),
31402
+ cancellationRate: z124.number().finite().min(0).lt(1),
31403
+ adsManagerCpa: z124.number().finite().nonnegative(),
31404
+ desiredMargin: z124.number().finite().min(0).lt(1)
31361
31405
  }).superRefine(({ returnRate, cancellationRate }, context) => {
31362
31406
  if (returnRate + cancellationRate >= 1) context.addIssue({
31363
- code: z123.ZodIssueCode.custom,
31407
+ code: z124.ZodIssueCode.custom,
31364
31408
  path: [
31365
31409
  "cancellationRate"
31366
31410
  ]
31367
31411
  });
31368
31412
  });
31369
- var FiniteCostingNumber = z123.number().finite();
31370
- var CostingResultSchema = z123.object({
31371
- country: z123.string().min(2).max(3),
31413
+ var FiniteCostingNumber = z124.number().finite();
31414
+ var CostingResultSchema = z124.object({
31415
+ country: z124.string().min(2).max(3),
31372
31416
  deliveryRate: FiniteCostingNumber,
31373
31417
  adjustedShippingCost: FiniteCostingNumber,
31374
31418
  adjustedCpa: FiniteCostingNumber,
@@ -31381,45 +31425,45 @@ var CostingResultSchema = z123.object({
31381
31425
  estimatedProfit: FiniteCostingNumber,
31382
31426
  actualMargin: FiniteCostingNumber,
31383
31427
  breakEvenAdsManagerCpa: FiniteCostingNumber,
31384
- wasPriceAutoAdjusted: z123.boolean(),
31385
- profitabilityStatus: z123.literal("healthy")
31386
- });
31387
- var RewardProgressSchema = z123.object({
31388
- campaignKey: z123.literal("dropshipping-launch-v1"),
31389
- totalCredits: z123.number().int().positive(),
31390
- earnedCredits: z123.number().int().nonnegative(),
31391
- milestones: z123.array(z123.object({
31428
+ wasPriceAutoAdjusted: z124.boolean(),
31429
+ profitabilityStatus: z124.literal("healthy")
31430
+ });
31431
+ var RewardProgressSchema = z124.object({
31432
+ campaignKey: z124.literal("dropshipping-launch-v1"),
31433
+ totalCredits: z124.number().int().positive(),
31434
+ earnedCredits: z124.number().int().nonnegative(),
31435
+ milestones: z124.array(z124.object({
31392
31436
  milestone: DropshippingRewardMilestone,
31393
- credits: z123.number().int().positive(),
31394
- available: z123.boolean().optional(),
31395
- earned: z123.boolean(),
31437
+ credits: z124.number().int().positive(),
31438
+ available: z124.boolean().optional(),
31439
+ earned: z124.boolean(),
31396
31440
  grantId: ProjectId.nullable(),
31397
- grantedAt: z123.string().datetime().nullable()
31441
+ grantedAt: z124.string().datetime().nullable()
31398
31442
  })).length(DropshippingRewardMilestone.options.length)
31399
31443
  });
31400
- var ProjectResponseSchema = z123.object({
31444
+ var ProjectResponseSchema = z124.object({
31401
31445
  id: ProjectId,
31402
31446
  taskId: ProjectId.nullable(),
31403
31447
  status: DropshippingProjectStatus,
31404
- originKey: z123.string().min(1),
31448
+ originKey: z124.string().min(1),
31405
31449
  researchRunId: ProjectId.nullable(),
31406
- candidateSourceId: z123.string().nullable(),
31407
- productName: z123.string().nullable(),
31450
+ candidateSourceId: z124.string().nullable(),
31451
+ productName: z124.string().nullable(),
31408
31452
  productUrl: HttpUrl3.nullable(),
31409
31453
  referenceImageUrl: HttpUrl3.nullable(),
31410
- targetCountry: z123.string().nullable(),
31411
- languageCode: z123.string().nullable(),
31412
- hasReferenceImage: z123.boolean(),
31413
- hasWinnerReferenceImage: z123.boolean(),
31454
+ targetCountry: z124.string().nullable(),
31455
+ languageCode: z124.string().nullable(),
31456
+ hasReferenceImage: z124.boolean(),
31457
+ hasWinnerReferenceImage: z124.boolean(),
31414
31458
  costingInput: CostingInputSchema.nullable(),
31415
31459
  costingResult: CostingResultSchema.nullable(),
31416
- costingVersion: z123.number().int().positive().nullable(),
31417
- version: z123.number().int().positive(),
31460
+ costingVersion: z124.number().int().positive().nullable(),
31461
+ version: z124.number().int().positive(),
31418
31462
  phase: DropshippingProjectPhase,
31419
31463
  nextAction: DropshippingProjectNextAction.nullable(),
31420
31464
  rewards: RewardProgressSchema,
31421
- createdAt: z123.string().datetime(),
31422
- updatedAt: z123.string().datetime()
31465
+ createdAt: z124.string().datetime(),
31466
+ updatedAt: z124.string().datetime()
31423
31467
  }).passthrough();
31424
31468
  var NEXT_ACTION_GUIDANCE = {
31425
31469
  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.",
@@ -31539,58 +31583,58 @@ function registerDropshippingProjectTools(server, api) {
31539
31583
  __name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
31540
31584
 
31541
31585
  // src/tools/daily-control.ts
31542
- import { z as z124 } from "zod";
31586
+ import { z as z125 } from "zod";
31543
31587
  var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
31544
31588
  var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
31545
31589
  var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
31546
- var ProviderCampaignIdentifier = z124.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
31547
- var DateOnly = z124.string().regex(/^\d{4}-\d{2}-\d{2}$/);
31548
- var DailyControlInput = z124.object({
31590
+ var ProviderCampaignIdentifier = z125.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
31591
+ var DateOnly = z125.string().regex(/^\d{4}-\d{2}-\d{2}$/);
31592
+ var DailyControlInput = z125.object({
31549
31593
  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."),
31550
- days: z124.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
31551
- projectId: z124.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
31594
+ days: z125.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
31595
+ projectId: z125.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
31552
31596
  }).strict();
31553
- var LinkCampaignInput = z124.object({
31554
- projectId: z124.string().uuid(),
31555
- provider: z124.enum([
31597
+ var LinkCampaignInput = z125.object({
31598
+ projectId: z125.string().uuid(),
31599
+ provider: z125.enum([
31556
31600
  "meta",
31557
31601
  "tiktok"
31558
31602
  ]),
31559
31603
  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."),
31560
31604
  campaignId: ProviderCampaignIdentifier
31561
31605
  }).strict();
31562
- var ReportReturnsInput = z124.object({
31563
- projectId: z124.string().uuid(),
31606
+ var ReportReturnsInput = z125.object({
31607
+ projectId: z125.string().uuid(),
31564
31608
  date: DateOnly,
31565
- returnedOrders: z124.number().int().min(0).max(1e5),
31566
- note: z124.string().trim().max(280).optional()
31609
+ returnedOrders: z125.number().int().min(0).max(1e5),
31610
+ note: z125.string().trim().max(280).optional()
31567
31611
  }).strict();
31568
- var DailyControlStatusMirror = DailyControlStatusEnum.or(z124.string());
31569
- var DailyControlLightMirror = DailyControlLightEnum.or(z124.string());
31570
- var DailyControlSourceMirror = DailyControlSourceEnum.or(z124.string());
31571
- var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z124.string());
31572
- var DailyControlDayMirror = z124.object({
31573
- date: z124.string(),
31574
- returnedOrders: z124.number(),
31612
+ var DailyControlStatusMirror = DailyControlStatusEnum.or(z125.string());
31613
+ var DailyControlLightMirror = DailyControlLightEnum.or(z125.string());
31614
+ var DailyControlSourceMirror = DailyControlSourceEnum.or(z125.string());
31615
+ var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z125.string());
31616
+ var DailyControlDayMirror = z125.object({
31617
+ date: z125.string(),
31618
+ returnedOrders: z125.number(),
31575
31619
  returnedSource: DailyControlSourceMirror,
31576
31620
  cancelledSource: DailyControlSourceMirror,
31577
- hasEstimates: z124.boolean(),
31621
+ hasEstimates: z125.boolean(),
31578
31622
  light: DailyControlLightMirror
31579
31623
  }).passthrough();
31580
- var DailyControlProductMirror = z124.object({
31581
- projectId: z124.string().uuid(),
31582
- productName: z124.string().nullable(),
31624
+ var DailyControlProductMirror = z125.object({
31625
+ projectId: z125.string().uuid(),
31626
+ productName: z125.string().nullable(),
31583
31627
  status: DailyControlStatusMirror,
31584
- statusMessage: z124.string().nullable(),
31585
- days: z124.array(DailyControlDayMirror),
31628
+ statusMessage: z125.string().nullable(),
31629
+ days: z125.array(DailyControlDayMirror),
31586
31630
  verdict: DailyControlVerdictMirror.nullable(),
31587
- rationale: z124.string().nullable()
31631
+ rationale: z125.string().nullable()
31588
31632
  }).passthrough();
31589
- var DailyControlResponseMirror = z124.object({
31590
- since: z124.string(),
31591
- until: z124.string(),
31592
- products: z124.array(DailyControlProductMirror),
31593
- archivedProjectSpend: z124.array(z124.unknown())
31633
+ var DailyControlResponseMirror = z125.object({
31634
+ since: z125.string(),
31635
+ until: z125.string(),
31636
+ products: z125.array(DailyControlProductMirror),
31637
+ archivedProjectSpend: z125.array(z125.unknown())
31594
31638
  }).passthrough();
31595
31639
  var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
31596
31640
  function withWarnings(response) {
@@ -31665,7 +31709,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
31665
31709
  // src/tools/product-control.ts
31666
31710
  import { readFile, stat } from "fs/promises";
31667
31711
  import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
31668
- import { z as z125 } from "zod";
31712
+ import { z as z126 } from "zod";
31669
31713
  var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
31670
31714
  var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
31671
31715
  var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
@@ -31678,36 +31722,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
31678
31722
  var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
31679
31723
  var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
31680
31724
  var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
31681
- var DateOnly2 = z125.string().regex(/^\d{4}-\d{2}-\d{2}$/);
31725
+ var DateOnly2 = z126.string().regex(/^\d{4}-\d{2}-\d{2}$/);
31682
31726
  var IMPORT_BATCH_MAX2 = 50;
31683
- var ProductControlListInput = z125.object({
31684
- days: z125.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
31727
+ var ProductControlListInput = z126.object({
31728
+ days: z126.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
31685
31729
  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."),
31686
- shopDomain: z125.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
31730
+ shopDomain: z126.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
31687
31731
  }).strict();
31688
- var ImportableProductsInput = z125.object({
31689
- q: z125.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
31690
- after: z125.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
31691
- shopDomain: z125.string().min(1).optional()
31732
+ var ImportableProductsInput = z126.object({
31733
+ q: z126.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
31734
+ after: z126.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
31735
+ shopDomain: z126.string().min(1).optional()
31692
31736
  }).strict();
31693
- var ImportProductControlsInput = z125.object({
31694
- 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."),
31737
+ var ImportProductControlsInput = z126.object({
31738
+ shopifyProductIds: z126.array(z126.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."),
31695
31739
  // Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
31696
31740
  // sin decir a cuál archivaría el producto bajo la tienda equivocada.
31697
- shopDomain: z125.string().min(1)
31741
+ shopDomain: z126.string().min(1)
31698
31742
  }).strict();
31699
- var SetProductCostingInput = z125.object({
31700
- shopDomain: z125.string().min(1),
31701
- shopifyProductId: z125.string().min(1).max(64),
31702
- targetCountry: z125.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
31703
- supplierCost: z125.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
31704
- shippingCost: z125.number().finite().nonnegative(),
31705
- returnRate: z125.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
31706
- cancellationRate: z125.number().finite().min(0).lt(1)
31743
+ var SetProductCostingInput = z126.object({
31744
+ shopDomain: z126.string().min(1),
31745
+ shopifyProductId: z126.string().min(1).max(64),
31746
+ targetCountry: z126.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
31747
+ supplierCost: z126.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
31748
+ shippingCost: z126.number().finite().nonnegative(),
31749
+ returnRate: z126.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
31750
+ cancellationRate: z126.number().finite().min(0).lt(1)
31707
31751
  }).strict();
31708
- var Count = z125.number().int().min(0).max(1e5).nullable().optional();
31709
- var ReportProductCountsInput = z125.object({
31710
- productControlId: z125.string().uuid().describe("El identificador que devuelve get_product_control."),
31752
+ var Count = z126.number().int().min(0).max(1e5).nullable().optional();
31753
+ var ReportProductCountsInput = z126.object({
31754
+ productControlId: z126.string().uuid().describe("El identificador que devuelve get_product_control."),
31711
31755
  date: DateOnly2,
31712
31756
  orders: Count.describe("Pedidos que entraron ese d\xEDa."),
31713
31757
  cancelledOrders: Count,
@@ -31717,36 +31761,36 @@ var ReportProductCountsInput = z125.object({
31717
31761
  }).strict();
31718
31762
  var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
31719
31763
  var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
31720
- var ImportOrdersFileInput = z125.object({
31764
+ var ImportOrdersFileInput = z126.object({
31721
31765
  /** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
31722
- path: z125.string().min(1),
31723
- operationId: z125.string().uuid().optional(),
31766
+ path: z126.string().min(1),
31767
+ operationId: z126.string().uuid().optional(),
31724
31768
  /** Solo mirar: devuelve el resumen y no escribe nada. */
31725
- dryRun: z125.boolean().optional()
31769
+ dryRun: z126.boolean().optional()
31726
31770
  }).strict();
31727
- var CreateOperationInput = z125.object({
31728
- countryCode: z125.string().length(2),
31729
- label: z125.string().trim().min(1).max(60).optional()
31771
+ var CreateOperationInput = z126.object({
31772
+ countryCode: z126.string().length(2),
31773
+ label: z126.string().trim().min(1).max(60).optional()
31730
31774
  }).strict();
31731
- var MergeProductsInput = z125.object({
31732
- sourceId: z125.string().uuid(),
31733
- targetId: z125.string().uuid()
31775
+ var MergeProductsInput = z126.object({
31776
+ sourceId: z126.string().uuid(),
31777
+ targetId: z126.string().uuid()
31734
31778
  }).strict();
31735
- var SetMonthlyExpenseInput = z125.object({
31736
- month: z125.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
31779
+ var SetMonthlyExpenseInput = z126.object({
31780
+ month: z126.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
31737
31781
  label: SaveMonthlyExpenseSchema.shape.label,
31738
- amount: z125.number().finite().min(0),
31739
- operationId: z125.string().uuid().optional()
31782
+ amount: z126.number().finite().min(0),
31783
+ operationId: z126.string().uuid().optional()
31740
31784
  }).strict();
31741
- var SetAdSpendInput = z125.object({
31742
- month: z125.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
31743
- operationId: z125.string().uuid().optional(),
31785
+ var SetAdSpendInput = z126.object({
31786
+ month: z126.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
31787
+ operationId: z126.string().uuid().optional(),
31744
31788
  /** null RETIRA la corrección; cero afirma que no pautó. */
31745
- amount: z125.number().finite().min(0).nullable()
31789
+ amount: z126.number().finite().min(0).nullable()
31746
31790
  }).strict();
31747
- var GetFinancesInput = z125.object({
31748
- 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."),
31749
- operationId: z125.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
31791
+ var GetFinancesInput = z126.object({
31792
+ month: z126.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."),
31793
+ operationId: z126.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
31750
31794
  }).strict();
31751
31795
  function registerProductControlTools(server, api, { transport = "http" } = {}) {
31752
31796
  server.registerTool("get_product_control", {
@@ -31936,28 +31980,28 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
31936
31980
  __name(registerProductControlTools, "registerProductControlTools");
31937
31981
 
31938
31982
  // src/tools/market-study-estimate.ts
31939
- import { z as z126 } from "zod";
31983
+ import { z as z127 } from "zod";
31940
31984
  var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
31941
- var ProductTaskOutputEnum = z126.enum([
31985
+ var ProductTaskOutputEnum = z127.enum([
31942
31986
  "landing",
31943
31987
  "video",
31944
31988
  "image"
31945
31989
  ]);
31946
- var EstimateMarketStudyInput = z126.object({
31947
- kind: z126.enum([
31990
+ var EstimateMarketStudyInput = z127.object({
31991
+ kind: z127.enum([
31948
31992
  "video",
31949
31993
  "product_task"
31950
31994
  ]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
31951
- videoAngleCount: z126.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
31952
- durationSeconds: z126.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
31995
+ videoAngleCount: z127.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
31996
+ durationSeconds: z127.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
31953
31997
  videoStructure: VideoStructureEnum.default("single_take"),
31954
31998
  videoQuality: VideoQualityEnum.default("economy"),
31955
31999
  videoResolution: VideoResolutionEnum.default("480p"),
31956
- productImageCount: z126.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
32000
+ productImageCount: z127.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
31957
32001
  outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
31958
- generateAiMusic: z126.boolean().optional(),
32002
+ generateAiMusic: z127.boolean().optional(),
31959
32003
  generateAiEdit: AiEditRequestSchema.optional(),
31960
- 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.")
32004
+ replicateWinnerWhenFound: z127.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.")
31961
32005
  }).strict();
31962
32006
  function buildMarketStudyEstimateRequests(input) {
31963
32007
  const quotesVideo = input.kind === "video" || (input.outputs ?? [