@productmaker/mcp 12.1.1 → 12.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/stdio.js CHANGED
@@ -2788,9 +2788,9 @@ var ClassicLandingSelectionSnapshotSchema = z18.object({
2788
2788
  }).strict().superRefine((snapshot, ctx) => {
2789
2789
  if (snapshot.images) {
2790
2790
  const selectedImages = snapshot.blocks.filter((block) => block.kind === "image");
2791
- const ids = snapshot.images.map((image) => classicLandingBlockId({
2791
+ const ids = snapshot.images.map((image2) => classicLandingBlockId({
2792
2792
  kind: "image",
2793
- ...image
2793
+ ...image2
2794
2794
  }));
2795
2795
  if (new Set(ids).size !== ids.length || ids.length !== selectedImages.length || selectedImages.some((block) => !ids.includes(classicLandingBlockId(block)))) ctx.addIssue({
2796
2796
  code: z18.ZodIssueCode.custom,
@@ -15491,9 +15491,9 @@ var MotionGraphicsVoiceDirectionSchema = z78.object({
15491
15491
  pace: z78.enum(MOTION_GRAPHICS_VOICE_PACES)
15492
15492
  }).strict();
15493
15493
  var AUDIO_TAG = /\[(?:sighs|laughs softly|short pause|emphatic|whispers|gasps|hesitant|warmly)\]/g;
15494
- function motionGraphicsTaggedSpeechMatches(text3, tagged) {
15494
+ function motionGraphicsTaggedSpeechMatches(text4, tagged) {
15495
15495
  const normalize = /* @__PURE__ */ __name((value) => value.normalize("NFC").replace(/\s+/g, " ").trim(), "normalize");
15496
- return normalize(tagged.replace(AUDIO_TAG, "")) === normalize(text3);
15496
+ return normalize(tagged.replace(AUDIO_TAG, "")) === normalize(text4);
15497
15497
  }
15498
15498
  __name(motionGraphicsTaggedSpeechMatches, "motionGraphicsTaggedSpeechMatches");
15499
15499
  var MotionGraphicsTaggedSpeechSchema = z78.string().trim().min(1).max(1200);
@@ -21658,10 +21658,10 @@ var GENDER_ALIASES = {
21658
21658
  };
21659
21659
  function matchAlias(raw, aliases) {
21660
21660
  if (typeof raw !== "string") return void 0;
21661
- const text3 = raw.trim().toLowerCase();
21662
- const exact = aliases[text3];
21661
+ const text4 = raw.trim().toLowerCase();
21662
+ const exact = aliases[text4];
21663
21663
  if (exact) return exact;
21664
- const words = new Set(text3.split(/[^a-z]+/).filter(Boolean));
21664
+ const words = new Set(text4.split(/[^a-z]+/).filter(Boolean));
21665
21665
  for (const [alias, value] of Object.entries(aliases)) {
21666
21666
  if (words.has(alias)) return value;
21667
21667
  }
@@ -23553,26 +23553,118 @@ var WebsiteCaptureResearchSchema = z116.object({
23553
23553
  });
23554
23554
 
23555
23555
  // ../../packages/types/src/demo-mode.ts
23556
- import { z as z118 } from "zod";
23556
+ import { z as z119 } from "zod";
23557
23557
 
23558
- // ../../packages/types/src/demo-mode-service-page-assets.ts
23558
+ // ../../packages/types/src/demo-mode-product.ts
23559
23559
  import { z as z117 } from "zod";
23560
- var DemoServicePageAssetSourceSchema = z117.object({
23561
- pageId: z117.string().uuid(),
23562
- ownerId: z117.string().min(1),
23563
- assets: z117.array(z117.object({
23564
- id: z117.string().uuid(),
23565
- storageKey: z117.string().min(1).max(1024),
23566
- mediaType: z117.enum([
23560
+ var text3 = z117.string().trim().min(1).max(2e5);
23561
+ var nullableText = z117.string().max(2e5).nullable();
23562
+ var image = z117.object({
23563
+ provider: text3,
23564
+ model: text3,
23565
+ prompt: z117.string().max(2e5),
23566
+ imageUrl: text3,
23567
+ width: z117.number().int().positive(),
23568
+ height: z117.number().int().positive(),
23569
+ adCopy: nullableText,
23570
+ rawResponse: z117.unknown()
23571
+ });
23572
+ var ProductDemoSnapshotSchema = z117.object({
23573
+ product: z117.object({
23574
+ title: text3,
23575
+ price: nullableText,
23576
+ country: nullableText,
23577
+ features: z117.array(text3).max(100),
23578
+ form: nullableText,
23579
+ details: z117.unknown(),
23580
+ isCombo: z117.boolean(),
23581
+ comboItems: z117.unknown(),
23582
+ images: z117.array(text3).min(1).max(50),
23583
+ cleanImages: z117.array(text3).max(50),
23584
+ cleanImagesMeta: z117.unknown()
23585
+ }),
23586
+ angles: z117.array(z117.object({
23587
+ content: text3,
23588
+ buyerPersona: nullableText,
23589
+ actor: nullableText,
23590
+ scriptNotes: nullableText
23591
+ })).min(1).max(10),
23592
+ videos: z117.array(z117.object({
23593
+ /** Present only for explicit multi-template packs; legacy arrays keep selection-order playback. */
23594
+ reviewAngleIndex: z117.number().int().min(0).max(9).optional(),
23595
+ provider: text3,
23596
+ model: text3,
23597
+ script: text3,
23598
+ prompt: z117.string().max(2e5),
23599
+ imageUrl: text3,
23600
+ durationSeconds: z117.number().int().positive().nullable(),
23601
+ format: VideoFormat,
23602
+ resultUrls: z117.array(text3).min(1).max(10),
23603
+ rawResponse: z117.unknown(),
23604
+ adCopy: nullableText
23605
+ })).min(1).max(10),
23606
+ landingImages: z117.array(z117.object({
23607
+ role: LandingRole,
23608
+ indexNum: z117.number().int().min(1),
23609
+ url: text3,
23610
+ width: z117.number().int().positive(),
23611
+ height: z117.number().int().positive(),
23612
+ notes: nullableText
23613
+ })).max(20),
23614
+ landingConfig: z117.unknown(),
23615
+ image,
23616
+ productUseSheet: z117.unknown(),
23617
+ productTruth: z117.unknown(),
23618
+ productReference: z117.object({
23619
+ referenceEvidenceVersion: z117.number().int().nonnegative(),
23620
+ planVersion: z117.number().int().positive(),
23621
+ baseReferenceSetHash: text3,
23622
+ referenceSet: z117.unknown(),
23623
+ preparationPlan: z117.unknown(),
23624
+ canonicalIdentityAnchors: z117.unknown()
23625
+ })
23626
+ });
23627
+ var ProductDemoPhaseSchema = z117.enum([
23628
+ "preparing",
23629
+ "angles",
23630
+ "preparing_scripts",
23631
+ "scripts",
23632
+ "generating",
23633
+ "done"
23634
+ ]);
23635
+ var ProductDemoJobPhaseSchema = z117.enum([
23636
+ "preparing",
23637
+ "scripts",
23638
+ "generating"
23639
+ ]);
23640
+ var ProductDemoTaskStateSchema = z117.object({
23641
+ admitted: z117.boolean().default(false),
23642
+ phase: ProductDemoPhaseSchema,
23643
+ waitMs: z117.number().int().positive(),
23644
+ snapshot: ProductDemoSnapshotSchema,
23645
+ selectedAngleIndices: z117.array(z117.number().int().min(0).max(9)).max(10),
23646
+ chargeCents: z117.number().int().min(0).max(1e5),
23647
+ maxCents: z117.number().int().min(0).optional()
23648
+ });
23649
+
23650
+ // ../../packages/types/src/demo-mode-service-page-assets.ts
23651
+ import { z as z118 } from "zod";
23652
+ var DemoServicePageAssetSourceSchema = z118.object({
23653
+ pageId: z118.string().uuid(),
23654
+ ownerId: z118.string().min(1),
23655
+ assets: z118.array(z118.object({
23656
+ id: z118.string().uuid(),
23657
+ storageKey: z118.string().min(1).max(1024),
23658
+ mediaType: z118.enum([
23567
23659
  "image/webp",
23568
23660
  "video/mp4"
23569
23661
  ]),
23570
- byteSize: z117.number().int().positive().max(32 * 1024 * 1024),
23571
- width: z117.number().int().positive().max(1920),
23572
- height: z117.number().int().positive().max(1920),
23573
- contentHash: z117.string().regex(/^[a-f0-9]{64}$/i),
23662
+ byteSize: z118.number().int().positive().max(32 * 1024 * 1024),
23663
+ width: z118.number().int().positive().max(1920),
23664
+ height: z118.number().int().positive().max(1920),
23665
+ contentHash: z118.string().regex(/^[a-f0-9]{64}$/i),
23574
23666
  sourceKind: ServicePageSourceKindSchema,
23575
- approvedAt: z117.string().datetime()
23667
+ approvedAt: z118.string().datetime()
23576
23668
  }).strict()).max(24)
23577
23669
  }).strict();
23578
23670
 
@@ -23581,9 +23673,10 @@ var DEMO_MODE_FLOWS = [
23581
23673
  "brand",
23582
23674
  "servicePage",
23583
23675
  "motion",
23584
- "image"
23676
+ "image",
23677
+ "product"
23585
23678
  ];
23586
- var DemoModeFlowSchema = z118.enum(DEMO_MODE_FLOWS);
23679
+ var DemoModeFlowSchema = z119.enum(DEMO_MODE_FLOWS);
23587
23680
  var DEMO_MODE_STEPS = [
23588
23681
  "running",
23589
23682
  "research",
@@ -23596,108 +23689,166 @@ var DEMO_MODE_STEPS = [
23596
23689
  "final",
23597
23690
  "watchdog"
23598
23691
  ];
23599
- var DemoModeStepSchema = z118.enum(DEMO_MODE_STEPS);
23692
+ var DemoModeStepSchema = z119.enum(DEMO_MODE_STEPS);
23600
23693
  var DEMO_MODE_WAIT_SECONDS = {
23601
23694
  min: 30,
23602
23695
  max: 450,
23603
23696
  default: 150
23604
23697
  };
23605
- var centsSchema = z118.number().int().min(0).max(1e5);
23606
- var emailSchema = z118.string().trim().toLowerCase().email();
23607
- var optionalTemplateId = z118.preprocess((value) => value === "" ? void 0 : value, z118.string().uuid().optional());
23608
- var DemoModeTemplatesSchema = z118.object({
23609
- brandId: z118.string().uuid(),
23610
- servicePageId: z118.string().uuid(),
23611
- motionTaskId: z118.string().uuid(),
23698
+ var DEMO_MODE_DEFAULT_CHARGE_CENTS = {
23699
+ brand: 100,
23700
+ servicePage: 300,
23701
+ motion: 1500,
23702
+ image: 200,
23703
+ product: 1500
23704
+ };
23705
+ var centsSchema = z119.number().int().min(0).max(1e5);
23706
+ var emailSchema = z119.string().trim().toLowerCase().email();
23707
+ var DEMO_MODE_OPTIONAL_MOTION_TEMPLATE_KEYS = [
23708
+ "motionVariantTaskId",
23709
+ "motionThirdTaskId"
23710
+ ];
23711
+ var DEMO_MODE_OPTIONAL_PRODUCT_VIDEO_TEMPLATE_KEYS = [
23712
+ "productVideoVariantTaskId",
23713
+ "productVideoThirdTaskId"
23714
+ ];
23715
+ var DEMO_MODE_PRODUCT_VIDEO_TEMPLATE_KEYS = [
23716
+ "productVideoTaskId",
23717
+ ...DEMO_MODE_OPTIONAL_PRODUCT_VIDEO_TEMPLATE_KEYS
23718
+ ];
23719
+ var DEMO_MODE_PRODUCT_TEMPLATE_KEYS = [
23720
+ "productLandingTaskId",
23721
+ "productVideoTaskId",
23722
+ "productImageTaskId"
23723
+ ];
23724
+ var DEMO_MODE_PRODUCT_ALL_TEMPLATE_KEYS = [
23725
+ ...DEMO_MODE_PRODUCT_TEMPLATE_KEYS,
23726
+ ...DEMO_MODE_OPTIONAL_PRODUCT_VIDEO_TEMPLATE_KEYS
23727
+ ];
23728
+ var DEMO_MODE_OPTIONAL_TEMPLATE_KEYS = [
23729
+ ...DEMO_MODE_OPTIONAL_MOTION_TEMPLATE_KEYS,
23730
+ ...DEMO_MODE_PRODUCT_ALL_TEMPLATE_KEYS
23731
+ ];
23732
+ var optionalTemplateId = z119.preprocess((value) => value === "" ? void 0 : value, z119.string().uuid().optional());
23733
+ var DemoModeTemplatesSchema = z119.object({
23734
+ brandId: z119.string().uuid(),
23735
+ servicePageId: z119.string().uuid(),
23736
+ motionTaskId: z119.string().uuid(),
23612
23737
  motionVariantTaskId: optionalTemplateId,
23613
23738
  motionThirdTaskId: optionalTemplateId,
23614
- imageTaskId: z118.string().uuid()
23615
- });
23616
- var DemoModeEditableSchema = z118.object({
23617
- enabled: z118.boolean(),
23618
- emails: z118.array(emailSchema).max(50).transform((list) => [
23739
+ imageTaskId: z119.string().uuid(),
23740
+ productLandingTaskId: optionalTemplateId,
23741
+ productVideoTaskId: optionalTemplateId,
23742
+ productVideoVariantTaskId: optionalTemplateId,
23743
+ productVideoThirdTaskId: optionalTemplateId,
23744
+ productImageTaskId: optionalTemplateId
23745
+ });
23746
+ var DemoModeEditableObjectSchema = z119.object({
23747
+ productsEnabled: z119.boolean().default(false),
23748
+ enabled: z119.boolean(),
23749
+ emails: z119.array(emailSchema).max(50).transform((list) => [
23619
23750
  ...new Set(list)
23620
23751
  ]),
23621
- waitSeconds: z118.number().int().min(DEMO_MODE_WAIT_SECONDS.min).max(DEMO_MODE_WAIT_SECONDS.max),
23622
- chargeCents: z118.object({
23752
+ waitSeconds: z119.number().int().min(DEMO_MODE_WAIT_SECONDS.min).max(DEMO_MODE_WAIT_SECONDS.max),
23753
+ chargeCents: z119.object({
23623
23754
  brand: centsSchema,
23624
23755
  servicePage: centsSchema,
23625
23756
  motion: centsSchema,
23626
- image: centsSchema
23757
+ image: centsSchema,
23758
+ product: centsSchema.default(DEMO_MODE_DEFAULT_CHARGE_CENTS.product)
23627
23759
  }),
23628
23760
  templates: DemoModeTemplatesSchema
23629
23761
  });
23630
- var nullableString = z118.string().nullable();
23631
- var DemoModeSnapshotSchema = z118.object({
23632
- brand: z118.object({
23762
+ var DemoModeEditableSchema = DemoModeEditableObjectSchema.superRefine((value, ctx) => {
23763
+ if (!value.productsEnabled) return;
23764
+ for (const key of DEMO_MODE_PRODUCT_TEMPLATE_KEYS) {
23765
+ if (!value.templates[key]) ctx.addIssue({
23766
+ code: z119.ZodIssueCode.custom,
23767
+ path: [
23768
+ "templates",
23769
+ key
23770
+ ],
23771
+ message: "Product demo requires all three templates"
23772
+ });
23773
+ }
23774
+ });
23775
+ var nullableString = z119.string().nullable();
23776
+ var DemoModeSnapshotSchema = z119.object({
23777
+ product: ProductDemoSnapshotSchema.optional(),
23778
+ brand: z119.object({
23633
23779
  /** Columnas de identidad de `Brand` listas para un `update` (sin id/userId/slug/estado/fechas). */
23634
- identity: z118.record(z118.unknown()),
23635
- productSamples: z118.array(z118.object({
23636
- name: z118.string(),
23637
- priceCents: z118.number().int().nullable(),
23780
+ identity: z119.record(z119.unknown()),
23781
+ productSamples: z119.array(z119.object({
23782
+ name: z119.string(),
23783
+ priceCents: z119.number().int().nullable(),
23638
23784
  currency: nullableString,
23639
- imageKey: z118.string(),
23785
+ imageKey: z119.string(),
23640
23786
  productUrl: nullableString,
23641
- position: z118.number().int()
23787
+ position: z119.number().int()
23642
23788
  })),
23643
- personas: z118.array(z118.object({
23644
- name: z118.string(),
23789
+ personas: z119.array(z119.object({
23790
+ name: z119.string(),
23645
23791
  demographics: nullableString,
23646
23792
  painPoints: nullableString,
23647
23793
  motivations: nullableString,
23648
23794
  objections: nullableString,
23649
23795
  gender: nullableString,
23650
- isDefault: z118.boolean()
23796
+ isDefault: z119.boolean()
23651
23797
  }))
23652
23798
  }),
23653
- servicePage: z118.object({
23654
- facts: z118.unknown(),
23655
- review: z118.unknown(),
23656
- artifact: z118.unknown(),
23799
+ servicePage: z119.object({
23800
+ facts: z119.unknown(),
23801
+ review: z119.unknown(),
23802
+ artifact: z119.unknown(),
23657
23803
  /** Optional only for snapshots saved before page-owned demo media. */
23658
23804
  assetSource: DemoServicePageAssetSourceSchema.optional()
23659
23805
  }),
23660
- motion: z118.object({
23806
+ motion: z119.object({
23661
23807
  outputs: MotionGraphicsOutputsSchema,
23662
23808
  /**
23663
23809
  * La captura REAL de la web de la plantilla (nunca una fabricada por la
23664
23810
  * demo). Null cuando la plantilla no tiene ninguna: la captura demo nunca
23665
23811
  * va live, así que el servicio usa `DEMO_MODE_PLACEHOLDER_CAPTURE`.
23666
23812
  */
23667
- capture: z118.object({
23668
- bundleKey: z118.string(),
23669
- sha256: z118.string(),
23670
- uploadBytes: z118.number().int().nullable(),
23813
+ capture: z119.object({
23814
+ bundleKey: z119.string(),
23815
+ sha256: z119.string(),
23816
+ uploadBytes: z119.number().int().nullable(),
23671
23817
  previewKey: nullableString
23672
23818
  }).nullable()
23673
23819
  }),
23674
- image: z118.object({
23675
- provider: z118.string(),
23676
- model: z118.string(),
23677
- prompt: z118.string(),
23678
- imageUrl: z118.string(),
23679
- width: z118.number().int(),
23680
- height: z118.number().int(),
23820
+ image: z119.object({
23821
+ provider: z119.string(),
23822
+ model: z119.string(),
23823
+ prompt: z119.string(),
23824
+ imageUrl: z119.string(),
23825
+ width: z119.number().int(),
23826
+ height: z119.number().int(),
23681
23827
  adCopy: nullableString,
23682
- rawResponse: z118.unknown()
23828
+ rawResponse: z119.unknown()
23683
23829
  })
23684
23830
  });
23685
- var DemoModeConfigSchema = DemoModeEditableSchema.extend({
23831
+ var DemoModeConfigSchema = DemoModeEditableObjectSchema.extend({
23686
23832
  snapshot: DemoModeSnapshotSchema.nullable(),
23687
- snapshotAt: z118.string().datetime().nullable()
23833
+ snapshotAt: z119.string().datetime().nullable()
23688
23834
  });
23689
- var DemoModeAdminViewSchema = DemoModeEditableSchema.extend({
23835
+ var DemoModeAdminViewSchema = DemoModeEditableObjectSchema.extend({
23690
23836
  // Sin configurar, la API devuelve ids vacíos ("" no es uuid): la vista los
23691
23837
  // admite; el PUT sí exige uuid (`DemoModeEditableSchema`).
23692
- templates: z118.object({
23693
- brandId: z118.string(),
23694
- servicePageId: z118.string(),
23695
- motionTaskId: z118.string(),
23696
- motionVariantTaskId: z118.string().optional(),
23697
- motionThirdTaskId: z118.string().optional(),
23698
- imageTaskId: z118.string()
23838
+ templates: z119.object({
23839
+ brandId: z119.string(),
23840
+ servicePageId: z119.string(),
23841
+ motionTaskId: z119.string(),
23842
+ motionVariantTaskId: z119.string().optional(),
23843
+ motionThirdTaskId: z119.string().optional(),
23844
+ imageTaskId: z119.string(),
23845
+ productLandingTaskId: z119.string().optional(),
23846
+ productVideoTaskId: z119.string().optional(),
23847
+ productVideoVariantTaskId: z119.string().optional(),
23848
+ productVideoThirdTaskId: z119.string().optional(),
23849
+ productImageTaskId: z119.string().optional()
23699
23850
  }),
23700
- snapshotAt: z118.string().nullable()
23851
+ snapshotAt: z119.string().nullable()
23701
23852
  });
23702
23853
  var DEMO_MODE_TEMPLATE_PROBLEMS = [
23703
23854
  "not_found",
@@ -23706,35 +23857,45 @@ var DEMO_MODE_TEMPLATE_PROBLEMS = [
23706
23857
  "artifact_invalid",
23707
23858
  "task_not_done",
23708
23859
  "no_video",
23709
- "no_creative"
23860
+ "no_creative",
23861
+ "product_invalid",
23862
+ "product_mismatch",
23863
+ "no_angles",
23864
+ "no_landing"
23710
23865
  ];
23711
- var DemoModeTemplateVerdictSchema = z118.discriminatedUnion("ok", [
23712
- z118.object({
23713
- ok: z118.literal(true)
23866
+ var DemoModeTemplateVerdictSchema = z119.discriminatedUnion("ok", [
23867
+ z119.object({
23868
+ ok: z119.literal(true)
23714
23869
  }),
23715
- z118.object({
23716
- ok: z118.literal(false),
23717
- problem: z118.enum(DEMO_MODE_TEMPLATE_PROBLEMS)
23870
+ z119.object({
23871
+ ok: z119.literal(false),
23872
+ problem: z119.enum(DEMO_MODE_TEMPLATE_PROBLEMS)
23718
23873
  })
23719
23874
  ]);
23720
- var DemoModeValidationSchema = z118.object({
23875
+ var DemoModeValidationSchema = z119.object({
23721
23876
  brandId: DemoModeTemplateVerdictSchema,
23722
23877
  servicePageId: DemoModeTemplateVerdictSchema,
23723
23878
  motionTaskId: DemoModeTemplateVerdictSchema,
23724
23879
  motionVariantTaskId: DemoModeTemplateVerdictSchema.optional(),
23725
23880
  motionThirdTaskId: DemoModeTemplateVerdictSchema.optional(),
23726
- imageTaskId: DemoModeTemplateVerdictSchema
23727
- });
23728
- var DemoModeJobSchema = z118.object({
23881
+ imageTaskId: DemoModeTemplateVerdictSchema,
23882
+ productLandingTaskId: DemoModeTemplateVerdictSchema.optional(),
23883
+ productVideoTaskId: DemoModeTemplateVerdictSchema.optional(),
23884
+ productVideoVariantTaskId: DemoModeTemplateVerdictSchema.optional(),
23885
+ productVideoThirdTaskId: DemoModeTemplateVerdictSchema.optional(),
23886
+ productImageTaskId: DemoModeTemplateVerdictSchema.optional()
23887
+ });
23888
+ var DemoModeJobSchema = z119.object({
23729
23889
  flow: DemoModeFlowSchema,
23890
+ productPhase: ProductDemoJobPhaseSchema.optional(),
23730
23891
  step: DemoModeStepSchema,
23731
23892
  /** brandId | servicePageOperationId | taskId según el flujo. */
23732
- targetId: z118.string().uuid(),
23733
- userId: z118.string().min(1),
23893
+ targetId: z119.string().uuid(),
23894
+ userId: z119.string().min(1),
23734
23895
  /** Solo marca: la generación de extracción que el guion completa. */
23735
- generation: z118.number().int().positive().optional(),
23896
+ generation: z119.number().int().positive().optional(),
23736
23897
  /** Solo `final`/`watchdog`: la parte del snapshot de ESTE flujo, congelada al empezar. */
23737
- result: z118.unknown().optional()
23898
+ result: z119.unknown().optional()
23738
23899
  });
23739
23900
 
23740
23901
  // ../../packages/utils/src/retry-after.ts
@@ -24210,7 +24371,7 @@ var ApiClient = class {
24210
24371
  };
24211
24372
 
24212
24373
  // src/index.ts
24213
- var MCP_VERSION = "12.1.1";
24374
+ var MCP_VERSION = "12.1.3";
24214
24375
 
24215
24376
  // src/meta-upload-app.ts
24216
24377
  import { readFileSync } from "fs";
@@ -24307,12 +24468,12 @@ function buildTaskResultsView(media, proxyBaseUrl) {
24307
24468
  return null;
24308
24469
  }
24309
24470
  }, "safeUrl");
24310
- const images = media.images.flatMap((image, index) => {
24311
- const url = safeUrl(image.url);
24471
+ const images = media.images.flatMap((image2, index) => {
24472
+ const url = safeUrl(image2.url);
24312
24473
  return url ? [
24313
24474
  {
24314
24475
  url,
24315
- alt: image.alt?.slice(0, 160) ?? `ProductMaker image ${index + 1}`
24476
+ alt: image2.alt?.slice(0, 160) ?? `ProductMaker image ${index + 1}`
24316
24477
  }
24317
24478
  ] : [];
24318
24479
  });
@@ -24397,7 +24558,7 @@ function registerTaskResultsAppResource(server, proxyBaseUrl) {
24397
24558
  __name(registerTaskResultsAppResource, "registerTaskResultsAppResource");
24398
24559
 
24399
24560
  // src/tools/tasks.ts
24400
- import { z as z124 } from "zod";
24561
+ import { z as z125 } from "zod";
24401
24562
 
24402
24563
  // src/resolve-image.ts
24403
24564
  import { lookup as dnsLookup } from "dns/promises";
@@ -24958,9 +25119,9 @@ async function resolveMediaRef(ref, opts) {
24958
25119
  __name(resolveMediaRef, "resolveMediaRef");
24959
25120
 
24960
25121
  // src/tools/shared.ts
24961
- import { z as z119 } from "zod";
24962
- var Lang = z119.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);
24963
- var Country = z119.string().min(2).max(3);
25122
+ import { z as z120 } from "zod";
25123
+ var Lang = z120.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);
25124
+ var Country = z120.string().min(2).max(3);
24964
25125
  var LandingStrategyEnum = LandingStrategySchema;
24965
25126
  var LandingImageFormatEnum = LandingImageFormatSchema;
24966
25127
  var VideoPresetEnum = VideoPreset.extract([
@@ -25064,7 +25225,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
25064
25225
  return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
25065
25226
  }
25066
25227
  __name(animationStyleApplies, "animationStyleApplies");
25067
- var VideoTierEnum = z119.enum([
25228
+ var VideoTierEnum = z120.enum([
25068
25229
  "basic"
25069
25230
  ]);
25070
25231
  function resolveVideoTier(_tier) {
@@ -25122,10 +25283,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
25122
25283
  var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
25123
25284
  var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
25124
25285
  var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
25125
- var ImageRefSchema = z119.object({
25126
- url: z119.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.'),
25127
- path: z119.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`.'),
25128
- assetId: z119.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.")
25286
+ var ImageRefSchema = z120.object({
25287
+ url: z120.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.'),
25288
+ path: z120.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`.'),
25289
+ assetId: z120.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.")
25129
25290
  }).refine((v) => [
25130
25291
  v.url,
25131
25292
  v.path,
@@ -25133,18 +25294,18 @@ var ImageRefSchema = z119.object({
25133
25294
  ].filter(Boolean).length === 1, {
25134
25295
  message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
25135
25296
  });
25136
- var ImagesInput = z119.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
25137
- const assetCount = images.filter((image) => Boolean(image.assetId)).length;
25297
+ var ImagesInput = z120.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
25298
+ const assetCount = images.filter((image2) => Boolean(image2.assetId)).length;
25138
25299
  if (assetCount > 0 && assetCount !== images.length) {
25139
25300
  ctx.addIssue({
25140
- code: z119.ZodIssueCode.custom,
25301
+ code: z120.ZodIssueCode.custom,
25141
25302
  message: "all image entries must use assetId, or all must use URL/path sources"
25142
25303
  });
25143
25304
  }
25144
25305
  }).describe('1 a 5 fotos del MISMO producto. La PRIMERA es la principal (hero); las dem\xE1s son \xE1ngulos adicionales. NO mezcles productos distintos en una sola llamada.\n\nCada entrada tiene EXACTAMENTE uno de:\n\u2022 `url` \u2014 URL p\xFAblica HTTPS (Shopify CDN, Cloudinary). Prefi\xE9rela si la foto ya est\xE1 hospedada.\n\u2022 `path` \u2014 Ruta del archivo en el computador del usuario (ej. "/Users/maria/Desktop/foto.jpg", "~/Downloads/camiseta.png"). \xDAsala cuando el usuario te dijo d\xF3nde guard\xF3 la foto. Solo MCP local \u2014 el cliente web rechaza paths.\n\n\u2022 `assetId` \u2014 ID opaco devuelto por `check_media_upload`. En MCP remoto, si el usuario quiere usar una foto de su laptop, llama `request_media_upload` y no pidas una ruta local ni URL.\n\nNo mezcles assetId con URL/path en la misma llamada. Los paths se conservan solo para MCP local por stdio.');
25145
25306
  function uploadedAssetIds(images) {
25146
- if (!images.length || !images.every((image) => Boolean(image.assetId))) return null;
25147
- return images.map((image) => image.assetId);
25307
+ if (!images.length || !images.every((image2) => Boolean(image2.assetId))) return null;
25308
+ return images.map((image2) => image2.assetId);
25148
25309
  }
25149
25310
  __name(uploadedAssetIds, "uploadedAssetIds");
25150
25311
  function asText(value) {
@@ -25218,14 +25379,14 @@ async function submitCreative(api, opts) {
25218
25379
  });
25219
25380
  }
25220
25381
  __name(submitCreative, "submitCreative");
25221
- var ResearchTargetCountryEnum = z119.enum([
25382
+ var ResearchTargetCountryEnum = z120.enum([
25222
25383
  "CO",
25223
25384
  "MX",
25224
25385
  "PE",
25225
25386
  "EC",
25226
25387
  "CL"
25227
25388
  ]);
25228
- var ResearchCategoryEnum = z119.enum([
25389
+ var ResearchCategoryEnum = z120.enum([
25229
25390
  "auto",
25230
25391
  "automotive",
25231
25392
  "kitchen",
@@ -26020,7 +26181,7 @@ function approveRefusalMessage(reason) {
26020
26181
  __name(approveRefusalMessage, "approveRefusalMessage");
26021
26182
 
26022
26183
  // src/tools/task-outputs.ts
26023
- import { z as z120 } from "zod";
26184
+ import { z as z121 } from "zod";
26024
26185
 
26025
26186
  // src/asset-proxy.ts
26026
26187
  import { createHmac, timingSafeEqual } from "crypto";
@@ -26204,12 +26365,12 @@ function serviceVideoResultMedia(result) {
26204
26365
  };
26205
26366
  }
26206
26367
  __name(serviceVideoResultMedia, "serviceVideoResultMedia");
26207
- var CreativeVariantIdentity = z120.object({
26208
- variantTaskId: z120.string().uuid(),
26209
- sourceTaskId: z120.string().uuid(),
26368
+ var CreativeVariantIdentity = z121.object({
26369
+ variantTaskId: z121.string().uuid(),
26370
+ sourceTaskId: z121.string().uuid(),
26210
26371
  kind: TaskCreativeVariantKind,
26211
26372
  status: TaskStatusSchema,
26212
- error: z120.string().optional()
26373
+ error: z121.string().optional()
26213
26374
  });
26214
26375
  function proxifyOutputs(outputs, proxyBaseUrl) {
26215
26376
  if (!proxyBaseUrl || !isProxyEnabled()) return outputs;
@@ -26813,59 +26974,59 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
26813
26974
  __name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
26814
26975
 
26815
26976
  // src/tools/media-presentation.ts
26816
- import { z as z121 } from "zod";
26817
- var HttpsPresentationUrlSchema = z121.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
26977
+ import { z as z122 } from "zod";
26978
+ var HttpsPresentationUrlSchema = z122.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
26818
26979
  var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
26819
26980
  const hostname = new URL(value).hostname.toLowerCase();
26820
26981
  return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
26821
26982
  }, "preview URL must be owned by ProductMaker");
26822
- var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z121.number().int().positive().max(maximum), "positiveIntAtMost");
26823
- var PresentationImageSchema = z121.object({
26824
- kind: z121.literal("image"),
26983
+ var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z122.number().int().positive().max(maximum), "positiveIntAtMost");
26984
+ var PresentationImageSchema = z122.object({
26985
+ kind: z122.literal("image"),
26825
26986
  url: HttpsPresentationUrlSchema,
26826
- mimeType: z121.enum([
26987
+ mimeType: z122.enum([
26827
26988
  "image/jpeg",
26828
26989
  "image/png"
26829
26990
  ]),
26830
26991
  byteSize: positiveIntAtMost(5 * 1024 * 1024),
26831
26992
  width: positiveIntAtMost(16384),
26832
26993
  height: positiveIntAtMost(16384),
26833
- alt: z121.string().trim().min(1).max(240)
26994
+ alt: z122.string().trim().min(1).max(240)
26834
26995
  }).strict();
26835
26996
  var McpMediaPresentationSchema = PresentationImageSchema;
26836
- var GalleryImageSchema = z121.object({
26997
+ var GalleryImageSchema = z122.object({
26837
26998
  url: ProductMakerPreviewUrlSchema,
26838
- alt: z121.string().trim().min(1).max(240)
26999
+ alt: z122.string().trim().min(1).max(240)
26839
27000
  });
26840
27001
  var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
26841
- async function imageBlocks(image, transport) {
27002
+ async function imageBlocks(image2, transport) {
26842
27003
  const portableFallback = [
26843
27004
  {
26844
27005
  type: "resource_link",
26845
- uri: image.url,
26846
- name: image.alt,
26847
- ...image.mimeType ? {
26848
- mimeType: image.mimeType
27006
+ uri: image2.url,
27007
+ name: image2.alt,
27008
+ ...image2.mimeType ? {
27009
+ mimeType: image2.mimeType
26849
27010
  } : {},
26850
- ...image.byteSize ? {
26851
- size: image.byteSize
27011
+ ...image2.byteSize ? {
27012
+ size: image2.byteSize
26852
27013
  } : {}
26853
27014
  },
26854
27015
  {
26855
27016
  type: "text",
26856
- text: `Si no ves la imagen, \xE1brela aqu\xED: ${image.url}`
27017
+ text: `Si no ves la imagen, \xE1brela aqu\xED: ${image2.url}`
26857
27018
  }
26858
27019
  ];
26859
27020
  try {
26860
27021
  const [resolved] = await resolveImages([
26861
27022
  {
26862
- url: image.url
27023
+ url: image2.url
26863
27024
  }
26864
27025
  ], {
26865
27026
  transport,
26866
- maxBytes: image.byteSize ?? MCP_GALLERY_IMAGE_MAX_BYTES
27027
+ maxBytes: image2.byteSize ?? MCP_GALLERY_IMAGE_MAX_BYTES
26867
27028
  });
26868
- if (!resolved || image.mimeType && resolved.mimetype !== image.mimeType || resolved.buffer.byteLength > (image.byteSize ?? MCP_GALLERY_IMAGE_MAX_BYTES)) {
27029
+ if (!resolved || image2.mimeType && resolved.mimetype !== image2.mimeType || resolved.buffer.byteLength > (image2.byteSize ?? MCP_GALLERY_IMAGE_MAX_BYTES)) {
26869
27030
  return portableFallback;
26870
27031
  }
26871
27032
  return [
@@ -26892,12 +27053,12 @@ async function buildMcpMediaPresentationContent(rawPresentation, transport = "ht
26892
27053
  ];
26893
27054
  }
26894
27055
  __name(buildMcpMediaPresentationContent, "buildMcpMediaPresentationContent");
26895
- var OwnedImagePreviewSchema = z121.object({
27056
+ var OwnedImagePreviewSchema = z122.object({
26896
27057
  url: HttpsPresentationUrlSchema.refine((value) => {
26897
27058
  const url = new URL(value);
26898
27059
  return !url.username && !url.password && !isPrivateHost(url.hostname);
26899
27060
  }, "Preview URL must be public HTTPS without credentials"),
26900
- alt: z121.string().trim().min(1).max(240)
27061
+ alt: z122.string().trim().min(1).max(240)
26901
27062
  });
26902
27063
  async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
26903
27064
  const preview2 = OwnedImagePreviewSchema.safeParse(rawPreview);
@@ -26973,24 +27134,24 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
26973
27134
  }
26974
27135
  ];
26975
27136
  }
26976
- const image = parsed.data;
27137
+ const image2 = parsed.data;
26977
27138
  const heading = {
26978
27139
  type: "text",
26979
- text: `Foto ${index + 1}: ${image.alt}`
27140
+ text: `Foto ${index + 1}: ${image2.alt}`
26980
27141
  };
26981
27142
  const fallback = {
26982
27143
  type: "resource_link",
26983
- uri: image.url,
26984
- name: `Abrir foto ${index + 1}: ${image.alt}`
27144
+ uri: image2.url,
27145
+ name: `Abrir foto ${index + 1}: ${image2.alt}`
26985
27146
  };
26986
27147
  const textFallback = {
26987
27148
  type: "text",
26988
- text: `Si no ves la foto ${index + 1}, \xE1brela aqu\xED: ${image.url}`
27149
+ text: `Si no ves la foto ${index + 1}, \xE1brela aqu\xED: ${image2.url}`
26989
27150
  };
26990
27151
  try {
26991
27152
  const [resolved] = await resolveImages([
26992
27153
  {
26993
- url: image.url
27154
+ url: image2.url
26994
27155
  }
26995
27156
  ], {
26996
27157
  transport,
@@ -27193,7 +27354,7 @@ async function observeMcpMediaDelivery(fingerprint, work) {
27193
27354
  __name(observeMcpMediaDelivery, "observeMcpMediaDelivery");
27194
27355
 
27195
27356
  // src/tools/animated-video.ts
27196
- import { z as z122 } from "zod";
27357
+ import { z as z123 } from "zod";
27197
27358
 
27198
27359
  // src/tools/paid-confirmation.ts
27199
27360
  function describeMarketStudyChoice(enabled) {
@@ -27442,30 +27603,30 @@ function hookVariantsLabel(count) {
27442
27603
  return count === 1 ? "1 versi\xF3n del gancho" : `${count} versiones del gancho`;
27443
27604
  }
27444
27605
  __name(hookVariantsLabel, "hookVariantsLabel");
27445
- var DurationInput = z122.union(MOTION_GRAPHICS_DURATIONS.map((d) => z122.literal(d)));
27446
- var CreateAnimatedVideoInput = z122.object({
27447
- action: z122.enum([
27606
+ var DurationInput = z123.union(MOTION_GRAPHICS_DURATIONS.map((d) => z123.literal(d)));
27607
+ var CreateAnimatedVideoInput = z123.object({
27608
+ action: z123.enum([
27448
27609
  "prepare",
27449
27610
  "status",
27450
27611
  "cancel",
27451
27612
  "generate"
27452
27613
  ]).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."),
27453
- brandId: z122.string().uuid().optional().describe("ID de un servicio propio y listo (de create_brand). Obligatorio al preparar y crear videos nuevos. Conserva el mismo brandId en reintentos; si recuperas una generaci\xF3n hist\xF3rica aceptada sin este campo, om\xEDtelo como en la petici\xF3n original. status/cancel no lo necesitan."),
27454
- websiteCaptureId: z122.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
27455
- generationRequestId: z122.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."),
27456
- confirmed: z122.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."),
27614
+ brandId: z123.string().uuid().optional().describe("ID de un servicio propio y listo (de create_brand). Obligatorio al preparar y crear videos nuevos. Conserva el mismo brandId en reintentos; si recuperas una generaci\xF3n hist\xF3rica aceptada sin este campo, om\xEDtelo como en la petici\xF3n original. status/cancel no lo necesitan."),
27615
+ websiteCaptureId: z123.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
27616
+ generationRequestId: z123.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."),
27617
+ confirmed: z123.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."),
27457
27618
  // Plain text, not `.url()`: users type «cal.com», and the web accepts it.
27458
27619
  // normalizeWebAddress (shared with the web) adds https:// and refuses
27459
27620
  // anything that is not a public http(s) address.
27460
- landingUrl: z122.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."),
27621
+ landingUrl: z123.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."),
27461
27622
  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.'),
27462
27623
  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.`),
27463
27624
  language: MotionGraphicsLanguageSchema.optional().describe('Idioma de los textos del video: "es", "en" o "pt".'),
27464
27625
  videoQuality: MotionGraphicsVideoQualitySchema.default(DEFAULT_MOTION_GRAPHICS_VIDEO_QUALITY).describe('Calidad IA: "economy" (econ\xF3mica) o "pro" (alta, por defecto). Afecta el precio de los clips IA.'),
27465
27626
  videoResolution: MotionGraphicsVideoResolutionSchema.default(DEFAULT_MOTION_GRAPHICS_VIDEO_RESOLUTION).describe('Resoluci\xF3n: "480p" (por defecto), "720p" o "1080p". 1080p solo est\xE1 disponible con videoQuality="pro".'),
27466
- notes: z122.string().trim().max(MOTION_GRAPHICS_NOTES_MAX_CHARS).optional().describe("Opcional. Idea creativa, escenarios, acciones, di\xE1logo, voz o m\xFAsica en lenguaje natural. El director puede hacer solo motion graphics, escenas reales o escenas imposibles seg\xFAn la idea; las frases gu\xEDan el guion sin garantizar reproducci\xF3n exacta."),
27627
+ notes: z123.string().trim().max(MOTION_GRAPHICS_NOTES_MAX_CHARS).optional().describe("Opcional. Idea creativa, escenarios, acciones, di\xE1logo, voz o m\xFAsica en lenguaje natural. El director puede hacer solo motion graphics, escenas reales o escenas imposibles seg\xFAn la idea; las frases gu\xEDan el guion sin garantizar reproducci\xF3n exacta."),
27467
27628
  hookVariants: MotionGraphicsHookVariantsSchema.optional().describe(`Opcional. Cantidad de videos independientes, de 1 a ${MOTION_GRAPHICS_HOOK_VARIANTS_MAX} (por defecto 1). Cada uno tiene su propio \xE1ngulo, guion y estilo visual, respetando notes, y reserva el precio completo de un video (ver la descripci\xF3n); \xFAsalo solo si el usuario lo pide.`),
27468
- music: z122.boolean().optional().describe("Opcional. M\xFAsica y efectos dirigidos seg\xFAn el negocio y el video (por defecto true), con una copia adicional solo con voces. false entrega solo voces, sin m\xFAsica ni efectos a\xF1adidos ni el cargo de m\xFAsica. \xDAsalo solo si el usuario lo pide.")
27629
+ music: z123.boolean().optional().describe("Opcional. M\xFAsica y efectos dirigidos seg\xFAn el negocio y el video (por defecto true), con una copia adicional solo con voces. false entrega solo voces, sin m\xFAsica ni efectos a\xF1adidos ni el cargo de m\xFAsica. \xDAsalo solo si el usuario lo pide.")
27469
27630
  }).strict();
27470
27631
  function captureNextAction(capture) {
27471
27632
  if (capture.status === "ready") return "Muestra la vista previa al usuario y confirma formato, duraci\xF3n, idioma, calidad IA, resoluci\xF3n y precio. Solo despu\xE9s llama create_animated_video con action=generate, este websiteCaptureId y confirmed=true.";
@@ -27518,33 +27679,33 @@ var FORMAT_LABELS = {
27518
27679
  square: "cuadrado 1:1",
27519
27680
  horizontal: "horizontal 16:9"
27520
27681
  };
27521
- var AnimatedVideoResultSchema = z122.object({
27522
- status: z122.enum([
27682
+ var AnimatedVideoResultSchema = z123.object({
27683
+ status: z123.enum([
27523
27684
  "pending",
27524
27685
  "done",
27525
27686
  "error"
27526
27687
  ]),
27527
- serviceMode: z122.literal("motion_graphics"),
27528
- finalMp4Url: z122.string().optional(),
27529
- adCopy: z122.string().optional(),
27530
- adCopies: z122.array(z122.string()).optional(),
27531
- error: z122.string().optional(),
27532
- motionGraphics: z122.object({
27688
+ serviceMode: z123.literal("motion_graphics"),
27689
+ finalMp4Url: z123.string().optional(),
27690
+ adCopy: z123.string().optional(),
27691
+ adCopies: z123.array(z123.string()).optional(),
27692
+ error: z123.string().optional(),
27693
+ motionGraphics: z123.object({
27533
27694
  stage: MotionGraphicsStageSchema,
27534
27695
  format: MotionGraphicsFormatSchema,
27535
- durationSec: z122.number(),
27536
- width: z122.number().optional(),
27537
- height: z122.number().optional(),
27696
+ durationSec: z123.number(),
27697
+ width: z123.number().optional(),
27698
+ height: z123.number().optional(),
27538
27699
  language: MotionGraphicsLanguageSchema.optional(),
27539
27700
  videoQuality: MotionGraphicsVideoQualitySchema.optional().catch(void 0),
27540
27701
  videoResolution: MotionGraphicsVideoResolutionSchema.optional().catch(void 0),
27541
- creativeBatch: z122.object({
27702
+ creativeBatch: z123.object({
27542
27703
  index: MotionGraphicsHookVariantsSchema,
27543
27704
  count: MotionGraphicsHookVariantsSchema,
27544
- tasks: z122.array(z122.object({
27545
- taskId: z122.string().uuid(),
27705
+ tasks: z123.array(z123.object({
27706
+ taskId: z123.string().uuid(),
27546
27707
  index: MotionGraphicsHookVariantsSchema,
27547
- status: z122.enum([
27708
+ status: z123.enum([
27548
27709
  "queued",
27549
27710
  "processing",
27550
27711
  "done",
@@ -27552,29 +27713,29 @@ var AnimatedVideoResultSchema = z122.object({
27552
27713
  ])
27553
27714
  })).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX)
27554
27715
  }).optional().catch(void 0),
27555
- queuedAt: z122.string().optional(),
27556
- jobsAhead: z122.number().int().nonnegative().optional(),
27557
- stageStartedAt: z122.string().optional(),
27558
- renderProgress: z122.number().optional(),
27716
+ queuedAt: z123.string().optional(),
27717
+ jobsAhead: z123.number().int().nonnegative().optional(),
27718
+ stageStartedAt: z123.string().optional(),
27719
+ renderProgress: z123.number().optional(),
27559
27720
  // AI clip fields (absent on a video paid before clips, or from an API
27560
27721
  // that predates them). Lenient: an unreadable value is dropped
27561
27722
  // instead of hiding the status.
27562
- clipCount: z122.number().int().nonnegative().optional().catch(void 0),
27563
- clipsUsed: z122.number().int().nonnegative().optional().catch(void 0),
27564
- clipPriceCents: z122.number().finite().nonnegative().optional().catch(void 0),
27565
- clipsRefunded: z122.number().int().nonnegative().optional().catch(void 0),
27723
+ clipCount: z123.number().int().nonnegative().optional().catch(void 0),
27724
+ clipsUsed: z123.number().int().nonnegative().optional().catch(void 0),
27725
+ clipPriceCents: z123.number().finite().nonnegative().optional().catch(void 0),
27726
+ clipsRefunded: z123.number().int().nonnegative().optional().catch(void 0),
27566
27727
  // Hook versions (absent from an API or a video before them): the
27567
27728
  // count ordered and, once done, the signed URLs of the EXTRA versions
27568
27729
  // (hook 2, hook 3); `finalMp4Url` is hook 1.
27569
- hookVariants: z122.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
27570
- cleanVideoUrl: z122.string().url().optional().catch(void 0),
27571
- cleanVariantUrls: z122.array(z122.string().url()).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
27572
- variantUrls: z122.array(z122.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
27730
+ hookVariants: z123.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
27731
+ cleanVideoUrl: z123.string().url().optional().catch(void 0),
27732
+ cleanVariantUrls: z123.array(z123.string().url()).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
27733
+ variantUrls: z123.array(z123.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
27573
27734
  // Extra hook versions given back, as the task recorded it once the
27574
27735
  // refunds landed (absent until then, and from an API before it).
27575
- variantsRefunded: z122.number().int().nonnegative().optional().catch(void 0),
27576
- activity: z122.array(MotionGraphicsActivitySchema).optional().catch(void 0),
27577
- previewUrl: z122.string().optional()
27736
+ variantsRefunded: z123.number().int().nonnegative().optional().catch(void 0),
27737
+ activity: z123.array(MotionGraphicsActivitySchema).optional().catch(void 0),
27738
+ previewUrl: z123.string().optional()
27578
27739
  }).passthrough()
27579
27740
  }).passthrough();
27580
27741
  function parseAnimatedVideoResult(value) {
@@ -27627,10 +27788,10 @@ function toAgentFacingAnimatedVideo(result) {
27627
27788
  ...hasSiteText && activity ? {
27628
27789
  activity: activity.map((item) => {
27629
27790
  if (!SITE_TEXT_CODES.has(item.code) || !item.text) return item;
27630
- const { text: text3, ...rest } = item;
27791
+ const { text: text4, ...rest } = item;
27631
27792
  return {
27632
27793
  ...rest,
27633
- untrustedSiteText: text3
27794
+ untrustedSiteText: text4
27634
27795
  };
27635
27796
  })
27636
27797
  } : {}
@@ -27853,7 +28014,7 @@ function registerAnimatedVideoTools(server, api) {
27853
28014
  nowMs: 0
27854
28015
  })
27855
28016
  });
27856
- const parsedTaskIds = z122.array(z122.string().uuid()).min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).safeParse(created.taskIds);
28017
+ const parsedTaskIds = z123.array(z123.string().uuid()).min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).safeParse(created.taskIds);
27857
28018
  const taskIds = parsedTaskIds.success && parsedTaskIds.data[0] === created.taskId ? parsedTaskIds.data : void 0;
27858
28019
  const receipt = {
27859
28020
  taskId: created.taskId,
@@ -27895,10 +28056,10 @@ function registerAnimatedVideoTools(server, api) {
27895
28056
  __name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
27896
28057
 
27897
28058
  // src/tools/winning-product-image.ts
27898
- import { z as z123 } from "zod";
27899
- var WinnerReferenceInput = z123.object({
27900
- runId: z123.string().uuid(),
27901
- candidateSourceId: z123.string().trim().min(1).max(160)
28059
+ import { z as z124 } from "zod";
28060
+ var WinnerReferenceInput = z124.object({
28061
+ runId: z124.string().uuid(),
28062
+ candidateSourceId: z124.string().trim().min(1).max(160)
27902
28063
  }).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
27903
28064
  async function resolveWinnerImages(api, winnerReference, images) {
27904
28065
  if (!winnerReference) return images;
@@ -27909,9 +28070,9 @@ async function resolveWinnerImages(api, winnerReference, images) {
27909
28070
  },
27910
28071
  ...images ?? []
27911
28072
  ];
27912
- const unique = combined.filter((image, index, all) => all.findIndex((candidate) => candidate.assetId === image.assetId) === index);
28073
+ const unique = combined.filter((image2, index, all) => all.findIndex((candidate) => candidate.assetId === image2.assetId) === index);
27913
28074
  if (unique.length > 5) throw new Error("M\xE1ximo 5 fotos del producto en total.");
27914
- if (!unique.every((image) => Boolean(image.assetId))) {
28075
+ if (!unique.every((image2) => Boolean(image2.assetId))) {
27915
28076
  throw new Error("Cuando reutilizas la foto encontrada, carga las fotos adicionales con request_media_upload.");
27916
28077
  }
27917
28078
  return unique;
@@ -27935,62 +28096,62 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
27935
28096
  var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
27936
28097
  var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
27937
28098
  var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
27938
- var CreateProductTaskInput = z124.object({
28099
+ var CreateProductTaskInput = z125.object({
27939
28100
  images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
27940
28101
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
27941
- projectId: z124.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
27942
- productUrl: z124.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."),
28102
+ projectId: z125.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
28103
+ productUrl: z125.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."),
27943
28104
  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.'),
27944
28105
  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.'),
27945
- price: z124.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.'),
27946
- compareAtPrice: z124.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".'),
27947
- offer: z124.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.'),
27948
- paymentMethods: z124.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.'),
27949
- productContext: z124.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."),
27950
- productLabel: z124.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.'),
28106
+ price: z125.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.'),
28107
+ compareAtPrice: z125.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".'),
28108
+ offer: z125.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.'),
28109
+ paymentMethods: z125.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.'),
28110
+ productContext: z125.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."),
28111
+ productLabel: z125.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.'),
27951
28112
  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.'),
27952
28113
  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.'),
27953
- durationSeconds: z124.union([
27954
- z124.literal(15),
27955
- z124.literal(30)
28114
+ durationSeconds: z125.union([
28115
+ z125.literal(15),
28116
+ z125.literal(30)
27956
28117
  ]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
27957
- pauseForAngleReview: z124.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."),
27958
- aiDecidesAll: z124.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."),
28118
+ pauseForAngleReview: z125.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."),
28119
+ aiDecidesAll: z125.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."),
27959
28120
  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.'),
27960
28121
  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.'),
27961
28122
  videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
27962
28123
  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).'),
27963
- videoAngleCount: z124.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."),
28124
+ videoAngleCount: z125.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."),
27964
28125
  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.'),
27965
- outputs: z124.array(z124.enum([
28126
+ outputs: z125.array(z125.enum([
27966
28127
  "landing",
27967
28128
  "video",
27968
28129
  "image"
27969
28130
  ])).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}`),
27970
- includeInitialLandingGif: z124.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."),
27971
- competitorScanEnabled: z124.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."),
28131
+ includeInitialLandingGif: z125.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."),
28132
+ competitorScanEnabled: z125.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."),
27972
28133
  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.'),
27973
- replicateWinnerWhenFound: z124.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."),
27974
- brandId: z124.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."),
27975
- actorId: z124.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."),
28134
+ replicateWinnerWhenFound: z125.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."),
28135
+ brandId: z125.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."),
28136
+ actorId: z125.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."),
27976
28137
  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.'),
27977
- creativeDirection: z124.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.'),
27978
- headline: z124.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."),
27979
- subheadline: z124.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."),
28138
+ creativeDirection: z125.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.'),
28139
+ headline: z125.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."),
28140
+ subheadline: z125.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."),
27980
28141
  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".'),
27981
28142
  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".')
27982
28143
  }).strict();
27983
- var CreateServiceVideoInput = z124.object({
27984
- landingUrl: z124.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
27985
- additionalContext: z124.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
28144
+ var CreateServiceVideoInput = z125.object({
28145
+ landingUrl: z125.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
28146
+ additionalContext: z125.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
27986
28147
  language: Lang.describe("Idioma del video: es, en o pt."),
27987
- voiceId: z124.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.'),
27988
- brandId: z124.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
27989
- reviewMode: z124.enum([
28148
+ voiceId: z125.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.'),
28149
+ brandId: z125.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
28150
+ reviewMode: z125.enum([
27990
28151
  "automatic",
27991
28152
  "guided"
27992
28153
  ]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
27993
- videoPreset: z124.enum([
28154
+ videoPreset: z125.enum([
27994
28155
  "auto",
27995
28156
  "ugc_dynamic",
27996
28157
  "ugc_how_to",
@@ -28000,128 +28161,128 @@ var CreateServiceVideoInput = z124.object({
28000
28161
  videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
28001
28162
  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.')
28002
28163
  }).strict();
28003
- var GetTaskStatusInput = z124.object({
28004
- taskId: z124.string().min(1),
28005
- waitSeconds: z124.number().int().min(0).max(120).optional()
28164
+ var GetTaskStatusInput = z125.object({
28165
+ taskId: z125.string().min(1),
28166
+ waitSeconds: z125.number().int().min(0).max(120).optional()
28006
28167
  });
28007
- var ListTasksInput = z124.object({
28008
- limit: z124.number().int().min(1).max(50).optional(),
28009
- offset: z124.number().int().min(0).optional(),
28010
- search: z124.string().optional()
28168
+ var ListTasksInput = z125.object({
28169
+ limit: z125.number().int().min(1).max(50).optional(),
28170
+ offset: z125.number().int().min(0).optional(),
28171
+ search: z125.string().optional()
28011
28172
  });
28012
28173
  var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
28013
28174
  var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
28014
- var EditTaskDraftInput = z124.object({
28015
- taskId: z124.string().min(1),
28016
- angleIndex: z124.number().int().min(0),
28017
- angle: z124.object({
28018
- angle: z124.string().min(1).max(480),
28019
- buyerPersona: z124.string().min(1).max(360),
28020
- actor: z124.string().min(1).max(360).optional(),
28021
- actorId: z124.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."),
28022
- gender: z124.enum([
28175
+ var EditTaskDraftInput = z125.object({
28176
+ taskId: z125.string().min(1),
28177
+ angleIndex: z125.number().int().min(0),
28178
+ angle: z125.object({
28179
+ angle: z125.string().min(1).max(480),
28180
+ buyerPersona: z125.string().min(1).max(360),
28181
+ actor: z125.string().min(1).max(360).optional(),
28182
+ actorId: z125.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."),
28183
+ gender: z125.enum([
28023
28184
  "female",
28024
28185
  "male"
28025
28186
  ]).optional(),
28026
- scriptNotes: z124.string().max(2e3).optional()
28187
+ scriptNotes: z125.string().max(2e3).optional()
28027
28188
  })
28028
28189
  });
28029
- var PendingActionPayload = z124.discriminatedUnion("kind", [
28030
- z124.object({
28031
- kind: z124.literal("product_reference_set_approval"),
28190
+ var PendingActionPayload = z125.discriminatedUnion("kind", [
28191
+ z125.object({
28192
+ kind: z125.literal("product_reference_set_approval"),
28032
28193
  scope: ProductReferenceScopeEnum.optional(),
28033
- scopeKey: z124.string().min(1).max(120).optional(),
28034
- scopeSnapshotId: z124.string().uuid().optional(),
28035
- expectedScopeHash: z124.string().min(1).max(128).optional(),
28194
+ scopeKey: z125.string().min(1).max(120).optional(),
28195
+ scopeSnapshotId: z125.string().uuid().optional(),
28196
+ expectedScopeHash: z125.string().min(1).max(128).optional(),
28036
28197
  decision: ProductReferenceResolutionDecisionEnum,
28037
28198
  reason: ProductReferenceRejectionReasonEnum.optional(),
28038
- affectedRefKeys: z124.array(z124.string().min(1).max(200)).min(1).optional(),
28039
- affectedPhotoNumbers: z124.array(z124.number().int().positive()).min(1).optional(),
28040
- recoveryAction: z124.enum([
28199
+ affectedRefKeys: z125.array(z125.string().min(1).max(200)).min(1).optional(),
28200
+ affectedPhotoNumbers: z125.array(z125.number().int().positive()).min(1).optional(),
28201
+ recoveryAction: z125.enum([
28041
28202
  "remove",
28042
28203
  "replace",
28043
28204
  "upload",
28044
28205
  "return_to_selection"
28045
28206
  ]).optional()
28046
28207
  }),
28047
- z124.object({
28048
- kind: z124.literal("product_reference_confirmation"),
28049
- selectedPhotoNumbers: z124.array(z124.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."),
28208
+ z125.object({
28209
+ kind: z125.literal("product_reference_confirmation"),
28210
+ selectedPhotoNumbers: z125.array(z125.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."),
28050
28211
  userChoice: ProductReferenceUserChoiceEnum.optional(),
28051
- confirmedProductNames: z124.array(z124.string().min(1).max(120)).min(2).max(8).optional(),
28212
+ confirmedProductNames: z125.array(z125.string().min(1).max(120)).min(2).max(8).optional(),
28052
28213
  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."),
28053
28214
  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."),
28054
- useMultiSceneShowcase: z124.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
28215
+ useMultiSceneShowcase: z125.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
28055
28216
  }),
28056
- z124.object({
28057
- kind: z124.literal("angle_review_approval"),
28217
+ z125.object({
28218
+ kind: z125.literal("angle_review_approval"),
28058
28219
  // All edits are optional — empty action body just approves the
28059
28220
  // backend-generated draft as-is. Field shapes mirror the angle-review
28060
28221
  // request contracts in @packages/types/wizard.ts; the handler routes to
28061
28222
  // the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
28062
- customAngle: z124.string().min(1).max(480).optional(),
28223
+ customAngle: z125.string().min(1).max(480).optional(),
28063
28224
  // Keep the shared MCP action within the strictest downstream contract:
28064
28225
  // autopilot/image resume endpoints cap these fields at 1500 characters.
28065
- painPoints: z124.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
28066
- benefits: z124.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
28226
+ painPoints: z125.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
28227
+ benefits: z125.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
28067
28228
  // Same policy as the two fields above: the strictest downstream contract
28068
28229
  // wins. The image endpoint caps each feature at 240 while landing/video
28069
28230
  // accept 300, and this single action routes to whichever the task is — so
28070
28231
  // accepting 300 here turns a 250-character feature on an image task into
28071
28232
  // an opaque HTTP 400 after the model already believed it had been saved.
28072
- features: z124.array(z124.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
28073
- buyerPersona: z124.string().min(1).max(360).optional(),
28233
+ features: z125.array(z125.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
28234
+ buyerPersona: z125.string().min(1).max(360).optional(),
28074
28235
  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.'),
28075
- actor: z124.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."),
28076
- actorId: z124.string().max(120).nullable().optional(),
28077
- creativeDirection: z124.string().max(2e3).optional(),
28078
- selectedAngleNumbers: z124.array(z124.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."),
28079
- angleEdits: z124.array(z124.object({
28080
- angleNumber: z124.number().int().positive(),
28081
- narrativeSelection: z124.enum([
28236
+ actor: z125.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."),
28237
+ actorId: z125.string().max(120).nullable().optional(),
28238
+ creativeDirection: z125.string().max(2e3).optional(),
28239
+ selectedAngleNumbers: z125.array(z125.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."),
28240
+ angleEdits: z125.array(z125.object({
28241
+ angleNumber: z125.number().int().positive(),
28242
+ narrativeSelection: z125.enum([
28082
28243
  "market",
28083
28244
  "guided"
28084
28245
  ]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
28085
- angle: z124.string().min(1).max(480).optional(),
28086
- buyerPersona: z124.string().min(1).max(360).optional(),
28246
+ angle: z125.string().min(1).max(480).optional(),
28247
+ buyerPersona: z125.string().min(1).max(360).optional(),
28087
28248
  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.'),
28088
- actor: z124.string().min(1).max(360).optional(),
28089
- actorId: z124.string().max(120).nullable().optional(),
28090
- creativeDirection: z124.string().max(2e3).optional()
28249
+ actor: z125.string().min(1).max(360).optional(),
28250
+ actorId: z125.string().max(120).nullable().optional(),
28251
+ creativeDirection: z125.string().max(2e3).optional()
28091
28252
  }).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)."),
28092
- gapDurationSeconds: z124.union([
28093
- z124.literal(15),
28094
- z124.literal(30)
28253
+ gapDurationSeconds: z125.union([
28254
+ z125.literal(15),
28255
+ z125.literal(30)
28095
28256
  ]).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.")
28096
28257
  }),
28097
- z124.object({
28098
- kind: z124.literal("service_angle_approval"),
28099
- angleId: z124.string().uuid().optional(),
28100
- angleNumber: z124.number().int().positive().optional(),
28101
- content: z124.string().min(1).max(480).optional(),
28102
- creativeDirection: z124.string().min(1).max(1500).optional(),
28103
- actor: z124.string().min(1).max(360).optional()
28258
+ z125.object({
28259
+ kind: z125.literal("service_angle_approval"),
28260
+ angleId: z125.string().uuid().optional(),
28261
+ angleNumber: z125.number().int().positive().optional(),
28262
+ content: z125.string().min(1).max(480).optional(),
28263
+ creativeDirection: z125.string().min(1).max(1500).optional(),
28264
+ actor: z125.string().min(1).max(360).optional()
28104
28265
  }),
28105
- z124.object({
28106
- kind: z124.literal("service_script_approval"),
28107
- voiceovers: z124.record(z124.string(), z124.string().min(1).max(600)).optional(),
28108
- visualDirections: z124.record(z124.string(), z124.string().min(1).max(1200)).optional(),
28109
- voiceoversByScene: z124.record(z124.string(), z124.string().min(1).max(600)).optional(),
28110
- visualDirectionsByScene: z124.record(z124.string(), z124.string().min(1).max(1200)).optional()
28266
+ z125.object({
28267
+ kind: z125.literal("service_script_approval"),
28268
+ voiceovers: z125.record(z125.string(), z125.string().min(1).max(600)).optional(),
28269
+ visualDirections: z125.record(z125.string(), z125.string().min(1).max(1200)).optional(),
28270
+ voiceoversByScene: z125.record(z125.string(), z125.string().min(1).max(600)).optional(),
28271
+ visualDirectionsByScene: z125.record(z125.string(), z125.string().min(1).max(1200)).optional()
28111
28272
  })
28112
28273
  ]);
28113
- var ResolvePendingActionInput = z124.object({
28114
- taskId: z124.string().min(1),
28274
+ var ResolvePendingActionInput = z125.object({
28275
+ taskId: z125.string().min(1),
28115
28276
  action: PendingActionPayload
28116
28277
  }).strict();
28117
28278
  function resolveVariantConfirmVideoTier(action) {
28118
28279
  return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
28119
28280
  }
28120
28281
  __name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
28121
- var StatusForResolveSchema = z124.object({
28282
+ var StatusForResolveSchema = z125.object({
28122
28283
  // Metadata used to select the backend resume contract. Older API responses
28123
28284
  // may omit these fields, so the resolver keeps the generic fallback.
28124
- kind: z124.enum([
28285
+ kind: z125.enum([
28125
28286
  "autopilot",
28126
28287
  "video",
28127
28288
  "image",
@@ -28129,18 +28290,18 @@ var StatusForResolveSchema = z124.object({
28129
28290
  "mix",
28130
28291
  "service"
28131
28292
  ]).optional(),
28132
- selectedOutputs: z124.array(z124.enum([
28293
+ selectedOutputs: z125.array(z125.enum([
28133
28294
  "landing",
28134
28295
  "video",
28135
28296
  "image"
28136
28297
  ])).optional(),
28137
- videoAngleCount: z124.number().int().min(1).max(3).optional(),
28138
- ugcFormat: z124.enum([
28298
+ videoAngleCount: z125.number().int().min(1).max(3).optional(),
28299
+ ugcFormat: z125.enum([
28139
28300
  "single_8s",
28140
28301
  "single_15s",
28141
28302
  "double_30s"
28142
28303
  ]).optional(),
28143
- videoStyle: z124.enum([
28304
+ videoStyle: z125.enum([
28144
28305
  "ugc",
28145
28306
  "cartoon_3d",
28146
28307
  "product_only",
@@ -28150,13 +28311,13 @@ var StatusForResolveSchema = z124.object({
28150
28311
  videoQuality: VideoQualityEnum.optional(),
28151
28312
  videoRouteId: VideoRouteIdEnum.optional(),
28152
28313
  videoModel: TaskVideoModelEnum.optional(),
28153
- videoTier: z124.enum([
28314
+ videoTier: z125.enum([
28154
28315
  "legacy",
28155
28316
  "standard",
28156
28317
  "pro",
28157
28318
  "single_call"
28158
28319
  ]).optional(),
28159
- videoResolution: z124.enum([
28320
+ videoResolution: z125.enum([
28160
28321
  "480p",
28161
28322
  "720p"
28162
28323
  ]).optional(),
@@ -28164,60 +28325,60 @@ var StatusForResolveSchema = z124.object({
28164
28325
  // A task created before a narrative was blocked/hidden must still parse,
28165
28326
  // or resolve_pending_action could never approve it.
28166
28327
  narrativeStyle: NarrativeStyle.optional(),
28167
- pauseForVideoScriptReview: z124.boolean().optional(),
28168
- pendingUserAction: z124.object({
28169
- kind: z124.string(),
28170
- candidateGrouping: z124.string().optional(),
28171
- selectedImageUrls: z124.array(z124.string()).optional(),
28172
- proposedProductNames: z124.array(z124.string()).optional(),
28328
+ pauseForVideoScriptReview: z125.boolean().optional(),
28329
+ pendingUserAction: z125.object({
28330
+ kind: z125.string(),
28331
+ candidateGrouping: z125.string().optional(),
28332
+ selectedImageUrls: z125.array(z125.string()).optional(),
28333
+ proposedProductNames: z125.array(z125.string()).optional(),
28173
28334
  // Adaptive reference questions are server-owned. Echo only the evidence
28174
28335
  // identity and the choices shown by the current snapshot; never accept a
28175
28336
  // client-supplied reference set as authorization.
28176
- options: z124.array(ProductReferenceUserChoiceEnum).max(4).optional(),
28177
- mode: z124.enum([
28337
+ options: z125.array(ProductReferenceUserChoiceEnum).max(4).optional(),
28338
+ mode: z125.enum([
28178
28339
  "question",
28179
28340
  "visual_recovery"
28180
28341
  ]).optional(),
28181
28342
  /** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
28182
- canKeepSelection: z124.boolean().optional(),
28183
- decisionKey: z124.string().optional(),
28184
- questionOrdinal: z124.number().int().min(1).max(5).optional(),
28185
- questionCeiling: z124.union([
28186
- z124.literal(3),
28187
- z124.literal(5)
28343
+ canKeepSelection: z125.boolean().optional(),
28344
+ decisionKey: z125.string().optional(),
28345
+ questionOrdinal: z125.number().int().min(1).max(5).optional(),
28346
+ questionCeiling: z125.union([
28347
+ z125.literal(3),
28348
+ z125.literal(5)
28188
28349
  ]).optional(),
28189
- referenceEvidenceVersion: z124.number().int().positive().optional(),
28190
- expectedEvidenceHash: z124.string().optional(),
28191
- question: z124.object({
28192
- prompt: z124.string().min(1).max(240),
28193
- helpText: z124.string().min(1).max(300).optional(),
28194
- options: z124.array(z124.object({
28350
+ referenceEvidenceVersion: z125.number().int().positive().optional(),
28351
+ expectedEvidenceHash: z125.string().optional(),
28352
+ question: z125.object({
28353
+ prompt: z125.string().min(1).max(240),
28354
+ helpText: z125.string().min(1).max(300).optional(),
28355
+ options: z125.array(z125.object({
28195
28356
  value: ProductReferenceUserChoiceEnum,
28196
- label: z124.string().min(1).max(120),
28197
- description: z124.string().min(1).max(240).optional()
28357
+ label: z125.string().min(1).max(120),
28358
+ description: z125.string().min(1).max(240).optional()
28198
28359
  })).min(2).max(4)
28199
28360
  }).optional(),
28200
28361
  scope: ProductReferenceScopeEnum.optional(),
28201
- scopeKey: z124.string().optional(),
28202
- scopeSnapshotId: z124.string().uuid().optional(),
28203
- scopeHash: z124.string().optional(),
28204
- baseReferenceSetHash: z124.string().optional(),
28205
- phase: z124.enum([
28362
+ scopeKey: z125.string().optional(),
28363
+ scopeSnapshotId: z125.string().uuid().optional(),
28364
+ scopeHash: z125.string().optional(),
28365
+ baseReferenceSetHash: z125.string().optional(),
28366
+ phase: z125.enum([
28206
28367
  "preparation",
28207
28368
  "final"
28208
28369
  ]).optional(),
28209
- selectedRefKeys: z124.array(z124.string().min(1).max(200)).optional(),
28210
- allowedDecisions: z124.array(ProductReferenceResolutionDecisionEnum).optional(),
28211
- previews: z124.array(z124.object({
28212
- refKey: z124.string().min(1).max(200)
28370
+ selectedRefKeys: z125.array(z125.string().min(1).max(200)).optional(),
28371
+ allowedDecisions: z125.array(ProductReferenceResolutionDecisionEnum).optional(),
28372
+ previews: z125.array(z125.object({
28373
+ refKey: z125.string().min(1).max(200)
28213
28374
  }).passthrough()).optional(),
28214
- customAngleDraft: z124.string().optional(),
28215
- painPointsDraft: z124.string().optional(),
28216
- benefitsDraft: z124.string().optional(),
28217
- featuresDraft: z124.array(z124.string()).optional(),
28218
- angleOptions: z124.array(z124.object({
28219
- index: z124.number().int().nonnegative(),
28220
- angle: z124.string().min(1)
28375
+ customAngleDraft: z125.string().optional(),
28376
+ painPointsDraft: z125.string().optional(),
28377
+ benefitsDraft: z125.string().optional(),
28378
+ featuresDraft: z125.array(z125.string()).optional(),
28379
+ angleOptions: z125.array(z125.object({
28380
+ index: z125.number().int().nonnegative(),
28381
+ angle: z125.string().min(1)
28221
28382
  }).passthrough()).min(1).max(5).optional(),
28222
28383
  // Recommendation consumed only when the caller explicitly sends
28223
28384
  // gapDurationSeconds: 30 in the angle approval action.
@@ -28227,17 +28388,17 @@ var StatusForResolveSchema = z124.object({
28227
28388
  // keys. `actorId` (the saved custom actor the picker stored) was silently
28228
28389
  // dropped here, so the approval handler below could not echo it back on the
28229
28390
  // PATCH — the selection looked accepted and reached no render.
28230
- angles: z124.array(z124.object({
28231
- id: z124.string().uuid(),
28232
- content: z124.string(),
28233
- creativeDirection: z124.string(),
28234
- actor: z124.string(),
28235
- actorId: z124.string().nullable().optional()
28391
+ angles: z125.array(z125.object({
28392
+ id: z125.string().uuid(),
28393
+ content: z125.string(),
28394
+ creativeDirection: z125.string(),
28395
+ actor: z125.string(),
28396
+ actorId: z125.string().nullable().optional()
28236
28397
  }).passthrough()).optional(),
28237
- panels: z124.array(z124.object({
28238
- beatId: z124.string(),
28239
- voiceover: z124.string(),
28240
- visualDirection: z124.string()
28398
+ panels: z125.array(z125.object({
28399
+ beatId: z125.string(),
28400
+ voiceover: z125.string(),
28401
+ visualDirection: z125.string()
28241
28402
  }).passthrough()).optional()
28242
28403
  }).optional()
28243
28404
  }).passthrough();
@@ -28590,8 +28751,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
28590
28751
  server.registerTool("verify_landing_commerce", {
28591
28752
  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.",
28592
28753
  inputSchema: {
28593
- taskId: z124.string().uuid(),
28594
- editId: z124.string().uuid()
28754
+ taskId: z125.string().uuid(),
28755
+ editId: z125.string().uuid()
28595
28756
  },
28596
28757
  annotations: OVERWRITES_EXTERNAL
28597
28758
  }, async (input) => {
@@ -28783,15 +28944,15 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
28783
28944
  const rawOutputs = await fetchTaskOutputs(api, input.taskId, {
28784
28945
  signal
28785
28946
  });
28786
- const imageContent = await buildMcpGeneratedImageContent(rawOutputs.images.map((image, i) => ({
28787
- url: image.url,
28947
+ const imageContent = await buildMcpGeneratedImageContent(rawOutputs.images.map((image2, i) => ({
28948
+ url: image2.url,
28788
28949
  alt: `Imagen ${i + 1}`
28789
28950
  })), transport);
28790
28951
  const outputs = proxifyOutputs(rawOutputs, proxyBaseUrl);
28791
28952
  const media = {
28792
28953
  images: [
28793
- ...outputs.images.map((image, i) => ({
28794
- url: image.url,
28954
+ ...outputs.images.map((image2, i) => ({
28955
+ url: image2.url,
28795
28956
  alt: `Imagen ${i + 1}`
28796
28957
  })),
28797
28958
  ...outputs.landing.sections.map((section) => ({
@@ -28862,16 +29023,16 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
28862
29023
  if (input.search) qs.set("search", input.search);
28863
29024
  const path3 = `/v1/tasks${qs.toString() ? "?" + qs.toString() : ""}`;
28864
29025
  const r = await api.getJson(path3);
28865
- const page = z124.object({
28866
- items: z124.array(z124.unknown())
29026
+ const page = z125.object({
29027
+ items: z125.array(z125.unknown())
28867
29028
  }).passthrough().safeParse(r);
28868
29029
  if (!page.success) return asText(r);
28869
29030
  return asText({
28870
29031
  ...page.data,
28871
29032
  items: page.data.items.map((item) => {
28872
- const servicePage = z124.object({
28873
- taskId: z124.string().uuid(),
28874
- resourceType: z124.literal("service_page")
29033
+ const servicePage = z125.object({
29034
+ taskId: z125.string().uuid(),
29035
+ resourceType: z125.literal("service_page")
28875
29036
  }).passthrough().safeParse(item);
28876
29037
  if (!servicePage.success) return item;
28877
29038
  return {
@@ -29361,28 +29522,28 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
29361
29522
  __name(registerTaskTools, "registerTaskTools");
29362
29523
 
29363
29524
  // src/tools/brands.ts
29364
- import { z as z125 } from "zod";
29525
+ import { z as z126 } from "zod";
29365
29526
  var guidance2 = getProductMakerCapabilityModelGuidance("create_brand");
29366
29527
  var BRAND_START_REPLAY_WINDOW_MS = 15 * 60 * 1e3;
29367
29528
  var BRAND_NOTES_MAX_CHARS = 2e4;
29368
29529
  var BRAND_AMBIGUOUS_REQUEST_RETENTION_MS = 24 * 60 * 60 * 1e3;
29369
29530
  var BRAND_CREATION_REQUEST_LIMIT = 500;
29370
29531
  var brandCreationRequests = /* @__PURE__ */ new Map();
29371
- var CreateBrandInput = z125.object({
29372
- action: z125.enum([
29532
+ var CreateBrandInput = z126.object({
29533
+ action: z126.enum([
29373
29534
  "start",
29374
29535
  "status",
29375
29536
  "list"
29376
29537
  ]).default("start").describe("start cotiza (sin confirmed) o inicia (confirmed=true) el an\xE1lisis; status consulta brandId hasta ready o failed; list muestra las marcas que el usuario ya tiene."),
29377
- sourceUrl: z125.string().trim().min(1).max(BRAND_SOURCE_URL_MAX_LENGTH).optional().describe("Instagram, Facebook, TikTok o web p\xFAblica del negocio, como la dio el usuario (\xAB@sanlucasbarberia\xBB, \xABinstagram.com/sanlucasbarberia\xBB, \xABmibarberia.com\xBB). Obligatorio para start."),
29378
- businessNotes: z125.string().trim().max(BRAND_NOTES_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cuente de su negocio en el chat (servicios y precios, WhatsApp, ciudad o zona, horarios). Se guarda como documento del negocio y llega tal cual a la marca y a su landing. Copia sus palabras; no inventes datos."),
29379
- language: z125.enum([
29538
+ sourceUrl: z126.string().trim().min(1).max(BRAND_SOURCE_URL_MAX_LENGTH).optional().describe("Instagram, Facebook, TikTok o web p\xFAblica del negocio, como la dio el usuario (\xAB@sanlucasbarberia\xBB, \xABinstagram.com/sanlucasbarberia\xBB, \xABmibarberia.com\xBB). Obligatorio para start."),
29539
+ businessNotes: z126.string().trim().max(BRAND_NOTES_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cuente de su negocio en el chat (servicios y precios, WhatsApp, ciudad o zona, horarios). Se guarda como documento del negocio y llega tal cual a la marca y a su landing. Copia sus palabras; no inventes datos."),
29540
+ language: z126.enum([
29380
29541
  "es",
29381
29542
  "en",
29382
29543
  "pt"
29383
29544
  ]).optional().describe("Idioma de la conversaci\xF3n. Solo se usa si la p\xE1gina del negocio no deja claro su idioma."),
29384
- confirmed: z125.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, start solo cotiza y no cobra."),
29385
- brandId: z125.string().uuid().optional().describe("ID de la marca. Obligatorio para status; no lo inventes.")
29545
+ confirmed: z126.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, start solo cotiza y no cobra."),
29546
+ brandId: z126.string().uuid().optional().describe("ID de la marca. Obligatorio para status; no lo inventes.")
29386
29547
  }).strict();
29387
29548
  function normalizeBrandSourceUrl(raw) {
29388
29549
  const value = raw.trim();
@@ -29666,31 +29827,31 @@ __name(registerBrandTools, "registerBrandTools");
29666
29827
 
29667
29828
  // src/tools/service-landing.ts
29668
29829
  import { createHash as createHash3, randomUUID } from "crypto";
29669
- import { z as z126 } from "zod";
29830
+ import { z as z127 } from "zod";
29670
29831
  var guidance3 = getProductMakerCapabilityModelGuidance("create_service_landing");
29671
29832
  var SERVICE_LANDING_KEY_NAMESPACE = "6f1d8c2a-3b4e-5f60-8a7b-9c0d1e2f3a4b";
29672
29833
  var SERVICE_LANDING_INFO_MAX_CHARS = 2e4;
29673
- var CreateServiceLandingInput = z126.object({
29674
- action: z126.enum([
29834
+ var CreateServiceLandingInput = z127.object({
29835
+ action: z127.enum([
29675
29836
  "prepare",
29676
29837
  "build",
29677
29838
  "status",
29678
29839
  "publish"
29679
29840
  ]).default("prepare").describe("prepare (gratis) crea o retoma la landing de la marca y da el precio; build (pagado, confirmed=true) genera la p\xE1gina directamente con la marca y los datos guardados; status sigue el avance; publish la publica y devuelve su enlace."),
29680
- brandId: z126.string().uuid().optional().describe("ID de la marca (de create_brand). Obligatorio para prepare. Nunca un taskId de producto."),
29681
- servicePageId: z126.string().uuid().optional().describe("ID de la landing que devolvi\xF3 prepare. Obligatorio para build, status y publish."),
29682
- businessInfo: z126.string().trim().max(SERVICE_LANDING_INFO_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cont\xF3 del negocio y no estaba en su marca: servicios y precios, WhatsApp o tel\xE9fono, ciudad o zona, horarios. Copia sus palabras; no inventes datos."),
29683
- confirmed: z126.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio total y que el usuario acepte. Obligatorio para build."),
29684
- maxCredits: z126.number().int().positive().optional().describe("El total en cr\xE9ditos que el usuario acept\xF3 (el que devolvi\xF3 prepare). Obligatorio para build: ninguna etapa se inicia si su precio supera este total."),
29685
- operationId: z126.string().uuid().optional().describe("Opcional en status: la operaci\xF3n que devolvi\xF3 build."),
29686
- slug: z126.string().trim().toLowerCase().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(64).optional().describe("Opcional en publish: la direcci\xF3n corta de la p\xE1gina (ej. sanlucas-barberia). Si falta se usa la sugerida desde el nombre del negocio.")
29841
+ brandId: z127.string().uuid().optional().describe("ID de la marca (de create_brand). Obligatorio para prepare. Nunca un taskId de producto."),
29842
+ servicePageId: z127.string().uuid().optional().describe("ID de la landing que devolvi\xF3 prepare. Obligatorio para build, status y publish."),
29843
+ businessInfo: z127.string().trim().max(SERVICE_LANDING_INFO_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cont\xF3 del negocio y no estaba en su marca: servicios y precios, WhatsApp o tel\xE9fono, ciudad o zona, horarios. Copia sus palabras; no inventes datos."),
29844
+ confirmed: z127.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio total y que el usuario acepte. Obligatorio para build."),
29845
+ maxCredits: z127.number().int().positive().optional().describe("El total en cr\xE9ditos que el usuario acept\xF3 (el que devolvi\xF3 prepare). Obligatorio para build: ninguna etapa se inicia si su precio supera este total."),
29846
+ operationId: z127.string().uuid().optional().describe("Opcional en status: la operaci\xF3n que devolvi\xF3 build."),
29847
+ slug: z127.string().trim().toLowerCase().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(64).optional().describe("Opcional en publish: la direcci\xF3n corta de la p\xE1gina (ej. sanlucas-barberia). Si falta se usa la sugerida desde el nombre del negocio.")
29687
29848
  }).strict();
29688
29849
  function serviceKey(...parts) {
29689
29850
  return deriveUuidV5(parts.join(":"), SERVICE_LANDING_KEY_NAMESPACE);
29690
29851
  }
29691
29852
  __name(serviceKey, "serviceKey");
29692
- function textHash(text3) {
29693
- return createHash3("sha256").update(text3, "utf8").digest("hex").slice(0, 16);
29853
+ function textHash(text4) {
29854
+ return createHash3("sha256").update(text4, "utf8").digest("hex").slice(0, 16);
29694
29855
  }
29695
29856
  __name(textHash, "textHash");
29696
29857
  function quoteRange(quote) {
@@ -30058,7 +30219,7 @@ function registerServiceLandingTools(server, api) {
30058
30219
  __name(registerServiceLandingTools, "registerServiceLandingTools");
30059
30220
 
30060
30221
  // src/tools/service-images.ts
30061
- import { z as z127 } from "zod";
30222
+ import { z as z128 } from "zod";
30062
30223
  var guidance4 = getProductMakerCapabilityModelGuidance("create_service_images");
30063
30224
  var SERVICE_IMAGE_FORMATS = [
30064
30225
  "4:5",
@@ -30071,23 +30232,23 @@ var LANGUAGE_TAGS = {
30071
30232
  en: "en-US",
30072
30233
  pt: "pt-BR"
30073
30234
  };
30074
- var CreateServiceImagesInput = z127.object({
30075
- brandId: z127.string().uuid().optional().describe("ID de un servicio propio y listo (de create_brand), obligatorio para cotizar y crear im\xE1genes nuevas. En un retry hist\xF3rico ya confirmado que originalmente no ten\xEDa este campo, conserva la petici\xF3n original. Nunca un taskId de producto."),
30076
- instruction: z127.string().trim().max(4e3).optional().describe("Opcional. Qu\xE9 servicio o promoci\xF3n mostrar, con las palabras del usuario (ej. \xABcorte + barba a $35.000 los martes\xBB). Si se omite, la IA propone la imagen usando la informaci\xF3n del servicio."),
30077
- delegateToAi: z127.boolean().optional().describe("true si el usuario prefiere que la IA elija qu\xE9 mostrar a partir de su servicio. Tambi\xE9n se delega cuando instruction est\xE1 vac\xEDo."),
30078
- format: z127.enum(SERVICE_IMAGE_FORMATS).optional().describe('Formato: "4:5" (feed, por defecto), "9:16" (historias/reels) o "1:1" (cuadrado).'),
30079
- count: z127.number().int().min(1).max(SERVICE_IMAGE_MAX_COUNT).optional().describe("Cu\xE1ntas im\xE1genes, de 1 a 3 (por defecto 1)."),
30080
- quality: z127.enum([
30235
+ var CreateServiceImagesInput = z128.object({
30236
+ brandId: z128.string().uuid().optional().describe("ID de un servicio propio y listo (de create_brand), obligatorio para cotizar y crear im\xE1genes nuevas. En un retry hist\xF3rico ya confirmado que originalmente no ten\xEDa este campo, conserva la petici\xF3n original. Nunca un taskId de producto."),
30237
+ instruction: z128.string().trim().max(4e3).optional().describe("Opcional. Qu\xE9 servicio o promoci\xF3n mostrar, con las palabras del usuario (ej. \xABcorte + barba a $35.000 los martes\xBB). Si se omite, la IA propone la imagen usando la informaci\xF3n del servicio."),
30238
+ delegateToAi: z128.boolean().optional().describe("true si el usuario prefiere que la IA elija qu\xE9 mostrar a partir de su servicio. Tambi\xE9n se delega cuando instruction est\xE1 vac\xEDo."),
30239
+ format: z128.enum(SERVICE_IMAGE_FORMATS).optional().describe('Formato: "4:5" (feed, por defecto), "9:16" (historias/reels) o "1:1" (cuadrado).'),
30240
+ count: z128.number().int().min(1).max(SERVICE_IMAGE_MAX_COUNT).optional().describe("Cu\xE1ntas im\xE1genes, de 1 a 3 (por defecto 1)."),
30241
+ quality: z128.enum([
30081
30242
  "standard",
30082
30243
  "high"
30083
30244
  ]).optional().describe('Calidad: "standard" (por defecto) o "high" (m\xE1s cara; no disponible en 4:5).'),
30084
- language: z127.enum([
30245
+ language: z128.enum([
30085
30246
  "es",
30086
30247
  "en",
30087
30248
  "pt"
30088
30249
  ]).optional().describe("Idioma de los textos de la imagen (por defecto es)."),
30089
- adCopy: z127.boolean().optional().describe("Compatibilidad con clientes anteriores: el copy para publicar siempre est\xE1 incluido en cada imagen de servicios."),
30090
- confirmed: z127.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, solo cotiza y no cobra.")
30250
+ adCopy: z128.boolean().optional().describe("Compatibilidad con clientes anteriores: el copy para publicar siempre est\xE1 incluido en cada imagen de servicios."),
30251
+ confirmed: z128.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, solo cotiza y no cobra.")
30091
30252
  }).strict();
30092
30253
  function serviceImageModel(quality) {
30093
30254
  return quality === "high" ? AD_CREATIVE_MODELS.PREMIUM : AD_CREATIVE_MODELS.STANDARD;
@@ -30204,7 +30365,7 @@ function registerServiceImageTools(server, api, options = {}) {
30204
30365
  nextAction: "Dile al usuario que est\xE1s creando sus im\xE1genes. Llama get_task_status con este taskId (waitSeconds=45) hasta done (trae las im\xE1genes reales de ProductMaker) o error. Muestra los recursos de imagen devueltos directamente en el chat. Nunca generes ni recrees una imagen sustituta con otra herramienta. Si la vista previa falla, explica el fallo y conserva los enlaces protegidos devueltos."
30205
30366
  });
30206
30367
  } catch (error) {
30207
- if (error instanceof z127.ZodError) throw invalidInputFromZod(error);
30368
+ if (error instanceof z128.ZodError) throw invalidInputFromZod(error);
30208
30369
  throw translateError(error);
30209
30370
  }
30210
30371
  });
@@ -30212,7 +30373,7 @@ function registerServiceImageTools(server, api, options = {}) {
30212
30373
  __name(registerServiceImageTools, "registerServiceImageTools");
30213
30374
 
30214
30375
  // src/tools/creatives.ts
30215
- import { z as z128 } from "zod";
30376
+ import { z as z129 } from "zod";
30216
30377
  var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
30217
30378
  var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
30218
30379
  var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
@@ -30223,72 +30384,72 @@ var CreativeRefs = {
30223
30384
  images: ImagesInput,
30224
30385
  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.'),
30225
30386
  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.'),
30226
- price: z128.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.'),
30227
- offer: z128.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.'),
30228
- compareAtPrice: z128.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
30229
- productContext: z128.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."),
30230
- productLabel: z128.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.'),
30231
- buyerPersona: z128.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.'),
30232
- isCombo: z128.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
30233
- competitorScanEnabled: z128.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."),
30234
- brandId: z128.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.")
30387
+ price: z129.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.'),
30388
+ offer: z129.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.'),
30389
+ compareAtPrice: z129.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
30390
+ productContext: z129.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."),
30391
+ productLabel: z129.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.'),
30392
+ buyerPersona: z129.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.'),
30393
+ isCombo: z129.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
30394
+ competitorScanEnabled: z129.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."),
30395
+ brandId: z129.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.")
30235
30396
  };
30236
- var VideoPresenter = z128.discriminatedUnion("mode", [
30237
- z128.object({
30238
- mode: z128.literal("none")
30397
+ var VideoPresenter = z129.discriminatedUnion("mode", [
30398
+ z129.object({
30399
+ mode: z129.literal("none")
30239
30400
  }).strict(),
30240
- z128.object({
30241
- mode: z128.literal("saved_actor"),
30242
- actorId: z128.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
30401
+ z129.object({
30402
+ mode: z129.literal("saved_actor"),
30403
+ actorId: z129.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
30243
30404
  }).strict(),
30244
- z128.object({
30245
- mode: z128.literal("described"),
30246
- description: z128.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
30405
+ z129.object({
30406
+ mode: z129.literal("described"),
30407
+ description: z129.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
30247
30408
  }).strict()
30248
30409
  ]);
30249
- var VideoCreativeSetup = z128.discriminatedUnion("mode", [
30250
- z128.object({
30251
- mode: z128.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
30410
+ var VideoCreativeSetup = z129.discriminatedUnion("mode", [
30411
+ z129.object({
30412
+ mode: z129.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
30252
30413
  }).strict(),
30253
- z128.object({
30254
- mode: z128.literal("guided"),
30414
+ z129.object({
30415
+ mode: z129.literal("guided"),
30255
30416
  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.'),
30256
- buyerPersona: z128.string().trim().min(1).max(360),
30417
+ buyerPersona: z129.string().trim().min(1).max(360),
30257
30418
  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.'),
30258
30419
  presenter: VideoPresenter,
30259
- creativeDirection: z128.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
30420
+ creativeDirection: z129.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
30260
30421
  }).strict()
30261
30422
  ]);
30262
- var VideoInput = z128.object({
30423
+ var VideoInput = z129.object({
30263
30424
  images: CreativeRefs.images.optional(),
30264
30425
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
30265
- title: z128.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
30266
- primaryAngle: z128.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".'),
30426
+ title: z129.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
30427
+ primaryAngle: z129.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".'),
30267
30428
  language: CreativeRefs.language,
30268
30429
  country: CreativeRefs.country,
30269
- aspectRatio: z128.enum([
30430
+ aspectRatio: z129.enum([
30270
30431
  "9:16",
30271
30432
  "16:9",
30272
30433
  "Auto"
30273
30434
  ]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
30274
30435
  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.'),
30275
- durationSeconds: z128.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."),
30276
- videoAngleCount: z128.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."),
30436
+ durationSeconds: z129.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."),
30437
+ videoAngleCount: z129.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."),
30277
30438
  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.'),
30278
30439
  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."),
30279
30440
  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.'),
30280
30441
  videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
30281
30442
  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.'),
30282
- features: z128.array(z128.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
30443
+ features: z129.array(z129.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
30283
30444
  price: CreativeRefs.price,
30284
30445
  offer: CreativeRefs.offer,
30285
30446
  productContext: CreativeRefs.productContext,
30286
30447
  productLabel: CreativeRefs.productLabel,
30287
- cta: z128.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.'),
30288
- scriptNotes: z128.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.'),
30448
+ cta: z129.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.'),
30449
+ scriptNotes: z129.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.'),
30289
30450
  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.'),
30290
30451
  competitorScanEnabled: CreativeRefs.competitorScanEnabled,
30291
- replicateWinnerWhenFound: z128.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."),
30452
+ replicateWinnerWhenFound: z129.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."),
30292
30453
  brandId: CreativeRefs.brandId
30293
30454
  }).strict();
30294
30455
  var FreeVideoQualityEnum = VideoQualityEnum;
@@ -30306,7 +30467,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
30306
30467
  length: 29
30307
30468
  }, (_, index) => index + 2)
30308
30469
  };
30309
- var FreeVideoModelIdEnum = z128.enum([
30470
+ var FreeVideoModelIdEnum = z129.enum([
30310
30471
  "grok-imagine-video-1-5-preview",
30311
30472
  "minimax-h3/reference-to-video",
30312
30473
  "wan/3-0-video",
@@ -30317,66 +30478,66 @@ var FREE_SELECTABLE_MODEL_IDS = [
30317
30478
  "minimax-h3/reference-to-video",
30318
30479
  "wan/3-0-video"
30319
30480
  ];
30320
- var FreeVideoInput = z128.object({
30481
+ var FreeVideoInput = z129.object({
30321
30482
  images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
30322
- rawPrompt: z128.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."),
30483
+ rawPrompt: z129.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."),
30323
30484
  language: CreativeRefs.language,
30324
30485
  quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
30325
30486
  // Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
30326
30487
  // parsed ONLY so the handler can reject it with a message naming its
30327
30488
  // replacement — dropping it silently would turn a caller's explicit
30328
30489
  // Pro++ pick into a quiet fallback to Wan.
30329
- freeProModel: z128.enum([
30490
+ freeProModel: z129.enum([
30330
30491
  "wan",
30331
30492
  "seedance"
30332
30493
  ]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
30333
30494
  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.'),
30334
- durationSeconds: z128.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."),
30495
+ durationSeconds: z129.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."),
30335
30496
  videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
30336
- generateAiMusic: z128.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.'),
30497
+ generateAiMusic: z129.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.'),
30337
30498
  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.'),
30338
- addSubtitles: z128.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
30339
- idempotencyKey: z128.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.")
30499
+ addSubtitles: z129.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
30500
+ idempotencyKey: z129.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.")
30340
30501
  }).strict();
30341
30502
  var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
30342
- var ImageCreativeSetup = z128.discriminatedUnion("mode", [
30343
- z128.object({
30344
- mode: z128.literal("automatic")
30503
+ var ImageCreativeSetup = z129.discriminatedUnion("mode", [
30504
+ z129.object({
30505
+ mode: z129.literal("automatic")
30345
30506
  }).strict(),
30346
- z128.object({
30347
- mode: z128.literal("guided"),
30348
- creativeArchetype: z128.union([
30507
+ z129.object({
30508
+ mode: z129.literal("guided"),
30509
+ creativeArchetype: z129.union([
30349
30510
  ImageCreativeArchetypeEnum,
30350
- z128.literal("ai_decides")
30511
+ z129.literal("ai_decides")
30351
30512
  ]),
30352
- visualTreatment: z128.union([
30513
+ visualTreatment: z129.union([
30353
30514
  ImageCreativeVisualTreatmentEnum,
30354
- z128.literal("ai_decides")
30515
+ z129.literal("ai_decides")
30355
30516
  ]),
30356
30517
  aspectRatio: ImageCreativeAspectRatioEnum,
30357
- nVariants: z128.union([
30358
- z128.literal(1),
30359
- z128.literal(2),
30360
- z128.literal(3),
30361
- z128.literal(4),
30362
- z128.literal(6)
30518
+ nVariants: z129.union([
30519
+ z129.literal(1),
30520
+ z129.literal(2),
30521
+ z129.literal(3),
30522
+ z129.literal(4),
30523
+ z129.literal(6)
30363
30524
  ]),
30364
- imageModel: z128.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.'),
30365
- styleMix: z128.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
30366
- generateAdCopy: z128.boolean(),
30367
- competitorScanEnabled: z128.boolean(),
30368
- productContext: z128.string().trim().min(1).max(3e3).nullable(),
30369
- creativeDirection: z128.string().trim().min(1).max(500).nullable(),
30370
- brandColors: z128.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.'),
30371
- headline: z128.string().trim().min(1).max(120).nullable(),
30372
- subheadline: z128.string().trim().min(1).max(160).nullable()
30525
+ imageModel: z129.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.'),
30526
+ styleMix: z129.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
30527
+ generateAdCopy: z129.boolean(),
30528
+ competitorScanEnabled: z129.boolean(),
30529
+ productContext: z129.string().trim().min(1).max(3e3).nullable(),
30530
+ creativeDirection: z129.string().trim().min(1).max(500).nullable(),
30531
+ brandColors: z129.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.'),
30532
+ headline: z129.string().trim().min(1).max(120).nullable(),
30533
+ subheadline: z129.string().trim().min(1).max(160).nullable()
30373
30534
  }).strict()
30374
30535
  ]).superRefine((setup, context) => {
30375
30536
  if (setup.mode !== "guided") return;
30376
30537
  const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
30377
30538
  if (needsStyleMix && setup.styleMix === null) {
30378
30539
  context.addIssue({
30379
- code: z128.ZodIssueCode.custom,
30540
+ code: z129.ZodIssueCode.custom,
30380
30541
  path: [
30381
30542
  "styleMix"
30382
30543
  ],
@@ -30385,7 +30546,7 @@ var ImageCreativeSetup = z128.discriminatedUnion("mode", [
30385
30546
  }
30386
30547
  if (!needsStyleMix && setup.styleMix !== null) {
30387
30548
  context.addIssue({
30388
- code: z128.ZodIssueCode.custom,
30549
+ code: z129.ZodIssueCode.custom,
30389
30550
  path: [
30390
30551
  "styleMix"
30391
30552
  ],
@@ -30394,7 +30555,7 @@ var ImageCreativeSetup = z128.discriminatedUnion("mode", [
30394
30555
  }
30395
30556
  if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
30396
30557
  context.addIssue({
30397
- code: z128.ZodIssueCode.custom,
30558
+ code: z129.ZodIssueCode.custom,
30398
30559
  path: [
30399
30560
  "aspectRatio"
30400
30561
  ],
@@ -30402,55 +30563,55 @@ var ImageCreativeSetup = z128.discriminatedUnion("mode", [
30402
30563
  });
30403
30564
  }
30404
30565
  });
30405
- var LandingCreativeSetup = z128.discriminatedUnion("mode", [
30406
- z128.object({
30407
- mode: z128.literal("automatic")
30566
+ var LandingCreativeSetup = z129.discriminatedUnion("mode", [
30567
+ z129.object({
30568
+ mode: z129.literal("automatic")
30408
30569
  }).strict(),
30409
- z128.object({
30410
- mode: z128.literal("guided"),
30570
+ z129.object({
30571
+ mode: z129.literal("guided"),
30411
30572
  landingStrategy: LandingStrategyEnum,
30412
30573
  landingImageFormat: LandingImageFormatEnum,
30413
- competitorScanEnabled: z128.boolean(),
30414
- paymentMethods: z128.string().trim().min(1).max(240).nullable(),
30415
- productContext: z128.string().trim().min(1).max(3e3).nullable(),
30416
- creativeDirection: z128.string().trim().min(1).max(500).nullable(),
30417
- headline: z128.string().trim().min(1).max(120).nullable(),
30418
- subheadline: z128.string().trim().min(1).max(160).nullable()
30574
+ competitorScanEnabled: z129.boolean(),
30575
+ paymentMethods: z129.string().trim().min(1).max(240).nullable(),
30576
+ productContext: z129.string().trim().min(1).max(3e3).nullable(),
30577
+ creativeDirection: z129.string().trim().min(1).max(500).nullable(),
30578
+ headline: z129.string().trim().min(1).max(120).nullable(),
30579
+ subheadline: z129.string().trim().min(1).max(160).nullable()
30419
30580
  }).strict()
30420
30581
  ]);
30421
- var ImageInput = z128.object({
30582
+ var ImageInput = z129.object({
30422
30583
  images: CreativeRefs.images.optional(),
30423
30584
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
30424
- productTitle: z128.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
30425
- primaryAngle: z128.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.'),
30585
+ productTitle: z129.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
30586
+ primaryAngle: z129.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.'),
30426
30587
  buyerPersona: CreativeRefs.buyerPersona,
30427
30588
  language: CreativeRefs.language,
30428
30589
  country: CreativeRefs.country,
30429
30590
  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."),
30430
30591
  imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
30431
- features: z128.array(z128.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
30592
+ features: z129.array(z129.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
30432
30593
  price: CreativeRefs.price,
30433
- omitPrice: z128.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."),
30594
+ omitPrice: z129.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."),
30434
30595
  compareAtPrice: CreativeRefs.compareAtPrice,
30435
30596
  offer: CreativeRefs.offer,
30436
30597
  productLabel: CreativeRefs.productLabel,
30437
30598
  isCombo: CreativeRefs.isCombo,
30438
30599
  brandId: CreativeRefs.brandId
30439
30600
  });
30440
- var EditImageCreativeInput = z128.object({
30441
- taskId: z128.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
30442
- variantIndex: z128.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
30443
- clientRequestId: z128.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."),
30444
- instruction: z128.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".')
30601
+ var EditImageCreativeInput = z129.object({
30602
+ taskId: z129.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
30603
+ variantIndex: z129.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
30604
+ clientRequestId: z129.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."),
30605
+ instruction: z129.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".')
30445
30606
  });
30446
- var LandingInput = z128.object({
30447
- includeInitialLandingGif: z128.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."),
30607
+ var LandingInput = z129.object({
30608
+ includeInitialLandingGif: z129.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."),
30448
30609
  images: CreativeRefs.images.optional(),
30449
30610
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
30450
30611
  language: CreativeRefs.language,
30451
30612
  country: CreativeRefs.country,
30452
30613
  creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
30453
- salesAngle: z128.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.'),
30614
+ salesAngle: z129.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.'),
30454
30615
  buyerPersona: CreativeRefs.buyerPersona,
30455
30616
  price: CreativeRefs.price,
30456
30617
  compareAtPrice: CreativeRefs.compareAtPrice,
@@ -30732,8 +30893,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
30732
30893
  server.registerTool("get_image_edit_status", {
30733
30894
  description: imageEditStatusGuidance.summary,
30734
30895
  inputSchema: {
30735
- taskId: z128.string().uuid(),
30736
- operationId: z128.string().uuid()
30896
+ taskId: z129.string().uuid(),
30897
+ operationId: z129.string().uuid()
30737
30898
  },
30738
30899
  annotations: READS_INTERNAL
30739
30900
  }, async (input) => {
@@ -30790,10 +30951,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
30790
30951
  __name(registerCreativeTools, "registerCreativeTools");
30791
30952
 
30792
30953
  // src/tools/creative-variants.ts
30793
- import { z as z129 } from "zod";
30954
+ import { z as z130 } from "zod";
30794
30955
  var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
30795
30956
  var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
30796
- var LandingSectionKeyEnum = z129.enum([
30957
+ var LandingSectionKeyEnum = z130.enum([
30797
30958
  "problem_hook",
30798
30959
  "problem_cost",
30799
30960
  "solution_mechanism",
@@ -30833,24 +30994,24 @@ var LandingSectionKeyEnum = z129.enum([
30833
30994
  "lifestyle_fit",
30834
30995
  "join_lifestyle"
30835
30996
  ]);
30836
- var CreativeVariantKindEnum = z129.enum([
30997
+ var CreativeVariantKindEnum = z130.enum([
30837
30998
  "video",
30838
30999
  "image",
30839
31000
  "landing"
30840
31001
  ]);
30841
- var EstimateCreativeVariantInputBase = z129.object({
30842
- sourceTaskId: z129.string().uuid().describe("ID de la tarea original completada."),
31002
+ var EstimateCreativeVariantInputBase = z130.object({
31003
+ sourceTaskId: z130.string().uuid().describe("ID de la tarea original completada."),
30843
31004
  kind: CreativeVariantKindEnum,
30844
31005
  videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
30845
31006
  videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
30846
- nVariants: z129.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
31007
+ nVariants: z130.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
30847
31008
  sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
30848
- instructions: z129.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.")
31009
+ instructions: z130.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.")
30849
31010
  }).strict();
30850
31011
  var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
30851
31012
  if (input.kind === "video" && input.nVariants !== void 0) {
30852
31013
  ctx.addIssue({
30853
- code: z129.ZodIssueCode.custom,
31014
+ code: z130.ZodIssueCode.custom,
30854
31015
  path: [
30855
31016
  "nVariants"
30856
31017
  ],
@@ -30860,7 +31021,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
30860
31021
  if (input.kind !== "video") {
30861
31022
  if (input.videoPreset !== void 0) {
30862
31023
  ctx.addIssue({
30863
- code: z129.ZodIssueCode.custom,
31024
+ code: z130.ZodIssueCode.custom,
30864
31025
  path: [
30865
31026
  "videoPreset"
30866
31027
  ],
@@ -30869,7 +31030,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
30869
31030
  }
30870
31031
  if (input.videoResolution !== void 0) {
30871
31032
  ctx.addIssue({
30872
- code: z129.ZodIssueCode.custom,
31033
+ code: z130.ZodIssueCode.custom,
30873
31034
  path: [
30874
31035
  "videoResolution"
30875
31036
  ],
@@ -30879,7 +31040,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
30879
31040
  }
30880
31041
  if (input.kind !== "image" && input.nVariants !== void 0) {
30881
31042
  ctx.addIssue({
30882
- code: z129.ZodIssueCode.custom,
31043
+ code: z130.ZodIssueCode.custom,
30883
31044
  path: [
30884
31045
  "nVariants"
30885
31046
  ],
@@ -30889,7 +31050,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
30889
31050
  if (input.kind !== "landing") {
30890
31051
  if (input.sectionKey !== void 0) {
30891
31052
  ctx.addIssue({
30892
- code: z129.ZodIssueCode.custom,
31053
+ code: z130.ZodIssueCode.custom,
30893
31054
  path: [
30894
31055
  "sectionKey"
30895
31056
  ],
@@ -30898,7 +31059,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
30898
31059
  }
30899
31060
  if (input.instructions !== void 0) {
30900
31061
  ctx.addIssue({
30901
- code: z129.ZodIssueCode.custom,
31062
+ code: z130.ZodIssueCode.custom,
30902
31063
  path: [
30903
31064
  "instructions"
30904
31065
  ],
@@ -30907,31 +31068,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
30907
31068
  }
30908
31069
  }
30909
31070
  });
30910
- var CreateCreativeVariantInputBase = z129.object({
30911
- sourceTaskId: z129.string().uuid().describe("ID de la tarea original completada."),
31071
+ var CreateCreativeVariantInputBase = z130.object({
31072
+ sourceTaskId: z130.string().uuid().describe("ID de la tarea original completada."),
30912
31073
  kind: CreativeVariantKindEnum,
30913
- confirm: z129.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
30914
- clientRequestId: z129.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."),
30915
- angle: z129.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
30916
- buyerPersona: z129.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
30917
- scriptNotes: z129.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
30918
- creativeDirection: z129.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
31074
+ confirm: z130.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
31075
+ clientRequestId: z130.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."),
31076
+ angle: z130.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
31077
+ buyerPersona: z130.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
31078
+ scriptNotes: z130.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
31079
+ creativeDirection: z130.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
30919
31080
  videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
30920
31081
  videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
30921
- generateAiMusic: z129.boolean().optional().describe("Opcional para video."),
30922
- nVariants: z129.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
31082
+ generateAiMusic: z130.boolean().optional().describe("Opcional para video."),
31083
+ nVariants: z130.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
30923
31084
  imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
30924
31085
  creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
30925
31086
  visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
30926
31087
  aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
30927
- styleMix: z129.boolean().optional().describe("Opcional para imagen."),
31088
+ styleMix: z130.boolean().optional().describe("Opcional para imagen."),
30928
31089
  sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
30929
- instructions: z129.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.")
31090
+ instructions: z130.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.")
30930
31091
  }).strict();
30931
31092
  var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
30932
31093
  if ((input.kind === "video" || input.kind === "image") && !input.angle) {
30933
31094
  ctx.addIssue({
30934
- code: z129.ZodIssueCode.custom,
31095
+ code: z130.ZodIssueCode.custom,
30935
31096
  path: [
30936
31097
  "angle"
30937
31098
  ],
@@ -30940,7 +31101,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
30940
31101
  }
30941
31102
  if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
30942
31103
  ctx.addIssue({
30943
- code: z129.ZodIssueCode.custom,
31104
+ code: z130.ZodIssueCode.custom,
30944
31105
  path: [
30945
31106
  "instructions"
30946
31107
  ],
@@ -30986,7 +31147,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
30986
31147
  for (const field of fieldsByKind[input.kind]) {
30987
31148
  if (input[field] !== void 0) {
30988
31149
  ctx.addIssue({
30989
- code: z129.ZodIssueCode.custom,
31150
+ code: z130.ZodIssueCode.custom,
30990
31151
  path: [
30991
31152
  field
30992
31153
  ],
@@ -31144,13 +31305,13 @@ function registerCreativeVariantTools(server, api) {
31144
31305
  __name(registerCreativeVariantTools, "registerCreativeVariantTools");
31145
31306
 
31146
31307
  // src/tools/script-review.ts
31147
- import { z as z130 } from "zod";
31308
+ import { z as z131 } from "zod";
31148
31309
  var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
31149
31310
  var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
31150
31311
  var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
31151
- var GetVideoScriptInput = z130.object({
31152
- taskId: z130.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
31153
- angleKey: z130.string().min(1).optional().describe('Clave persistida del \xE1ngulo cuyo guion se quiere leer (formato "angle_0", "angle_1", ...). Usa exactamente el angleKey recibido en reviewNextAction.calls al aprobar \xE1ngulos, incluso si s\xF3lo elegiste uno. Si se omite, el backend resuelve a "angle_0" literal; elegir el segundo candidato no crea angle_0. No derives esta clave del n\xFAmero visible del candidato.')
31312
+ var GetVideoScriptInput = z131.object({
31313
+ taskId: z131.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
31314
+ angleKey: z131.string().min(1).optional().describe('Clave persistida del \xE1ngulo cuyo guion se quiere leer (formato "angle_0", "angle_1", ...). Usa exactamente el angleKey recibido en reviewNextAction.calls al aprobar \xE1ngulos, incluso si s\xF3lo elegiste uno. Si se omite, el backend resuelve a "angle_0" literal; elegir el segundo candidato no crea angle_0. No derives esta clave del n\xFAmero visible del candidato.')
31154
31315
  }).strict();
31155
31316
  var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
31156
31317
  var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
@@ -31255,7 +31416,7 @@ Consulta get_task_status con esta tarea antes de reintentar. Si la tarea termin\
31255
31416
  __name(registerScriptReviewTools, "registerScriptReviewTools");
31256
31417
 
31257
31418
  // src/tools/connections.ts
31258
- import { z as z131 } from "zod";
31419
+ import { z as z132 } from "zod";
31259
31420
  var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
31260
31421
  var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
31261
31422
  var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
@@ -31264,7 +31425,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
31264
31425
  function registerConnectionTools(server, api) {
31265
31426
  server.registerTool("list_shopify_shops", {
31266
31427
  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.",
31267
- inputSchema: z131.object({}).shape,
31428
+ inputSchema: z132.object({}).shape,
31268
31429
  annotations: READS_INTERNAL
31269
31430
  }, async () => {
31270
31431
  try {
@@ -31276,10 +31437,10 @@ function registerConnectionTools(server, api) {
31276
31437
  });
31277
31438
  server.registerTool("list_shopify_products", {
31278
31439
  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.',
31279
- inputSchema: z131.object({
31280
- shopDomain: z131.string().min(3).max(120),
31281
- query: z131.string().trim().max(120).optional(),
31282
- taskId: z131.string().uuid().optional()
31440
+ inputSchema: z132.object({
31441
+ shopDomain: z132.string().min(3).max(120),
31442
+ query: z132.string().trim().max(120).optional(),
31443
+ taskId: z132.string().uuid().optional()
31283
31444
  }).shape,
31284
31445
  annotations: READS_EXTERNAL
31285
31446
  }, async ({ shopDomain, query, taskId }) => {
@@ -31297,7 +31458,7 @@ function registerConnectionTools(server, api) {
31297
31458
  });
31298
31459
  server.registerTool("list_meta_ad_accounts", {
31299
31460
  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.",
31300
- inputSchema: z131.object({}).shape,
31461
+ inputSchema: z132.object({}).shape,
31301
31462
  annotations: READS_EXTERNAL
31302
31463
  }, async () => {
31303
31464
  try {
@@ -31309,7 +31470,7 @@ function registerConnectionTools(server, api) {
31309
31470
  });
31310
31471
  server.registerTool("list_meta_destinations", {
31311
31472
  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.",
31312
- inputSchema: z131.object({}).shape,
31473
+ inputSchema: z132.object({}).shape,
31313
31474
  annotations: READS_EXTERNAL,
31314
31475
  _meta: {
31315
31476
  "openai/widgetAccessible": true
@@ -31324,7 +31485,7 @@ function registerConnectionTools(server, api) {
31324
31485
  });
31325
31486
  server.registerTool("list_tiktok_advertisers", {
31326
31487
  description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
31327
- inputSchema: z131.object({}).shape,
31488
+ inputSchema: z132.object({}).shape,
31328
31489
  annotations: READS_EXTERNAL
31329
31490
  }, async () => {
31330
31491
  try {
@@ -31338,7 +31499,7 @@ function registerConnectionTools(server, api) {
31338
31499
  __name(registerConnectionTools, "registerConnectionTools");
31339
31500
 
31340
31501
  // src/tools/actors.ts
31341
- import { z as z132 } from "zod";
31502
+ import { z as z133 } from "zod";
31342
31503
  var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
31343
31504
  var actorVoiceGuidance = {
31344
31505
  capabilities: getProductMakerCapabilityModelGuidance("get_actor_voice_capabilities"),
@@ -31378,7 +31539,7 @@ function sanitizeVoiceResult(value) {
31378
31539
  __name(sanitizeVoiceResult, "sanitizeVoiceResult");
31379
31540
  function registerActorTools(server, api) {
31380
31541
  const actor = {
31381
- actorId: z132.string().min(1).max(64)
31542
+ actorId: z133.string().min(1).max(64)
31382
31543
  };
31383
31544
  const safe = /* @__PURE__ */ __name(async (request) => {
31384
31545
  try {
@@ -31407,8 +31568,8 @@ function registerActorTools(server, api) {
31407
31568
  inputSchema: {
31408
31569
  ...actor,
31409
31570
  draft: ActorVoiceDraftSchema,
31410
- requestKey: z132.string().trim().min(1).max(128),
31411
- acceptedQuoteId: z132.string().trim().min(1).max(128)
31571
+ requestKey: z133.string().trim().min(1).max(128),
31572
+ acceptedQuoteId: z133.string().trim().min(1).max(128)
31412
31573
  },
31413
31574
  annotations: CREATES_PAID
31414
31575
  }, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews`, body)));
@@ -31416,7 +31577,7 @@ function registerActorTools(server, api) {
31416
31577
  description: actorVoiceGuidance.get.summary,
31417
31578
  inputSchema: {
31418
31579
  ...actor,
31419
- candidateId: z132.string().min(1).max(64)
31580
+ candidateId: z133.string().min(1).max(64)
31420
31581
  },
31421
31582
  // Polling can resume the first paid submission of an accepted quote.
31422
31583
  // The immutable candidate/operation key keeps recovery idempotent.
@@ -31429,16 +31590,16 @@ function registerActorTools(server, api) {
31429
31590
  description: actorVoiceGuidance.approve.summary,
31430
31591
  inputSchema: {
31431
31592
  ...actor,
31432
- candidateId: z132.string().min(1).max(64),
31433
- expectedRevision: z132.number().int().positive(),
31434
- expectedApprovedRevision: z132.number().int().positive().nullable().optional()
31593
+ candidateId: z133.string().min(1).max(64),
31594
+ expectedRevision: z133.number().int().positive(),
31595
+ expectedApprovedRevision: z133.number().int().positive().nullable().optional()
31435
31596
  },
31436
31597
  // Replaces the selected voice and withdraws the old catalog grants.
31437
31598
  annotations: OVERWRITES_INTERNAL
31438
31599
  }, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/approve`, body)));
31439
31600
  server.registerTool("list_actors", {
31440
31601
  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.",
31441
- inputSchema: z132.object({}).shape,
31602
+ inputSchema: z133.object({}).shape,
31442
31603
  annotations: READS_INTERNAL
31443
31604
  }, async () => {
31444
31605
  try {
@@ -31471,7 +31632,7 @@ function registerActorTools(server, api) {
31471
31632
  __name(registerActorTools, "registerActorTools");
31472
31633
 
31473
31634
  // src/tools/publish.ts
31474
- import { z as z133 } from "zod";
31635
+ import { z as z134 } from "zod";
31475
31636
 
31476
31637
  // src/tools/meta-publish-attempt-id.ts
31477
31638
  var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
@@ -31510,40 +31671,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
31510
31671
  var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
31511
31672
  var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
31512
31673
  var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
31513
- var ShopifyInput = z133.object({
31514
- taskId: z133.string().min(1),
31515
- shopDomain: z133.string().min(1),
31674
+ var ShopifyInput = z134.object({
31675
+ taskId: z134.string().min(1),
31676
+ shopDomain: z134.string().min(1),
31516
31677
  /** Override: number of landing images to include. Default = ALL images the
31517
31678
  * task generated (the MCP fetches /v1/results first to count). Bounded
31518
31679
  * generously here; the backend validates each index against
31519
31680
  * landing.images.length and rejects out-of-range. */
31520
- numLandingImages: z133.number().int().min(1).max(20).optional(),
31521
- variantIndex: z133.number().int().min(0).optional(),
31681
+ numLandingImages: z134.number().int().min(1).max(20).optional(),
31682
+ variantIndex: z134.number().int().min(0).optional(),
31522
31683
  /** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
31523
31684
  * When true, the landing renders variant-picker pills; when false, it ships
31524
31685
  * a single-option product page. Defaults to false. */
31525
- showVariantPicker: z133.boolean().optional(),
31686
+ showVariantPicker: z134.boolean().optional(),
31526
31687
  /** Default `auto` updates the product previously published for this task and
31527
31688
  * shop. Use `existing` with targetProductId to choose another product, or
31528
31689
  * `new` only when the user explicitly wants a duplicate/new listing. */
31529
- publicationMode: z133.enum([
31690
+ publicationMode: z134.enum([
31530
31691
  "auto",
31531
31692
  "existing",
31532
31693
  "new"
31533
31694
  ]).optional(),
31534
31695
  /** Shopify product GID, numeric id, or admin product URL. Required when
31535
31696
  * publicationMode is `existing`. */
31536
- targetProductId: z133.string().trim().min(1).max(300).optional(),
31697
+ targetProductId: z134.string().trim().min(1).max(300).optional(),
31537
31698
  /** Add an announcement bar text above add-to-cart (optional). */
31538
- announcementBarEnabled: z133.boolean().optional(),
31539
- announcementBarText: z133.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
31699
+ announcementBarEnabled: z134.boolean().optional(),
31700
+ announcementBarText: z134.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
31540
31701
  commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
31541
- confirmed: z133.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
31702
+ confirmed: z134.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
31542
31703
  });
31543
31704
  var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
31544
31705
  if (value.commerceCorrection && value.confirmed !== true) {
31545
31706
  ctx.addIssue({
31546
- code: z133.ZodIssueCode.custom,
31707
+ code: z134.ZodIssueCode.custom,
31547
31708
  path: [
31548
31709
  "confirmed"
31549
31710
  ],
@@ -31552,7 +31713,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
31552
31713
  }
31553
31714
  if (value.announcementBarEnabled && !value.announcementBarText) {
31554
31715
  ctx.addIssue({
31555
- code: z133.ZodIssueCode.custom,
31716
+ code: z134.ZodIssueCode.custom,
31556
31717
  path: [
31557
31718
  "announcementBarText"
31558
31719
  ],
@@ -31561,7 +31722,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
31561
31722
  }
31562
31723
  if (!value.announcementBarEnabled && value.announcementBarText) {
31563
31724
  ctx.addIssue({
31564
- code: z133.ZodIssueCode.custom,
31725
+ code: z134.ZodIssueCode.custom,
31565
31726
  path: [
31566
31727
  "announcementBarText"
31567
31728
  ],
@@ -31575,90 +31736,90 @@ function parseShopifyInput(rawInput) {
31575
31736
  return parsed.data;
31576
31737
  }
31577
31738
  __name(parseShopifyInput, "parseShopifyInput");
31578
- var McpCampaignConfig = z133.object({
31739
+ var McpCampaignConfig = z134.object({
31579
31740
  /** Legacy USD amount. Meta retains its existing conversion; the TikTok
31580
31741
  * schema below restricts this input to USD advertiser accounts. */
31581
- dailyBudgetUsd: z133.number().positive().optional(),
31742
+ dailyBudgetUsd: z134.number().positive().optional(),
31582
31743
  /** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
31583
31744
  * normalizes at validation). Meta accepts max 1 (single-country ad set).
31584
31745
  * TikTok takes only the first entry. */
31585
- targetCountries: z133.array(CountryIso2Schema).max(1).optional(),
31586
- campaignName: z133.string().trim().min(1).max(100).optional()
31746
+ targetCountries: z134.array(CountryIso2Schema).max(1).optional(),
31747
+ campaignName: z134.string().trim().min(1).max(100).optional()
31587
31748
  });
31588
31749
  var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
31589
- var MetaInput = z133.object({
31590
- taskId: z133.string().min(1),
31750
+ var MetaInput = z134.object({
31751
+ taskId: z134.string().min(1),
31591
31752
  /** Exact Meta Business portfolio selected from `list_meta_destinations`. */
31592
- portfolioId: z133.string().trim().min(1),
31753
+ portfolioId: z134.string().trim().min(1),
31593
31754
  /** Exact Facebook Page selected from `list_meta_destinations`. */
31594
- pageId: z133.string().trim().min(1),
31755
+ pageId: z134.string().trim().min(1),
31595
31756
  adAccountId: McpAdAccountId,
31596
- pixelId: z133.string().min(1).optional(),
31597
- landingUrl: z133.string().url().optional(),
31757
+ pixelId: z134.string().min(1).optional(),
31758
+ landingUrl: z134.string().url().optional(),
31598
31759
  /** Select which angles to publish by 0-based index. Omit to publish all
31599
31760
  * successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
31600
- angleIndexes: z133.array(z133.number().int().nonnegative()).optional(),
31761
+ angleIndexes: z134.array(z134.number().int().nonnegative()).optional(),
31601
31762
  campaignConfig: McpCampaignConfig.optional(),
31602
31763
  /** Override the ad's primary text (body copy). If omitted, ProductMaker
31603
31764
  * uses the auto-generated copy attached to the task. Capped at 500 chars
31604
31765
  * (Meta's primary-text limit). */
31605
- primaryText: z133.string().trim().min(1).max(500).optional(),
31766
+ primaryText: z134.string().trim().min(1).max(500).optional(),
31606
31767
  /** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
31607
31768
  * (wa.me) instead of a landing page. */
31608
- phoneNumber: z133.string().min(8).max(32).optional()
31769
+ phoneNumber: z134.string().min(8).max(32).optional()
31609
31770
  });
31610
- var GroupedTaskSource = z133.object({
31611
- type: z133.literal("task"),
31612
- taskId: z133.string().min(1),
31613
- angleIndex: z133.number().int().min(0).optional(),
31614
- videoVariant: z133.enum([
31771
+ var GroupedTaskSource = z134.object({
31772
+ type: z134.literal("task"),
31773
+ taskId: z134.string().min(1),
31774
+ angleIndex: z134.number().int().min(0).optional(),
31775
+ videoVariant: z134.enum([
31615
31776
  "with_subtitles",
31616
31777
  "without_subtitles"
31617
31778
  ]).optional(),
31618
- imageVariantIndex: z133.number().int().min(0).optional()
31619
- });
31620
- var GroupedMediaSource = z133.object({
31621
- type: z133.literal("media"),
31622
- url: z133.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
31623
- path: z133.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".'),
31624
- thumbnailUrl: z133.string().url().optional(),
31625
- thumbnailPath: z133.string().min(1).optional()
31779
+ imageVariantIndex: z134.number().int().min(0).optional()
31780
+ });
31781
+ var GroupedMediaSource = z134.object({
31782
+ type: z134.literal("media"),
31783
+ url: z134.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
31784
+ path: z134.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".'),
31785
+ thumbnailUrl: z134.string().url().optional(),
31786
+ thumbnailPath: z134.string().min(1).optional()
31626
31787
  }).refine((value) => Boolean(value.url) !== Boolean(value.path), {
31627
31788
  message: "media source needs exactly one of `url` or `path`"
31628
31789
  }).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
31629
31790
  message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
31630
31791
  });
31631
- var GroupedUploadedAssetSource = z133.object({
31632
- type: z133.literal("asset"),
31792
+ var GroupedUploadedAssetSource = z134.object({
31793
+ type: z134.literal("asset"),
31633
31794
  /** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
31634
- assetId: z133.string().uuid(),
31635
- thumbnailAssetId: z133.string().uuid().optional()
31795
+ assetId: z134.string().uuid(),
31796
+ thumbnailAssetId: z134.string().uuid().optional()
31636
31797
  });
31637
- var GroupedCreative = z133.object({
31638
- type: z133.enum([
31798
+ var GroupedCreative = z134.object({
31799
+ type: z134.enum([
31639
31800
  "image",
31640
31801
  "video"
31641
31802
  ]),
31642
- source: z133.union([
31803
+ source: z134.union([
31643
31804
  GroupedTaskSource,
31644
31805
  GroupedMediaSource,
31645
31806
  GroupedUploadedAssetSource
31646
31807
  ]),
31647
- title: z133.string().max(120).optional(),
31648
- description: z133.string().max(500).optional(),
31808
+ title: z134.string().max(120).optional(),
31809
+ description: z134.string().max(500).optional(),
31649
31810
  cta: MetaCtaType.optional(),
31650
- creativeId: z133.string().min(1).optional()
31811
+ creativeId: z134.string().min(1).optional()
31651
31812
  });
31652
- var GroupedCampaignConfigBase = z133.object({
31813
+ var GroupedCampaignConfigBase = z134.object({
31653
31814
  campaignType: MetaCampaignType.default("sales"),
31654
31815
  optimizationMode: MetaOptimizationMode.default("advantage_plus"),
31655
31816
  budgetMode: MetaBudgetMode.optional(),
31656
- campaignDailyBudget: z133.number().int().positive().optional(),
31657
- adSets: z133.array(z133.object({
31658
- tempId: z133.string().min(1).max(80),
31659
- name: z133.string().min(1).max(100),
31660
- dailyBudget: z133.number().int().positive().optional(),
31661
- creativeIds: z133.array(z133.string().min(1)).min(1)
31817
+ campaignDailyBudget: z134.number().int().positive().optional(),
31818
+ adSets: z134.array(z134.object({
31819
+ tempId: z134.string().min(1).max(80),
31820
+ name: z134.string().min(1).max(100),
31821
+ dailyBudget: z134.number().int().positive().optional(),
31822
+ creativeIds: z134.array(z134.string().min(1)).min(1)
31662
31823
  })).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
31663
31824
  /**
31664
31825
  * Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
@@ -31666,17 +31827,17 @@ var GroupedCampaignConfigBase = z133.object({
31666
31827
  * opaque `invalid_literal` and made the WhatsApp destination — supported by
31667
31828
  * the API since #849 — unreachable from this tool.
31668
31829
  */
31669
- destination: z133.discriminatedUnion("type", [
31670
- z133.object({
31671
- type: z133.literal("landing"),
31672
- landingUrl: z133.string().url()
31830
+ destination: z134.discriminatedUnion("type", [
31831
+ z134.object({
31832
+ type: z134.literal("landing"),
31833
+ landingUrl: z134.string().url()
31673
31834
  }),
31674
- z133.object({
31675
- type: z133.literal("whatsapp"),
31676
- phoneNumber: z133.string().min(8).max(32)
31835
+ z134.object({
31836
+ type: z134.literal("whatsapp"),
31837
+ phoneNumber: z134.string().min(8).max(32)
31677
31838
  })
31678
31839
  ]),
31679
- saveAsDefault: z133.boolean().default(false),
31840
+ saveAsDefault: z134.boolean().default(false),
31680
31841
  budgetPolicy: MetaBudgetPolicy.optional()
31681
31842
  });
31682
31843
  function resolveBudgetMode(value) {
@@ -31690,7 +31851,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
31690
31851
  const budgetMode = resolveBudgetMode(value);
31691
31852
  if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
31692
31853
  ctx.addIssue({
31693
- code: z133.ZodIssueCode.custom,
31854
+ code: z134.ZodIssueCode.custom,
31694
31855
  path: [
31695
31856
  "campaignDailyBudget"
31696
31857
  ],
@@ -31701,7 +31862,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
31701
31862
  value.adSets.forEach((adSet, index) => {
31702
31863
  if (adSet.dailyBudget === void 0) {
31703
31864
  ctx.addIssue({
31704
- code: z133.ZodIssueCode.custom,
31865
+ code: z134.ZodIssueCode.custom,
31705
31866
  path: [
31706
31867
  "adSets",
31707
31868
  index,
@@ -31716,25 +31877,25 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
31716
31877
  ...value,
31717
31878
  budgetMode: resolveBudgetMode(value)
31718
31879
  }));
31719
- var PublishCreativesToMetaInputBase = z133.object({
31720
- creatives: z133.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
31880
+ var PublishCreativesToMetaInputBase = z134.object({
31881
+ creatives: z134.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
31721
31882
  /** Exact Meta Business portfolio selected from `list_meta_destinations`. */
31722
- portfolioId: z133.string().trim().min(1),
31883
+ portfolioId: z134.string().trim().min(1),
31723
31884
  /** Exact Facebook Page selected from `list_meta_destinations`. */
31724
- pageId: z133.string().trim().min(1),
31885
+ pageId: z134.string().trim().min(1),
31725
31886
  adAccountId: McpAdAccountId,
31726
- pixelId: z133.string().min(1).optional(),
31887
+ pixelId: z134.string().min(1).optional(),
31727
31888
  /** Required unless `campaignConfig.destination` is whatsapp or a creative
31728
31889
  * comes from a task (the API then lands on the published service landing
31729
31890
  * of its service tasks) — see the superRefine below. Mirrors the API's
31730
31891
  * `FacebookCreateCampaignFromTasksBodySchema`. */
31731
- landingUrl: z133.string().url().optional(),
31892
+ landingUrl: z134.string().url().optional(),
31732
31893
  /** ISO-2 code or resolvable country name — mirrors the API contract
31733
31894
  * (CountryIso2Schema), which normalizes names to alpha-2 at validation.
31734
31895
  * Omitted: the brand country of its service tasks (the API answers
31735
31896
  * META_NO_TARGET_COUNTRY when it has none); "US" for products. */
31736
31897
  targetCountry: CountryIso2Schema.optional(),
31737
- campaignName: z133.string().trim().min(1).max(100),
31898
+ campaignName: z134.string().trim().min(1).max(100),
31738
31899
  campaignConfig: GroupedCampaignConfig.optional()
31739
31900
  });
31740
31901
  var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
@@ -31742,7 +31903,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
31742
31903
  const hasTaskCreative = value.creatives.some((creative) => creative.source.type === "task");
31743
31904
  if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl && !hasTaskCreative) {
31744
31905
  ctx.addIssue({
31745
- code: z133.ZodIssueCode.custom,
31906
+ code: z134.ZodIssueCode.custom,
31746
31907
  path: [
31747
31908
  "landingUrl"
31748
31909
  ],
@@ -31751,7 +31912,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
31751
31912
  }
31752
31913
  if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
31753
31914
  ctx.addIssue({
31754
- code: z133.ZodIssueCode.custom,
31915
+ code: z134.ZodIssueCode.custom,
31755
31916
  path: [
31756
31917
  "campaignConfig",
31757
31918
  "destination",
@@ -31770,16 +31931,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
31770
31931
  }
31771
31932
  return value;
31772
31933
  });
31773
- var PresignUploadResponseSchema = z133.object({
31774
- uploadUrl: z133.string().url().refine((value) => {
31934
+ var PresignUploadResponseSchema = z134.object({
31935
+ uploadUrl: z134.string().url().refine((value) => {
31775
31936
  const url = new URL(value);
31776
31937
  return !url.username && !url.password && url.protocol === "https:";
31777
31938
  }, "presigned upload URL must be HTTPS without embedded credentials"),
31778
- publicUrl: z133.string().url().refine((value) => {
31939
+ publicUrl: z134.string().url().refine((value) => {
31779
31940
  const url = new URL(value);
31780
31941
  return !url.username && !url.password;
31781
31942
  }, "public media URL must not contain embedded credentials"),
31782
- stagingAssetId: z133.string().uuid()
31943
+ stagingAssetId: z134.string().uuid()
31783
31944
  });
31784
31945
  async function uploadResolvedMedia(api, media, assetRole) {
31785
31946
  if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
@@ -31805,14 +31966,14 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
31805
31966
  }
31806
31967
  __name(resolveAndUploadMedia, "resolveAndUploadMedia");
31807
31968
  var TikTokMcpCampaignConfig = McpCampaignConfig.extend({
31808
- dailyBudgetUsd: z133.number().finite().positive().optional().describe("Legacy USD amount, supported only for USD advertiser accounts. No FX conversion."),
31809
- dailyBudget: z133.number().finite().positive().optional().describe("Daily budget in the selected advertiser currency major units; pass budgetCurrency together."),
31969
+ dailyBudgetUsd: z134.number().finite().positive().optional().describe("Legacy USD amount, supported only for USD advertiser accounts. No FX conversion."),
31970
+ dailyBudget: z134.number().finite().positive().optional().describe("Daily budget in the selected advertiser currency major units; pass budgetCurrency together."),
31810
31971
  budgetCurrency: TikTokBudgetCurrencySchema.optional(),
31811
31972
  destination: TikTokCampaignDestinationSchema.optional()
31812
31973
  }).superRefine((value, ctx) => {
31813
31974
  if (value.dailyBudgetUsd !== void 0 && (value.dailyBudget !== void 0 || value.budgetCurrency !== void 0)) {
31814
31975
  ctx.addIssue({
31815
- code: z133.ZodIssueCode.custom,
31976
+ code: z134.ZodIssueCode.custom,
31816
31977
  path: [
31817
31978
  "dailyBudgetUsd"
31818
31979
  ],
@@ -31821,7 +31982,7 @@ var TikTokMcpCampaignConfig = McpCampaignConfig.extend({
31821
31982
  }
31822
31983
  if (value.dailyBudget !== void 0 !== (value.budgetCurrency !== void 0)) {
31823
31984
  ctx.addIssue({
31824
- code: z133.ZodIssueCode.custom,
31985
+ code: z134.ZodIssueCode.custom,
31825
31986
  path: [
31826
31987
  "budgetCurrency"
31827
31988
  ],
@@ -31829,16 +31990,16 @@ var TikTokMcpCampaignConfig = McpCampaignConfig.extend({
31829
31990
  });
31830
31991
  }
31831
31992
  });
31832
- var TikTokInput = z133.object({
31833
- taskId: z133.string().min(1),
31834
- advertiserId: z133.string().min(1),
31835
- pixelId: z133.string().min(1).optional(),
31836
- landingUrl: z133.string().url().optional(),
31837
- angleIndexes: z133.array(z133.number().int().nonnegative()).optional(),
31993
+ var TikTokInput = z134.object({
31994
+ taskId: z134.string().min(1),
31995
+ advertiserId: z134.string().min(1),
31996
+ pixelId: z134.string().min(1).optional(),
31997
+ landingUrl: z134.string().url().optional(),
31998
+ angleIndexes: z134.array(z134.number().int().nonnegative()).optional(),
31838
31999
  campaignConfig: TikTokMcpCampaignConfig.optional(),
31839
32000
  /** Override the ad's description (TikTok's body copy). If omitted,
31840
32001
  * ProductMaker uses the auto-generated copy attached to the task. */
31841
- primaryText: z133.string().trim().min(1).max(500).optional()
32002
+ primaryText: z134.string().trim().min(1).max(500).optional()
31842
32003
  });
31843
32004
  function registerPublishTools(server, api, opts = {}) {
31844
32005
  const transport = opts.transport ?? "http";
@@ -32197,39 +32358,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
32197
32358
 
32198
32359
  // src/tools/meta-upload.ts
32199
32360
  import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
32200
- import { z as z134 } from "zod";
32361
+ import { z as z135 } from "zod";
32201
32362
  var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
32202
- var UploadSessionInputBase = z134.object({
32203
- mediaKind: z134.enum([
32363
+ var UploadSessionInputBase = z135.object({
32364
+ mediaKind: z135.enum([
32204
32365
  "image",
32205
32366
  "video",
32206
32367
  "mixed"
32207
32368
  ]).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."),
32208
- assetRole: z134.enum([
32369
+ assetRole: z135.enum([
32209
32370
  "media",
32210
32371
  "thumbnail"
32211
32372
  ]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
32212
- uploadPurpose: z134.enum([
32373
+ uploadPurpose: z135.enum([
32213
32374
  "product_reference",
32214
32375
  "creative",
32215
32376
  "generic"
32216
32377
  ]).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."),
32217
- maxFiles: z134.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
32378
+ maxFiles: z135.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
32218
32379
  });
32219
- var OpenAiFileReference = z134.object({
32220
- download_url: z134.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."),
32221
- file_id: z134.string().min(1),
32222
- mime_type: z134.string().min(1).optional(),
32223
- file_name: z134.string().min(1).optional()
32380
+ var OpenAiFileReference = z135.object({
32381
+ download_url: z135.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."),
32382
+ file_id: z135.string().min(1),
32383
+ mime_type: z135.string().min(1).optional(),
32384
+ file_name: z135.string().min(1).optional()
32224
32385
  });
32225
32386
  var UploadSessionToolInputShape = {
32226
32387
  ...UploadSessionInputBase.shape,
32227
- files: z134.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.")
32388
+ files: z135.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.")
32228
32389
  };
32229
- var UploadSessionToolInput = z134.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
32390
+ var UploadSessionToolInput = z135.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
32230
32391
  if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
32231
32392
  ctx.addIssue({
32232
- code: z134.ZodIssueCode.custom,
32393
+ code: z135.ZodIssueCode.custom,
32233
32394
  path: [
32234
32395
  "mediaKind"
32235
32396
  ],
@@ -32238,7 +32399,7 @@ var UploadSessionToolInput = z134.object(UploadSessionToolInputShape).superRefin
32238
32399
  }
32239
32400
  if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
32240
32401
  ctx.addIssue({
32241
- code: z134.ZodIssueCode.custom,
32402
+ code: z135.ZodIssueCode.custom,
32242
32403
  path: [
32243
32404
  "maxFiles"
32244
32405
  ],
@@ -32247,7 +32408,7 @@ var UploadSessionToolInput = z134.object(UploadSessionToolInputShape).superRefin
32247
32408
  }
32248
32409
  if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
32249
32410
  ctx.addIssue({
32250
- code: z134.ZodIssueCode.custom,
32411
+ code: z135.ZodIssueCode.custom,
32251
32412
  path: [
32252
32413
  "maxFiles"
32253
32414
  ],
@@ -32255,38 +32416,38 @@ var UploadSessionToolInput = z134.object(UploadSessionToolInputShape).superRefin
32255
32416
  });
32256
32417
  }
32257
32418
  });
32258
- var UploadSessionResponse = z134.object({
32259
- sessionId: z134.string().uuid(),
32260
- uploadPageUrl: z134.string().url(),
32261
- mediaKind: z134.enum([
32419
+ var UploadSessionResponse = z135.object({
32420
+ sessionId: z135.string().uuid(),
32421
+ uploadPageUrl: z135.string().url(),
32422
+ mediaKind: z135.enum([
32262
32423
  "image",
32263
32424
  "video",
32264
32425
  "mixed"
32265
32426
  ]),
32266
- assetRole: z134.enum([
32427
+ assetRole: z135.enum([
32267
32428
  "media",
32268
32429
  "thumbnail"
32269
32430
  ]),
32270
- maxFiles: z134.number().int().positive(),
32271
- expiresAt: z134.string().datetime()
32431
+ maxFiles: z135.number().int().positive(),
32432
+ expiresAt: z135.string().datetime()
32272
32433
  });
32273
- var UploadStatusInput = z134.object({
32274
- sessionId: z134.string().uuid().describe("The sessionId returned by request_media_upload.")
32434
+ var UploadStatusInput = z135.object({
32435
+ sessionId: z135.string().uuid().describe("The sessionId returned by request_media_upload.")
32275
32436
  });
32276
- var UniversalUploadStatusResponse = z134.discriminatedUnion("status", [
32277
- z134.object({
32278
- status: z134.literal("pending"),
32279
- assets: z134.array(z134.never()).length(0)
32437
+ var UniversalUploadStatusResponse = z135.discriminatedUnion("status", [
32438
+ z135.object({
32439
+ status: z135.literal("pending"),
32440
+ assets: z135.array(z135.never()).length(0)
32280
32441
  }),
32281
- z134.object({
32282
- status: z134.literal("uploaded"),
32283
- assets: z134.array(z134.object({
32284
- assetId: z134.string().uuid(),
32285
- mediaKind: z134.enum([
32442
+ z135.object({
32443
+ status: z135.literal("uploaded"),
32444
+ assets: z135.array(z135.object({
32445
+ assetId: z135.string().uuid(),
32446
+ mediaKind: z135.enum([
32286
32447
  "image",
32287
32448
  "video"
32288
32449
  ]),
32289
- assetRole: z134.enum([
32450
+ assetRole: z135.enum([
32290
32451
  "media",
32291
32452
  "thumbnail"
32292
32453
  ])
@@ -32294,13 +32455,13 @@ var UniversalUploadStatusResponse = z134.discriminatedUnion("status", [
32294
32455
  })
32295
32456
  ]);
32296
32457
  var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
32297
- uploadPurpose: z134.enum([
32458
+ uploadPurpose: z135.enum([
32298
32459
  "product_reference",
32299
32460
  "creative",
32300
32461
  "generic"
32301
32462
  ]),
32302
- checkToolName: z134.literal("check_media_upload"),
32303
- resolveEndpoint: z134.string().url()
32463
+ checkToolName: z135.literal("check_media_upload"),
32464
+ resolveEndpoint: z135.string().url()
32304
32465
  });
32305
32466
  function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
32306
32467
  const url = new URL(uploadPageUrl);
@@ -32391,15 +32552,15 @@ function registerMediaUploadTools(server, api) {
32391
32552
  __name(registerMediaUploadTools, "registerMediaUploadTools");
32392
32553
 
32393
32554
  // src/tools/campaigns.ts
32394
- import { z as z135 } from "zod";
32555
+ import { z as z136 } from "zod";
32395
32556
  var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
32396
32557
  var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
32397
- var MetaStatusInput = z135.object({
32398
- campaignId: z135.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
32558
+ var MetaStatusInput = z136.object({
32559
+ campaignId: z136.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
32399
32560
  });
32400
- var TikTokStatusInput = z135.object({
32401
- campaignId: z135.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
32402
- advertiserId: z135.string().min(1).describe("The same advertiserId used to publish the campaign.")
32561
+ var TikTokStatusInput = z136.object({
32562
+ campaignId: z136.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
32563
+ advertiserId: z136.string().min(1).describe("The same advertiserId used to publish the campaign.")
32403
32564
  });
32404
32565
  function registerCampaignTools(server, api) {
32405
32566
  server.registerTool("get_meta_campaign_status", {
@@ -32504,10 +32665,10 @@ function renderTikTokStatusMarkdown(r) {
32504
32665
  __name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
32505
32666
 
32506
32667
  // ../../packages/product-economics/src/product-costing.ts
32507
- import { z as z137 } from "zod";
32668
+ import { z as z138 } from "zod";
32508
32669
 
32509
32670
  // ../../packages/product-economics/src/product-costing-countries.ts
32510
- import { z as z136 } from "zod";
32671
+ import { z as z137 } from "zod";
32511
32672
 
32512
32673
  // ../../packages/product-economics/src/product-costing-shipping-references.json
32513
32674
  var product_costing_shipping_references_default = {
@@ -32571,21 +32732,21 @@ var product_costing_shipping_references_default = {
32571
32732
  };
32572
32733
 
32573
32734
  // ../../packages/product-economics/src/product-costing-countries.ts
32574
- var ShippingReferenceSchema = z136.object({
32575
- reference: z136.number().positive(),
32576
- min: z136.number().nonnegative(),
32577
- max: z136.number().positive(),
32578
- updatedAt: z136.string().date(),
32579
- confidence: z136.enum([
32735
+ var ShippingReferenceSchema = z137.object({
32736
+ reference: z137.number().positive(),
32737
+ min: z137.number().nonnegative(),
32738
+ max: z137.number().positive(),
32739
+ updatedAt: z137.string().date(),
32740
+ confidence: z137.enum([
32580
32741
  "high",
32581
32742
  "medium",
32582
32743
  "medium-low"
32583
32744
  ]),
32584
- sources: z136.array(z136.string().url().startsWith("https://")).min(1).max(3)
32745
+ sources: z137.array(z137.string().url().startsWith("https://")).min(1).max(3)
32585
32746
  }).superRefine(({ reference, min, max }, context) => {
32586
32747
  if (min > reference || reference > max) {
32587
32748
  context.addIssue({
32588
- code: z136.ZodIssueCode.custom,
32749
+ code: z137.ZodIssueCode.custom,
32589
32750
  message: "shipping_reference_outside_range",
32590
32751
  path: [
32591
32752
  "reference"
@@ -32593,7 +32754,7 @@ var ShippingReferenceSchema = z136.object({
32593
32754
  });
32594
32755
  }
32595
32756
  });
32596
- var SHIPPING_REFERENCES = z136.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
32757
+ var SHIPPING_REFERENCES = z137.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
32597
32758
  var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
32598
32759
  var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
32599
32760
  "MX",
@@ -32775,18 +32936,18 @@ function getProductCostingCountryName(country) {
32775
32936
  __name(getProductCostingCountryName, "getProductCostingCountryName");
32776
32937
 
32777
32938
  // ../../packages/product-economics/src/product-costing.ts
32778
- var ProductCostingInputSchema = z137.object({
32779
- country: z137.string().refine(isProductCostingCountryCode, "unsupported_country"),
32780
- supplierCost: z137.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
32781
- shippingCost: z137.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
32782
- returnRate: z137.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
32783
- cancellationRate: z137.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
32784
- adsManagerCpa: z137.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
32785
- desiredMargin: z137.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
32939
+ var ProductCostingInputSchema = z138.object({
32940
+ country: z138.string().refine(isProductCostingCountryCode, "unsupported_country"),
32941
+ supplierCost: z138.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
32942
+ shippingCost: z138.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
32943
+ returnRate: z138.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
32944
+ cancellationRate: z138.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
32945
+ adsManagerCpa: z138.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
32946
+ desiredMargin: z138.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
32786
32947
  }).superRefine(({ returnRate, cancellationRate }, context) => {
32787
32948
  if (returnRate + cancellationRate >= 1) {
32788
32949
  context.addIssue({
32789
- code: z137.ZodIssueCode.custom,
32950
+ code: z138.ZodIssueCode.custom,
32790
32951
  message: "delivery_rate_positive",
32791
32952
  path: [
32792
32953
  "cancellationRate"
@@ -32883,15 +33044,15 @@ function calculateProductCosting(rawInput) {
32883
33044
  __name(calculateProductCosting, "calculateProductCosting");
32884
33045
 
32885
33046
  // src/tools/product-costing.ts
32886
- import { z as z138 } from "zod";
33047
+ import { z as z139 } from "zod";
32887
33048
  var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
32888
- var optionalAmount = /* @__PURE__ */ __name((description) => z138.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
32889
- var optionalPercent = /* @__PURE__ */ __name((description) => z138.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
32890
- var ProductCostingToolInput = z138.object({
32891
- country: z138.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
33049
+ var optionalAmount = /* @__PURE__ */ __name((description) => z139.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
33050
+ var optionalPercent = /* @__PURE__ */ __name((description) => z139.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
33051
+ var ProductCostingToolInput = z139.object({
33052
+ country: z139.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
32892
33053
  message: "Pa\xEDs no soportado por ProductMaker."
32893
33054
  }).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
32894
- supplierCost: z138.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."),
33055
+ supplierCost: z139.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."),
32895
33056
  supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
32896
33057
  shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
32897
33058
  shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
@@ -33054,7 +33215,7 @@ function formatPercent(value) {
33054
33215
  __name(formatPercent, "formatPercent");
33055
33216
 
33056
33217
  // src/tools/product-research.ts
33057
- import { z as z139 } from "zod";
33218
+ import { z as z140 } from "zod";
33058
33219
 
33059
33220
  // src/tools/product-research-idempotency.ts
33060
33221
  var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
@@ -33425,35 +33586,35 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
33425
33586
  ]);
33426
33587
  var POLL_INTERVAL_MS = 5e3;
33427
33588
  var MAX_WAIT_SECONDS = 120;
33428
- var FindInput = z139.object({
33589
+ var FindInput = z140.object({
33429
33590
  targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
33430
33591
  categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
33431
- confirmed: z139.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
33432
- waitSeconds: z139.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
33592
+ confirmed: z140.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
33593
+ waitSeconds: z140.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
33433
33594
  });
33434
- var GetInput = z139.object({
33435
- runId: z139.string().uuid().describe("ID del run devuelto por find_winning_products.")
33595
+ var GetInput = z140.object({
33596
+ runId: z140.string().uuid().describe("ID del run devuelto por find_winning_products.")
33436
33597
  });
33437
- var ListInput = z139.object({
33438
- limit: z139.number().int().min(1).max(20).default(10)
33598
+ var ListInput = z140.object({
33599
+ limit: z140.number().int().min(1).max(20).default(10)
33439
33600
  });
33440
- function textResult(text3) {
33601
+ function textResult(text4) {
33441
33602
  return {
33442
33603
  content: [
33443
33604
  {
33444
33605
  type: "text",
33445
- text: text3
33606
+ text: text4
33446
33607
  }
33447
33608
  ]
33448
33609
  };
33449
33610
  }
33450
33611
  __name(textResult, "textResult");
33451
- function researchResult(run, text3) {
33612
+ function researchResult(run, text4) {
33452
33613
  return {
33453
33614
  content: [
33454
33615
  {
33455
33616
  type: "text",
33456
- text: text3
33617
+ text: text4
33457
33618
  }
33458
33619
  ],
33459
33620
  structuredContent: run
@@ -33574,17 +33735,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
33574
33735
  __name(registerProductResearchTools, "registerProductResearchTools");
33575
33736
 
33576
33737
  // src/tools/dropshipping-projects.ts
33577
- import { z as z140 } from "zod";
33738
+ import { z as z141 } from "zod";
33578
33739
  var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
33579
33740
  var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
33580
33741
  var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
33581
- var ProjectId = z140.string().uuid();
33582
- var DropshippingProjectStatus = z140.enum([
33742
+ var ProjectId = z141.string().uuid();
33743
+ var DropshippingProjectStatus = z141.enum([
33583
33744
  "active",
33584
33745
  "completed",
33585
33746
  "archived"
33586
33747
  ]);
33587
- var DropshippingProjectPhase = z140.enum([
33748
+ var DropshippingProjectPhase = z141.enum([
33588
33749
  "research",
33589
33750
  "costing",
33590
33751
  "media",
@@ -33593,21 +33754,21 @@ var DropshippingProjectPhase = z140.enum([
33593
33754
  "advertising",
33594
33755
  "complete"
33595
33756
  ]);
33596
- var DropshippingRewardMilestone = z140.enum([
33757
+ var DropshippingRewardMilestone = z141.enum([
33597
33758
  "product_selected",
33598
33759
  "costing_saved",
33599
33760
  "product_media_ready",
33600
33761
  "creatives_completed",
33601
33762
  "campaign_created"
33602
33763
  ]);
33603
- var TargetCountry = z140.enum([
33764
+ var TargetCountry = z141.enum([
33604
33765
  "CO",
33605
33766
  "MX",
33606
33767
  "PE",
33607
33768
  "EC",
33608
33769
  "CL"
33609
33770
  ]);
33610
- var ResearchCategory = z140.enum([
33771
+ var ResearchCategory = z141.enum([
33611
33772
  "auto",
33612
33773
  "automotive",
33613
33774
  "kitchen",
@@ -33622,7 +33783,7 @@ var ResearchCategory = z140.enum([
33622
33783
  "garden",
33623
33784
  "cleaning"
33624
33785
  ]);
33625
- var HttpUrl3 = z140.string().url().max(2e3).refine((value) => {
33786
+ var HttpUrl3 = z141.string().url().max(2e3).refine((value) => {
33626
33787
  try {
33627
33788
  return [
33628
33789
  "http:",
@@ -33632,45 +33793,45 @@ var HttpUrl3 = z140.string().url().max(2e3).refine((value) => {
33632
33793
  return false;
33633
33794
  }
33634
33795
  }, "URL must use HTTP(S)");
33635
- var ResearchCandidateOrigin = z140.object({
33636
- type: z140.literal("research_candidate"),
33796
+ var ResearchCandidateOrigin = z141.object({
33797
+ type: z141.literal("research_candidate"),
33637
33798
  runId: ProjectId,
33638
- candidateSourceId: z140.string().min(1).max(160)
33799
+ candidateSourceId: z141.string().min(1).max(160)
33639
33800
  });
33640
- var TaskOrigin = z140.object({
33641
- type: z140.literal("task"),
33801
+ var TaskOrigin = z141.object({
33802
+ type: z141.literal("task"),
33642
33803
  taskId: ProjectId
33643
33804
  });
33644
- var ManualOrigin = z140.object({
33645
- type: z140.literal("manual"),
33805
+ var ManualOrigin = z141.object({
33806
+ type: z141.literal("manual"),
33646
33807
  clientRequestId: ProjectId,
33647
- country: z140.string().min(2).max(3).optional()
33808
+ country: z141.string().min(2).max(3).optional()
33648
33809
  });
33649
- var StartProjectInput = z140.object({
33650
- origin: z140.discriminatedUnion("type", [
33810
+ var StartProjectInput = z141.object({
33811
+ origin: z141.discriminatedUnion("type", [
33651
33812
  ResearchCandidateOrigin,
33652
33813
  TaskOrigin,
33653
33814
  ManualOrigin
33654
33815
  ]),
33655
- productName: z140.string().trim().min(1).max(240).optional(),
33816
+ productName: z141.string().trim().min(1).max(240).optional(),
33656
33817
  productUrl: HttpUrl3.optional(),
33657
- country: z140.string().min(2).max(3).optional(),
33658
- languageCode: z140.string().min(2).max(16).optional()
33818
+ country: z141.string().min(2).max(3).optional(),
33819
+ languageCode: z141.string().min(2).max(16).optional()
33659
33820
  }).strict();
33660
- var CostProjectInput = z140.object({
33821
+ var CostProjectInput = z141.object({
33661
33822
  projectId: ProjectId,
33662
- version: z140.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
33663
- country: z140.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
33823
+ version: z141.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
33824
+ country: z141.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
33664
33825
  message: "Pa\xEDs no soportado por ProductMaker."
33665
33826
  }).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
33666
- supplierCost: z140.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."),
33667
- shippingCost: z140.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
33668
- returnRate: z140.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."),
33669
- cancellationRate: z140.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."),
33670
- adsManagerCpa: z140.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
33671
- desiredMargin: z140.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
33672
- });
33673
- var GuideInput = z140.object({
33827
+ supplierCost: z141.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."),
33828
+ shippingCost: z141.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
33829
+ returnRate: z141.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."),
33830
+ cancellationRate: z141.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."),
33831
+ adsManagerCpa: z141.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
33832
+ desiredMargin: z141.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
33833
+ });
33834
+ var GuideInput = z141.object({
33674
33835
  projectId: ProjectId.optional()
33675
33836
  }).strict();
33676
33837
  var NEXT_ACTION_KINDS = [
@@ -33688,29 +33849,29 @@ var NEXT_ACTION_KINDS = [
33688
33849
  "repair_meta_campaign",
33689
33850
  "review_paused_campaign"
33690
33851
  ];
33691
- var DropshippingProjectNextAction = z140.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z140.object({
33692
- kind: z140.literal(kind),
33693
- href: z140.string().min(1)
33852
+ var DropshippingProjectNextAction = z141.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z141.object({
33853
+ kind: z141.literal(kind),
33854
+ href: z141.string().min(1)
33694
33855
  })));
33695
- var CostingInputSchema = z140.object({
33696
- country: z140.string().min(2).max(3),
33697
- supplierCost: z140.number().finite().positive(),
33698
- shippingCost: z140.number().finite().nonnegative(),
33699
- returnRate: z140.number().finite().min(0).lt(1),
33700
- cancellationRate: z140.number().finite().min(0).lt(1),
33701
- adsManagerCpa: z140.number().finite().nonnegative(),
33702
- desiredMargin: z140.number().finite().min(0).lt(1)
33856
+ var CostingInputSchema = z141.object({
33857
+ country: z141.string().min(2).max(3),
33858
+ supplierCost: z141.number().finite().positive(),
33859
+ shippingCost: z141.number().finite().nonnegative(),
33860
+ returnRate: z141.number().finite().min(0).lt(1),
33861
+ cancellationRate: z141.number().finite().min(0).lt(1),
33862
+ adsManagerCpa: z141.number().finite().nonnegative(),
33863
+ desiredMargin: z141.number().finite().min(0).lt(1)
33703
33864
  }).superRefine(({ returnRate, cancellationRate }, context) => {
33704
33865
  if (returnRate + cancellationRate >= 1) context.addIssue({
33705
- code: z140.ZodIssueCode.custom,
33866
+ code: z141.ZodIssueCode.custom,
33706
33867
  path: [
33707
33868
  "cancellationRate"
33708
33869
  ]
33709
33870
  });
33710
33871
  });
33711
- var FiniteCostingNumber = z140.number().finite();
33712
- var CostingResultSchema = z140.object({
33713
- country: z140.string().min(2).max(3),
33872
+ var FiniteCostingNumber = z141.number().finite();
33873
+ var CostingResultSchema = z141.object({
33874
+ country: z141.string().min(2).max(3),
33714
33875
  deliveryRate: FiniteCostingNumber,
33715
33876
  adjustedShippingCost: FiniteCostingNumber,
33716
33877
  adjustedCpa: FiniteCostingNumber,
@@ -33723,45 +33884,45 @@ var CostingResultSchema = z140.object({
33723
33884
  estimatedProfit: FiniteCostingNumber,
33724
33885
  actualMargin: FiniteCostingNumber,
33725
33886
  breakEvenAdsManagerCpa: FiniteCostingNumber,
33726
- wasPriceAutoAdjusted: z140.boolean(),
33727
- profitabilityStatus: z140.literal("healthy")
33728
- });
33729
- var RewardProgressSchema = z140.object({
33730
- campaignKey: z140.literal("dropshipping-launch-v1"),
33731
- totalCredits: z140.number().int().positive(),
33732
- earnedCredits: z140.number().int().nonnegative(),
33733
- milestones: z140.array(z140.object({
33887
+ wasPriceAutoAdjusted: z141.boolean(),
33888
+ profitabilityStatus: z141.literal("healthy")
33889
+ });
33890
+ var RewardProgressSchema = z141.object({
33891
+ campaignKey: z141.literal("dropshipping-launch-v1"),
33892
+ totalCredits: z141.number().int().positive(),
33893
+ earnedCredits: z141.number().int().nonnegative(),
33894
+ milestones: z141.array(z141.object({
33734
33895
  milestone: DropshippingRewardMilestone,
33735
- credits: z140.number().int().positive(),
33736
- available: z140.boolean().optional(),
33737
- earned: z140.boolean(),
33896
+ credits: z141.number().int().positive(),
33897
+ available: z141.boolean().optional(),
33898
+ earned: z141.boolean(),
33738
33899
  grantId: ProjectId.nullable(),
33739
- grantedAt: z140.string().datetime().nullable()
33900
+ grantedAt: z141.string().datetime().nullable()
33740
33901
  })).length(DropshippingRewardMilestone.options.length)
33741
33902
  });
33742
- var ProjectResponseSchema = z140.object({
33903
+ var ProjectResponseSchema = z141.object({
33743
33904
  id: ProjectId,
33744
33905
  taskId: ProjectId.nullable(),
33745
33906
  status: DropshippingProjectStatus,
33746
- originKey: z140.string().min(1),
33907
+ originKey: z141.string().min(1),
33747
33908
  researchRunId: ProjectId.nullable(),
33748
- candidateSourceId: z140.string().nullable(),
33749
- productName: z140.string().nullable(),
33909
+ candidateSourceId: z141.string().nullable(),
33910
+ productName: z141.string().nullable(),
33750
33911
  productUrl: HttpUrl3.nullable(),
33751
33912
  referenceImageUrl: HttpUrl3.nullable(),
33752
- targetCountry: z140.string().nullable(),
33753
- languageCode: z140.string().nullable(),
33754
- hasReferenceImage: z140.boolean(),
33755
- hasWinnerReferenceImage: z140.boolean(),
33913
+ targetCountry: z141.string().nullable(),
33914
+ languageCode: z141.string().nullable(),
33915
+ hasReferenceImage: z141.boolean(),
33916
+ hasWinnerReferenceImage: z141.boolean(),
33756
33917
  costingInput: CostingInputSchema.nullable(),
33757
33918
  costingResult: CostingResultSchema.nullable(),
33758
- costingVersion: z140.number().int().positive().nullable(),
33759
- version: z140.number().int().positive(),
33919
+ costingVersion: z141.number().int().positive().nullable(),
33920
+ version: z141.number().int().positive(),
33760
33921
  phase: DropshippingProjectPhase,
33761
33922
  nextAction: DropshippingProjectNextAction.nullable(),
33762
33923
  rewards: RewardProgressSchema,
33763
- createdAt: z140.string().datetime(),
33764
- updatedAt: z140.string().datetime()
33924
+ createdAt: z141.string().datetime(),
33925
+ updatedAt: z141.string().datetime()
33765
33926
  }).passthrough();
33766
33927
  var NEXT_ACTION_GUIDANCE = {
33767
33928
  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.",
@@ -33881,58 +34042,58 @@ function registerDropshippingProjectTools(server, api) {
33881
34042
  __name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
33882
34043
 
33883
34044
  // src/tools/daily-control.ts
33884
- import { z as z141 } from "zod";
34045
+ import { z as z142 } from "zod";
33885
34046
  var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
33886
34047
  var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
33887
34048
  var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
33888
- var ProviderCampaignIdentifier = z141.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
33889
- var DateOnly = z141.string().regex(/^\d{4}-\d{2}-\d{2}$/);
33890
- var DailyControlInput = z141.object({
34049
+ var ProviderCampaignIdentifier = z142.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
34050
+ var DateOnly = z142.string().regex(/^\d{4}-\d{2}-\d{2}$/);
34051
+ var DailyControlInput = z142.object({
33891
34052
  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."),
33892
- days: z141.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
33893
- projectId: z141.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
34053
+ days: z142.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
34054
+ projectId: z142.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
33894
34055
  }).strict();
33895
- var LinkCampaignInput = z141.object({
33896
- projectId: z141.string().uuid(),
33897
- provider: z141.enum([
34056
+ var LinkCampaignInput = z142.object({
34057
+ projectId: z142.string().uuid(),
34058
+ provider: z142.enum([
33898
34059
  "meta",
33899
34060
  "tiktok"
33900
34061
  ]),
33901
34062
  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."),
33902
34063
  campaignId: ProviderCampaignIdentifier
33903
34064
  }).strict();
33904
- var ReportReturnsInput = z141.object({
33905
- projectId: z141.string().uuid(),
34065
+ var ReportReturnsInput = z142.object({
34066
+ projectId: z142.string().uuid(),
33906
34067
  date: DateOnly,
33907
- returnedOrders: z141.number().int().min(0).max(1e5),
33908
- note: z141.string().trim().max(280).optional()
33909
- }).strict();
33910
- var DailyControlStatusMirror = DailyControlStatusEnum.or(z141.string());
33911
- var DailyControlLightMirror = DailyControlLightEnum.or(z141.string());
33912
- var DailyControlSourceMirror = DailyControlSourceEnum.or(z141.string());
33913
- var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z141.string());
33914
- var DailyControlDayMirror = z141.object({
33915
- date: z141.string(),
33916
- returnedOrders: z141.number(),
34068
+ returnedOrders: z142.number().int().min(0).max(1e5),
34069
+ note: z142.string().trim().max(280).optional()
34070
+ }).strict();
34071
+ var DailyControlStatusMirror = DailyControlStatusEnum.or(z142.string());
34072
+ var DailyControlLightMirror = DailyControlLightEnum.or(z142.string());
34073
+ var DailyControlSourceMirror = DailyControlSourceEnum.or(z142.string());
34074
+ var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z142.string());
34075
+ var DailyControlDayMirror = z142.object({
34076
+ date: z142.string(),
34077
+ returnedOrders: z142.number(),
33917
34078
  returnedSource: DailyControlSourceMirror,
33918
34079
  cancelledSource: DailyControlSourceMirror,
33919
- hasEstimates: z141.boolean(),
34080
+ hasEstimates: z142.boolean(),
33920
34081
  light: DailyControlLightMirror
33921
34082
  }).passthrough();
33922
- var DailyControlProductMirror = z141.object({
33923
- projectId: z141.string().uuid(),
33924
- productName: z141.string().nullable(),
34083
+ var DailyControlProductMirror = z142.object({
34084
+ projectId: z142.string().uuid(),
34085
+ productName: z142.string().nullable(),
33925
34086
  status: DailyControlStatusMirror,
33926
- statusMessage: z141.string().nullable(),
33927
- days: z141.array(DailyControlDayMirror),
34087
+ statusMessage: z142.string().nullable(),
34088
+ days: z142.array(DailyControlDayMirror),
33928
34089
  verdict: DailyControlVerdictMirror.nullable(),
33929
- rationale: z141.string().nullable()
34090
+ rationale: z142.string().nullable()
33930
34091
  }).passthrough();
33931
- var DailyControlResponseMirror = z141.object({
33932
- since: z141.string(),
33933
- until: z141.string(),
33934
- products: z141.array(DailyControlProductMirror),
33935
- archivedProjectSpend: z141.array(z141.unknown())
34092
+ var DailyControlResponseMirror = z142.object({
34093
+ since: z142.string(),
34094
+ until: z142.string(),
34095
+ products: z142.array(DailyControlProductMirror),
34096
+ archivedProjectSpend: z142.array(z142.unknown())
33936
34097
  }).passthrough();
33937
34098
  var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
33938
34099
  function withWarnings(response) {
@@ -34007,7 +34168,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
34007
34168
  // src/tools/product-control.ts
34008
34169
  import { readFile, stat } from "fs/promises";
34009
34170
  import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
34010
- import { z as z142 } from "zod";
34171
+ import { z as z143 } from "zod";
34011
34172
  var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
34012
34173
  var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
34013
34174
  var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
@@ -34020,36 +34181,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
34020
34181
  var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
34021
34182
  var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
34022
34183
  var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
34023
- var DateOnly2 = z142.string().regex(/^\d{4}-\d{2}-\d{2}$/);
34184
+ var DateOnly2 = z143.string().regex(/^\d{4}-\d{2}-\d{2}$/);
34024
34185
  var IMPORT_BATCH_MAX2 = 50;
34025
- var ProductControlListInput = z142.object({
34026
- days: z142.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
34186
+ var ProductControlListInput = z143.object({
34187
+ days: z143.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
34027
34188
  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."),
34028
- shopDomain: z142.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
34189
+ shopDomain: z143.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
34029
34190
  }).strict();
34030
- var ImportableProductsInput = z142.object({
34031
- q: z142.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
34032
- after: z142.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
34033
- shopDomain: z142.string().min(1).optional()
34191
+ var ImportableProductsInput = z143.object({
34192
+ q: z143.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
34193
+ after: z143.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
34194
+ shopDomain: z143.string().min(1).optional()
34034
34195
  }).strict();
34035
- var ImportProductControlsInput = z142.object({
34036
- shopifyProductIds: z142.array(z142.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."),
34196
+ var ImportProductControlsInput = z143.object({
34197
+ shopifyProductIds: z143.array(z143.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."),
34037
34198
  // Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
34038
34199
  // sin decir a cuál archivaría el producto bajo la tienda equivocada.
34039
- shopDomain: z142.string().min(1)
34040
- }).strict();
34041
- var SetProductCostingInput = z142.object({
34042
- shopDomain: z142.string().min(1),
34043
- shopifyProductId: z142.string().min(1).max(64),
34044
- targetCountry: z142.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
34045
- supplierCost: z142.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
34046
- shippingCost: z142.number().finite().nonnegative(),
34047
- returnRate: z142.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
34048
- cancellationRate: z142.number().finite().min(0).lt(1)
34049
- }).strict();
34050
- var Count = z142.number().int().min(0).max(1e5).nullable().optional();
34051
- var ReportProductCountsInput = z142.object({
34052
- productControlId: z142.string().uuid().describe("El identificador que devuelve get_product_control."),
34200
+ shopDomain: z143.string().min(1)
34201
+ }).strict();
34202
+ var SetProductCostingInput = z143.object({
34203
+ shopDomain: z143.string().min(1),
34204
+ shopifyProductId: z143.string().min(1).max(64),
34205
+ targetCountry: z143.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
34206
+ supplierCost: z143.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
34207
+ shippingCost: z143.number().finite().nonnegative(),
34208
+ returnRate: z143.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
34209
+ cancellationRate: z143.number().finite().min(0).lt(1)
34210
+ }).strict();
34211
+ var Count = z143.number().int().min(0).max(1e5).nullable().optional();
34212
+ var ReportProductCountsInput = z143.object({
34213
+ productControlId: z143.string().uuid().describe("El identificador que devuelve get_product_control."),
34053
34214
  date: DateOnly2,
34054
34215
  orders: Count.describe("Pedidos que entraron ese d\xEDa."),
34055
34216
  cancelledOrders: Count,
@@ -34059,36 +34220,36 @@ var ReportProductCountsInput = z142.object({
34059
34220
  }).strict();
34060
34221
  var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
34061
34222
  var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
34062
- var ImportOrdersFileInput = z142.object({
34223
+ var ImportOrdersFileInput = z143.object({
34063
34224
  /** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
34064
- path: z142.string().min(1),
34065
- operationId: z142.string().uuid().optional(),
34225
+ path: z143.string().min(1),
34226
+ operationId: z143.string().uuid().optional(),
34066
34227
  /** Solo mirar: devuelve el resumen y no escribe nada. */
34067
- dryRun: z142.boolean().optional()
34228
+ dryRun: z143.boolean().optional()
34068
34229
  }).strict();
34069
- var CreateOperationInput = z142.object({
34070
- countryCode: z142.string().length(2),
34071
- label: z142.string().trim().min(1).max(60).optional()
34230
+ var CreateOperationInput = z143.object({
34231
+ countryCode: z143.string().length(2),
34232
+ label: z143.string().trim().min(1).max(60).optional()
34072
34233
  }).strict();
34073
- var MergeProductsInput = z142.object({
34074
- sourceId: z142.string().uuid(),
34075
- targetId: z142.string().uuid()
34234
+ var MergeProductsInput = z143.object({
34235
+ sourceId: z143.string().uuid(),
34236
+ targetId: z143.string().uuid()
34076
34237
  }).strict();
34077
- var SetMonthlyExpenseInput = z142.object({
34078
- month: z142.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
34238
+ var SetMonthlyExpenseInput = z143.object({
34239
+ month: z143.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
34079
34240
  label: SaveMonthlyExpenseSchema.shape.label,
34080
- amount: z142.number().finite().min(0),
34081
- operationId: z142.string().uuid().optional()
34241
+ amount: z143.number().finite().min(0),
34242
+ operationId: z143.string().uuid().optional()
34082
34243
  }).strict();
34083
- var SetAdSpendInput = z142.object({
34084
- month: z142.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
34085
- operationId: z142.string().uuid().optional(),
34244
+ var SetAdSpendInput = z143.object({
34245
+ month: z143.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
34246
+ operationId: z143.string().uuid().optional(),
34086
34247
  /** null RETIRA la corrección; cero afirma que no pautó. */
34087
- amount: z142.number().finite().min(0).nullable()
34248
+ amount: z143.number().finite().min(0).nullable()
34088
34249
  }).strict();
34089
- var GetFinancesInput = z142.object({
34090
- month: z142.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."),
34091
- operationId: z142.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
34250
+ var GetFinancesInput = z143.object({
34251
+ month: z143.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."),
34252
+ operationId: z143.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
34092
34253
  }).strict();
34093
34254
  function registerProductControlTools(server, api, { transport = "http" } = {}) {
34094
34255
  server.registerTool("get_product_control", {
@@ -34280,28 +34441,28 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
34280
34441
  __name(registerProductControlTools, "registerProductControlTools");
34281
34442
 
34282
34443
  // src/tools/market-study-estimate.ts
34283
- import { z as z143 } from "zod";
34444
+ import { z as z144 } from "zod";
34284
34445
  var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
34285
- var ProductTaskOutputEnum = z143.enum([
34446
+ var ProductTaskOutputEnum = z144.enum([
34286
34447
  "landing",
34287
34448
  "video",
34288
34449
  "image"
34289
34450
  ]);
34290
- var EstimateMarketStudyInput = z143.object({
34291
- kind: z143.enum([
34451
+ var EstimateMarketStudyInput = z144.object({
34452
+ kind: z144.enum([
34292
34453
  "video",
34293
34454
  "product_task"
34294
34455
  ]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
34295
- videoAngleCount: z143.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
34296
- durationSeconds: z143.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
34456
+ videoAngleCount: z144.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
34457
+ durationSeconds: z144.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
34297
34458
  videoStructure: VideoStructureEnum.default("single_take"),
34298
34459
  videoQuality: VideoQualityEnum.default("economy"),
34299
34460
  videoResolution: VideoResolutionEnum.default("480p"),
34300
- productImageCount: z143.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
34461
+ productImageCount: z144.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
34301
34462
  outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
34302
- generateAiMusic: z143.boolean().optional(),
34463
+ generateAiMusic: z144.boolean().optional(),
34303
34464
  generateAiEdit: AiEditRequestSchema.optional(),
34304
- replicateWinnerWhenFound: z143.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.")
34465
+ replicateWinnerWhenFound: z144.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.")
34305
34466
  }).strict();
34306
34467
  function buildMarketStudyEstimateRequests(input) {
34307
34468
  const quotesVideo = input.kind === "video" || (input.outputs ?? [