@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/http.js
CHANGED
|
@@ -2315,6 +2315,15 @@ var DEFAULT_PRICING = {
|
|
|
2315
2315
|
ourCostCents: 0.01,
|
|
2316
2316
|
userPriceCents: 0.02
|
|
2317
2317
|
},
|
|
2318
|
+
// OpenAI Decisions same-product check of DropKiller listings (market formats study),
|
|
2319
|
+
// per 1,000 input tokens. Decisions has no price row of its own; it bills as its
|
|
2320
|
+
// model, gpt-6-luna: $0.10/1M input (https://developers.openai.com/api/docs/pricing,
|
|
2321
|
+
// 2026-11-02). Answers are closed choices, so output is negligible. Cost-only:
|
|
2322
|
+
// the seller is not charged, the fixed study quote absorbs it.
|
|
2323
|
+
"openai:competitor-listing-decision": {
|
|
2324
|
+
ourCostCents: 0.01,
|
|
2325
|
+
userPriceCents: 0
|
|
2326
|
+
},
|
|
2318
2327
|
// Full competitor-source transcript used by the flat-price Frankenstein bundle.
|
|
2319
2328
|
"openai:frankenstein-source-transcribe": {
|
|
2320
2329
|
ourCostCents: 0.01,
|
|
@@ -2476,6 +2485,19 @@ var DEFAULT_PRICING = {
|
|
|
2476
2485
|
ourCostCents: 1,
|
|
2477
2486
|
userPriceCents: 2
|
|
2478
2487
|
},
|
|
2488
|
+
// Market formats read each competitor ad by its medium. Video: Gemini over
|
|
2489
|
+
// the whole ad with audio, measured 1.641¢ avg / 2.071¢ max over 60 local
|
|
2490
|
+
// analyses (6.9k in / 3.0k out tokens, 2026-11-04). Image: one still with the
|
|
2491
|
+
// same prompt, estimated (~4.2k in / ~2k out) — no producer until image ads
|
|
2492
|
+
// are analyzed. Frames (the key above) stays the flag-off and fallback leg.
|
|
2493
|
+
"openrouter:market-ad-video-analysis": {
|
|
2494
|
+
ourCostCents: 1.65,
|
|
2495
|
+
userPriceCents: 3.3
|
|
2496
|
+
},
|
|
2497
|
+
"openrouter:market-ad-image-analysis": {
|
|
2498
|
+
ourCostCents: 1.1,
|
|
2499
|
+
userPriceCents: 2.2
|
|
2500
|
+
},
|
|
2479
2501
|
"openrouter:competitor-commercial-dossier": {
|
|
2480
2502
|
ourCostCents: 5,
|
|
2481
2503
|
userPriceCents: 10
|
|
@@ -4093,6 +4115,13 @@ var AiEditWinnerOverlayItemSchema = z5.object({
|
|
|
4093
4115
|
/** Target-truth field ids backing `text` (from the adaptation plan). */
|
|
4094
4116
|
truthSourceIds: z5.array(z5.string().min(1).max(200)).max(16).optional()
|
|
4095
4117
|
}).strict();
|
|
4118
|
+
var AiEditDeliveredExecutionSchema = z5.object({
|
|
4119
|
+
taskId: z5.string().min(1).max(200),
|
|
4120
|
+
angleKey: z5.string().min(1).max(200),
|
|
4121
|
+
creativeRevision: z5.string().min(1).max(200),
|
|
4122
|
+
planHash: z5.string().min(1).max(200),
|
|
4123
|
+
outputHash: z5.string().min(1).max(200)
|
|
4124
|
+
}).strict();
|
|
4096
4125
|
var AiEditWinnerOverlaysSchema = z5.object({
|
|
4097
4126
|
version: z5.literal(1),
|
|
4098
4127
|
source: z5.object({
|
|
@@ -4102,13 +4131,7 @@ var AiEditWinnerOverlaysSchema = z5.object({
|
|
|
4102
4131
|
adaptationPlanRevision: z5.string().regex(/^[a-f0-9]{64}$/).optional()
|
|
4103
4132
|
}).strict(),
|
|
4104
4133
|
/** The delivered execution this plan was fitted against. */
|
|
4105
|
-
current:
|
|
4106
|
-
taskId: z5.string().min(1).max(200),
|
|
4107
|
-
angleKey: z5.string().min(1).max(200),
|
|
4108
|
-
creativeRevision: z5.string().min(1).max(200),
|
|
4109
|
-
planHash: z5.string().min(1).max(200),
|
|
4110
|
-
outputHash: z5.string().min(1).max(200)
|
|
4111
|
-
}).strict(),
|
|
4134
|
+
current: AiEditDeliveredExecutionSchema,
|
|
4112
4135
|
items: z5.array(AiEditWinnerOverlayItemSchema).max(64),
|
|
4113
4136
|
omitted: z5.array(z5.object({
|
|
4114
4137
|
id: z5.string().min(1).max(200),
|
|
@@ -4124,12 +4147,46 @@ var AiEditWinnerOverlaysSchema = z5.object({
|
|
|
4124
4147
|
])
|
|
4125
4148
|
}).strict()).max(64)
|
|
4126
4149
|
}).strict();
|
|
4150
|
+
var AiEditMarketFormatOverlaysSchema = z5.object({
|
|
4151
|
+
version: z5.literal(1),
|
|
4152
|
+
source: z5.object({
|
|
4153
|
+
formatId: z5.string().min(1).max(200),
|
|
4154
|
+
anchorSourceId: z5.string().min(1).max(200),
|
|
4155
|
+
contextHash: z5.string().min(1).max(200)
|
|
4156
|
+
}).strict(),
|
|
4157
|
+
current: AiEditDeliveredExecutionSchema,
|
|
4158
|
+
/** The format's look and editing pace, for the overlay style. */
|
|
4159
|
+
style: z5.object({
|
|
4160
|
+
visualStyle: z5.string().max(600),
|
|
4161
|
+
editingPace: z5.string().max(300).optional()
|
|
4162
|
+
}).strict(),
|
|
4163
|
+
items: z5.array(z5.object({
|
|
4164
|
+
formatBeatIndex: z5.number().int().nonnegative(),
|
|
4165
|
+
beat: z5.string().max(200),
|
|
4166
|
+
sourceText: z5.string().min(1).max(400),
|
|
4167
|
+
target: z5.object({
|
|
4168
|
+
sceneId: z5.string().min(1).max(200),
|
|
4169
|
+
beatIds: z5.array(z5.string().min(1).max(200)).max(16),
|
|
4170
|
+
startSec: z5.number().finite().nonnegative(),
|
|
4171
|
+
endSec: z5.number().finite().nonnegative()
|
|
4172
|
+
}).strict()
|
|
4173
|
+
}).strict()).max(10),
|
|
4174
|
+
omitted: z5.array(z5.object({
|
|
4175
|
+
formatBeatIndex: z5.number().int().nonnegative(),
|
|
4176
|
+
reason: z5.enum([
|
|
4177
|
+
"unmapped_beat",
|
|
4178
|
+
"unfitted_interval"
|
|
4179
|
+
])
|
|
4180
|
+
}).strict()).max(10)
|
|
4181
|
+
}).strict();
|
|
4127
4182
|
var AiEditBriefSchema = z5.object({
|
|
4128
4183
|
script: z5.string(),
|
|
4129
4184
|
words: z5.array(AiEditWordSchema),
|
|
4130
4185
|
sceneCutsSec: z5.array(z5.number().min(0)),
|
|
4131
4186
|
/** Optional winner-overlay adaptation plan; absent without winner+edit consent. */
|
|
4132
|
-
winnerOverlays: AiEditWinnerOverlaysSchema.optional()
|
|
4187
|
+
winnerOverlays: AiEditWinnerOverlaysSchema.optional(),
|
|
4188
|
+
/** Optional market-format overlays; absent without an applied format. */
|
|
4189
|
+
marketFormatOverlays: AiEditMarketFormatOverlaysSchema.optional()
|
|
4133
4190
|
});
|
|
4134
4191
|
var AiEditOutputsSchema = z5.object({
|
|
4135
4192
|
editKey: z5.string(),
|
|
@@ -5279,8 +5336,11 @@ var COUNTRY_NAME_TO_ISO2 = {
|
|
|
5279
5336
|
var COUNTRY_NAME_ALIASES = {
|
|
5280
5337
|
usa: "united states",
|
|
5281
5338
|
"estados unidos": "united states",
|
|
5339
|
+
estadosunidos: "united states",
|
|
5340
|
+
unitedstates: "united states",
|
|
5282
5341
|
uk: "united kingdom",
|
|
5283
5342
|
"reino unido": "united kingdom",
|
|
5343
|
+
unitedkingdom: "united kingdom",
|
|
5284
5344
|
brasil: "brazil",
|
|
5285
5345
|
espana: "spain",
|
|
5286
5346
|
alemania: "germany",
|
|
@@ -5333,6 +5393,7 @@ function normalizeToIso2(value) {
|
|
|
5333
5393
|
return void 0;
|
|
5334
5394
|
}
|
|
5335
5395
|
__name(normalizeToIso2, "normalizeToIso2");
|
|
5396
|
+
var SUPPORTED_COUNTRY_ISO2 = new Set(Object.values(COUNTRY_NAME_TO_ISO2));
|
|
5336
5397
|
var CountryIso2Schema = z11.preprocess(
|
|
5337
5398
|
(value) => typeof value === "string" ? normalizeToIso2(value) ?? value : value,
|
|
5338
5399
|
// The regex rejects unresolvable 2-unit garbage ('$$', '💩') that would
|
|
@@ -6108,7 +6169,8 @@ var LANDING_STRATEGIES = [
|
|
|
6108
6169
|
var LandingStrategySchema = z14.enum(LANDING_STRATEGIES);
|
|
6109
6170
|
var SELECTABLE_LANDING_STRATEGIES = [
|
|
6110
6171
|
"classic",
|
|
6111
|
-
"social_proof"
|
|
6172
|
+
"social_proof",
|
|
6173
|
+
"pain_solution"
|
|
6112
6174
|
];
|
|
6113
6175
|
var SelectableLandingStrategySchema = z14.enum(SELECTABLE_LANDING_STRATEGIES);
|
|
6114
6176
|
var EffectiveLandingStrategySchema = LandingStrategySchema.exclude([
|
|
@@ -6389,6 +6451,13 @@ var CODE_LANDING_USAGE_VARIANTS = [
|
|
|
6389
6451
|
"steps"
|
|
6390
6452
|
];
|
|
6391
6453
|
var CodeLandingUsageVariantSchema = z16.enum(CODE_LANDING_USAGE_VARIANTS);
|
|
6454
|
+
var CODE_LANDING_BUY_BOX_FORMATS = [
|
|
6455
|
+
"classic",
|
|
6456
|
+
"benefits",
|
|
6457
|
+
"impact",
|
|
6458
|
+
"pop"
|
|
6459
|
+
];
|
|
6460
|
+
var CodeLandingBuyBoxFormatSchema = z16.enum(CODE_LANDING_BUY_BOX_FORMATS);
|
|
6392
6461
|
var CodeLandingRecipeVariantsSchema = z16.object({
|
|
6393
6462
|
hero: CodeLandingHeroVariantSchema,
|
|
6394
6463
|
"benefits-grid": CodeLandingBenefitsVariantSchema,
|
|
@@ -6429,7 +6498,8 @@ var CodeLandingRecipePlanFields = {
|
|
|
6429
6498
|
var CodeLandingRecipeProposalSchema = z16.object(CodeLandingRecipePlanFields).strict();
|
|
6430
6499
|
var CodeLandingRecipePlanObjectSchema = z16.object({
|
|
6431
6500
|
version: z16.literal(1),
|
|
6432
|
-
...CodeLandingRecipePlanFields
|
|
6501
|
+
...CodeLandingRecipePlanFields,
|
|
6502
|
+
buyBoxFormat: CodeLandingBuyBoxFormatSchema.optional()
|
|
6433
6503
|
}).strict();
|
|
6434
6504
|
function hasDuplicateIds(ids) {
|
|
6435
6505
|
return new Set(ids).size !== ids.length;
|
|
@@ -7876,6 +7946,13 @@ var CodeLandingCommerceSnapshotSchema = z23.object({
|
|
|
7876
7946
|
compareAtPrice: z23.string().trim().min(1).max(500).optional(),
|
|
7877
7947
|
/** Explicit removal survives projections that otherwise derive a comparison. */
|
|
7878
7948
|
compareAtPriceRemoved: z23.literal(true).optional(),
|
|
7949
|
+
/** Seller-confirmed prices by product option, never purchase quantities. */
|
|
7950
|
+
offerVariants: z23.array(z23.object({
|
|
7951
|
+
option: z23.string().trim().min(1).max(60),
|
|
7952
|
+
value: z23.string().trim().min(1).max(60),
|
|
7953
|
+
price: PublishCommerceValuesSchema.shape.unitPrice,
|
|
7954
|
+
compareAtPrice: PublishCommerceValuesSchema.shape.unitPrice.nullable().optional()
|
|
7955
|
+
}).strict()).max(20).optional(),
|
|
7879
7956
|
/** Confirmed offer facts before Shopify supplies real chargeable variants. */
|
|
7880
7957
|
offerPacks: z23.array(z23.object({
|
|
7881
7958
|
units: z23.number().int().min(2).max(99),
|
|
@@ -8653,6 +8730,16 @@ var LandingEditAttachmentDto = z23.object({
|
|
|
8653
8730
|
width: z23.number().int().positive().nullable(),
|
|
8654
8731
|
height: z23.number().int().positive().nullable()
|
|
8655
8732
|
});
|
|
8733
|
+
var ApplyLandingCarouselGifRequest = z23.object({
|
|
8734
|
+
attachmentId: z23.string().uuid(),
|
|
8735
|
+
expectedRevision: z23.number().int().nonnegative(),
|
|
8736
|
+
idempotencyKey: z23.string().uuid()
|
|
8737
|
+
}).strict();
|
|
8738
|
+
var ApplyLandingCarouselGifResponse = z23.object({
|
|
8739
|
+
artifact: CodeLandingArtifactSchema,
|
|
8740
|
+
appliedRevision: z23.number().int().positive(),
|
|
8741
|
+
replayed: z23.boolean()
|
|
8742
|
+
});
|
|
8656
8743
|
var UploadLandingEditAttachmentResponse = z23.object({
|
|
8657
8744
|
attachment: LandingEditAttachmentDto
|
|
8658
8745
|
});
|
|
@@ -10459,6 +10546,49 @@ var ObservedCommercialClaimSchema = z37.object({
|
|
|
10459
10546
|
"other"
|
|
10460
10547
|
])
|
|
10461
10548
|
}).strict();
|
|
10549
|
+
var CreativeFormatFramingSchema = z37.object({
|
|
10550
|
+
shotSize: z37.enum([
|
|
10551
|
+
"macro",
|
|
10552
|
+
"close_up",
|
|
10553
|
+
"medium",
|
|
10554
|
+
"wide"
|
|
10555
|
+
]),
|
|
10556
|
+
camera: z37.enum([
|
|
10557
|
+
"static",
|
|
10558
|
+
"handheld",
|
|
10559
|
+
"selfie",
|
|
10560
|
+
"moving"
|
|
10561
|
+
]),
|
|
10562
|
+
faceVisible: z37.boolean()
|
|
10563
|
+
}).strict();
|
|
10564
|
+
var CompetitorCreativeFormatSchema = z37.object({
|
|
10565
|
+
formatName: z37.string().trim().min(1).max(120),
|
|
10566
|
+
renderTechnique: z37.string().trim().min(1).max(300),
|
|
10567
|
+
visualWorld: z37.string().trim().min(1).max(600),
|
|
10568
|
+
protagonist: z37.string().trim().min(1).max(300),
|
|
10569
|
+
narrativeEngine: z37.string().trim().min(1).max(600),
|
|
10570
|
+
beats: z37.array(z37.object({
|
|
10571
|
+
atSec: z37.number().finite().nonnegative(),
|
|
10572
|
+
beat: z37.string().trim().min(1).max(200),
|
|
10573
|
+
/** What physically happens on camera, never its overlay text. */
|
|
10574
|
+
visual: z37.string().trim().min(1).max(400),
|
|
10575
|
+
/** Text, captions or graphics shown over that beat ("" = none). */
|
|
10576
|
+
onScreenText: z37.string().trim().max(400).optional()
|
|
10577
|
+
}).strict()).min(1).max(12),
|
|
10578
|
+
hookDevice: z37.string().trim().min(1).max(600),
|
|
10579
|
+
ctaDevice: z37.string().trim().min(1).max(600),
|
|
10580
|
+
productRole: z37.string().trim().min(1).max(600),
|
|
10581
|
+
tone: z37.string().trim().min(1).max(300),
|
|
10582
|
+
editingPace: z37.string().trim().min(1).max(300),
|
|
10583
|
+
confidence: z37.enum([
|
|
10584
|
+
"high",
|
|
10585
|
+
"medium",
|
|
10586
|
+
"low"
|
|
10587
|
+
]),
|
|
10588
|
+
/** ISO 639-1 of the spoken words, or "none" without speech. */
|
|
10589
|
+
spokenLanguage: z37.string().trim().toLowerCase().regex(/^(?:[a-z]{2}|none)$/).optional(),
|
|
10590
|
+
framing: CreativeFormatFramingSchema.optional()
|
|
10591
|
+
}).strict();
|
|
10462
10592
|
var CompetitorCommercialProfileSchema = z37.object({
|
|
10463
10593
|
durationSec: z37.number().finite().positive(),
|
|
10464
10594
|
transcript: z37.string().max(2e4).optional(),
|
|
@@ -10484,7 +10614,9 @@ var CompetitorCommercialProfileSchema = z37.object({
|
|
|
10484
10614
|
"incompatible",
|
|
10485
10615
|
"uncertain"
|
|
10486
10616
|
]).optional(),
|
|
10487
|
-
marketRelevanceEvidence: z37.string().trim().min(1).max(1e3).optional()
|
|
10617
|
+
marketRelevanceEvidence: z37.string().trim().min(1).max(1e3).optional(),
|
|
10618
|
+
/** Requested only for market-format studies; absent on every other path. */
|
|
10619
|
+
creativeFormat: CompetitorCreativeFormatSchema.optional()
|
|
10488
10620
|
}).strict();
|
|
10489
10621
|
var MarketSceneIntentSchema = z37.object({
|
|
10490
10622
|
id: z37.string().trim().min(1).max(80),
|
|
@@ -10542,6 +10674,99 @@ var CommercialMarketDossierSchema = z37.object({
|
|
|
10542
10674
|
recipes: z37.array(MarketCreativeRecipeSchema).length(3),
|
|
10543
10675
|
evidenceDisclaimer: z37.string().trim().min(1).max(1e3)
|
|
10544
10676
|
}).strict();
|
|
10677
|
+
var MarketVoiceLineSchema = z37.object({
|
|
10678
|
+
/** Quoted exactly as spoken in the source transcript, original language. */
|
|
10679
|
+
text: z37.string().trim().min(1).max(400),
|
|
10680
|
+
sourceId: z37.string().trim().min(1)
|
|
10681
|
+
}).strict();
|
|
10682
|
+
var MarketFormatVoiceSchema = z37.object({
|
|
10683
|
+
hookLines: z37.array(MarketVoiceLineSchema).max(6),
|
|
10684
|
+
ctaLines: z37.array(MarketVoiceLineSchema).max(6),
|
|
10685
|
+
recurringPhrases: z37.array(z37.string().trim().min(1).max(200)).max(12),
|
|
10686
|
+
topics: z37.array(z37.string().trim().min(1).max(200)).max(10),
|
|
10687
|
+
rawness: z37.number().int().min(1).max(5)
|
|
10688
|
+
}).strict();
|
|
10689
|
+
var MarketFormatAnchorFrameSchema = z37.object({
|
|
10690
|
+
index: z37.number().int().min(0).max(3),
|
|
10691
|
+
assetKey: z37.string().trim().min(1).max(500),
|
|
10692
|
+
timestampSec: z37.number().finite().nonnegative()
|
|
10693
|
+
}).strict();
|
|
10694
|
+
var MarketFormatPacingSchema = z37.object({
|
|
10695
|
+
shotCount: z37.number().int().min(1).max(12),
|
|
10696
|
+
secondsPerShot: z37.number().finite().positive().max(600),
|
|
10697
|
+
editingPace: z37.string().trim().min(1).max(300).optional()
|
|
10698
|
+
}).strict();
|
|
10699
|
+
var MarketBeatExampleSchema = z37.object({
|
|
10700
|
+
visual: z37.string().trim().min(1).max(400),
|
|
10701
|
+
sourceId: z37.string().trim().min(1)
|
|
10702
|
+
}).strict();
|
|
10703
|
+
var MarketFormatDirectionSchema = z37.object({
|
|
10704
|
+
id: z37.string().trim().min(1).max(80),
|
|
10705
|
+
formatName: z37.string().trim().min(1).max(120),
|
|
10706
|
+
anchorSourceId: z37.string().trim().min(1),
|
|
10707
|
+
sourceIds: z37.array(z37.string().trim().min(1)).min(1).max(20),
|
|
10708
|
+
advertiserCount: z37.number().int().positive(),
|
|
10709
|
+
weightShare: z37.number().finite().min(0).max(1),
|
|
10710
|
+
advertiserShare: z37.number().finite().min(0).max(1),
|
|
10711
|
+
visualStyle: z37.string().trim().min(1).max(600),
|
|
10712
|
+
protagonist: z37.string().trim().min(1).max(300),
|
|
10713
|
+
narrative: z37.string().trim().min(1).max(600),
|
|
10714
|
+
storyLine: z37.string().trim().min(1).max(600),
|
|
10715
|
+
beats: z37.array(z37.object({
|
|
10716
|
+
beat: z37.string().trim().min(1).max(200),
|
|
10717
|
+
/** The on-camera action to stage (a CTA action included). */
|
|
10718
|
+
visual: z37.string().trim().min(1).max(600),
|
|
10719
|
+
/** Graphics for the optional edit ("" = none); never staged. */
|
|
10720
|
+
onScreenText: z37.string().trim().max(400).optional(),
|
|
10721
|
+
/** How different member ads stage this shared beat. */
|
|
10722
|
+
examples: z37.array(MarketBeatExampleSchema).max(4).optional()
|
|
10723
|
+
}).strict()).min(2).max(10),
|
|
10724
|
+
hook: z37.string().trim().min(1).max(600),
|
|
10725
|
+
cta: z37.string().trim().min(1).max(600),
|
|
10726
|
+
productRole: z37.string().trim().min(1).max(600),
|
|
10727
|
+
adaptToProduct: z37.string().trim().min(1).max(1e3),
|
|
10728
|
+
doNotCopy: z37.array(z37.string().trim().min(1).max(300)).max(10),
|
|
10729
|
+
whyThisFormat: z37.string().trim().min(1).max(1e3),
|
|
10730
|
+
voice: MarketFormatVoiceSchema.optional(),
|
|
10731
|
+
anchorFrames: z37.array(MarketFormatAnchorFrameSchema).max(4).optional(),
|
|
10732
|
+
/** Server-owned: the anchor ad's framing, binding for the director. */
|
|
10733
|
+
framing: CreativeFormatFramingSchema.optional(),
|
|
10734
|
+
/** Server-owned: the anchor ad's cut rhythm, binding for the director. */
|
|
10735
|
+
pacing: MarketFormatPacingSchema.optional(),
|
|
10736
|
+
/** Server-owned: no member speaks the target market's language. */
|
|
10737
|
+
languageFallback: z37.boolean().optional()
|
|
10738
|
+
}).strict();
|
|
10739
|
+
var MarketMenuItemSchema = z37.object({
|
|
10740
|
+
kind: z37.string().trim().min(1).max(120),
|
|
10741
|
+
description: z37.string().trim().min(1).max(400),
|
|
10742
|
+
lines: z37.array(MarketVoiceLineSchema).max(4).optional(),
|
|
10743
|
+
sourceIds: z37.array(z37.string().trim().min(1)).min(1).max(20),
|
|
10744
|
+
advertiserCount: z37.number().int().positive(),
|
|
10745
|
+
weightShare: z37.number().finite().min(0).max(1)
|
|
10746
|
+
}).strict();
|
|
10747
|
+
var MarketCreativeMenuSchema = z37.object({
|
|
10748
|
+
hooks: z37.array(MarketMenuItemSchema).max(6),
|
|
10749
|
+
ctas: z37.array(MarketMenuItemSchema).max(6),
|
|
10750
|
+
visualStyles: z37.array(MarketMenuItemSchema).max(6),
|
|
10751
|
+
demos: z37.array(MarketMenuItemSchema).max(8),
|
|
10752
|
+
rhythms: z37.array(MarketMenuItemSchema).max(4)
|
|
10753
|
+
}).strict();
|
|
10754
|
+
var MarketCreativeDirectionSchema = z37.object({
|
|
10755
|
+
version: z37.literal("1.0.0"),
|
|
10756
|
+
sourceSnapshotHash: z37.string().trim().min(1),
|
|
10757
|
+
evidenceSource: z37.enum([
|
|
10758
|
+
"dropkiller",
|
|
10759
|
+
"meta",
|
|
10760
|
+
"mixed"
|
|
10761
|
+
]),
|
|
10762
|
+
analyzedVideoCount: z37.number().int().positive(),
|
|
10763
|
+
advertiserCount: z37.number().int().positive(),
|
|
10764
|
+
/** Dropi units sold in 30 days across confirmed listings, when known. */
|
|
10765
|
+
productSoldUnits30d: z37.number().int().nonnegative().optional(),
|
|
10766
|
+
formats: z37.array(MarketFormatDirectionSchema).min(1).max(3),
|
|
10767
|
+
/** The market's recurring hooks, CTAs, styles, demos and rhythms. */
|
|
10768
|
+
menu: MarketCreativeMenuSchema.optional()
|
|
10769
|
+
}).strict();
|
|
10545
10770
|
var MarketPersuasionDeviceSchema = z37.object({
|
|
10546
10771
|
/** Verbatim hook/CTA/market pattern from the persisted dossier. */
|
|
10547
10772
|
sourcePattern: z37.string().trim().min(1).max(1e3),
|
|
@@ -10750,6 +10975,24 @@ var CreativeEngineWinnerContextSchema = z38.object({
|
|
|
10750
10975
|
}).strict()).max(24)
|
|
10751
10976
|
}).strict().optional()
|
|
10752
10977
|
}).strict();
|
|
10978
|
+
var CreativeEngineMarketPickSchema = z38.object({
|
|
10979
|
+
kind: z38.string().trim().min(1).max(120),
|
|
10980
|
+
description: z38.string().trim().min(1).max(400),
|
|
10981
|
+
/** A verbatim market line to adapt (hooks and CTAs). */
|
|
10982
|
+
line: z38.string().trim().min(1).max(400).optional(),
|
|
10983
|
+
sourceId: id2
|
|
10984
|
+
}).strict();
|
|
10985
|
+
var CreativeEngineMarketSelectionSchema = z38.object({
|
|
10986
|
+
version: z38.literal(1),
|
|
10987
|
+
formatId: id2,
|
|
10988
|
+
/** The member ad shown as one example of the format, never a template. */
|
|
10989
|
+
exampleSourceId: id2,
|
|
10990
|
+
hook: CreativeEngineMarketPickSchema.optional(),
|
|
10991
|
+
cta: CreativeEngineMarketPickSchema.optional(),
|
|
10992
|
+
visualStyle: CreativeEngineMarketPickSchema.optional(),
|
|
10993
|
+
demo: CreativeEngineMarketPickSchema.optional(),
|
|
10994
|
+
rhythm: CreativeEngineMarketPickSchema.optional()
|
|
10995
|
+
}).strict();
|
|
10753
10996
|
var CreativeEngineMarketInputSchema = z38.object({
|
|
10754
10997
|
version: z38.literal(1),
|
|
10755
10998
|
/** The dossier's own snapshot hash (not necessarily hex-64). */
|
|
@@ -10778,7 +11021,22 @@ var CreativeEngineMarketInputSchema = z38.object({
|
|
|
10778
11021
|
])
|
|
10779
11022
|
}).strict()).max(64),
|
|
10780
11023
|
/** Validated when it names a recipe actually present in `recipes`. */
|
|
10781
|
-
marketRecipeId: id2.optional()
|
|
11024
|
+
marketRecipeId: id2.optional(),
|
|
11025
|
+
/**
|
|
11026
|
+
* Market formats flag only: formats #1..#3 (HOW the video looks and flows)
|
|
11027
|
+
* with the anchor ad's transcript. Absent keeps the historical context.
|
|
11028
|
+
*/
|
|
11029
|
+
formats: z38.array(MarketFormatDirectionSchema.extend({
|
|
11030
|
+
anchorTranscript: z38.string().max(2e4).optional()
|
|
11031
|
+
}).strict()).min(1).max(3).optional(),
|
|
11032
|
+
/** The format the server binds; the director may drop to the next with a reason. */
|
|
11033
|
+
marketFormatId: id2.optional(),
|
|
11034
|
+
/**
|
|
11035
|
+
* Market formats only: the combination sampled for this creative by market
|
|
11036
|
+
* weight (format, hook, CTA, style, demo, example member), seeded by the
|
|
11037
|
+
* task so a retry repeats it and sibling creatives vary inside the market.
|
|
11038
|
+
*/
|
|
11039
|
+
marketSelection: CreativeEngineMarketSelectionSchema.optional()
|
|
10782
11040
|
}).strict();
|
|
10783
11041
|
var CreativeEngineCommercialExecutionSchema = z38.discriminatedUnion("mode", [
|
|
10784
11042
|
z38.object({
|
|
@@ -10787,7 +11045,17 @@ var CreativeEngineCommercialExecutionSchema = z38.discriminatedUnion("mode", [
|
|
|
10787
11045
|
mode: z38.literal("market"),
|
|
10788
11046
|
sourceSnapshotHash: z38.string().min(1).max(200),
|
|
10789
11047
|
recipeId: id2,
|
|
10790
|
-
sourceIds: z38.array(id2).min(1).max(64)
|
|
11048
|
+
sourceIds: z38.array(id2).min(1).max(64),
|
|
11049
|
+
/** The market format actually applied (context `market.formats` only). */
|
|
11050
|
+
formatId: id2.optional(),
|
|
11051
|
+
/** Each format beat mapped onto the authored scene/beats. */
|
|
11052
|
+
beatMap: z38.array(z38.object({
|
|
11053
|
+
formatBeatIndex: z38.number().int().nonnegative(),
|
|
11054
|
+
targetSceneId: id2,
|
|
11055
|
+
targetBeatIds: z38.array(id2).max(16)
|
|
11056
|
+
}).strict()).min(1).max(10).optional(),
|
|
11057
|
+
/** Required only when formatId is not the server-bound format. */
|
|
11058
|
+
formatFallbackReason: z38.string().min(1).max(500).optional()
|
|
10791
11059
|
}).strict(),
|
|
10792
11060
|
z38.object({
|
|
10793
11061
|
version: z38.literal(1),
|
|
@@ -11491,6 +11759,13 @@ var CreativeEngineRepairAuthorContractRetrySchema = z38.object({
|
|
|
11491
11759
|
requestedAtMs: z38.number().int().nonnegative(),
|
|
11492
11760
|
token: id2
|
|
11493
11761
|
}).strict();
|
|
11762
|
+
var CreativeEngineReplanAuthorContractRetrySchema = z38.object({
|
|
11763
|
+
failedOperationId: id2,
|
|
11764
|
+
planHash: hash,
|
|
11765
|
+
context: CreativeEngineContextBindingSchema,
|
|
11766
|
+
requestedAtMs: z38.number().int().nonnegative(),
|
|
11767
|
+
token: id2
|
|
11768
|
+
}).strict();
|
|
11494
11769
|
var CreativeEngineCompositionRepairSchema = z38.object({
|
|
11495
11770
|
reviewId: id2,
|
|
11496
11771
|
outputHash: hash,
|
|
@@ -11624,6 +11899,7 @@ var CreativeEngineStateSchema = z38.object({
|
|
|
11624
11899
|
token: id2
|
|
11625
11900
|
}).strict().optional(),
|
|
11626
11901
|
repairAuthorContractRetry: CreativeEngineRepairAuthorContractRetrySchema.optional(),
|
|
11902
|
+
replanAuthorContractRetry: CreativeEngineReplanAuthorContractRetrySchema.optional(),
|
|
11627
11903
|
final: CreativeEngineFinalSchema.optional()
|
|
11628
11904
|
}).strict().superRefine((state, ctx) => {
|
|
11629
11905
|
const repairAuthorContractRetry = state.repairAuthorContractRetry;
|
|
@@ -11782,6 +12058,13 @@ var CreativeEngineEventSchema = z38.discriminatedUnion("type", [
|
|
|
11782
12058
|
context: CreativeEngineContextBindingSchema,
|
|
11783
12059
|
token: id2
|
|
11784
12060
|
}).strict(),
|
|
12061
|
+
z38.object({
|
|
12062
|
+
type: z38.literal("replan_author_contract_retry_requested"),
|
|
12063
|
+
failedOperationId: id2,
|
|
12064
|
+
planHash: hash,
|
|
12065
|
+
context: CreativeEngineContextBindingSchema,
|
|
12066
|
+
token: id2
|
|
12067
|
+
}).strict(),
|
|
11785
12068
|
z38.object({
|
|
11786
12069
|
type: z38.literal("repair_author_contract_retry_requested"),
|
|
11787
12070
|
failedOperationId: id2,
|
|
@@ -12029,10 +12312,10 @@ import { z as z40 } from "zod";
|
|
|
12029
12312
|
var MAX_BILLING_DECIMAL_PLACES = 10;
|
|
12030
12313
|
function countDecimalPlaces(value) {
|
|
12031
12314
|
if (!Number.isFinite(value)) return MAX_BILLING_DECIMAL_PLACES + 1;
|
|
12032
|
-
|
|
12315
|
+
let normalized = value.toString();
|
|
12033
12316
|
if (/e/i.test(normalized)) {
|
|
12034
|
-
|
|
12035
|
-
|
|
12317
|
+
if (Math.abs(value) >= 1e21) return 0;
|
|
12318
|
+
normalized = value.toFixed(MAX_BILLING_DECIMAL_PLACES);
|
|
12036
12319
|
}
|
|
12037
12320
|
const parts = normalized.split(".");
|
|
12038
12321
|
if (parts.length < 2) return 0;
|
|
@@ -14575,6 +14858,8 @@ var CostEstimationRequest = z50.discriminatedUnion("type", [
|
|
|
14575
14858
|
var CostEstimationResponse = z50.object({
|
|
14576
14859
|
/** Server confirms the range includes the first generated classic-landing GIF. */
|
|
14577
14860
|
includesInitialLandingGif: z50.boolean().optional(),
|
|
14861
|
+
/** The initial-GIF choice is offerable for this config (code landings only quote it after explicit consent). */
|
|
14862
|
+
initialLandingGifOffered: z50.boolean().optional(),
|
|
14578
14863
|
estimatedCostCents: z50.number().nonnegative(),
|
|
14579
14864
|
estimatedCostCredits: z50.number().int().nonnegative(),
|
|
14580
14865
|
/** Scan-only midpoint; excludes generating a winner replica. Not an admission limit. */
|
|
@@ -15472,8 +15757,13 @@ var AdminQualityReportSummary = z53.object({
|
|
|
15472
15757
|
mixTaskId: z53.string().nullable(),
|
|
15473
15758
|
kind: QualityReportKind,
|
|
15474
15759
|
// Historical rows can contain `quality` in the DB's free-text reason column.
|
|
15760
|
+
// Support refunds can also contain `generation_failed`, presented as `other`.
|
|
15475
15761
|
// Normalize only on read; new submissions keep the strict QualityReportReason enum.
|
|
15476
|
-
reason: z53.preprocess((value) =>
|
|
15762
|
+
reason: z53.preprocess((value) => {
|
|
15763
|
+
if (value === "quality") return "unacceptable_quality";
|
|
15764
|
+
if (value === "generation_failed") return "other";
|
|
15765
|
+
return value;
|
|
15766
|
+
}, QualityReportReason),
|
|
15477
15767
|
status: QualityReportStatus,
|
|
15478
15768
|
estimatedCostCents: z53.number().nullable(),
|
|
15479
15769
|
refundedCents: z53.number().nullable(),
|
|
@@ -21517,6 +21807,24 @@ var CAPABILITY_MODEL_GUIDANCE = {
|
|
|
21517
21807
|
"solo lectura; un d\xEDa sin conteos usa la tasa estimada"
|
|
21518
21808
|
]
|
|
21519
21809
|
},
|
|
21810
|
+
get_product_ads: {
|
|
21811
|
+
summary: "Muestra cada anuncio (\xE1ngulo de venta) de un producto en un d\xEDa, con cifras de Meta y qu\xE9 hacer con \xE9l.",
|
|
21812
|
+
useWhen: [
|
|
21813
|
+
"cu\xE1l de mis anuncios est\xE1 vendiendo",
|
|
21814
|
+
"qu\xE9 anuncio apago",
|
|
21815
|
+
"c\xF3mo le fue a cada \xE1ngulo ayer"
|
|
21816
|
+
],
|
|
21817
|
+
avoidWhen: [
|
|
21818
|
+
"pregunta por el producto entero: get_product_control"
|
|
21819
|
+
],
|
|
21820
|
+
defaults: [
|
|
21821
|
+
"el id sale de get_product_control, nunca se inventa",
|
|
21822
|
+
"compras del p\xEDxel de Meta, no pedidos de la tienda"
|
|
21823
|
+
],
|
|
21824
|
+
disclosures: [
|
|
21825
|
+
"solo lectura; nunca pausa ni modifica un anuncio"
|
|
21826
|
+
]
|
|
21827
|
+
},
|
|
21520
21828
|
report_product_counts: {
|
|
21521
21829
|
summary: "Registra lo que de verdad pas\xF3 con un producto en un d\xEDa: pedidos, cancelados, entregados y devueltos.",
|
|
21522
21830
|
useWhen: [
|
|
@@ -22897,6 +23205,76 @@ var CreateManualProductControlResponseSchema = z100.object({
|
|
|
22897
23205
|
productControlId: z100.string().guid(),
|
|
22898
23206
|
created: z100.boolean()
|
|
22899
23207
|
});
|
|
23208
|
+
var ProductControlAdsQuerySchema = z100.object({
|
|
23209
|
+
date: z100.string().regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
23210
|
+
});
|
|
23211
|
+
var PRODUCT_CONTROL_AD_VERDICTS = [
|
|
23212
|
+
"keep",
|
|
23213
|
+
"turn_off",
|
|
23214
|
+
"review",
|
|
23215
|
+
"no_data"
|
|
23216
|
+
];
|
|
23217
|
+
var ProductControlAdVerdictSchema = z100.enum(PRODUCT_CONTROL_AD_VERDICTS);
|
|
23218
|
+
var PRODUCT_CONTROL_AD_REASONS = [
|
|
23219
|
+
"sells_within_break_even",
|
|
23220
|
+
"sells_above_break_even",
|
|
23221
|
+
"spent_break_even_without_sales",
|
|
23222
|
+
"low_spend_no_sales",
|
|
23223
|
+
"no_spend",
|
|
23224
|
+
"missing_break_even",
|
|
23225
|
+
"unknown_purchases",
|
|
23226
|
+
"different_time_zone"
|
|
23227
|
+
];
|
|
23228
|
+
var ProductControlAdReasonSchema = z100.enum(PRODUCT_CONTROL_AD_REASONS);
|
|
23229
|
+
var metric = z100.number().finite().nonnegative().nullable();
|
|
23230
|
+
var ProductControlAdSchema = z100.object({
|
|
23231
|
+
adId: z100.string(),
|
|
23232
|
+
campaignId: z100.string(),
|
|
23233
|
+
accountId: z100.string(),
|
|
23234
|
+
name: z100.string(),
|
|
23235
|
+
/** `effective_status` de Meta (ACTIVE, PAUSED, …), tal cual. */
|
|
23236
|
+
status: z100.string().nullable(),
|
|
23237
|
+
thumbnailUrl: z100.string().url().nullable(),
|
|
23238
|
+
creativeKind: z100.enum([
|
|
23239
|
+
"video",
|
|
23240
|
+
"image",
|
|
23241
|
+
"unknown"
|
|
23242
|
+
]),
|
|
23243
|
+
adsManagerUrl: z100.string().url(),
|
|
23244
|
+
spend: metric,
|
|
23245
|
+
impressions: metric,
|
|
23246
|
+
clicks: metric,
|
|
23247
|
+
ctr: metric,
|
|
23248
|
+
landingPageViews: metric,
|
|
23249
|
+
viewContent: metric,
|
|
23250
|
+
initiatedCheckout: metric,
|
|
23251
|
+
/** Compras del píxel (`offsite_conversion.fb_pixel_purchase`). */
|
|
23252
|
+
purchases: metric,
|
|
23253
|
+
costPerPurchase: metric,
|
|
23254
|
+
videoPlays: metric,
|
|
23255
|
+
videoP25: metric,
|
|
23256
|
+
videoP75: metric,
|
|
23257
|
+
videoP100: metric,
|
|
23258
|
+
/** p100 / reproducciones; `null` si no es vídeo o no hubo reproducciones. */
|
|
23259
|
+
completionRate: z100.number().finite().min(0).max(1).nullable(),
|
|
23260
|
+
verdict: ProductControlAdVerdictSchema,
|
|
23261
|
+
reason: ProductControlAdReasonSchema
|
|
23262
|
+
});
|
|
23263
|
+
var ProductControlAdsStatusSchema = z100.enum([
|
|
23264
|
+
"ok",
|
|
23265
|
+
"no_meta_campaign",
|
|
23266
|
+
"meta_not_connected",
|
|
23267
|
+
"unavailable"
|
|
23268
|
+
]);
|
|
23269
|
+
var ProductControlAdsResponseSchema = z100.object({
|
|
23270
|
+
productControlId: z100.string(),
|
|
23271
|
+
date: z100.string().regex(/^\d{4}-\d{2}-\d{2}$/),
|
|
23272
|
+
status: ProductControlAdsStatusSchema,
|
|
23273
|
+
currency: z100.string().nullable(),
|
|
23274
|
+
/** Publicidad máxima por compra para no perder (CPA de equilibrio). */
|
|
23275
|
+
breakEvenCpa: z100.number().finite().nonnegative().nullable(),
|
|
23276
|
+
ads: z100.array(ProductControlAdSchema)
|
|
23277
|
+
});
|
|
22900
23278
|
|
|
22901
23279
|
// ../../packages/types/src/productmaker-capability-registry.ts
|
|
22902
23280
|
var SHARED_CHANNEL_EXPOSURE = {
|
|
@@ -23177,7 +23555,8 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
23177
23555
|
// MCP 8.10.0: storyteller family blocked (BLOCKED_NARRATIVE_STYLES).
|
|
23178
23556
|
// MCP 9.1.0: combine current animated-video controls and initial GIF choice.
|
|
23179
23557
|
// MCP 12.4.0: landingStrategy narrowed to classic + social_proof.
|
|
23180
|
-
|
|
23558
|
+
// MCP 12.5.0: pain_solution restored to landingStrategy.
|
|
23559
|
+
"68a740d97238e720000c16db56ae5748ceb560e342f8fbfe605c954e6284fda7",
|
|
23181
23560
|
"credit_consuming",
|
|
23182
23561
|
"creative",
|
|
23183
23562
|
[
|
|
@@ -23623,7 +24002,8 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
23623
24002
|
defineCapability(
|
|
23624
24003
|
"generate_landing",
|
|
23625
24004
|
// MCP 12.4.0: guided landingStrategy narrowed to classic + social_proof.
|
|
23626
|
-
|
|
24005
|
+
// MCP 12.5.0: pain_solution restored to guided landingStrategy.
|
|
24006
|
+
"16c4e1ea0cd12ee3367e06b4f73a177c94e16ab7d5323d971d577301ba2c7b70",
|
|
23627
24007
|
"credit_consuming",
|
|
23628
24008
|
"creative",
|
|
23629
24009
|
[
|
|
@@ -24685,6 +25065,20 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
24685
25065
|
], [
|
|
24686
25066
|
"product_control_report"
|
|
24687
25067
|
]),
|
|
25068
|
+
defineCapability("get_product_ads", "df2873f9776f34f8a5a4c02b2878fbd6fb6ed1cfd9998cf728603b2bbd10069b", "none", "read_only", [
|
|
25069
|
+
"read"
|
|
25070
|
+
], [
|
|
25071
|
+
slot("product_control", true, [
|
|
25072
|
+
"productControlId"
|
|
25073
|
+
]),
|
|
25074
|
+
slot("day", true, [
|
|
25075
|
+
"date"
|
|
25076
|
+
])
|
|
25077
|
+
], [
|
|
25078
|
+
"product_control"
|
|
25079
|
+
], [
|
|
25080
|
+
"product_control_ads"
|
|
25081
|
+
], MCP_ONLY_CHANNEL_EXPOSURE),
|
|
24688
25082
|
defineCapability("report_product_counts", "8fa2561901b7743506a3639038d7806186c0512470bc6988a54c6bee5dbbb0b0", "state_change", "business", [
|
|
24689
25083
|
"state_change"
|
|
24690
25084
|
], [
|
|
@@ -30949,7 +31343,7 @@ var ApiClient = class {
|
|
|
30949
31343
|
};
|
|
30950
31344
|
|
|
30951
31345
|
// src/index.ts
|
|
30952
|
-
var MCP_VERSION = "12.
|
|
31346
|
+
var MCP_VERSION = "12.6.0";
|
|
30953
31347
|
|
|
30954
31348
|
// src/meta-upload-app.ts
|
|
30955
31349
|
import { readFileSync } from "fs";
|
|
@@ -34810,7 +35204,7 @@ var CreateProductTaskInput = z138.object({
|
|
|
34810
35204
|
creativeDirection: z138.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.'),
|
|
34811
35205
|
headline: z138.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."),
|
|
34812
35206
|
subheadline: z138.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."),
|
|
34813
|
-
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)
|
|
35207
|
+
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".'),
|
|
34814
35208
|
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".')
|
|
34815
35209
|
}).strict();
|
|
34816
35210
|
var CreateServiceVideoInput = z138.object({
|
|
@@ -40886,6 +41280,7 @@ import { readFile, stat } from "fs/promises";
|
|
|
40886
41280
|
import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
|
|
40887
41281
|
import { z as z156 } from "zod";
|
|
40888
41282
|
var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
|
|
41283
|
+
var getProductAdsGuidance = getProductMakerCapabilityModelGuidance("get_product_ads");
|
|
40889
41284
|
var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
|
|
40890
41285
|
var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
|
|
40891
41286
|
var setProductCostingGuidance = getProductMakerCapabilityModelGuidance("set_product_costing");
|
|
@@ -40913,6 +41308,10 @@ var ProductControlListInput = z156.object({
|
|
|
40913
41308
|
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."),
|
|
40914
41309
|
shopDomain: z156.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
40915
41310
|
}).strict();
|
|
41311
|
+
var ProductAdsInput = z156.object({
|
|
41312
|
+
productControlId: z156.string().uuid().describe("El `productControlId` que devuelve get_product_control."),
|
|
41313
|
+
date: DateOnly2.describe("D\xEDa a leer (YYYY-MM-DD).")
|
|
41314
|
+
}).strict();
|
|
40916
41315
|
var ImportableProductsInput = z156.object({
|
|
40917
41316
|
q: z156.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
|
|
40918
41317
|
after: z156.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
|
|
@@ -41040,6 +41439,20 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
|
41040
41439
|
throw translateError(error);
|
|
41041
41440
|
}
|
|
41042
41441
|
});
|
|
41442
|
+
server.registerTool("get_product_ads", {
|
|
41443
|
+
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.",
|
|
41444
|
+
inputSchema: ProductAdsInput.shape,
|
|
41445
|
+
annotations: READS_EXTERNAL
|
|
41446
|
+
}, async (input) => {
|
|
41447
|
+
try {
|
|
41448
|
+
const params = new URLSearchParams({
|
|
41449
|
+
date: input.date
|
|
41450
|
+
});
|
|
41451
|
+
return asText(await api.getJson(`/v1/product-control/${encodeURIComponent(input.productControlId)}/ads?${params.toString()}`));
|
|
41452
|
+
} catch (error) {
|
|
41453
|
+
throw translateError(error);
|
|
41454
|
+
}
|
|
41455
|
+
});
|
|
41043
41456
|
server.registerTool("get_finances", {
|
|
41044
41457
|
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.',
|
|
41045
41458
|
inputSchema: GetFinancesInput.shape,
|