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