@productmaker/mcp 11.3.2 → 11.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/http.js +1068 -844
- package/dist/stdio.js +1057 -833
- package/package.json +1 -1
package/dist/stdio.js
CHANGED
|
@@ -9698,13 +9698,23 @@ var FacebookCreateCampaignFromTasksBodySchema = z51.object({
|
|
|
9698
9698
|
portfolioId: z51.string().min(1),
|
|
9699
9699
|
pageId: z51.string().min(1),
|
|
9700
9700
|
pixelId: z51.string().optional(),
|
|
9701
|
+
/**
|
|
9702
|
+
* Omitted: a campaign with task creatives lands on the published service
|
|
9703
|
+
* landing of its service tasks (resolved server side, META_NO_LANDING_URL
|
|
9704
|
+
* when there is none); a media-only campaign must name it.
|
|
9705
|
+
*/
|
|
9701
9706
|
landingUrl: HttpUrl2.optional(),
|
|
9702
|
-
|
|
9707
|
+
/**
|
|
9708
|
+
* Omitted: the brand country of its service tasks; a product-only campaign
|
|
9709
|
+
* keeps "US". Never a hardcoded country for a service (META_NO_TARGET_COUNTRY).
|
|
9710
|
+
*/
|
|
9711
|
+
targetCountry: CountryIso2Schema.optional(),
|
|
9703
9712
|
campaignName: z51.string().min(1).max(100),
|
|
9704
9713
|
campaignConfig: MetaCampaignConfig.optional()
|
|
9705
9714
|
}).superRefine((value, ctx) => {
|
|
9706
9715
|
const isWhatsapp = value.campaignConfig?.destination?.type === "whatsapp";
|
|
9707
|
-
|
|
9716
|
+
const hasTaskCreative = value.creatives.some((creative) => creative.source.type === "task");
|
|
9717
|
+
if (!isWhatsapp && !value.landingUrl && !hasTaskCreative) {
|
|
9708
9718
|
ctx.addIssue({
|
|
9709
9719
|
code: z51.ZodIssueCode.custom,
|
|
9710
9720
|
path: [
|
|
@@ -18781,7 +18791,7 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
18781
18791
|
], [
|
|
18782
18792
|
"tiktok_advertiser"
|
|
18783
18793
|
]),
|
|
18784
|
-
defineCapability("publish_creatives_to_meta", "
|
|
18794
|
+
defineCapability("publish_creatives_to_meta", "dff962c84ed7d0393444dcbe86cb6f4016b5928c1d0005f78ce9a365f1923ac3", "external_mutation", "publishing", [
|
|
18785
18795
|
"external_mutation",
|
|
18786
18796
|
"state_change"
|
|
18787
18797
|
], [
|
|
@@ -21368,8 +21378,33 @@ var ServicePageGenerateRequestSchema = z100.object({
|
|
|
21368
21378
|
instruction: ServicePageEditInstructionSchema.optional(),
|
|
21369
21379
|
attachmentRefs: ServicePageAttachmentRefsSchema.optional()
|
|
21370
21380
|
}).strict();
|
|
21381
|
+
var SERVICE_PAGE_CREATION_MAX_ATTEMPTS = 3;
|
|
21382
|
+
var ServicePageCreationMarkerSchema = z100.object({
|
|
21383
|
+
rootOperationId: z100.string().uuid().optional(),
|
|
21384
|
+
attempt: z100.number().int().min(1).max(SERVICE_PAGE_CREATION_MAX_ATTEMPTS)
|
|
21385
|
+
}).strict();
|
|
21386
|
+
var ServicePageCreationEstimateRequestSchema = z100.object({
|
|
21387
|
+
textCharacters: z100.number().int().min(0).max(1e6),
|
|
21388
|
+
documentBytes: z100.number().int().min(0).max(1e8),
|
|
21389
|
+
imageCount: z100.number().int().min(0).max(50),
|
|
21390
|
+
instagram: z100.boolean()
|
|
21391
|
+
}).strict();
|
|
21392
|
+
var ServicePageCreationEstimateResponseSchema = z100.object({
|
|
21393
|
+
estimatedMinCostCredits: z100.number().int().nonnegative(),
|
|
21394
|
+
estimatedMaxCostCredits: z100.number().int().nonnegative()
|
|
21395
|
+
}).strict();
|
|
21396
|
+
var ServicePageCreationStatusSchema = z100.object({
|
|
21397
|
+
status: z100.enum([
|
|
21398
|
+
"idle",
|
|
21399
|
+
"running",
|
|
21400
|
+
"failed"
|
|
21401
|
+
]),
|
|
21402
|
+
errorCode: z100.string().max(64).optional()
|
|
21403
|
+
}).strict();
|
|
21371
21404
|
var ServicePageFactExtractionRequestSchema = ServicePageGenerateRequestSchema.omit({
|
|
21372
21405
|
instruction: true
|
|
21406
|
+
}).extend({
|
|
21407
|
+
continueWith: z100.literal("generation").optional()
|
|
21373
21408
|
});
|
|
21374
21409
|
var ServicePageOperationStatusSchema = z100.enum([
|
|
21375
21410
|
"queued",
|
|
@@ -21852,19 +21887,37 @@ var ServiceImageContextSchema = z106.object({
|
|
|
21852
21887
|
referenceKeys: z106.array(z106.string()).max(10)
|
|
21853
21888
|
}).strict();
|
|
21854
21889
|
|
|
21855
|
-
// ../../packages/types/src/
|
|
21890
|
+
// ../../packages/types/src/task-ad-defaults.ts
|
|
21856
21891
|
import { z as z107 } from "zod";
|
|
21892
|
+
var AD_HEADLINE_MAX_CHARS = 255;
|
|
21893
|
+
var TaskAdDefaultsSchema = z107.object({
|
|
21894
|
+
subjectKind: z107.enum([
|
|
21895
|
+
"product",
|
|
21896
|
+
"service"
|
|
21897
|
+
]),
|
|
21898
|
+
landingUrl: z107.string().url().nullable(),
|
|
21899
|
+
landingSource: z107.enum([
|
|
21900
|
+
"shopify",
|
|
21901
|
+
"service_page"
|
|
21902
|
+
]).nullable(),
|
|
21903
|
+
headline: z107.string().min(1).max(AD_HEADLINE_MAX_CHARS).nullable(),
|
|
21904
|
+
/** ISO 3166-1 alpha-2 when known. */
|
|
21905
|
+
country: z107.string().min(2).nullable()
|
|
21906
|
+
});
|
|
21907
|
+
|
|
21908
|
+
// ../../packages/types/src/service-website-capture.ts
|
|
21909
|
+
import { z as z108 } from "zod";
|
|
21857
21910
|
var WEBSITE_CAPTURE_MAX_RESEARCH_BYTES = 1024 * 1024;
|
|
21858
21911
|
var WEBSITE_CAPTURE_MAX_FILES = 100;
|
|
21859
21912
|
var WEBSITE_CAPTURE_MAX_FILE_BYTES = 8 * 1024 * 1024;
|
|
21860
21913
|
var WEBSITE_CAPTURE_MAX_BUNDLE_BYTES = 30 * 1024 * 1024;
|
|
21861
|
-
var WebsiteCaptureCauseSchema =
|
|
21914
|
+
var WebsiteCaptureCauseSchema = z108.enum([
|
|
21862
21915
|
"site_blocked",
|
|
21863
21916
|
"site_unreachable",
|
|
21864
21917
|
"not_enough_content",
|
|
21865
21918
|
"internal"
|
|
21866
21919
|
]);
|
|
21867
|
-
var WebsiteCaptureStatusSchema =
|
|
21920
|
+
var WebsiteCaptureStatusSchema = z108.enum([
|
|
21868
21921
|
"queued",
|
|
21869
21922
|
"capturing",
|
|
21870
21923
|
"ready",
|
|
@@ -21886,134 +21939,287 @@ function normalizeWebsiteCaptureUrl(value) {
|
|
|
21886
21939
|
}
|
|
21887
21940
|
}
|
|
21888
21941
|
__name(normalizeWebsiteCaptureUrl, "normalizeWebsiteCaptureUrl");
|
|
21889
|
-
var WebsiteCaptureRequestSchema =
|
|
21890
|
-
url:
|
|
21942
|
+
var WebsiteCaptureRequestSchema = z108.object({
|
|
21943
|
+
url: z108.string().trim().max(2048).url().refine((value) => normalizeWebsiteCaptureUrl(value) !== null, "Use an HTTP(S) URL without credentials").transform((value) => normalizeWebsiteCaptureUrl(value)),
|
|
21891
21944
|
language: MotionGraphicsLanguageSchema
|
|
21892
21945
|
}).strict();
|
|
21893
|
-
var WebsiteCaptureResponseSchema =
|
|
21894
|
-
captureId:
|
|
21946
|
+
var WebsiteCaptureResponseSchema = z108.object({
|
|
21947
|
+
captureId: z108.string().uuid(),
|
|
21895
21948
|
status: WebsiteCaptureStatusSchema,
|
|
21896
|
-
expiresAt:
|
|
21897
|
-
previewUrl:
|
|
21949
|
+
expiresAt: z108.string().datetime(),
|
|
21950
|
+
previewUrl: z108.string().url().optional(),
|
|
21898
21951
|
cause: WebsiteCaptureCauseSchema.optional()
|
|
21899
21952
|
});
|
|
21900
21953
|
var WebsiteCaptureJobSchema = WebsiteCaptureRequestSchema.extend({
|
|
21901
|
-
captureId:
|
|
21902
|
-
attempt:
|
|
21903
|
-
leaseUntil:
|
|
21954
|
+
captureId: z108.string().uuid(),
|
|
21955
|
+
attempt: z108.number().int().positive(),
|
|
21956
|
+
leaseUntil: z108.string().datetime()
|
|
21904
21957
|
});
|
|
21905
|
-
var WebsiteCaptureClaimResponseSchema =
|
|
21958
|
+
var WebsiteCaptureClaimResponseSchema = z108.object({
|
|
21906
21959
|
capture: WebsiteCaptureJobSchema.nullable()
|
|
21907
21960
|
});
|
|
21908
21961
|
var attempt = {
|
|
21909
|
-
attempt:
|
|
21962
|
+
attempt: z108.number().int().positive()
|
|
21910
21963
|
};
|
|
21911
|
-
var digest =
|
|
21912
|
-
var WebsiteCaptureUploadRequestSchema =
|
|
21964
|
+
var digest = z108.string().regex(/^[a-f0-9]{64}$/);
|
|
21965
|
+
var WebsiteCaptureUploadRequestSchema = z108.object({
|
|
21913
21966
|
...attempt,
|
|
21914
|
-
contentLength:
|
|
21967
|
+
contentLength: z108.number().int().positive().max(WEBSITE_CAPTURE_MAX_BUNDLE_BYTES),
|
|
21915
21968
|
sha256: digest
|
|
21916
21969
|
}).strict();
|
|
21917
|
-
var WebsiteCaptureDoneRequestSchema =
|
|
21970
|
+
var WebsiteCaptureDoneRequestSchema = z108.object({
|
|
21918
21971
|
...attempt,
|
|
21919
21972
|
sha256: digest
|
|
21920
21973
|
}).strict();
|
|
21921
|
-
var WebsiteCaptureFailedRequestSchema =
|
|
21974
|
+
var WebsiteCaptureFailedRequestSchema = z108.object({
|
|
21922
21975
|
...attempt,
|
|
21923
21976
|
cause: WebsiteCaptureCauseSchema
|
|
21924
21977
|
}).strict();
|
|
21925
|
-
var WebsiteCaptureBundleSchema =
|
|
21926
|
-
version:
|
|
21927
|
-
files:
|
|
21928
|
-
path:
|
|
21929
|
-
base64:
|
|
21978
|
+
var WebsiteCaptureBundleSchema = z108.object({
|
|
21979
|
+
version: z108.literal(1),
|
|
21980
|
+
files: z108.array(z108.object({
|
|
21981
|
+
path: z108.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))$/),
|
|
21982
|
+
base64: z108.string().max(Math.ceil(WEBSITE_CAPTURE_MAX_FILE_BYTES / 3) * 4).regex(/^[A-Za-z0-9+/]*={0,2}$/).refine((value) => value.length % 4 === 0),
|
|
21930
21983
|
sha256: digest
|
|
21931
21984
|
}).strict()).min(1).max(WEBSITE_CAPTURE_MAX_FILES)
|
|
21932
21985
|
}).strict().refine((bundle) => new Set(bundle.files.map((file) => file.path)).size === bundle.files.length, "Duplicate capture file");
|
|
21933
|
-
var WebsiteCaptureScreenshotSchema =
|
|
21934
|
-
file:
|
|
21935
|
-
scrollTop:
|
|
21936
|
-
});
|
|
21937
|
-
var WebsiteCaptureAccessSchema =
|
|
21938
|
-
publicContentText:
|
|
21939
|
-
passwordGate:
|
|
21940
|
-
challengeGate:
|
|
21941
|
-
blockingOverlay:
|
|
21986
|
+
var WebsiteCaptureScreenshotSchema = z108.object({
|
|
21987
|
+
file: z108.string(),
|
|
21988
|
+
scrollTop: z108.number()
|
|
21989
|
+
});
|
|
21990
|
+
var WebsiteCaptureAccessSchema = z108.object({
|
|
21991
|
+
publicContentText: z108.string().max(8e3),
|
|
21992
|
+
passwordGate: z108.boolean(),
|
|
21993
|
+
challengeGate: z108.boolean(),
|
|
21994
|
+
blockingOverlay: z108.boolean(),
|
|
21942
21995
|
// Decoded, substantial images visible outside access walls and page chrome.
|
|
21943
21996
|
// Optional for compatibility with already captured text-led research.
|
|
21944
|
-
publicImageUrls:
|
|
21945
|
-
});
|
|
21946
|
-
var WebsiteCaptureResearchSchema =
|
|
21947
|
-
requestedUrl:
|
|
21948
|
-
capturedAt:
|
|
21949
|
-
locale:
|
|
21950
|
-
bodyTextTruncated:
|
|
21951
|
-
finalUrl:
|
|
21952
|
-
lang:
|
|
21953
|
-
title:
|
|
21954
|
-
description:
|
|
21955
|
-
openGraph:
|
|
21956
|
-
title:
|
|
21957
|
-
description:
|
|
21958
|
-
image:
|
|
21959
|
-
siteName:
|
|
21997
|
+
publicImageUrls: z108.array(z108.string().url().max(8192)).max(20).optional()
|
|
21998
|
+
});
|
|
21999
|
+
var WebsiteCaptureResearchSchema = z108.object({
|
|
22000
|
+
requestedUrl: z108.string().url(),
|
|
22001
|
+
capturedAt: z108.string().datetime(),
|
|
22002
|
+
locale: z108.string(),
|
|
22003
|
+
bodyTextTruncated: z108.boolean(),
|
|
22004
|
+
finalUrl: z108.string().url(),
|
|
22005
|
+
lang: z108.string().nullable(),
|
|
22006
|
+
title: z108.string(),
|
|
22007
|
+
description: z108.string(),
|
|
22008
|
+
openGraph: z108.object({
|
|
22009
|
+
title: z108.string(),
|
|
22010
|
+
description: z108.string(),
|
|
22011
|
+
image: z108.string(),
|
|
22012
|
+
siteName: z108.string()
|
|
21960
22013
|
}),
|
|
21961
|
-
themeColor:
|
|
21962
|
-
headings:
|
|
21963
|
-
h1:
|
|
21964
|
-
h2:
|
|
21965
|
-
h3:
|
|
22014
|
+
themeColor: z108.string(),
|
|
22015
|
+
headings: z108.object({
|
|
22016
|
+
h1: z108.array(z108.string()),
|
|
22017
|
+
h2: z108.array(z108.string()),
|
|
22018
|
+
h3: z108.array(z108.string())
|
|
21966
22019
|
}),
|
|
21967
|
-
callsToAction:
|
|
21968
|
-
listItems:
|
|
21969
|
-
bodyText:
|
|
22020
|
+
callsToAction: z108.array(z108.string()),
|
|
22021
|
+
listItems: z108.array(z108.string()),
|
|
22022
|
+
bodyText: z108.string(),
|
|
21970
22023
|
access: WebsiteCaptureAccessSchema.optional(),
|
|
21971
|
-
consent:
|
|
21972
|
-
pressed:
|
|
21973
|
-
removed:
|
|
22024
|
+
consent: z108.object({
|
|
22025
|
+
pressed: z108.string().nullable(),
|
|
22026
|
+
removed: z108.number().nonnegative()
|
|
21974
22027
|
}).optional(),
|
|
21975
|
-
overlaysDismissed:
|
|
21976
|
-
style:
|
|
21977
|
-
bodyBackground:
|
|
21978
|
-
bodyColor:
|
|
21979
|
-
bodyFont:
|
|
21980
|
-
headingFont:
|
|
21981
|
-
headingColor:
|
|
21982
|
-
actionColors:
|
|
21983
|
-
color:
|
|
21984
|
-
uses:
|
|
22028
|
+
overlaysDismissed: z108.number().int().nonnegative().optional(),
|
|
22029
|
+
style: z108.object({
|
|
22030
|
+
bodyBackground: z108.string(),
|
|
22031
|
+
bodyColor: z108.string(),
|
|
22032
|
+
bodyFont: z108.string(),
|
|
22033
|
+
headingFont: z108.string().nullable(),
|
|
22034
|
+
headingColor: z108.string().nullable(),
|
|
22035
|
+
actionColors: z108.array(z108.object({
|
|
22036
|
+
color: z108.string(),
|
|
22037
|
+
uses: z108.number()
|
|
21985
22038
|
}))
|
|
21986
22039
|
}),
|
|
21987
|
-
images:
|
|
21988
|
-
file:
|
|
21989
|
-
src:
|
|
21990
|
-
alt:
|
|
21991
|
-
width:
|
|
21992
|
-
height:
|
|
21993
|
-
isOpenGraph:
|
|
22040
|
+
images: z108.array(z108.object({
|
|
22041
|
+
file: z108.string(),
|
|
22042
|
+
src: z108.string(),
|
|
22043
|
+
alt: z108.string(),
|
|
22044
|
+
width: z108.number().nullable(),
|
|
22045
|
+
height: z108.number().nullable(),
|
|
22046
|
+
isOpenGraph: z108.boolean()
|
|
21994
22047
|
})),
|
|
21995
|
-
logo:
|
|
21996
|
-
file:
|
|
21997
|
-
svg:
|
|
21998
|
-
width:
|
|
21999
|
-
height:
|
|
22048
|
+
logo: z108.object({
|
|
22049
|
+
file: z108.literal("logo.png"),
|
|
22050
|
+
svg: z108.literal("logo.svg").optional(),
|
|
22051
|
+
width: z108.number(),
|
|
22052
|
+
height: z108.number()
|
|
22000
22053
|
}).nullable(),
|
|
22001
|
-
fonts:
|
|
22002
|
-
family:
|
|
22003
|
-
weight:
|
|
22004
|
-
style:
|
|
22005
|
-
unicodeRange:
|
|
22006
|
-
file:
|
|
22054
|
+
fonts: z108.array(z108.object({
|
|
22055
|
+
family: z108.string(),
|
|
22056
|
+
weight: z108.string(),
|
|
22057
|
+
style: z108.string(),
|
|
22058
|
+
unicodeRange: z108.string().nullable(),
|
|
22059
|
+
file: z108.string().optional()
|
|
22007
22060
|
}).transform((font) => ({
|
|
22008
22061
|
...font,
|
|
22009
22062
|
file: font.file
|
|
22010
22063
|
}))),
|
|
22011
|
-
screenshots:
|
|
22012
|
-
desktop:
|
|
22013
|
-
mobile:
|
|
22064
|
+
screenshots: z108.object({
|
|
22065
|
+
desktop: z108.array(WebsiteCaptureScreenshotSchema),
|
|
22066
|
+
mobile: z108.array(WebsiteCaptureScreenshotSchema)
|
|
22014
22067
|
})
|
|
22015
22068
|
});
|
|
22016
22069
|
|
|
22070
|
+
// ../../packages/types/src/demo-mode.ts
|
|
22071
|
+
import { z as z109 } from "zod";
|
|
22072
|
+
var DEMO_MODE_FLOWS = [
|
|
22073
|
+
"brand",
|
|
22074
|
+
"servicePage",
|
|
22075
|
+
"motion",
|
|
22076
|
+
"image"
|
|
22077
|
+
];
|
|
22078
|
+
var DemoModeFlowSchema = z109.enum(DEMO_MODE_FLOWS);
|
|
22079
|
+
var DEMO_MODE_STEPS = [
|
|
22080
|
+
"running",
|
|
22081
|
+
"research",
|
|
22082
|
+
"design",
|
|
22083
|
+
"render_0",
|
|
22084
|
+
"render_33",
|
|
22085
|
+
"render_66",
|
|
22086
|
+
"render_100",
|
|
22087
|
+
"review",
|
|
22088
|
+
"final",
|
|
22089
|
+
"watchdog"
|
|
22090
|
+
];
|
|
22091
|
+
var DemoModeStepSchema = z109.enum(DEMO_MODE_STEPS);
|
|
22092
|
+
var DEMO_MODE_WAIT_SECONDS = {
|
|
22093
|
+
min: 30,
|
|
22094
|
+
max: 450,
|
|
22095
|
+
default: 150
|
|
22096
|
+
};
|
|
22097
|
+
var centsSchema = z109.number().int().min(0).max(1e5);
|
|
22098
|
+
var emailSchema = z109.string().trim().toLowerCase().email();
|
|
22099
|
+
var DemoModeTemplatesSchema = z109.object({
|
|
22100
|
+
brandId: z109.string().uuid(),
|
|
22101
|
+
servicePageId: z109.string().uuid(),
|
|
22102
|
+
motionTaskId: z109.string().uuid(),
|
|
22103
|
+
imageTaskId: z109.string().uuid()
|
|
22104
|
+
});
|
|
22105
|
+
var DemoModeEditableSchema = z109.object({
|
|
22106
|
+
enabled: z109.boolean(),
|
|
22107
|
+
emails: z109.array(emailSchema).max(50).transform((list) => [
|
|
22108
|
+
...new Set(list)
|
|
22109
|
+
]),
|
|
22110
|
+
waitSeconds: z109.number().int().min(DEMO_MODE_WAIT_SECONDS.min).max(DEMO_MODE_WAIT_SECONDS.max),
|
|
22111
|
+
chargeCents: z109.object({
|
|
22112
|
+
brand: centsSchema,
|
|
22113
|
+
servicePage: centsSchema,
|
|
22114
|
+
motion: centsSchema,
|
|
22115
|
+
image: centsSchema
|
|
22116
|
+
}),
|
|
22117
|
+
templates: DemoModeTemplatesSchema
|
|
22118
|
+
});
|
|
22119
|
+
var nullableString = z109.string().nullable();
|
|
22120
|
+
var DemoModeSnapshotSchema = z109.object({
|
|
22121
|
+
brand: z109.object({
|
|
22122
|
+
/** Columnas de identidad de `Brand` listas para un `update` (sin id/userId/slug/estado/fechas). */
|
|
22123
|
+
identity: z109.record(z109.unknown()),
|
|
22124
|
+
productSamples: z109.array(z109.object({
|
|
22125
|
+
name: z109.string(),
|
|
22126
|
+
priceCents: z109.number().int().nullable(),
|
|
22127
|
+
currency: nullableString,
|
|
22128
|
+
imageKey: z109.string(),
|
|
22129
|
+
productUrl: nullableString,
|
|
22130
|
+
position: z109.number().int()
|
|
22131
|
+
})),
|
|
22132
|
+
personas: z109.array(z109.object({
|
|
22133
|
+
name: z109.string(),
|
|
22134
|
+
demographics: nullableString,
|
|
22135
|
+
painPoints: nullableString,
|
|
22136
|
+
motivations: nullableString,
|
|
22137
|
+
objections: nullableString,
|
|
22138
|
+
gender: nullableString,
|
|
22139
|
+
isDefault: z109.boolean()
|
|
22140
|
+
}))
|
|
22141
|
+
}),
|
|
22142
|
+
servicePage: z109.object({
|
|
22143
|
+
facts: z109.unknown(),
|
|
22144
|
+
review: z109.unknown(),
|
|
22145
|
+
artifact: z109.unknown()
|
|
22146
|
+
}),
|
|
22147
|
+
motion: z109.object({
|
|
22148
|
+
outputs: MotionGraphicsOutputsSchema,
|
|
22149
|
+
/**
|
|
22150
|
+
* La captura REAL de la web de la plantilla (nunca una fabricada por la
|
|
22151
|
+
* demo). Null cuando la plantilla no tiene ninguna: la captura demo nunca
|
|
22152
|
+
* va live, así que el servicio usa `DEMO_MODE_PLACEHOLDER_CAPTURE`.
|
|
22153
|
+
*/
|
|
22154
|
+
capture: z109.object({
|
|
22155
|
+
bundleKey: z109.string(),
|
|
22156
|
+
sha256: z109.string(),
|
|
22157
|
+
uploadBytes: z109.number().int().nullable(),
|
|
22158
|
+
previewKey: nullableString
|
|
22159
|
+
}).nullable()
|
|
22160
|
+
}),
|
|
22161
|
+
image: z109.object({
|
|
22162
|
+
provider: z109.string(),
|
|
22163
|
+
model: z109.string(),
|
|
22164
|
+
prompt: z109.string(),
|
|
22165
|
+
imageUrl: z109.string(),
|
|
22166
|
+
width: z109.number().int(),
|
|
22167
|
+
height: z109.number().int(),
|
|
22168
|
+
adCopy: nullableString,
|
|
22169
|
+
rawResponse: z109.unknown()
|
|
22170
|
+
})
|
|
22171
|
+
});
|
|
22172
|
+
var DemoModeConfigSchema = DemoModeEditableSchema.extend({
|
|
22173
|
+
snapshot: DemoModeSnapshotSchema.nullable(),
|
|
22174
|
+
snapshotAt: z109.string().datetime().nullable()
|
|
22175
|
+
});
|
|
22176
|
+
var DemoModeAdminViewSchema = DemoModeEditableSchema.extend({
|
|
22177
|
+
// Sin configurar, la API devuelve ids vacíos ("" no es uuid): la vista los
|
|
22178
|
+
// admite; el PUT sí exige uuid (`DemoModeEditableSchema`).
|
|
22179
|
+
templates: z109.object({
|
|
22180
|
+
brandId: z109.string(),
|
|
22181
|
+
servicePageId: z109.string(),
|
|
22182
|
+
motionTaskId: z109.string(),
|
|
22183
|
+
imageTaskId: z109.string()
|
|
22184
|
+
}),
|
|
22185
|
+
snapshotAt: z109.string().nullable()
|
|
22186
|
+
});
|
|
22187
|
+
var DEMO_MODE_TEMPLATE_PROBLEMS = [
|
|
22188
|
+
"not_found",
|
|
22189
|
+
"brand_not_ready",
|
|
22190
|
+
"no_artifact",
|
|
22191
|
+
"artifact_invalid",
|
|
22192
|
+
"task_not_done",
|
|
22193
|
+
"no_video",
|
|
22194
|
+
"no_creative"
|
|
22195
|
+
];
|
|
22196
|
+
var DemoModeTemplateVerdictSchema = z109.discriminatedUnion("ok", [
|
|
22197
|
+
z109.object({
|
|
22198
|
+
ok: z109.literal(true)
|
|
22199
|
+
}),
|
|
22200
|
+
z109.object({
|
|
22201
|
+
ok: z109.literal(false),
|
|
22202
|
+
problem: z109.enum(DEMO_MODE_TEMPLATE_PROBLEMS)
|
|
22203
|
+
})
|
|
22204
|
+
]);
|
|
22205
|
+
var DemoModeValidationSchema = z109.object({
|
|
22206
|
+
brandId: DemoModeTemplateVerdictSchema,
|
|
22207
|
+
servicePageId: DemoModeTemplateVerdictSchema,
|
|
22208
|
+
motionTaskId: DemoModeTemplateVerdictSchema,
|
|
22209
|
+
imageTaskId: DemoModeTemplateVerdictSchema
|
|
22210
|
+
});
|
|
22211
|
+
var DemoModeJobSchema = z109.object({
|
|
22212
|
+
flow: DemoModeFlowSchema,
|
|
22213
|
+
step: DemoModeStepSchema,
|
|
22214
|
+
/** brandId | servicePageOperationId | taskId según el flujo. */
|
|
22215
|
+
targetId: z109.string().uuid(),
|
|
22216
|
+
userId: z109.string().min(1),
|
|
22217
|
+
/** Solo marca: la generación de extracción que el guion completa. */
|
|
22218
|
+
generation: z109.number().int().positive().optional(),
|
|
22219
|
+
/** Solo `final`/`watchdog`: la parte del snapshot de ESTE flujo, congelada al empezar. */
|
|
22220
|
+
result: z109.unknown().optional()
|
|
22221
|
+
});
|
|
22222
|
+
|
|
22017
22223
|
// src/response-body.ts
|
|
22018
22224
|
var ResponseBodyTooLargeError = class extends Error {
|
|
22019
22225
|
static {
|
|
@@ -22256,7 +22462,7 @@ var ApiClient = class {
|
|
|
22256
22462
|
};
|
|
22257
22463
|
|
|
22258
22464
|
// src/index.ts
|
|
22259
|
-
var MCP_VERSION = "11.
|
|
22465
|
+
var MCP_VERSION = "11.4.0";
|
|
22260
22466
|
|
|
22261
22467
|
// src/meta-upload-app.ts
|
|
22262
22468
|
import { readFileSync } from "fs";
|
|
@@ -22328,7 +22534,7 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
|
|
|
22328
22534
|
__name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
|
|
22329
22535
|
|
|
22330
22536
|
// src/tools/tasks.ts
|
|
22331
|
-
import { z as
|
|
22537
|
+
import { z as z114 } from "zod";
|
|
22332
22538
|
|
|
22333
22539
|
// src/resolve-image.ts
|
|
22334
22540
|
import { lookup as dnsLookup } from "dns/promises";
|
|
@@ -22889,9 +23095,9 @@ async function resolveMediaRef(ref, opts) {
|
|
|
22889
23095
|
__name(resolveMediaRef, "resolveMediaRef");
|
|
22890
23096
|
|
|
22891
23097
|
// src/tools/shared.ts
|
|
22892
|
-
import { z as
|
|
22893
|
-
var Lang =
|
|
22894
|
-
var Country =
|
|
23098
|
+
import { z as z110 } from "zod";
|
|
23099
|
+
var Lang = z110.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);
|
|
23100
|
+
var Country = z110.string().min(2).max(3);
|
|
22895
23101
|
var LandingStrategyEnum = LandingStrategySchema;
|
|
22896
23102
|
var LandingImageFormatEnum = LandingImageFormatSchema;
|
|
22897
23103
|
var VideoPresetEnum = VideoPreset.extract([
|
|
@@ -22995,7 +23201,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
|
|
|
22995
23201
|
return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
|
|
22996
23202
|
}
|
|
22997
23203
|
__name(animationStyleApplies, "animationStyleApplies");
|
|
22998
|
-
var VideoTierEnum =
|
|
23204
|
+
var VideoTierEnum = z110.enum([
|
|
22999
23205
|
"basic"
|
|
23000
23206
|
]);
|
|
23001
23207
|
function resolveVideoTier(_tier) {
|
|
@@ -23053,10 +23259,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
|
|
|
23053
23259
|
var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
|
|
23054
23260
|
var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
|
|
23055
23261
|
var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
|
|
23056
|
-
var ImageRefSchema =
|
|
23057
|
-
url:
|
|
23058
|
-
path:
|
|
23059
|
-
assetId:
|
|
23262
|
+
var ImageRefSchema = z110.object({
|
|
23263
|
+
url: z110.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.'),
|
|
23264
|
+
path: z110.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`.'),
|
|
23265
|
+
assetId: z110.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.")
|
|
23060
23266
|
}).refine((v) => [
|
|
23061
23267
|
v.url,
|
|
23062
23268
|
v.path,
|
|
@@ -23064,11 +23270,11 @@ var ImageRefSchema = z108.object({
|
|
|
23064
23270
|
].filter(Boolean).length === 1, {
|
|
23065
23271
|
message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
|
|
23066
23272
|
});
|
|
23067
|
-
var ImagesInput =
|
|
23273
|
+
var ImagesInput = z110.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
|
|
23068
23274
|
const assetCount = images.filter((image) => Boolean(image.assetId)).length;
|
|
23069
23275
|
if (assetCount > 0 && assetCount !== images.length) {
|
|
23070
23276
|
ctx.addIssue({
|
|
23071
|
-
code:
|
|
23277
|
+
code: z110.ZodIssueCode.custom,
|
|
23072
23278
|
message: "all image entries must use assetId, or all must use URL/path sources"
|
|
23073
23279
|
});
|
|
23074
23280
|
}
|
|
@@ -23118,16 +23324,24 @@ async function submitCreative(api, opts) {
|
|
|
23118
23324
|
...img,
|
|
23119
23325
|
filename: `image-${i}.png`
|
|
23120
23326
|
}));
|
|
23121
|
-
const r = await api.postMultipart(
|
|
23122
|
-
|
|
23123
|
-
|
|
23124
|
-
|
|
23125
|
-
|
|
23126
|
-
|
|
23127
|
-
|
|
23128
|
-
|
|
23129
|
-
|
|
23130
|
-
|
|
23327
|
+
const r = await api.postMultipart(
|
|
23328
|
+
opts.path,
|
|
23329
|
+
{
|
|
23330
|
+
images: parts
|
|
23331
|
+
},
|
|
23332
|
+
// assetIds stays an array so postMultipart appends one `assetIds` field per
|
|
23333
|
+
// id: `flatten` would comma-join them into a single non-UUID value and the
|
|
23334
|
+
// API rejects every multi-photo upload with "assetId must be a valid UUID".
|
|
23335
|
+
{
|
|
23336
|
+
...flatten(rest),
|
|
23337
|
+
...assetIds ? {
|
|
23338
|
+
assetIds
|
|
23339
|
+
} : {}
|
|
23340
|
+
},
|
|
23341
|
+
opts.idempotencyKey ? {
|
|
23342
|
+
idempotencyKey: opts.idempotencyKey
|
|
23343
|
+
} : void 0
|
|
23344
|
+
);
|
|
23131
23345
|
const taskId = r.taskId ?? r.jobId;
|
|
23132
23346
|
return asText({
|
|
23133
23347
|
taskId,
|
|
@@ -23141,14 +23355,14 @@ async function submitCreative(api, opts) {
|
|
|
23141
23355
|
});
|
|
23142
23356
|
}
|
|
23143
23357
|
__name(submitCreative, "submitCreative");
|
|
23144
|
-
var ResearchTargetCountryEnum =
|
|
23358
|
+
var ResearchTargetCountryEnum = z110.enum([
|
|
23145
23359
|
"CO",
|
|
23146
23360
|
"MX",
|
|
23147
23361
|
"PE",
|
|
23148
23362
|
"EC",
|
|
23149
23363
|
"CL"
|
|
23150
23364
|
]);
|
|
23151
|
-
var ResearchCategoryEnum =
|
|
23365
|
+
var ResearchCategoryEnum = z110.enum([
|
|
23152
23366
|
"auto",
|
|
23153
23367
|
"automotive",
|
|
23154
23368
|
"kitchen",
|
|
@@ -23278,6 +23492,7 @@ var McpErrorCode = {
|
|
|
23278
23492
|
CAMPAIGN_NOT_FOUND: "CAMPAIGN_NOT_FOUND",
|
|
23279
23493
|
CAMPAIGN_TASK_NOT_FOUND: "CAMPAIGN_TASK_NOT_FOUND",
|
|
23280
23494
|
CAMPAIGN_MISSING_LANDING_URL: "CAMPAIGN_MISSING_LANDING_URL",
|
|
23495
|
+
CAMPAIGN_MISSING_TARGET_COUNTRY: "CAMPAIGN_MISSING_TARGET_COUNTRY",
|
|
23281
23496
|
CAMPAIGN_NO_CREATIVES: "CAMPAIGN_NO_CREATIVES",
|
|
23282
23497
|
CAMPAIGN_MISSING_THUMBNAILS: "CAMPAIGN_MISSING_THUMBNAILS",
|
|
23283
23498
|
CAMPAIGN_RECONCILIATION_REQUIRED: "CAMPAIGN_RECONCILIATION_REQUIRED",
|
|
@@ -23317,6 +23532,7 @@ var McpErrorCode = {
|
|
|
23317
23532
|
META_NO_ASSETS_READY: "META_NO_ASSETS_READY",
|
|
23318
23533
|
META_NO_THUMBNAIL_SOURCE: "META_NO_THUMBNAIL_SOURCE",
|
|
23319
23534
|
META_NO_LANDING_URL: "META_NO_LANDING_URL",
|
|
23535
|
+
META_NO_TARGET_COUNTRY: "META_NO_TARGET_COUNTRY",
|
|
23320
23536
|
META_TASK_NOT_FOUND: "META_TASK_NOT_FOUND",
|
|
23321
23537
|
META_INVALID_DATA: "META_INVALID_DATA",
|
|
23322
23538
|
META_INVALID_AD_ACCOUNT: "META_INVALID_AD_ACCOUNT",
|
|
@@ -23404,7 +23620,8 @@ var CODE_MESSAGES = {
|
|
|
23404
23620
|
META_NO_ADS_CREATED: "No ads could be created. Most likely: the Meta Ads account has no payment method, no Facebook Page is linked, or the Facebook app lost permissions. Verify all three at https://business.facebook.com.",
|
|
23405
23621
|
META_NO_ASSETS_READY: "The task has no videos or ad creative ready to publish yet. Wait for generation to finish or regenerate the assets.",
|
|
23406
23622
|
META_NO_THUMBNAIL_SOURCE: "No image is available to use as the video thumbnail. Upload a product image or generate the ad creative before publishing.",
|
|
23407
|
-
META_NO_LANDING_URL: "Missing landing URL. Pass it in `landingUrl
|
|
23623
|
+
META_NO_LANDING_URL: "Missing landing URL. Pass it in `landingUrl`, or publish first: a product to Shopify with `publish_to_shopify`, a service to its service landing.",
|
|
23624
|
+
META_NO_TARGET_COUNTRY: "This service ad has no target country (its brand sets none). Ask the user which country and pass it in `campaignConfig.targetCountries`; never assume one.",
|
|
23408
23625
|
META_TASK_NOT_FOUND: "Task not found or does not belong to this user. Verify the `taskId`.",
|
|
23409
23626
|
META_INVALID_DATA: "Meta rejected the request due to invalid data. Verify that `adAccountId` and `pixelId` are correct.",
|
|
23410
23627
|
META_INVALID_AD_ACCOUNT: "Ad account not found or no access. Confirm the `adAccountId` with `list_meta_ad_accounts`.",
|
|
@@ -23443,7 +23660,8 @@ var CODE_MESSAGES = {
|
|
|
23443
23660
|
// Campaign (shared)
|
|
23444
23661
|
CAMPAIGN_NOT_FOUND: "Campaign not found or does not belong to this user. Verify the `campaignId`.",
|
|
23445
23662
|
CAMPAIGN_TASK_NOT_FOUND: "Campaign task not found. Verify the `taskId`.",
|
|
23446
|
-
CAMPAIGN_MISSING_LANDING_URL: "Missing landing URL for the campaign. Publish to Shopify
|
|
23663
|
+
CAMPAIGN_MISSING_LANDING_URL: "Missing landing URL for the campaign. Publish first (a product to Shopify, a service to its service landing) or pass `landingUrl` explicitly.",
|
|
23664
|
+
CAMPAIGN_MISSING_TARGET_COUNTRY: "This service ad has no target country (its brand sets none). Ask the user which country and pass it in `campaignConfig.targetCountries`; never assume one.",
|
|
23447
23665
|
CAMPAIGN_NO_CREATIVES: "The task has no creatives (video/image) ready for the campaign. Wait for generation to finish.",
|
|
23448
23666
|
CAMPAIGN_MISSING_THUMBNAILS: "Missing thumbnails for the videos. Verify that image/video generation has finished.",
|
|
23449
23667
|
CAMPAIGN_RECONCILIATION_REQUIRED: "A campaign may already have been created. Do not retry creation; reopen the project and reconcile it or contact support.",
|
|
@@ -23535,8 +23753,10 @@ var INVALID_PARAM_CODES = /* @__PURE__ */ new Set([
|
|
|
23535
23753
|
McpErrorCode.TIKTOK_ADVERTISER_REQUIRED,
|
|
23536
23754
|
McpErrorCode.TIKTOK_PIXEL_NOT_FOUND,
|
|
23537
23755
|
McpErrorCode.CAMPAIGN_MISSING_LANDING_URL,
|
|
23756
|
+
McpErrorCode.CAMPAIGN_MISSING_TARGET_COUNTRY,
|
|
23538
23757
|
McpErrorCode.CAMPAIGN_RECONCILIATION_REQUIRED,
|
|
23539
23758
|
McpErrorCode.META_NO_LANDING_URL,
|
|
23759
|
+
McpErrorCode.META_NO_TARGET_COUNTRY,
|
|
23540
23760
|
McpErrorCode.META_PORTFOLIO_MISMATCH,
|
|
23541
23761
|
McpErrorCode.META_PAGE_SELECTION_REQUIRED,
|
|
23542
23762
|
McpErrorCode.META_INVALID_PAGE,
|
|
@@ -23647,6 +23867,7 @@ var PASSTHROUGH_CODES = /* @__PURE__ */ new Set([
|
|
|
23647
23867
|
McpErrorCode.META_NO_ASSETS_READY,
|
|
23648
23868
|
McpErrorCode.META_NO_THUMBNAIL_SOURCE,
|
|
23649
23869
|
McpErrorCode.META_NO_LANDING_URL,
|
|
23870
|
+
McpErrorCode.META_NO_TARGET_COUNTRY,
|
|
23650
23871
|
McpErrorCode.META_TASK_NOT_FOUND,
|
|
23651
23872
|
McpErrorCode.META_INVALID_DATA,
|
|
23652
23873
|
McpErrorCode.META_INVALID_AD_ACCOUNT,
|
|
@@ -23694,6 +23915,7 @@ var PASSTHROUGH_CODES = /* @__PURE__ */ new Set([
|
|
|
23694
23915
|
McpErrorCode.CAMPAIGN_NOT_FOUND,
|
|
23695
23916
|
McpErrorCode.CAMPAIGN_TASK_NOT_FOUND,
|
|
23696
23917
|
McpErrorCode.CAMPAIGN_MISSING_LANDING_URL,
|
|
23918
|
+
McpErrorCode.CAMPAIGN_MISSING_TARGET_COUNTRY,
|
|
23697
23919
|
McpErrorCode.CAMPAIGN_NO_CREATIVES,
|
|
23698
23920
|
McpErrorCode.CAMPAIGN_MISSING_THUMBNAILS,
|
|
23699
23921
|
McpErrorCode.CAMPAIGN_RECONCILIATION_REQUIRED,
|
|
@@ -24513,29 +24735,29 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
|
|
|
24513
24735
|
__name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
|
|
24514
24736
|
|
|
24515
24737
|
// src/tools/media-presentation.ts
|
|
24516
|
-
import { z as
|
|
24517
|
-
var HttpsPresentationUrlSchema =
|
|
24738
|
+
import { z as z111 } from "zod";
|
|
24739
|
+
var HttpsPresentationUrlSchema = z111.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
|
|
24518
24740
|
var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
|
|
24519
24741
|
const hostname = new URL(value).hostname.toLowerCase();
|
|
24520
24742
|
return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
|
|
24521
24743
|
}, "preview URL must be owned by ProductMaker");
|
|
24522
|
-
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) =>
|
|
24523
|
-
var PresentationImageSchema =
|
|
24524
|
-
kind:
|
|
24744
|
+
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z111.number().int().positive().max(maximum), "positiveIntAtMost");
|
|
24745
|
+
var PresentationImageSchema = z111.object({
|
|
24746
|
+
kind: z111.literal("image"),
|
|
24525
24747
|
url: HttpsPresentationUrlSchema,
|
|
24526
|
-
mimeType:
|
|
24748
|
+
mimeType: z111.enum([
|
|
24527
24749
|
"image/jpeg",
|
|
24528
24750
|
"image/png"
|
|
24529
24751
|
]),
|
|
24530
24752
|
byteSize: positiveIntAtMost(5 * 1024 * 1024),
|
|
24531
24753
|
width: positiveIntAtMost(16384),
|
|
24532
24754
|
height: positiveIntAtMost(16384),
|
|
24533
|
-
alt:
|
|
24755
|
+
alt: z111.string().trim().min(1).max(240)
|
|
24534
24756
|
}).strict();
|
|
24535
24757
|
var McpMediaPresentationSchema = PresentationImageSchema;
|
|
24536
|
-
var GalleryImageSchema =
|
|
24758
|
+
var GalleryImageSchema = z111.object({
|
|
24537
24759
|
url: ProductMakerPreviewUrlSchema,
|
|
24538
|
-
alt:
|
|
24760
|
+
alt: z111.string().trim().min(1).max(240)
|
|
24539
24761
|
});
|
|
24540
24762
|
var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
24541
24763
|
async function imageBlocks(image, transport) {
|
|
@@ -24592,12 +24814,12 @@ async function buildMcpMediaPresentationContent(rawPresentation, transport = "ht
|
|
|
24592
24814
|
];
|
|
24593
24815
|
}
|
|
24594
24816
|
__name(buildMcpMediaPresentationContent, "buildMcpMediaPresentationContent");
|
|
24595
|
-
var OwnedImagePreviewSchema =
|
|
24817
|
+
var OwnedImagePreviewSchema = z111.object({
|
|
24596
24818
|
url: HttpsPresentationUrlSchema.refine((value) => {
|
|
24597
24819
|
const url = new URL(value);
|
|
24598
24820
|
return !url.username && !url.password && !isPrivateHost(url.hostname);
|
|
24599
24821
|
}, "Preview URL must be public HTTPS without credentials"),
|
|
24600
|
-
alt:
|
|
24822
|
+
alt: z111.string().trim().min(1).max(240)
|
|
24601
24823
|
});
|
|
24602
24824
|
async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
|
|
24603
24825
|
const preview2 = OwnedImagePreviewSchema.safeParse(rawPreview);
|
|
@@ -24680,7 +24902,7 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
|
|
|
24680
24902
|
__name(buildMcpImageGalleryContent, "buildMcpImageGalleryContent");
|
|
24681
24903
|
|
|
24682
24904
|
// src/tools/animated-video.ts
|
|
24683
|
-
import { z as
|
|
24905
|
+
import { z as z112 } from "zod";
|
|
24684
24906
|
|
|
24685
24907
|
// src/tools/paid-confirmation.ts
|
|
24686
24908
|
function describeMarketStudyChoice(enabled) {
|
|
@@ -24930,27 +25152,27 @@ function hookVariantsLabel(count) {
|
|
|
24930
25152
|
return count === 1 ? "1 versi\xF3n del gancho" : `${count} versiones del gancho`;
|
|
24931
25153
|
}
|
|
24932
25154
|
__name(hookVariantsLabel, "hookVariantsLabel");
|
|
24933
|
-
var DurationInput =
|
|
24934
|
-
var CreateAnimatedVideoInput =
|
|
24935
|
-
action:
|
|
25155
|
+
var DurationInput = z112.union(MOTION_GRAPHICS_DURATIONS.map((d) => z112.literal(d)));
|
|
25156
|
+
var CreateAnimatedVideoInput = z112.object({
|
|
25157
|
+
action: z112.enum([
|
|
24936
25158
|
"prepare",
|
|
24937
25159
|
"status",
|
|
24938
25160
|
"cancel",
|
|
24939
25161
|
"generate"
|
|
24940
25162
|
]).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."),
|
|
24941
|
-
websiteCaptureId:
|
|
24942
|
-
generationRequestId:
|
|
24943
|
-
confirmed:
|
|
25163
|
+
websiteCaptureId: z112.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
|
|
25164
|
+
generationRequestId: z112.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."),
|
|
25165
|
+
confirmed: z112.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."),
|
|
24944
25166
|
// Plain text, not `.url()`: users type «cal.com», and the web accepts it.
|
|
24945
25167
|
// normalizeWebAddress (shared with the web) adds https:// and refuses
|
|
24946
25168
|
// anything that is not a public http(s) address.
|
|
24947
|
-
landingUrl:
|
|
25169
|
+
landingUrl: z112.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."),
|
|
24948
25170
|
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.'),
|
|
24949
25171
|
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.`),
|
|
24950
25172
|
language: MotionGraphicsLanguageSchema.optional().describe('Idioma de los textos del video: "es", "en" o "pt".'),
|
|
24951
|
-
notes:
|
|
25173
|
+
notes: z112.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)."),
|
|
24952
25174
|
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.`),
|
|
24953
|
-
music:
|
|
25175
|
+
music: z112.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.")
|
|
24954
25176
|
}).strict();
|
|
24955
25177
|
function captureNextAction(capture) {
|
|
24956
25178
|
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.";
|
|
@@ -24983,43 +25205,43 @@ var FORMAT_LABELS = {
|
|
|
24983
25205
|
square: "cuadrado 1:1",
|
|
24984
25206
|
horizontal: "horizontal 16:9"
|
|
24985
25207
|
};
|
|
24986
|
-
var AnimatedVideoResultSchema =
|
|
24987
|
-
status:
|
|
25208
|
+
var AnimatedVideoResultSchema = z112.object({
|
|
25209
|
+
status: z112.enum([
|
|
24988
25210
|
"pending",
|
|
24989
25211
|
"done",
|
|
24990
25212
|
"error"
|
|
24991
25213
|
]),
|
|
24992
|
-
serviceMode:
|
|
24993
|
-
finalMp4Url:
|
|
24994
|
-
error:
|
|
24995
|
-
motionGraphics:
|
|
25214
|
+
serviceMode: z112.literal("motion_graphics"),
|
|
25215
|
+
finalMp4Url: z112.string().optional(),
|
|
25216
|
+
error: z112.string().optional(),
|
|
25217
|
+
motionGraphics: z112.object({
|
|
24996
25218
|
stage: MotionGraphicsStageSchema,
|
|
24997
25219
|
format: MotionGraphicsFormatSchema,
|
|
24998
|
-
durationSec:
|
|
24999
|
-
width:
|
|
25000
|
-
height:
|
|
25220
|
+
durationSec: z112.number(),
|
|
25221
|
+
width: z112.number().optional(),
|
|
25222
|
+
height: z112.number().optional(),
|
|
25001
25223
|
language: MotionGraphicsLanguageSchema.optional(),
|
|
25002
|
-
queuedAt:
|
|
25003
|
-
jobsAhead:
|
|
25004
|
-
stageStartedAt:
|
|
25005
|
-
renderProgress:
|
|
25224
|
+
queuedAt: z112.string().optional(),
|
|
25225
|
+
jobsAhead: z112.number().int().nonnegative().optional(),
|
|
25226
|
+
stageStartedAt: z112.string().optional(),
|
|
25227
|
+
renderProgress: z112.number().optional(),
|
|
25006
25228
|
// AI clip fields (absent on a video paid before clips, or from an API
|
|
25007
25229
|
// that predates them). Lenient: an unreadable value is dropped
|
|
25008
25230
|
// instead of hiding the status.
|
|
25009
|
-
clipCount:
|
|
25010
|
-
clipsUsed:
|
|
25011
|
-
clipPriceCents:
|
|
25012
|
-
clipsRefunded:
|
|
25231
|
+
clipCount: z112.number().int().nonnegative().optional().catch(void 0),
|
|
25232
|
+
clipsUsed: z112.number().int().nonnegative().optional().catch(void 0),
|
|
25233
|
+
clipPriceCents: z112.number().finite().nonnegative().optional().catch(void 0),
|
|
25234
|
+
clipsRefunded: z112.number().int().nonnegative().optional().catch(void 0),
|
|
25013
25235
|
// Hook versions (absent from an API or a video before them): the
|
|
25014
25236
|
// count ordered and, once done, the signed URLs of the EXTRA versions
|
|
25015
25237
|
// (hook 2, hook 3); `finalMp4Url` is hook 1.
|
|
25016
|
-
hookVariants:
|
|
25017
|
-
variantUrls:
|
|
25238
|
+
hookVariants: z112.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
|
|
25239
|
+
variantUrls: z112.array(z112.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
|
|
25018
25240
|
// Extra hook versions given back, as the task recorded it once the
|
|
25019
25241
|
// refunds landed (absent until then, and from an API before it).
|
|
25020
|
-
variantsRefunded:
|
|
25021
|
-
activity:
|
|
25022
|
-
previewUrl:
|
|
25242
|
+
variantsRefunded: z112.number().int().nonnegative().optional().catch(void 0),
|
|
25243
|
+
activity: z112.array(MotionGraphicsActivitySchema).optional().catch(void 0),
|
|
25244
|
+
previewUrl: z112.string().optional()
|
|
25023
25245
|
}).passthrough()
|
|
25024
25246
|
}).passthrough();
|
|
25025
25247
|
function parseAnimatedVideoResult(value) {
|
|
@@ -25275,10 +25497,10 @@ function registerAnimatedVideoTools(server, api) {
|
|
|
25275
25497
|
__name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
|
|
25276
25498
|
|
|
25277
25499
|
// src/tools/winning-product-image.ts
|
|
25278
|
-
import { z as
|
|
25279
|
-
var WinnerReferenceInput =
|
|
25280
|
-
runId:
|
|
25281
|
-
candidateSourceId:
|
|
25500
|
+
import { z as z113 } from "zod";
|
|
25501
|
+
var WinnerReferenceInput = z113.object({
|
|
25502
|
+
runId: z113.string().uuid(),
|
|
25503
|
+
candidateSourceId: z113.string().trim().min(1).max(160)
|
|
25282
25504
|
}).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
|
|
25283
25505
|
async function resolveWinnerImages(api, winnerReference, images) {
|
|
25284
25506
|
if (!winnerReference) return images;
|
|
@@ -25315,62 +25537,62 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
|
|
|
25315
25537
|
var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
|
|
25316
25538
|
var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
|
|
25317
25539
|
var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
|
|
25318
|
-
var CreateProductTaskInput =
|
|
25540
|
+
var CreateProductTaskInput = z114.object({
|
|
25319
25541
|
images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
|
|
25320
25542
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
25321
|
-
projectId:
|
|
25322
|
-
productUrl:
|
|
25543
|
+
projectId: z114.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
|
|
25544
|
+
productUrl: z114.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."),
|
|
25323
25545
|
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.'),
|
|
25324
25546
|
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.'),
|
|
25325
|
-
price:
|
|
25326
|
-
compareAtPrice:
|
|
25327
|
-
offer:
|
|
25328
|
-
paymentMethods:
|
|
25329
|
-
productContext:
|
|
25330
|
-
productLabel:
|
|
25547
|
+
price: z114.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.'),
|
|
25548
|
+
compareAtPrice: z114.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".'),
|
|
25549
|
+
offer: z114.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.'),
|
|
25550
|
+
paymentMethods: z114.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.'),
|
|
25551
|
+
productContext: z114.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."),
|
|
25552
|
+
productLabel: z114.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.'),
|
|
25331
25553
|
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.'),
|
|
25332
25554
|
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.'),
|
|
25333
|
-
durationSeconds:
|
|
25334
|
-
|
|
25335
|
-
|
|
25555
|
+
durationSeconds: z114.union([
|
|
25556
|
+
z114.literal(15),
|
|
25557
|
+
z114.literal(30)
|
|
25336
25558
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
25337
|
-
pauseForAngleReview:
|
|
25338
|
-
aiDecidesAll:
|
|
25559
|
+
pauseForAngleReview: z114.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."),
|
|
25560
|
+
aiDecidesAll: z114.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."),
|
|
25339
25561
|
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.'),
|
|
25340
25562
|
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.'),
|
|
25341
25563
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
25342
25564
|
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).'),
|
|
25343
|
-
videoAngleCount:
|
|
25565
|
+
videoAngleCount: z114.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."),
|
|
25344
25566
|
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.'),
|
|
25345
|
-
outputs:
|
|
25567
|
+
outputs: z114.array(z114.enum([
|
|
25346
25568
|
"landing",
|
|
25347
25569
|
"video",
|
|
25348
25570
|
"image"
|
|
25349
25571
|
])).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}`),
|
|
25350
|
-
includeInitialLandingGif:
|
|
25351
|
-
competitorScanEnabled:
|
|
25572
|
+
includeInitialLandingGif: z114.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."),
|
|
25573
|
+
competitorScanEnabled: z114.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."),
|
|
25352
25574
|
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.'),
|
|
25353
|
-
replicateWinnerWhenFound:
|
|
25354
|
-
brandId:
|
|
25355
|
-
actorId:
|
|
25575
|
+
replicateWinnerWhenFound: z114.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."),
|
|
25576
|
+
brandId: z114.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."),
|
|
25577
|
+
actorId: z114.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."),
|
|
25356
25578
|
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.'),
|
|
25357
|
-
creativeDirection:
|
|
25358
|
-
headline:
|
|
25359
|
-
subheadline:
|
|
25579
|
+
creativeDirection: z114.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.'),
|
|
25580
|
+
headline: z114.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."),
|
|
25581
|
+
subheadline: z114.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."),
|
|
25360
25582
|
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".'),
|
|
25361
25583
|
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".')
|
|
25362
25584
|
}).strict();
|
|
25363
|
-
var CreateServiceVideoInput =
|
|
25364
|
-
landingUrl:
|
|
25365
|
-
additionalContext:
|
|
25585
|
+
var CreateServiceVideoInput = z114.object({
|
|
25586
|
+
landingUrl: z114.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
|
|
25587
|
+
additionalContext: z114.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
|
|
25366
25588
|
language: Lang.describe("Idioma del video: es, en o pt."),
|
|
25367
|
-
voiceId:
|
|
25368
|
-
brandId:
|
|
25369
|
-
reviewMode:
|
|
25589
|
+
voiceId: z114.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.'),
|
|
25590
|
+
brandId: z114.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
|
|
25591
|
+
reviewMode: z114.enum([
|
|
25370
25592
|
"automatic",
|
|
25371
25593
|
"guided"
|
|
25372
25594
|
]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
|
|
25373
|
-
videoPreset:
|
|
25595
|
+
videoPreset: z114.enum([
|
|
25374
25596
|
"auto",
|
|
25375
25597
|
"ugc_dynamic",
|
|
25376
25598
|
"ugc_how_to",
|
|
@@ -25380,128 +25602,128 @@ var CreateServiceVideoInput = z112.object({
|
|
|
25380
25602
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
25381
25603
|
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.')
|
|
25382
25604
|
}).strict();
|
|
25383
|
-
var GetTaskStatusInput =
|
|
25384
|
-
taskId:
|
|
25385
|
-
waitSeconds:
|
|
25605
|
+
var GetTaskStatusInput = z114.object({
|
|
25606
|
+
taskId: z114.string().min(1),
|
|
25607
|
+
waitSeconds: z114.number().int().min(0).max(120).optional()
|
|
25386
25608
|
});
|
|
25387
|
-
var ListTasksInput =
|
|
25388
|
-
limit:
|
|
25389
|
-
offset:
|
|
25390
|
-
search:
|
|
25609
|
+
var ListTasksInput = z114.object({
|
|
25610
|
+
limit: z114.number().int().min(1).max(50).optional(),
|
|
25611
|
+
offset: z114.number().int().min(0).optional(),
|
|
25612
|
+
search: z114.string().optional()
|
|
25391
25613
|
});
|
|
25392
25614
|
var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
|
|
25393
25615
|
var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
|
|
25394
|
-
var EditTaskDraftInput =
|
|
25395
|
-
taskId:
|
|
25396
|
-
angleIndex:
|
|
25397
|
-
angle:
|
|
25398
|
-
angle:
|
|
25399
|
-
buyerPersona:
|
|
25400
|
-
actor:
|
|
25401
|
-
actorId:
|
|
25402
|
-
gender:
|
|
25616
|
+
var EditTaskDraftInput = z114.object({
|
|
25617
|
+
taskId: z114.string().min(1),
|
|
25618
|
+
angleIndex: z114.number().int().min(0),
|
|
25619
|
+
angle: z114.object({
|
|
25620
|
+
angle: z114.string().min(1).max(480),
|
|
25621
|
+
buyerPersona: z114.string().min(1).max(360),
|
|
25622
|
+
actor: z114.string().min(1).max(360).optional(),
|
|
25623
|
+
actorId: z114.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."),
|
|
25624
|
+
gender: z114.enum([
|
|
25403
25625
|
"female",
|
|
25404
25626
|
"male"
|
|
25405
25627
|
]).optional(),
|
|
25406
|
-
scriptNotes:
|
|
25628
|
+
scriptNotes: z114.string().max(2e3).optional()
|
|
25407
25629
|
})
|
|
25408
25630
|
});
|
|
25409
|
-
var PendingActionPayload =
|
|
25410
|
-
|
|
25411
|
-
kind:
|
|
25631
|
+
var PendingActionPayload = z114.discriminatedUnion("kind", [
|
|
25632
|
+
z114.object({
|
|
25633
|
+
kind: z114.literal("product_reference_set_approval"),
|
|
25412
25634
|
scope: ProductReferenceScopeEnum.optional(),
|
|
25413
|
-
scopeKey:
|
|
25414
|
-
scopeSnapshotId:
|
|
25415
|
-
expectedScopeHash:
|
|
25635
|
+
scopeKey: z114.string().min(1).max(120).optional(),
|
|
25636
|
+
scopeSnapshotId: z114.string().uuid().optional(),
|
|
25637
|
+
expectedScopeHash: z114.string().min(1).max(128).optional(),
|
|
25416
25638
|
decision: ProductReferenceResolutionDecisionEnum,
|
|
25417
25639
|
reason: ProductReferenceRejectionReasonEnum.optional(),
|
|
25418
|
-
affectedRefKeys:
|
|
25419
|
-
affectedPhotoNumbers:
|
|
25420
|
-
recoveryAction:
|
|
25640
|
+
affectedRefKeys: z114.array(z114.string().min(1).max(200)).min(1).optional(),
|
|
25641
|
+
affectedPhotoNumbers: z114.array(z114.number().int().positive()).min(1).optional(),
|
|
25642
|
+
recoveryAction: z114.enum([
|
|
25421
25643
|
"remove",
|
|
25422
25644
|
"replace",
|
|
25423
25645
|
"upload",
|
|
25424
25646
|
"return_to_selection"
|
|
25425
25647
|
]).optional()
|
|
25426
25648
|
}),
|
|
25427
|
-
|
|
25428
|
-
kind:
|
|
25429
|
-
selectedPhotoNumbers:
|
|
25649
|
+
z114.object({
|
|
25650
|
+
kind: z114.literal("product_reference_confirmation"),
|
|
25651
|
+
selectedPhotoNumbers: z114.array(z114.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."),
|
|
25430
25652
|
userChoice: ProductReferenceUserChoiceEnum.optional(),
|
|
25431
|
-
confirmedProductNames:
|
|
25653
|
+
confirmedProductNames: z114.array(z114.string().min(1).max(120)).min(2).max(8).optional(),
|
|
25432
25654
|
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."),
|
|
25433
25655
|
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."),
|
|
25434
|
-
useMultiSceneShowcase:
|
|
25656
|
+
useMultiSceneShowcase: z114.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
|
|
25435
25657
|
}),
|
|
25436
|
-
|
|
25437
|
-
kind:
|
|
25658
|
+
z114.object({
|
|
25659
|
+
kind: z114.literal("angle_review_approval"),
|
|
25438
25660
|
// All edits are optional — empty action body just approves the
|
|
25439
25661
|
// backend-generated draft as-is. Field shapes mirror the angle-review
|
|
25440
25662
|
// request contracts in @packages/types/wizard.ts; the handler routes to
|
|
25441
25663
|
// the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
|
|
25442
|
-
customAngle:
|
|
25664
|
+
customAngle: z114.string().min(1).max(480).optional(),
|
|
25443
25665
|
// Keep the shared MCP action within the strictest downstream contract:
|
|
25444
25666
|
// autopilot/image resume endpoints cap these fields at 1500 characters.
|
|
25445
|
-
painPoints:
|
|
25446
|
-
benefits:
|
|
25667
|
+
painPoints: z114.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
25668
|
+
benefits: z114.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
25447
25669
|
// Same policy as the two fields above: the strictest downstream contract
|
|
25448
25670
|
// wins. The image endpoint caps each feature at 240 while landing/video
|
|
25449
25671
|
// accept 300, and this single action routes to whichever the task is — so
|
|
25450
25672
|
// accepting 300 here turns a 250-character feature on an image task into
|
|
25451
25673
|
// an opaque HTTP 400 after the model already believed it had been saved.
|
|
25452
|
-
features:
|
|
25453
|
-
buyerPersona:
|
|
25674
|
+
features: z114.array(z114.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
|
|
25675
|
+
buyerPersona: z114.string().min(1).max(360).optional(),
|
|
25454
25676
|
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.'),
|
|
25455
|
-
actor:
|
|
25456
|
-
actorId:
|
|
25457
|
-
creativeDirection:
|
|
25458
|
-
selectedAngleNumbers:
|
|
25459
|
-
angleEdits:
|
|
25460
|
-
angleNumber:
|
|
25461
|
-
narrativeSelection:
|
|
25677
|
+
actor: z114.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."),
|
|
25678
|
+
actorId: z114.string().max(120).nullable().optional(),
|
|
25679
|
+
creativeDirection: z114.string().max(2e3).optional(),
|
|
25680
|
+
selectedAngleNumbers: z114.array(z114.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."),
|
|
25681
|
+
angleEdits: z114.array(z114.object({
|
|
25682
|
+
angleNumber: z114.number().int().positive(),
|
|
25683
|
+
narrativeSelection: z114.enum([
|
|
25462
25684
|
"market",
|
|
25463
25685
|
"guided"
|
|
25464
25686
|
]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
|
|
25465
|
-
angle:
|
|
25466
|
-
buyerPersona:
|
|
25687
|
+
angle: z114.string().min(1).max(480).optional(),
|
|
25688
|
+
buyerPersona: z114.string().min(1).max(360).optional(),
|
|
25467
25689
|
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.'),
|
|
25468
|
-
actor:
|
|
25469
|
-
actorId:
|
|
25470
|
-
creativeDirection:
|
|
25690
|
+
actor: z114.string().min(1).max(360).optional(),
|
|
25691
|
+
actorId: z114.string().max(120).nullable().optional(),
|
|
25692
|
+
creativeDirection: z114.string().max(2e3).optional()
|
|
25471
25693
|
}).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)."),
|
|
25472
|
-
gapDurationSeconds:
|
|
25473
|
-
|
|
25474
|
-
|
|
25694
|
+
gapDurationSeconds: z114.union([
|
|
25695
|
+
z114.literal(15),
|
|
25696
|
+
z114.literal(30)
|
|
25475
25697
|
]).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.")
|
|
25476
25698
|
}),
|
|
25477
|
-
|
|
25478
|
-
kind:
|
|
25479
|
-
angleId:
|
|
25480
|
-
angleNumber:
|
|
25481
|
-
content:
|
|
25482
|
-
creativeDirection:
|
|
25483
|
-
actor:
|
|
25699
|
+
z114.object({
|
|
25700
|
+
kind: z114.literal("service_angle_approval"),
|
|
25701
|
+
angleId: z114.string().uuid().optional(),
|
|
25702
|
+
angleNumber: z114.number().int().positive().optional(),
|
|
25703
|
+
content: z114.string().min(1).max(480).optional(),
|
|
25704
|
+
creativeDirection: z114.string().min(1).max(1500).optional(),
|
|
25705
|
+
actor: z114.string().min(1).max(360).optional()
|
|
25484
25706
|
}),
|
|
25485
|
-
|
|
25486
|
-
kind:
|
|
25487
|
-
voiceovers:
|
|
25488
|
-
visualDirections:
|
|
25489
|
-
voiceoversByScene:
|
|
25490
|
-
visualDirectionsByScene:
|
|
25707
|
+
z114.object({
|
|
25708
|
+
kind: z114.literal("service_script_approval"),
|
|
25709
|
+
voiceovers: z114.record(z114.string(), z114.string().min(1).max(600)).optional(),
|
|
25710
|
+
visualDirections: z114.record(z114.string(), z114.string().min(1).max(1200)).optional(),
|
|
25711
|
+
voiceoversByScene: z114.record(z114.string(), z114.string().min(1).max(600)).optional(),
|
|
25712
|
+
visualDirectionsByScene: z114.record(z114.string(), z114.string().min(1).max(1200)).optional()
|
|
25491
25713
|
})
|
|
25492
25714
|
]);
|
|
25493
|
-
var ResolvePendingActionInput =
|
|
25494
|
-
taskId:
|
|
25715
|
+
var ResolvePendingActionInput = z114.object({
|
|
25716
|
+
taskId: z114.string().min(1),
|
|
25495
25717
|
action: PendingActionPayload
|
|
25496
25718
|
}).strict();
|
|
25497
25719
|
function resolveVariantConfirmVideoTier(action) {
|
|
25498
25720
|
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
25499
25721
|
}
|
|
25500
25722
|
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
25501
|
-
var StatusForResolveSchema =
|
|
25723
|
+
var StatusForResolveSchema = z114.object({
|
|
25502
25724
|
// Metadata used to select the backend resume contract. Older API responses
|
|
25503
25725
|
// may omit these fields, so the resolver keeps the generic fallback.
|
|
25504
|
-
kind:
|
|
25726
|
+
kind: z114.enum([
|
|
25505
25727
|
"autopilot",
|
|
25506
25728
|
"video",
|
|
25507
25729
|
"image",
|
|
@@ -25509,18 +25731,18 @@ var StatusForResolveSchema = z112.object({
|
|
|
25509
25731
|
"mix",
|
|
25510
25732
|
"service"
|
|
25511
25733
|
]).optional(),
|
|
25512
|
-
selectedOutputs:
|
|
25734
|
+
selectedOutputs: z114.array(z114.enum([
|
|
25513
25735
|
"landing",
|
|
25514
25736
|
"video",
|
|
25515
25737
|
"image"
|
|
25516
25738
|
])).optional(),
|
|
25517
|
-
videoAngleCount:
|
|
25518
|
-
ugcFormat:
|
|
25739
|
+
videoAngleCount: z114.number().int().min(1).max(3).optional(),
|
|
25740
|
+
ugcFormat: z114.enum([
|
|
25519
25741
|
"single_8s",
|
|
25520
25742
|
"single_15s",
|
|
25521
25743
|
"double_30s"
|
|
25522
25744
|
]).optional(),
|
|
25523
|
-
videoStyle:
|
|
25745
|
+
videoStyle: z114.enum([
|
|
25524
25746
|
"ugc",
|
|
25525
25747
|
"cartoon_3d",
|
|
25526
25748
|
"product_only",
|
|
@@ -25530,13 +25752,13 @@ var StatusForResolveSchema = z112.object({
|
|
|
25530
25752
|
videoQuality: VideoQualityEnum.optional(),
|
|
25531
25753
|
videoRouteId: VideoRouteIdEnum.optional(),
|
|
25532
25754
|
videoModel: TaskVideoModelEnum.optional(),
|
|
25533
|
-
videoTier:
|
|
25755
|
+
videoTier: z114.enum([
|
|
25534
25756
|
"legacy",
|
|
25535
25757
|
"standard",
|
|
25536
25758
|
"pro",
|
|
25537
25759
|
"single_call"
|
|
25538
25760
|
]).optional(),
|
|
25539
|
-
videoResolution:
|
|
25761
|
+
videoResolution: z114.enum([
|
|
25540
25762
|
"480p",
|
|
25541
25763
|
"720p"
|
|
25542
25764
|
]).optional(),
|
|
@@ -25544,60 +25766,60 @@ var StatusForResolveSchema = z112.object({
|
|
|
25544
25766
|
// A task created before a narrative was blocked/hidden must still parse,
|
|
25545
25767
|
// or resolve_pending_action could never approve it.
|
|
25546
25768
|
narrativeStyle: NarrativeStyle.optional(),
|
|
25547
|
-
pauseForVideoScriptReview:
|
|
25548
|
-
pendingUserAction:
|
|
25549
|
-
kind:
|
|
25550
|
-
candidateGrouping:
|
|
25551
|
-
selectedImageUrls:
|
|
25552
|
-
proposedProductNames:
|
|
25769
|
+
pauseForVideoScriptReview: z114.boolean().optional(),
|
|
25770
|
+
pendingUserAction: z114.object({
|
|
25771
|
+
kind: z114.string(),
|
|
25772
|
+
candidateGrouping: z114.string().optional(),
|
|
25773
|
+
selectedImageUrls: z114.array(z114.string()).optional(),
|
|
25774
|
+
proposedProductNames: z114.array(z114.string()).optional(),
|
|
25553
25775
|
// Adaptive reference questions are server-owned. Echo only the evidence
|
|
25554
25776
|
// identity and the choices shown by the current snapshot; never accept a
|
|
25555
25777
|
// client-supplied reference set as authorization.
|
|
25556
|
-
options:
|
|
25557
|
-
mode:
|
|
25778
|
+
options: z114.array(ProductReferenceUserChoiceEnum).max(4).optional(),
|
|
25779
|
+
mode: z114.enum([
|
|
25558
25780
|
"question",
|
|
25559
25781
|
"visual_recovery"
|
|
25560
25782
|
]).optional(),
|
|
25561
25783
|
/** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
|
|
25562
|
-
canKeepSelection:
|
|
25563
|
-
decisionKey:
|
|
25564
|
-
questionOrdinal:
|
|
25565
|
-
questionCeiling:
|
|
25566
|
-
|
|
25567
|
-
|
|
25784
|
+
canKeepSelection: z114.boolean().optional(),
|
|
25785
|
+
decisionKey: z114.string().optional(),
|
|
25786
|
+
questionOrdinal: z114.number().int().min(1).max(5).optional(),
|
|
25787
|
+
questionCeiling: z114.union([
|
|
25788
|
+
z114.literal(3),
|
|
25789
|
+
z114.literal(5)
|
|
25568
25790
|
]).optional(),
|
|
25569
|
-
referenceEvidenceVersion:
|
|
25570
|
-
expectedEvidenceHash:
|
|
25571
|
-
question:
|
|
25572
|
-
prompt:
|
|
25573
|
-
helpText:
|
|
25574
|
-
options:
|
|
25791
|
+
referenceEvidenceVersion: z114.number().int().positive().optional(),
|
|
25792
|
+
expectedEvidenceHash: z114.string().optional(),
|
|
25793
|
+
question: z114.object({
|
|
25794
|
+
prompt: z114.string().min(1).max(240),
|
|
25795
|
+
helpText: z114.string().min(1).max(300).optional(),
|
|
25796
|
+
options: z114.array(z114.object({
|
|
25575
25797
|
value: ProductReferenceUserChoiceEnum,
|
|
25576
|
-
label:
|
|
25577
|
-
description:
|
|
25798
|
+
label: z114.string().min(1).max(120),
|
|
25799
|
+
description: z114.string().min(1).max(240).optional()
|
|
25578
25800
|
})).min(2).max(4)
|
|
25579
25801
|
}).optional(),
|
|
25580
25802
|
scope: ProductReferenceScopeEnum.optional(),
|
|
25581
|
-
scopeKey:
|
|
25582
|
-
scopeSnapshotId:
|
|
25583
|
-
scopeHash:
|
|
25584
|
-
baseReferenceSetHash:
|
|
25585
|
-
phase:
|
|
25803
|
+
scopeKey: z114.string().optional(),
|
|
25804
|
+
scopeSnapshotId: z114.string().uuid().optional(),
|
|
25805
|
+
scopeHash: z114.string().optional(),
|
|
25806
|
+
baseReferenceSetHash: z114.string().optional(),
|
|
25807
|
+
phase: z114.enum([
|
|
25586
25808
|
"preparation",
|
|
25587
25809
|
"final"
|
|
25588
25810
|
]).optional(),
|
|
25589
|
-
selectedRefKeys:
|
|
25590
|
-
allowedDecisions:
|
|
25591
|
-
previews:
|
|
25592
|
-
refKey:
|
|
25811
|
+
selectedRefKeys: z114.array(z114.string().min(1).max(200)).optional(),
|
|
25812
|
+
allowedDecisions: z114.array(ProductReferenceResolutionDecisionEnum).optional(),
|
|
25813
|
+
previews: z114.array(z114.object({
|
|
25814
|
+
refKey: z114.string().min(1).max(200)
|
|
25593
25815
|
}).passthrough()).optional(),
|
|
25594
|
-
customAngleDraft:
|
|
25595
|
-
painPointsDraft:
|
|
25596
|
-
benefitsDraft:
|
|
25597
|
-
featuresDraft:
|
|
25598
|
-
angleOptions:
|
|
25599
|
-
index:
|
|
25600
|
-
angle:
|
|
25816
|
+
customAngleDraft: z114.string().optional(),
|
|
25817
|
+
painPointsDraft: z114.string().optional(),
|
|
25818
|
+
benefitsDraft: z114.string().optional(),
|
|
25819
|
+
featuresDraft: z114.array(z114.string()).optional(),
|
|
25820
|
+
angleOptions: z114.array(z114.object({
|
|
25821
|
+
index: z114.number().int().nonnegative(),
|
|
25822
|
+
angle: z114.string().min(1)
|
|
25601
25823
|
}).passthrough()).min(1).max(5).optional(),
|
|
25602
25824
|
// Recommendation consumed only when the caller explicitly sends
|
|
25603
25825
|
// gapDurationSeconds: 30 in the angle approval action.
|
|
@@ -25607,17 +25829,17 @@ var StatusForResolveSchema = z112.object({
|
|
|
25607
25829
|
// keys. `actorId` (the saved custom actor the picker stored) was silently
|
|
25608
25830
|
// dropped here, so the approval handler below could not echo it back on the
|
|
25609
25831
|
// PATCH — the selection looked accepted and reached no render.
|
|
25610
|
-
angles:
|
|
25611
|
-
id:
|
|
25612
|
-
content:
|
|
25613
|
-
creativeDirection:
|
|
25614
|
-
actor:
|
|
25615
|
-
actorId:
|
|
25832
|
+
angles: z114.array(z114.object({
|
|
25833
|
+
id: z114.string().uuid(),
|
|
25834
|
+
content: z114.string(),
|
|
25835
|
+
creativeDirection: z114.string(),
|
|
25836
|
+
actor: z114.string(),
|
|
25837
|
+
actorId: z114.string().nullable().optional()
|
|
25616
25838
|
}).passthrough()).optional(),
|
|
25617
|
-
panels:
|
|
25618
|
-
beatId:
|
|
25619
|
-
voiceover:
|
|
25620
|
-
visualDirection:
|
|
25839
|
+
panels: z114.array(z114.object({
|
|
25840
|
+
beatId: z114.string(),
|
|
25841
|
+
voiceover: z114.string(),
|
|
25842
|
+
visualDirection: z114.string()
|
|
25621
25843
|
}).passthrough()).optional()
|
|
25622
25844
|
}).optional()
|
|
25623
25845
|
}).passthrough();
|
|
@@ -25969,8 +26191,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
25969
26191
|
server.registerTool("verify_landing_commerce", {
|
|
25970
26192
|
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.",
|
|
25971
26193
|
inputSchema: {
|
|
25972
|
-
taskId:
|
|
25973
|
-
editId:
|
|
26194
|
+
taskId: z114.string().uuid(),
|
|
26195
|
+
editId: z114.string().uuid()
|
|
25974
26196
|
},
|
|
25975
26197
|
annotations: OVERWRITES_EXTERNAL
|
|
25976
26198
|
}, async (input) => {
|
|
@@ -26616,25 +26838,25 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
26616
26838
|
__name(registerTaskTools, "registerTaskTools");
|
|
26617
26839
|
|
|
26618
26840
|
// src/tools/brands.ts
|
|
26619
|
-
import { z as
|
|
26841
|
+
import { z as z115 } from "zod";
|
|
26620
26842
|
var guidance2 = getProductMakerCapabilityModelGuidance("create_brand");
|
|
26621
26843
|
var BRAND_START_REPLAY_WINDOW_MS = 15 * 60 * 1e3;
|
|
26622
26844
|
var BRAND_NOTES_MAX_CHARS = 2e4;
|
|
26623
|
-
var CreateBrandInput =
|
|
26624
|
-
action:
|
|
26845
|
+
var CreateBrandInput = z115.object({
|
|
26846
|
+
action: z115.enum([
|
|
26625
26847
|
"start",
|
|
26626
26848
|
"status",
|
|
26627
26849
|
"list"
|
|
26628
26850
|
]).default("start").describe("start cotiza (sin confirmed) o inicia (confirmed=true) el an\xE1lisis; status consulta brandId hasta ready o failed; list muestra las marcas que el usuario ya tiene."),
|
|
26629
|
-
sourceUrl:
|
|
26630
|
-
businessNotes:
|
|
26631
|
-
language:
|
|
26851
|
+
sourceUrl: z115.string().trim().min(1).max(500).optional().describe("Instagram, Facebook, TikTok o web p\xFAblica del negocio, como la dio el usuario (\xAB@sanlucasbarberia\xBB, \xABinstagram.com/sanlucasbarberia\xBB, \xABmibarberia.com\xBB). Obligatorio para start."),
|
|
26852
|
+
businessNotes: z115.string().trim().max(BRAND_NOTES_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cuente de su negocio en el chat (servicios y precios, WhatsApp, ciudad o zona, horarios). Se guarda como documento del negocio y llega tal cual a la marca y a su landing. Copia sus palabras; no inventes datos."),
|
|
26853
|
+
language: z115.enum([
|
|
26632
26854
|
"es",
|
|
26633
26855
|
"en",
|
|
26634
26856
|
"pt"
|
|
26635
26857
|
]).optional().describe("Idioma de la conversaci\xF3n. Solo se usa si la p\xE1gina del negocio no deja claro su idioma."),
|
|
26636
|
-
confirmed:
|
|
26637
|
-
brandId:
|
|
26858
|
+
confirmed: z115.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, start solo cotiza y no cobra."),
|
|
26859
|
+
brandId: z115.string().uuid().optional().describe("ID de la marca. Obligatorio para status; no lo inventes.")
|
|
26638
26860
|
}).strict();
|
|
26639
26861
|
function normalizeBrandSourceUrl(raw) {
|
|
26640
26862
|
const value = raw.trim();
|
|
@@ -26874,24 +27096,24 @@ __name(registerBrandTools, "registerBrandTools");
|
|
|
26874
27096
|
|
|
26875
27097
|
// src/tools/service-landing.ts
|
|
26876
27098
|
import { createHash as createHash3 } from "crypto";
|
|
26877
|
-
import { z as
|
|
27099
|
+
import { z as z116 } from "zod";
|
|
26878
27100
|
var guidance3 = getProductMakerCapabilityModelGuidance("create_service_landing");
|
|
26879
27101
|
var SERVICE_LANDING_KEY_NAMESPACE = "6f1d8c2a-3b4e-5f60-8a7b-9c0d1e2f3a4b";
|
|
26880
27102
|
var SERVICE_LANDING_INFO_MAX_CHARS = 2e4;
|
|
26881
|
-
var CreateServiceLandingInput =
|
|
26882
|
-
action:
|
|
27103
|
+
var CreateServiceLandingInput = z116.object({
|
|
27104
|
+
action: z116.enum([
|
|
26883
27105
|
"prepare",
|
|
26884
27106
|
"build",
|
|
26885
27107
|
"status",
|
|
26886
27108
|
"publish"
|
|
26887
27109
|
]).default("prepare").describe("prepare (gratis) crea o retoma la landing de la marca y da el precio; build (pagado, confirmed=true) lee los datos del negocio y luego crea la p\xE1gina; status sigue el avance; publish la publica y devuelve su enlace."),
|
|
26888
|
-
brandId:
|
|
26889
|
-
servicePageId:
|
|
26890
|
-
businessInfo:
|
|
26891
|
-
confirmed:
|
|
26892
|
-
maxCredits:
|
|
26893
|
-
operationId:
|
|
26894
|
-
slug:
|
|
27110
|
+
brandId: z116.string().uuid().optional().describe("ID de la marca (de create_brand). Obligatorio para prepare. Nunca un taskId de producto."),
|
|
27111
|
+
servicePageId: z116.string().uuid().optional().describe("ID de la landing que devolvi\xF3 prepare. Obligatorio para build, status y publish."),
|
|
27112
|
+
businessInfo: z116.string().trim().max(SERVICE_LANDING_INFO_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cont\xF3 del negocio y no estaba en su marca: servicios y precios, WhatsApp o tel\xE9fono, ciudad o zona, horarios. Copia sus palabras; no inventes datos."),
|
|
27113
|
+
confirmed: z116.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio total y que el usuario acepte. Obligatorio para build."),
|
|
27114
|
+
maxCredits: z116.number().int().positive().optional().describe("El total en cr\xE9ditos que el usuario acept\xF3 (el que devolvi\xF3 prepare). Obligatorio para build: ninguna etapa se inicia si su precio supera este total."),
|
|
27115
|
+
operationId: z116.string().uuid().optional().describe("Opcional en status: la operaci\xF3n que devolvi\xF3 build."),
|
|
27116
|
+
slug: z116.string().trim().toLowerCase().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(64).optional().describe("Opcional en publish: la direcci\xF3n corta de la p\xE1gina (ej. sanlucas-barberia). Si falta se usa la sugerida desde el nombre del negocio.")
|
|
26895
27117
|
}).strict();
|
|
26896
27118
|
var SERVICE_LANDING_MAX_BUILD_ATTEMPTS = 10;
|
|
26897
27119
|
function serviceKey(...parts) {
|
|
@@ -27113,9 +27335,6 @@ function registerServiceLandingTools(server, api) {
|
|
|
27113
27335
|
let operation2 = null;
|
|
27114
27336
|
if (input.operationId) {
|
|
27115
27337
|
operation2 = await api.getJson(`/v1/service-pages/operations/${encodeURIComponent(input.operationId)}`);
|
|
27116
|
-
if (operation2.recoverable && (operation2.status === "failed" || operation2.status === "requires_reconciliation")) {
|
|
27117
|
-
operation2 = await api.postJson(`${pagePath(input.servicePageId)}/operations/${encodeURIComponent(operation2.opId)}/recover`, {});
|
|
27118
|
-
}
|
|
27119
27338
|
if (operation2.status === "queued" || operation2.status === "running") {
|
|
27120
27339
|
return asText({
|
|
27121
27340
|
servicePageId: input.servicePageId,
|
|
@@ -27132,7 +27351,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
27132
27351
|
status: "in_review",
|
|
27133
27352
|
// Unknown on purpose: the charge is exactly what is being
|
|
27134
27353
|
// confirmed. Settlement only charges a completed step.
|
|
27135
|
-
nextAction: "Esta etapa qued\xF3 en revisi\xF3n por un problema temporal:
|
|
27354
|
+
nextAction: "Esta etapa qued\xF3 en revisi\xF3n por un problema temporal: el servidor est\xE1 confirmando si se complet\xF3 y la resuelve solo. Si no se completa, se devuelve lo cobrado. Dile al usuario que sus datos est\xE1n guardados; vuelve a llamar action=status con el mismo operationId en unos minutos (si no se complet\xF3, pasa a fallida y la reintentas con build). No inicies otra etapa mientras tanto."
|
|
27136
27355
|
});
|
|
27137
27356
|
}
|
|
27138
27357
|
if (operation2.status !== "succeeded") {
|
|
@@ -27227,7 +27446,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
27227
27446
|
__name(registerServiceLandingTools, "registerServiceLandingTools");
|
|
27228
27447
|
|
|
27229
27448
|
// src/tools/service-images.ts
|
|
27230
|
-
import { z as
|
|
27449
|
+
import { z as z117 } from "zod";
|
|
27231
27450
|
var guidance4 = getProductMakerCapabilityModelGuidance("create_service_images");
|
|
27232
27451
|
var SERVICE_IMAGE_FORMATS = [
|
|
27233
27452
|
"4:5",
|
|
@@ -27240,23 +27459,23 @@ var LANGUAGE_TAGS = {
|
|
|
27240
27459
|
en: "en-US",
|
|
27241
27460
|
pt: "pt-BR"
|
|
27242
27461
|
};
|
|
27243
|
-
var CreateServiceImagesInput =
|
|
27244
|
-
brandId:
|
|
27245
|
-
instruction:
|
|
27246
|
-
delegateToAi:
|
|
27247
|
-
format:
|
|
27248
|
-
count:
|
|
27249
|
-
quality:
|
|
27462
|
+
var CreateServiceImagesInput = z117.object({
|
|
27463
|
+
brandId: z117.string().uuid().optional().describe("ID de la marca (de create_brand). Recomendado: da nombre, colores, tono y servicios. Nunca un taskId de producto."),
|
|
27464
|
+
instruction: z117.string().trim().max(4e3).optional().describe("Qu\xE9 servicio o promoci\xF3n mostrar, con las palabras del usuario (ej. \xABcorte + barba a $35.000 los martes\xBB). Si el usuario deja que la IA decida, om\xEDtelo y usa delegateToAi=true."),
|
|
27465
|
+
delegateToAi: z117.boolean().optional().describe("true si el usuario prefiere que la IA elija qu\xE9 mostrar a partir de su marca."),
|
|
27466
|
+
format: z117.enum(SERVICE_IMAGE_FORMATS).optional().describe('Formato: "4:5" (feed, por defecto), "9:16" (historias/reels) o "1:1" (cuadrado).'),
|
|
27467
|
+
count: z117.number().int().min(1).max(SERVICE_IMAGE_MAX_COUNT).optional().describe("Cu\xE1ntas im\xE1genes, de 1 a 3 (por defecto 1)."),
|
|
27468
|
+
quality: z117.enum([
|
|
27250
27469
|
"standard",
|
|
27251
27470
|
"high"
|
|
27252
27471
|
]).optional().describe('Calidad: "standard" (por defecto) o "high" (m\xE1s cara; no disponible en 4:5).'),
|
|
27253
|
-
language:
|
|
27472
|
+
language: z117.enum([
|
|
27254
27473
|
"es",
|
|
27255
27474
|
"en",
|
|
27256
27475
|
"pt"
|
|
27257
27476
|
]).optional().describe("Idioma de los textos de la imagen (por defecto es)."),
|
|
27258
|
-
adCopy:
|
|
27259
|
-
confirmed:
|
|
27477
|
+
adCopy: z117.boolean().optional().describe("Opcional. true agrega textos para el anuncio (titular y descripci\xF3n). Por defecto false."),
|
|
27478
|
+
confirmed: z117.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, solo cotiza y no cobra.")
|
|
27260
27479
|
}).strict();
|
|
27261
27480
|
function serviceImageModel(quality) {
|
|
27262
27481
|
return quality === "high" ? AD_CREATIVE_MODELS.PREMIUM : AD_CREATIVE_MODELS.STANDARD;
|
|
@@ -27367,7 +27586,7 @@ function registerServiceImageTools(server, api, options = {}) {
|
|
|
27367
27586
|
nextAction: "Dile al usuario que est\xE1s creando sus im\xE1genes. Llama get_task_status con este taskId (waitSeconds=45) hasta done (trae las im\xE1genes) o error."
|
|
27368
27587
|
});
|
|
27369
27588
|
} catch (error) {
|
|
27370
|
-
if (error instanceof
|
|
27589
|
+
if (error instanceof z117.ZodError) throw invalidInputFromZod(error);
|
|
27371
27590
|
throw translateError(error);
|
|
27372
27591
|
}
|
|
27373
27592
|
});
|
|
@@ -27375,7 +27594,7 @@ function registerServiceImageTools(server, api, options = {}) {
|
|
|
27375
27594
|
__name(registerServiceImageTools, "registerServiceImageTools");
|
|
27376
27595
|
|
|
27377
27596
|
// src/tools/creatives.ts
|
|
27378
|
-
import { z as
|
|
27597
|
+
import { z as z118 } from "zod";
|
|
27379
27598
|
var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
|
|
27380
27599
|
var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
|
|
27381
27600
|
var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
|
|
@@ -27386,72 +27605,72 @@ var CreativeRefs = {
|
|
|
27386
27605
|
images: ImagesInput,
|
|
27387
27606
|
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.'),
|
|
27388
27607
|
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.'),
|
|
27389
|
-
price:
|
|
27390
|
-
offer:
|
|
27391
|
-
compareAtPrice:
|
|
27392
|
-
productContext:
|
|
27393
|
-
productLabel:
|
|
27394
|
-
buyerPersona:
|
|
27395
|
-
isCombo:
|
|
27396
|
-
competitorScanEnabled:
|
|
27397
|
-
brandId:
|
|
27608
|
+
price: z118.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.'),
|
|
27609
|
+
offer: z118.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.'),
|
|
27610
|
+
compareAtPrice: z118.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
|
|
27611
|
+
productContext: z118.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."),
|
|
27612
|
+
productLabel: z118.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.'),
|
|
27613
|
+
buyerPersona: z118.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.'),
|
|
27614
|
+
isCombo: z118.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
|
|
27615
|
+
competitorScanEnabled: z118.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."),
|
|
27616
|
+
brandId: z118.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.")
|
|
27398
27617
|
};
|
|
27399
|
-
var VideoPresenter =
|
|
27400
|
-
|
|
27401
|
-
mode:
|
|
27618
|
+
var VideoPresenter = z118.discriminatedUnion("mode", [
|
|
27619
|
+
z118.object({
|
|
27620
|
+
mode: z118.literal("none")
|
|
27402
27621
|
}).strict(),
|
|
27403
|
-
|
|
27404
|
-
mode:
|
|
27405
|
-
actorId:
|
|
27622
|
+
z118.object({
|
|
27623
|
+
mode: z118.literal("saved_actor"),
|
|
27624
|
+
actorId: z118.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
|
|
27406
27625
|
}).strict(),
|
|
27407
|
-
|
|
27408
|
-
mode:
|
|
27409
|
-
description:
|
|
27626
|
+
z118.object({
|
|
27627
|
+
mode: z118.literal("described"),
|
|
27628
|
+
description: z118.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
|
|
27410
27629
|
}).strict()
|
|
27411
27630
|
]);
|
|
27412
|
-
var VideoCreativeSetup =
|
|
27413
|
-
|
|
27414
|
-
mode:
|
|
27631
|
+
var VideoCreativeSetup = z118.discriminatedUnion("mode", [
|
|
27632
|
+
z118.object({
|
|
27633
|
+
mode: z118.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
|
|
27415
27634
|
}).strict(),
|
|
27416
|
-
|
|
27417
|
-
mode:
|
|
27635
|
+
z118.object({
|
|
27636
|
+
mode: z118.literal("guided"),
|
|
27418
27637
|
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.'),
|
|
27419
|
-
buyerPersona:
|
|
27638
|
+
buyerPersona: z118.string().trim().min(1).max(360),
|
|
27420
27639
|
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.'),
|
|
27421
27640
|
presenter: VideoPresenter,
|
|
27422
|
-
creativeDirection:
|
|
27641
|
+
creativeDirection: z118.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
|
|
27423
27642
|
}).strict()
|
|
27424
27643
|
]);
|
|
27425
|
-
var VideoInput =
|
|
27644
|
+
var VideoInput = z118.object({
|
|
27426
27645
|
images: CreativeRefs.images.optional(),
|
|
27427
27646
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
27428
|
-
title:
|
|
27429
|
-
primaryAngle:
|
|
27647
|
+
title: z118.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
|
|
27648
|
+
primaryAngle: z118.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".'),
|
|
27430
27649
|
language: CreativeRefs.language,
|
|
27431
27650
|
country: CreativeRefs.country,
|
|
27432
|
-
aspectRatio:
|
|
27651
|
+
aspectRatio: z118.enum([
|
|
27433
27652
|
"9:16",
|
|
27434
27653
|
"16:9",
|
|
27435
27654
|
"Auto"
|
|
27436
27655
|
]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
|
|
27437
27656
|
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.'),
|
|
27438
|
-
durationSeconds:
|
|
27439
|
-
videoAngleCount:
|
|
27657
|
+
durationSeconds: z118.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."),
|
|
27658
|
+
videoAngleCount: z118.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."),
|
|
27440
27659
|
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.'),
|
|
27441
27660
|
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."),
|
|
27442
27661
|
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.'),
|
|
27443
27662
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
|
|
27444
27663
|
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.'),
|
|
27445
|
-
features:
|
|
27664
|
+
features: z118.array(z118.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
|
|
27446
27665
|
price: CreativeRefs.price,
|
|
27447
27666
|
offer: CreativeRefs.offer,
|
|
27448
27667
|
productContext: CreativeRefs.productContext,
|
|
27449
27668
|
productLabel: CreativeRefs.productLabel,
|
|
27450
|
-
cta:
|
|
27451
|
-
scriptNotes:
|
|
27669
|
+
cta: z118.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.'),
|
|
27670
|
+
scriptNotes: z118.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.'),
|
|
27452
27671
|
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.'),
|
|
27453
27672
|
competitorScanEnabled: CreativeRefs.competitorScanEnabled,
|
|
27454
|
-
replicateWinnerWhenFound:
|
|
27673
|
+
replicateWinnerWhenFound: z118.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."),
|
|
27455
27674
|
brandId: CreativeRefs.brandId
|
|
27456
27675
|
}).strict();
|
|
27457
27676
|
var FreeVideoQualityEnum = VideoQualityEnum;
|
|
@@ -27469,7 +27688,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
|
|
|
27469
27688
|
length: 29
|
|
27470
27689
|
}, (_, index) => index + 2)
|
|
27471
27690
|
};
|
|
27472
|
-
var FreeVideoModelIdEnum =
|
|
27691
|
+
var FreeVideoModelIdEnum = z118.enum([
|
|
27473
27692
|
"grok-imagine-video-1-5-preview",
|
|
27474
27693
|
"minimax-h3/reference-to-video",
|
|
27475
27694
|
"wan/3-0-video",
|
|
@@ -27480,66 +27699,66 @@ var FREE_SELECTABLE_MODEL_IDS = [
|
|
|
27480
27699
|
"minimax-h3/reference-to-video",
|
|
27481
27700
|
"wan/3-0-video"
|
|
27482
27701
|
];
|
|
27483
|
-
var FreeVideoInput =
|
|
27702
|
+
var FreeVideoInput = z118.object({
|
|
27484
27703
|
images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
|
|
27485
|
-
rawPrompt:
|
|
27704
|
+
rawPrompt: z118.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."),
|
|
27486
27705
|
language: CreativeRefs.language,
|
|
27487
27706
|
quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
|
|
27488
27707
|
// Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
|
|
27489
27708
|
// parsed ONLY so the handler can reject it with a message naming its
|
|
27490
27709
|
// replacement — dropping it silently would turn a caller's explicit
|
|
27491
27710
|
// Pro++ pick into a quiet fallback to Wan.
|
|
27492
|
-
freeProModel:
|
|
27711
|
+
freeProModel: z118.enum([
|
|
27493
27712
|
"wan",
|
|
27494
27713
|
"seedance"
|
|
27495
27714
|
]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
|
|
27496
27715
|
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.'),
|
|
27497
|
-
durationSeconds:
|
|
27716
|
+
durationSeconds: z118.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."),
|
|
27498
27717
|
videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
|
|
27499
|
-
generateAiMusic:
|
|
27718
|
+
generateAiMusic: z118.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.'),
|
|
27500
27719
|
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.'),
|
|
27501
|
-
addSubtitles:
|
|
27502
|
-
idempotencyKey:
|
|
27720
|
+
addSubtitles: z118.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
|
|
27721
|
+
idempotencyKey: z118.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.")
|
|
27503
27722
|
}).strict();
|
|
27504
27723
|
var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
|
|
27505
|
-
var ImageCreativeSetup =
|
|
27506
|
-
|
|
27507
|
-
mode:
|
|
27724
|
+
var ImageCreativeSetup = z118.discriminatedUnion("mode", [
|
|
27725
|
+
z118.object({
|
|
27726
|
+
mode: z118.literal("automatic")
|
|
27508
27727
|
}).strict(),
|
|
27509
|
-
|
|
27510
|
-
mode:
|
|
27511
|
-
creativeArchetype:
|
|
27728
|
+
z118.object({
|
|
27729
|
+
mode: z118.literal("guided"),
|
|
27730
|
+
creativeArchetype: z118.union([
|
|
27512
27731
|
ImageCreativeArchetypeEnum,
|
|
27513
|
-
|
|
27732
|
+
z118.literal("ai_decides")
|
|
27514
27733
|
]),
|
|
27515
|
-
visualTreatment:
|
|
27734
|
+
visualTreatment: z118.union([
|
|
27516
27735
|
ImageCreativeVisualTreatmentEnum,
|
|
27517
|
-
|
|
27736
|
+
z118.literal("ai_decides")
|
|
27518
27737
|
]),
|
|
27519
27738
|
aspectRatio: ImageCreativeAspectRatioEnum,
|
|
27520
|
-
nVariants:
|
|
27521
|
-
|
|
27522
|
-
|
|
27523
|
-
|
|
27524
|
-
|
|
27525
|
-
|
|
27739
|
+
nVariants: z118.union([
|
|
27740
|
+
z118.literal(1),
|
|
27741
|
+
z118.literal(2),
|
|
27742
|
+
z118.literal(3),
|
|
27743
|
+
z118.literal(4),
|
|
27744
|
+
z118.literal(6)
|
|
27526
27745
|
]),
|
|
27527
|
-
imageModel:
|
|
27528
|
-
styleMix:
|
|
27529
|
-
generateAdCopy:
|
|
27530
|
-
competitorScanEnabled:
|
|
27531
|
-
productContext:
|
|
27532
|
-
creativeDirection:
|
|
27533
|
-
brandColors:
|
|
27534
|
-
headline:
|
|
27535
|
-
subheadline:
|
|
27746
|
+
imageModel: z118.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.'),
|
|
27747
|
+
styleMix: z118.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
|
|
27748
|
+
generateAdCopy: z118.boolean(),
|
|
27749
|
+
competitorScanEnabled: z118.boolean(),
|
|
27750
|
+
productContext: z118.string().trim().min(1).max(3e3).nullable(),
|
|
27751
|
+
creativeDirection: z118.string().trim().min(1).max(500).nullable(),
|
|
27752
|
+
brandColors: z118.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.'),
|
|
27753
|
+
headline: z118.string().trim().min(1).max(120).nullable(),
|
|
27754
|
+
subheadline: z118.string().trim().min(1).max(160).nullable()
|
|
27536
27755
|
}).strict()
|
|
27537
27756
|
]).superRefine((setup, context) => {
|
|
27538
27757
|
if (setup.mode !== "guided") return;
|
|
27539
27758
|
const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
|
|
27540
27759
|
if (needsStyleMix && setup.styleMix === null) {
|
|
27541
27760
|
context.addIssue({
|
|
27542
|
-
code:
|
|
27761
|
+
code: z118.ZodIssueCode.custom,
|
|
27543
27762
|
path: [
|
|
27544
27763
|
"styleMix"
|
|
27545
27764
|
],
|
|
@@ -27548,7 +27767,7 @@ var ImageCreativeSetup = z116.discriminatedUnion("mode", [
|
|
|
27548
27767
|
}
|
|
27549
27768
|
if (!needsStyleMix && setup.styleMix !== null) {
|
|
27550
27769
|
context.addIssue({
|
|
27551
|
-
code:
|
|
27770
|
+
code: z118.ZodIssueCode.custom,
|
|
27552
27771
|
path: [
|
|
27553
27772
|
"styleMix"
|
|
27554
27773
|
],
|
|
@@ -27557,7 +27776,7 @@ var ImageCreativeSetup = z116.discriminatedUnion("mode", [
|
|
|
27557
27776
|
}
|
|
27558
27777
|
if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
|
|
27559
27778
|
context.addIssue({
|
|
27560
|
-
code:
|
|
27779
|
+
code: z118.ZodIssueCode.custom,
|
|
27561
27780
|
path: [
|
|
27562
27781
|
"aspectRatio"
|
|
27563
27782
|
],
|
|
@@ -27565,55 +27784,55 @@ var ImageCreativeSetup = z116.discriminatedUnion("mode", [
|
|
|
27565
27784
|
});
|
|
27566
27785
|
}
|
|
27567
27786
|
});
|
|
27568
|
-
var LandingCreativeSetup =
|
|
27569
|
-
|
|
27570
|
-
mode:
|
|
27787
|
+
var LandingCreativeSetup = z118.discriminatedUnion("mode", [
|
|
27788
|
+
z118.object({
|
|
27789
|
+
mode: z118.literal("automatic")
|
|
27571
27790
|
}).strict(),
|
|
27572
|
-
|
|
27573
|
-
mode:
|
|
27791
|
+
z118.object({
|
|
27792
|
+
mode: z118.literal("guided"),
|
|
27574
27793
|
landingStrategy: LandingStrategyEnum,
|
|
27575
27794
|
landingImageFormat: LandingImageFormatEnum,
|
|
27576
|
-
competitorScanEnabled:
|
|
27577
|
-
paymentMethods:
|
|
27578
|
-
productContext:
|
|
27579
|
-
creativeDirection:
|
|
27580
|
-
headline:
|
|
27581
|
-
subheadline:
|
|
27795
|
+
competitorScanEnabled: z118.boolean(),
|
|
27796
|
+
paymentMethods: z118.string().trim().min(1).max(240).nullable(),
|
|
27797
|
+
productContext: z118.string().trim().min(1).max(3e3).nullable(),
|
|
27798
|
+
creativeDirection: z118.string().trim().min(1).max(500).nullable(),
|
|
27799
|
+
headline: z118.string().trim().min(1).max(120).nullable(),
|
|
27800
|
+
subheadline: z118.string().trim().min(1).max(160).nullable()
|
|
27582
27801
|
}).strict()
|
|
27583
27802
|
]);
|
|
27584
|
-
var ImageInput =
|
|
27803
|
+
var ImageInput = z118.object({
|
|
27585
27804
|
images: CreativeRefs.images.optional(),
|
|
27586
27805
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
27587
|
-
productTitle:
|
|
27588
|
-
primaryAngle:
|
|
27806
|
+
productTitle: z118.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
|
|
27807
|
+
primaryAngle: z118.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.'),
|
|
27589
27808
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
27590
27809
|
language: CreativeRefs.language,
|
|
27591
27810
|
country: CreativeRefs.country,
|
|
27592
27811
|
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."),
|
|
27593
27812
|
imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
|
|
27594
|
-
features:
|
|
27813
|
+
features: z118.array(z118.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
|
|
27595
27814
|
price: CreativeRefs.price,
|
|
27596
|
-
omitPrice:
|
|
27815
|
+
omitPrice: z118.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."),
|
|
27597
27816
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
27598
27817
|
offer: CreativeRefs.offer,
|
|
27599
27818
|
productLabel: CreativeRefs.productLabel,
|
|
27600
27819
|
isCombo: CreativeRefs.isCombo,
|
|
27601
27820
|
brandId: CreativeRefs.brandId
|
|
27602
27821
|
});
|
|
27603
|
-
var EditImageCreativeInput =
|
|
27604
|
-
taskId:
|
|
27605
|
-
variantIndex:
|
|
27606
|
-
clientRequestId:
|
|
27607
|
-
instruction:
|
|
27822
|
+
var EditImageCreativeInput = z118.object({
|
|
27823
|
+
taskId: z118.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
|
|
27824
|
+
variantIndex: z118.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
|
|
27825
|
+
clientRequestId: z118.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."),
|
|
27826
|
+
instruction: z118.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".')
|
|
27608
27827
|
});
|
|
27609
|
-
var LandingInput =
|
|
27610
|
-
includeInitialLandingGif:
|
|
27828
|
+
var LandingInput = z118.object({
|
|
27829
|
+
includeInitialLandingGif: z118.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."),
|
|
27611
27830
|
images: CreativeRefs.images.optional(),
|
|
27612
27831
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
27613
27832
|
language: CreativeRefs.language,
|
|
27614
27833
|
country: CreativeRefs.country,
|
|
27615
27834
|
creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
|
|
27616
|
-
salesAngle:
|
|
27835
|
+
salesAngle: z118.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.'),
|
|
27617
27836
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
27618
27837
|
price: CreativeRefs.price,
|
|
27619
27838
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
@@ -27895,8 +28114,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
27895
28114
|
server.registerTool("get_image_edit_status", {
|
|
27896
28115
|
description: imageEditStatusGuidance.summary,
|
|
27897
28116
|
inputSchema: {
|
|
27898
|
-
taskId:
|
|
27899
|
-
operationId:
|
|
28117
|
+
taskId: z118.string().uuid(),
|
|
28118
|
+
operationId: z118.string().uuid()
|
|
27900
28119
|
},
|
|
27901
28120
|
annotations: READS_INTERNAL
|
|
27902
28121
|
}, async (input) => {
|
|
@@ -27953,10 +28172,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
27953
28172
|
__name(registerCreativeTools, "registerCreativeTools");
|
|
27954
28173
|
|
|
27955
28174
|
// src/tools/creative-variants.ts
|
|
27956
|
-
import { z as
|
|
28175
|
+
import { z as z119 } from "zod";
|
|
27957
28176
|
var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
|
|
27958
28177
|
var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
|
|
27959
|
-
var LandingSectionKeyEnum =
|
|
28178
|
+
var LandingSectionKeyEnum = z119.enum([
|
|
27960
28179
|
"problem_hook",
|
|
27961
28180
|
"problem_cost",
|
|
27962
28181
|
"solution_mechanism",
|
|
@@ -27996,24 +28215,24 @@ var LandingSectionKeyEnum = z117.enum([
|
|
|
27996
28215
|
"lifestyle_fit",
|
|
27997
28216
|
"join_lifestyle"
|
|
27998
28217
|
]);
|
|
27999
|
-
var CreativeVariantKindEnum =
|
|
28218
|
+
var CreativeVariantKindEnum = z119.enum([
|
|
28000
28219
|
"video",
|
|
28001
28220
|
"image",
|
|
28002
28221
|
"landing"
|
|
28003
28222
|
]);
|
|
28004
|
-
var EstimateCreativeVariantInputBase =
|
|
28005
|
-
sourceTaskId:
|
|
28223
|
+
var EstimateCreativeVariantInputBase = z119.object({
|
|
28224
|
+
sourceTaskId: z119.string().uuid().describe("ID de la tarea original completada."),
|
|
28006
28225
|
kind: CreativeVariantKindEnum,
|
|
28007
28226
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
|
|
28008
28227
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
|
|
28009
|
-
nVariants:
|
|
28228
|
+
nVariants: z119.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
28010
28229
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
|
|
28011
|
-
instructions:
|
|
28230
|
+
instructions: z119.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.")
|
|
28012
28231
|
}).strict();
|
|
28013
28232
|
var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
28014
28233
|
if (input.kind === "video" && input.nVariants !== void 0) {
|
|
28015
28234
|
ctx.addIssue({
|
|
28016
|
-
code:
|
|
28235
|
+
code: z119.ZodIssueCode.custom,
|
|
28017
28236
|
path: [
|
|
28018
28237
|
"nVariants"
|
|
28019
28238
|
],
|
|
@@ -28023,7 +28242,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28023
28242
|
if (input.kind !== "video") {
|
|
28024
28243
|
if (input.videoPreset !== void 0) {
|
|
28025
28244
|
ctx.addIssue({
|
|
28026
|
-
code:
|
|
28245
|
+
code: z119.ZodIssueCode.custom,
|
|
28027
28246
|
path: [
|
|
28028
28247
|
"videoPreset"
|
|
28029
28248
|
],
|
|
@@ -28032,7 +28251,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28032
28251
|
}
|
|
28033
28252
|
if (input.videoResolution !== void 0) {
|
|
28034
28253
|
ctx.addIssue({
|
|
28035
|
-
code:
|
|
28254
|
+
code: z119.ZodIssueCode.custom,
|
|
28036
28255
|
path: [
|
|
28037
28256
|
"videoResolution"
|
|
28038
28257
|
],
|
|
@@ -28042,7 +28261,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28042
28261
|
}
|
|
28043
28262
|
if (input.kind !== "image" && input.nVariants !== void 0) {
|
|
28044
28263
|
ctx.addIssue({
|
|
28045
|
-
code:
|
|
28264
|
+
code: z119.ZodIssueCode.custom,
|
|
28046
28265
|
path: [
|
|
28047
28266
|
"nVariants"
|
|
28048
28267
|
],
|
|
@@ -28052,7 +28271,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28052
28271
|
if (input.kind !== "landing") {
|
|
28053
28272
|
if (input.sectionKey !== void 0) {
|
|
28054
28273
|
ctx.addIssue({
|
|
28055
|
-
code:
|
|
28274
|
+
code: z119.ZodIssueCode.custom,
|
|
28056
28275
|
path: [
|
|
28057
28276
|
"sectionKey"
|
|
28058
28277
|
],
|
|
@@ -28061,7 +28280,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28061
28280
|
}
|
|
28062
28281
|
if (input.instructions !== void 0) {
|
|
28063
28282
|
ctx.addIssue({
|
|
28064
|
-
code:
|
|
28283
|
+
code: z119.ZodIssueCode.custom,
|
|
28065
28284
|
path: [
|
|
28066
28285
|
"instructions"
|
|
28067
28286
|
],
|
|
@@ -28070,31 +28289,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28070
28289
|
}
|
|
28071
28290
|
}
|
|
28072
28291
|
});
|
|
28073
|
-
var CreateCreativeVariantInputBase =
|
|
28074
|
-
sourceTaskId:
|
|
28292
|
+
var CreateCreativeVariantInputBase = z119.object({
|
|
28293
|
+
sourceTaskId: z119.string().uuid().describe("ID de la tarea original completada."),
|
|
28075
28294
|
kind: CreativeVariantKindEnum,
|
|
28076
|
-
confirm:
|
|
28077
|
-
clientRequestId:
|
|
28078
|
-
angle:
|
|
28079
|
-
buyerPersona:
|
|
28080
|
-
scriptNotes:
|
|
28081
|
-
creativeDirection:
|
|
28295
|
+
confirm: z119.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
|
|
28296
|
+
clientRequestId: z119.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."),
|
|
28297
|
+
angle: z119.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
|
|
28298
|
+
buyerPersona: z119.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
|
|
28299
|
+
scriptNotes: z119.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
|
|
28300
|
+
creativeDirection: z119.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
|
|
28082
28301
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
|
|
28083
28302
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
|
|
28084
|
-
generateAiMusic:
|
|
28085
|
-
nVariants:
|
|
28303
|
+
generateAiMusic: z119.boolean().optional().describe("Opcional para video."),
|
|
28304
|
+
nVariants: z119.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
28086
28305
|
imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
|
|
28087
28306
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
|
|
28088
28307
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
|
|
28089
28308
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
|
|
28090
|
-
styleMix:
|
|
28309
|
+
styleMix: z119.boolean().optional().describe("Opcional para imagen."),
|
|
28091
28310
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
|
|
28092
|
-
instructions:
|
|
28311
|
+
instructions: z119.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.")
|
|
28093
28312
|
}).strict();
|
|
28094
28313
|
var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
28095
28314
|
if ((input.kind === "video" || input.kind === "image") && !input.angle) {
|
|
28096
28315
|
ctx.addIssue({
|
|
28097
|
-
code:
|
|
28316
|
+
code: z119.ZodIssueCode.custom,
|
|
28098
28317
|
path: [
|
|
28099
28318
|
"angle"
|
|
28100
28319
|
],
|
|
@@ -28103,7 +28322,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
28103
28322
|
}
|
|
28104
28323
|
if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
|
|
28105
28324
|
ctx.addIssue({
|
|
28106
|
-
code:
|
|
28325
|
+
code: z119.ZodIssueCode.custom,
|
|
28107
28326
|
path: [
|
|
28108
28327
|
"instructions"
|
|
28109
28328
|
],
|
|
@@ -28149,7 +28368,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
28149
28368
|
for (const field of fieldsByKind[input.kind]) {
|
|
28150
28369
|
if (input[field] !== void 0) {
|
|
28151
28370
|
ctx.addIssue({
|
|
28152
|
-
code:
|
|
28371
|
+
code: z119.ZodIssueCode.custom,
|
|
28153
28372
|
path: [
|
|
28154
28373
|
field
|
|
28155
28374
|
],
|
|
@@ -28282,13 +28501,13 @@ function registerCreativeVariantTools(server, api) {
|
|
|
28282
28501
|
__name(registerCreativeVariantTools, "registerCreativeVariantTools");
|
|
28283
28502
|
|
|
28284
28503
|
// src/tools/script-review.ts
|
|
28285
|
-
import { z as
|
|
28504
|
+
import { z as z120 } from "zod";
|
|
28286
28505
|
var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
|
|
28287
28506
|
var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
|
|
28288
28507
|
var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
|
|
28289
|
-
var GetVideoScriptInput =
|
|
28290
|
-
taskId:
|
|
28291
|
-
angleKey:
|
|
28508
|
+
var GetVideoScriptInput = z120.object({
|
|
28509
|
+
taskId: z120.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
|
|
28510
|
+
angleKey: z120.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.')
|
|
28292
28511
|
}).strict();
|
|
28293
28512
|
var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
|
|
28294
28513
|
var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
|
|
@@ -28371,7 +28590,7 @@ function registerScriptReviewTools(server, api) {
|
|
|
28371
28590
|
__name(registerScriptReviewTools, "registerScriptReviewTools");
|
|
28372
28591
|
|
|
28373
28592
|
// src/tools/connections.ts
|
|
28374
|
-
import { z as
|
|
28593
|
+
import { z as z121 } from "zod";
|
|
28375
28594
|
var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
|
|
28376
28595
|
var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
|
|
28377
28596
|
var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
|
|
@@ -28380,7 +28599,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
|
|
|
28380
28599
|
function registerConnectionTools(server, api) {
|
|
28381
28600
|
server.registerTool("list_shopify_shops", {
|
|
28382
28601
|
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.",
|
|
28383
|
-
inputSchema:
|
|
28602
|
+
inputSchema: z121.object({}).shape,
|
|
28384
28603
|
annotations: READS_INTERNAL
|
|
28385
28604
|
}, async () => {
|
|
28386
28605
|
try {
|
|
@@ -28392,10 +28611,10 @@ function registerConnectionTools(server, api) {
|
|
|
28392
28611
|
});
|
|
28393
28612
|
server.registerTool("list_shopify_products", {
|
|
28394
28613
|
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.',
|
|
28395
|
-
inputSchema:
|
|
28396
|
-
shopDomain:
|
|
28397
|
-
query:
|
|
28398
|
-
taskId:
|
|
28614
|
+
inputSchema: z121.object({
|
|
28615
|
+
shopDomain: z121.string().min(3).max(120),
|
|
28616
|
+
query: z121.string().trim().max(120).optional(),
|
|
28617
|
+
taskId: z121.string().uuid().optional()
|
|
28399
28618
|
}).shape,
|
|
28400
28619
|
annotations: READS_EXTERNAL
|
|
28401
28620
|
}, async ({ shopDomain, query, taskId }) => {
|
|
@@ -28413,7 +28632,7 @@ function registerConnectionTools(server, api) {
|
|
|
28413
28632
|
});
|
|
28414
28633
|
server.registerTool("list_meta_ad_accounts", {
|
|
28415
28634
|
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.",
|
|
28416
|
-
inputSchema:
|
|
28635
|
+
inputSchema: z121.object({}).shape,
|
|
28417
28636
|
annotations: READS_EXTERNAL
|
|
28418
28637
|
}, async () => {
|
|
28419
28638
|
try {
|
|
@@ -28425,7 +28644,7 @@ function registerConnectionTools(server, api) {
|
|
|
28425
28644
|
});
|
|
28426
28645
|
server.registerTool("list_meta_destinations", {
|
|
28427
28646
|
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.",
|
|
28428
|
-
inputSchema:
|
|
28647
|
+
inputSchema: z121.object({}).shape,
|
|
28429
28648
|
annotations: READS_EXTERNAL,
|
|
28430
28649
|
_meta: {
|
|
28431
28650
|
"openai/widgetAccessible": true
|
|
@@ -28440,7 +28659,7 @@ function registerConnectionTools(server, api) {
|
|
|
28440
28659
|
});
|
|
28441
28660
|
server.registerTool("list_tiktok_advertisers", {
|
|
28442
28661
|
description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
|
|
28443
|
-
inputSchema:
|
|
28662
|
+
inputSchema: z121.object({}).shape,
|
|
28444
28663
|
annotations: READS_EXTERNAL
|
|
28445
28664
|
}, async () => {
|
|
28446
28665
|
try {
|
|
@@ -28454,7 +28673,7 @@ function registerConnectionTools(server, api) {
|
|
|
28454
28673
|
__name(registerConnectionTools, "registerConnectionTools");
|
|
28455
28674
|
|
|
28456
28675
|
// src/tools/actors.ts
|
|
28457
|
-
import { z as
|
|
28676
|
+
import { z as z122 } from "zod";
|
|
28458
28677
|
var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
|
|
28459
28678
|
var actorVoiceGuidance = {
|
|
28460
28679
|
capabilities: getProductMakerCapabilityModelGuidance("get_actor_voice_capabilities"),
|
|
@@ -28494,7 +28713,7 @@ function sanitizeVoiceResult(value) {
|
|
|
28494
28713
|
__name(sanitizeVoiceResult, "sanitizeVoiceResult");
|
|
28495
28714
|
function registerActorTools(server, api) {
|
|
28496
28715
|
const actor = {
|
|
28497
|
-
actorId:
|
|
28716
|
+
actorId: z122.string().min(1).max(64)
|
|
28498
28717
|
};
|
|
28499
28718
|
const safe = /* @__PURE__ */ __name(async (request) => {
|
|
28500
28719
|
try {
|
|
@@ -28523,8 +28742,8 @@ function registerActorTools(server, api) {
|
|
|
28523
28742
|
inputSchema: {
|
|
28524
28743
|
...actor,
|
|
28525
28744
|
draft: ActorVoiceDraftSchema,
|
|
28526
|
-
requestKey:
|
|
28527
|
-
acceptedQuoteId:
|
|
28745
|
+
requestKey: z122.string().trim().min(1).max(128),
|
|
28746
|
+
acceptedQuoteId: z122.string().trim().min(1).max(128)
|
|
28528
28747
|
},
|
|
28529
28748
|
annotations: CREATES_PAID
|
|
28530
28749
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews`, body)));
|
|
@@ -28532,7 +28751,7 @@ function registerActorTools(server, api) {
|
|
|
28532
28751
|
description: actorVoiceGuidance.get.summary,
|
|
28533
28752
|
inputSchema: {
|
|
28534
28753
|
...actor,
|
|
28535
|
-
candidateId:
|
|
28754
|
+
candidateId: z122.string().min(1).max(64)
|
|
28536
28755
|
},
|
|
28537
28756
|
// Polling can resume the first paid submission of an accepted quote.
|
|
28538
28757
|
// The immutable candidate/operation key keeps recovery idempotent.
|
|
@@ -28545,16 +28764,16 @@ function registerActorTools(server, api) {
|
|
|
28545
28764
|
description: actorVoiceGuidance.approve.summary,
|
|
28546
28765
|
inputSchema: {
|
|
28547
28766
|
...actor,
|
|
28548
|
-
candidateId:
|
|
28549
|
-
expectedRevision:
|
|
28550
|
-
expectedApprovedRevision:
|
|
28767
|
+
candidateId: z122.string().min(1).max(64),
|
|
28768
|
+
expectedRevision: z122.number().int().positive(),
|
|
28769
|
+
expectedApprovedRevision: z122.number().int().positive().nullable().optional()
|
|
28551
28770
|
},
|
|
28552
28771
|
// Replaces the selected voice and withdraws the old catalog grants.
|
|
28553
28772
|
annotations: OVERWRITES_INTERNAL
|
|
28554
28773
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/approve`, body)));
|
|
28555
28774
|
server.registerTool("list_actors", {
|
|
28556
28775
|
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.",
|
|
28557
|
-
inputSchema:
|
|
28776
|
+
inputSchema: z122.object({}).shape,
|
|
28558
28777
|
annotations: READS_INTERNAL
|
|
28559
28778
|
}, async () => {
|
|
28560
28779
|
try {
|
|
@@ -28587,7 +28806,7 @@ function registerActorTools(server, api) {
|
|
|
28587
28806
|
__name(registerActorTools, "registerActorTools");
|
|
28588
28807
|
|
|
28589
28808
|
// src/tools/publish.ts
|
|
28590
|
-
import { z as
|
|
28809
|
+
import { z as z123 } from "zod";
|
|
28591
28810
|
|
|
28592
28811
|
// src/tools/meta-publish-attempt-id.ts
|
|
28593
28812
|
var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
|
|
@@ -28626,40 +28845,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
|
|
|
28626
28845
|
var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
|
|
28627
28846
|
var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
|
|
28628
28847
|
var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
|
|
28629
|
-
var ShopifyInput =
|
|
28630
|
-
taskId:
|
|
28631
|
-
shopDomain:
|
|
28848
|
+
var ShopifyInput = z123.object({
|
|
28849
|
+
taskId: z123.string().min(1),
|
|
28850
|
+
shopDomain: z123.string().min(1),
|
|
28632
28851
|
/** Override: number of landing images to include. Default = ALL images the
|
|
28633
28852
|
* task generated (the MCP fetches /v1/results first to count). Bounded
|
|
28634
28853
|
* generously here; the backend validates each index against
|
|
28635
28854
|
* landing.images.length and rejects out-of-range. */
|
|
28636
|
-
numLandingImages:
|
|
28637
|
-
variantIndex:
|
|
28855
|
+
numLandingImages: z123.number().int().min(1).max(20).optional(),
|
|
28856
|
+
variantIndex: z123.number().int().min(0).optional(),
|
|
28638
28857
|
/** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
|
|
28639
28858
|
* When true, the landing renders variant-picker pills; when false, it ships
|
|
28640
28859
|
* a single-option product page. Defaults to false. */
|
|
28641
|
-
showVariantPicker:
|
|
28860
|
+
showVariantPicker: z123.boolean().optional(),
|
|
28642
28861
|
/** Default `auto` updates the product previously published for this task and
|
|
28643
28862
|
* shop. Use `existing` with targetProductId to choose another product, or
|
|
28644
28863
|
* `new` only when the user explicitly wants a duplicate/new listing. */
|
|
28645
|
-
publicationMode:
|
|
28864
|
+
publicationMode: z123.enum([
|
|
28646
28865
|
"auto",
|
|
28647
28866
|
"existing",
|
|
28648
28867
|
"new"
|
|
28649
28868
|
]).optional(),
|
|
28650
28869
|
/** Shopify product GID, numeric id, or admin product URL. Required when
|
|
28651
28870
|
* publicationMode is `existing`. */
|
|
28652
|
-
targetProductId:
|
|
28871
|
+
targetProductId: z123.string().trim().min(1).max(300).optional(),
|
|
28653
28872
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
28654
|
-
announcementBarEnabled:
|
|
28655
|
-
announcementBarText:
|
|
28873
|
+
announcementBarEnabled: z123.boolean().optional(),
|
|
28874
|
+
announcementBarText: z123.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
|
|
28656
28875
|
commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
|
|
28657
|
-
confirmed:
|
|
28876
|
+
confirmed: z123.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
|
|
28658
28877
|
});
|
|
28659
28878
|
var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
|
|
28660
28879
|
if (value.commerceCorrection && value.confirmed !== true) {
|
|
28661
28880
|
ctx.addIssue({
|
|
28662
|
-
code:
|
|
28881
|
+
code: z123.ZodIssueCode.custom,
|
|
28663
28882
|
path: [
|
|
28664
28883
|
"confirmed"
|
|
28665
28884
|
],
|
|
@@ -28668,7 +28887,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
28668
28887
|
}
|
|
28669
28888
|
if (value.announcementBarEnabled && !value.announcementBarText) {
|
|
28670
28889
|
ctx.addIssue({
|
|
28671
|
-
code:
|
|
28890
|
+
code: z123.ZodIssueCode.custom,
|
|
28672
28891
|
path: [
|
|
28673
28892
|
"announcementBarText"
|
|
28674
28893
|
],
|
|
@@ -28677,7 +28896,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
28677
28896
|
}
|
|
28678
28897
|
if (!value.announcementBarEnabled && value.announcementBarText) {
|
|
28679
28898
|
ctx.addIssue({
|
|
28680
|
-
code:
|
|
28899
|
+
code: z123.ZodIssueCode.custom,
|
|
28681
28900
|
path: [
|
|
28682
28901
|
"announcementBarText"
|
|
28683
28902
|
],
|
|
@@ -28691,91 +28910,91 @@ function parseShopifyInput(rawInput) {
|
|
|
28691
28910
|
return parsed.data;
|
|
28692
28911
|
}
|
|
28693
28912
|
__name(parseShopifyInput, "parseShopifyInput");
|
|
28694
|
-
var McpCampaignConfig =
|
|
28913
|
+
var McpCampaignConfig = z123.object({
|
|
28695
28914
|
/** ALWAYS in US dollars, whatever the ad account's currency is. ProductMaker
|
|
28696
28915
|
* converts to the account currency server-side. Do NOT pre-convert: on a COP
|
|
28697
28916
|
* account the user's "60.000 al día" is `dailyBudgetUsd: 15`, not 60000. */
|
|
28698
|
-
dailyBudgetUsd:
|
|
28917
|
+
dailyBudgetUsd: z123.number().positive().optional(),
|
|
28699
28918
|
/** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
|
|
28700
28919
|
* normalizes at validation). Meta accepts max 1 (single-country ad set).
|
|
28701
28920
|
* TikTok takes only the first entry. */
|
|
28702
|
-
targetCountries:
|
|
28703
|
-
campaignName:
|
|
28921
|
+
targetCountries: z123.array(CountryIso2Schema).max(1).optional(),
|
|
28922
|
+
campaignName: z123.string().trim().min(1).max(100).optional()
|
|
28704
28923
|
});
|
|
28705
28924
|
var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
|
|
28706
|
-
var MetaInput =
|
|
28707
|
-
taskId:
|
|
28925
|
+
var MetaInput = z123.object({
|
|
28926
|
+
taskId: z123.string().min(1),
|
|
28708
28927
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
28709
|
-
portfolioId:
|
|
28928
|
+
portfolioId: z123.string().trim().min(1),
|
|
28710
28929
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
28711
|
-
pageId:
|
|
28930
|
+
pageId: z123.string().trim().min(1),
|
|
28712
28931
|
adAccountId: McpAdAccountId,
|
|
28713
|
-
pixelId:
|
|
28714
|
-
landingUrl:
|
|
28932
|
+
pixelId: z123.string().min(1).optional(),
|
|
28933
|
+
landingUrl: z123.string().url().optional(),
|
|
28715
28934
|
/** Select which angles to publish by 0-based index. Omit to publish all
|
|
28716
28935
|
* successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
|
|
28717
|
-
angleIndexes:
|
|
28936
|
+
angleIndexes: z123.array(z123.number().int().nonnegative()).optional(),
|
|
28718
28937
|
campaignConfig: McpCampaignConfig.optional(),
|
|
28719
28938
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
28720
28939
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
28721
28940
|
* (Meta's primary-text limit). */
|
|
28722
|
-
primaryText:
|
|
28941
|
+
primaryText: z123.string().trim().min(1).max(500).optional(),
|
|
28723
28942
|
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
28724
28943
|
* (wa.me) instead of a landing page. */
|
|
28725
|
-
phoneNumber:
|
|
28944
|
+
phoneNumber: z123.string().min(8).max(32).optional()
|
|
28726
28945
|
});
|
|
28727
|
-
var GroupedTaskSource =
|
|
28728
|
-
type:
|
|
28729
|
-
taskId:
|
|
28730
|
-
angleIndex:
|
|
28731
|
-
videoVariant:
|
|
28946
|
+
var GroupedTaskSource = z123.object({
|
|
28947
|
+
type: z123.literal("task"),
|
|
28948
|
+
taskId: z123.string().min(1),
|
|
28949
|
+
angleIndex: z123.number().int().min(0).optional(),
|
|
28950
|
+
videoVariant: z123.enum([
|
|
28732
28951
|
"with_subtitles",
|
|
28733
28952
|
"without_subtitles"
|
|
28734
28953
|
]).optional(),
|
|
28735
|
-
imageVariantIndex:
|
|
28736
|
-
});
|
|
28737
|
-
var GroupedMediaSource =
|
|
28738
|
-
type:
|
|
28739
|
-
url:
|
|
28740
|
-
path:
|
|
28741
|
-
thumbnailUrl:
|
|
28742
|
-
thumbnailPath:
|
|
28954
|
+
imageVariantIndex: z123.number().int().min(0).optional()
|
|
28955
|
+
});
|
|
28956
|
+
var GroupedMediaSource = z123.object({
|
|
28957
|
+
type: z123.literal("media"),
|
|
28958
|
+
url: z123.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
|
|
28959
|
+
path: z123.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".'),
|
|
28960
|
+
thumbnailUrl: z123.string().url().optional(),
|
|
28961
|
+
thumbnailPath: z123.string().min(1).optional()
|
|
28743
28962
|
}).refine((value) => Boolean(value.url) !== Boolean(value.path), {
|
|
28744
28963
|
message: "media source needs exactly one of `url` or `path`"
|
|
28745
28964
|
}).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
|
|
28746
28965
|
message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
|
|
28747
28966
|
});
|
|
28748
|
-
var GroupedUploadedAssetSource =
|
|
28749
|
-
type:
|
|
28967
|
+
var GroupedUploadedAssetSource = z123.object({
|
|
28968
|
+
type: z123.literal("asset"),
|
|
28750
28969
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
28751
|
-
assetId:
|
|
28752
|
-
thumbnailAssetId:
|
|
28970
|
+
assetId: z123.string().uuid(),
|
|
28971
|
+
thumbnailAssetId: z123.string().uuid().optional()
|
|
28753
28972
|
});
|
|
28754
|
-
var GroupedCreative =
|
|
28755
|
-
type:
|
|
28973
|
+
var GroupedCreative = z123.object({
|
|
28974
|
+
type: z123.enum([
|
|
28756
28975
|
"image",
|
|
28757
28976
|
"video"
|
|
28758
28977
|
]),
|
|
28759
|
-
source:
|
|
28978
|
+
source: z123.union([
|
|
28760
28979
|
GroupedTaskSource,
|
|
28761
28980
|
GroupedMediaSource,
|
|
28762
28981
|
GroupedUploadedAssetSource
|
|
28763
28982
|
]),
|
|
28764
|
-
title:
|
|
28765
|
-
description:
|
|
28983
|
+
title: z123.string().max(120).optional(),
|
|
28984
|
+
description: z123.string().max(500).optional(),
|
|
28766
28985
|
cta: MetaCtaType.optional(),
|
|
28767
|
-
creativeId:
|
|
28986
|
+
creativeId: z123.string().min(1).optional()
|
|
28768
28987
|
});
|
|
28769
|
-
var GroupedCampaignConfigBase =
|
|
28988
|
+
var GroupedCampaignConfigBase = z123.object({
|
|
28770
28989
|
campaignType: MetaCampaignType.default("sales"),
|
|
28771
28990
|
optimizationMode: MetaOptimizationMode.default("advantage_plus"),
|
|
28772
28991
|
budgetMode: MetaBudgetMode.optional(),
|
|
28773
|
-
campaignDailyBudget:
|
|
28774
|
-
adSets:
|
|
28775
|
-
tempId:
|
|
28776
|
-
name:
|
|
28777
|
-
dailyBudget:
|
|
28778
|
-
creativeIds:
|
|
28992
|
+
campaignDailyBudget: z123.number().int().positive().optional(),
|
|
28993
|
+
adSets: z123.array(z123.object({
|
|
28994
|
+
tempId: z123.string().min(1).max(80),
|
|
28995
|
+
name: z123.string().min(1).max(100),
|
|
28996
|
+
dailyBudget: z123.number().int().positive().optional(),
|
|
28997
|
+
creativeIds: z123.array(z123.string().min(1)).min(1)
|
|
28779
28998
|
})).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
|
|
28780
28999
|
/**
|
|
28781
29000
|
* Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
|
|
@@ -28783,17 +29002,17 @@ var GroupedCampaignConfigBase = z121.object({
|
|
|
28783
29002
|
* opaque `invalid_literal` and made the WhatsApp destination — supported by
|
|
28784
29003
|
* the API since #849 — unreachable from this tool.
|
|
28785
29004
|
*/
|
|
28786
|
-
destination:
|
|
28787
|
-
|
|
28788
|
-
type:
|
|
28789
|
-
landingUrl:
|
|
29005
|
+
destination: z123.discriminatedUnion("type", [
|
|
29006
|
+
z123.object({
|
|
29007
|
+
type: z123.literal("landing"),
|
|
29008
|
+
landingUrl: z123.string().url()
|
|
28790
29009
|
}),
|
|
28791
|
-
|
|
28792
|
-
type:
|
|
28793
|
-
phoneNumber:
|
|
29010
|
+
z123.object({
|
|
29011
|
+
type: z123.literal("whatsapp"),
|
|
29012
|
+
phoneNumber: z123.string().min(8).max(32)
|
|
28794
29013
|
})
|
|
28795
29014
|
]),
|
|
28796
|
-
saveAsDefault:
|
|
29015
|
+
saveAsDefault: z123.boolean().default(false),
|
|
28797
29016
|
budgetPolicy: MetaBudgetPolicy.optional()
|
|
28798
29017
|
});
|
|
28799
29018
|
function resolveBudgetMode(value) {
|
|
@@ -28807,7 +29026,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
28807
29026
|
const budgetMode = resolveBudgetMode(value);
|
|
28808
29027
|
if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
|
|
28809
29028
|
ctx.addIssue({
|
|
28810
|
-
code:
|
|
29029
|
+
code: z123.ZodIssueCode.custom,
|
|
28811
29030
|
path: [
|
|
28812
29031
|
"campaignDailyBudget"
|
|
28813
29032
|
],
|
|
@@ -28818,7 +29037,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
28818
29037
|
value.adSets.forEach((adSet, index) => {
|
|
28819
29038
|
if (adSet.dailyBudget === void 0) {
|
|
28820
29039
|
ctx.addIssue({
|
|
28821
|
-
code:
|
|
29040
|
+
code: z123.ZodIssueCode.custom,
|
|
28822
29041
|
path: [
|
|
28823
29042
|
"adSets",
|
|
28824
29043
|
index,
|
|
@@ -28833,28 +29052,33 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
28833
29052
|
...value,
|
|
28834
29053
|
budgetMode: resolveBudgetMode(value)
|
|
28835
29054
|
}));
|
|
28836
|
-
var PublishCreativesToMetaInputBase =
|
|
28837
|
-
creatives:
|
|
29055
|
+
var PublishCreativesToMetaInputBase = z123.object({
|
|
29056
|
+
creatives: z123.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
|
|
28838
29057
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
28839
|
-
portfolioId:
|
|
29058
|
+
portfolioId: z123.string().trim().min(1),
|
|
28840
29059
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
28841
|
-
pageId:
|
|
29060
|
+
pageId: z123.string().trim().min(1),
|
|
28842
29061
|
adAccountId: McpAdAccountId,
|
|
28843
|
-
pixelId:
|
|
28844
|
-
/** Required unless `campaignConfig.destination` is whatsapp
|
|
28845
|
-
*
|
|
28846
|
-
|
|
29062
|
+
pixelId: z123.string().min(1).optional(),
|
|
29063
|
+
/** Required unless `campaignConfig.destination` is whatsapp or a creative
|
|
29064
|
+
* comes from a task (the API then lands on the published service landing
|
|
29065
|
+
* of its service tasks) — see the superRefine below. Mirrors the API's
|
|
29066
|
+
* `FacebookCreateCampaignFromTasksBodySchema`. */
|
|
29067
|
+
landingUrl: z123.string().url().optional(),
|
|
28847
29068
|
/** ISO-2 code or resolvable country name — mirrors the API contract
|
|
28848
|
-
* (CountryIso2Schema), which normalizes names to alpha-2 at validation.
|
|
28849
|
-
|
|
28850
|
-
|
|
29069
|
+
* (CountryIso2Schema), which normalizes names to alpha-2 at validation.
|
|
29070
|
+
* Omitted: the brand country of its service tasks (the API answers
|
|
29071
|
+
* META_NO_TARGET_COUNTRY when it has none); "US" for products. */
|
|
29072
|
+
targetCountry: CountryIso2Schema.optional(),
|
|
29073
|
+
campaignName: z123.string().trim().min(1).max(100),
|
|
28851
29074
|
campaignConfig: GroupedCampaignConfig.optional()
|
|
28852
29075
|
});
|
|
28853
29076
|
var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
|
|
28854
29077
|
const destination = value.campaignConfig?.destination;
|
|
28855
|
-
|
|
29078
|
+
const hasTaskCreative = value.creatives.some((creative) => creative.source.type === "task");
|
|
29079
|
+
if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl && !hasTaskCreative) {
|
|
28856
29080
|
ctx.addIssue({
|
|
28857
|
-
code:
|
|
29081
|
+
code: z123.ZodIssueCode.custom,
|
|
28858
29082
|
path: [
|
|
28859
29083
|
"landingUrl"
|
|
28860
29084
|
],
|
|
@@ -28863,7 +29087,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
28863
29087
|
}
|
|
28864
29088
|
if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
|
|
28865
29089
|
ctx.addIssue({
|
|
28866
|
-
code:
|
|
29090
|
+
code: z123.ZodIssueCode.custom,
|
|
28867
29091
|
path: [
|
|
28868
29092
|
"campaignConfig",
|
|
28869
29093
|
"destination",
|
|
@@ -28882,16 +29106,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
28882
29106
|
}
|
|
28883
29107
|
return value;
|
|
28884
29108
|
});
|
|
28885
|
-
var PresignUploadResponseSchema =
|
|
28886
|
-
uploadUrl:
|
|
29109
|
+
var PresignUploadResponseSchema = z123.object({
|
|
29110
|
+
uploadUrl: z123.string().url().refine((value) => {
|
|
28887
29111
|
const url = new URL(value);
|
|
28888
29112
|
return !url.username && !url.password && url.protocol === "https:";
|
|
28889
29113
|
}, "presigned upload URL must be HTTPS without embedded credentials"),
|
|
28890
|
-
publicUrl:
|
|
29114
|
+
publicUrl: z123.string().url().refine((value) => {
|
|
28891
29115
|
const url = new URL(value);
|
|
28892
29116
|
return !url.username && !url.password;
|
|
28893
29117
|
}, "public media URL must not contain embedded credentials"),
|
|
28894
|
-
stagingAssetId:
|
|
29118
|
+
stagingAssetId: z123.string().uuid()
|
|
28895
29119
|
});
|
|
28896
29120
|
async function uploadResolvedMedia(api, media, assetRole) {
|
|
28897
29121
|
if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
|
|
@@ -28916,16 +29140,16 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
|
|
|
28916
29140
|
return uploadResolvedMedia(api, media, assetRole);
|
|
28917
29141
|
}
|
|
28918
29142
|
__name(resolveAndUploadMedia, "resolveAndUploadMedia");
|
|
28919
|
-
var TikTokInput =
|
|
28920
|
-
taskId:
|
|
28921
|
-
advertiserId:
|
|
28922
|
-
pixelId:
|
|
28923
|
-
landingUrl:
|
|
28924
|
-
angleIndexes:
|
|
29143
|
+
var TikTokInput = z123.object({
|
|
29144
|
+
taskId: z123.string().min(1),
|
|
29145
|
+
advertiserId: z123.string().min(1),
|
|
29146
|
+
pixelId: z123.string().min(1).optional(),
|
|
29147
|
+
landingUrl: z123.string().url().optional(),
|
|
29148
|
+
angleIndexes: z123.array(z123.number().int().nonnegative()).optional(),
|
|
28925
29149
|
campaignConfig: McpCampaignConfig.optional(),
|
|
28926
29150
|
/** Override the ad's description (TikTok's body copy). If omitted,
|
|
28927
29151
|
* ProductMaker uses the auto-generated copy attached to the task. */
|
|
28928
|
-
primaryText:
|
|
29152
|
+
primaryText: z123.string().trim().min(1).max(500).optional()
|
|
28929
29153
|
});
|
|
28930
29154
|
function registerPublishTools(server, api, opts = {}) {
|
|
28931
29155
|
const transport = opts.transport ?? "http";
|
|
@@ -29047,7 +29271,7 @@ function registerPublishTools(server, api, opts = {}) {
|
|
|
29047
29271
|
}
|
|
29048
29272
|
});
|
|
29049
29273
|
server.registerTool("publish_creatives_to_meta", {
|
|
29050
|
-
description: publishCreativesToMetaGuidance.summary + ' Publica tus creativos en Meta sin gastar cr\xE9ditos de ProductMaker. El presupuesto de anuncios se paga directamente desde tu cuenta de Meta. Crear creativos o copy con IA sigue usando cr\xE9ditos. Si la petici\xF3n natural adjunta o menciona archivos locales, llama primero `request_media_upload`; tras OK usa cada resultado como `source.type="asset"` con su `assetId` y el `type` que coincide con `mediaKind`. No pidas path ni URL. Despu\xE9s llama `list_meta_destinations` y pregunta en el chat por el `portfolioId`, `adAccountId` y `pageId` exactos; el App es solo para archivos. Si la carga fue parcial, conserva los assets confirmados, procesa s\xF3lo los pendientes y publica \xFAnicamente assets confirmados; nunca inventes assets ni superes diez creativos. Las rutas locales s\xF3lo funcionan con MCP stdio. Los medios propios se eliminan despu\xE9s de publicar correctamente; si falla antes de enviar una mutaci\xF3n a Meta, quedan durante el TTL. Para videos la miniatura es opcional y ProductMaker puede generarla con FFmpeg. `campaignConfig.destination` acepta landing o WhatsApp. Para landing basta `campaignConfig.destination.landingUrl`; no dupliques la URL arriba. Si omites `budgetMode`, se infiere `ad_set` cuando cada ad set trae `dailyBudget`, o `campaign` cuando env\xEDas `campaignDailyBudget`. No actives la campa\xF1a autom\xE1ticamente. Si el resultado es ambiguo, NO reenv\xEDes: revisa Meta Ads Manager.',
|
|
29274
|
+
description: publishCreativesToMetaGuidance.summary + ' Publica tus creativos en Meta sin gastar cr\xE9ditos de ProductMaker. El presupuesto de anuncios se paga directamente desde tu cuenta de Meta. Crear creativos o copy con IA sigue usando cr\xE9ditos. Si la petici\xF3n natural adjunta o menciona archivos locales, llama primero `request_media_upload`; tras OK usa cada resultado como `source.type="asset"` con su `assetId` y el `type` que coincide con `mediaKind`. No pidas path ni URL. Despu\xE9s llama `list_meta_destinations` y pregunta en el chat por el `portfolioId`, `adAccountId` y `pageId` exactos; el App es solo para archivos. Si la carga fue parcial, conserva los assets confirmados, procesa s\xF3lo los pendientes y publica \xFAnicamente assets confirmados; nunca inventes assets ni superes diez creativos. Las rutas locales s\xF3lo funcionan con MCP stdio. Los medios propios se eliminan despu\xE9s de publicar correctamente; si falla antes de enviar una mutaci\xF3n a Meta, quedan durante el TTL. Para videos la miniatura es opcional y ProductMaker puede generarla con FFmpeg. `campaignConfig.destination` acepta landing o WhatsApp. Para landing basta `campaignConfig.destination.landingUrl`; no dupliques la URL arriba. Con creativos de tarea de servicio puedes omitir `landingUrl` y `targetCountry`: se usan su landing de servicio publicada y el pa\xEDs de su marca; si falta alguno, pregunta al usuario (nunca asumas un pa\xEDs). Si omites `budgetMode`, se infiere `ad_set` cuando cada ad set trae `dailyBudget`, o `campaign` cuando env\xEDas `campaignDailyBudget`. No actives la campa\xF1a autom\xE1ticamente. Si el resultado es ambiguo, NO reenv\xEDes: revisa Meta Ads Manager.',
|
|
29051
29275
|
inputSchema: PublishCreativesToMetaInputBase.shape,
|
|
29052
29276
|
annotations: CREATES_EXTERNAL
|
|
29053
29277
|
}, async (rawInput, extra) => {
|
|
@@ -29277,39 +29501,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
|
|
|
29277
29501
|
|
|
29278
29502
|
// src/tools/meta-upload.ts
|
|
29279
29503
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
29280
|
-
import { z as
|
|
29504
|
+
import { z as z124 } from "zod";
|
|
29281
29505
|
var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
|
|
29282
|
-
var UploadSessionInputBase =
|
|
29283
|
-
mediaKind:
|
|
29506
|
+
var UploadSessionInputBase = z124.object({
|
|
29507
|
+
mediaKind: z124.enum([
|
|
29284
29508
|
"image",
|
|
29285
29509
|
"video",
|
|
29286
29510
|
"mixed"
|
|
29287
29511
|
]).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."),
|
|
29288
|
-
assetRole:
|
|
29512
|
+
assetRole: z124.enum([
|
|
29289
29513
|
"media",
|
|
29290
29514
|
"thumbnail"
|
|
29291
29515
|
]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
|
|
29292
|
-
uploadPurpose:
|
|
29516
|
+
uploadPurpose: z124.enum([
|
|
29293
29517
|
"product_reference",
|
|
29294
29518
|
"creative",
|
|
29295
29519
|
"generic"
|
|
29296
29520
|
]).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."),
|
|
29297
|
-
maxFiles:
|
|
29521
|
+
maxFiles: z124.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
29298
29522
|
});
|
|
29299
|
-
var OpenAiFileReference =
|
|
29300
|
-
download_url:
|
|
29301
|
-
file_id:
|
|
29302
|
-
mime_type:
|
|
29303
|
-
file_name:
|
|
29523
|
+
var OpenAiFileReference = z124.object({
|
|
29524
|
+
download_url: z124.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."),
|
|
29525
|
+
file_id: z124.string().min(1),
|
|
29526
|
+
mime_type: z124.string().min(1).optional(),
|
|
29527
|
+
file_name: z124.string().min(1).optional()
|
|
29304
29528
|
});
|
|
29305
29529
|
var UploadSessionToolInputShape = {
|
|
29306
29530
|
...UploadSessionInputBase.shape,
|
|
29307
|
-
files:
|
|
29531
|
+
files: z124.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.")
|
|
29308
29532
|
};
|
|
29309
|
-
var UploadSessionToolInput =
|
|
29533
|
+
var UploadSessionToolInput = z124.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
29310
29534
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
29311
29535
|
ctx.addIssue({
|
|
29312
|
-
code:
|
|
29536
|
+
code: z124.ZodIssueCode.custom,
|
|
29313
29537
|
path: [
|
|
29314
29538
|
"mediaKind"
|
|
29315
29539
|
],
|
|
@@ -29318,7 +29542,7 @@ var UploadSessionToolInput = z122.object(UploadSessionToolInputShape).superRefin
|
|
|
29318
29542
|
}
|
|
29319
29543
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
29320
29544
|
ctx.addIssue({
|
|
29321
|
-
code:
|
|
29545
|
+
code: z124.ZodIssueCode.custom,
|
|
29322
29546
|
path: [
|
|
29323
29547
|
"maxFiles"
|
|
29324
29548
|
],
|
|
@@ -29327,7 +29551,7 @@ var UploadSessionToolInput = z122.object(UploadSessionToolInputShape).superRefin
|
|
|
29327
29551
|
}
|
|
29328
29552
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
|
|
29329
29553
|
ctx.addIssue({
|
|
29330
|
-
code:
|
|
29554
|
+
code: z124.ZodIssueCode.custom,
|
|
29331
29555
|
path: [
|
|
29332
29556
|
"maxFiles"
|
|
29333
29557
|
],
|
|
@@ -29335,38 +29559,38 @@ var UploadSessionToolInput = z122.object(UploadSessionToolInputShape).superRefin
|
|
|
29335
29559
|
});
|
|
29336
29560
|
}
|
|
29337
29561
|
});
|
|
29338
|
-
var UploadSessionResponse =
|
|
29339
|
-
sessionId:
|
|
29340
|
-
uploadPageUrl:
|
|
29341
|
-
mediaKind:
|
|
29562
|
+
var UploadSessionResponse = z124.object({
|
|
29563
|
+
sessionId: z124.string().uuid(),
|
|
29564
|
+
uploadPageUrl: z124.string().url(),
|
|
29565
|
+
mediaKind: z124.enum([
|
|
29342
29566
|
"image",
|
|
29343
29567
|
"video",
|
|
29344
29568
|
"mixed"
|
|
29345
29569
|
]),
|
|
29346
|
-
assetRole:
|
|
29570
|
+
assetRole: z124.enum([
|
|
29347
29571
|
"media",
|
|
29348
29572
|
"thumbnail"
|
|
29349
29573
|
]),
|
|
29350
|
-
maxFiles:
|
|
29351
|
-
expiresAt:
|
|
29574
|
+
maxFiles: z124.number().int().positive(),
|
|
29575
|
+
expiresAt: z124.string().datetime()
|
|
29352
29576
|
});
|
|
29353
|
-
var UploadStatusInput =
|
|
29354
|
-
sessionId:
|
|
29577
|
+
var UploadStatusInput = z124.object({
|
|
29578
|
+
sessionId: z124.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
29355
29579
|
});
|
|
29356
|
-
var UniversalUploadStatusResponse =
|
|
29357
|
-
|
|
29358
|
-
status:
|
|
29359
|
-
assets:
|
|
29580
|
+
var UniversalUploadStatusResponse = z124.discriminatedUnion("status", [
|
|
29581
|
+
z124.object({
|
|
29582
|
+
status: z124.literal("pending"),
|
|
29583
|
+
assets: z124.array(z124.never()).length(0)
|
|
29360
29584
|
}),
|
|
29361
|
-
|
|
29362
|
-
status:
|
|
29363
|
-
assets:
|
|
29364
|
-
assetId:
|
|
29365
|
-
mediaKind:
|
|
29585
|
+
z124.object({
|
|
29586
|
+
status: z124.literal("uploaded"),
|
|
29587
|
+
assets: z124.array(z124.object({
|
|
29588
|
+
assetId: z124.string().uuid(),
|
|
29589
|
+
mediaKind: z124.enum([
|
|
29366
29590
|
"image",
|
|
29367
29591
|
"video"
|
|
29368
29592
|
]),
|
|
29369
|
-
assetRole:
|
|
29593
|
+
assetRole: z124.enum([
|
|
29370
29594
|
"media",
|
|
29371
29595
|
"thumbnail"
|
|
29372
29596
|
])
|
|
@@ -29374,13 +29598,13 @@ var UniversalUploadStatusResponse = z122.discriminatedUnion("status", [
|
|
|
29374
29598
|
})
|
|
29375
29599
|
]);
|
|
29376
29600
|
var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
|
|
29377
|
-
uploadPurpose:
|
|
29601
|
+
uploadPurpose: z124.enum([
|
|
29378
29602
|
"product_reference",
|
|
29379
29603
|
"creative",
|
|
29380
29604
|
"generic"
|
|
29381
29605
|
]),
|
|
29382
|
-
checkToolName:
|
|
29383
|
-
resolveEndpoint:
|
|
29606
|
+
checkToolName: z124.literal("check_media_upload"),
|
|
29607
|
+
resolveEndpoint: z124.string().url()
|
|
29384
29608
|
});
|
|
29385
29609
|
function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
|
|
29386
29610
|
const url = new URL(uploadPageUrl);
|
|
@@ -29471,15 +29695,15 @@ function registerMediaUploadTools(server, api) {
|
|
|
29471
29695
|
__name(registerMediaUploadTools, "registerMediaUploadTools");
|
|
29472
29696
|
|
|
29473
29697
|
// src/tools/campaigns.ts
|
|
29474
|
-
import { z as
|
|
29698
|
+
import { z as z125 } from "zod";
|
|
29475
29699
|
var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
|
|
29476
29700
|
var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
|
|
29477
|
-
var MetaStatusInput =
|
|
29478
|
-
campaignId:
|
|
29701
|
+
var MetaStatusInput = z125.object({
|
|
29702
|
+
campaignId: z125.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
|
|
29479
29703
|
});
|
|
29480
|
-
var TikTokStatusInput =
|
|
29481
|
-
campaignId:
|
|
29482
|
-
advertiserId:
|
|
29704
|
+
var TikTokStatusInput = z125.object({
|
|
29705
|
+
campaignId: z125.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
|
|
29706
|
+
advertiserId: z125.string().min(1).describe("The same advertiserId used to publish the campaign.")
|
|
29483
29707
|
});
|
|
29484
29708
|
function registerCampaignTools(server, api) {
|
|
29485
29709
|
server.registerTool("get_meta_campaign_status", {
|
|
@@ -29584,10 +29808,10 @@ function renderTikTokStatusMarkdown(r) {
|
|
|
29584
29808
|
__name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
|
|
29585
29809
|
|
|
29586
29810
|
// ../../packages/product-economics/src/product-costing.ts
|
|
29587
|
-
import { z as
|
|
29811
|
+
import { z as z127 } from "zod";
|
|
29588
29812
|
|
|
29589
29813
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
29590
|
-
import { z as
|
|
29814
|
+
import { z as z126 } from "zod";
|
|
29591
29815
|
|
|
29592
29816
|
// ../../packages/product-economics/src/product-costing-shipping-references.json
|
|
29593
29817
|
var product_costing_shipping_references_default = {
|
|
@@ -29651,21 +29875,21 @@ var product_costing_shipping_references_default = {
|
|
|
29651
29875
|
};
|
|
29652
29876
|
|
|
29653
29877
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
29654
|
-
var ShippingReferenceSchema =
|
|
29655
|
-
reference:
|
|
29656
|
-
min:
|
|
29657
|
-
max:
|
|
29658
|
-
updatedAt:
|
|
29659
|
-
confidence:
|
|
29878
|
+
var ShippingReferenceSchema = z126.object({
|
|
29879
|
+
reference: z126.number().positive(),
|
|
29880
|
+
min: z126.number().nonnegative(),
|
|
29881
|
+
max: z126.number().positive(),
|
|
29882
|
+
updatedAt: z126.string().date(),
|
|
29883
|
+
confidence: z126.enum([
|
|
29660
29884
|
"high",
|
|
29661
29885
|
"medium",
|
|
29662
29886
|
"medium-low"
|
|
29663
29887
|
]),
|
|
29664
|
-
sources:
|
|
29888
|
+
sources: z126.array(z126.string().url().startsWith("https://")).min(1).max(3)
|
|
29665
29889
|
}).superRefine(({ reference, min, max }, context) => {
|
|
29666
29890
|
if (min > reference || reference > max) {
|
|
29667
29891
|
context.addIssue({
|
|
29668
|
-
code:
|
|
29892
|
+
code: z126.ZodIssueCode.custom,
|
|
29669
29893
|
message: "shipping_reference_outside_range",
|
|
29670
29894
|
path: [
|
|
29671
29895
|
"reference"
|
|
@@ -29673,7 +29897,7 @@ var ShippingReferenceSchema = z124.object({
|
|
|
29673
29897
|
});
|
|
29674
29898
|
}
|
|
29675
29899
|
});
|
|
29676
|
-
var SHIPPING_REFERENCES =
|
|
29900
|
+
var SHIPPING_REFERENCES = z126.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
|
|
29677
29901
|
var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
|
|
29678
29902
|
var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
|
|
29679
29903
|
"MX",
|
|
@@ -29855,18 +30079,18 @@ function getProductCostingCountryName(country) {
|
|
|
29855
30079
|
__name(getProductCostingCountryName, "getProductCostingCountryName");
|
|
29856
30080
|
|
|
29857
30081
|
// ../../packages/product-economics/src/product-costing.ts
|
|
29858
|
-
var ProductCostingInputSchema =
|
|
29859
|
-
country:
|
|
29860
|
-
supplierCost:
|
|
29861
|
-
shippingCost:
|
|
29862
|
-
returnRate:
|
|
29863
|
-
cancellationRate:
|
|
29864
|
-
adsManagerCpa:
|
|
29865
|
-
desiredMargin:
|
|
30082
|
+
var ProductCostingInputSchema = z127.object({
|
|
30083
|
+
country: z127.string().refine(isProductCostingCountryCode, "unsupported_country"),
|
|
30084
|
+
supplierCost: z127.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
|
|
30085
|
+
shippingCost: z127.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
|
|
30086
|
+
returnRate: z127.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
30087
|
+
cancellationRate: z127.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
30088
|
+
adsManagerCpa: z127.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
|
|
30089
|
+
desiredMargin: z127.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
|
|
29866
30090
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
29867
30091
|
if (returnRate + cancellationRate >= 1) {
|
|
29868
30092
|
context.addIssue({
|
|
29869
|
-
code:
|
|
30093
|
+
code: z127.ZodIssueCode.custom,
|
|
29870
30094
|
message: "delivery_rate_positive",
|
|
29871
30095
|
path: [
|
|
29872
30096
|
"cancellationRate"
|
|
@@ -29963,15 +30187,15 @@ function calculateProductCosting(rawInput) {
|
|
|
29963
30187
|
__name(calculateProductCosting, "calculateProductCosting");
|
|
29964
30188
|
|
|
29965
30189
|
// src/tools/product-costing.ts
|
|
29966
|
-
import { z as
|
|
30190
|
+
import { z as z128 } from "zod";
|
|
29967
30191
|
var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
|
|
29968
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
29969
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
29970
|
-
var ProductCostingToolInput =
|
|
29971
|
-
country:
|
|
30192
|
+
var optionalAmount = /* @__PURE__ */ __name((description) => z128.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
|
|
30193
|
+
var optionalPercent = /* @__PURE__ */ __name((description) => z128.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
|
|
30194
|
+
var ProductCostingToolInput = z128.object({
|
|
30195
|
+
country: z128.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
29972
30196
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
29973
30197
|
}).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
|
|
29974
|
-
supplierCost:
|
|
30198
|
+
supplierCost: z128.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."),
|
|
29975
30199
|
supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
|
|
29976
30200
|
shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
|
|
29977
30201
|
shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
|
|
@@ -30134,7 +30358,7 @@ function formatPercent(value) {
|
|
|
30134
30358
|
__name(formatPercent, "formatPercent");
|
|
30135
30359
|
|
|
30136
30360
|
// src/tools/product-research.ts
|
|
30137
|
-
import { z as
|
|
30361
|
+
import { z as z129 } from "zod";
|
|
30138
30362
|
|
|
30139
30363
|
// src/tools/product-research-idempotency.ts
|
|
30140
30364
|
var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
|
|
@@ -30505,17 +30729,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
|
|
|
30505
30729
|
]);
|
|
30506
30730
|
var POLL_INTERVAL_MS = 5e3;
|
|
30507
30731
|
var MAX_WAIT_SECONDS = 120;
|
|
30508
|
-
var FindInput =
|
|
30732
|
+
var FindInput = z129.object({
|
|
30509
30733
|
targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
|
|
30510
30734
|
categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
|
|
30511
|
-
confirmed:
|
|
30512
|
-
waitSeconds:
|
|
30735
|
+
confirmed: z129.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
|
|
30736
|
+
waitSeconds: z129.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
|
|
30513
30737
|
});
|
|
30514
|
-
var GetInput =
|
|
30515
|
-
runId:
|
|
30738
|
+
var GetInput = z129.object({
|
|
30739
|
+
runId: z129.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
30516
30740
|
});
|
|
30517
|
-
var ListInput =
|
|
30518
|
-
limit:
|
|
30741
|
+
var ListInput = z129.object({
|
|
30742
|
+
limit: z129.number().int().min(1).max(20).default(10)
|
|
30519
30743
|
});
|
|
30520
30744
|
function textResult(text2) {
|
|
30521
30745
|
return {
|
|
@@ -30654,17 +30878,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
30654
30878
|
__name(registerProductResearchTools, "registerProductResearchTools");
|
|
30655
30879
|
|
|
30656
30880
|
// src/tools/dropshipping-projects.ts
|
|
30657
|
-
import { z as
|
|
30881
|
+
import { z as z130 } from "zod";
|
|
30658
30882
|
var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
|
|
30659
30883
|
var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
|
|
30660
30884
|
var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
|
|
30661
|
-
var ProjectId =
|
|
30662
|
-
var DropshippingProjectStatus =
|
|
30885
|
+
var ProjectId = z130.string().uuid();
|
|
30886
|
+
var DropshippingProjectStatus = z130.enum([
|
|
30663
30887
|
"active",
|
|
30664
30888
|
"completed",
|
|
30665
30889
|
"archived"
|
|
30666
30890
|
]);
|
|
30667
|
-
var DropshippingProjectPhase =
|
|
30891
|
+
var DropshippingProjectPhase = z130.enum([
|
|
30668
30892
|
"research",
|
|
30669
30893
|
"costing",
|
|
30670
30894
|
"media",
|
|
@@ -30673,21 +30897,21 @@ var DropshippingProjectPhase = z128.enum([
|
|
|
30673
30897
|
"advertising",
|
|
30674
30898
|
"complete"
|
|
30675
30899
|
]);
|
|
30676
|
-
var DropshippingRewardMilestone =
|
|
30900
|
+
var DropshippingRewardMilestone = z130.enum([
|
|
30677
30901
|
"product_selected",
|
|
30678
30902
|
"costing_saved",
|
|
30679
30903
|
"product_media_ready",
|
|
30680
30904
|
"creatives_completed",
|
|
30681
30905
|
"campaign_created"
|
|
30682
30906
|
]);
|
|
30683
|
-
var TargetCountry =
|
|
30907
|
+
var TargetCountry = z130.enum([
|
|
30684
30908
|
"CO",
|
|
30685
30909
|
"MX",
|
|
30686
30910
|
"PE",
|
|
30687
30911
|
"EC",
|
|
30688
30912
|
"CL"
|
|
30689
30913
|
]);
|
|
30690
|
-
var ResearchCategory =
|
|
30914
|
+
var ResearchCategory = z130.enum([
|
|
30691
30915
|
"auto",
|
|
30692
30916
|
"automotive",
|
|
30693
30917
|
"kitchen",
|
|
@@ -30702,7 +30926,7 @@ var ResearchCategory = z128.enum([
|
|
|
30702
30926
|
"garden",
|
|
30703
30927
|
"cleaning"
|
|
30704
30928
|
]);
|
|
30705
|
-
var HttpUrl3 =
|
|
30929
|
+
var HttpUrl3 = z130.string().url().max(2e3).refine((value) => {
|
|
30706
30930
|
try {
|
|
30707
30931
|
return [
|
|
30708
30932
|
"http:",
|
|
@@ -30712,45 +30936,45 @@ var HttpUrl3 = z128.string().url().max(2e3).refine((value) => {
|
|
|
30712
30936
|
return false;
|
|
30713
30937
|
}
|
|
30714
30938
|
}, "URL must use HTTP(S)");
|
|
30715
|
-
var ResearchCandidateOrigin =
|
|
30716
|
-
type:
|
|
30939
|
+
var ResearchCandidateOrigin = z130.object({
|
|
30940
|
+
type: z130.literal("research_candidate"),
|
|
30717
30941
|
runId: ProjectId,
|
|
30718
|
-
candidateSourceId:
|
|
30942
|
+
candidateSourceId: z130.string().min(1).max(160)
|
|
30719
30943
|
});
|
|
30720
|
-
var TaskOrigin =
|
|
30721
|
-
type:
|
|
30944
|
+
var TaskOrigin = z130.object({
|
|
30945
|
+
type: z130.literal("task"),
|
|
30722
30946
|
taskId: ProjectId
|
|
30723
30947
|
});
|
|
30724
|
-
var ManualOrigin =
|
|
30725
|
-
type:
|
|
30948
|
+
var ManualOrigin = z130.object({
|
|
30949
|
+
type: z130.literal("manual"),
|
|
30726
30950
|
clientRequestId: ProjectId,
|
|
30727
|
-
country:
|
|
30951
|
+
country: z130.string().min(2).max(3).optional()
|
|
30728
30952
|
});
|
|
30729
|
-
var StartProjectInput =
|
|
30730
|
-
origin:
|
|
30953
|
+
var StartProjectInput = z130.object({
|
|
30954
|
+
origin: z130.discriminatedUnion("type", [
|
|
30731
30955
|
ResearchCandidateOrigin,
|
|
30732
30956
|
TaskOrigin,
|
|
30733
30957
|
ManualOrigin
|
|
30734
30958
|
]),
|
|
30735
|
-
productName:
|
|
30959
|
+
productName: z130.string().trim().min(1).max(240).optional(),
|
|
30736
30960
|
productUrl: HttpUrl3.optional(),
|
|
30737
|
-
country:
|
|
30738
|
-
languageCode:
|
|
30961
|
+
country: z130.string().min(2).max(3).optional(),
|
|
30962
|
+
languageCode: z130.string().min(2).max(16).optional()
|
|
30739
30963
|
}).strict();
|
|
30740
|
-
var CostProjectInput =
|
|
30964
|
+
var CostProjectInput = z130.object({
|
|
30741
30965
|
projectId: ProjectId,
|
|
30742
|
-
version:
|
|
30743
|
-
country:
|
|
30966
|
+
version: z130.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
|
|
30967
|
+
country: z130.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
30744
30968
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
30745
30969
|
}).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
|
|
30746
|
-
supplierCost:
|
|
30747
|
-
shippingCost:
|
|
30748
|
-
returnRate:
|
|
30749
|
-
cancellationRate:
|
|
30750
|
-
adsManagerCpa:
|
|
30751
|
-
desiredMargin:
|
|
30752
|
-
});
|
|
30753
|
-
var GuideInput =
|
|
30970
|
+
supplierCost: z130.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."),
|
|
30971
|
+
shippingCost: z130.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
|
|
30972
|
+
returnRate: z130.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."),
|
|
30973
|
+
cancellationRate: z130.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."),
|
|
30974
|
+
adsManagerCpa: z130.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
30975
|
+
desiredMargin: z130.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
|
|
30976
|
+
});
|
|
30977
|
+
var GuideInput = z130.object({
|
|
30754
30978
|
projectId: ProjectId.optional()
|
|
30755
30979
|
}).strict();
|
|
30756
30980
|
var NEXT_ACTION_KINDS = [
|
|
@@ -30768,29 +30992,29 @@ var NEXT_ACTION_KINDS = [
|
|
|
30768
30992
|
"repair_meta_campaign",
|
|
30769
30993
|
"review_paused_campaign"
|
|
30770
30994
|
];
|
|
30771
|
-
var DropshippingProjectNextAction =
|
|
30772
|
-
kind:
|
|
30773
|
-
href:
|
|
30995
|
+
var DropshippingProjectNextAction = z130.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z130.object({
|
|
30996
|
+
kind: z130.literal(kind),
|
|
30997
|
+
href: z130.string().min(1)
|
|
30774
30998
|
})));
|
|
30775
|
-
var CostingInputSchema =
|
|
30776
|
-
country:
|
|
30777
|
-
supplierCost:
|
|
30778
|
-
shippingCost:
|
|
30779
|
-
returnRate:
|
|
30780
|
-
cancellationRate:
|
|
30781
|
-
adsManagerCpa:
|
|
30782
|
-
desiredMargin:
|
|
30999
|
+
var CostingInputSchema = z130.object({
|
|
31000
|
+
country: z130.string().min(2).max(3),
|
|
31001
|
+
supplierCost: z130.number().finite().positive(),
|
|
31002
|
+
shippingCost: z130.number().finite().nonnegative(),
|
|
31003
|
+
returnRate: z130.number().finite().min(0).lt(1),
|
|
31004
|
+
cancellationRate: z130.number().finite().min(0).lt(1),
|
|
31005
|
+
adsManagerCpa: z130.number().finite().nonnegative(),
|
|
31006
|
+
desiredMargin: z130.number().finite().min(0).lt(1)
|
|
30783
31007
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
30784
31008
|
if (returnRate + cancellationRate >= 1) context.addIssue({
|
|
30785
|
-
code:
|
|
31009
|
+
code: z130.ZodIssueCode.custom,
|
|
30786
31010
|
path: [
|
|
30787
31011
|
"cancellationRate"
|
|
30788
31012
|
]
|
|
30789
31013
|
});
|
|
30790
31014
|
});
|
|
30791
|
-
var FiniteCostingNumber =
|
|
30792
|
-
var CostingResultSchema =
|
|
30793
|
-
country:
|
|
31015
|
+
var FiniteCostingNumber = z130.number().finite();
|
|
31016
|
+
var CostingResultSchema = z130.object({
|
|
31017
|
+
country: z130.string().min(2).max(3),
|
|
30794
31018
|
deliveryRate: FiniteCostingNumber,
|
|
30795
31019
|
adjustedShippingCost: FiniteCostingNumber,
|
|
30796
31020
|
adjustedCpa: FiniteCostingNumber,
|
|
@@ -30803,45 +31027,45 @@ var CostingResultSchema = z128.object({
|
|
|
30803
31027
|
estimatedProfit: FiniteCostingNumber,
|
|
30804
31028
|
actualMargin: FiniteCostingNumber,
|
|
30805
31029
|
breakEvenAdsManagerCpa: FiniteCostingNumber,
|
|
30806
|
-
wasPriceAutoAdjusted:
|
|
30807
|
-
profitabilityStatus:
|
|
30808
|
-
});
|
|
30809
|
-
var RewardProgressSchema =
|
|
30810
|
-
campaignKey:
|
|
30811
|
-
totalCredits:
|
|
30812
|
-
earnedCredits:
|
|
30813
|
-
milestones:
|
|
31030
|
+
wasPriceAutoAdjusted: z130.boolean(),
|
|
31031
|
+
profitabilityStatus: z130.literal("healthy")
|
|
31032
|
+
});
|
|
31033
|
+
var RewardProgressSchema = z130.object({
|
|
31034
|
+
campaignKey: z130.literal("dropshipping-launch-v1"),
|
|
31035
|
+
totalCredits: z130.number().int().positive(),
|
|
31036
|
+
earnedCredits: z130.number().int().nonnegative(),
|
|
31037
|
+
milestones: z130.array(z130.object({
|
|
30814
31038
|
milestone: DropshippingRewardMilestone,
|
|
30815
|
-
credits:
|
|
30816
|
-
available:
|
|
30817
|
-
earned:
|
|
31039
|
+
credits: z130.number().int().positive(),
|
|
31040
|
+
available: z130.boolean().optional(),
|
|
31041
|
+
earned: z130.boolean(),
|
|
30818
31042
|
grantId: ProjectId.nullable(),
|
|
30819
|
-
grantedAt:
|
|
31043
|
+
grantedAt: z130.string().datetime().nullable()
|
|
30820
31044
|
})).length(DropshippingRewardMilestone.options.length)
|
|
30821
31045
|
});
|
|
30822
|
-
var ProjectResponseSchema =
|
|
31046
|
+
var ProjectResponseSchema = z130.object({
|
|
30823
31047
|
id: ProjectId,
|
|
30824
31048
|
taskId: ProjectId.nullable(),
|
|
30825
31049
|
status: DropshippingProjectStatus,
|
|
30826
|
-
originKey:
|
|
31050
|
+
originKey: z130.string().min(1),
|
|
30827
31051
|
researchRunId: ProjectId.nullable(),
|
|
30828
|
-
candidateSourceId:
|
|
30829
|
-
productName:
|
|
31052
|
+
candidateSourceId: z130.string().nullable(),
|
|
31053
|
+
productName: z130.string().nullable(),
|
|
30830
31054
|
productUrl: HttpUrl3.nullable(),
|
|
30831
31055
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
30832
|
-
targetCountry:
|
|
30833
|
-
languageCode:
|
|
30834
|
-
hasReferenceImage:
|
|
30835
|
-
hasWinnerReferenceImage:
|
|
31056
|
+
targetCountry: z130.string().nullable(),
|
|
31057
|
+
languageCode: z130.string().nullable(),
|
|
31058
|
+
hasReferenceImage: z130.boolean(),
|
|
31059
|
+
hasWinnerReferenceImage: z130.boolean(),
|
|
30836
31060
|
costingInput: CostingInputSchema.nullable(),
|
|
30837
31061
|
costingResult: CostingResultSchema.nullable(),
|
|
30838
|
-
costingVersion:
|
|
30839
|
-
version:
|
|
31062
|
+
costingVersion: z130.number().int().positive().nullable(),
|
|
31063
|
+
version: z130.number().int().positive(),
|
|
30840
31064
|
phase: DropshippingProjectPhase,
|
|
30841
31065
|
nextAction: DropshippingProjectNextAction.nullable(),
|
|
30842
31066
|
rewards: RewardProgressSchema,
|
|
30843
|
-
createdAt:
|
|
30844
|
-
updatedAt:
|
|
31067
|
+
createdAt: z130.string().datetime(),
|
|
31068
|
+
updatedAt: z130.string().datetime()
|
|
30845
31069
|
}).passthrough();
|
|
30846
31070
|
var NEXT_ACTION_GUIDANCE = {
|
|
30847
31071
|
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.",
|
|
@@ -30961,58 +31185,58 @@ function registerDropshippingProjectTools(server, api) {
|
|
|
30961
31185
|
__name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
|
|
30962
31186
|
|
|
30963
31187
|
// src/tools/daily-control.ts
|
|
30964
|
-
import { z as
|
|
31188
|
+
import { z as z131 } from "zod";
|
|
30965
31189
|
var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
|
|
30966
31190
|
var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
|
|
30967
31191
|
var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
|
|
30968
|
-
var ProviderCampaignIdentifier =
|
|
30969
|
-
var DateOnly =
|
|
30970
|
-
var DailyControlInput =
|
|
31192
|
+
var ProviderCampaignIdentifier = z131.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
|
|
31193
|
+
var DateOnly = z131.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
31194
|
+
var DailyControlInput = z131.object({
|
|
30971
31195
|
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."),
|
|
30972
|
-
days:
|
|
30973
|
-
projectId:
|
|
31196
|
+
days: z131.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
31197
|
+
projectId: z131.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
|
|
30974
31198
|
}).strict();
|
|
30975
|
-
var LinkCampaignInput =
|
|
30976
|
-
projectId:
|
|
30977
|
-
provider:
|
|
31199
|
+
var LinkCampaignInput = z131.object({
|
|
31200
|
+
projectId: z131.string().uuid(),
|
|
31201
|
+
provider: z131.enum([
|
|
30978
31202
|
"meta",
|
|
30979
31203
|
"tiktok"
|
|
30980
31204
|
]),
|
|
30981
31205
|
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."),
|
|
30982
31206
|
campaignId: ProviderCampaignIdentifier
|
|
30983
31207
|
}).strict();
|
|
30984
|
-
var ReportReturnsInput =
|
|
30985
|
-
projectId:
|
|
31208
|
+
var ReportReturnsInput = z131.object({
|
|
31209
|
+
projectId: z131.string().uuid(),
|
|
30986
31210
|
date: DateOnly,
|
|
30987
|
-
returnedOrders:
|
|
30988
|
-
note:
|
|
31211
|
+
returnedOrders: z131.number().int().min(0).max(1e5),
|
|
31212
|
+
note: z131.string().trim().max(280).optional()
|
|
30989
31213
|
}).strict();
|
|
30990
|
-
var DailyControlStatusMirror = DailyControlStatusEnum.or(
|
|
30991
|
-
var DailyControlLightMirror = DailyControlLightEnum.or(
|
|
30992
|
-
var DailyControlSourceMirror = DailyControlSourceEnum.or(
|
|
30993
|
-
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(
|
|
30994
|
-
var DailyControlDayMirror =
|
|
30995
|
-
date:
|
|
30996
|
-
returnedOrders:
|
|
31214
|
+
var DailyControlStatusMirror = DailyControlStatusEnum.or(z131.string());
|
|
31215
|
+
var DailyControlLightMirror = DailyControlLightEnum.or(z131.string());
|
|
31216
|
+
var DailyControlSourceMirror = DailyControlSourceEnum.or(z131.string());
|
|
31217
|
+
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z131.string());
|
|
31218
|
+
var DailyControlDayMirror = z131.object({
|
|
31219
|
+
date: z131.string(),
|
|
31220
|
+
returnedOrders: z131.number(),
|
|
30997
31221
|
returnedSource: DailyControlSourceMirror,
|
|
30998
31222
|
cancelledSource: DailyControlSourceMirror,
|
|
30999
|
-
hasEstimates:
|
|
31223
|
+
hasEstimates: z131.boolean(),
|
|
31000
31224
|
light: DailyControlLightMirror
|
|
31001
31225
|
}).passthrough();
|
|
31002
|
-
var DailyControlProductMirror =
|
|
31003
|
-
projectId:
|
|
31004
|
-
productName:
|
|
31226
|
+
var DailyControlProductMirror = z131.object({
|
|
31227
|
+
projectId: z131.string().uuid(),
|
|
31228
|
+
productName: z131.string().nullable(),
|
|
31005
31229
|
status: DailyControlStatusMirror,
|
|
31006
|
-
statusMessage:
|
|
31007
|
-
days:
|
|
31230
|
+
statusMessage: z131.string().nullable(),
|
|
31231
|
+
days: z131.array(DailyControlDayMirror),
|
|
31008
31232
|
verdict: DailyControlVerdictMirror.nullable(),
|
|
31009
|
-
rationale:
|
|
31233
|
+
rationale: z131.string().nullable()
|
|
31010
31234
|
}).passthrough();
|
|
31011
|
-
var DailyControlResponseMirror =
|
|
31012
|
-
since:
|
|
31013
|
-
until:
|
|
31014
|
-
products:
|
|
31015
|
-
archivedProjectSpend:
|
|
31235
|
+
var DailyControlResponseMirror = z131.object({
|
|
31236
|
+
since: z131.string(),
|
|
31237
|
+
until: z131.string(),
|
|
31238
|
+
products: z131.array(DailyControlProductMirror),
|
|
31239
|
+
archivedProjectSpend: z131.array(z131.unknown())
|
|
31016
31240
|
}).passthrough();
|
|
31017
31241
|
var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
|
|
31018
31242
|
function withWarnings(response) {
|
|
@@ -31087,7 +31311,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
|
|
|
31087
31311
|
// src/tools/product-control.ts
|
|
31088
31312
|
import { readFile, stat } from "fs/promises";
|
|
31089
31313
|
import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
|
|
31090
|
-
import { z as
|
|
31314
|
+
import { z as z132 } from "zod";
|
|
31091
31315
|
var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
|
|
31092
31316
|
var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
|
|
31093
31317
|
var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
|
|
@@ -31100,36 +31324,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
|
|
|
31100
31324
|
var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
|
|
31101
31325
|
var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
|
|
31102
31326
|
var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
|
|
31103
|
-
var DateOnly2 =
|
|
31327
|
+
var DateOnly2 = z132.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
31104
31328
|
var IMPORT_BATCH_MAX2 = 50;
|
|
31105
|
-
var ProductControlListInput =
|
|
31106
|
-
days:
|
|
31329
|
+
var ProductControlListInput = z132.object({
|
|
31330
|
+
days: z132.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
31107
31331
|
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."),
|
|
31108
|
-
shopDomain:
|
|
31332
|
+
shopDomain: z132.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
31109
31333
|
}).strict();
|
|
31110
|
-
var ImportableProductsInput =
|
|
31111
|
-
q:
|
|
31112
|
-
after:
|
|
31113
|
-
shopDomain:
|
|
31334
|
+
var ImportableProductsInput = z132.object({
|
|
31335
|
+
q: z132.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
|
|
31336
|
+
after: z132.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
|
|
31337
|
+
shopDomain: z132.string().min(1).optional()
|
|
31114
31338
|
}).strict();
|
|
31115
|
-
var ImportProductControlsInput =
|
|
31116
|
-
shopifyProductIds:
|
|
31339
|
+
var ImportProductControlsInput = z132.object({
|
|
31340
|
+
shopifyProductIds: z132.array(z132.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."),
|
|
31117
31341
|
// Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
|
|
31118
31342
|
// sin decir a cuál archivaría el producto bajo la tienda equivocada.
|
|
31119
|
-
shopDomain:
|
|
31343
|
+
shopDomain: z132.string().min(1)
|
|
31120
31344
|
}).strict();
|
|
31121
|
-
var SetProductCostingInput =
|
|
31122
|
-
shopDomain:
|
|
31123
|
-
shopifyProductId:
|
|
31124
|
-
targetCountry:
|
|
31125
|
-
supplierCost:
|
|
31126
|
-
shippingCost:
|
|
31127
|
-
returnRate:
|
|
31128
|
-
cancellationRate:
|
|
31345
|
+
var SetProductCostingInput = z132.object({
|
|
31346
|
+
shopDomain: z132.string().min(1),
|
|
31347
|
+
shopifyProductId: z132.string().min(1).max(64),
|
|
31348
|
+
targetCountry: z132.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
|
|
31349
|
+
supplierCost: z132.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
|
|
31350
|
+
shippingCost: z132.number().finite().nonnegative(),
|
|
31351
|
+
returnRate: z132.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
|
|
31352
|
+
cancellationRate: z132.number().finite().min(0).lt(1)
|
|
31129
31353
|
}).strict();
|
|
31130
|
-
var Count =
|
|
31131
|
-
var ReportProductCountsInput =
|
|
31132
|
-
productControlId:
|
|
31354
|
+
var Count = z132.number().int().min(0).max(1e5).nullable().optional();
|
|
31355
|
+
var ReportProductCountsInput = z132.object({
|
|
31356
|
+
productControlId: z132.string().uuid().describe("El identificador que devuelve get_product_control."),
|
|
31133
31357
|
date: DateOnly2,
|
|
31134
31358
|
orders: Count.describe("Pedidos que entraron ese d\xEDa."),
|
|
31135
31359
|
cancelledOrders: Count,
|
|
@@ -31139,36 +31363,36 @@ var ReportProductCountsInput = z130.object({
|
|
|
31139
31363
|
}).strict();
|
|
31140
31364
|
var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
|
|
31141
31365
|
var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
|
|
31142
|
-
var ImportOrdersFileInput =
|
|
31366
|
+
var ImportOrdersFileInput = z132.object({
|
|
31143
31367
|
/** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
|
|
31144
|
-
path:
|
|
31145
|
-
operationId:
|
|
31368
|
+
path: z132.string().min(1),
|
|
31369
|
+
operationId: z132.string().uuid().optional(),
|
|
31146
31370
|
/** Solo mirar: devuelve el resumen y no escribe nada. */
|
|
31147
|
-
dryRun:
|
|
31371
|
+
dryRun: z132.boolean().optional()
|
|
31148
31372
|
}).strict();
|
|
31149
|
-
var CreateOperationInput =
|
|
31150
|
-
countryCode:
|
|
31151
|
-
label:
|
|
31373
|
+
var CreateOperationInput = z132.object({
|
|
31374
|
+
countryCode: z132.string().length(2),
|
|
31375
|
+
label: z132.string().trim().min(1).max(60).optional()
|
|
31152
31376
|
}).strict();
|
|
31153
|
-
var MergeProductsInput =
|
|
31154
|
-
sourceId:
|
|
31155
|
-
targetId:
|
|
31377
|
+
var MergeProductsInput = z132.object({
|
|
31378
|
+
sourceId: z132.string().uuid(),
|
|
31379
|
+
targetId: z132.string().uuid()
|
|
31156
31380
|
}).strict();
|
|
31157
|
-
var SetMonthlyExpenseInput =
|
|
31158
|
-
month:
|
|
31381
|
+
var SetMonthlyExpenseInput = z132.object({
|
|
31382
|
+
month: z132.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
31159
31383
|
label: SaveMonthlyExpenseSchema.shape.label,
|
|
31160
|
-
amount:
|
|
31161
|
-
operationId:
|
|
31384
|
+
amount: z132.number().finite().min(0),
|
|
31385
|
+
operationId: z132.string().uuid().optional()
|
|
31162
31386
|
}).strict();
|
|
31163
|
-
var SetAdSpendInput =
|
|
31164
|
-
month:
|
|
31165
|
-
operationId:
|
|
31387
|
+
var SetAdSpendInput = z132.object({
|
|
31388
|
+
month: z132.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
31389
|
+
operationId: z132.string().uuid().optional(),
|
|
31166
31390
|
/** null RETIRA la corrección; cero afirma que no pautó. */
|
|
31167
|
-
amount:
|
|
31391
|
+
amount: z132.number().finite().min(0).nullable()
|
|
31168
31392
|
}).strict();
|
|
31169
|
-
var GetFinancesInput =
|
|
31170
|
-
month:
|
|
31171
|
-
operationId:
|
|
31393
|
+
var GetFinancesInput = z132.object({
|
|
31394
|
+
month: z132.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."),
|
|
31395
|
+
operationId: z132.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
|
|
31172
31396
|
}).strict();
|
|
31173
31397
|
function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
31174
31398
|
server.registerTool("get_product_control", {
|
|
@@ -31360,28 +31584,28 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
|
31360
31584
|
__name(registerProductControlTools, "registerProductControlTools");
|
|
31361
31585
|
|
|
31362
31586
|
// src/tools/market-study-estimate.ts
|
|
31363
|
-
import { z as
|
|
31587
|
+
import { z as z133 } from "zod";
|
|
31364
31588
|
var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
|
|
31365
|
-
var ProductTaskOutputEnum =
|
|
31589
|
+
var ProductTaskOutputEnum = z133.enum([
|
|
31366
31590
|
"landing",
|
|
31367
31591
|
"video",
|
|
31368
31592
|
"image"
|
|
31369
31593
|
]);
|
|
31370
|
-
var EstimateMarketStudyInput =
|
|
31371
|
-
kind:
|
|
31594
|
+
var EstimateMarketStudyInput = z133.object({
|
|
31595
|
+
kind: z133.enum([
|
|
31372
31596
|
"video",
|
|
31373
31597
|
"product_task"
|
|
31374
31598
|
]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
|
|
31375
|
-
videoAngleCount:
|
|
31376
|
-
durationSeconds:
|
|
31599
|
+
videoAngleCount: z133.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
|
|
31600
|
+
durationSeconds: z133.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
|
|
31377
31601
|
videoStructure: VideoStructureEnum.default("single_take"),
|
|
31378
31602
|
videoQuality: VideoQualityEnum.default("economy"),
|
|
31379
31603
|
videoResolution: VideoResolutionEnum.default("480p"),
|
|
31380
|
-
productImageCount:
|
|
31604
|
+
productImageCount: z133.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
|
|
31381
31605
|
outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
|
|
31382
|
-
generateAiMusic:
|
|
31606
|
+
generateAiMusic: z133.boolean().optional(),
|
|
31383
31607
|
generateAiEdit: AiEditRequestSchema.optional(),
|
|
31384
|
-
replicateWinnerWhenFound:
|
|
31608
|
+
replicateWinnerWhenFound: z133.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.")
|
|
31385
31609
|
}).strict();
|
|
31386
31610
|
function buildMarketStudyEstimateRequests(input) {
|
|
31387
31611
|
const quotesVideo = input.kind === "video" || (input.outputs ?? [
|