@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/README.md +11 -0
- package/dist/http.js +1049 -888
- package/dist/stdio.js +1036 -875
- package/dist/ui/task-results-app.html +71 -8
- package/package.json +1 -1
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((
|
|
2791
|
+
const ids = snapshot.images.map((image2) => classicLandingBlockId({
|
|
2792
2792
|
kind: "image",
|
|
2793
|
-
...
|
|
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(
|
|
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(
|
|
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
|
|
21662
|
-
const exact = aliases[
|
|
21661
|
+
const text4 = raw.trim().toLowerCase();
|
|
21662
|
+
const exact = aliases[text4];
|
|
21663
21663
|
if (exact) return exact;
|
|
21664
|
-
const words = new Set(
|
|
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
|
|
23556
|
+
import { z as z119 } from "zod";
|
|
23557
23557
|
|
|
23558
|
-
// ../../packages/types/src/demo-mode-
|
|
23558
|
+
// ../../packages/types/src/demo-mode-product.ts
|
|
23559
23559
|
import { z as z117 } from "zod";
|
|
23560
|
-
var
|
|
23561
|
-
|
|
23562
|
-
|
|
23563
|
-
|
|
23564
|
-
|
|
23565
|
-
|
|
23566
|
-
|
|
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:
|
|
23571
|
-
width:
|
|
23572
|
-
height:
|
|
23573
|
-
contentHash:
|
|
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:
|
|
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 =
|
|
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 =
|
|
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
|
|
23606
|
-
|
|
23607
|
-
|
|
23608
|
-
|
|
23609
|
-
|
|
23610
|
-
|
|
23611
|
-
|
|
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:
|
|
23615
|
-
|
|
23616
|
-
|
|
23617
|
-
|
|
23618
|
-
|
|
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:
|
|
23622
|
-
chargeCents:
|
|
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
|
|
23631
|
-
|
|
23632
|
-
|
|
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:
|
|
23635
|
-
productSamples:
|
|
23636
|
-
name:
|
|
23637
|
-
priceCents:
|
|
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:
|
|
23785
|
+
imageKey: z119.string(),
|
|
23640
23786
|
productUrl: nullableString,
|
|
23641
|
-
position:
|
|
23787
|
+
position: z119.number().int()
|
|
23642
23788
|
})),
|
|
23643
|
-
personas:
|
|
23644
|
-
name:
|
|
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:
|
|
23796
|
+
isDefault: z119.boolean()
|
|
23651
23797
|
}))
|
|
23652
23798
|
}),
|
|
23653
|
-
servicePage:
|
|
23654
|
-
facts:
|
|
23655
|
-
review:
|
|
23656
|
-
artifact:
|
|
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:
|
|
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:
|
|
23668
|
-
bundleKey:
|
|
23669
|
-
sha256:
|
|
23670
|
-
uploadBytes:
|
|
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:
|
|
23675
|
-
provider:
|
|
23676
|
-
model:
|
|
23677
|
-
prompt:
|
|
23678
|
-
imageUrl:
|
|
23679
|
-
width:
|
|
23680
|
-
height:
|
|
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:
|
|
23828
|
+
rawResponse: z119.unknown()
|
|
23683
23829
|
})
|
|
23684
23830
|
});
|
|
23685
|
-
var DemoModeConfigSchema =
|
|
23831
|
+
var DemoModeConfigSchema = DemoModeEditableObjectSchema.extend({
|
|
23686
23832
|
snapshot: DemoModeSnapshotSchema.nullable(),
|
|
23687
|
-
snapshotAt:
|
|
23833
|
+
snapshotAt: z119.string().datetime().nullable()
|
|
23688
23834
|
});
|
|
23689
|
-
var DemoModeAdminViewSchema =
|
|
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:
|
|
23693
|
-
brandId:
|
|
23694
|
-
servicePageId:
|
|
23695
|
-
motionTaskId:
|
|
23696
|
-
motionVariantTaskId:
|
|
23697
|
-
motionThirdTaskId:
|
|
23698
|
-
imageTaskId:
|
|
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:
|
|
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 =
|
|
23712
|
-
|
|
23713
|
-
ok:
|
|
23866
|
+
var DemoModeTemplateVerdictSchema = z119.discriminatedUnion("ok", [
|
|
23867
|
+
z119.object({
|
|
23868
|
+
ok: z119.literal(true)
|
|
23714
23869
|
}),
|
|
23715
|
-
|
|
23716
|
-
ok:
|
|
23717
|
-
problem:
|
|
23870
|
+
z119.object({
|
|
23871
|
+
ok: z119.literal(false),
|
|
23872
|
+
problem: z119.enum(DEMO_MODE_TEMPLATE_PROBLEMS)
|
|
23718
23873
|
})
|
|
23719
23874
|
]);
|
|
23720
|
-
var DemoModeValidationSchema =
|
|
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
|
-
|
|
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:
|
|
23733
|
-
userId:
|
|
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:
|
|
23896
|
+
generation: z119.number().int().positive().optional(),
|
|
23736
23897
|
/** Solo `final`/`watchdog`: la parte del snapshot de ESTE flujo, congelada al empezar. */
|
|
23737
|
-
result:
|
|
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.
|
|
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((
|
|
24311
|
-
const url = safeUrl(
|
|
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:
|
|
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
|
|
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
|
|
24962
|
-
var Lang =
|
|
24963
|
-
var Country =
|
|
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 =
|
|
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 =
|
|
25126
|
-
url:
|
|
25127
|
-
path:
|
|
25128
|
-
assetId:
|
|
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 =
|
|
25137
|
-
const assetCount = images.filter((
|
|
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:
|
|
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((
|
|
25147
|
-
return images.map((
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
26208
|
-
variantTaskId:
|
|
26209
|
-
sourceTaskId:
|
|
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:
|
|
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
|
|
26817
|
-
var HttpsPresentationUrlSchema =
|
|
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) =>
|
|
26823
|
-
var PresentationImageSchema =
|
|
26824
|
-
kind:
|
|
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:
|
|
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:
|
|
26994
|
+
alt: z122.string().trim().min(1).max(240)
|
|
26834
26995
|
}).strict();
|
|
26835
26996
|
var McpMediaPresentationSchema = PresentationImageSchema;
|
|
26836
|
-
var GalleryImageSchema =
|
|
26997
|
+
var GalleryImageSchema = z122.object({
|
|
26837
26998
|
url: ProductMakerPreviewUrlSchema,
|
|
26838
|
-
alt:
|
|
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(
|
|
27002
|
+
async function imageBlocks(image2, transport) {
|
|
26842
27003
|
const portableFallback = [
|
|
26843
27004
|
{
|
|
26844
27005
|
type: "resource_link",
|
|
26845
|
-
uri:
|
|
26846
|
-
name:
|
|
26847
|
-
...
|
|
26848
|
-
mimeType:
|
|
27006
|
+
uri: image2.url,
|
|
27007
|
+
name: image2.alt,
|
|
27008
|
+
...image2.mimeType ? {
|
|
27009
|
+
mimeType: image2.mimeType
|
|
26849
27010
|
} : {},
|
|
26850
|
-
...
|
|
26851
|
-
size:
|
|
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: ${
|
|
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:
|
|
27023
|
+
url: image2.url
|
|
26863
27024
|
}
|
|
26864
27025
|
], {
|
|
26865
27026
|
transport,
|
|
26866
|
-
maxBytes:
|
|
27027
|
+
maxBytes: image2.byteSize ?? MCP_GALLERY_IMAGE_MAX_BYTES
|
|
26867
27028
|
});
|
|
26868
|
-
if (!resolved ||
|
|
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 =
|
|
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:
|
|
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
|
|
27137
|
+
const image2 = parsed.data;
|
|
26977
27138
|
const heading = {
|
|
26978
27139
|
type: "text",
|
|
26979
|
-
text: `Foto ${index + 1}: ${
|
|
27140
|
+
text: `Foto ${index + 1}: ${image2.alt}`
|
|
26980
27141
|
};
|
|
26981
27142
|
const fallback = {
|
|
26982
27143
|
type: "resource_link",
|
|
26983
|
-
uri:
|
|
26984
|
-
name: `Abrir foto ${index + 1}: ${
|
|
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: ${
|
|
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:
|
|
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
|
|
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 =
|
|
27446
|
-
var CreateAnimatedVideoInput =
|
|
27447
|
-
action:
|
|
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:
|
|
27454
|
-
websiteCaptureId:
|
|
27455
|
-
generationRequestId:
|
|
27456
|
-
confirmed:
|
|
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:
|
|
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:
|
|
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:
|
|
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 =
|
|
27522
|
-
status:
|
|
27682
|
+
var AnimatedVideoResultSchema = z123.object({
|
|
27683
|
+
status: z123.enum([
|
|
27523
27684
|
"pending",
|
|
27524
27685
|
"done",
|
|
27525
27686
|
"error"
|
|
27526
27687
|
]),
|
|
27527
|
-
serviceMode:
|
|
27528
|
-
finalMp4Url:
|
|
27529
|
-
adCopy:
|
|
27530
|
-
adCopies:
|
|
27531
|
-
error:
|
|
27532
|
-
motionGraphics:
|
|
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:
|
|
27536
|
-
width:
|
|
27537
|
-
height:
|
|
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:
|
|
27702
|
+
creativeBatch: z123.object({
|
|
27542
27703
|
index: MotionGraphicsHookVariantsSchema,
|
|
27543
27704
|
count: MotionGraphicsHookVariantsSchema,
|
|
27544
|
-
tasks:
|
|
27545
|
-
taskId:
|
|
27705
|
+
tasks: z123.array(z123.object({
|
|
27706
|
+
taskId: z123.string().uuid(),
|
|
27546
27707
|
index: MotionGraphicsHookVariantsSchema,
|
|
27547
|
-
status:
|
|
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:
|
|
27556
|
-
jobsAhead:
|
|
27557
|
-
stageStartedAt:
|
|
27558
|
-
renderProgress:
|
|
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:
|
|
27563
|
-
clipsUsed:
|
|
27564
|
-
clipPriceCents:
|
|
27565
|
-
clipsRefunded:
|
|
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:
|
|
27570
|
-
cleanVideoUrl:
|
|
27571
|
-
cleanVariantUrls:
|
|
27572
|
-
variantUrls:
|
|
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:
|
|
27576
|
-
activity:
|
|
27577
|
-
previewUrl:
|
|
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:
|
|
27791
|
+
const { text: text4, ...rest } = item;
|
|
27631
27792
|
return {
|
|
27632
27793
|
...rest,
|
|
27633
|
-
untrustedSiteText:
|
|
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 =
|
|
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
|
|
27899
|
-
var WinnerReferenceInput =
|
|
27900
|
-
runId:
|
|
27901
|
-
candidateSourceId:
|
|
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((
|
|
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((
|
|
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 =
|
|
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:
|
|
27942
|
-
productUrl:
|
|
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:
|
|
27946
|
-
compareAtPrice:
|
|
27947
|
-
offer:
|
|
27948
|
-
paymentMethods:
|
|
27949
|
-
productContext:
|
|
27950
|
-
productLabel:
|
|
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:
|
|
27954
|
-
|
|
27955
|
-
|
|
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:
|
|
27958
|
-
aiDecidesAll:
|
|
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:
|
|
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:
|
|
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:
|
|
27971
|
-
competitorScanEnabled:
|
|
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:
|
|
27974
|
-
brandId:
|
|
27975
|
-
actorId:
|
|
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:
|
|
27978
|
-
headline:
|
|
27979
|
-
subheadline:
|
|
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 =
|
|
27984
|
-
landingUrl:
|
|
27985
|
-
additionalContext:
|
|
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:
|
|
27988
|
-
brandId:
|
|
27989
|
-
reviewMode:
|
|
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:
|
|
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 =
|
|
28004
|
-
taskId:
|
|
28005
|
-
waitSeconds:
|
|
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 =
|
|
28008
|
-
limit:
|
|
28009
|
-
offset:
|
|
28010
|
-
search:
|
|
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 =
|
|
28015
|
-
taskId:
|
|
28016
|
-
angleIndex:
|
|
28017
|
-
angle:
|
|
28018
|
-
angle:
|
|
28019
|
-
buyerPersona:
|
|
28020
|
-
actor:
|
|
28021
|
-
actorId:
|
|
28022
|
-
gender:
|
|
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:
|
|
28187
|
+
scriptNotes: z125.string().max(2e3).optional()
|
|
28027
28188
|
})
|
|
28028
28189
|
});
|
|
28029
|
-
var PendingActionPayload =
|
|
28030
|
-
|
|
28031
|
-
kind:
|
|
28190
|
+
var PendingActionPayload = z125.discriminatedUnion("kind", [
|
|
28191
|
+
z125.object({
|
|
28192
|
+
kind: z125.literal("product_reference_set_approval"),
|
|
28032
28193
|
scope: ProductReferenceScopeEnum.optional(),
|
|
28033
|
-
scopeKey:
|
|
28034
|
-
scopeSnapshotId:
|
|
28035
|
-
expectedScopeHash:
|
|
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:
|
|
28039
|
-
affectedPhotoNumbers:
|
|
28040
|
-
recoveryAction:
|
|
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
|
-
|
|
28048
|
-
kind:
|
|
28049
|
-
selectedPhotoNumbers:
|
|
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:
|
|
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:
|
|
28215
|
+
useMultiSceneShowcase: z125.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
|
|
28055
28216
|
}),
|
|
28056
|
-
|
|
28057
|
-
kind:
|
|
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:
|
|
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:
|
|
28066
|
-
benefits:
|
|
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:
|
|
28073
|
-
buyerPersona:
|
|
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:
|
|
28076
|
-
actorId:
|
|
28077
|
-
creativeDirection:
|
|
28078
|
-
selectedAngleNumbers:
|
|
28079
|
-
angleEdits:
|
|
28080
|
-
angleNumber:
|
|
28081
|
-
narrativeSelection:
|
|
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:
|
|
28086
|
-
buyerPersona:
|
|
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:
|
|
28089
|
-
actorId:
|
|
28090
|
-
creativeDirection:
|
|
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:
|
|
28093
|
-
|
|
28094
|
-
|
|
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
|
-
|
|
28098
|
-
kind:
|
|
28099
|
-
angleId:
|
|
28100
|
-
angleNumber:
|
|
28101
|
-
content:
|
|
28102
|
-
creativeDirection:
|
|
28103
|
-
actor:
|
|
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
|
-
|
|
28106
|
-
kind:
|
|
28107
|
-
voiceovers:
|
|
28108
|
-
visualDirections:
|
|
28109
|
-
voiceoversByScene:
|
|
28110
|
-
visualDirectionsByScene:
|
|
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 =
|
|
28114
|
-
taskId:
|
|
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 =
|
|
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:
|
|
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:
|
|
28293
|
+
selectedOutputs: z125.array(z125.enum([
|
|
28133
28294
|
"landing",
|
|
28134
28295
|
"video",
|
|
28135
28296
|
"image"
|
|
28136
28297
|
])).optional(),
|
|
28137
|
-
videoAngleCount:
|
|
28138
|
-
ugcFormat:
|
|
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:
|
|
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:
|
|
28314
|
+
videoTier: z125.enum([
|
|
28154
28315
|
"legacy",
|
|
28155
28316
|
"standard",
|
|
28156
28317
|
"pro",
|
|
28157
28318
|
"single_call"
|
|
28158
28319
|
]).optional(),
|
|
28159
|
-
videoResolution:
|
|
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:
|
|
28168
|
-
pendingUserAction:
|
|
28169
|
-
kind:
|
|
28170
|
-
candidateGrouping:
|
|
28171
|
-
selectedImageUrls:
|
|
28172
|
-
proposedProductNames:
|
|
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:
|
|
28177
|
-
mode:
|
|
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:
|
|
28183
|
-
decisionKey:
|
|
28184
|
-
questionOrdinal:
|
|
28185
|
-
questionCeiling:
|
|
28186
|
-
|
|
28187
|
-
|
|
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:
|
|
28190
|
-
expectedEvidenceHash:
|
|
28191
|
-
question:
|
|
28192
|
-
prompt:
|
|
28193
|
-
helpText:
|
|
28194
|
-
options:
|
|
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:
|
|
28197
|
-
description:
|
|
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:
|
|
28202
|
-
scopeSnapshotId:
|
|
28203
|
-
scopeHash:
|
|
28204
|
-
baseReferenceSetHash:
|
|
28205
|
-
phase:
|
|
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:
|
|
28210
|
-
allowedDecisions:
|
|
28211
|
-
previews:
|
|
28212
|
-
refKey:
|
|
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:
|
|
28215
|
-
painPointsDraft:
|
|
28216
|
-
benefitsDraft:
|
|
28217
|
-
featuresDraft:
|
|
28218
|
-
angleOptions:
|
|
28219
|
-
index:
|
|
28220
|
-
angle:
|
|
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:
|
|
28231
|
-
id:
|
|
28232
|
-
content:
|
|
28233
|
-
creativeDirection:
|
|
28234
|
-
actor:
|
|
28235
|
-
actorId:
|
|
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:
|
|
28238
|
-
beatId:
|
|
28239
|
-
voiceover:
|
|
28240
|
-
visualDirection:
|
|
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:
|
|
28594
|
-
editId:
|
|
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((
|
|
28787
|
-
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((
|
|
28794
|
-
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 =
|
|
28866
|
-
items:
|
|
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 =
|
|
28873
|
-
taskId:
|
|
28874
|
-
resourceType:
|
|
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
|
|
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 =
|
|
29372
|
-
action:
|
|
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:
|
|
29378
|
-
businessNotes:
|
|
29379
|
-
language:
|
|
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:
|
|
29385
|
-
brandId:
|
|
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
|
|
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 =
|
|
29674
|
-
action:
|
|
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:
|
|
29681
|
-
servicePageId:
|
|
29682
|
-
businessInfo:
|
|
29683
|
-
confirmed:
|
|
29684
|
-
maxCredits:
|
|
29685
|
-
operationId:
|
|
29686
|
-
slug:
|
|
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(
|
|
29693
|
-
return createHash3("sha256").update(
|
|
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
|
|
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 =
|
|
30075
|
-
brandId:
|
|
30076
|
-
instruction:
|
|
30077
|
-
delegateToAi:
|
|
30078
|
-
format:
|
|
30079
|
-
count:
|
|
30080
|
-
quality:
|
|
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:
|
|
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:
|
|
30090
|
-
confirmed:
|
|
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
|
|
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
|
|
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:
|
|
30227
|
-
offer:
|
|
30228
|
-
compareAtPrice:
|
|
30229
|
-
productContext:
|
|
30230
|
-
productLabel:
|
|
30231
|
-
buyerPersona:
|
|
30232
|
-
isCombo:
|
|
30233
|
-
competitorScanEnabled:
|
|
30234
|
-
brandId:
|
|
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 =
|
|
30237
|
-
|
|
30238
|
-
mode:
|
|
30397
|
+
var VideoPresenter = z129.discriminatedUnion("mode", [
|
|
30398
|
+
z129.object({
|
|
30399
|
+
mode: z129.literal("none")
|
|
30239
30400
|
}).strict(),
|
|
30240
|
-
|
|
30241
|
-
mode:
|
|
30242
|
-
actorId:
|
|
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
|
-
|
|
30245
|
-
mode:
|
|
30246
|
-
description:
|
|
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 =
|
|
30250
|
-
|
|
30251
|
-
mode:
|
|
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
|
-
|
|
30254
|
-
mode:
|
|
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:
|
|
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:
|
|
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 =
|
|
30423
|
+
var VideoInput = z129.object({
|
|
30263
30424
|
images: CreativeRefs.images.optional(),
|
|
30264
30425
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
30265
|
-
title:
|
|
30266
|
-
primaryAngle:
|
|
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:
|
|
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:
|
|
30276
|
-
videoAngleCount:
|
|
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:
|
|
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:
|
|
30288
|
-
scriptNotes:
|
|
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:
|
|
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 =
|
|
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 =
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
30339
|
-
idempotencyKey:
|
|
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 =
|
|
30343
|
-
|
|
30344
|
-
mode:
|
|
30503
|
+
var ImageCreativeSetup = z129.discriminatedUnion("mode", [
|
|
30504
|
+
z129.object({
|
|
30505
|
+
mode: z129.literal("automatic")
|
|
30345
30506
|
}).strict(),
|
|
30346
|
-
|
|
30347
|
-
mode:
|
|
30348
|
-
creativeArchetype:
|
|
30507
|
+
z129.object({
|
|
30508
|
+
mode: z129.literal("guided"),
|
|
30509
|
+
creativeArchetype: z129.union([
|
|
30349
30510
|
ImageCreativeArchetypeEnum,
|
|
30350
|
-
|
|
30511
|
+
z129.literal("ai_decides")
|
|
30351
30512
|
]),
|
|
30352
|
-
visualTreatment:
|
|
30513
|
+
visualTreatment: z129.union([
|
|
30353
30514
|
ImageCreativeVisualTreatmentEnum,
|
|
30354
|
-
|
|
30515
|
+
z129.literal("ai_decides")
|
|
30355
30516
|
]),
|
|
30356
30517
|
aspectRatio: ImageCreativeAspectRatioEnum,
|
|
30357
|
-
nVariants:
|
|
30358
|
-
|
|
30359
|
-
|
|
30360
|
-
|
|
30361
|
-
|
|
30362
|
-
|
|
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:
|
|
30365
|
-
styleMix:
|
|
30366
|
-
generateAdCopy:
|
|
30367
|
-
competitorScanEnabled:
|
|
30368
|
-
productContext:
|
|
30369
|
-
creativeDirection:
|
|
30370
|
-
brandColors:
|
|
30371
|
-
headline:
|
|
30372
|
-
subheadline:
|
|
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:
|
|
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:
|
|
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:
|
|
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 =
|
|
30406
|
-
|
|
30407
|
-
mode:
|
|
30566
|
+
var LandingCreativeSetup = z129.discriminatedUnion("mode", [
|
|
30567
|
+
z129.object({
|
|
30568
|
+
mode: z129.literal("automatic")
|
|
30408
30569
|
}).strict(),
|
|
30409
|
-
|
|
30410
|
-
mode:
|
|
30570
|
+
z129.object({
|
|
30571
|
+
mode: z129.literal("guided"),
|
|
30411
30572
|
landingStrategy: LandingStrategyEnum,
|
|
30412
30573
|
landingImageFormat: LandingImageFormatEnum,
|
|
30413
|
-
competitorScanEnabled:
|
|
30414
|
-
paymentMethods:
|
|
30415
|
-
productContext:
|
|
30416
|
-
creativeDirection:
|
|
30417
|
-
headline:
|
|
30418
|
-
subheadline:
|
|
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 =
|
|
30582
|
+
var ImageInput = z129.object({
|
|
30422
30583
|
images: CreativeRefs.images.optional(),
|
|
30423
30584
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
30424
|
-
productTitle:
|
|
30425
|
-
primaryAngle:
|
|
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:
|
|
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:
|
|
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 =
|
|
30441
|
-
taskId:
|
|
30442
|
-
variantIndex:
|
|
30443
|
-
clientRequestId:
|
|
30444
|
-
instruction:
|
|
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 =
|
|
30447
|
-
includeInitialLandingGif:
|
|
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:
|
|
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:
|
|
30736
|
-
operationId:
|
|
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
|
|
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 =
|
|
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 =
|
|
30997
|
+
var CreativeVariantKindEnum = z130.enum([
|
|
30837
30998
|
"video",
|
|
30838
30999
|
"image",
|
|
30839
31000
|
"landing"
|
|
30840
31001
|
]);
|
|
30841
|
-
var EstimateCreativeVariantInputBase =
|
|
30842
|
-
sourceTaskId:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 =
|
|
30911
|
-
sourceTaskId:
|
|
31071
|
+
var CreateCreativeVariantInputBase = z130.object({
|
|
31072
|
+
sourceTaskId: z130.string().uuid().describe("ID de la tarea original completada."),
|
|
30912
31073
|
kind: CreativeVariantKindEnum,
|
|
30913
|
-
confirm:
|
|
30914
|
-
clientRequestId:
|
|
30915
|
-
angle:
|
|
30916
|
-
buyerPersona:
|
|
30917
|
-
scriptNotes:
|
|
30918
|
-
creativeDirection:
|
|
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:
|
|
30922
|
-
nVariants:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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 =
|
|
31152
|
-
taskId:
|
|
31153
|
-
angleKey:
|
|
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
|
|
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:
|
|
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:
|
|
31280
|
-
shopDomain:
|
|
31281
|
-
query:
|
|
31282
|
-
taskId:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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:
|
|
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:
|
|
31411
|
-
acceptedQuoteId:
|
|
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:
|
|
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:
|
|
31433
|
-
expectedRevision:
|
|
31434
|
-
expectedApprovedRevision:
|
|
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:
|
|
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
|
|
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 =
|
|
31514
|
-
taskId:
|
|
31515
|
-
shopDomain:
|
|
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:
|
|
31521
|
-
variantIndex:
|
|
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:
|
|
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:
|
|
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:
|
|
31697
|
+
targetProductId: z134.string().trim().min(1).max(300).optional(),
|
|
31537
31698
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
31538
|
-
announcementBarEnabled:
|
|
31539
|
-
announcementBarText:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 =
|
|
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:
|
|
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:
|
|
31586
|
-
campaignName:
|
|
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 =
|
|
31590
|
-
taskId:
|
|
31750
|
+
var MetaInput = z134.object({
|
|
31751
|
+
taskId: z134.string().min(1),
|
|
31591
31752
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
31592
|
-
portfolioId:
|
|
31753
|
+
portfolioId: z134.string().trim().min(1),
|
|
31593
31754
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
31594
|
-
pageId:
|
|
31755
|
+
pageId: z134.string().trim().min(1),
|
|
31595
31756
|
adAccountId: McpAdAccountId,
|
|
31596
|
-
pixelId:
|
|
31597
|
-
landingUrl:
|
|
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:
|
|
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:
|
|
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:
|
|
31769
|
+
phoneNumber: z134.string().min(8).max(32).optional()
|
|
31609
31770
|
});
|
|
31610
|
-
var GroupedTaskSource =
|
|
31611
|
-
type:
|
|
31612
|
-
taskId:
|
|
31613
|
-
angleIndex:
|
|
31614
|
-
videoVariant:
|
|
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:
|
|
31619
|
-
});
|
|
31620
|
-
var GroupedMediaSource =
|
|
31621
|
-
type:
|
|
31622
|
-
url:
|
|
31623
|
-
path:
|
|
31624
|
-
thumbnailUrl:
|
|
31625
|
-
thumbnailPath:
|
|
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 =
|
|
31632
|
-
type:
|
|
31792
|
+
var GroupedUploadedAssetSource = z134.object({
|
|
31793
|
+
type: z134.literal("asset"),
|
|
31633
31794
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
31634
|
-
assetId:
|
|
31635
|
-
thumbnailAssetId:
|
|
31795
|
+
assetId: z134.string().uuid(),
|
|
31796
|
+
thumbnailAssetId: z134.string().uuid().optional()
|
|
31636
31797
|
});
|
|
31637
|
-
var GroupedCreative =
|
|
31638
|
-
type:
|
|
31798
|
+
var GroupedCreative = z134.object({
|
|
31799
|
+
type: z134.enum([
|
|
31639
31800
|
"image",
|
|
31640
31801
|
"video"
|
|
31641
31802
|
]),
|
|
31642
|
-
source:
|
|
31803
|
+
source: z134.union([
|
|
31643
31804
|
GroupedTaskSource,
|
|
31644
31805
|
GroupedMediaSource,
|
|
31645
31806
|
GroupedUploadedAssetSource
|
|
31646
31807
|
]),
|
|
31647
|
-
title:
|
|
31648
|
-
description:
|
|
31808
|
+
title: z134.string().max(120).optional(),
|
|
31809
|
+
description: z134.string().max(500).optional(),
|
|
31649
31810
|
cta: MetaCtaType.optional(),
|
|
31650
|
-
creativeId:
|
|
31811
|
+
creativeId: z134.string().min(1).optional()
|
|
31651
31812
|
});
|
|
31652
|
-
var GroupedCampaignConfigBase =
|
|
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:
|
|
31657
|
-
adSets:
|
|
31658
|
-
tempId:
|
|
31659
|
-
name:
|
|
31660
|
-
dailyBudget:
|
|
31661
|
-
creativeIds:
|
|
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:
|
|
31670
|
-
|
|
31671
|
-
type:
|
|
31672
|
-
landingUrl:
|
|
31830
|
+
destination: z134.discriminatedUnion("type", [
|
|
31831
|
+
z134.object({
|
|
31832
|
+
type: z134.literal("landing"),
|
|
31833
|
+
landingUrl: z134.string().url()
|
|
31673
31834
|
}),
|
|
31674
|
-
|
|
31675
|
-
type:
|
|
31676
|
-
phoneNumber:
|
|
31835
|
+
z134.object({
|
|
31836
|
+
type: z134.literal("whatsapp"),
|
|
31837
|
+
phoneNumber: z134.string().min(8).max(32)
|
|
31677
31838
|
})
|
|
31678
31839
|
]),
|
|
31679
|
-
saveAsDefault:
|
|
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:
|
|
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:
|
|
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 =
|
|
31720
|
-
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:
|
|
31883
|
+
portfolioId: z134.string().trim().min(1),
|
|
31723
31884
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
31724
|
-
pageId:
|
|
31885
|
+
pageId: z134.string().trim().min(1),
|
|
31725
31886
|
adAccountId: McpAdAccountId,
|
|
31726
|
-
pixelId:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 =
|
|
31774
|
-
uploadUrl:
|
|
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:
|
|
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:
|
|
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:
|
|
31809
|
-
dailyBudget:
|
|
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:
|
|
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:
|
|
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 =
|
|
31833
|
-
taskId:
|
|
31834
|
-
advertiserId:
|
|
31835
|
-
pixelId:
|
|
31836
|
-
landingUrl:
|
|
31837
|
-
angleIndexes:
|
|
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:
|
|
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
|
|
32361
|
+
import { z as z135 } from "zod";
|
|
32201
32362
|
var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
|
|
32202
|
-
var UploadSessionInputBase =
|
|
32203
|
-
mediaKind:
|
|
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:
|
|
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:
|
|
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:
|
|
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 =
|
|
32220
|
-
download_url:
|
|
32221
|
-
file_id:
|
|
32222
|
-
mime_type:
|
|
32223
|
-
file_name:
|
|
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:
|
|
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 =
|
|
32390
|
+
var UploadSessionToolInput = z135.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
32230
32391
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
32231
32392
|
ctx.addIssue({
|
|
32232
|
-
code:
|
|
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:
|
|
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:
|
|
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 =
|
|
32259
|
-
sessionId:
|
|
32260
|
-
uploadPageUrl:
|
|
32261
|
-
mediaKind:
|
|
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:
|
|
32427
|
+
assetRole: z135.enum([
|
|
32267
32428
|
"media",
|
|
32268
32429
|
"thumbnail"
|
|
32269
32430
|
]),
|
|
32270
|
-
maxFiles:
|
|
32271
|
-
expiresAt:
|
|
32431
|
+
maxFiles: z135.number().int().positive(),
|
|
32432
|
+
expiresAt: z135.string().datetime()
|
|
32272
32433
|
});
|
|
32273
|
-
var UploadStatusInput =
|
|
32274
|
-
sessionId:
|
|
32434
|
+
var UploadStatusInput = z135.object({
|
|
32435
|
+
sessionId: z135.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
32275
32436
|
});
|
|
32276
|
-
var UniversalUploadStatusResponse =
|
|
32277
|
-
|
|
32278
|
-
status:
|
|
32279
|
-
assets:
|
|
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
|
-
|
|
32282
|
-
status:
|
|
32283
|
-
assets:
|
|
32284
|
-
assetId:
|
|
32285
|
-
mediaKind:
|
|
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:
|
|
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:
|
|
32458
|
+
uploadPurpose: z135.enum([
|
|
32298
32459
|
"product_reference",
|
|
32299
32460
|
"creative",
|
|
32300
32461
|
"generic"
|
|
32301
32462
|
]),
|
|
32302
|
-
checkToolName:
|
|
32303
|
-
resolveEndpoint:
|
|
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
|
|
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 =
|
|
32398
|
-
campaignId:
|
|
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 =
|
|
32401
|
-
campaignId:
|
|
32402
|
-
advertiserId:
|
|
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
|
|
32668
|
+
import { z as z138 } from "zod";
|
|
32508
32669
|
|
|
32509
32670
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
32510
|
-
import { z as
|
|
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 =
|
|
32575
|
-
reference:
|
|
32576
|
-
min:
|
|
32577
|
-
max:
|
|
32578
|
-
updatedAt:
|
|
32579
|
-
confidence:
|
|
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:
|
|
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:
|
|
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 =
|
|
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 =
|
|
32779
|
-
country:
|
|
32780
|
-
supplierCost:
|
|
32781
|
-
shippingCost:
|
|
32782
|
-
returnRate:
|
|
32783
|
-
cancellationRate:
|
|
32784
|
-
adsManagerCpa:
|
|
32785
|
-
desiredMargin:
|
|
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:
|
|
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
|
|
33047
|
+
import { z as z139 } from "zod";
|
|
32887
33048
|
var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
|
|
32888
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
32889
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
32890
|
-
var ProductCostingToolInput =
|
|
32891
|
-
country:
|
|
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:
|
|
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
|
|
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 =
|
|
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:
|
|
33432
|
-
waitSeconds:
|
|
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 =
|
|
33435
|
-
runId:
|
|
33595
|
+
var GetInput = z140.object({
|
|
33596
|
+
runId: z140.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
33436
33597
|
});
|
|
33437
|
-
var ListInput =
|
|
33438
|
-
limit:
|
|
33598
|
+
var ListInput = z140.object({
|
|
33599
|
+
limit: z140.number().int().min(1).max(20).default(10)
|
|
33439
33600
|
});
|
|
33440
|
-
function textResult(
|
|
33601
|
+
function textResult(text4) {
|
|
33441
33602
|
return {
|
|
33442
33603
|
content: [
|
|
33443
33604
|
{
|
|
33444
33605
|
type: "text",
|
|
33445
|
-
text:
|
|
33606
|
+
text: text4
|
|
33446
33607
|
}
|
|
33447
33608
|
]
|
|
33448
33609
|
};
|
|
33449
33610
|
}
|
|
33450
33611
|
__name(textResult, "textResult");
|
|
33451
|
-
function researchResult(run,
|
|
33612
|
+
function researchResult(run, text4) {
|
|
33452
33613
|
return {
|
|
33453
33614
|
content: [
|
|
33454
33615
|
{
|
|
33455
33616
|
type: "text",
|
|
33456
|
-
text:
|
|
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
|
|
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 =
|
|
33582
|
-
var DropshippingProjectStatus =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
33636
|
-
type:
|
|
33796
|
+
var ResearchCandidateOrigin = z141.object({
|
|
33797
|
+
type: z141.literal("research_candidate"),
|
|
33637
33798
|
runId: ProjectId,
|
|
33638
|
-
candidateSourceId:
|
|
33799
|
+
candidateSourceId: z141.string().min(1).max(160)
|
|
33639
33800
|
});
|
|
33640
|
-
var TaskOrigin =
|
|
33641
|
-
type:
|
|
33801
|
+
var TaskOrigin = z141.object({
|
|
33802
|
+
type: z141.literal("task"),
|
|
33642
33803
|
taskId: ProjectId
|
|
33643
33804
|
});
|
|
33644
|
-
var ManualOrigin =
|
|
33645
|
-
type:
|
|
33805
|
+
var ManualOrigin = z141.object({
|
|
33806
|
+
type: z141.literal("manual"),
|
|
33646
33807
|
clientRequestId: ProjectId,
|
|
33647
|
-
country:
|
|
33808
|
+
country: z141.string().min(2).max(3).optional()
|
|
33648
33809
|
});
|
|
33649
|
-
var StartProjectInput =
|
|
33650
|
-
origin:
|
|
33810
|
+
var StartProjectInput = z141.object({
|
|
33811
|
+
origin: z141.discriminatedUnion("type", [
|
|
33651
33812
|
ResearchCandidateOrigin,
|
|
33652
33813
|
TaskOrigin,
|
|
33653
33814
|
ManualOrigin
|
|
33654
33815
|
]),
|
|
33655
|
-
productName:
|
|
33816
|
+
productName: z141.string().trim().min(1).max(240).optional(),
|
|
33656
33817
|
productUrl: HttpUrl3.optional(),
|
|
33657
|
-
country:
|
|
33658
|
-
languageCode:
|
|
33818
|
+
country: z141.string().min(2).max(3).optional(),
|
|
33819
|
+
languageCode: z141.string().min(2).max(16).optional()
|
|
33659
33820
|
}).strict();
|
|
33660
|
-
var CostProjectInput =
|
|
33821
|
+
var CostProjectInput = z141.object({
|
|
33661
33822
|
projectId: ProjectId,
|
|
33662
|
-
version:
|
|
33663
|
-
country:
|
|
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:
|
|
33667
|
-
shippingCost:
|
|
33668
|
-
returnRate:
|
|
33669
|
-
cancellationRate:
|
|
33670
|
-
adsManagerCpa:
|
|
33671
|
-
desiredMargin:
|
|
33672
|
-
});
|
|
33673
|
-
var GuideInput =
|
|
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 =
|
|
33692
|
-
kind:
|
|
33693
|
-
href:
|
|
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 =
|
|
33696
|
-
country:
|
|
33697
|
-
supplierCost:
|
|
33698
|
-
shippingCost:
|
|
33699
|
-
returnRate:
|
|
33700
|
-
cancellationRate:
|
|
33701
|
-
adsManagerCpa:
|
|
33702
|
-
desiredMargin:
|
|
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:
|
|
33866
|
+
code: z141.ZodIssueCode.custom,
|
|
33706
33867
|
path: [
|
|
33707
33868
|
"cancellationRate"
|
|
33708
33869
|
]
|
|
33709
33870
|
});
|
|
33710
33871
|
});
|
|
33711
|
-
var FiniteCostingNumber =
|
|
33712
|
-
var CostingResultSchema =
|
|
33713
|
-
country:
|
|
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:
|
|
33727
|
-
profitabilityStatus:
|
|
33728
|
-
});
|
|
33729
|
-
var RewardProgressSchema =
|
|
33730
|
-
campaignKey:
|
|
33731
|
-
totalCredits:
|
|
33732
|
-
earnedCredits:
|
|
33733
|
-
milestones:
|
|
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:
|
|
33736
|
-
available:
|
|
33737
|
-
earned:
|
|
33896
|
+
credits: z141.number().int().positive(),
|
|
33897
|
+
available: z141.boolean().optional(),
|
|
33898
|
+
earned: z141.boolean(),
|
|
33738
33899
|
grantId: ProjectId.nullable(),
|
|
33739
|
-
grantedAt:
|
|
33900
|
+
grantedAt: z141.string().datetime().nullable()
|
|
33740
33901
|
})).length(DropshippingRewardMilestone.options.length)
|
|
33741
33902
|
});
|
|
33742
|
-
var ProjectResponseSchema =
|
|
33903
|
+
var ProjectResponseSchema = z141.object({
|
|
33743
33904
|
id: ProjectId,
|
|
33744
33905
|
taskId: ProjectId.nullable(),
|
|
33745
33906
|
status: DropshippingProjectStatus,
|
|
33746
|
-
originKey:
|
|
33907
|
+
originKey: z141.string().min(1),
|
|
33747
33908
|
researchRunId: ProjectId.nullable(),
|
|
33748
|
-
candidateSourceId:
|
|
33749
|
-
productName:
|
|
33909
|
+
candidateSourceId: z141.string().nullable(),
|
|
33910
|
+
productName: z141.string().nullable(),
|
|
33750
33911
|
productUrl: HttpUrl3.nullable(),
|
|
33751
33912
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
33752
|
-
targetCountry:
|
|
33753
|
-
languageCode:
|
|
33754
|
-
hasReferenceImage:
|
|
33755
|
-
hasWinnerReferenceImage:
|
|
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:
|
|
33759
|
-
version:
|
|
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:
|
|
33764
|
-
updatedAt:
|
|
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
|
|
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 =
|
|
33889
|
-
var DateOnly =
|
|
33890
|
-
var DailyControlInput =
|
|
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:
|
|
33893
|
-
projectId:
|
|
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 =
|
|
33896
|
-
projectId:
|
|
33897
|
-
provider:
|
|
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 =
|
|
33905
|
-
projectId:
|
|
34065
|
+
var ReportReturnsInput = z142.object({
|
|
34066
|
+
projectId: z142.string().uuid(),
|
|
33906
34067
|
date: DateOnly,
|
|
33907
|
-
returnedOrders:
|
|
33908
|
-
note:
|
|
33909
|
-
}).strict();
|
|
33910
|
-
var DailyControlStatusMirror = DailyControlStatusEnum.or(
|
|
33911
|
-
var DailyControlLightMirror = DailyControlLightEnum.or(
|
|
33912
|
-
var DailyControlSourceMirror = DailyControlSourceEnum.or(
|
|
33913
|
-
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(
|
|
33914
|
-
var DailyControlDayMirror =
|
|
33915
|
-
date:
|
|
33916
|
-
returnedOrders:
|
|
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:
|
|
34080
|
+
hasEstimates: z142.boolean(),
|
|
33920
34081
|
light: DailyControlLightMirror
|
|
33921
34082
|
}).passthrough();
|
|
33922
|
-
var DailyControlProductMirror =
|
|
33923
|
-
projectId:
|
|
33924
|
-
productName:
|
|
34083
|
+
var DailyControlProductMirror = z142.object({
|
|
34084
|
+
projectId: z142.string().uuid(),
|
|
34085
|
+
productName: z142.string().nullable(),
|
|
33925
34086
|
status: DailyControlStatusMirror,
|
|
33926
|
-
statusMessage:
|
|
33927
|
-
days:
|
|
34087
|
+
statusMessage: z142.string().nullable(),
|
|
34088
|
+
days: z142.array(DailyControlDayMirror),
|
|
33928
34089
|
verdict: DailyControlVerdictMirror.nullable(),
|
|
33929
|
-
rationale:
|
|
34090
|
+
rationale: z142.string().nullable()
|
|
33930
34091
|
}).passthrough();
|
|
33931
|
-
var DailyControlResponseMirror =
|
|
33932
|
-
since:
|
|
33933
|
-
until:
|
|
33934
|
-
products:
|
|
33935
|
-
archivedProjectSpend:
|
|
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
|
|
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 =
|
|
34184
|
+
var DateOnly2 = z143.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
34024
34185
|
var IMPORT_BATCH_MAX2 = 50;
|
|
34025
|
-
var ProductControlListInput =
|
|
34026
|
-
days:
|
|
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:
|
|
34189
|
+
shopDomain: z143.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
34029
34190
|
}).strict();
|
|
34030
|
-
var ImportableProductsInput =
|
|
34031
|
-
q:
|
|
34032
|
-
after:
|
|
34033
|
-
shopDomain:
|
|
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 =
|
|
34036
|
-
shopifyProductIds:
|
|
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:
|
|
34040
|
-
}).strict();
|
|
34041
|
-
var SetProductCostingInput =
|
|
34042
|
-
shopDomain:
|
|
34043
|
-
shopifyProductId:
|
|
34044
|
-
targetCountry:
|
|
34045
|
-
supplierCost:
|
|
34046
|
-
shippingCost:
|
|
34047
|
-
returnRate:
|
|
34048
|
-
cancellationRate:
|
|
34049
|
-
}).strict();
|
|
34050
|
-
var Count =
|
|
34051
|
-
var ReportProductCountsInput =
|
|
34052
|
-
productControlId:
|
|
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 =
|
|
34223
|
+
var ImportOrdersFileInput = z143.object({
|
|
34063
34224
|
/** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
|
|
34064
|
-
path:
|
|
34065
|
-
operationId:
|
|
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:
|
|
34228
|
+
dryRun: z143.boolean().optional()
|
|
34068
34229
|
}).strict();
|
|
34069
|
-
var CreateOperationInput =
|
|
34070
|
-
countryCode:
|
|
34071
|
-
label:
|
|
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 =
|
|
34074
|
-
sourceId:
|
|
34075
|
-
targetId:
|
|
34234
|
+
var MergeProductsInput = z143.object({
|
|
34235
|
+
sourceId: z143.string().uuid(),
|
|
34236
|
+
targetId: z143.string().uuid()
|
|
34076
34237
|
}).strict();
|
|
34077
|
-
var SetMonthlyExpenseInput =
|
|
34078
|
-
month:
|
|
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:
|
|
34081
|
-
operationId:
|
|
34241
|
+
amount: z143.number().finite().min(0),
|
|
34242
|
+
operationId: z143.string().uuid().optional()
|
|
34082
34243
|
}).strict();
|
|
34083
|
-
var SetAdSpendInput =
|
|
34084
|
-
month:
|
|
34085
|
-
operationId:
|
|
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:
|
|
34248
|
+
amount: z143.number().finite().min(0).nullable()
|
|
34088
34249
|
}).strict();
|
|
34089
|
-
var GetFinancesInput =
|
|
34090
|
-
month:
|
|
34091
|
-
operationId:
|
|
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
|
|
34444
|
+
import { z as z144 } from "zod";
|
|
34284
34445
|
var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
|
|
34285
|
-
var ProductTaskOutputEnum =
|
|
34446
|
+
var ProductTaskOutputEnum = z144.enum([
|
|
34286
34447
|
"landing",
|
|
34287
34448
|
"video",
|
|
34288
34449
|
"image"
|
|
34289
34450
|
]);
|
|
34290
|
-
var EstimateMarketStudyInput =
|
|
34291
|
-
kind:
|
|
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:
|
|
34296
|
-
durationSeconds:
|
|
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:
|
|
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:
|
|
34463
|
+
generateAiMusic: z144.boolean().optional(),
|
|
34303
34464
|
generateAiEdit: AiEditRequestSchema.optional(),
|
|
34304
|
-
replicateWinnerWhenFound:
|
|
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 ?? [
|