@productmaker/mcp 12.4.1 → 12.6.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 +1 -0
- package/dist/http.js +434 -21
- package/dist/stdio.js +434 -21
- package/package.json +1 -1
package/dist/stdio.js
CHANGED
|
@@ -2090,6 +2090,15 @@ var DEFAULT_PRICING = {
|
|
|
2090
2090
|
ourCostCents: 0.01,
|
|
2091
2091
|
userPriceCents: 0.02
|
|
2092
2092
|
},
|
|
2093
|
+
// OpenAI Decisions same-product check of DropKiller listings (market formats study),
|
|
2094
|
+
// per 1,000 input tokens. Decisions has no price row of its own; it bills as its
|
|
2095
|
+
// model, gpt-6-luna: $0.10/1M input (https://developers.openai.com/api/docs/pricing,
|
|
2096
|
+
// 2026-11-02). Answers are closed choices, so output is negligible. Cost-only:
|
|
2097
|
+
// the seller is not charged, the fixed study quote absorbs it.
|
|
2098
|
+
"openai:competitor-listing-decision": {
|
|
2099
|
+
ourCostCents: 0.01,
|
|
2100
|
+
userPriceCents: 0
|
|
2101
|
+
},
|
|
2093
2102
|
// Full competitor-source transcript used by the flat-price Frankenstein bundle.
|
|
2094
2103
|
"openai:frankenstein-source-transcribe": {
|
|
2095
2104
|
ourCostCents: 0.01,
|
|
@@ -2251,6 +2260,19 @@ var DEFAULT_PRICING = {
|
|
|
2251
2260
|
ourCostCents: 1,
|
|
2252
2261
|
userPriceCents: 2
|
|
2253
2262
|
},
|
|
2263
|
+
// Market formats read each competitor ad by its medium. Video: Gemini over
|
|
2264
|
+
// the whole ad with audio, measured 1.641¢ avg / 2.071¢ max over 60 local
|
|
2265
|
+
// analyses (6.9k in / 3.0k out tokens, 2026-11-04). Image: one still with the
|
|
2266
|
+
// same prompt, estimated (~4.2k in / ~2k out) — no producer until image ads
|
|
2267
|
+
// are analyzed. Frames (the key above) stays the flag-off and fallback leg.
|
|
2268
|
+
"openrouter:market-ad-video-analysis": {
|
|
2269
|
+
ourCostCents: 1.65,
|
|
2270
|
+
userPriceCents: 3.3
|
|
2271
|
+
},
|
|
2272
|
+
"openrouter:market-ad-image-analysis": {
|
|
2273
|
+
ourCostCents: 1.1,
|
|
2274
|
+
userPriceCents: 2.2
|
|
2275
|
+
},
|
|
2254
2276
|
"openrouter:competitor-commercial-dossier": {
|
|
2255
2277
|
ourCostCents: 5,
|
|
2256
2278
|
userPriceCents: 10
|
|
@@ -3868,6 +3890,13 @@ var AiEditWinnerOverlayItemSchema = z5.object({
|
|
|
3868
3890
|
/** Target-truth field ids backing `text` (from the adaptation plan). */
|
|
3869
3891
|
truthSourceIds: z5.array(z5.string().min(1).max(200)).max(16).optional()
|
|
3870
3892
|
}).strict();
|
|
3893
|
+
var AiEditDeliveredExecutionSchema = z5.object({
|
|
3894
|
+
taskId: z5.string().min(1).max(200),
|
|
3895
|
+
angleKey: z5.string().min(1).max(200),
|
|
3896
|
+
creativeRevision: z5.string().min(1).max(200),
|
|
3897
|
+
planHash: z5.string().min(1).max(200),
|
|
3898
|
+
outputHash: z5.string().min(1).max(200)
|
|
3899
|
+
}).strict();
|
|
3871
3900
|
var AiEditWinnerOverlaysSchema = z5.object({
|
|
3872
3901
|
version: z5.literal(1),
|
|
3873
3902
|
source: z5.object({
|
|
@@ -3877,13 +3906,7 @@ var AiEditWinnerOverlaysSchema = z5.object({
|
|
|
3877
3906
|
adaptationPlanRevision: z5.string().regex(/^[a-f0-9]{64}$/).optional()
|
|
3878
3907
|
}).strict(),
|
|
3879
3908
|
/** The delivered execution this plan was fitted against. */
|
|
3880
|
-
current:
|
|
3881
|
-
taskId: z5.string().min(1).max(200),
|
|
3882
|
-
angleKey: z5.string().min(1).max(200),
|
|
3883
|
-
creativeRevision: z5.string().min(1).max(200),
|
|
3884
|
-
planHash: z5.string().min(1).max(200),
|
|
3885
|
-
outputHash: z5.string().min(1).max(200)
|
|
3886
|
-
}).strict(),
|
|
3909
|
+
current: AiEditDeliveredExecutionSchema,
|
|
3887
3910
|
items: z5.array(AiEditWinnerOverlayItemSchema).max(64),
|
|
3888
3911
|
omitted: z5.array(z5.object({
|
|
3889
3912
|
id: z5.string().min(1).max(200),
|
|
@@ -3899,12 +3922,46 @@ var AiEditWinnerOverlaysSchema = z5.object({
|
|
|
3899
3922
|
])
|
|
3900
3923
|
}).strict()).max(64)
|
|
3901
3924
|
}).strict();
|
|
3925
|
+
var AiEditMarketFormatOverlaysSchema = z5.object({
|
|
3926
|
+
version: z5.literal(1),
|
|
3927
|
+
source: z5.object({
|
|
3928
|
+
formatId: z5.string().min(1).max(200),
|
|
3929
|
+
anchorSourceId: z5.string().min(1).max(200),
|
|
3930
|
+
contextHash: z5.string().min(1).max(200)
|
|
3931
|
+
}).strict(),
|
|
3932
|
+
current: AiEditDeliveredExecutionSchema,
|
|
3933
|
+
/** The format's look and editing pace, for the overlay style. */
|
|
3934
|
+
style: z5.object({
|
|
3935
|
+
visualStyle: z5.string().max(600),
|
|
3936
|
+
editingPace: z5.string().max(300).optional()
|
|
3937
|
+
}).strict(),
|
|
3938
|
+
items: z5.array(z5.object({
|
|
3939
|
+
formatBeatIndex: z5.number().int().nonnegative(),
|
|
3940
|
+
beat: z5.string().max(200),
|
|
3941
|
+
sourceText: z5.string().min(1).max(400),
|
|
3942
|
+
target: z5.object({
|
|
3943
|
+
sceneId: z5.string().min(1).max(200),
|
|
3944
|
+
beatIds: z5.array(z5.string().min(1).max(200)).max(16),
|
|
3945
|
+
startSec: z5.number().finite().nonnegative(),
|
|
3946
|
+
endSec: z5.number().finite().nonnegative()
|
|
3947
|
+
}).strict()
|
|
3948
|
+
}).strict()).max(10),
|
|
3949
|
+
omitted: z5.array(z5.object({
|
|
3950
|
+
formatBeatIndex: z5.number().int().nonnegative(),
|
|
3951
|
+
reason: z5.enum([
|
|
3952
|
+
"unmapped_beat",
|
|
3953
|
+
"unfitted_interval"
|
|
3954
|
+
])
|
|
3955
|
+
}).strict()).max(10)
|
|
3956
|
+
}).strict();
|
|
3902
3957
|
var AiEditBriefSchema = z5.object({
|
|
3903
3958
|
script: z5.string(),
|
|
3904
3959
|
words: z5.array(AiEditWordSchema),
|
|
3905
3960
|
sceneCutsSec: z5.array(z5.number().min(0)),
|
|
3906
3961
|
/** Optional winner-overlay adaptation plan; absent without winner+edit consent. */
|
|
3907
|
-
winnerOverlays: AiEditWinnerOverlaysSchema.optional()
|
|
3962
|
+
winnerOverlays: AiEditWinnerOverlaysSchema.optional(),
|
|
3963
|
+
/** Optional market-format overlays; absent without an applied format. */
|
|
3964
|
+
marketFormatOverlays: AiEditMarketFormatOverlaysSchema.optional()
|
|
3908
3965
|
});
|
|
3909
3966
|
var AiEditOutputsSchema = z5.object({
|
|
3910
3967
|
editKey: z5.string(),
|
|
@@ -5054,8 +5111,11 @@ var COUNTRY_NAME_TO_ISO2 = {
|
|
|
5054
5111
|
var COUNTRY_NAME_ALIASES = {
|
|
5055
5112
|
usa: "united states",
|
|
5056
5113
|
"estados unidos": "united states",
|
|
5114
|
+
estadosunidos: "united states",
|
|
5115
|
+
unitedstates: "united states",
|
|
5057
5116
|
uk: "united kingdom",
|
|
5058
5117
|
"reino unido": "united kingdom",
|
|
5118
|
+
unitedkingdom: "united kingdom",
|
|
5059
5119
|
brasil: "brazil",
|
|
5060
5120
|
espana: "spain",
|
|
5061
5121
|
alemania: "germany",
|
|
@@ -5108,6 +5168,7 @@ function normalizeToIso2(value) {
|
|
|
5108
5168
|
return void 0;
|
|
5109
5169
|
}
|
|
5110
5170
|
__name(normalizeToIso2, "normalizeToIso2");
|
|
5171
|
+
var SUPPORTED_COUNTRY_ISO2 = new Set(Object.values(COUNTRY_NAME_TO_ISO2));
|
|
5111
5172
|
var CountryIso2Schema = z11.preprocess(
|
|
5112
5173
|
(value) => typeof value === "string" ? normalizeToIso2(value) ?? value : value,
|
|
5113
5174
|
// The regex rejects unresolvable 2-unit garbage ('$$', '💩') that would
|
|
@@ -5883,7 +5944,8 @@ var LANDING_STRATEGIES = [
|
|
|
5883
5944
|
var LandingStrategySchema = z14.enum(LANDING_STRATEGIES);
|
|
5884
5945
|
var SELECTABLE_LANDING_STRATEGIES = [
|
|
5885
5946
|
"classic",
|
|
5886
|
-
"social_proof"
|
|
5947
|
+
"social_proof",
|
|
5948
|
+
"pain_solution"
|
|
5887
5949
|
];
|
|
5888
5950
|
var SelectableLandingStrategySchema = z14.enum(SELECTABLE_LANDING_STRATEGIES);
|
|
5889
5951
|
var EffectiveLandingStrategySchema = LandingStrategySchema.exclude([
|
|
@@ -6164,6 +6226,13 @@ var CODE_LANDING_USAGE_VARIANTS = [
|
|
|
6164
6226
|
"steps"
|
|
6165
6227
|
];
|
|
6166
6228
|
var CodeLandingUsageVariantSchema = z16.enum(CODE_LANDING_USAGE_VARIANTS);
|
|
6229
|
+
var CODE_LANDING_BUY_BOX_FORMATS = [
|
|
6230
|
+
"classic",
|
|
6231
|
+
"benefits",
|
|
6232
|
+
"impact",
|
|
6233
|
+
"pop"
|
|
6234
|
+
];
|
|
6235
|
+
var CodeLandingBuyBoxFormatSchema = z16.enum(CODE_LANDING_BUY_BOX_FORMATS);
|
|
6167
6236
|
var CodeLandingRecipeVariantsSchema = z16.object({
|
|
6168
6237
|
hero: CodeLandingHeroVariantSchema,
|
|
6169
6238
|
"benefits-grid": CodeLandingBenefitsVariantSchema,
|
|
@@ -6204,7 +6273,8 @@ var CodeLandingRecipePlanFields = {
|
|
|
6204
6273
|
var CodeLandingRecipeProposalSchema = z16.object(CodeLandingRecipePlanFields).strict();
|
|
6205
6274
|
var CodeLandingRecipePlanObjectSchema = z16.object({
|
|
6206
6275
|
version: z16.literal(1),
|
|
6207
|
-
...CodeLandingRecipePlanFields
|
|
6276
|
+
...CodeLandingRecipePlanFields,
|
|
6277
|
+
buyBoxFormat: CodeLandingBuyBoxFormatSchema.optional()
|
|
6208
6278
|
}).strict();
|
|
6209
6279
|
function hasDuplicateIds(ids) {
|
|
6210
6280
|
return new Set(ids).size !== ids.length;
|
|
@@ -7651,6 +7721,13 @@ var CodeLandingCommerceSnapshotSchema = z23.object({
|
|
|
7651
7721
|
compareAtPrice: z23.string().trim().min(1).max(500).optional(),
|
|
7652
7722
|
/** Explicit removal survives projections that otherwise derive a comparison. */
|
|
7653
7723
|
compareAtPriceRemoved: z23.literal(true).optional(),
|
|
7724
|
+
/** Seller-confirmed prices by product option, never purchase quantities. */
|
|
7725
|
+
offerVariants: z23.array(z23.object({
|
|
7726
|
+
option: z23.string().trim().min(1).max(60),
|
|
7727
|
+
value: z23.string().trim().min(1).max(60),
|
|
7728
|
+
price: PublishCommerceValuesSchema.shape.unitPrice,
|
|
7729
|
+
compareAtPrice: PublishCommerceValuesSchema.shape.unitPrice.nullable().optional()
|
|
7730
|
+
}).strict()).max(20).optional(),
|
|
7654
7731
|
/** Confirmed offer facts before Shopify supplies real chargeable variants. */
|
|
7655
7732
|
offerPacks: z23.array(z23.object({
|
|
7656
7733
|
units: z23.number().int().min(2).max(99),
|
|
@@ -8428,6 +8505,16 @@ var LandingEditAttachmentDto = z23.object({
|
|
|
8428
8505
|
width: z23.number().int().positive().nullable(),
|
|
8429
8506
|
height: z23.number().int().positive().nullable()
|
|
8430
8507
|
});
|
|
8508
|
+
var ApplyLandingCarouselGifRequest = z23.object({
|
|
8509
|
+
attachmentId: z23.string().uuid(),
|
|
8510
|
+
expectedRevision: z23.number().int().nonnegative(),
|
|
8511
|
+
idempotencyKey: z23.string().uuid()
|
|
8512
|
+
}).strict();
|
|
8513
|
+
var ApplyLandingCarouselGifResponse = z23.object({
|
|
8514
|
+
artifact: CodeLandingArtifactSchema,
|
|
8515
|
+
appliedRevision: z23.number().int().positive(),
|
|
8516
|
+
replayed: z23.boolean()
|
|
8517
|
+
});
|
|
8431
8518
|
var UploadLandingEditAttachmentResponse = z23.object({
|
|
8432
8519
|
attachment: LandingEditAttachmentDto
|
|
8433
8520
|
});
|
|
@@ -10234,6 +10321,49 @@ var ObservedCommercialClaimSchema = z37.object({
|
|
|
10234
10321
|
"other"
|
|
10235
10322
|
])
|
|
10236
10323
|
}).strict();
|
|
10324
|
+
var CreativeFormatFramingSchema = z37.object({
|
|
10325
|
+
shotSize: z37.enum([
|
|
10326
|
+
"macro",
|
|
10327
|
+
"close_up",
|
|
10328
|
+
"medium",
|
|
10329
|
+
"wide"
|
|
10330
|
+
]),
|
|
10331
|
+
camera: z37.enum([
|
|
10332
|
+
"static",
|
|
10333
|
+
"handheld",
|
|
10334
|
+
"selfie",
|
|
10335
|
+
"moving"
|
|
10336
|
+
]),
|
|
10337
|
+
faceVisible: z37.boolean()
|
|
10338
|
+
}).strict();
|
|
10339
|
+
var CompetitorCreativeFormatSchema = z37.object({
|
|
10340
|
+
formatName: z37.string().trim().min(1).max(120),
|
|
10341
|
+
renderTechnique: z37.string().trim().min(1).max(300),
|
|
10342
|
+
visualWorld: z37.string().trim().min(1).max(600),
|
|
10343
|
+
protagonist: z37.string().trim().min(1).max(300),
|
|
10344
|
+
narrativeEngine: z37.string().trim().min(1).max(600),
|
|
10345
|
+
beats: z37.array(z37.object({
|
|
10346
|
+
atSec: z37.number().finite().nonnegative(),
|
|
10347
|
+
beat: z37.string().trim().min(1).max(200),
|
|
10348
|
+
/** What physically happens on camera, never its overlay text. */
|
|
10349
|
+
visual: z37.string().trim().min(1).max(400),
|
|
10350
|
+
/** Text, captions or graphics shown over that beat ("" = none). */
|
|
10351
|
+
onScreenText: z37.string().trim().max(400).optional()
|
|
10352
|
+
}).strict()).min(1).max(12),
|
|
10353
|
+
hookDevice: z37.string().trim().min(1).max(600),
|
|
10354
|
+
ctaDevice: z37.string().trim().min(1).max(600),
|
|
10355
|
+
productRole: z37.string().trim().min(1).max(600),
|
|
10356
|
+
tone: z37.string().trim().min(1).max(300),
|
|
10357
|
+
editingPace: z37.string().trim().min(1).max(300),
|
|
10358
|
+
confidence: z37.enum([
|
|
10359
|
+
"high",
|
|
10360
|
+
"medium",
|
|
10361
|
+
"low"
|
|
10362
|
+
]),
|
|
10363
|
+
/** ISO 639-1 of the spoken words, or "none" without speech. */
|
|
10364
|
+
spokenLanguage: z37.string().trim().toLowerCase().regex(/^(?:[a-z]{2}|none)$/).optional(),
|
|
10365
|
+
framing: CreativeFormatFramingSchema.optional()
|
|
10366
|
+
}).strict();
|
|
10237
10367
|
var CompetitorCommercialProfileSchema = z37.object({
|
|
10238
10368
|
durationSec: z37.number().finite().positive(),
|
|
10239
10369
|
transcript: z37.string().max(2e4).optional(),
|
|
@@ -10259,7 +10389,9 @@ var CompetitorCommercialProfileSchema = z37.object({
|
|
|
10259
10389
|
"incompatible",
|
|
10260
10390
|
"uncertain"
|
|
10261
10391
|
]).optional(),
|
|
10262
|
-
marketRelevanceEvidence: z37.string().trim().min(1).max(1e3).optional()
|
|
10392
|
+
marketRelevanceEvidence: z37.string().trim().min(1).max(1e3).optional(),
|
|
10393
|
+
/** Requested only for market-format studies; absent on every other path. */
|
|
10394
|
+
creativeFormat: CompetitorCreativeFormatSchema.optional()
|
|
10263
10395
|
}).strict();
|
|
10264
10396
|
var MarketSceneIntentSchema = z37.object({
|
|
10265
10397
|
id: z37.string().trim().min(1).max(80),
|
|
@@ -10317,6 +10449,99 @@ var CommercialMarketDossierSchema = z37.object({
|
|
|
10317
10449
|
recipes: z37.array(MarketCreativeRecipeSchema).length(3),
|
|
10318
10450
|
evidenceDisclaimer: z37.string().trim().min(1).max(1e3)
|
|
10319
10451
|
}).strict();
|
|
10452
|
+
var MarketVoiceLineSchema = z37.object({
|
|
10453
|
+
/** Quoted exactly as spoken in the source transcript, original language. */
|
|
10454
|
+
text: z37.string().trim().min(1).max(400),
|
|
10455
|
+
sourceId: z37.string().trim().min(1)
|
|
10456
|
+
}).strict();
|
|
10457
|
+
var MarketFormatVoiceSchema = z37.object({
|
|
10458
|
+
hookLines: z37.array(MarketVoiceLineSchema).max(6),
|
|
10459
|
+
ctaLines: z37.array(MarketVoiceLineSchema).max(6),
|
|
10460
|
+
recurringPhrases: z37.array(z37.string().trim().min(1).max(200)).max(12),
|
|
10461
|
+
topics: z37.array(z37.string().trim().min(1).max(200)).max(10),
|
|
10462
|
+
rawness: z37.number().int().min(1).max(5)
|
|
10463
|
+
}).strict();
|
|
10464
|
+
var MarketFormatAnchorFrameSchema = z37.object({
|
|
10465
|
+
index: z37.number().int().min(0).max(3),
|
|
10466
|
+
assetKey: z37.string().trim().min(1).max(500),
|
|
10467
|
+
timestampSec: z37.number().finite().nonnegative()
|
|
10468
|
+
}).strict();
|
|
10469
|
+
var MarketFormatPacingSchema = z37.object({
|
|
10470
|
+
shotCount: z37.number().int().min(1).max(12),
|
|
10471
|
+
secondsPerShot: z37.number().finite().positive().max(600),
|
|
10472
|
+
editingPace: z37.string().trim().min(1).max(300).optional()
|
|
10473
|
+
}).strict();
|
|
10474
|
+
var MarketBeatExampleSchema = z37.object({
|
|
10475
|
+
visual: z37.string().trim().min(1).max(400),
|
|
10476
|
+
sourceId: z37.string().trim().min(1)
|
|
10477
|
+
}).strict();
|
|
10478
|
+
var MarketFormatDirectionSchema = z37.object({
|
|
10479
|
+
id: z37.string().trim().min(1).max(80),
|
|
10480
|
+
formatName: z37.string().trim().min(1).max(120),
|
|
10481
|
+
anchorSourceId: z37.string().trim().min(1),
|
|
10482
|
+
sourceIds: z37.array(z37.string().trim().min(1)).min(1).max(20),
|
|
10483
|
+
advertiserCount: z37.number().int().positive(),
|
|
10484
|
+
weightShare: z37.number().finite().min(0).max(1),
|
|
10485
|
+
advertiserShare: z37.number().finite().min(0).max(1),
|
|
10486
|
+
visualStyle: z37.string().trim().min(1).max(600),
|
|
10487
|
+
protagonist: z37.string().trim().min(1).max(300),
|
|
10488
|
+
narrative: z37.string().trim().min(1).max(600),
|
|
10489
|
+
storyLine: z37.string().trim().min(1).max(600),
|
|
10490
|
+
beats: z37.array(z37.object({
|
|
10491
|
+
beat: z37.string().trim().min(1).max(200),
|
|
10492
|
+
/** The on-camera action to stage (a CTA action included). */
|
|
10493
|
+
visual: z37.string().trim().min(1).max(600),
|
|
10494
|
+
/** Graphics for the optional edit ("" = none); never staged. */
|
|
10495
|
+
onScreenText: z37.string().trim().max(400).optional(),
|
|
10496
|
+
/** How different member ads stage this shared beat. */
|
|
10497
|
+
examples: z37.array(MarketBeatExampleSchema).max(4).optional()
|
|
10498
|
+
}).strict()).min(2).max(10),
|
|
10499
|
+
hook: z37.string().trim().min(1).max(600),
|
|
10500
|
+
cta: z37.string().trim().min(1).max(600),
|
|
10501
|
+
productRole: z37.string().trim().min(1).max(600),
|
|
10502
|
+
adaptToProduct: z37.string().trim().min(1).max(1e3),
|
|
10503
|
+
doNotCopy: z37.array(z37.string().trim().min(1).max(300)).max(10),
|
|
10504
|
+
whyThisFormat: z37.string().trim().min(1).max(1e3),
|
|
10505
|
+
voice: MarketFormatVoiceSchema.optional(),
|
|
10506
|
+
anchorFrames: z37.array(MarketFormatAnchorFrameSchema).max(4).optional(),
|
|
10507
|
+
/** Server-owned: the anchor ad's framing, binding for the director. */
|
|
10508
|
+
framing: CreativeFormatFramingSchema.optional(),
|
|
10509
|
+
/** Server-owned: the anchor ad's cut rhythm, binding for the director. */
|
|
10510
|
+
pacing: MarketFormatPacingSchema.optional(),
|
|
10511
|
+
/** Server-owned: no member speaks the target market's language. */
|
|
10512
|
+
languageFallback: z37.boolean().optional()
|
|
10513
|
+
}).strict();
|
|
10514
|
+
var MarketMenuItemSchema = z37.object({
|
|
10515
|
+
kind: z37.string().trim().min(1).max(120),
|
|
10516
|
+
description: z37.string().trim().min(1).max(400),
|
|
10517
|
+
lines: z37.array(MarketVoiceLineSchema).max(4).optional(),
|
|
10518
|
+
sourceIds: z37.array(z37.string().trim().min(1)).min(1).max(20),
|
|
10519
|
+
advertiserCount: z37.number().int().positive(),
|
|
10520
|
+
weightShare: z37.number().finite().min(0).max(1)
|
|
10521
|
+
}).strict();
|
|
10522
|
+
var MarketCreativeMenuSchema = z37.object({
|
|
10523
|
+
hooks: z37.array(MarketMenuItemSchema).max(6),
|
|
10524
|
+
ctas: z37.array(MarketMenuItemSchema).max(6),
|
|
10525
|
+
visualStyles: z37.array(MarketMenuItemSchema).max(6),
|
|
10526
|
+
demos: z37.array(MarketMenuItemSchema).max(8),
|
|
10527
|
+
rhythms: z37.array(MarketMenuItemSchema).max(4)
|
|
10528
|
+
}).strict();
|
|
10529
|
+
var MarketCreativeDirectionSchema = z37.object({
|
|
10530
|
+
version: z37.literal("1.0.0"),
|
|
10531
|
+
sourceSnapshotHash: z37.string().trim().min(1),
|
|
10532
|
+
evidenceSource: z37.enum([
|
|
10533
|
+
"dropkiller",
|
|
10534
|
+
"meta",
|
|
10535
|
+
"mixed"
|
|
10536
|
+
]),
|
|
10537
|
+
analyzedVideoCount: z37.number().int().positive(),
|
|
10538
|
+
advertiserCount: z37.number().int().positive(),
|
|
10539
|
+
/** Dropi units sold in 30 days across confirmed listings, when known. */
|
|
10540
|
+
productSoldUnits30d: z37.number().int().nonnegative().optional(),
|
|
10541
|
+
formats: z37.array(MarketFormatDirectionSchema).min(1).max(3),
|
|
10542
|
+
/** The market's recurring hooks, CTAs, styles, demos and rhythms. */
|
|
10543
|
+
menu: MarketCreativeMenuSchema.optional()
|
|
10544
|
+
}).strict();
|
|
10320
10545
|
var MarketPersuasionDeviceSchema = z37.object({
|
|
10321
10546
|
/** Verbatim hook/CTA/market pattern from the persisted dossier. */
|
|
10322
10547
|
sourcePattern: z37.string().trim().min(1).max(1e3),
|
|
@@ -10525,6 +10750,24 @@ var CreativeEngineWinnerContextSchema = z38.object({
|
|
|
10525
10750
|
}).strict()).max(24)
|
|
10526
10751
|
}).strict().optional()
|
|
10527
10752
|
}).strict();
|
|
10753
|
+
var CreativeEngineMarketPickSchema = z38.object({
|
|
10754
|
+
kind: z38.string().trim().min(1).max(120),
|
|
10755
|
+
description: z38.string().trim().min(1).max(400),
|
|
10756
|
+
/** A verbatim market line to adapt (hooks and CTAs). */
|
|
10757
|
+
line: z38.string().trim().min(1).max(400).optional(),
|
|
10758
|
+
sourceId: id2
|
|
10759
|
+
}).strict();
|
|
10760
|
+
var CreativeEngineMarketSelectionSchema = z38.object({
|
|
10761
|
+
version: z38.literal(1),
|
|
10762
|
+
formatId: id2,
|
|
10763
|
+
/** The member ad shown as one example of the format, never a template. */
|
|
10764
|
+
exampleSourceId: id2,
|
|
10765
|
+
hook: CreativeEngineMarketPickSchema.optional(),
|
|
10766
|
+
cta: CreativeEngineMarketPickSchema.optional(),
|
|
10767
|
+
visualStyle: CreativeEngineMarketPickSchema.optional(),
|
|
10768
|
+
demo: CreativeEngineMarketPickSchema.optional(),
|
|
10769
|
+
rhythm: CreativeEngineMarketPickSchema.optional()
|
|
10770
|
+
}).strict();
|
|
10528
10771
|
var CreativeEngineMarketInputSchema = z38.object({
|
|
10529
10772
|
version: z38.literal(1),
|
|
10530
10773
|
/** The dossier's own snapshot hash (not necessarily hex-64). */
|
|
@@ -10553,7 +10796,22 @@ var CreativeEngineMarketInputSchema = z38.object({
|
|
|
10553
10796
|
])
|
|
10554
10797
|
}).strict()).max(64),
|
|
10555
10798
|
/** Validated when it names a recipe actually present in `recipes`. */
|
|
10556
|
-
marketRecipeId: id2.optional()
|
|
10799
|
+
marketRecipeId: id2.optional(),
|
|
10800
|
+
/**
|
|
10801
|
+
* Market formats flag only: formats #1..#3 (HOW the video looks and flows)
|
|
10802
|
+
* with the anchor ad's transcript. Absent keeps the historical context.
|
|
10803
|
+
*/
|
|
10804
|
+
formats: z38.array(MarketFormatDirectionSchema.extend({
|
|
10805
|
+
anchorTranscript: z38.string().max(2e4).optional()
|
|
10806
|
+
}).strict()).min(1).max(3).optional(),
|
|
10807
|
+
/** The format the server binds; the director may drop to the next with a reason. */
|
|
10808
|
+
marketFormatId: id2.optional(),
|
|
10809
|
+
/**
|
|
10810
|
+
* Market formats only: the combination sampled for this creative by market
|
|
10811
|
+
* weight (format, hook, CTA, style, demo, example member), seeded by the
|
|
10812
|
+
* task so a retry repeats it and sibling creatives vary inside the market.
|
|
10813
|
+
*/
|
|
10814
|
+
marketSelection: CreativeEngineMarketSelectionSchema.optional()
|
|
10557
10815
|
}).strict();
|
|
10558
10816
|
var CreativeEngineCommercialExecutionSchema = z38.discriminatedUnion("mode", [
|
|
10559
10817
|
z38.object({
|
|
@@ -10562,7 +10820,17 @@ var CreativeEngineCommercialExecutionSchema = z38.discriminatedUnion("mode", [
|
|
|
10562
10820
|
mode: z38.literal("market"),
|
|
10563
10821
|
sourceSnapshotHash: z38.string().min(1).max(200),
|
|
10564
10822
|
recipeId: id2,
|
|
10565
|
-
sourceIds: z38.array(id2).min(1).max(64)
|
|
10823
|
+
sourceIds: z38.array(id2).min(1).max(64),
|
|
10824
|
+
/** The market format actually applied (context `market.formats` only). */
|
|
10825
|
+
formatId: id2.optional(),
|
|
10826
|
+
/** Each format beat mapped onto the authored scene/beats. */
|
|
10827
|
+
beatMap: z38.array(z38.object({
|
|
10828
|
+
formatBeatIndex: z38.number().int().nonnegative(),
|
|
10829
|
+
targetSceneId: id2,
|
|
10830
|
+
targetBeatIds: z38.array(id2).max(16)
|
|
10831
|
+
}).strict()).min(1).max(10).optional(),
|
|
10832
|
+
/** Required only when formatId is not the server-bound format. */
|
|
10833
|
+
formatFallbackReason: z38.string().min(1).max(500).optional()
|
|
10566
10834
|
}).strict(),
|
|
10567
10835
|
z38.object({
|
|
10568
10836
|
version: z38.literal(1),
|
|
@@ -11266,6 +11534,13 @@ var CreativeEngineRepairAuthorContractRetrySchema = z38.object({
|
|
|
11266
11534
|
requestedAtMs: z38.number().int().nonnegative(),
|
|
11267
11535
|
token: id2
|
|
11268
11536
|
}).strict();
|
|
11537
|
+
var CreativeEngineReplanAuthorContractRetrySchema = z38.object({
|
|
11538
|
+
failedOperationId: id2,
|
|
11539
|
+
planHash: hash,
|
|
11540
|
+
context: CreativeEngineContextBindingSchema,
|
|
11541
|
+
requestedAtMs: z38.number().int().nonnegative(),
|
|
11542
|
+
token: id2
|
|
11543
|
+
}).strict();
|
|
11269
11544
|
var CreativeEngineCompositionRepairSchema = z38.object({
|
|
11270
11545
|
reviewId: id2,
|
|
11271
11546
|
outputHash: hash,
|
|
@@ -11399,6 +11674,7 @@ var CreativeEngineStateSchema = z38.object({
|
|
|
11399
11674
|
token: id2
|
|
11400
11675
|
}).strict().optional(),
|
|
11401
11676
|
repairAuthorContractRetry: CreativeEngineRepairAuthorContractRetrySchema.optional(),
|
|
11677
|
+
replanAuthorContractRetry: CreativeEngineReplanAuthorContractRetrySchema.optional(),
|
|
11402
11678
|
final: CreativeEngineFinalSchema.optional()
|
|
11403
11679
|
}).strict().superRefine((state, ctx) => {
|
|
11404
11680
|
const repairAuthorContractRetry = state.repairAuthorContractRetry;
|
|
@@ -11557,6 +11833,13 @@ var CreativeEngineEventSchema = z38.discriminatedUnion("type", [
|
|
|
11557
11833
|
context: CreativeEngineContextBindingSchema,
|
|
11558
11834
|
token: id2
|
|
11559
11835
|
}).strict(),
|
|
11836
|
+
z38.object({
|
|
11837
|
+
type: z38.literal("replan_author_contract_retry_requested"),
|
|
11838
|
+
failedOperationId: id2,
|
|
11839
|
+
planHash: hash,
|
|
11840
|
+
context: CreativeEngineContextBindingSchema,
|
|
11841
|
+
token: id2
|
|
11842
|
+
}).strict(),
|
|
11560
11843
|
z38.object({
|
|
11561
11844
|
type: z38.literal("repair_author_contract_retry_requested"),
|
|
11562
11845
|
failedOperationId: id2,
|
|
@@ -11804,10 +12087,10 @@ import { z as z40 } from "zod";
|
|
|
11804
12087
|
var MAX_BILLING_DECIMAL_PLACES = 10;
|
|
11805
12088
|
function countDecimalPlaces(value) {
|
|
11806
12089
|
if (!Number.isFinite(value)) return MAX_BILLING_DECIMAL_PLACES + 1;
|
|
11807
|
-
|
|
12090
|
+
let normalized = value.toString();
|
|
11808
12091
|
if (/e/i.test(normalized)) {
|
|
11809
|
-
|
|
11810
|
-
|
|
12092
|
+
if (Math.abs(value) >= 1e21) return 0;
|
|
12093
|
+
normalized = value.toFixed(MAX_BILLING_DECIMAL_PLACES);
|
|
11811
12094
|
}
|
|
11812
12095
|
const parts = normalized.split(".");
|
|
11813
12096
|
if (parts.length < 2) return 0;
|
|
@@ -14350,6 +14633,8 @@ var CostEstimationRequest = z50.discriminatedUnion("type", [
|
|
|
14350
14633
|
var CostEstimationResponse = z50.object({
|
|
14351
14634
|
/** Server confirms the range includes the first generated classic-landing GIF. */
|
|
14352
14635
|
includesInitialLandingGif: z50.boolean().optional(),
|
|
14636
|
+
/** The initial-GIF choice is offerable for this config (code landings only quote it after explicit consent). */
|
|
14637
|
+
initialLandingGifOffered: z50.boolean().optional(),
|
|
14353
14638
|
estimatedCostCents: z50.number().nonnegative(),
|
|
14354
14639
|
estimatedCostCredits: z50.number().int().nonnegative(),
|
|
14355
14640
|
/** Scan-only midpoint; excludes generating a winner replica. Not an admission limit. */
|
|
@@ -15247,8 +15532,13 @@ var AdminQualityReportSummary = z53.object({
|
|
|
15247
15532
|
mixTaskId: z53.string().nullable(),
|
|
15248
15533
|
kind: QualityReportKind,
|
|
15249
15534
|
// Historical rows can contain `quality` in the DB's free-text reason column.
|
|
15535
|
+
// Support refunds can also contain `generation_failed`, presented as `other`.
|
|
15250
15536
|
// Normalize only on read; new submissions keep the strict QualityReportReason enum.
|
|
15251
|
-
reason: z53.preprocess((value) =>
|
|
15537
|
+
reason: z53.preprocess((value) => {
|
|
15538
|
+
if (value === "quality") return "unacceptable_quality";
|
|
15539
|
+
if (value === "generation_failed") return "other";
|
|
15540
|
+
return value;
|
|
15541
|
+
}, QualityReportReason),
|
|
15252
15542
|
status: QualityReportStatus,
|
|
15253
15543
|
estimatedCostCents: z53.number().nullable(),
|
|
15254
15544
|
refundedCents: z53.number().nullable(),
|
|
@@ -21292,6 +21582,24 @@ var CAPABILITY_MODEL_GUIDANCE = {
|
|
|
21292
21582
|
"solo lectura; un d\xEDa sin conteos usa la tasa estimada"
|
|
21293
21583
|
]
|
|
21294
21584
|
},
|
|
21585
|
+
get_product_ads: {
|
|
21586
|
+
summary: "Muestra cada anuncio (\xE1ngulo de venta) de un producto en un d\xEDa, con cifras de Meta y qu\xE9 hacer con \xE9l.",
|
|
21587
|
+
useWhen: [
|
|
21588
|
+
"cu\xE1l de mis anuncios est\xE1 vendiendo",
|
|
21589
|
+
"qu\xE9 anuncio apago",
|
|
21590
|
+
"c\xF3mo le fue a cada \xE1ngulo ayer"
|
|
21591
|
+
],
|
|
21592
|
+
avoidWhen: [
|
|
21593
|
+
"pregunta por el producto entero: get_product_control"
|
|
21594
|
+
],
|
|
21595
|
+
defaults: [
|
|
21596
|
+
"el id sale de get_product_control, nunca se inventa",
|
|
21597
|
+
"compras del p\xEDxel de Meta, no pedidos de la tienda"
|
|
21598
|
+
],
|
|
21599
|
+
disclosures: [
|
|
21600
|
+
"solo lectura; nunca pausa ni modifica un anuncio"
|
|
21601
|
+
]
|
|
21602
|
+
},
|
|
21295
21603
|
report_product_counts: {
|
|
21296
21604
|
summary: "Registra lo que de verdad pas\xF3 con un producto en un d\xEDa: pedidos, cancelados, entregados y devueltos.",
|
|
21297
21605
|
useWhen: [
|
|
@@ -22672,6 +22980,76 @@ var CreateManualProductControlResponseSchema = z100.object({
|
|
|
22672
22980
|
productControlId: z100.string().guid(),
|
|
22673
22981
|
created: z100.boolean()
|
|
22674
22982
|
});
|
|
22983
|
+
var ProductControlAdsQuerySchema = z100.object({
|
|
22984
|
+
date: z100.string().regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
22985
|
+
});
|
|
22986
|
+
var PRODUCT_CONTROL_AD_VERDICTS = [
|
|
22987
|
+
"keep",
|
|
22988
|
+
"turn_off",
|
|
22989
|
+
"review",
|
|
22990
|
+
"no_data"
|
|
22991
|
+
];
|
|
22992
|
+
var ProductControlAdVerdictSchema = z100.enum(PRODUCT_CONTROL_AD_VERDICTS);
|
|
22993
|
+
var PRODUCT_CONTROL_AD_REASONS = [
|
|
22994
|
+
"sells_within_break_even",
|
|
22995
|
+
"sells_above_break_even",
|
|
22996
|
+
"spent_break_even_without_sales",
|
|
22997
|
+
"low_spend_no_sales",
|
|
22998
|
+
"no_spend",
|
|
22999
|
+
"missing_break_even",
|
|
23000
|
+
"unknown_purchases",
|
|
23001
|
+
"different_time_zone"
|
|
23002
|
+
];
|
|
23003
|
+
var ProductControlAdReasonSchema = z100.enum(PRODUCT_CONTROL_AD_REASONS);
|
|
23004
|
+
var metric = z100.number().finite().nonnegative().nullable();
|
|
23005
|
+
var ProductControlAdSchema = z100.object({
|
|
23006
|
+
adId: z100.string(),
|
|
23007
|
+
campaignId: z100.string(),
|
|
23008
|
+
accountId: z100.string(),
|
|
23009
|
+
name: z100.string(),
|
|
23010
|
+
/** `effective_status` de Meta (ACTIVE, PAUSED, …), tal cual. */
|
|
23011
|
+
status: z100.string().nullable(),
|
|
23012
|
+
thumbnailUrl: z100.string().url().nullable(),
|
|
23013
|
+
creativeKind: z100.enum([
|
|
23014
|
+
"video",
|
|
23015
|
+
"image",
|
|
23016
|
+
"unknown"
|
|
23017
|
+
]),
|
|
23018
|
+
adsManagerUrl: z100.string().url(),
|
|
23019
|
+
spend: metric,
|
|
23020
|
+
impressions: metric,
|
|
23021
|
+
clicks: metric,
|
|
23022
|
+
ctr: metric,
|
|
23023
|
+
landingPageViews: metric,
|
|
23024
|
+
viewContent: metric,
|
|
23025
|
+
initiatedCheckout: metric,
|
|
23026
|
+
/** Compras del píxel (`offsite_conversion.fb_pixel_purchase`). */
|
|
23027
|
+
purchases: metric,
|
|
23028
|
+
costPerPurchase: metric,
|
|
23029
|
+
videoPlays: metric,
|
|
23030
|
+
videoP25: metric,
|
|
23031
|
+
videoP75: metric,
|
|
23032
|
+
videoP100: metric,
|
|
23033
|
+
/** p100 / reproducciones; `null` si no es vídeo o no hubo reproducciones. */
|
|
23034
|
+
completionRate: z100.number().finite().min(0).max(1).nullable(),
|
|
23035
|
+
verdict: ProductControlAdVerdictSchema,
|
|
23036
|
+
reason: ProductControlAdReasonSchema
|
|
23037
|
+
});
|
|
23038
|
+
var ProductControlAdsStatusSchema = z100.enum([
|
|
23039
|
+
"ok",
|
|
23040
|
+
"no_meta_campaign",
|
|
23041
|
+
"meta_not_connected",
|
|
23042
|
+
"unavailable"
|
|
23043
|
+
]);
|
|
23044
|
+
var ProductControlAdsResponseSchema = z100.object({
|
|
23045
|
+
productControlId: z100.string(),
|
|
23046
|
+
date: z100.string().regex(/^\d{4}-\d{2}-\d{2}$/),
|
|
23047
|
+
status: ProductControlAdsStatusSchema,
|
|
23048
|
+
currency: z100.string().nullable(),
|
|
23049
|
+
/** Publicidad máxima por compra para no perder (CPA de equilibrio). */
|
|
23050
|
+
breakEvenCpa: z100.number().finite().nonnegative().nullable(),
|
|
23051
|
+
ads: z100.array(ProductControlAdSchema)
|
|
23052
|
+
});
|
|
22675
23053
|
|
|
22676
23054
|
// ../../packages/types/src/productmaker-capability-registry.ts
|
|
22677
23055
|
var SHARED_CHANNEL_EXPOSURE = {
|
|
@@ -22952,7 +23330,8 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
22952
23330
|
// MCP 8.10.0: storyteller family blocked (BLOCKED_NARRATIVE_STYLES).
|
|
22953
23331
|
// MCP 9.1.0: combine current animated-video controls and initial GIF choice.
|
|
22954
23332
|
// MCP 12.4.0: landingStrategy narrowed to classic + social_proof.
|
|
22955
|
-
|
|
23333
|
+
// MCP 12.5.0: pain_solution restored to landingStrategy.
|
|
23334
|
+
"68a740d97238e720000c16db56ae5748ceb560e342f8fbfe605c954e6284fda7",
|
|
22956
23335
|
"credit_consuming",
|
|
22957
23336
|
"creative",
|
|
22958
23337
|
[
|
|
@@ -23398,7 +23777,8 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
23398
23777
|
defineCapability(
|
|
23399
23778
|
"generate_landing",
|
|
23400
23779
|
// MCP 12.4.0: guided landingStrategy narrowed to classic + social_proof.
|
|
23401
|
-
|
|
23780
|
+
// MCP 12.5.0: pain_solution restored to guided landingStrategy.
|
|
23781
|
+
"16c4e1ea0cd12ee3367e06b4f73a177c94e16ab7d5323d971d577301ba2c7b70",
|
|
23402
23782
|
"credit_consuming",
|
|
23403
23783
|
"creative",
|
|
23404
23784
|
[
|
|
@@ -24460,6 +24840,20 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
24460
24840
|
], [
|
|
24461
24841
|
"product_control_report"
|
|
24462
24842
|
]),
|
|
24843
|
+
defineCapability("get_product_ads", "df2873f9776f34f8a5a4c02b2878fbd6fb6ed1cfd9998cf728603b2bbd10069b", "none", "read_only", [
|
|
24844
|
+
"read"
|
|
24845
|
+
], [
|
|
24846
|
+
slot("product_control", true, [
|
|
24847
|
+
"productControlId"
|
|
24848
|
+
]),
|
|
24849
|
+
slot("day", true, [
|
|
24850
|
+
"date"
|
|
24851
|
+
])
|
|
24852
|
+
], [
|
|
24853
|
+
"product_control"
|
|
24854
|
+
], [
|
|
24855
|
+
"product_control_ads"
|
|
24856
|
+
], MCP_ONLY_CHANNEL_EXPOSURE),
|
|
24463
24857
|
defineCapability("report_product_counts", "8fa2561901b7743506a3639038d7806186c0512470bc6988a54c6bee5dbbb0b0", "state_change", "business", [
|
|
24464
24858
|
"state_change"
|
|
24465
24859
|
], [
|
|
@@ -29276,7 +29670,7 @@ var ApiClient = class {
|
|
|
29276
29670
|
};
|
|
29277
29671
|
|
|
29278
29672
|
// src/index.ts
|
|
29279
|
-
var MCP_VERSION = "12.
|
|
29673
|
+
var MCP_VERSION = "12.6.0";
|
|
29280
29674
|
|
|
29281
29675
|
// src/meta-upload-app.ts
|
|
29282
29676
|
import { readFileSync } from "fs";
|
|
@@ -33295,7 +33689,7 @@ var CreateProductTaskInput = z137.object({
|
|
|
33295
33689
|
creativeDirection: z137.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.'),
|
|
33296
33690
|
headline: z137.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."),
|
|
33297
33691
|
subheadline: z137.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."),
|
|
33298
|
-
landingStrategy: LandingStrategyEnum.optional().describe('Opcional. Estructura de la landing cl\xE1sica cuando landing est\xE1 entre outputs: "classic" (Landing cl\xE1sica de ProductMaker: estructura original probada y recomendada)
|
|
33692
|
+
landingStrategy: LandingStrategyEnum.optional().describe('Opcional. Estructura de la landing cl\xE1sica cuando landing est\xE1 entre outputs: "classic" (Landing cl\xE1sica de ProductMaker: estructura original probada y recomendada) , "social_proof" (Landing Viral: UGC, WhatsApp, Instagram y evidencia social) o "pain_solution" (Problema y soluci\xF3n: dolor reconocible, demostraci\xF3n y transformaci\xF3n). Default "classic".'),
|
|
33299
33693
|
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".')
|
|
33300
33694
|
}).strict();
|
|
33301
33695
|
var CreateServiceVideoInput = z137.object({
|
|
@@ -39371,6 +39765,7 @@ import { readFile, stat } from "fs/promises";
|
|
|
39371
39765
|
import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
|
|
39372
39766
|
import { z as z155 } from "zod";
|
|
39373
39767
|
var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
|
|
39768
|
+
var getProductAdsGuidance = getProductMakerCapabilityModelGuidance("get_product_ads");
|
|
39374
39769
|
var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
|
|
39375
39770
|
var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
|
|
39376
39771
|
var setProductCostingGuidance = getProductMakerCapabilityModelGuidance("set_product_costing");
|
|
@@ -39398,6 +39793,10 @@ var ProductControlListInput = z155.object({
|
|
|
39398
39793
|
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."),
|
|
39399
39794
|
shopDomain: z155.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
39400
39795
|
}).strict();
|
|
39796
|
+
var ProductAdsInput = z155.object({
|
|
39797
|
+
productControlId: z155.string().uuid().describe("El `productControlId` que devuelve get_product_control."),
|
|
39798
|
+
date: DateOnly2.describe("D\xEDa a leer (YYYY-MM-DD).")
|
|
39799
|
+
}).strict();
|
|
39401
39800
|
var ImportableProductsInput = z155.object({
|
|
39402
39801
|
q: z155.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
|
|
39403
39802
|
after: z155.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
|
|
@@ -39525,6 +39924,20 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
|
39525
39924
|
throw translateError(error);
|
|
39526
39925
|
}
|
|
39527
39926
|
});
|
|
39927
|
+
server.registerTool("get_product_ads", {
|
|
39928
|
+
description: getProductAdsGuidance.summary + " Devuelve cada anuncio de las campa\xF1as de Meta enlazadas al producto, con sus cifras DE META ese d\xEDa: gasto, impresiones, clics, CTR, visitas a la landing, view content, inicios de pago, compras del p\xEDxel, costo por compra y retenci\xF3n del v\xEDdeo (reproducciones, 25/75/100 % y `completionRate`). `verdict` es lo que la pantalla le sugiere: `keep` (mantener), `turn_off` (apagar), `review` (revisar) y `no_data` (todav\xEDa no hay con qu\xE9 juzgarlo); `reason` dice por qu\xE9, y el umbral es `breakEvenCpa`, la publicidad m\xE1xima por compra para no perder. Las compras del p\xEDxel NO son los pedidos de la tienda: el producto se decide con get_product_control y los anuncios se comparan entre s\xED con esto, porque un pedido contraentrega no dice de qu\xE9 anuncio vino. `status` distinto de `ok` no trae anuncios: `meta_not_connected` (conectar Meta), `no_meta_campaign` (enlazar campa\xF1a) o `unavailable` (Meta no respondi\xF3). Si falta un dato o Meta no respondi\xF3 y el usuario tiene su propio MCP de Meta, complementa ah\xED y di de d\xF3nde sale cada cifra. Es READ-ONLY: nunca pausa ni modifica un anuncio; apagar lo decide y lo hace ella en Meta.",
|
|
39929
|
+
inputSchema: ProductAdsInput.shape,
|
|
39930
|
+
annotations: READS_EXTERNAL
|
|
39931
|
+
}, async (input) => {
|
|
39932
|
+
try {
|
|
39933
|
+
const params = new URLSearchParams({
|
|
39934
|
+
date: input.date
|
|
39935
|
+
});
|
|
39936
|
+
return asText(await api.getJson(`/v1/product-control/${encodeURIComponent(input.productControlId)}/ads?${params.toString()}`));
|
|
39937
|
+
} catch (error) {
|
|
39938
|
+
throw translateError(error);
|
|
39939
|
+
}
|
|
39940
|
+
});
|
|
39528
39941
|
server.registerTool("get_finances", {
|
|
39529
39942
|
description: getFinancesGuidance.summary + ' Contesta la pregunta que de verdad importa --- \xABeste negocio gana plata?\xBB --- con el mes armado: ventas totales y entregadas, fletes, costo de los productos, utilidad bruta, publicidad, gastos fijos y utilidad NETA. Esa utilidad es ANTES de impuestos y hay que decirlo asi: el contador es un gasto mas, no un calculo nuestro. Trae tambien los porcentajes contra sus metas. Si `deliveredSalesKnown` no es true, faltan importes de ventas entregadas: la utilidad y los m\xE1rgenes no est\xE1n completos. `grossSalesKnown` distinto de true indica ventas totales parciales. Si `costsKnown` viene en `false`, esos pedidos llegaron de una fuente que NO sabe cuanto costaron \u2014la tienda, o la API del proveedor\u2014 y la utilidad BRUTA esta incompleta: no es que el producto salga gratis. Si `adSpendKnown` viene en `false`, la publicidad NO se pudo leer y la utilidad esta INCOMPLETA: dilo antes de que alguien celebre un mes que perdio plata. `adSpendSource: "user"` significa que ella corrigio la cifra a mano, y eso se revisa distinto de una leida. Si `unconfirmedExpenses` es mayor que cero, ese monto viene heredado del mes pasado y ella no lo ha revisado. Es READ-ONLY: nunca pausa ni modifica una campana. Si viene `costEstimate` con `source: "product_costing"`, presenta sus importes como ESTIMACI\xD3N antes de impuestos, usando los costos actuales configurados del producto: no son costos reales confirmados de esos pedidos. Conserva el aviso de `costsKnown: false` y distingue esta estimaci\xF3n de los importes reales del libro. `linesEstimated` indica cu\xE1ntas l\xEDneas usan costos configurados. La API s\xF3lo ofrece esta estimaci\xF3n cuando cubre todos los costos faltantes con perfiles asociados del mismo pa\xEDs y moneda, y conoce ventas entregadas, publicidad y gastos revisados. Si `costEstimate` es null o no existe, no inventes una estimaci\xF3n ni completes importes faltantes.',
|
|
39530
39943
|
inputSchema: GetFinancesInput.shape,
|