@productmaker/mcp 3.4.0 → 3.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/http.js +1012 -885
- package/dist/stdio.js +1000 -873
- package/package.json +1 -1
package/dist/http.js
CHANGED
|
@@ -3692,6 +3692,32 @@ var StatusResponse = z24.object({
|
|
|
3692
3692
|
requiresAction: z24.boolean().optional(),
|
|
3693
3693
|
/** True when the task needs the user's attention rather than passive progress. */
|
|
3694
3694
|
needsReview: z24.boolean().optional(),
|
|
3695
|
+
/**
|
|
3696
|
+
* THE answer to "does this task still owe the seller a question — now OR later
|
|
3697
|
+
* in this run?". The chat leaves for /tasks/:id only on an explicit `false`,
|
|
3698
|
+
* and /tasks/:id bounces her back on `true`. ONE field drives BOTH directions
|
|
3699
|
+
* on purpose: deciding them on two different facts is what looped
|
|
3700
|
+
* /tasks/:id ↔ wizard before (see apps/web/lib/task-routing.ts).
|
|
3701
|
+
*
|
|
3702
|
+
* STRICTLY WIDER THAN `needsReview`, and the difference is the whole point:
|
|
3703
|
+
* · `needsReview` answers "is a gate open RIGHT NOW", and it under-reports —
|
|
3704
|
+
* `buildPendingUserAction` only serves the reference-grouping question when
|
|
3705
|
+
* it is RENDERABLE, so an unconfirmed target reports `false` while
|
|
3706
|
+
* `angles.worker` will still pause at the END of the angles stage.
|
|
3707
|
+
* · this field adds the gates that are GUARANTEED to open: both pause flags,
|
|
3708
|
+
* plus that same worker prediction, through the one shared helper.
|
|
3709
|
+
*
|
|
3710
|
+
* Absent (undefined) means "an older API that cannot answer" — the client must
|
|
3711
|
+
* treat that as `true` and stay put. Uncertainty resolves to staying: a false
|
|
3712
|
+
* positive costs her a wait, a false negative strands her on a screen that
|
|
3713
|
+
* cannot render the gate (prod bd4d0bb1 / 52dc15a7, both refunded and
|
|
3714
|
+
* undelivered).
|
|
3715
|
+
*
|
|
3716
|
+
* ALWAYS false on a terminal task. `pauseForAngleReview` SURVIVES on completed
|
|
3717
|
+
* tasks, so without that guard a finished landing would report `true` forever
|
|
3718
|
+
* and get bounced into a chat with nothing left to ask.
|
|
3719
|
+
*/
|
|
3720
|
+
willAskAgain: z24.boolean().optional(),
|
|
3695
3721
|
/** True when an open gate exists that somebody can actually ANSWER. A strictly
|
|
3696
3722
|
* narrower fact than `needsReview` — see the identical field on `TaskSummary`
|
|
3697
3723
|
* below for why conflating the two produced a call to action that led nowhere. */
|
|
@@ -3826,6 +3852,9 @@ var CostEstimationType = z25.enum([
|
|
|
3826
3852
|
"landing-regenerate",
|
|
3827
3853
|
"landing-creative",
|
|
3828
3854
|
"campaign-copy",
|
|
3855
|
+
"brand-extract",
|
|
3856
|
+
"persona-suggest",
|
|
3857
|
+
"chat-parse",
|
|
3829
3858
|
"service-creative",
|
|
3830
3859
|
"actor-grid"
|
|
3831
3860
|
]);
|
|
@@ -3991,11 +4020,14 @@ var LandingCreativeEstimationOptions = z25.object({
|
|
|
3991
4020
|
landingStrategy: LandingStrategySchema.optional()
|
|
3992
4021
|
});
|
|
3993
4022
|
var CampaignCopyEstimationOptions = z25.object({
|
|
3994
|
-
/** Number of creatives
|
|
3995
|
-
nCreatives: z25.number().int().min(1).max(
|
|
3996
|
-
/** Number of image creatives that
|
|
3997
|
-
nImages: z25.number().int().min(0).max(
|
|
3998
|
-
});
|
|
4023
|
+
/** Number of creatives in the one copy-completion request (1-10). */
|
|
4024
|
+
nCreatives: z25.number().int().min(1).max(10),
|
|
4025
|
+
/** Number of image creatives that can each use one vision analysis (0-10). */
|
|
4026
|
+
nImages: z25.number().int().min(0).max(10).default(0)
|
|
4027
|
+
});
|
|
4028
|
+
var BrandExtractEstimationOptions = z25.object({}).strict();
|
|
4029
|
+
var PersonaSuggestEstimationOptions = z25.object({}).strict();
|
|
4030
|
+
var ChatParseEstimationOptions = z25.object({}).strict();
|
|
3999
4031
|
var ServiceCreativeEstimationOptions = z25.object({
|
|
4000
4032
|
mediaAssetCount: z25.number().int().min(0).max(8).optional(),
|
|
4001
4033
|
uploadedVideoDurationSeconds: z25.number().min(0).max(240).optional()
|
|
@@ -4034,6 +4066,18 @@ var CostEstimationRequest = z25.discriminatedUnion("type", [
|
|
|
4034
4066
|
type: z25.literal("campaign-copy"),
|
|
4035
4067
|
options: CampaignCopyEstimationOptions
|
|
4036
4068
|
}),
|
|
4069
|
+
z25.object({
|
|
4070
|
+
type: z25.literal("brand-extract"),
|
|
4071
|
+
options: BrandExtractEstimationOptions
|
|
4072
|
+
}),
|
|
4073
|
+
z25.object({
|
|
4074
|
+
type: z25.literal("persona-suggest"),
|
|
4075
|
+
options: PersonaSuggestEstimationOptions
|
|
4076
|
+
}),
|
|
4077
|
+
z25.object({
|
|
4078
|
+
type: z25.literal("chat-parse"),
|
|
4079
|
+
options: ChatParseEstimationOptions
|
|
4080
|
+
}),
|
|
4037
4081
|
z25.object({
|
|
4038
4082
|
type: z25.literal("service-creative"),
|
|
4039
4083
|
options: ServiceCreativeEstimationOptions
|
|
@@ -4533,6 +4577,9 @@ var VideoMixQaJobSchema = z30.object({
|
|
|
4533
4577
|
});
|
|
4534
4578
|
var BrandExtractJobSchema = z30.object({
|
|
4535
4579
|
brandId: z30.string().uuid(),
|
|
4580
|
+
// Generation is part of the durable paid-spend identity. Default 1 keeps
|
|
4581
|
+
// pre-migration BullMQ payloads parseable; their DB state fails safe.
|
|
4582
|
+
generation: z30.number().int().positive().default(1),
|
|
4536
4583
|
url: z30.string().url().refine((value) => {
|
|
4537
4584
|
const protocol = new URL(value).protocol;
|
|
4538
4585
|
return protocol === "http:" || protocol === "https:";
|
|
@@ -5578,6 +5625,10 @@ var TikTokCreateCampaignResponseSchema = z35.object({
|
|
|
5578
5625
|
adsManagerUrl: z35.string().optional()
|
|
5579
5626
|
});
|
|
5580
5627
|
|
|
5628
|
+
// ../../packages/types/src/pricing-gemini-omni.ts
|
|
5629
|
+
var GEMINI_OMNI_FLAT_OUR_COST_CENTS = 84;
|
|
5630
|
+
var GEMINI_OMNI_FLAT_USER_PRICE_CENTS = 168;
|
|
5631
|
+
|
|
5581
5632
|
// ../../packages/types/src/pricing.ts
|
|
5582
5633
|
var CREDITS_PER_USD_CENT = 10;
|
|
5583
5634
|
var CREDITS_PER_DOLLAR = 100 * CREDITS_PER_USD_CENT;
|
|
@@ -5986,6 +6037,18 @@ var DEFAULT_PRICING = {
|
|
|
5986
6037
|
ourCostCents: 120,
|
|
5987
6038
|
userPriceCents: 240
|
|
5988
6039
|
},
|
|
6040
|
+
// Gemini Omni Video (gemini-omni-video) — Mix primary generator since
|
|
6041
|
+
// 2026-08-18. FLAT per generation: 168 KIE credits = $0.84, identical at
|
|
6042
|
+
// 720p and 1080p and independent of the 3.5-10s trim window. Do NOT add
|
|
6043
|
+
// per-second overrides for this key — resolveSuccessBilling bills it flat.
|
|
6044
|
+
//
|
|
6045
|
+
// Shares the constants with the pre-submit ESTIMATOR (mix-cost.ts) rather
|
|
6046
|
+
// than repeating the numbers: a literal here that drifted from the estimator
|
|
6047
|
+
// would quote one price and charge another on every mix.
|
|
6048
|
+
"kie:gemini-omni-video": {
|
|
6049
|
+
ourCostCents: GEMINI_OMNI_FLAT_OUR_COST_CENTS,
|
|
6050
|
+
userPriceCents: GEMINI_OMNI_FLAT_USER_PRICE_CENTS
|
|
6051
|
+
},
|
|
5989
6052
|
"kie:video-lipsync-generation": {
|
|
5990
6053
|
ourCostCents: 45,
|
|
5991
6054
|
userPriceCents: 90
|
|
@@ -7949,7 +8012,57 @@ var FeatureSpec = z36.object({
|
|
|
7949
8012
|
});
|
|
7950
8013
|
|
|
7951
8014
|
// ../../packages/types/src/mix.ts
|
|
8015
|
+
import { z as z38 } from "zod";
|
|
8016
|
+
|
|
8017
|
+
// ../../packages/types/src/mix-degradation.ts
|
|
7952
8018
|
import { z as z37 } from "zod";
|
|
8019
|
+
var MIX_DEGRADATION_REASONS = [
|
|
8020
|
+
/**
|
|
8021
|
+
* At least one scene the mix PLANNED is missing from the delivered video, so
|
|
8022
|
+
* the result is shorter than the source. Set at assemble time by comparing
|
|
8023
|
+
* the concat set against the planned scene set — the scene's own code (if it
|
|
8024
|
+
* had one) never reaches the mix-level rollup, which only sees scenes that
|
|
8025
|
+
* SUCCEEDED, and that is exactly how a live 17.00s-of-20.00s delivery
|
|
8026
|
+
* shipped with degradedReason NULL and no banner at all.
|
|
8027
|
+
*
|
|
8028
|
+
* ORDERING: FIRST, above every refusal code. A short delivery must never be
|
|
8029
|
+
* MASKED. It used to sit below the three content refusals on the theory that
|
|
8030
|
+
* a refusal names something the user can change AND explains the missing
|
|
8031
|
+
* scene — but it does neither reliably: in a 3-scene mix where scene 1 fails
|
|
8032
|
+
* outright and scene 2 ships through Wan after a reference refusal, the
|
|
8033
|
+
* refusal copy reads "we used a lower-quality alternative", a claim about
|
|
8034
|
+
* QUALITY that says nothing about the video being shorter than what was paid
|
|
8035
|
+
* for, and that is actively wrong about the dropped scene (for which we used
|
|
8036
|
+
* nothing). Every other code in this list describes a scene that DID ship.
|
|
8037
|
+
*/
|
|
8038
|
+
"scenes_dropped",
|
|
8039
|
+
/** Google's safety filter rejected the user's reference photo. Deterministic. */
|
|
8040
|
+
"reference_rejected",
|
|
8041
|
+
/** Google refused the wording of the change description. */
|
|
8042
|
+
"prompt_rejected",
|
|
8043
|
+
/**
|
|
8044
|
+
* The provider refused the content but its message names neither the
|
|
8045
|
+
* reference nor the wording, so we cannot say which. Distinct from
|
|
8046
|
+
* 'provider_unavailable' on purpose: "unavailable" invites the user to retry
|
|
8047
|
+
* unchanged, which can never succeed against a content refusal and only
|
|
8048
|
+
* burns their credits. This code tells them something must change.
|
|
8049
|
+
*/
|
|
8050
|
+
"content_rejected",
|
|
8051
|
+
/**
|
|
8052
|
+
* The scene's length fell outside Gemini's usable 3.5s-10s trim window —
|
|
8053
|
+
* EITHER bound. Deliberately ONE code for both: the user controls neither
|
|
8054
|
+
* (scene segmentation is entirely ours), so "too short" and "too long" are
|
|
8055
|
+
* not differently actionable, and one honest explanation beats two that
|
|
8056
|
+
* both amount to "our segmentation produced a length the primary generator
|
|
8057
|
+
* cannot take".
|
|
8058
|
+
*/
|
|
8059
|
+
"scene_length_unsupported",
|
|
8060
|
+
/** Transient provider failures exhausted the budget. */
|
|
8061
|
+
"provider_unavailable"
|
|
8062
|
+
];
|
|
8063
|
+
var MixDegradationReasonSchema = z37.enum(MIX_DEGRADATION_REASONS);
|
|
8064
|
+
|
|
8065
|
+
// ../../packages/types/src/mix.ts
|
|
7953
8066
|
var MEDIA_TYPES = [
|
|
7954
8067
|
"video",
|
|
7955
8068
|
"image"
|
|
@@ -7987,38 +8100,38 @@ function isPublicHttpsUrl(raw) {
|
|
|
7987
8100
|
return true;
|
|
7988
8101
|
}
|
|
7989
8102
|
__name(isPublicHttpsUrl, "isPublicHttpsUrl");
|
|
7990
|
-
var PublicHttpsUrl =
|
|
8103
|
+
var PublicHttpsUrl = z38.string().url().refine(isPublicHttpsUrl, {
|
|
7991
8104
|
message: "must be a public HTTPS URL"
|
|
7992
8105
|
});
|
|
7993
|
-
var InternalAssetPath =
|
|
7994
|
-
var MixImageUrl =
|
|
8106
|
+
var InternalAssetPath = z38.string().regex(/^\/(?:api|v1)\/assets\/[A-Za-z0-9._~%/-]+$/, "must be a public HTTPS URL or an internal asset path");
|
|
8107
|
+
var MixImageUrl = z38.union([
|
|
7995
8108
|
PublicHttpsUrl,
|
|
7996
8109
|
InternalAssetPath
|
|
7997
8110
|
]);
|
|
7998
|
-
var MixAxes =
|
|
7999
|
-
product:
|
|
8000
|
-
person:
|
|
8001
|
-
setting:
|
|
8002
|
-
});
|
|
8003
|
-
var MixReferences =
|
|
8004
|
-
product:
|
|
8005
|
-
person:
|
|
8006
|
-
setting:
|
|
8007
|
-
});
|
|
8008
|
-
var MixImageEdit =
|
|
8009
|
-
instruction:
|
|
8010
|
-
imageUrls:
|
|
8011
|
-
});
|
|
8012
|
-
var MixRequest =
|
|
8013
|
-
mediaType:
|
|
8014
|
-
originalUrl:
|
|
8111
|
+
var MixAxes = z38.object({
|
|
8112
|
+
product: z38.boolean(),
|
|
8113
|
+
person: z38.boolean(),
|
|
8114
|
+
setting: z38.boolean()
|
|
8115
|
+
});
|
|
8116
|
+
var MixReferences = z38.object({
|
|
8117
|
+
product: z38.array(PublicHttpsUrl).max(3, "at most 3 product references"),
|
|
8118
|
+
person: z38.array(PublicHttpsUrl).max(3, "at most 3 person references"),
|
|
8119
|
+
setting: z38.array(PublicHttpsUrl).max(3, "at most 3 setting references")
|
|
8120
|
+
});
|
|
8121
|
+
var MixImageEdit = z38.object({
|
|
8122
|
+
instruction: z38.string().min(1).max(600),
|
|
8123
|
+
imageUrls: z38.array(MixImageUrl).min(1).max(3)
|
|
8124
|
+
});
|
|
8125
|
+
var MixRequest = z38.object({
|
|
8126
|
+
mediaType: z38.enum(MEDIA_TYPES),
|
|
8127
|
+
originalUrl: z38.union([
|
|
8015
8128
|
PublicHttpsUrl,
|
|
8016
8129
|
InternalAssetPath
|
|
8017
8130
|
]),
|
|
8018
8131
|
axes: MixAxes,
|
|
8019
8132
|
references: MixReferences,
|
|
8020
|
-
personText:
|
|
8021
|
-
settingText:
|
|
8133
|
+
personText: z38.string().max(500).optional(),
|
|
8134
|
+
settingText: z38.string().max(500).optional(),
|
|
8022
8135
|
/**
|
|
8023
8136
|
* Optional public URL of a user-uploaded audio file (mp3/wav). Wan Video
|
|
8024
8137
|
* Edit has no audio input and the mix never lipsyncs: the Wan output is
|
|
@@ -8027,11 +8140,11 @@ var MixRequest = z37.object({
|
|
|
8027
8140
|
* (mute + overlay). No per-scene slicing, no `reference_audio_urls`.
|
|
8028
8141
|
*/
|
|
8029
8142
|
audioUrl: PublicHttpsUrl.optional(),
|
|
8030
|
-
resolution:
|
|
8031
|
-
originalDurationSec:
|
|
8143
|
+
resolution: z38.enum(RESOLUTIONS).default("720p"),
|
|
8144
|
+
originalDurationSec: z38.number().positive().max(600).optional(),
|
|
8032
8145
|
image: MixImageEdit.optional(),
|
|
8033
|
-
sourceTaskId:
|
|
8034
|
-
sourceCreativeId:
|
|
8146
|
+
sourceTaskId: z38.string().max(64).optional(),
|
|
8147
|
+
sourceCreativeId: z38.string().max(64).optional()
|
|
8035
8148
|
}).superRefine((req, ctx) => {
|
|
8036
8149
|
if (req.mediaType === "image") {
|
|
8037
8150
|
if (!req.image) {
|
|
@@ -8065,18 +8178,18 @@ var MixRequest = z37.object({
|
|
|
8065
8178
|
});
|
|
8066
8179
|
}
|
|
8067
8180
|
});
|
|
8068
|
-
var ReferenceMap =
|
|
8069
|
-
product:
|
|
8070
|
-
start:
|
|
8071
|
-
end:
|
|
8181
|
+
var ReferenceMap = z38.object({
|
|
8182
|
+
product: z38.object({
|
|
8183
|
+
start: z38.number().int(),
|
|
8184
|
+
end: z38.number().int()
|
|
8072
8185
|
}).optional(),
|
|
8073
|
-
person:
|
|
8074
|
-
start:
|
|
8075
|
-
end:
|
|
8186
|
+
person: z38.object({
|
|
8187
|
+
start: z38.number().int(),
|
|
8188
|
+
end: z38.number().int()
|
|
8076
8189
|
}).optional(),
|
|
8077
|
-
setting:
|
|
8078
|
-
start:
|
|
8079
|
-
end:
|
|
8190
|
+
setting: z38.object({
|
|
8191
|
+
start: z38.number().int(),
|
|
8192
|
+
end: z38.number().int()
|
|
8080
8193
|
}).optional()
|
|
8081
8194
|
});
|
|
8082
8195
|
var SCENE_CLIP_TYPES = [
|
|
@@ -8092,39 +8205,39 @@ var INSTANCE_CARDINALITIES = [
|
|
|
8092
8205
|
"multiple_same",
|
|
8093
8206
|
"multiple_distinct"
|
|
8094
8207
|
];
|
|
8095
|
-
var SceneSegment =
|
|
8096
|
-
index:
|
|
8097
|
-
startTs:
|
|
8098
|
-
endTs:
|
|
8099
|
-
seedanceDuration:
|
|
8208
|
+
var SceneSegment = z38.object({
|
|
8209
|
+
index: z38.number().int().positive(),
|
|
8210
|
+
startTs: z38.number().nonnegative(),
|
|
8211
|
+
endTs: z38.number().positive(),
|
|
8212
|
+
seedanceDuration: z38.number().int().min(4).max(15),
|
|
8100
8213
|
// Pass 1 / Pass 2 outputs (all optional — populated when the rich analyzer
|
|
8101
8214
|
// runs and empty on fallback).
|
|
8102
|
-
action:
|
|
8103
|
-
motion:
|
|
8104
|
-
clipType:
|
|
8105
|
-
hasCharacter:
|
|
8106
|
-
faceVisible:
|
|
8215
|
+
action: z38.string().optional(),
|
|
8216
|
+
motion: z38.string().optional(),
|
|
8217
|
+
clipType: z38.enum(SCENE_CLIP_TYPES).optional(),
|
|
8218
|
+
hasCharacter: z38.boolean().optional(),
|
|
8219
|
+
faceVisible: z38.boolean().optional(),
|
|
8107
8220
|
// Pass 2 refinement — rich per-scene metadata used by buildMixPrompt.
|
|
8108
|
-
startState:
|
|
8109
|
-
endState:
|
|
8110
|
-
cameraMovement:
|
|
8111
|
-
emotion:
|
|
8112
|
-
productPlacement:
|
|
8113
|
-
productInteraction:
|
|
8114
|
-
settingDescription:
|
|
8115
|
-
dialogue:
|
|
8221
|
+
startState: z38.string().optional(),
|
|
8222
|
+
endState: z38.string().optional(),
|
|
8223
|
+
cameraMovement: z38.string().optional(),
|
|
8224
|
+
emotion: z38.string().optional(),
|
|
8225
|
+
productPlacement: z38.string().optional(),
|
|
8226
|
+
productInteraction: z38.string().optional(),
|
|
8227
|
+
settingDescription: z38.string().optional(),
|
|
8228
|
+
dialogue: z38.string().optional(),
|
|
8116
8229
|
// Main vs extras / noise (our addition on top of the script's schema).
|
|
8117
|
-
mainPersonDescription:
|
|
8118
|
-
mainProductDescription:
|
|
8119
|
-
personInstances:
|
|
8120
|
-
productInstances:
|
|
8230
|
+
mainPersonDescription: z38.string().optional(),
|
|
8231
|
+
mainProductDescription: z38.string().optional(),
|
|
8232
|
+
personInstances: z38.enum(INSTANCE_CARDINALITIES).optional(),
|
|
8233
|
+
productInstances: z38.enum(INSTANCE_CARDINALITIES).optional(),
|
|
8121
8234
|
/**
|
|
8122
8235
|
* Seconds of prev-clipType content absorbed at the start of this scene by
|
|
8123
8236
|
* Pass 2.7's clipType boundary margin. When > 0 and the scene is a
|
|
8124
8237
|
* pass-through (no Seedance), the concatenator prepends a held-still
|
|
8125
8238
|
* preamble (nano-banana-swapped first frame) to hide the leak.
|
|
8126
8239
|
*/
|
|
8127
|
-
absorbedMarginSec:
|
|
8240
|
+
absorbedMarginSec: z38.number().nonnegative().optional(),
|
|
8128
8241
|
/**
|
|
8129
8242
|
* True when the scene shows post-production graphics baked into the frame:
|
|
8130
8243
|
* caption/subtitle text, infographic overlay cards, or inset
|
|
@@ -8133,33 +8246,39 @@ var SceneSegment = z37.object({
|
|
|
8133
8246
|
* (mentioning nonexistent overlays gives the generator license to
|
|
8134
8247
|
* fabricate them).
|
|
8135
8248
|
*/
|
|
8136
|
-
hasOverlayGraphics:
|
|
8249
|
+
hasOverlayGraphics: z38.boolean().optional()
|
|
8137
8250
|
});
|
|
8138
|
-
var MixSceneResult =
|
|
8139
|
-
index:
|
|
8140
|
-
status:
|
|
8251
|
+
var MixSceneResult = z38.object({
|
|
8252
|
+
index: z38.number().int().positive(),
|
|
8253
|
+
status: z38.enum([
|
|
8141
8254
|
"queued",
|
|
8142
8255
|
"submitted",
|
|
8143
8256
|
"done",
|
|
8144
8257
|
"failed"
|
|
8145
8258
|
]),
|
|
8146
|
-
seedanceTaskId:
|
|
8147
|
-
videoUrl:
|
|
8148
|
-
error:
|
|
8149
|
-
|
|
8150
|
-
|
|
8151
|
-
|
|
8152
|
-
|
|
8259
|
+
seedanceTaskId: z38.string().optional(),
|
|
8260
|
+
videoUrl: z38.string().url().optional(),
|
|
8261
|
+
error: z38.string().optional(),
|
|
8262
|
+
degradedReason: MixDegradationReasonSchema.optional()
|
|
8263
|
+
});
|
|
8264
|
+
var MixResult = z38.object({
|
|
8265
|
+
mixTaskId: z38.string().uuid(),
|
|
8266
|
+
status: z38.enum([
|
|
8153
8267
|
"queued",
|
|
8154
8268
|
"processing",
|
|
8155
8269
|
"done",
|
|
8156
8270
|
"error"
|
|
8157
8271
|
]),
|
|
8158
|
-
resultUrl:
|
|
8159
|
-
scenes:
|
|
8160
|
-
failReason:
|
|
8272
|
+
resultUrl: z38.string().url().optional(),
|
|
8273
|
+
scenes: z38.array(MixSceneResult).default([]),
|
|
8274
|
+
failReason: z38.string().optional(),
|
|
8275
|
+
degradedReason: MixDegradationReasonSchema.optional()
|
|
8161
8276
|
});
|
|
8162
8277
|
|
|
8278
|
+
// ../../packages/types/src/mix-cost.ts
|
|
8279
|
+
var MAX_QA_RETRIES_PER_SCENE_UPPER_BOUND = 1;
|
|
8280
|
+
var MAX_BILLABLE_GENERATIONS_PER_BLOCK = 1 + MAX_QA_RETRIES_PER_SCENE_UPPER_BOUND;
|
|
8281
|
+
|
|
8163
8282
|
// ../../packages/types/src/product-delivery-format.ts
|
|
8164
8283
|
var DELIVERY_FAMILIES = [
|
|
8165
8284
|
"solid_dose",
|
|
@@ -8248,41 +8367,41 @@ var DECLARATION = DELIVERY_FAMILIES.map((family) => [
|
|
|
8248
8367
|
]);
|
|
8249
8368
|
|
|
8250
8369
|
// ../../packages/types/src/task-type.ts
|
|
8251
|
-
import { z as
|
|
8252
|
-
var TaskTypeSchema =
|
|
8370
|
+
import { z as z39 } from "zod";
|
|
8371
|
+
var TaskTypeSchema = z39.enum([
|
|
8253
8372
|
"product",
|
|
8254
8373
|
"service"
|
|
8255
8374
|
]);
|
|
8256
8375
|
|
|
8257
8376
|
// ../../packages/types/src/landing-regeneration.ts
|
|
8258
|
-
import { z as
|
|
8259
|
-
var LandingRegenerationStatus =
|
|
8377
|
+
import { z as z40 } from "zod";
|
|
8378
|
+
var LandingRegenerationStatus = z40.enum([
|
|
8260
8379
|
"queued",
|
|
8261
8380
|
"processing",
|
|
8262
8381
|
"published",
|
|
8263
8382
|
"failed"
|
|
8264
8383
|
]);
|
|
8265
|
-
var RegenerateLandingRoleResponse =
|
|
8266
|
-
ok:
|
|
8384
|
+
var RegenerateLandingRoleResponse = z40.object({
|
|
8385
|
+
ok: z40.literal(true),
|
|
8267
8386
|
role: LandingRole,
|
|
8268
|
-
promptIndex:
|
|
8269
|
-
operationId:
|
|
8387
|
+
promptIndex: z40.number().int().nonnegative(),
|
|
8388
|
+
operationId: z40.string().min(1)
|
|
8270
8389
|
});
|
|
8271
|
-
var LandingRegenerationStatusResponse =
|
|
8272
|
-
ok:
|
|
8273
|
-
operationId:
|
|
8390
|
+
var LandingRegenerationStatusResponse = z40.object({
|
|
8391
|
+
ok: z40.literal(true),
|
|
8392
|
+
operationId: z40.string().min(1),
|
|
8274
8393
|
role: LandingRole,
|
|
8275
8394
|
status: LandingRegenerationStatus,
|
|
8276
|
-
refunded:
|
|
8277
|
-
failureReason:
|
|
8278
|
-
publishedAssetKey:
|
|
8279
|
-
updatedAt:
|
|
8395
|
+
refunded: z40.boolean(),
|
|
8396
|
+
failureReason: z40.string().nullable(),
|
|
8397
|
+
publishedAssetKey: z40.string().nullable(),
|
|
8398
|
+
updatedAt: z40.string().datetime()
|
|
8280
8399
|
});
|
|
8281
8400
|
|
|
8282
8401
|
// ../../packages/types/src/video-edit.ts
|
|
8283
|
-
import { z as
|
|
8402
|
+
import { z as z41 } from "zod";
|
|
8284
8403
|
var MAX_SEGMENT_SECONDS = 3;
|
|
8285
|
-
var VideoEditStatusSchema =
|
|
8404
|
+
var VideoEditStatusSchema = z41.enum([
|
|
8286
8405
|
"pending",
|
|
8287
8406
|
"processing",
|
|
8288
8407
|
"assembling",
|
|
@@ -8291,9 +8410,9 @@ var VideoEditStatusSchema = z40.enum([
|
|
|
8291
8410
|
"discarded",
|
|
8292
8411
|
"failed"
|
|
8293
8412
|
]);
|
|
8294
|
-
var VideoEditTimeSectionSchema =
|
|
8295
|
-
startSec:
|
|
8296
|
-
endSec:
|
|
8413
|
+
var VideoEditTimeSectionSchema = z41.object({
|
|
8414
|
+
startSec: z41.number().min(0),
|
|
8415
|
+
endSec: z41.number().positive()
|
|
8297
8416
|
}).refine((v) => v.endSec > v.startSec, {
|
|
8298
8417
|
message: "endSec must be after startSec",
|
|
8299
8418
|
path: [
|
|
@@ -8305,45 +8424,45 @@ var VideoEditTimeSectionSchema = z40.object({
|
|
|
8305
8424
|
"endSec"
|
|
8306
8425
|
]
|
|
8307
8426
|
});
|
|
8308
|
-
var VideoEditRequestSchema =
|
|
8309
|
-
comment:
|
|
8310
|
-
sections:
|
|
8427
|
+
var VideoEditRequestSchema = z41.object({
|
|
8428
|
+
comment: z41.string().trim().min(1).max(2e3),
|
|
8429
|
+
sections: z41.array(VideoEditTimeSectionSchema).min(1).optional()
|
|
8311
8430
|
});
|
|
8312
|
-
var VideoEditModeSchema =
|
|
8431
|
+
var VideoEditModeSchema = z41.enum([
|
|
8313
8432
|
"wan_edit",
|
|
8314
8433
|
"regenerate"
|
|
8315
8434
|
]);
|
|
8316
|
-
var VideoRegenerationEngineSchema =
|
|
8435
|
+
var VideoRegenerationEngineSchema = z41.enum([
|
|
8317
8436
|
"free_text",
|
|
8318
8437
|
"free_image",
|
|
8319
8438
|
"single_call",
|
|
8320
8439
|
"multi_shot"
|
|
8321
8440
|
]);
|
|
8322
|
-
var VideoRegenerationRouteFingerprintSchema =
|
|
8323
|
-
var RegenerateEditRequestSchema =
|
|
8324
|
-
angleKey:
|
|
8325
|
-
comment:
|
|
8441
|
+
var VideoRegenerationRouteFingerprintSchema = z41.string().trim().min(1).max(128);
|
|
8442
|
+
var RegenerateEditRequestSchema = z41.object({
|
|
8443
|
+
angleKey: z41.string().min(1),
|
|
8444
|
+
comment: z41.string().min(1).max(2e3)
|
|
8326
8445
|
});
|
|
8327
8446
|
|
|
8328
8447
|
// ../../packages/types/src/uploaded-asset.ts
|
|
8329
|
-
import { z as
|
|
8330
|
-
var UploadedAssetMediaKind =
|
|
8448
|
+
import { z as z42 } from "zod";
|
|
8449
|
+
var UploadedAssetMediaKind = z42.enum([
|
|
8331
8450
|
"image",
|
|
8332
8451
|
"video"
|
|
8333
8452
|
]);
|
|
8334
|
-
var UploadedAssetSessionMediaKind =
|
|
8453
|
+
var UploadedAssetSessionMediaKind = z42.enum([
|
|
8335
8454
|
"image",
|
|
8336
8455
|
"video",
|
|
8337
8456
|
"mixed"
|
|
8338
8457
|
]);
|
|
8339
|
-
var UploadedAssetRole =
|
|
8458
|
+
var UploadedAssetRole = z42.enum([
|
|
8340
8459
|
"media",
|
|
8341
8460
|
"thumbnail"
|
|
8342
8461
|
]);
|
|
8343
8462
|
var UPLOADED_ASSET_MAX_FILES = 10;
|
|
8344
8463
|
var UPLOADED_ASSET_IMAGE_MAX_FILES = 5;
|
|
8345
|
-
var UploadedAssetId =
|
|
8346
|
-
var HttpsUrl =
|
|
8464
|
+
var UploadedAssetId = z42.string().uuid();
|
|
8465
|
+
var HttpsUrl = z42.string().url().refine((value) => {
|
|
8347
8466
|
try {
|
|
8348
8467
|
const url = new URL(value);
|
|
8349
8468
|
return url.protocol === "https:" && !url.username && !url.password;
|
|
@@ -8351,23 +8470,23 @@ var HttpsUrl = z41.string().url().refine((value) => {
|
|
|
8351
8470
|
return false;
|
|
8352
8471
|
}
|
|
8353
8472
|
}, "URL must use https");
|
|
8354
|
-
var UtcDateTime =
|
|
8473
|
+
var UtcDateTime = z42.string().datetime().refine((value) => {
|
|
8355
8474
|
const parts = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?Z$/.exec(value);
|
|
8356
8475
|
const timestamp = Date.parse(value);
|
|
8357
8476
|
if (!parts || Number.isNaN(timestamp)) return false;
|
|
8358
8477
|
const date = new Date(timestamp);
|
|
8359
8478
|
return date.getUTCFullYear() === Number(parts[1]) && date.getUTCMonth() + 1 === Number(parts[2]) && date.getUTCDate() === Number(parts[3]) && date.getUTCHours() === Number(parts[4]) && date.getUTCMinutes() === Number(parts[5]) && date.getUTCSeconds() === Number(parts[6]);
|
|
8360
8479
|
}, "datetime must be a valid UTC calendar instant");
|
|
8361
|
-
var UploadedAssetRef =
|
|
8480
|
+
var UploadedAssetRef = z42.object({
|
|
8362
8481
|
assetId: UploadedAssetId
|
|
8363
8482
|
}).strict();
|
|
8364
8483
|
var UploadedAssetCompletion = UploadedAssetRef.extend({
|
|
8365
8484
|
mediaKind: UploadedAssetMediaKind,
|
|
8366
8485
|
assetRole: UploadedAssetRole
|
|
8367
8486
|
}).strict();
|
|
8368
|
-
var UploadedAssetMetadata =
|
|
8487
|
+
var UploadedAssetMetadata = z42.object({
|
|
8369
8488
|
assetId: UploadedAssetId,
|
|
8370
|
-
ownerId:
|
|
8489
|
+
ownerId: z42.string().min(1),
|
|
8371
8490
|
mediaKind: UploadedAssetMediaKind,
|
|
8372
8491
|
assetRole: UploadedAssetRole,
|
|
8373
8492
|
createdAt: UtcDateTime,
|
|
@@ -8375,7 +8494,7 @@ var UploadedAssetMetadata = z41.object({
|
|
|
8375
8494
|
}).strict().superRefine((value, ctx) => {
|
|
8376
8495
|
if (Date.parse(value.expiresAt) <= Date.parse(value.createdAt)) {
|
|
8377
8496
|
ctx.addIssue({
|
|
8378
|
-
code:
|
|
8497
|
+
code: z42.ZodIssueCode.custom,
|
|
8379
8498
|
path: [
|
|
8380
8499
|
"expiresAt"
|
|
8381
8500
|
],
|
|
@@ -8383,27 +8502,27 @@ var UploadedAssetMetadata = z41.object({
|
|
|
8383
8502
|
});
|
|
8384
8503
|
}
|
|
8385
8504
|
});
|
|
8386
|
-
var MediaSourceRef =
|
|
8505
|
+
var MediaSourceRef = z42.object({
|
|
8387
8506
|
url: HttpsUrl.optional(),
|
|
8388
|
-
path:
|
|
8507
|
+
path: z42.string().min(1).optional(),
|
|
8389
8508
|
assetId: UploadedAssetId.optional()
|
|
8390
8509
|
}).strict().superRefine((value, ctx) => {
|
|
8391
8510
|
const sourceCount = Number(value.url !== void 0) + Number(value.path !== void 0) + Number(value.assetId !== void 0);
|
|
8392
8511
|
if (sourceCount !== 1) {
|
|
8393
8512
|
ctx.addIssue({
|
|
8394
|
-
code:
|
|
8513
|
+
code: z42.ZodIssueCode.custom,
|
|
8395
8514
|
message: "media source needs exactly one of url, path, or assetId"
|
|
8396
8515
|
});
|
|
8397
8516
|
}
|
|
8398
8517
|
});
|
|
8399
|
-
var UploadedAssetSessionRequest =
|
|
8518
|
+
var UploadedAssetSessionRequest = z42.object({
|
|
8400
8519
|
mediaKind: UploadedAssetSessionMediaKind,
|
|
8401
8520
|
assetRole: UploadedAssetRole.default("media"),
|
|
8402
|
-
maxFiles:
|
|
8521
|
+
maxFiles: z42.number().int().min(1).max(UPLOADED_ASSET_MAX_FILES).optional()
|
|
8403
8522
|
}).strict().superRefine((value, ctx) => {
|
|
8404
8523
|
if (value.mediaKind === "mixed" && value.assetRole === "thumbnail") {
|
|
8405
8524
|
ctx.addIssue({
|
|
8406
|
-
code:
|
|
8525
|
+
code: z42.ZodIssueCode.custom,
|
|
8407
8526
|
path: [
|
|
8408
8527
|
"mediaKind"
|
|
8409
8528
|
],
|
|
@@ -8412,7 +8531,7 @@ var UploadedAssetSessionRequest = z41.object({
|
|
|
8412
8531
|
}
|
|
8413
8532
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
8414
8533
|
ctx.addIssue({
|
|
8415
|
-
code:
|
|
8534
|
+
code: z42.ZodIssueCode.custom,
|
|
8416
8535
|
path: [
|
|
8417
8536
|
"maxFiles"
|
|
8418
8537
|
],
|
|
@@ -8421,7 +8540,7 @@ var UploadedAssetSessionRequest = z41.object({
|
|
|
8421
8540
|
}
|
|
8422
8541
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > UPLOADED_ASSET_IMAGE_MAX_FILES) {
|
|
8423
8542
|
ctx.addIssue({
|
|
8424
|
-
code:
|
|
8543
|
+
code: z42.ZodIssueCode.custom,
|
|
8425
8544
|
path: [
|
|
8426
8545
|
"maxFiles"
|
|
8427
8546
|
],
|
|
@@ -8430,7 +8549,7 @@ var UploadedAssetSessionRequest = z41.object({
|
|
|
8430
8549
|
}
|
|
8431
8550
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
8432
8551
|
ctx.addIssue({
|
|
8433
|
-
code:
|
|
8552
|
+
code: z42.ZodIssueCode.custom,
|
|
8434
8553
|
path: [
|
|
8435
8554
|
"mediaKind"
|
|
8436
8555
|
],
|
|
@@ -8438,32 +8557,32 @@ var UploadedAssetSessionRequest = z41.object({
|
|
|
8438
8557
|
});
|
|
8439
8558
|
}
|
|
8440
8559
|
});
|
|
8441
|
-
var UploadedAssetSessionStatus =
|
|
8442
|
-
|
|
8443
|
-
status:
|
|
8444
|
-
assets:
|
|
8560
|
+
var UploadedAssetSessionStatus = z42.discriminatedUnion("status", [
|
|
8561
|
+
z42.object({
|
|
8562
|
+
status: z42.literal("pending"),
|
|
8563
|
+
assets: z42.array(UploadedAssetCompletion).length(0)
|
|
8445
8564
|
}).strict(),
|
|
8446
|
-
|
|
8447
|
-
status:
|
|
8448
|
-
assets:
|
|
8565
|
+
z42.object({
|
|
8566
|
+
status: z42.literal("uploaded"),
|
|
8567
|
+
assets: z42.array(UploadedAssetCompletion).min(1).max(UPLOADED_ASSET_MAX_FILES)
|
|
8449
8568
|
}).strict()
|
|
8450
8569
|
]);
|
|
8451
|
-
var UploadedAssetAdoptionRequest =
|
|
8570
|
+
var UploadedAssetAdoptionRequest = z42.object({
|
|
8452
8571
|
assetId: UploadedAssetId,
|
|
8453
|
-
ownerId:
|
|
8454
|
-
consumer:
|
|
8455
|
-
idempotencyKey:
|
|
8572
|
+
ownerId: z42.string().min(1),
|
|
8573
|
+
consumer: z42.string().min(1).max(100),
|
|
8574
|
+
idempotencyKey: z42.string().min(1).max(255)
|
|
8456
8575
|
}).strict();
|
|
8457
8576
|
|
|
8458
8577
|
// ../../packages/types/src/dropshipping-project.ts
|
|
8459
|
-
import { z as
|
|
8460
|
-
var DropshippingProjectStatusSchema =
|
|
8578
|
+
import { z as z43 } from "zod";
|
|
8579
|
+
var DropshippingProjectStatusSchema = z43.enum([
|
|
8461
8580
|
"active",
|
|
8462
8581
|
"completed",
|
|
8463
8582
|
"archived"
|
|
8464
8583
|
]);
|
|
8465
8584
|
var DROPSHIPPING_LAUNCH_REWARD_CAMPAIGN = "dropshipping-launch-v1";
|
|
8466
|
-
var DropshippingRewardMilestoneSchema =
|
|
8585
|
+
var DropshippingRewardMilestoneSchema = z43.enum([
|
|
8467
8586
|
"product_selected",
|
|
8468
8587
|
"costing_saved",
|
|
8469
8588
|
"product_media_ready",
|
|
@@ -8478,21 +8597,21 @@ var DROPSHIPPING_LAUNCH_REWARD_CREDITS = {
|
|
|
8478
8597
|
campaign_created: 200
|
|
8479
8598
|
};
|
|
8480
8599
|
var DROPSHIPPING_LAUNCH_REWARD_TOTAL_CREDITS = Object.values(DROPSHIPPING_LAUNCH_REWARD_CREDITS).reduce((sum, credits) => sum + credits, 0);
|
|
8481
|
-
var DropshippingProjectRewardMilestoneStateSchema =
|
|
8600
|
+
var DropshippingProjectRewardMilestoneStateSchema = z43.object({
|
|
8482
8601
|
milestone: DropshippingRewardMilestoneSchema,
|
|
8483
|
-
credits:
|
|
8484
|
-
available:
|
|
8485
|
-
earned:
|
|
8486
|
-
grantId:
|
|
8487
|
-
grantedAt:
|
|
8488
|
-
});
|
|
8489
|
-
var DropshippingProjectRewardProgressSchema =
|
|
8490
|
-
campaignKey:
|
|
8491
|
-
totalCredits:
|
|
8492
|
-
earnedCredits:
|
|
8493
|
-
milestones:
|
|
8494
|
-
});
|
|
8495
|
-
var DropshippingProjectPhaseSchema =
|
|
8602
|
+
credits: z43.number().int().positive(),
|
|
8603
|
+
available: z43.boolean().optional(),
|
|
8604
|
+
earned: z43.boolean(),
|
|
8605
|
+
grantId: z43.string().uuid().nullable(),
|
|
8606
|
+
grantedAt: z43.string().datetime().nullable()
|
|
8607
|
+
});
|
|
8608
|
+
var DropshippingProjectRewardProgressSchema = z43.object({
|
|
8609
|
+
campaignKey: z43.literal(DROPSHIPPING_LAUNCH_REWARD_CAMPAIGN),
|
|
8610
|
+
totalCredits: z43.number().int().positive(),
|
|
8611
|
+
earnedCredits: z43.number().int().nonnegative(),
|
|
8612
|
+
milestones: z43.array(DropshippingProjectRewardMilestoneStateSchema).length(DropshippingRewardMilestoneSchema.options.length)
|
|
8613
|
+
});
|
|
8614
|
+
var DropshippingProjectPhaseSchema = z43.enum([
|
|
8496
8615
|
"research",
|
|
8497
8616
|
"costing",
|
|
8498
8617
|
"media",
|
|
@@ -8501,18 +8620,18 @@ var DropshippingProjectPhaseSchema = z42.enum([
|
|
|
8501
8620
|
"advertising",
|
|
8502
8621
|
"complete"
|
|
8503
8622
|
]);
|
|
8504
|
-
var DropshippingProjectCostingInputSchema =
|
|
8505
|
-
country:
|
|
8506
|
-
supplierCost:
|
|
8507
|
-
shippingCost:
|
|
8508
|
-
returnRate:
|
|
8509
|
-
cancellationRate:
|
|
8510
|
-
adsManagerCpa:
|
|
8511
|
-
desiredMargin:
|
|
8623
|
+
var DropshippingProjectCostingInputSchema = z43.object({
|
|
8624
|
+
country: z43.string().min(2).max(3),
|
|
8625
|
+
supplierCost: z43.number().finite().positive(),
|
|
8626
|
+
shippingCost: z43.number().finite().nonnegative(),
|
|
8627
|
+
returnRate: z43.number().finite().min(0).lt(1),
|
|
8628
|
+
cancellationRate: z43.number().finite().min(0).lt(1),
|
|
8629
|
+
adsManagerCpa: z43.number().finite().nonnegative(),
|
|
8630
|
+
desiredMargin: z43.number().finite().min(0).lt(1)
|
|
8512
8631
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
8513
8632
|
if (returnRate + cancellationRate >= 1) {
|
|
8514
8633
|
context.addIssue({
|
|
8515
|
-
code:
|
|
8634
|
+
code: z43.ZodIssueCode.custom,
|
|
8516
8635
|
path: [
|
|
8517
8636
|
"cancellationRate"
|
|
8518
8637
|
],
|
|
@@ -8520,24 +8639,24 @@ var DropshippingProjectCostingInputSchema = z42.object({
|
|
|
8520
8639
|
});
|
|
8521
8640
|
}
|
|
8522
8641
|
});
|
|
8523
|
-
var DropshippingProjectCostingResultSchema =
|
|
8524
|
-
country:
|
|
8525
|
-
deliveryRate:
|
|
8526
|
-
adjustedShippingCost:
|
|
8527
|
-
adjustedCpa:
|
|
8528
|
-
totalCost:
|
|
8529
|
-
suggestedPrice:
|
|
8530
|
-
baseCommercialPrice:
|
|
8531
|
-
minimumSafePrice:
|
|
8532
|
-
commercialPrice:
|
|
8533
|
-
comparisonPrice:
|
|
8534
|
-
estimatedProfit:
|
|
8535
|
-
actualMargin:
|
|
8536
|
-
breakEvenAdsManagerCpa:
|
|
8537
|
-
wasPriceAutoAdjusted:
|
|
8538
|
-
profitabilityStatus:
|
|
8539
|
-
});
|
|
8540
|
-
var HttpUrlSchema =
|
|
8642
|
+
var DropshippingProjectCostingResultSchema = z43.object({
|
|
8643
|
+
country: z43.string().min(2).max(3),
|
|
8644
|
+
deliveryRate: z43.number().finite(),
|
|
8645
|
+
adjustedShippingCost: z43.number().finite(),
|
|
8646
|
+
adjustedCpa: z43.number().finite(),
|
|
8647
|
+
totalCost: z43.number().finite(),
|
|
8648
|
+
suggestedPrice: z43.number().finite(),
|
|
8649
|
+
baseCommercialPrice: z43.number().finite(),
|
|
8650
|
+
minimumSafePrice: z43.number().finite(),
|
|
8651
|
+
commercialPrice: z43.number().finite(),
|
|
8652
|
+
comparisonPrice: z43.number().finite(),
|
|
8653
|
+
estimatedProfit: z43.number().finite(),
|
|
8654
|
+
actualMargin: z43.number().finite(),
|
|
8655
|
+
breakEvenAdsManagerCpa: z43.number().finite(),
|
|
8656
|
+
wasPriceAutoAdjusted: z43.boolean(),
|
|
8657
|
+
profitabilityStatus: z43.literal("healthy")
|
|
8658
|
+
});
|
|
8659
|
+
var HttpUrlSchema = z43.string().url().max(2e3).refine((value) => {
|
|
8541
8660
|
try {
|
|
8542
8661
|
return [
|
|
8543
8662
|
"http:",
|
|
@@ -8547,124 +8666,124 @@ var HttpUrlSchema = z42.string().url().max(2e3).refine((value) => {
|
|
|
8547
8666
|
return false;
|
|
8548
8667
|
}
|
|
8549
8668
|
}, "Product URL must use HTTP(S)");
|
|
8550
|
-
var ResearchCandidateOriginSchema =
|
|
8551
|
-
type:
|
|
8552
|
-
runId:
|
|
8553
|
-
candidateSourceId:
|
|
8554
|
-
});
|
|
8555
|
-
var TaskOriginSchema =
|
|
8556
|
-
type:
|
|
8557
|
-
taskId:
|
|
8558
|
-
});
|
|
8559
|
-
var ManualOriginSchema =
|
|
8560
|
-
type:
|
|
8561
|
-
clientRequestId:
|
|
8562
|
-
country:
|
|
8563
|
-
});
|
|
8564
|
-
var CreateDropshippingProjectRequestSchema =
|
|
8565
|
-
origin:
|
|
8669
|
+
var ResearchCandidateOriginSchema = z43.object({
|
|
8670
|
+
type: z43.literal("research_candidate"),
|
|
8671
|
+
runId: z43.string().uuid(),
|
|
8672
|
+
candidateSourceId: z43.string().min(1).max(160)
|
|
8673
|
+
});
|
|
8674
|
+
var TaskOriginSchema = z43.object({
|
|
8675
|
+
type: z43.literal("task"),
|
|
8676
|
+
taskId: z43.string().uuid()
|
|
8677
|
+
});
|
|
8678
|
+
var ManualOriginSchema = z43.object({
|
|
8679
|
+
type: z43.literal("manual"),
|
|
8680
|
+
clientRequestId: z43.string().uuid(),
|
|
8681
|
+
country: z43.string().min(2).max(3).optional()
|
|
8682
|
+
});
|
|
8683
|
+
var CreateDropshippingProjectRequestSchema = z43.object({
|
|
8684
|
+
origin: z43.discriminatedUnion("type", [
|
|
8566
8685
|
ResearchCandidateOriginSchema,
|
|
8567
8686
|
TaskOriginSchema,
|
|
8568
8687
|
ManualOriginSchema
|
|
8569
8688
|
]),
|
|
8570
|
-
productName:
|
|
8689
|
+
productName: z43.string().trim().min(1).max(240).optional(),
|
|
8571
8690
|
productUrl: HttpUrlSchema.optional(),
|
|
8572
|
-
country:
|
|
8573
|
-
languageCode:
|
|
8691
|
+
country: z43.string().min(2).max(3).optional(),
|
|
8692
|
+
languageCode: z43.string().min(2).max(16).optional()
|
|
8574
8693
|
}).strict();
|
|
8575
|
-
var SaveDropshippingProjectCostingRequestSchema =
|
|
8694
|
+
var SaveDropshippingProjectCostingRequestSchema = z43.object({
|
|
8576
8695
|
input: DropshippingProjectCostingInputSchema,
|
|
8577
|
-
version:
|
|
8696
|
+
version: z43.number().int().positive()
|
|
8578
8697
|
}).strict();
|
|
8579
|
-
var DropshippingProjectNextActionSchema =
|
|
8580
|
-
|
|
8581
|
-
kind:
|
|
8582
|
-
href:
|
|
8698
|
+
var DropshippingProjectNextActionSchema = z43.discriminatedUnion("kind", [
|
|
8699
|
+
z43.object({
|
|
8700
|
+
kind: z43.literal("cost_product"),
|
|
8701
|
+
href: z43.string().min(1)
|
|
8583
8702
|
}),
|
|
8584
|
-
|
|
8585
|
-
kind:
|
|
8586
|
-
href:
|
|
8703
|
+
z43.object({
|
|
8704
|
+
kind: z43.literal("provide_product_media"),
|
|
8705
|
+
href: z43.string().min(1)
|
|
8587
8706
|
}),
|
|
8588
|
-
|
|
8589
|
-
kind:
|
|
8590
|
-
href:
|
|
8707
|
+
z43.object({
|
|
8708
|
+
kind: z43.literal("generate_creatives"),
|
|
8709
|
+
href: z43.string().min(1)
|
|
8591
8710
|
}),
|
|
8592
|
-
|
|
8593
|
-
kind:
|
|
8594
|
-
href:
|
|
8711
|
+
z43.object({
|
|
8712
|
+
kind: z43.literal("wait_for_creatives"),
|
|
8713
|
+
href: z43.string().min(1)
|
|
8595
8714
|
}),
|
|
8596
|
-
|
|
8597
|
-
kind:
|
|
8598
|
-
href:
|
|
8715
|
+
z43.object({
|
|
8716
|
+
kind: z43.literal("repair_creatives"),
|
|
8717
|
+
href: z43.string().min(1)
|
|
8599
8718
|
}),
|
|
8600
|
-
|
|
8601
|
-
kind:
|
|
8602
|
-
href:
|
|
8719
|
+
z43.object({
|
|
8720
|
+
kind: z43.literal("complete_creative_set"),
|
|
8721
|
+
href: z43.string().min(1)
|
|
8603
8722
|
}),
|
|
8604
|
-
|
|
8605
|
-
kind:
|
|
8606
|
-
href:
|
|
8723
|
+
z43.object({
|
|
8724
|
+
kind: z43.literal("connect_shopify"),
|
|
8725
|
+
href: z43.string().min(1)
|
|
8607
8726
|
}),
|
|
8608
|
-
|
|
8609
|
-
kind:
|
|
8610
|
-
href:
|
|
8727
|
+
z43.object({
|
|
8728
|
+
kind: z43.literal("publish_storefront"),
|
|
8729
|
+
href: z43.string().min(1)
|
|
8611
8730
|
}),
|
|
8612
|
-
|
|
8613
|
-
kind:
|
|
8614
|
-
href:
|
|
8731
|
+
z43.object({
|
|
8732
|
+
kind: z43.literal("wait_for_storefront"),
|
|
8733
|
+
href: z43.string().min(1)
|
|
8615
8734
|
}),
|
|
8616
|
-
|
|
8617
|
-
kind:
|
|
8618
|
-
href:
|
|
8735
|
+
z43.object({
|
|
8736
|
+
kind: z43.literal("connect_meta"),
|
|
8737
|
+
href: z43.string().min(1)
|
|
8619
8738
|
}),
|
|
8620
|
-
|
|
8621
|
-
kind:
|
|
8622
|
-
href:
|
|
8739
|
+
z43.object({
|
|
8740
|
+
kind: z43.literal("create_meta_campaign"),
|
|
8741
|
+
href: z43.string().min(1)
|
|
8623
8742
|
}),
|
|
8624
|
-
|
|
8625
|
-
kind:
|
|
8626
|
-
href:
|
|
8743
|
+
z43.object({
|
|
8744
|
+
kind: z43.literal("repair_meta_campaign"),
|
|
8745
|
+
href: z43.string().min(1)
|
|
8627
8746
|
}),
|
|
8628
|
-
|
|
8629
|
-
kind:
|
|
8630
|
-
href:
|
|
8747
|
+
z43.object({
|
|
8748
|
+
kind: z43.literal("review_paused_campaign"),
|
|
8749
|
+
href: z43.string().min(1)
|
|
8631
8750
|
})
|
|
8632
8751
|
]);
|
|
8633
|
-
var DropshippingProjectResponseSchema =
|
|
8634
|
-
id:
|
|
8635
|
-
taskId:
|
|
8752
|
+
var DropshippingProjectResponseSchema = z43.object({
|
|
8753
|
+
id: z43.string().uuid(),
|
|
8754
|
+
taskId: z43.string().uuid().nullable(),
|
|
8636
8755
|
status: DropshippingProjectStatusSchema,
|
|
8637
|
-
originKey:
|
|
8638
|
-
researchRunId:
|
|
8639
|
-
candidateSourceId:
|
|
8640
|
-
productName:
|
|
8756
|
+
originKey: z43.string().min(1),
|
|
8757
|
+
researchRunId: z43.string().uuid().nullable(),
|
|
8758
|
+
candidateSourceId: z43.string().nullable(),
|
|
8759
|
+
productName: z43.string().nullable(),
|
|
8641
8760
|
productUrl: HttpUrlSchema.nullable(),
|
|
8642
|
-
referenceImageUrl:
|
|
8643
|
-
hasReferenceImage:
|
|
8644
|
-
targetCountry:
|
|
8645
|
-
languageCode:
|
|
8761
|
+
referenceImageUrl: z43.string().url().nullable(),
|
|
8762
|
+
hasReferenceImage: z43.boolean(),
|
|
8763
|
+
targetCountry: z43.string().nullable(),
|
|
8764
|
+
languageCode: z43.string().nullable(),
|
|
8646
8765
|
costingInput: DropshippingProjectCostingInputSchema.nullable(),
|
|
8647
8766
|
costingResult: DropshippingProjectCostingResultSchema.nullable(),
|
|
8648
|
-
costingVersion:
|
|
8649
|
-
version:
|
|
8767
|
+
costingVersion: z43.number().int().positive().nullable(),
|
|
8768
|
+
version: z43.number().int().positive(),
|
|
8650
8769
|
phase: DropshippingProjectPhaseSchema,
|
|
8651
8770
|
nextAction: DropshippingProjectNextActionSchema.nullable(),
|
|
8652
8771
|
rewards: DropshippingProjectRewardProgressSchema,
|
|
8653
|
-
createdAt:
|
|
8654
|
-
updatedAt:
|
|
8772
|
+
createdAt: z43.string().datetime(),
|
|
8773
|
+
updatedAt: z43.string().datetime()
|
|
8655
8774
|
});
|
|
8656
8775
|
|
|
8657
8776
|
// ../../packages/types/src/scene-subject-contract.ts
|
|
8658
|
-
import { z as
|
|
8659
|
-
var SceneSubjectContractSchema =
|
|
8660
|
-
maxPeople:
|
|
8661
|
-
minPeople:
|
|
8662
|
-
minDistinctPeople:
|
|
8663
|
-
maxHands:
|
|
8777
|
+
import { z as z44 } from "zod";
|
|
8778
|
+
var SceneSubjectContractSchema = z44.object({
|
|
8779
|
+
maxPeople: z44.number().int().min(1).max(10),
|
|
8780
|
+
minPeople: z44.number().int().min(0).max(10),
|
|
8781
|
+
minDistinctPeople: z44.number().int().min(0).max(10),
|
|
8782
|
+
maxHands: z44.number().int().min(0).max(20)
|
|
8664
8783
|
}).superRefine((value, ctx) => {
|
|
8665
8784
|
if (value.minPeople > value.maxPeople) {
|
|
8666
8785
|
ctx.addIssue({
|
|
8667
|
-
code:
|
|
8786
|
+
code: z44.ZodIssueCode.custom,
|
|
8668
8787
|
path: [
|
|
8669
8788
|
"minPeople"
|
|
8670
8789
|
],
|
|
@@ -8673,7 +8792,7 @@ var SceneSubjectContractSchema = z43.object({
|
|
|
8673
8792
|
}
|
|
8674
8793
|
if (value.minDistinctPeople > value.maxPeople) {
|
|
8675
8794
|
ctx.addIssue({
|
|
8676
|
-
code:
|
|
8795
|
+
code: z44.ZodIssueCode.custom,
|
|
8677
8796
|
path: [
|
|
8678
8797
|
"minDistinctPeople"
|
|
8679
8798
|
],
|
|
@@ -8682,7 +8801,7 @@ var SceneSubjectContractSchema = z43.object({
|
|
|
8682
8801
|
}
|
|
8683
8802
|
if (value.minDistinctPeople > value.minPeople) {
|
|
8684
8803
|
ctx.addIssue({
|
|
8685
|
-
code:
|
|
8804
|
+
code: z44.ZodIssueCode.custom,
|
|
8686
8805
|
path: [
|
|
8687
8806
|
"minDistinctPeople"
|
|
8688
8807
|
],
|
|
@@ -8692,7 +8811,7 @@ var SceneSubjectContractSchema = z43.object({
|
|
|
8692
8811
|
});
|
|
8693
8812
|
|
|
8694
8813
|
// ../../packages/types/src/service-creative.ts
|
|
8695
|
-
import { z as
|
|
8814
|
+
import { z as z45 } from "zod";
|
|
8696
8815
|
var SERVICE_CREATIVE_PUBLIC_PRESETS = [
|
|
8697
8816
|
"auto",
|
|
8698
8817
|
"ugc_dynamic",
|
|
@@ -8700,19 +8819,19 @@ var SERVICE_CREATIVE_PUBLIC_PRESETS = [
|
|
|
8700
8819
|
"cinematic",
|
|
8701
8820
|
"wild_card"
|
|
8702
8821
|
];
|
|
8703
|
-
var ServiceCreativePresetSchema =
|
|
8822
|
+
var ServiceCreativePresetSchema = z45.enum(SERVICE_CREATIVE_PUBLIC_PRESETS);
|
|
8704
8823
|
var SERVICE_REVIEW_MODES = [
|
|
8705
8824
|
"automatic",
|
|
8706
8825
|
"guided"
|
|
8707
8826
|
];
|
|
8708
|
-
var ServiceReviewModeSchema =
|
|
8827
|
+
var ServiceReviewModeSchema = z45.enum(SERVICE_REVIEW_MODES);
|
|
8709
8828
|
var SERVICE_HIGGSFIELD_MODES = [
|
|
8710
8829
|
"product_review",
|
|
8711
8830
|
"ugc_how_to",
|
|
8712
8831
|
"tv_spot",
|
|
8713
8832
|
"wild_card"
|
|
8714
8833
|
];
|
|
8715
|
-
var ServiceHiggsfieldModeSchema =
|
|
8834
|
+
var ServiceHiggsfieldModeSchema = z45.enum(SERVICE_HIGGSFIELD_MODES);
|
|
8716
8835
|
var SERVICE_MEDIA_ROLES = [
|
|
8717
8836
|
"screen_demo",
|
|
8718
8837
|
"ad_reference",
|
|
@@ -8720,20 +8839,20 @@ var SERVICE_MEDIA_ROLES = [
|
|
|
8720
8839
|
"presenter_reference",
|
|
8721
8840
|
"brand_asset"
|
|
8722
8841
|
];
|
|
8723
|
-
var ServiceMediaRoleSchema =
|
|
8724
|
-
var ServiceMediaAssetSchema =
|
|
8842
|
+
var ServiceMediaRoleSchema = z45.enum(SERVICE_MEDIA_ROLES);
|
|
8843
|
+
var ServiceMediaAssetSchema = z45.object({
|
|
8725
8844
|
role: ServiceMediaRoleSchema,
|
|
8726
|
-
s3Key:
|
|
8845
|
+
s3Key: z45.string().min(1),
|
|
8727
8846
|
/** HMAC ticket returned by the authenticated service-media presign route. */
|
|
8728
|
-
uploadToken:
|
|
8729
|
-
mimeType:
|
|
8730
|
-
durationSec:
|
|
8731
|
-
sourceName:
|
|
8847
|
+
uploadToken: z45.string().min(1).optional(),
|
|
8848
|
+
mimeType: z45.string().min(1),
|
|
8849
|
+
durationSec: z45.number().positive().max(30).optional(),
|
|
8850
|
+
sourceName: z45.string().max(255).optional()
|
|
8732
8851
|
}).superRefine((asset, ctx) => {
|
|
8733
8852
|
const isVideoRole = asset.role === "screen_demo" || asset.role === "ad_reference";
|
|
8734
8853
|
if (isVideoRole && !asset.mimeType.startsWith("video/")) {
|
|
8735
8854
|
ctx.addIssue({
|
|
8736
|
-
code:
|
|
8855
|
+
code: z45.ZodIssueCode.custom,
|
|
8737
8856
|
message: `${asset.role} requires video media`,
|
|
8738
8857
|
path: [
|
|
8739
8858
|
"mimeType"
|
|
@@ -8742,7 +8861,7 @@ var ServiceMediaAssetSchema = z44.object({
|
|
|
8742
8861
|
}
|
|
8743
8862
|
if (isVideoRole && asset.durationSec === void 0) {
|
|
8744
8863
|
ctx.addIssue({
|
|
8745
|
-
code:
|
|
8864
|
+
code: z45.ZodIssueCode.custom,
|
|
8746
8865
|
message: `${asset.role} requires durationSec`,
|
|
8747
8866
|
path: [
|
|
8748
8867
|
"durationSec"
|
|
@@ -8751,7 +8870,7 @@ var ServiceMediaAssetSchema = z44.object({
|
|
|
8751
8870
|
}
|
|
8752
8871
|
if (!isVideoRole && !asset.mimeType.startsWith("image/")) {
|
|
8753
8872
|
ctx.addIssue({
|
|
8754
|
-
code:
|
|
8873
|
+
code: z45.ZodIssueCode.custom,
|
|
8755
8874
|
message: `${asset.role} requires image media`,
|
|
8756
8875
|
path: [
|
|
8757
8876
|
"mimeType"
|
|
@@ -8759,13 +8878,13 @@ var ServiceMediaAssetSchema = z44.object({
|
|
|
8759
8878
|
});
|
|
8760
8879
|
}
|
|
8761
8880
|
});
|
|
8762
|
-
var ServiceMediaBundleSchema =
|
|
8763
|
-
assets:
|
|
8881
|
+
var ServiceMediaBundleSchema = z45.object({
|
|
8882
|
+
assets: z45.array(ServiceMediaAssetSchema).max(15).default([])
|
|
8764
8883
|
}).superRefine((bundle, ctx) => {
|
|
8765
8884
|
const adReferences = bundle.assets.filter((asset) => asset.role === "ad_reference");
|
|
8766
8885
|
if (adReferences.length > 5) {
|
|
8767
8886
|
ctx.addIssue({
|
|
8768
|
-
code:
|
|
8887
|
+
code: z45.ZodIssueCode.custom,
|
|
8769
8888
|
message: "A maximum of five ad_reference videos is allowed",
|
|
8770
8889
|
path: [
|
|
8771
8890
|
"assets"
|
|
@@ -8775,7 +8894,7 @@ var ServiceMediaBundleSchema = z44.object({
|
|
|
8775
8894
|
const screenDemos = bundle.assets.filter((asset) => asset.role === "screen_demo");
|
|
8776
8895
|
if (screenDemos.length > 3) {
|
|
8777
8896
|
ctx.addIssue({
|
|
8778
|
-
code:
|
|
8897
|
+
code: z45.ZodIssueCode.custom,
|
|
8779
8898
|
message: "A maximum of three screen_demo videos is allowed",
|
|
8780
8899
|
path: [
|
|
8781
8900
|
"assets"
|
|
@@ -8792,33 +8911,33 @@ var SERVICE_MEDIA_ANALYSIS_KINDS = [
|
|
|
8792
8911
|
"product",
|
|
8793
8912
|
"other"
|
|
8794
8913
|
];
|
|
8795
|
-
var ServiceMediaAnalysisKindSchema =
|
|
8796
|
-
var ServiceMediaAnalysisItemSchema =
|
|
8797
|
-
assetIndex:
|
|
8798
|
-
mediaType:
|
|
8914
|
+
var ServiceMediaAnalysisKindSchema = z45.enum(SERVICE_MEDIA_ANALYSIS_KINDS);
|
|
8915
|
+
var ServiceMediaAnalysisItemSchema = z45.object({
|
|
8916
|
+
assetIndex: z45.number().int().nonnegative(),
|
|
8917
|
+
mediaType: z45.enum([
|
|
8799
8918
|
"image",
|
|
8800
8919
|
"video"
|
|
8801
8920
|
]),
|
|
8802
8921
|
kind: ServiceMediaAnalysisKindSchema,
|
|
8803
|
-
description:
|
|
8804
|
-
tags:
|
|
8805
|
-
suggestedRoles:
|
|
8806
|
-
visiblePeople:
|
|
8807
|
-
ocrText:
|
|
8808
|
-
speechSummary:
|
|
8809
|
-
});
|
|
8810
|
-
var ServiceMediaAnalysisSchema =
|
|
8811
|
-
version:
|
|
8812
|
-
analyzedAt:
|
|
8813
|
-
pricingAction:
|
|
8814
|
-
assetFingerprint:
|
|
8922
|
+
description: z45.string().min(1).max(1200),
|
|
8923
|
+
tags: z45.array(z45.string().min(1).max(80)).max(12),
|
|
8924
|
+
suggestedRoles: z45.array(ServiceMediaRoleSchema).max(4),
|
|
8925
|
+
visiblePeople: z45.number().int().nonnegative().max(20).optional(),
|
|
8926
|
+
ocrText: z45.string().max(2e3).optional(),
|
|
8927
|
+
speechSummary: z45.string().max(2e3).optional()
|
|
8928
|
+
});
|
|
8929
|
+
var ServiceMediaAnalysisSchema = z45.object({
|
|
8930
|
+
version: z45.literal(1),
|
|
8931
|
+
analyzedAt: z45.string().datetime(),
|
|
8932
|
+
pricingAction: z45.literal("service-media-analysis"),
|
|
8933
|
+
assetFingerprint: z45.string().regex(/^[a-f0-9]{64}$/),
|
|
8815
8934
|
/** Language used for human-readable descriptions and tags. Optional for old checkpoints. */
|
|
8816
|
-
language:
|
|
8935
|
+
language: z45.enum([
|
|
8817
8936
|
"es",
|
|
8818
8937
|
"en",
|
|
8819
8938
|
"pt"
|
|
8820
8939
|
]).optional(),
|
|
8821
|
-
items:
|
|
8940
|
+
items: z45.array(ServiceMediaAnalysisItemSchema).max(15)
|
|
8822
8941
|
});
|
|
8823
8942
|
|
|
8824
8943
|
// ../../packages/types/src/productmaker-capability-registry.ts
|
|
@@ -9335,7 +9454,7 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
9335
9454
|
], [
|
|
9336
9455
|
"creative"
|
|
9337
9456
|
]),
|
|
9338
|
-
defineCapability("generate_landing", "
|
|
9457
|
+
defineCapability("generate_landing", "67520417176396516cd5ad358dca39f70a5c4a74169eecd85987217226c12251", "credit_consuming", "creative", [
|
|
9339
9458
|
"credit_consuming",
|
|
9340
9459
|
"state_change"
|
|
9341
9460
|
], [
|
|
@@ -9380,12 +9499,14 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
9380
9499
|
"competitorScanEnabled",
|
|
9381
9500
|
"landingStrategy",
|
|
9382
9501
|
"landingImageFormat",
|
|
9502
|
+
"pauseForAngleReview",
|
|
9383
9503
|
// MCP-only, like create_product_task's aiDecidesAll.
|
|
9384
9504
|
"aiDecidesAll"
|
|
9385
9505
|
], [
|
|
9386
9506
|
"competitorScanEnabled",
|
|
9387
9507
|
"landingStrategy",
|
|
9388
|
-
"landingImageFormat"
|
|
9508
|
+
"landingImageFormat",
|
|
9509
|
+
"pauseForAngleReview"
|
|
9389
9510
|
])
|
|
9390
9511
|
], [
|
|
9391
9512
|
"product_reference"
|
|
@@ -9901,8 +10022,8 @@ var PRODUCTMAKER_MCP_CAPABILITIES = toLegacyCapabilityCatalog(PRODUCTMAKER_MCP_C
|
|
|
9901
10022
|
var PRODUCTMAKER_MCP_CAPABILITY_NAMES = PRODUCTMAKER_MCP_CAPABILITY_REGISTRY.map((capability) => capability.name);
|
|
9902
10023
|
|
|
9903
10024
|
// ../../packages/types/src/actor.ts
|
|
9904
|
-
import { z as
|
|
9905
|
-
var ActorStatusSchema =
|
|
10025
|
+
import { z as z46 } from "zod";
|
|
10026
|
+
var ActorStatusSchema = z46.enum([
|
|
9906
10027
|
"draft",
|
|
9907
10028
|
"generating",
|
|
9908
10029
|
"ready",
|
|
@@ -9911,18 +10032,18 @@ var ActorStatusSchema = z45.enum([
|
|
|
9911
10032
|
var ACTOR_NAME_MAX_CHARS = 60;
|
|
9912
10033
|
var ACTOR_DESCRIPTION_MAX_CHARS = 600;
|
|
9913
10034
|
var ACTOR_CANDIDATE_COUNT = 4;
|
|
9914
|
-
var ActorGenderSchema =
|
|
10035
|
+
var ActorGenderSchema = z46.enum([
|
|
9915
10036
|
"female",
|
|
9916
10037
|
"male",
|
|
9917
10038
|
"non_binary"
|
|
9918
10039
|
]);
|
|
9919
|
-
var ActorSchema =
|
|
9920
|
-
id:
|
|
9921
|
-
name:
|
|
9922
|
-
description:
|
|
10040
|
+
var ActorSchema = z46.object({
|
|
10041
|
+
id: z46.string(),
|
|
10042
|
+
name: z46.string().min(1).max(ACTOR_NAME_MAX_CHARS),
|
|
10043
|
+
description: z46.string().max(ACTOR_DESCRIPTION_MAX_CHARS),
|
|
9923
10044
|
gender: ActorGenderSchema,
|
|
9924
|
-
voiceId:
|
|
9925
|
-
brandId:
|
|
10045
|
+
voiceId: z46.string().nullable().optional(),
|
|
10046
|
+
brandId: z46.string().nullable().optional(),
|
|
9926
10047
|
status: ActorStatusSchema,
|
|
9927
10048
|
/**
|
|
9928
10049
|
* A candidate-grid run is in flight RIGHT NOW.
|
|
@@ -9934,36 +10055,36 @@ var ActorSchema = z45.object({
|
|
|
9934
10055
|
* timestamp with a TTL, so an orphaned run reads as `false` instead of
|
|
9935
10056
|
* pinning the personaje forever.
|
|
9936
10057
|
*/
|
|
9937
|
-
generating:
|
|
9938
|
-
photoUrl:
|
|
9939
|
-
avatarUrl:
|
|
9940
|
-
candidateUrls:
|
|
10058
|
+
generating: z46.boolean().optional(),
|
|
10059
|
+
photoUrl: z46.string().url().nullable().optional(),
|
|
10060
|
+
avatarUrl: z46.string().url().nullable().optional(),
|
|
10061
|
+
candidateUrls: z46.array(z46.string().url()).optional(),
|
|
9941
10062
|
/** Indices of candidateUrls that failed the anatomy check (Task 6). */
|
|
9942
|
-
flaggedCandidateIndices:
|
|
10063
|
+
flaggedCandidateIndices: z46.array(z46.number().int()).optional()
|
|
9943
10064
|
});
|
|
9944
|
-
var CreateActorRequest =
|
|
9945
|
-
name:
|
|
9946
|
-
description:
|
|
10065
|
+
var CreateActorRequest = z46.object({
|
|
10066
|
+
name: z46.string().min(1).max(ACTOR_NAME_MAX_CHARS),
|
|
10067
|
+
description: z46.string().max(ACTOR_DESCRIPTION_MAX_CHARS).default(""),
|
|
9947
10068
|
gender: ActorGenderSchema,
|
|
9948
|
-
voiceId:
|
|
9949
|
-
brandId:
|
|
9950
|
-
sourcePhotoKey:
|
|
10069
|
+
voiceId: z46.string().optional(),
|
|
10070
|
+
brandId: z46.string().optional(),
|
|
10071
|
+
sourcePhotoKey: z46.string().optional()
|
|
9951
10072
|
}).refine((v) => v.description.trim().length > 0 || !!v.sourcePhotoKey, {
|
|
9952
10073
|
message: "Se necesita una descripci\xF3n o una foto"
|
|
9953
10074
|
});
|
|
9954
|
-
var UpdateActorRequest =
|
|
9955
|
-
name:
|
|
9956
|
-
description:
|
|
10075
|
+
var UpdateActorRequest = z46.object({
|
|
10076
|
+
name: z46.string().min(1).max(ACTOR_NAME_MAX_CHARS).optional(),
|
|
10077
|
+
description: z46.string().max(ACTOR_DESCRIPTION_MAX_CHARS).optional(),
|
|
9957
10078
|
gender: ActorGenderSchema.optional(),
|
|
9958
|
-
voiceId:
|
|
9959
|
-
brandId:
|
|
10079
|
+
voiceId: z46.string().nullable().optional(),
|
|
10080
|
+
brandId: z46.string().nullable().optional()
|
|
9960
10081
|
});
|
|
9961
|
-
var ApproveActorRequest =
|
|
9962
|
-
candidateIndex:
|
|
10082
|
+
var ApproveActorRequest = z46.object({
|
|
10083
|
+
candidateIndex: z46.number().int().min(0).max(ACTOR_CANDIDATE_COUNT - 1)
|
|
9963
10084
|
});
|
|
9964
10085
|
|
|
9965
10086
|
// ../../packages/types/src/referral-dashboard.ts
|
|
9966
|
-
import { z as
|
|
10087
|
+
import { z as z47 } from "zod";
|
|
9967
10088
|
var REFERRAL_DASHBOARD_RAW_STATUSES = [
|
|
9968
10089
|
"ACTIVE",
|
|
9969
10090
|
"PENDING",
|
|
@@ -9982,66 +10103,66 @@ var REFERRAL_DASHBOARD_PLAN_KINDS = [
|
|
|
9982
10103
|
"last",
|
|
9983
10104
|
"none"
|
|
9984
10105
|
];
|
|
9985
|
-
var ReferralDashboardRawStatusSchema =
|
|
9986
|
-
var ReferralDashboardStateSchema =
|
|
9987
|
-
var ReferralDashboardPlanKindSchema =
|
|
9988
|
-
var ReferralDashboardStatusSchema =
|
|
10106
|
+
var ReferralDashboardRawStatusSchema = z47.enum(REFERRAL_DASHBOARD_RAW_STATUSES);
|
|
10107
|
+
var ReferralDashboardStateSchema = z47.enum(REFERRAL_DASHBOARD_STATES);
|
|
10108
|
+
var ReferralDashboardPlanKindSchema = z47.enum(REFERRAL_DASHBOARD_PLAN_KINDS);
|
|
10109
|
+
var ReferralDashboardStatusSchema = z47.enum([
|
|
9989
10110
|
"all",
|
|
9990
10111
|
"active",
|
|
9991
10112
|
"pending",
|
|
9992
10113
|
"inactive"
|
|
9993
10114
|
]).default("all");
|
|
9994
|
-
var ReferralDashboardPlanSchema =
|
|
9995
|
-
var ReferralDashboardFiltersSchema =
|
|
10115
|
+
var ReferralDashboardPlanSchema = z47.string().trim().min(1).max(100).optional();
|
|
10116
|
+
var ReferralDashboardFiltersSchema = z47.object({
|
|
9996
10117
|
status: ReferralDashboardStatusSchema,
|
|
9997
10118
|
plan: ReferralDashboardPlanSchema
|
|
9998
10119
|
});
|
|
9999
|
-
var ReferralDashboardSubscriptionSchema =
|
|
10000
|
-
planName:
|
|
10120
|
+
var ReferralDashboardSubscriptionSchema = z47.object({
|
|
10121
|
+
planName: z47.string().nullable(),
|
|
10001
10122
|
planKind: ReferralDashboardPlanKindSchema,
|
|
10002
10123
|
rawStatus: ReferralDashboardRawStatusSchema.nullable(),
|
|
10003
10124
|
state: ReferralDashboardStateSchema,
|
|
10004
|
-
currentPeriodEnd:
|
|
10125
|
+
currentPeriodEnd: z47.string().datetime({
|
|
10005
10126
|
offset: true
|
|
10006
10127
|
}).nullable(),
|
|
10007
|
-
cancelAtPeriodEnd:
|
|
10128
|
+
cancelAtPeriodEnd: z47.boolean()
|
|
10008
10129
|
});
|
|
10009
|
-
var ReferralDashboardReferralSchema =
|
|
10010
|
-
id:
|
|
10011
|
-
registeredAt:
|
|
10130
|
+
var ReferralDashboardReferralSchema = z47.object({
|
|
10131
|
+
id: z47.string().min(1),
|
|
10132
|
+
registeredAt: z47.string().datetime({
|
|
10012
10133
|
offset: true
|
|
10013
10134
|
}),
|
|
10014
10135
|
// Kept in the response for compatibility with existing referral API clients.
|
|
10015
10136
|
// The referrer dashboard intentionally does not render these legacy fields.
|
|
10016
|
-
expiresAt:
|
|
10137
|
+
expiresAt: z47.string().datetime({
|
|
10017
10138
|
offset: true
|
|
10018
10139
|
}).nullable().optional(),
|
|
10019
|
-
status:
|
|
10020
|
-
referredUser:
|
|
10021
|
-
email:
|
|
10140
|
+
status: z47.string().min(1).optional(),
|
|
10141
|
+
referredUser: z47.object({
|
|
10142
|
+
email: z47.string().nullable()
|
|
10022
10143
|
}),
|
|
10023
10144
|
subscription: ReferralDashboardSubscriptionSchema
|
|
10024
10145
|
});
|
|
10025
|
-
var ReferralDashboardReferralsPageSchema =
|
|
10026
|
-
referrals:
|
|
10027
|
-
total:
|
|
10146
|
+
var ReferralDashboardReferralsPageSchema = z47.object({
|
|
10147
|
+
referrals: z47.array(ReferralDashboardReferralSchema),
|
|
10148
|
+
total: z47.number().int().nonnegative()
|
|
10028
10149
|
});
|
|
10029
|
-
var ReferralDashboardPlanBreakdownSchema =
|
|
10030
|
-
planName:
|
|
10031
|
-
count:
|
|
10150
|
+
var ReferralDashboardPlanBreakdownSchema = z47.object({
|
|
10151
|
+
planName: z47.string().nullable(),
|
|
10152
|
+
count: z47.number().int().nonnegative()
|
|
10032
10153
|
});
|
|
10033
|
-
var ReferralDashboardMonthlyRegistrationSchema =
|
|
10034
|
-
month:
|
|
10035
|
-
count:
|
|
10154
|
+
var ReferralDashboardMonthlyRegistrationSchema = z47.object({
|
|
10155
|
+
month: z47.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/),
|
|
10156
|
+
count: z47.number().int().nonnegative()
|
|
10036
10157
|
});
|
|
10037
|
-
var ReferralDashboardOverviewSchema =
|
|
10038
|
-
totalReferredUsers:
|
|
10039
|
-
activeUsers:
|
|
10040
|
-
pendingUsers:
|
|
10041
|
-
inactiveUsers:
|
|
10042
|
-
noPlanUsers:
|
|
10043
|
-
planBreakdown:
|
|
10044
|
-
monthlyRegistrations:
|
|
10158
|
+
var ReferralDashboardOverviewSchema = z47.object({
|
|
10159
|
+
totalReferredUsers: z47.number().int().nonnegative(),
|
|
10160
|
+
activeUsers: z47.number().int().nonnegative(),
|
|
10161
|
+
pendingUsers: z47.number().int().nonnegative(),
|
|
10162
|
+
inactiveUsers: z47.number().int().nonnegative(),
|
|
10163
|
+
noPlanUsers: z47.number().int().nonnegative(),
|
|
10164
|
+
planBreakdown: z47.array(ReferralDashboardPlanBreakdownSchema),
|
|
10165
|
+
monthlyRegistrations: z47.array(ReferralDashboardMonthlyRegistrationSchema).refine((months) => months.length === 6, "Expected six monthly registration buckets")
|
|
10045
10166
|
});
|
|
10046
10167
|
|
|
10047
10168
|
// ../../packages/types/src/mcp-oauth.ts
|
|
@@ -10803,19 +10924,19 @@ import { InsufficientScopeError, InvalidTokenError } from "@modelcontextprotocol
|
|
|
10803
10924
|
import { createRemoteJWKSet as createRemoteJWKSet2, jwtVerify as jwtVerify2 } from "jose";
|
|
10804
10925
|
|
|
10805
10926
|
// src/auth/oauth-config.ts
|
|
10806
|
-
import { z as
|
|
10927
|
+
import { z as z48 } from "zod";
|
|
10807
10928
|
var MCP_RESOURCE = new URL("https://mcp.productmaker.app/mcp");
|
|
10808
10929
|
var MCP_SCOPE = "mcp:access";
|
|
10809
|
-
var oauthEnvSchema =
|
|
10810
|
-
MCP_REMOTE_AUTH_MODE:
|
|
10811
|
-
MCP_AUTH0_ISSUER:
|
|
10812
|
-
MCP_AUTH0_AUDIENCE:
|
|
10930
|
+
var oauthEnvSchema = z48.object({
|
|
10931
|
+
MCP_REMOTE_AUTH_MODE: z48.literal("oauth"),
|
|
10932
|
+
MCP_AUTH0_ISSUER: z48.string().trim().min(1),
|
|
10933
|
+
MCP_AUTH0_AUDIENCE: z48.string().trim().refine((value) => value === MCP_RESOURCE.href, {
|
|
10813
10934
|
message: `must equal ${MCP_RESOURCE.href}`
|
|
10814
10935
|
}),
|
|
10815
|
-
MCP_AUTH0_CLIENT_ID:
|
|
10816
|
-
MCP_AUTH0_CLIENT_SECRET:
|
|
10817
|
-
PM_API_AUDIENCE:
|
|
10818
|
-
AUTH0_AUDIENCE:
|
|
10936
|
+
MCP_AUTH0_CLIENT_ID: z48.string().trim().min(1),
|
|
10937
|
+
MCP_AUTH0_CLIENT_SECRET: z48.string().trim().min(1),
|
|
10938
|
+
PM_API_AUDIENCE: z48.string().trim().min(1),
|
|
10939
|
+
AUTH0_AUDIENCE: z48.string().trim().min(1)
|
|
10819
10940
|
});
|
|
10820
10941
|
function formatZodIssues(error) {
|
|
10821
10942
|
return error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ");
|
|
@@ -11557,7 +11678,7 @@ var ApiClient = class {
|
|
|
11557
11678
|
};
|
|
11558
11679
|
|
|
11559
11680
|
// src/index.ts
|
|
11560
|
-
var MCP_VERSION = "3.4.
|
|
11681
|
+
var MCP_VERSION = "3.4.2";
|
|
11561
11682
|
|
|
11562
11683
|
// src/meta-upload-app.ts
|
|
11563
11684
|
import { readFileSync } from "fs";
|
|
@@ -11629,7 +11750,7 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
|
|
|
11629
11750
|
__name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
|
|
11630
11751
|
|
|
11631
11752
|
// src/tools/tasks.ts
|
|
11632
|
-
import { z as
|
|
11753
|
+
import { z as z50 } from "zod";
|
|
11633
11754
|
|
|
11634
11755
|
// src/resolve-image.ts
|
|
11635
11756
|
import { lookup as dnsLookup } from "dns/promises";
|
|
@@ -11869,6 +11990,7 @@ __name(resolveOne, "resolveOne");
|
|
|
11869
11990
|
|
|
11870
11991
|
// src/status-poller.ts
|
|
11871
11992
|
var TERMINAL = /* @__PURE__ */ new Set([
|
|
11993
|
+
"done",
|
|
11872
11994
|
"complete",
|
|
11873
11995
|
"error"
|
|
11874
11996
|
]);
|
|
@@ -12156,10 +12278,10 @@ async function resolveMediaRef(ref, opts) {
|
|
|
12156
12278
|
__name(resolveMediaRef, "resolveMediaRef");
|
|
12157
12279
|
|
|
12158
12280
|
// src/tools/shared.ts
|
|
12159
|
-
import { z as
|
|
12160
|
-
var Lang =
|
|
12161
|
-
var Country =
|
|
12162
|
-
var LandingStrategyEnum =
|
|
12281
|
+
import { z as z49 } from "zod";
|
|
12282
|
+
var Lang = z49.string().min(2).max(10);
|
|
12283
|
+
var Country = z49.string().min(2).max(3);
|
|
12284
|
+
var LandingStrategyEnum = z49.enum([
|
|
12163
12285
|
"auto",
|
|
12164
12286
|
"classic",
|
|
12165
12287
|
"pain_solution",
|
|
@@ -12168,12 +12290,12 @@ var LandingStrategyEnum = z48.enum([
|
|
|
12168
12290
|
"offer_value",
|
|
12169
12291
|
"lifestyle_identity"
|
|
12170
12292
|
]);
|
|
12171
|
-
var LandingImageFormatEnum =
|
|
12293
|
+
var LandingImageFormatEnum = z49.enum([
|
|
12172
12294
|
"9:16",
|
|
12173
12295
|
"4:5",
|
|
12174
12296
|
"1:1"
|
|
12175
12297
|
]);
|
|
12176
|
-
var VideoPresetEnum =
|
|
12298
|
+
var VideoPresetEnum = z49.enum([
|
|
12177
12299
|
"auto",
|
|
12178
12300
|
"ugc_dynamic",
|
|
12179
12301
|
"ugc_how_to",
|
|
@@ -12186,7 +12308,7 @@ var VideoPresetEnum = z48.enum([
|
|
|
12186
12308
|
"pixar_problem",
|
|
12187
12309
|
"pixar_sassy"
|
|
12188
12310
|
]);
|
|
12189
|
-
var TaskCreativeVariantVideoPresetEnum =
|
|
12311
|
+
var TaskCreativeVariantVideoPresetEnum = z49.enum([
|
|
12190
12312
|
"auto",
|
|
12191
12313
|
"ugc_dynamic",
|
|
12192
12314
|
"ugc_how_to",
|
|
@@ -12257,7 +12379,7 @@ function resolveVideoPreset(preset) {
|
|
|
12257
12379
|
return VIDEO_PRESET_RESOLUTION[preset] ?? null;
|
|
12258
12380
|
}
|
|
12259
12381
|
__name(resolveVideoPreset, "resolveVideoPreset");
|
|
12260
|
-
var VideoTierEnum =
|
|
12382
|
+
var VideoTierEnum = z49.enum([
|
|
12261
12383
|
"basic"
|
|
12262
12384
|
]);
|
|
12263
12385
|
function resolveVideoTier(_tier) {
|
|
@@ -12272,17 +12394,17 @@ function resolveVideoFormatForDuration(durationSeconds) {
|
|
|
12272
12394
|
return durationSeconds === 30 ? "double_30s" : "single_15s";
|
|
12273
12395
|
}
|
|
12274
12396
|
__name(resolveVideoFormatForDuration, "resolveVideoFormatForDuration");
|
|
12275
|
-
var VideoResolutionEnum =
|
|
12397
|
+
var VideoResolutionEnum = z49.enum([
|
|
12276
12398
|
"480p",
|
|
12277
12399
|
"720p"
|
|
12278
12400
|
]);
|
|
12279
|
-
var VideoStyleEnum =
|
|
12401
|
+
var VideoStyleEnum = z49.enum([
|
|
12280
12402
|
"ugc",
|
|
12281
12403
|
"cartoon_3d",
|
|
12282
12404
|
"product_only",
|
|
12283
12405
|
"ai_dynamic"
|
|
12284
12406
|
]);
|
|
12285
|
-
var NarrativeStyleEnum =
|
|
12407
|
+
var NarrativeStyleEnum = z49.enum([
|
|
12286
12408
|
"review",
|
|
12287
12409
|
"ugc_how_to",
|
|
12288
12410
|
"problem_product_cta",
|
|
@@ -12299,7 +12421,7 @@ var NarrativeStyleEnum = z48.enum([
|
|
|
12299
12421
|
"ugc_skeptic_confession",
|
|
12300
12422
|
"ugc_demo_review"
|
|
12301
12423
|
]);
|
|
12302
|
-
var PublicNarrativeStyleEnum =
|
|
12424
|
+
var PublicNarrativeStyleEnum = z49.enum([
|
|
12303
12425
|
"review",
|
|
12304
12426
|
"ugc_how_to",
|
|
12305
12427
|
"ugc_unboxing_chaos",
|
|
@@ -12311,7 +12433,7 @@ var PublicNarrativeStyleEnum = z48.enum([
|
|
|
12311
12433
|
"animated_problem_pixar",
|
|
12312
12434
|
"sassy_product_pixar"
|
|
12313
12435
|
]);
|
|
12314
|
-
var VideoModelEnum =
|
|
12436
|
+
var VideoModelEnum = z49.enum([
|
|
12315
12437
|
"veo",
|
|
12316
12438
|
"wan",
|
|
12317
12439
|
"bytedance",
|
|
@@ -12319,29 +12441,29 @@ var VideoModelEnum = z48.enum([
|
|
|
12319
12441
|
"grok",
|
|
12320
12442
|
"kling"
|
|
12321
12443
|
]);
|
|
12322
|
-
var ProductReferenceUserChoiceEnum =
|
|
12444
|
+
var ProductReferenceUserChoiceEnum = z49.enum([
|
|
12323
12445
|
"same_product",
|
|
12324
12446
|
"variants",
|
|
12325
12447
|
"different_products",
|
|
12326
12448
|
"combo_distinct"
|
|
12327
12449
|
]);
|
|
12328
|
-
var ProductReferenceCandidateGroupingEnum =
|
|
12450
|
+
var ProductReferenceCandidateGroupingEnum = z49.enum([
|
|
12329
12451
|
"same_product_same_variant",
|
|
12330
12452
|
"same_product_different_variants",
|
|
12331
12453
|
"different_products",
|
|
12332
12454
|
"unclear"
|
|
12333
12455
|
]);
|
|
12334
|
-
var ProductReferenceScopeEnum =
|
|
12456
|
+
var ProductReferenceScopeEnum = z49.enum([
|
|
12335
12457
|
"base",
|
|
12336
12458
|
"video_view_pack"
|
|
12337
12459
|
]);
|
|
12338
|
-
var ProductReferenceResolutionDecisionEnum =
|
|
12460
|
+
var ProductReferenceResolutionDecisionEnum = z49.enum([
|
|
12339
12461
|
"approve",
|
|
12340
12462
|
"reject",
|
|
12341
12463
|
"observed_only",
|
|
12342
12464
|
"correct_view"
|
|
12343
12465
|
]);
|
|
12344
|
-
var ProductReferenceRejectionReasonEnum =
|
|
12466
|
+
var ProductReferenceRejectionReasonEnum = z49.enum([
|
|
12345
12467
|
"replacement_requested",
|
|
12346
12468
|
"wrong_product_identity",
|
|
12347
12469
|
"wrong_variant",
|
|
@@ -12352,13 +12474,13 @@ var ProductReferenceRejectionReasonEnum = z48.enum([
|
|
|
12352
12474
|
"not_a_product_photo",
|
|
12353
12475
|
"other"
|
|
12354
12476
|
]);
|
|
12355
|
-
var GapDurationChoiceMirror =
|
|
12356
|
-
angleIndex:
|
|
12357
|
-
recommendedSec:
|
|
12358
|
-
|
|
12359
|
-
|
|
12477
|
+
var GapDurationChoiceMirror = z49.object({
|
|
12478
|
+
angleIndex: z49.number().int().nonnegative(),
|
|
12479
|
+
recommendedSec: z49.union([
|
|
12480
|
+
z49.literal(15),
|
|
12481
|
+
z49.literal(30)
|
|
12360
12482
|
]),
|
|
12361
|
-
estimatedDeltaCredits:
|
|
12483
|
+
estimatedDeltaCredits: z49.number().int().nonnegative().optional()
|
|
12362
12484
|
});
|
|
12363
12485
|
function buildSelectedImageUrlsHash(urls) {
|
|
12364
12486
|
const input = [
|
|
@@ -12368,13 +12490,13 @@ function buildSelectedImageUrlsHash(urls) {
|
|
|
12368
12490
|
return `fnv1a:${hash.toString(16).padStart(8, "0")}:${urls.length}`;
|
|
12369
12491
|
}
|
|
12370
12492
|
__name(buildSelectedImageUrlsHash, "buildSelectedImageUrlsHash");
|
|
12371
|
-
var ImageCreativeStyleEnum =
|
|
12493
|
+
var ImageCreativeStyleEnum = z49.enum([
|
|
12372
12494
|
"studio",
|
|
12373
12495
|
"floating",
|
|
12374
12496
|
"ingredients",
|
|
12375
12497
|
"in_use"
|
|
12376
12498
|
]);
|
|
12377
|
-
var ImageCreativeArchetypeEnum =
|
|
12499
|
+
var ImageCreativeArchetypeEnum = z49.enum([
|
|
12378
12500
|
"direct_response_product_ad",
|
|
12379
12501
|
"hero_outcome",
|
|
12380
12502
|
"offer_value_prop",
|
|
@@ -12383,20 +12505,20 @@ var ImageCreativeArchetypeEnum = z48.enum([
|
|
|
12383
12505
|
"problem_solution",
|
|
12384
12506
|
"lifestyle_identity"
|
|
12385
12507
|
]);
|
|
12386
|
-
var ImageCreativeVisualTreatmentEnum =
|
|
12508
|
+
var ImageCreativeVisualTreatmentEnum = z49.enum([
|
|
12387
12509
|
"performance_product_ad",
|
|
12388
12510
|
"premium_dtc_carousel"
|
|
12389
12511
|
]);
|
|
12390
|
-
var ImageCreativeAspectRatioEnum =
|
|
12512
|
+
var ImageCreativeAspectRatioEnum = z49.enum([
|
|
12391
12513
|
"1:1",
|
|
12392
12514
|
"4:5",
|
|
12393
12515
|
"9:16",
|
|
12394
12516
|
"16:9"
|
|
12395
12517
|
]);
|
|
12396
|
-
var ImageRefSchema =
|
|
12397
|
-
url:
|
|
12398
|
-
path:
|
|
12399
|
-
assetId:
|
|
12518
|
+
var ImageRefSchema = z49.object({
|
|
12519
|
+
url: z49.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.'),
|
|
12520
|
+
path: z49.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`.'),
|
|
12521
|
+
assetId: z49.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.")
|
|
12400
12522
|
}).refine((v) => [
|
|
12401
12523
|
v.url,
|
|
12402
12524
|
v.path,
|
|
@@ -12404,11 +12526,11 @@ var ImageRefSchema = z48.object({
|
|
|
12404
12526
|
].filter(Boolean).length === 1, {
|
|
12405
12527
|
message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
|
|
12406
12528
|
});
|
|
12407
|
-
var ImagesInput =
|
|
12529
|
+
var ImagesInput = z49.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
|
|
12408
12530
|
const assetCount = images.filter((image) => Boolean(image.assetId)).length;
|
|
12409
12531
|
if (assetCount > 0 && assetCount !== images.length) {
|
|
12410
12532
|
ctx.addIssue({
|
|
12411
|
-
code:
|
|
12533
|
+
code: z49.ZodIssueCode.custom,
|
|
12412
12534
|
message: "all image entries must use assetId, or all must use URL/path sources"
|
|
12413
12535
|
});
|
|
12414
12536
|
}
|
|
@@ -12478,14 +12600,14 @@ async function submitCreative(api, opts) {
|
|
|
12478
12600
|
});
|
|
12479
12601
|
}
|
|
12480
12602
|
__name(submitCreative, "submitCreative");
|
|
12481
|
-
var ResearchTargetCountryEnum =
|
|
12603
|
+
var ResearchTargetCountryEnum = z49.enum([
|
|
12482
12604
|
"CO",
|
|
12483
12605
|
"MX",
|
|
12484
12606
|
"PE",
|
|
12485
12607
|
"EC",
|
|
12486
12608
|
"CL"
|
|
12487
12609
|
]);
|
|
12488
|
-
var ResearchCategoryEnum =
|
|
12610
|
+
var ResearchCategoryEnum = z49.enum([
|
|
12489
12611
|
"auto",
|
|
12490
12612
|
"automotive",
|
|
12491
12613
|
"kitchen",
|
|
@@ -12544,6 +12666,7 @@ var McpErrorCode = {
|
|
|
12544
12666
|
REVOKED_API_KEY: "REVOKED_API_KEY",
|
|
12545
12667
|
// Rate limit / quota
|
|
12546
12668
|
RATE_LIMITED: "RATE_LIMITED",
|
|
12669
|
+
CREDIT_ADMISSION_UNAVAILABLE: "CREDIT_ADMISSION_UNAVAILABLE",
|
|
12547
12670
|
// Input
|
|
12548
12671
|
INVALID_INPUT: "INVALID_INPUT",
|
|
12549
12672
|
INSUFFICIENT_CREDITS: "INSUFFICIENT_CREDITS",
|
|
@@ -12732,6 +12855,7 @@ var CODE_MESSAGES = {
|
|
|
12732
12855
|
REVOKED_API_KEY: "API key revoked. Generate a new one at https://productmaker.app/account/api-keys.",
|
|
12733
12856
|
// Rate
|
|
12734
12857
|
RATE_LIMITED: "Too many requests. Wait a few seconds.",
|
|
12858
|
+
CREDIT_ADMISSION_UNAVAILABLE: "Credit admission is temporarily unavailable. Do not retry a paid action until ProductMaker can verify the balance.",
|
|
12735
12859
|
INSUFFICIENT_CREDITS: "Insufficient credits for this action. Check your balance and add credits at https://productmaker.app before retrying.",
|
|
12736
12860
|
TASK_QUOTA_EXCEEDED: "You reached the active-task limit. Wait for a task to finish before creating another variant.",
|
|
12737
12861
|
// Generic
|
|
@@ -12826,6 +12950,7 @@ var INVALID_PARAM_CODES = /* @__PURE__ */ new Set([
|
|
|
12826
12950
|
McpErrorCode.NO_META_AD_ACCOUNTS
|
|
12827
12951
|
]);
|
|
12828
12952
|
var PASSTHROUGH_CODES = /* @__PURE__ */ new Set([
|
|
12953
|
+
McpErrorCode.CREDIT_ADMISSION_UNAVAILABLE,
|
|
12829
12954
|
McpErrorCode.INSUFFICIENT_CREDITS,
|
|
12830
12955
|
McpErrorCode.TASK_QUOTA_EXCEEDED,
|
|
12831
12956
|
McpErrorCode.DROPSHIPPING_PROJECT_NOT_FOUND,
|
|
@@ -12924,6 +13049,7 @@ __name(looksLikeMeaningfulBackendMessage, "looksLikeMeaningfulBackendMessage");
|
|
|
12924
13049
|
function resolveMessage(code, backendMessage) {
|
|
12925
13050
|
const mapped = CODE_MESSAGES[code];
|
|
12926
13051
|
const backend = typeof backendMessage === "string" ? backendMessage.trim() : "";
|
|
13052
|
+
if (code === McpErrorCode.CREDIT_ADMISSION_UNAVAILABLE && mapped) return mapped;
|
|
12927
13053
|
if (mapped && backend && looksLikeMeaningfulBackendMessage(backend, mapped)) {
|
|
12928
13054
|
return `${mapped} (Detail: ${backend})`;
|
|
12929
13055
|
}
|
|
@@ -13133,54 +13259,54 @@ function renderOutputsMarkdown(outputs) {
|
|
|
13133
13259
|
__name(renderOutputsMarkdown, "renderOutputsMarkdown");
|
|
13134
13260
|
|
|
13135
13261
|
// src/tools/tasks.ts
|
|
13136
|
-
var CreateProductTaskInput =
|
|
13262
|
+
var CreateProductTaskInput = z50.object({
|
|
13137
13263
|
images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
|
|
13138
|
-
projectId:
|
|
13139
|
-
productUrl:
|
|
13264
|
+
projectId: z50.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
|
|
13265
|
+
productUrl: z50.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."),
|
|
13140
13266
|
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.'),
|
|
13141
13267
|
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.'),
|
|
13142
|
-
price:
|
|
13143
|
-
compareAtPrice:
|
|
13144
|
-
offer:
|
|
13145
|
-
paymentMethods:
|
|
13146
|
-
productContext:
|
|
13147
|
-
productLabel:
|
|
13268
|
+
price: z50.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.'),
|
|
13269
|
+
compareAtPrice: z50.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".'),
|
|
13270
|
+
offer: z50.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.'),
|
|
13271
|
+
paymentMethods: z50.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.'),
|
|
13272
|
+
productContext: z50.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."),
|
|
13273
|
+
productLabel: z50.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.'),
|
|
13148
13274
|
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). 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" (una regla visual experimental original), "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.'),
|
|
13149
|
-
durationSeconds:
|
|
13150
|
-
|
|
13151
|
-
|
|
13275
|
+
durationSeconds: z50.union([
|
|
13276
|
+
z50.literal(15),
|
|
13277
|
+
z50.literal(30)
|
|
13152
13278
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
13153
|
-
pauseForAngleReview:
|
|
13154
|
-
aiDecidesAll:
|
|
13279
|
+
pauseForAngleReview: z50.boolean().optional().describe("Opcional. Si true, pausa despu\xE9s de generar el \xE1ngulo para que el usuario lo confirme o edite antes del render. \xDAsalo si quiere decidir 15/30s cuando aparezca un winner. Default false."),
|
|
13280
|
+
aiDecidesAll: z50.boolean().optional().describe("Opcional. Si true, ProductMaker decide TODO y no vuelve a interrumpir al usuario: resuelve solo las confirmaciones de referencias del producto y no abre gates de aprobaci\xF3n, as\xED que `pendingUserAction` no deber\xEDa aparecer. Act\xEDvalo \xFAnicamente cuando el usuario pida expl\xEDcitamente que la IA decida todo o que no le pregunten m\xE1s. Default false."),
|
|
13155
13281
|
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.'),
|
|
13156
13282
|
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).'),
|
|
13157
|
-
multiAngleVideos:
|
|
13283
|
+
multiAngleVideos: z50.boolean().optional().describe("Opcional. Si true, genera m\xFAltiples \xE1ngulos de venta en paralelo (3-5 videos). Si false/omitido, genera 1 video del \xE1ngulo principal. Default false."),
|
|
13158
13284
|
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". angleNarratives[i] fuerza la narrativa del \xE1ngulo i; las posiciones restantes las elige la IA. Requiere multiAngleVideos:true para varios \xE1ngulos.'),
|
|
13159
|
-
outputs:
|
|
13285
|
+
outputs: z50.array(z50.enum([
|
|
13160
13286
|
"landing",
|
|
13161
13287
|
"video",
|
|
13162
13288
|
"image"
|
|
13163
13289
|
])).min(2).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). Para 1 solo output, usa generate_landing / generate_video_creative / generate_image_creatives.'),
|
|
13164
|
-
competitorScanEnabled:
|
|
13165
|
-
brandId:
|
|
13166
|
-
actorId:
|
|
13167
|
-
creativeDirection:
|
|
13168
|
-
headline:
|
|
13169
|
-
subheadline:
|
|
13290
|
+
competitorScanEnabled: z50.boolean().optional().describe("Opcional. Si true (default), el sistema analiza ads de competencia en Meta Ad Library y enriquece los \xE1ngulos generados con hooks y painPoints validados por el mercado (\u2248$0.20-0.48 extra por task \u2014 var\xEDa con cu\xE1ntas transcripciones de video se capturen). Si false, el pipeline genera \xE1ngulos sin esa se\xF1al \u2014 usa esto SOLO si el usuario ya tiene su propia investigaci\xF3n de mercado o quiere ahorrar costos en productos muy nicho sin presencia en Meta. Default true."),
|
|
13291
|
+
brandId: z50.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."),
|
|
13292
|
+
actorId: z50.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."),
|
|
13293
|
+
creativeDirection: z50.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.'),
|
|
13294
|
+
headline: z50.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."),
|
|
13295
|
+
subheadline: z50.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."),
|
|
13170
13296
|
landingStrategy: LandingStrategyEnum.default("classic").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".'),
|
|
13171
13297
|
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".')
|
|
13172
13298
|
}).strict();
|
|
13173
|
-
var CreateServiceVideoInput =
|
|
13174
|
-
landingUrl:
|
|
13175
|
-
additionalContext:
|
|
13299
|
+
var CreateServiceVideoInput = z50.object({
|
|
13300
|
+
landingUrl: z50.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
|
|
13301
|
+
additionalContext: z50.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
|
|
13176
13302
|
language: Lang.describe("Idioma del video: es, en o pt."),
|
|
13177
|
-
voiceId:
|
|
13178
|
-
brandId:
|
|
13179
|
-
reviewMode:
|
|
13303
|
+
voiceId: z50.string().trim().min(1).optional().describe('Opcional. Voz de ElevenLabs para toda la narraci\xF3n. Usa "auto" para que la IA la alinee con el presentador o env\xEDa un ID concreto de la lista de voces de la web.'),
|
|
13304
|
+
brandId: z50.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
|
|
13305
|
+
reviewMode: z50.enum([
|
|
13180
13306
|
"automatic",
|
|
13181
13307
|
"guided"
|
|
13182
13308
|
]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
|
|
13183
|
-
videoPreset:
|
|
13309
|
+
videoPreset: z50.enum([
|
|
13184
13310
|
"auto",
|
|
13185
13311
|
"ugc_dynamic",
|
|
13186
13312
|
"ugc_how_to",
|
|
@@ -13188,51 +13314,51 @@ var CreateServiceVideoInput = z49.object({
|
|
|
13188
13314
|
"wild_card"
|
|
13189
13315
|
]).default("auto")
|
|
13190
13316
|
}).strict();
|
|
13191
|
-
var GetTaskStatusInput =
|
|
13192
|
-
taskId:
|
|
13193
|
-
waitSeconds:
|
|
13194
|
-
});
|
|
13195
|
-
var ListTasksInput =
|
|
13196
|
-
limit:
|
|
13197
|
-
offset:
|
|
13198
|
-
search:
|
|
13199
|
-
});
|
|
13200
|
-
var EditTaskDraftInput =
|
|
13201
|
-
taskId:
|
|
13202
|
-
angleIndex:
|
|
13203
|
-
angle:
|
|
13204
|
-
angle:
|
|
13205
|
-
buyerPersona:
|
|
13206
|
-
actor:
|
|
13207
|
-
actorId:
|
|
13208
|
-
gender:
|
|
13317
|
+
var GetTaskStatusInput = z50.object({
|
|
13318
|
+
taskId: z50.string().min(1),
|
|
13319
|
+
waitSeconds: z50.number().int().min(0).max(120).optional()
|
|
13320
|
+
});
|
|
13321
|
+
var ListTasksInput = z50.object({
|
|
13322
|
+
limit: z50.number().int().min(1).max(50).optional(),
|
|
13323
|
+
offset: z50.number().int().min(0).optional(),
|
|
13324
|
+
search: z50.string().optional()
|
|
13325
|
+
});
|
|
13326
|
+
var EditTaskDraftInput = z50.object({
|
|
13327
|
+
taskId: z50.string().min(1),
|
|
13328
|
+
angleIndex: z50.number().int().min(0),
|
|
13329
|
+
angle: z50.object({
|
|
13330
|
+
angle: z50.string().min(1).max(480),
|
|
13331
|
+
buyerPersona: z50.string().min(1).max(360),
|
|
13332
|
+
actor: z50.string().min(1).max(360).optional(),
|
|
13333
|
+
actorId: z50.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."),
|
|
13334
|
+
gender: z50.enum([
|
|
13209
13335
|
"female",
|
|
13210
13336
|
"male"
|
|
13211
13337
|
]).optional(),
|
|
13212
|
-
scriptNotes:
|
|
13338
|
+
scriptNotes: z50.string().max(2e3).optional()
|
|
13213
13339
|
})
|
|
13214
13340
|
});
|
|
13215
|
-
var PendingActionPayload =
|
|
13216
|
-
|
|
13217
|
-
kind:
|
|
13341
|
+
var PendingActionPayload = z50.discriminatedUnion("kind", [
|
|
13342
|
+
z50.object({
|
|
13343
|
+
kind: z50.literal("product_reference_set_approval"),
|
|
13218
13344
|
scope: ProductReferenceScopeEnum,
|
|
13219
|
-
scopeKey:
|
|
13220
|
-
scopeSnapshotId:
|
|
13221
|
-
expectedScopeHash:
|
|
13345
|
+
scopeKey: z50.string().min(1).max(120),
|
|
13346
|
+
scopeSnapshotId: z50.string().uuid(),
|
|
13347
|
+
expectedScopeHash: z50.string().min(1).max(128),
|
|
13222
13348
|
decision: ProductReferenceResolutionDecisionEnum,
|
|
13223
13349
|
reason: ProductReferenceRejectionReasonEnum.optional(),
|
|
13224
|
-
affectedRefKeys:
|
|
13225
|
-
recoveryAction:
|
|
13350
|
+
affectedRefKeys: z50.array(z50.string().min(1).max(200)).min(1).optional(),
|
|
13351
|
+
recoveryAction: z50.enum([
|
|
13226
13352
|
"remove",
|
|
13227
13353
|
"replace",
|
|
13228
13354
|
"upload",
|
|
13229
13355
|
"return_to_selection"
|
|
13230
13356
|
]).optional()
|
|
13231
13357
|
}),
|
|
13232
|
-
|
|
13233
|
-
kind:
|
|
13358
|
+
z50.object({
|
|
13359
|
+
kind: z50.literal("product_reference_confirmation"),
|
|
13234
13360
|
userChoice: ProductReferenceUserChoiceEnum.optional(),
|
|
13235
|
-
confirmedProductNames:
|
|
13361
|
+
confirmedProductNames: z50.array(z50.string().min(1).max(120)).min(2).max(8).optional(),
|
|
13236
13362
|
// SCOPED multi-scene opt-in — the ONLY way STANDARD ("Multiescena") is
|
|
13237
13363
|
// reachable via MCP. Valid ONLY together with userChoice='variants' (same
|
|
13238
13364
|
// product in several colors): renders one shot per color and stitches them,
|
|
@@ -13243,50 +13369,50 @@ var PendingActionPayload = z49.discriminatedUnion("kind", [
|
|
|
13243
13369
|
// safe because multi-scene IS the intended render for a color variant set,
|
|
13244
13370
|
// not a blind quality upsell. Maps to `videoTier: 'standard'` on the
|
|
13245
13371
|
// confirm call; the backend re-gates it (variants + variant_set only).
|
|
13246
|
-
useMultiSceneShowcase:
|
|
13372
|
+
useMultiSceneShowcase: z50.boolean().optional().describe('Opcional (SOLO con userChoice="variants"). true = render Multiescena: una toma por color, mostrando todas las variantes, hasta 30s. Se factura POR ESCENA (m\xE1s caro que el render normal de una sola toma) \u2014 AV\xCDSALE del mayor costo al usuario antes de activarlo. Omitir = render est\xE1ndar de una sola toma. Se ignora si userChoice no es "variants".')
|
|
13247
13373
|
}),
|
|
13248
|
-
|
|
13249
|
-
kind:
|
|
13374
|
+
z50.object({
|
|
13375
|
+
kind: z50.literal("angle_review_approval"),
|
|
13250
13376
|
// All edits are optional — empty action body just approves the
|
|
13251
13377
|
// backend-generated draft as-is. Field shapes mirror the angle-review
|
|
13252
13378
|
// request contracts in @packages/types/wizard.ts; the handler routes to
|
|
13253
13379
|
// the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
|
|
13254
|
-
customAngle:
|
|
13380
|
+
customAngle: z50.string().min(1).max(480).optional(),
|
|
13255
13381
|
// Keep the shared MCP action within the strictest downstream contract:
|
|
13256
13382
|
// autopilot/image resume endpoints cap these fields at 1500 characters.
|
|
13257
|
-
painPoints:
|
|
13258
|
-
benefits:
|
|
13259
|
-
features:
|
|
13260
|
-
gapDurationSeconds:
|
|
13261
|
-
|
|
13262
|
-
|
|
13383
|
+
painPoints: z50.string().max(1500).optional(),
|
|
13384
|
+
benefits: z50.string().max(1500).optional(),
|
|
13385
|
+
features: z50.array(z50.string().min(1).max(300)).max(10).optional(),
|
|
13386
|
+
gapDurationSeconds: z50.union([
|
|
13387
|
+
z50.literal(15),
|
|
13388
|
+
z50.literal(30)
|
|
13263
13389
|
]).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.")
|
|
13264
13390
|
}),
|
|
13265
|
-
|
|
13266
|
-
kind:
|
|
13267
|
-
angleId:
|
|
13268
|
-
content:
|
|
13269
|
-
creativeDirection:
|
|
13270
|
-
actor:
|
|
13391
|
+
z50.object({
|
|
13392
|
+
kind: z50.literal("service_angle_approval"),
|
|
13393
|
+
angleId: z50.string().uuid(),
|
|
13394
|
+
content: z50.string().min(1).max(480).optional(),
|
|
13395
|
+
creativeDirection: z50.string().min(1).max(1500).optional(),
|
|
13396
|
+
actor: z50.string().min(1).max(360).optional()
|
|
13271
13397
|
}),
|
|
13272
|
-
|
|
13273
|
-
kind:
|
|
13274
|
-
voiceovers:
|
|
13275
|
-
visualDirections:
|
|
13398
|
+
z50.object({
|
|
13399
|
+
kind: z50.literal("service_script_approval"),
|
|
13400
|
+
voiceovers: z50.record(z50.string(), z50.string().min(1).max(600)).optional(),
|
|
13401
|
+
visualDirections: z50.record(z50.string(), z50.string().min(1).max(1200)).optional()
|
|
13276
13402
|
})
|
|
13277
13403
|
]);
|
|
13278
|
-
var ResolvePendingActionInput =
|
|
13279
|
-
taskId:
|
|
13404
|
+
var ResolvePendingActionInput = z50.object({
|
|
13405
|
+
taskId: z50.string().min(1),
|
|
13280
13406
|
action: PendingActionPayload
|
|
13281
13407
|
}).strict();
|
|
13282
13408
|
function resolveVariantConfirmVideoTier(action) {
|
|
13283
13409
|
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
13284
13410
|
}
|
|
13285
13411
|
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
13286
|
-
var StatusForResolveSchema =
|
|
13412
|
+
var StatusForResolveSchema = z50.object({
|
|
13287
13413
|
// Metadata used to select the backend resume contract. Older API responses
|
|
13288
13414
|
// may omit these fields, so the resolver keeps the generic fallback.
|
|
13289
|
-
kind:
|
|
13415
|
+
kind: z50.enum([
|
|
13290
13416
|
"autopilot",
|
|
13291
13417
|
"video",
|
|
13292
13418
|
"image",
|
|
@@ -13294,24 +13420,24 @@ var StatusForResolveSchema = z49.object({
|
|
|
13294
13420
|
"mix",
|
|
13295
13421
|
"service"
|
|
13296
13422
|
]).optional(),
|
|
13297
|
-
selectedOutputs:
|
|
13423
|
+
selectedOutputs: z50.array(z50.enum([
|
|
13298
13424
|
"landing",
|
|
13299
13425
|
"video",
|
|
13300
13426
|
"image"
|
|
13301
13427
|
])).optional(),
|
|
13302
|
-
videoAngleCount:
|
|
13303
|
-
ugcFormat:
|
|
13428
|
+
videoAngleCount: z50.number().int().min(1).max(3).optional(),
|
|
13429
|
+
ugcFormat: z50.enum([
|
|
13304
13430
|
"single_8s",
|
|
13305
13431
|
"single_15s",
|
|
13306
13432
|
"double_30s"
|
|
13307
13433
|
]).optional(),
|
|
13308
|
-
videoStyle:
|
|
13434
|
+
videoStyle: z50.enum([
|
|
13309
13435
|
"ugc",
|
|
13310
13436
|
"cartoon_3d",
|
|
13311
13437
|
"product_only",
|
|
13312
13438
|
"ai_dynamic"
|
|
13313
13439
|
]).optional(),
|
|
13314
|
-
videoModel:
|
|
13440
|
+
videoModel: z50.enum([
|
|
13315
13441
|
"veo",
|
|
13316
13442
|
"wan",
|
|
13317
13443
|
"bytedance",
|
|
@@ -13319,62 +13445,62 @@ var StatusForResolveSchema = z49.object({
|
|
|
13319
13445
|
"grok",
|
|
13320
13446
|
"kling"
|
|
13321
13447
|
]).optional(),
|
|
13322
|
-
videoTier:
|
|
13448
|
+
videoTier: z50.enum([
|
|
13323
13449
|
"legacy",
|
|
13324
13450
|
"standard",
|
|
13325
13451
|
"pro",
|
|
13326
13452
|
"single_call"
|
|
13327
13453
|
]).optional(),
|
|
13328
|
-
videoResolution:
|
|
13454
|
+
videoResolution: z50.enum([
|
|
13329
13455
|
"480p",
|
|
13330
13456
|
"720p"
|
|
13331
13457
|
]).optional(),
|
|
13332
13458
|
narrativeStyle: NarrativeStyleEnum.optional(),
|
|
13333
|
-
pendingUserAction:
|
|
13334
|
-
kind:
|
|
13335
|
-
candidateGrouping:
|
|
13336
|
-
selectedImageUrls:
|
|
13337
|
-
proposedProductNames:
|
|
13459
|
+
pendingUserAction: z50.object({
|
|
13460
|
+
kind: z50.string(),
|
|
13461
|
+
candidateGrouping: z50.string().optional(),
|
|
13462
|
+
selectedImageUrls: z50.array(z50.string()).optional(),
|
|
13463
|
+
proposedProductNames: z50.array(z50.string()).optional(),
|
|
13338
13464
|
// Adaptive reference questions are server-owned. Echo only the evidence
|
|
13339
13465
|
// identity and the choices shown by the current snapshot; never accept a
|
|
13340
13466
|
// client-supplied reference set as authorization.
|
|
13341
|
-
options:
|
|
13342
|
-
mode:
|
|
13467
|
+
options: z50.array(ProductReferenceUserChoiceEnum).max(4).optional(),
|
|
13468
|
+
mode: z50.enum([
|
|
13343
13469
|
"question",
|
|
13344
13470
|
"visual_recovery"
|
|
13345
13471
|
]).optional(),
|
|
13346
|
-
decisionKey:
|
|
13347
|
-
questionOrdinal:
|
|
13348
|
-
questionCeiling:
|
|
13349
|
-
|
|
13350
|
-
|
|
13472
|
+
decisionKey: z50.string().optional(),
|
|
13473
|
+
questionOrdinal: z50.number().int().min(1).max(5).optional(),
|
|
13474
|
+
questionCeiling: z50.union([
|
|
13475
|
+
z50.literal(3),
|
|
13476
|
+
z50.literal(5)
|
|
13351
13477
|
]).optional(),
|
|
13352
|
-
referenceEvidenceVersion:
|
|
13353
|
-
expectedEvidenceHash:
|
|
13354
|
-
question:
|
|
13355
|
-
prompt:
|
|
13356
|
-
helpText:
|
|
13357
|
-
options:
|
|
13478
|
+
referenceEvidenceVersion: z50.number().int().positive().optional(),
|
|
13479
|
+
expectedEvidenceHash: z50.string().optional(),
|
|
13480
|
+
question: z50.object({
|
|
13481
|
+
prompt: z50.string().min(1).max(240),
|
|
13482
|
+
helpText: z50.string().min(1).max(300).optional(),
|
|
13483
|
+
options: z50.array(z50.object({
|
|
13358
13484
|
value: ProductReferenceUserChoiceEnum,
|
|
13359
|
-
label:
|
|
13360
|
-
description:
|
|
13485
|
+
label: z50.string().min(1).max(120),
|
|
13486
|
+
description: z50.string().min(1).max(240).optional()
|
|
13361
13487
|
})).min(2).max(4)
|
|
13362
13488
|
}).optional(),
|
|
13363
13489
|
scope: ProductReferenceScopeEnum.optional(),
|
|
13364
|
-
scopeKey:
|
|
13365
|
-
scopeSnapshotId:
|
|
13366
|
-
scopeHash:
|
|
13367
|
-
baseReferenceSetHash:
|
|
13368
|
-
phase:
|
|
13490
|
+
scopeKey: z50.string().optional(),
|
|
13491
|
+
scopeSnapshotId: z50.string().uuid().optional(),
|
|
13492
|
+
scopeHash: z50.string().optional(),
|
|
13493
|
+
baseReferenceSetHash: z50.string().optional(),
|
|
13494
|
+
phase: z50.enum([
|
|
13369
13495
|
"preparation",
|
|
13370
13496
|
"final"
|
|
13371
13497
|
]).optional(),
|
|
13372
|
-
selectedRefKeys:
|
|
13373
|
-
allowedDecisions:
|
|
13374
|
-
customAngleDraft:
|
|
13375
|
-
painPointsDraft:
|
|
13376
|
-
benefitsDraft:
|
|
13377
|
-
featuresDraft:
|
|
13498
|
+
selectedRefKeys: z50.array(z50.string().min(1).max(200)).optional(),
|
|
13499
|
+
allowedDecisions: z50.array(ProductReferenceResolutionDecisionEnum).optional(),
|
|
13500
|
+
customAngleDraft: z50.string().optional(),
|
|
13501
|
+
painPointsDraft: z50.string().optional(),
|
|
13502
|
+
benefitsDraft: z50.string().optional(),
|
|
13503
|
+
featuresDraft: z50.array(z50.string()).optional(),
|
|
13378
13504
|
// Recommendation consumed only when the caller explicitly sends
|
|
13379
13505
|
// gapDurationSeconds: 30 in the angle approval action.
|
|
13380
13506
|
gapDurationChoice: GapDurationChoiceMirror.optional(),
|
|
@@ -13383,17 +13509,17 @@ var StatusForResolveSchema = z49.object({
|
|
|
13383
13509
|
// keys. `actorId` (the saved custom actor the picker stored) was silently
|
|
13384
13510
|
// dropped here, so the approval handler below could not echo it back on the
|
|
13385
13511
|
// PATCH — the selection looked accepted and reached no render.
|
|
13386
|
-
angles:
|
|
13387
|
-
id:
|
|
13388
|
-
content:
|
|
13389
|
-
creativeDirection:
|
|
13390
|
-
actor:
|
|
13391
|
-
actorId:
|
|
13512
|
+
angles: z50.array(z50.object({
|
|
13513
|
+
id: z50.string().uuid(),
|
|
13514
|
+
content: z50.string(),
|
|
13515
|
+
creativeDirection: z50.string(),
|
|
13516
|
+
actor: z50.string(),
|
|
13517
|
+
actorId: z50.string().nullable().optional()
|
|
13392
13518
|
}).passthrough()).optional(),
|
|
13393
|
-
panels:
|
|
13394
|
-
beatId:
|
|
13395
|
-
voiceover:
|
|
13396
|
-
visualDirection:
|
|
13519
|
+
panels: z50.array(z50.object({
|
|
13520
|
+
beatId: z50.string(),
|
|
13521
|
+
voiceover: z50.string(),
|
|
13522
|
+
visualDirection: z50.string()
|
|
13397
13523
|
}).passthrough()).optional()
|
|
13398
13524
|
}).optional()
|
|
13399
13525
|
}).passthrough();
|
|
@@ -13906,59 +14032,59 @@ __name(registerTaskTools, "registerTaskTools");
|
|
|
13906
14032
|
|
|
13907
14033
|
// src/tools/creatives.ts
|
|
13908
14034
|
import { randomUUID } from "crypto";
|
|
13909
|
-
import { z as
|
|
14035
|
+
import { z as z51 } from "zod";
|
|
13910
14036
|
var CreativeRefs = {
|
|
13911
14037
|
images: ImagesInput,
|
|
13912
14038
|
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.'),
|
|
13913
14039
|
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.'),
|
|
13914
|
-
price:
|
|
13915
|
-
offer:
|
|
13916
|
-
compareAtPrice:
|
|
13917
|
-
paymentMethods:
|
|
13918
|
-
productContext:
|
|
13919
|
-
productLabel:
|
|
13920
|
-
buyerPersona:
|
|
13921
|
-
isCombo:
|
|
13922
|
-
competitorScanEnabled:
|
|
13923
|
-
brandId:
|
|
13924
|
-
projectId:
|
|
13925
|
-
creativeDirection:
|
|
13926
|
-
headline:
|
|
13927
|
-
subheadline:
|
|
14040
|
+
price: z51.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.'),
|
|
14041
|
+
offer: z51.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.'),
|
|
14042
|
+
compareAtPrice: z51.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
|
|
14043
|
+
paymentMethods: z51.string().min(1).max(240).optional().describe('Opcional. M\xE9todos de pago a mostrar. Ej. "Tarjeta, PSE, Nequi, Contraentrega". Si se omite, la landing no muestra m\xE9todos de pago.'),
|
|
14044
|
+
productContext: z51.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."),
|
|
14045
|
+
productLabel: z51.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.'),
|
|
14046
|
+
buyerPersona: z51.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.'),
|
|
14047
|
+
isCombo: z51.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
|
|
14048
|
+
competitorScanEnabled: z51.boolean().optional().describe("Opcional. Si true (default), el sistema analiza ads de competencia en Meta Ad Library y enriquece los \xE1ngulos generados con hooks y painPoints validados por el mercado (\u2248$0.20-0.48 extra por task \u2014 var\xEDa con cu\xE1ntas transcripciones de video se capturen). Si false, el pipeline genera \xE1ngulos sin esa se\xF1al \u2014 usa esto SOLO si el usuario ya tiene su propia investigaci\xF3n de mercado o quiere ahorrar costos en productos muy nicho sin presencia en Meta. Default true."),
|
|
14049
|
+
brandId: z51.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."),
|
|
14050
|
+
projectId: z51.string().uuid().optional().describe("Opcional. ID de un proyecto guiado de dropshipping activo del usuario. Enlaza esta generaci\xF3n con su progreso y recompensas."),
|
|
14051
|
+
creativeDirection: z51.string().max(500).optional().describe('Opcional. Direcci\xF3n creativa en texto libre (colores, mood, estilo). M\xC1XIMA PRIORIDAD: anula marca, colores y estilo por defecto. Aplica SOLO a im\xE1genes y landing. Ej. im\xE1genes: "amarillo, azul y rojo, minimalista"; landing: "elegante, paleta fr\xEDa". Para video usa scriptNotes (ambiente/escenario). M\xE1x 500 caracteres.'),
|
|
14052
|
+
headline: z51.string().max(120).optional().describe("Opcional. Titular EXACTO a renderizar en la imagen (o en la portada de la landing). Se imprime tal cual: la IA no lo reescribe, no lo acorta y no lo traduce. \xDAsalo cuando el copy es de marca y no es negociable. M\xE1x 120 caracteres. Si lo omites, la IA escribe el titular."),
|
|
14053
|
+
subheadline: z51.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.")
|
|
13928
14054
|
};
|
|
13929
|
-
var VideoInput =
|
|
14055
|
+
var VideoInput = z51.object({
|
|
13930
14056
|
images: CreativeRefs.images,
|
|
13931
|
-
title:
|
|
13932
|
-
primaryAngle:
|
|
14057
|
+
title: z51.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
|
|
14058
|
+
primaryAngle: z51.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".'),
|
|
13933
14059
|
language: CreativeRefs.language,
|
|
13934
14060
|
country: CreativeRefs.country,
|
|
13935
|
-
aspectRatio:
|
|
14061
|
+
aspectRatio: z51.enum([
|
|
13936
14062
|
"9:16",
|
|
13937
14063
|
"16:9",
|
|
13938
14064
|
"Auto"
|
|
13939
14065
|
]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
|
|
13940
|
-
durationSeconds:
|
|
13941
|
-
|
|
13942
|
-
|
|
14066
|
+
durationSeconds: z51.union([
|
|
14067
|
+
z51.literal(15),
|
|
14068
|
+
z51.literal(30)
|
|
13943
14069
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
13944
14070
|
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). 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" (una regla visual experimental original), "pixar_problem" (problema animado 3D), "pixar_sassy" (producto que habla).'),
|
|
13945
14071
|
videoTier: VideoTierEnum.optional().describe('Opcional. Estilo del video. "basic" = "Realista"; para durationSeconds=30 el sistema selecciona internamente Multiescena. No se expone el tier interno directamente.'),
|
|
13946
14072
|
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).'),
|
|
13947
|
-
features:
|
|
14073
|
+
features: z51.array(z51.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
|
|
13948
14074
|
price: CreativeRefs.price,
|
|
13949
14075
|
offer: CreativeRefs.offer,
|
|
13950
14076
|
productContext: CreativeRefs.productContext,
|
|
13951
14077
|
productLabel: CreativeRefs.productLabel,
|
|
13952
|
-
cta:
|
|
13953
|
-
scriptNotes:
|
|
13954
|
-
pauseForVideoScriptReview:
|
|
13955
|
-
pauseForAngleReview:
|
|
13956
|
-
aiDecidesAll:
|
|
14078
|
+
cta: z51.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.'),
|
|
14079
|
+
scriptNotes: z51.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 \u2014 para editar el guion palabra-por-palabra, pasa `pauseForVideoScriptReview: true` y usa get_video_script / approve_video_script tras la pausa.'),
|
|
14080
|
+
pauseForVideoScriptReview: z51.boolean().optional().describe("Opcional. Si true, la tarea pausa despu\xE9s de generar el guion y antes de renderizar. \xDAsalo cuando el usuario quiera editar el guion antes de gastar cr\xE9ditos en el video. Tras la pausa: get_video_script para leerlo, approve_video_script para aprobar (con o sin ediciones). Default false."),
|
|
14081
|
+
pauseForAngleReview: z51.boolean().optional().describe("Opcional. Si true, pausa despu\xE9s de generar el \xE1ngulo para que el usuario lo confirme o edite antes del render. Default false."),
|
|
14082
|
+
aiDecidesAll: z51.boolean().optional().describe("Opcional. Si true, ProductMaker decide TODO y no vuelve a interrumpir al usuario: resuelve solo las confirmaciones de referencias del producto y no abre gates de aprobaci\xF3n. Act\xEDvalo \xFAnicamente cuando el usuario pida expl\xEDcitamente que la IA decida todo o que no le pregunten m\xE1s. Default false."),
|
|
13957
14083
|
competitorScanEnabled: CreativeRefs.competitorScanEnabled,
|
|
13958
14084
|
brandId: CreativeRefs.brandId,
|
|
13959
14085
|
projectId: CreativeRefs.projectId
|
|
13960
14086
|
}).strict();
|
|
13961
|
-
var FreeVideoQualityEnum =
|
|
14087
|
+
var FreeVideoQualityEnum = z51.enum([
|
|
13962
14088
|
"economical",
|
|
13963
14089
|
"high_detail"
|
|
13964
14090
|
]);
|
|
@@ -13980,38 +14106,38 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
|
|
|
13980
14106
|
15
|
|
13981
14107
|
]
|
|
13982
14108
|
};
|
|
13983
|
-
var FreeVideoInput =
|
|
14109
|
+
var FreeVideoInput = z51.object({
|
|
13984
14110
|
images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Si el usuario adjunt\xF3 o mencion\xF3 fotos locales y no existe un assetId reutilizable, llama primero request_media_upload con mediaKind=image y usa los assetId devueltos; no pidas rutas ni URLs. Om\xEDtelo para generar desde texto puro."),
|
|
13985
|
-
rawPrompt:
|
|
14111
|
+
rawPrompt: z51.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."),
|
|
13986
14112
|
quality: FreeVideoQualityEnum.describe('Calidad del video: "economical" = Econ\xF3mico o "high_detail" = Alto detalle.'),
|
|
13987
|
-
durationSeconds:
|
|
14113
|
+
durationSeconds: z51.number().int().min(1).max(15).describe("Duraci\xF3n exacta. Econ\xF3mico permite 6, 8, 10 o 15s; Alto detalle permite 4, 8, 12 o 15s."),
|
|
13988
14114
|
videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
|
|
13989
|
-
generateAiMusic:
|
|
13990
|
-
addSubtitles:
|
|
13991
|
-
idempotencyKey:
|
|
14115
|
+
generateAiMusic: z51.boolean().default(false).describe("Opcional. Agrega m\xFAsica instrumental IA debajo del audio nativo. Default false."),
|
|
14116
|
+
addSubtitles: z51.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
|
|
14117
|
+
idempotencyKey: z51.string().uuid().optional().describe("Opcional. UUID para reintentar exactamente esta misma solicitud sin crear ni cobrar otro video. Reutiliza el mismo valor si el cliente no recibi\xF3 la respuesta.")
|
|
13992
14118
|
}).strict();
|
|
13993
14119
|
var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
|
|
13994
14120
|
var archetypeList = ImageCreativeArchetypeEnum.options.join(" | ");
|
|
13995
14121
|
var visualTreatmentList = ImageCreativeVisualTreatmentEnum.options.join(" | ");
|
|
13996
14122
|
var aspectRatioList = ImageCreativeAspectRatioEnum.options.join(" | ");
|
|
13997
|
-
var ImageInput =
|
|
14123
|
+
var ImageInput = z51.object({
|
|
13998
14124
|
images: CreativeRefs.images,
|
|
13999
|
-
productTitle:
|
|
14000
|
-
primaryAngle:
|
|
14125
|
+
productTitle: z51.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
|
|
14126
|
+
primaryAngle: z51.string().min(1).describe('\xC1ngulo de venta principal. Ej. "Reduce arrugas en 14 d\xEDas".'),
|
|
14001
14127
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
14002
14128
|
language: CreativeRefs.language,
|
|
14003
14129
|
country: CreativeRefs.country,
|
|
14004
|
-
nVariants:
|
|
14005
|
-
imageModel:
|
|
14130
|
+
nVariants: z51.number().int().min(1).max(6).optional().describe("Opcional. N\xFAmero de variantes a generar (1-6). Default 3."),
|
|
14131
|
+
imageModel: z51.string().optional().describe('Opcional. Modelo de imagen. Ej. "gpt-image-2", "nano-banana-2". Om\xEDtelo para usar el default optimizado por costo/calidad.'),
|
|
14006
14132
|
imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
|
|
14007
14133
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe(`Opcional. Arquetipo CRO de la composici\xF3n. Valores: ${archetypeList}. Si se omite, la IA escoge seg\xFAn \xE1ngulo+oferta (ej. "offer_value_prop" cuando hay descuento, "social_proof_trust" cuando el \xE1ngulo es testimonial).`),
|
|
14008
14134
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe(`Opcional. Tratamiento gr\xE1fico. Valores: ${visualTreatmentList} ("performance_product_ad" = dealer-style alto CTR para Meta/TikTok ads; "premium_dtc_carousel" = fotograf\xEDa limpia estilo Allbirds/Glossier). Si se omite, la IA escoge.`),
|
|
14009
|
-
styleMix:
|
|
14135
|
+
styleMix: z51.boolean().optional().describe("Opcional. Si true, las N variantes mezclan distintos imageStyle para A/B test. Si false/omitido, todas comparten estilo. Default false."),
|
|
14010
14136
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe(`Opcional. Relaci\xF3n de aspecto. Valores: ${aspectRatioList}. Default "4:5" (vertical Instagram feed).`),
|
|
14011
|
-
generateAdCopy:
|
|
14012
|
-
pauseForAngleReview:
|
|
14013
|
-
features:
|
|
14014
|
-
brandColors:
|
|
14137
|
+
generateAdCopy: z51.boolean().optional().describe("Opcional. Si true, tambi\xE9n genera headline/body/CTA para el ad. Default false."),
|
|
14138
|
+
pauseForAngleReview: z51.boolean().optional().describe("Opcional. Si true, pausa despu\xE9s de generar el \xE1ngulo y antes de las im\xE1genes para que el usuario edite v\xEDa edit_task_draft. Default false."),
|
|
14139
|
+
features: z51.array(z51.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
|
|
14140
|
+
brandColors: z51.array(z51.string()).optional().describe('Opcional. Paleta de marca en hex. Ej. ["#FF6B35", "#004E89"]. Si se omite, la IA elige seg\xFAn el producto.'),
|
|
14015
14141
|
price: CreativeRefs.price,
|
|
14016
14142
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
14017
14143
|
offer: CreativeRefs.offer,
|
|
@@ -14025,17 +14151,17 @@ var ImageInput = z50.object({
|
|
|
14025
14151
|
headline: CreativeRefs.headline,
|
|
14026
14152
|
subheadline: CreativeRefs.subheadline
|
|
14027
14153
|
});
|
|
14028
|
-
var EditImageCreativeInput =
|
|
14029
|
-
taskId:
|
|
14030
|
-
variantIndex:
|
|
14031
|
-
instruction:
|
|
14154
|
+
var EditImageCreativeInput = z51.object({
|
|
14155
|
+
taskId: z51.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
|
|
14156
|
+
variantIndex: z51.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
|
|
14157
|
+
instruction: z51.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".')
|
|
14032
14158
|
});
|
|
14033
|
-
var LandingInput =
|
|
14034
|
-
aiDecidesAll:
|
|
14159
|
+
var LandingInput = z51.object({
|
|
14160
|
+
aiDecidesAll: z51.boolean().optional().describe("Opcional. Si true, ProductMaker decide TODO y no vuelve a interrumpir al usuario: resuelve solo las confirmaciones de referencias del producto y no abre gates de aprobaci\xF3n. Act\xEDvalo \xFAnicamente cuando el usuario pida expl\xEDcitamente que la IA decida todo o que no le pregunten m\xE1s. Default false."),
|
|
14035
14161
|
images: CreativeRefs.images,
|
|
14036
14162
|
language: CreativeRefs.language,
|
|
14037
14163
|
country: CreativeRefs.country,
|
|
14038
|
-
salesAngle:
|
|
14164
|
+
salesAngle: z51.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.'),
|
|
14039
14165
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
14040
14166
|
price: CreativeRefs.price,
|
|
14041
14167
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
@@ -14050,6 +14176,7 @@ var LandingInput = z50.object({
|
|
|
14050
14176
|
creativeDirection: CreativeRefs.creativeDirection,
|
|
14051
14177
|
landingStrategy: LandingStrategyEnum.default("classic").describe('Opcional. Estructura de la landing cl\xE1sica: "classic" (estructura original probada y recomendada; default del primer rollout), "auto" (la IA decide; experimental), "pain_solution" (problema\u2192soluci\xF3n), "social_proof" (Landing Viral: UGC, WhatsApp, Instagram y evidencia social), "benefits_clarity" (beneficios claros), "offer_value" (promoci\xF3n/valor) o "lifestyle_identity" (estilo de vida). Default "classic".'),
|
|
14052
14178
|
landingImageFormat: LandingImageFormatEnum.default("9:16").describe('Opcional. Formato/relaci\xF3n de aspecto de las im\xE1genes de la landing cl\xE1sica: "9:16" (vertical, por defecto), "4:5" (vertical compacto para feed) o "1:1" (cuadrado). Default "9:16".'),
|
|
14179
|
+
pauseForAngleReview: z51.boolean().optional().describe("Opcional. Si true, pausa despu\xE9s de generar el \xE1ngulo para que el usuario lo confirme o edite antes de la creaci\xF3n de la landing. Default false."),
|
|
14053
14180
|
headline: CreativeRefs.headline,
|
|
14054
14181
|
subheadline: CreativeRefs.subheadline
|
|
14055
14182
|
});
|
|
@@ -14160,8 +14287,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
14160
14287
|
__name(registerCreativeTools, "registerCreativeTools");
|
|
14161
14288
|
|
|
14162
14289
|
// src/tools/creative-variants.ts
|
|
14163
|
-
import { z as
|
|
14164
|
-
var LandingSectionKeyEnum =
|
|
14290
|
+
import { z as z52 } from "zod";
|
|
14291
|
+
var LandingSectionKeyEnum = z52.enum([
|
|
14165
14292
|
"problem_hook",
|
|
14166
14293
|
"problem_cost",
|
|
14167
14294
|
"solution_mechanism",
|
|
@@ -14201,24 +14328,24 @@ var LandingSectionKeyEnum = z51.enum([
|
|
|
14201
14328
|
"lifestyle_fit",
|
|
14202
14329
|
"join_lifestyle"
|
|
14203
14330
|
]);
|
|
14204
|
-
var CreativeVariantKindEnum =
|
|
14331
|
+
var CreativeVariantKindEnum = z52.enum([
|
|
14205
14332
|
"video",
|
|
14206
14333
|
"image",
|
|
14207
14334
|
"landing"
|
|
14208
14335
|
]);
|
|
14209
|
-
var EstimateCreativeVariantInputBase =
|
|
14210
|
-
sourceTaskId:
|
|
14336
|
+
var EstimateCreativeVariantInputBase = z52.object({
|
|
14337
|
+
sourceTaskId: z52.string().uuid().describe("ID de la tarea original completada."),
|
|
14211
14338
|
kind: CreativeVariantKindEnum,
|
|
14212
14339
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
|
|
14213
14340
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
|
|
14214
|
-
nVariants:
|
|
14341
|
+
nVariants: z52.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
14215
14342
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
|
|
14216
|
-
instructions:
|
|
14343
|
+
instructions: z52.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.")
|
|
14217
14344
|
}).strict();
|
|
14218
14345
|
var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
14219
14346
|
if (input.kind === "video" && input.nVariants !== void 0) {
|
|
14220
14347
|
ctx.addIssue({
|
|
14221
|
-
code:
|
|
14348
|
+
code: z52.ZodIssueCode.custom,
|
|
14222
14349
|
path: [
|
|
14223
14350
|
"nVariants"
|
|
14224
14351
|
],
|
|
@@ -14228,7 +14355,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
14228
14355
|
if (input.kind !== "video") {
|
|
14229
14356
|
if (input.videoPreset !== void 0) {
|
|
14230
14357
|
ctx.addIssue({
|
|
14231
|
-
code:
|
|
14358
|
+
code: z52.ZodIssueCode.custom,
|
|
14232
14359
|
path: [
|
|
14233
14360
|
"videoPreset"
|
|
14234
14361
|
],
|
|
@@ -14237,7 +14364,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
14237
14364
|
}
|
|
14238
14365
|
if (input.videoResolution !== void 0) {
|
|
14239
14366
|
ctx.addIssue({
|
|
14240
|
-
code:
|
|
14367
|
+
code: z52.ZodIssueCode.custom,
|
|
14241
14368
|
path: [
|
|
14242
14369
|
"videoResolution"
|
|
14243
14370
|
],
|
|
@@ -14247,7 +14374,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
14247
14374
|
}
|
|
14248
14375
|
if (input.kind !== "image" && input.nVariants !== void 0) {
|
|
14249
14376
|
ctx.addIssue({
|
|
14250
|
-
code:
|
|
14377
|
+
code: z52.ZodIssueCode.custom,
|
|
14251
14378
|
path: [
|
|
14252
14379
|
"nVariants"
|
|
14253
14380
|
],
|
|
@@ -14257,7 +14384,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
14257
14384
|
if (input.kind !== "landing") {
|
|
14258
14385
|
if (input.sectionKey !== void 0) {
|
|
14259
14386
|
ctx.addIssue({
|
|
14260
|
-
code:
|
|
14387
|
+
code: z52.ZodIssueCode.custom,
|
|
14261
14388
|
path: [
|
|
14262
14389
|
"sectionKey"
|
|
14263
14390
|
],
|
|
@@ -14266,7 +14393,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
14266
14393
|
}
|
|
14267
14394
|
if (input.instructions !== void 0) {
|
|
14268
14395
|
ctx.addIssue({
|
|
14269
|
-
code:
|
|
14396
|
+
code: z52.ZodIssueCode.custom,
|
|
14270
14397
|
path: [
|
|
14271
14398
|
"instructions"
|
|
14272
14399
|
],
|
|
@@ -14275,31 +14402,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
14275
14402
|
}
|
|
14276
14403
|
}
|
|
14277
14404
|
});
|
|
14278
|
-
var CreateCreativeVariantInputBase =
|
|
14279
|
-
sourceTaskId:
|
|
14405
|
+
var CreateCreativeVariantInputBase = z52.object({
|
|
14406
|
+
sourceTaskId: z52.string().uuid().describe("ID de la tarea original completada."),
|
|
14280
14407
|
kind: CreativeVariantKindEnum,
|
|
14281
|
-
confirm:
|
|
14282
|
-
clientRequestId:
|
|
14283
|
-
angle:
|
|
14284
|
-
buyerPersona:
|
|
14285
|
-
scriptNotes:
|
|
14286
|
-
creativeDirection:
|
|
14408
|
+
confirm: z52.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
|
|
14409
|
+
clientRequestId: z52.string().uuid().describe("UUID estable y obligatorio para esta intenci\xF3n. Reutil\xEDzalo ante timeouts o transporte ambiguo. Si la API devuelve status=error, una nueva generaci\xF3n exige otra confirmaci\xF3n y un UUID nuevo."),
|
|
14410
|
+
angle: z52.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
|
|
14411
|
+
buyerPersona: z52.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
|
|
14412
|
+
scriptNotes: z52.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
|
|
14413
|
+
creativeDirection: z52.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
|
|
14287
14414
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
|
|
14288
14415
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
|
|
14289
|
-
generateAiMusic:
|
|
14290
|
-
nVariants:
|
|
14416
|
+
generateAiMusic: z52.boolean().optional().describe("Opcional para video."),
|
|
14417
|
+
nVariants: z52.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
14291
14418
|
imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
|
|
14292
14419
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
|
|
14293
14420
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
|
|
14294
14421
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
|
|
14295
|
-
styleMix:
|
|
14422
|
+
styleMix: z52.boolean().optional().describe("Opcional para imagen."),
|
|
14296
14423
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
|
|
14297
|
-
instructions:
|
|
14424
|
+
instructions: z52.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.")
|
|
14298
14425
|
}).strict();
|
|
14299
14426
|
var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
14300
14427
|
if ((input.kind === "video" || input.kind === "image") && !input.angle) {
|
|
14301
14428
|
ctx.addIssue({
|
|
14302
|
-
code:
|
|
14429
|
+
code: z52.ZodIssueCode.custom,
|
|
14303
14430
|
path: [
|
|
14304
14431
|
"angle"
|
|
14305
14432
|
],
|
|
@@ -14308,7 +14435,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
14308
14435
|
}
|
|
14309
14436
|
if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
|
|
14310
14437
|
ctx.addIssue({
|
|
14311
|
-
code:
|
|
14438
|
+
code: z52.ZodIssueCode.custom,
|
|
14312
14439
|
path: [
|
|
14313
14440
|
"instructions"
|
|
14314
14441
|
],
|
|
@@ -14354,7 +14481,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
14354
14481
|
for (const field of fieldsByKind[input.kind]) {
|
|
14355
14482
|
if (input[field] !== void 0) {
|
|
14356
14483
|
ctx.addIssue({
|
|
14357
|
-
code:
|
|
14484
|
+
code: z52.ZodIssueCode.custom,
|
|
14358
14485
|
path: [
|
|
14359
14486
|
field
|
|
14360
14487
|
],
|
|
@@ -14471,27 +14598,27 @@ function registerCreativeVariantTools(server, api) {
|
|
|
14471
14598
|
__name(registerCreativeVariantTools, "registerCreativeVariantTools");
|
|
14472
14599
|
|
|
14473
14600
|
// src/tools/script-review.ts
|
|
14474
|
-
import { z as
|
|
14475
|
-
var GetVideoScriptInput =
|
|
14476
|
-
taskId:
|
|
14477
|
-
angleKey:
|
|
14601
|
+
import { z as z53 } from "zod";
|
|
14602
|
+
var GetVideoScriptInput = z53.object({
|
|
14603
|
+
taskId: z53.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
|
|
14604
|
+
angleKey: z53.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.')
|
|
14478
14605
|
}).strict();
|
|
14479
14606
|
var VIDEO_SCRIPT_APPROVAL_MAX_SCENES2 = 50;
|
|
14480
14607
|
var VIDEO_SCRIPT_APPROVAL_MAX_DIALOGUE_CHARS2 = 2e3;
|
|
14481
|
-
var ApproveSceneEdit =
|
|
14482
|
-
index:
|
|
14483
|
-
dialogue:
|
|
14608
|
+
var ApproveSceneEdit = z53.object({
|
|
14609
|
+
index: z53.number().int().nonnegative().describe("\xCDndice de la escena (0-based, mismo que devuelve get_video_script)."),
|
|
14610
|
+
dialogue: z53.string().min(1).max(VIDEO_SCRIPT_APPROVAL_MAX_DIALOGUE_CHARS2).refine((v) => v.trim().length > 0, {
|
|
14484
14611
|
message: "dialogue no puede ser s\xF3lo espacios"
|
|
14485
14612
|
}).describe("Di\xE1logo final de la escena. NO puede estar vac\xEDo ni ser s\xF3lo espacios. Puede ser el original sin cambios o la edici\xF3n del usuario.")
|
|
14486
14613
|
}).strict();
|
|
14487
|
-
var ApproveVideoScriptInput =
|
|
14488
|
-
taskId:
|
|
14489
|
-
angleKey:
|
|
14490
|
-
scenes:
|
|
14614
|
+
var ApproveVideoScriptInput = z53.object({
|
|
14615
|
+
taskId: z53.string().min(1).describe("ID de la tarea."),
|
|
14616
|
+
angleKey: z53.string().trim().min(1).max(120).optional().describe('Mismo angleKey usado en get_video_script. REQUERIDO en multi-angle (si se omite el backend resuelve a "angle_0" literal). En single-angle puede omitirse.'),
|
|
14617
|
+
scenes: z53.array(ApproveSceneEdit).min(1).max(VIDEO_SCRIPT_APPROVAL_MAX_SCENES2).describe("Escenas con los di\xE1logos finales. El backend mergea por `index` \u2014 las escenas NO incluidas conservan el di\xE1logo original. Debe haber entre 1 y 50 entradas. Para cada entrada que mandes con un dialogue distinto del original, el backend valida minWords \u2264 words \u2264 maxWords y rechaza con 400 si te sales del rango.")
|
|
14491
14618
|
}).strict();
|
|
14492
|
-
var RegenerateVideoScriptInput =
|
|
14493
|
-
taskId:
|
|
14494
|
-
angleKey:
|
|
14619
|
+
var RegenerateVideoScriptInput = z53.object({
|
|
14620
|
+
taskId: z53.string().min(1).describe("ID de la tarea."),
|
|
14621
|
+
angleKey: z53.string().min(1).describe('Clave del \xE1ngulo a regenerar. Single-angle: pasa "angle_0". Multi-angle: el mismo que devuelve get_video_script. NO se puede omitir \u2014 el backend lo exige siempre.'),
|
|
14495
14622
|
narrativeStyle: NarrativeStyleEnum.describe('Narrativa para el nuevo guion. Incluye valores hist\xF3ricos porque esta herramienta tambi\xE9n regenera tareas antiguas. REQUERIDO \u2014 el backend NO acepta "mantener la actual"; siempre tienes que elegir una. Si el usuario quiere re-rolear con la misma narrativa, pasa la que ya tiene el \xE1ngulo (la ves en get_video_script o en get_task_status).')
|
|
14496
14623
|
}).strict();
|
|
14497
14624
|
function registerScriptReviewTools(server, api) {
|
|
@@ -14542,9 +14669,9 @@ function registerScriptReviewTools(server, api) {
|
|
|
14542
14669
|
__name(registerScriptReviewTools, "registerScriptReviewTools");
|
|
14543
14670
|
|
|
14544
14671
|
// src/tools/connections.ts
|
|
14545
|
-
import { z as
|
|
14672
|
+
import { z as z54 } from "zod";
|
|
14546
14673
|
function registerConnectionTools(server, api) {
|
|
14547
|
-
server.tool("list_shopify_shops", "Lista las tiendas Shopify conectadas por este usuario. Si la lista est\xE1 vac\xEDa, dile al usuario que conecte una tienda en productmaker.app/integrations antes de intentar publicar.",
|
|
14674
|
+
server.tool("list_shopify_shops", "Lista las tiendas Shopify conectadas por este usuario. Si la lista est\xE1 vac\xEDa, dile al usuario que conecte una tienda en productmaker.app/integrations antes de intentar publicar.", z54.object({}).shape, READS_INTERNAL, async () => {
|
|
14548
14675
|
try {
|
|
14549
14676
|
const r = await api.getJson("/v1/shopify/shops");
|
|
14550
14677
|
return asText(r);
|
|
@@ -14552,10 +14679,10 @@ function registerConnectionTools(server, api) {
|
|
|
14552
14679
|
throw translateError(e);
|
|
14553
14680
|
}
|
|
14554
14681
|
});
|
|
14555
|
-
server.tool("list_shopify_products", 'Busca productos en una tienda Shopify conectada para elegir el target de una republicaci\xF3n. 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.',
|
|
14556
|
-
shopDomain:
|
|
14557
|
-
query:
|
|
14558
|
-
taskId:
|
|
14682
|
+
server.tool("list_shopify_products", 'Busca productos en una tienda Shopify conectada para elegir el target de una republicaci\xF3n. 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.', z54.object({
|
|
14683
|
+
shopDomain: z54.string().min(3).max(120),
|
|
14684
|
+
query: z54.string().trim().max(120).optional(),
|
|
14685
|
+
taskId: z54.string().uuid().optional()
|
|
14559
14686
|
}).shape, READS_EXTERNAL, async ({ shopDomain, query, taskId }) => {
|
|
14560
14687
|
try {
|
|
14561
14688
|
const params = new URLSearchParams({
|
|
@@ -14569,7 +14696,7 @@ function registerConnectionTools(server, api) {
|
|
|
14569
14696
|
throw translateError(e);
|
|
14570
14697
|
}
|
|
14571
14698
|
});
|
|
14572
|
-
server.tool("list_meta_ad_accounts", "Lista las cuentas publicitarias de Meta conectadas. 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.",
|
|
14699
|
+
server.tool("list_meta_ad_accounts", "Lista las cuentas publicitarias de Meta conectadas. 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.", z54.object({}).shape, READS_EXTERNAL, async () => {
|
|
14573
14700
|
try {
|
|
14574
14701
|
const r = await api.getJson("/v1/facebook/ad-accounts");
|
|
14575
14702
|
return asText(r);
|
|
@@ -14579,7 +14706,7 @@ function registerConnectionTools(server, api) {
|
|
|
14579
14706
|
});
|
|
14580
14707
|
server.registerTool("list_meta_destinations", {
|
|
14581
14708
|
description: "Lista los destinos de publicaci\xF3n de Meta del usuario: Business portfolios, cuentas publicitarias dentro de cada portfolio y Facebook Pages disponibles. 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.",
|
|
14582
|
-
inputSchema:
|
|
14709
|
+
inputSchema: z54.object({}).shape,
|
|
14583
14710
|
annotations: READS_EXTERNAL,
|
|
14584
14711
|
_meta: {
|
|
14585
14712
|
"openai/widgetAccessible": true
|
|
@@ -14592,7 +14719,7 @@ function registerConnectionTools(server, api) {
|
|
|
14592
14719
|
throw translateError(e);
|
|
14593
14720
|
}
|
|
14594
14721
|
});
|
|
14595
|
-
server.tool("list_tiktok_advertisers", "Lista las cuentas de TikTok Ads conectadas. Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
|
|
14722
|
+
server.tool("list_tiktok_advertisers", "Lista las cuentas de TikTok Ads conectadas. Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.", z54.object({}).shape, READS_EXTERNAL, async () => {
|
|
14596
14723
|
try {
|
|
14597
14724
|
const r = await api.getJson("/v1/tiktok/advertisers");
|
|
14598
14725
|
return asText(r);
|
|
@@ -14604,9 +14731,9 @@ function registerConnectionTools(server, api) {
|
|
|
14604
14731
|
__name(registerConnectionTools, "registerConnectionTools");
|
|
14605
14732
|
|
|
14606
14733
|
// src/tools/actors.ts
|
|
14607
|
-
import { z as
|
|
14734
|
+
import { z as z55 } from "zod";
|
|
14608
14735
|
function registerActorTools(server, api) {
|
|
14609
|
-
server.tool("list_actors", "Lista los personajes guardados del usuario (personas creadas con IA que pueden protagonizar los videos e im\xE1genes). Devuelve id, nombre, descripci\xF3n, g\xE9nero y voz. 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.",
|
|
14736
|
+
server.tool("list_actors", "Lista los personajes guardados del usuario (personas creadas con IA que pueden protagonizar los videos e im\xE1genes). Devuelve id, nombre, descripci\xF3n, g\xE9nero y voz. 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.", z55.object({}).shape, READS_INTERNAL, async () => {
|
|
14610
14737
|
try {
|
|
14611
14738
|
const rows = await api.getJson("/v1/actors");
|
|
14612
14739
|
const actors = (Array.isArray(rows) ? rows : []).filter((actor) => actor.status === "ready").map(({ id, name, description, gender, voiceId }) => ({
|
|
@@ -14627,39 +14754,39 @@ function registerActorTools(server, api) {
|
|
|
14627
14754
|
__name(registerActorTools, "registerActorTools");
|
|
14628
14755
|
|
|
14629
14756
|
// src/tools/publish.ts
|
|
14630
|
-
import { z as
|
|
14631
|
-
var ShopifyInput =
|
|
14632
|
-
taskId:
|
|
14633
|
-
shopDomain:
|
|
14757
|
+
import { z as z56 } from "zod";
|
|
14758
|
+
var ShopifyInput = z56.object({
|
|
14759
|
+
taskId: z56.string().min(1),
|
|
14760
|
+
shopDomain: z56.string().min(1),
|
|
14634
14761
|
/** Override: number of landing images to include. Default = ALL images the
|
|
14635
14762
|
* task generated (the MCP fetches /v1/results first to count). Bounded
|
|
14636
14763
|
* generously here; the backend validates each index against
|
|
14637
14764
|
* landing.images.length and rejects out-of-range. */
|
|
14638
|
-
numLandingImages:
|
|
14639
|
-
variantIndex:
|
|
14765
|
+
numLandingImages: z56.number().int().min(1).max(20).optional(),
|
|
14766
|
+
variantIndex: z56.number().int().min(0).optional(),
|
|
14640
14767
|
/** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
|
|
14641
14768
|
* When true, the landing renders variant-picker pills; when false, it ships
|
|
14642
14769
|
* a single-option product page. Defaults to false. */
|
|
14643
|
-
showVariantPicker:
|
|
14770
|
+
showVariantPicker: z56.boolean().optional(),
|
|
14644
14771
|
/** Default `auto` updates the product previously published for this task and
|
|
14645
14772
|
* shop. Use `existing` with targetProductId to choose another product, or
|
|
14646
14773
|
* `new` only when the user explicitly wants a duplicate/new listing. */
|
|
14647
|
-
publicationMode:
|
|
14774
|
+
publicationMode: z56.enum([
|
|
14648
14775
|
"auto",
|
|
14649
14776
|
"existing",
|
|
14650
14777
|
"new"
|
|
14651
14778
|
]).optional(),
|
|
14652
14779
|
/** Shopify product GID, numeric id, or admin product URL. Required when
|
|
14653
14780
|
* publicationMode is `existing`. */
|
|
14654
|
-
targetProductId:
|
|
14781
|
+
targetProductId: z56.string().trim().min(1).max(300).optional(),
|
|
14655
14782
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
14656
|
-
announcementBarEnabled:
|
|
14657
|
-
announcementBarText:
|
|
14783
|
+
announcementBarEnabled: z56.boolean().optional(),
|
|
14784
|
+
announcementBarText: z56.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional()
|
|
14658
14785
|
});
|
|
14659
14786
|
var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
|
|
14660
14787
|
if (value.announcementBarEnabled && !value.announcementBarText) {
|
|
14661
14788
|
ctx.addIssue({
|
|
14662
|
-
code:
|
|
14789
|
+
code: z56.ZodIssueCode.custom,
|
|
14663
14790
|
path: [
|
|
14664
14791
|
"announcementBarText"
|
|
14665
14792
|
],
|
|
@@ -14668,7 +14795,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
14668
14795
|
}
|
|
14669
14796
|
if (!value.announcementBarEnabled && value.announcementBarText) {
|
|
14670
14797
|
ctx.addIssue({
|
|
14671
|
-
code:
|
|
14798
|
+
code: z56.ZodIssueCode.custom,
|
|
14672
14799
|
path: [
|
|
14673
14800
|
"announcementBarText"
|
|
14674
14801
|
],
|
|
@@ -14682,90 +14809,90 @@ function parseShopifyInput(rawInput) {
|
|
|
14682
14809
|
return parsed.data;
|
|
14683
14810
|
}
|
|
14684
14811
|
__name(parseShopifyInput, "parseShopifyInput");
|
|
14685
|
-
var McpCampaignConfig =
|
|
14812
|
+
var McpCampaignConfig = z56.object({
|
|
14686
14813
|
/** ALWAYS in US dollars, whatever the ad account's currency is. ProductMaker
|
|
14687
14814
|
* converts to the account currency server-side. Do NOT pre-convert: on a COP
|
|
14688
14815
|
* account the user's "60.000 al día" is `dailyBudgetUsd: 15`, not 60000. */
|
|
14689
|
-
dailyBudgetUsd:
|
|
14816
|
+
dailyBudgetUsd: z56.number().positive().optional(),
|
|
14690
14817
|
/** ISO-3166-1 alpha-2 country codes. Meta accepts max 1 (single-country
|
|
14691
14818
|
* ad set). TikTok takes only the first entry. */
|
|
14692
|
-
targetCountries:
|
|
14693
|
-
campaignName:
|
|
14819
|
+
targetCountries: z56.array(z56.string().length(2)).max(1).optional(),
|
|
14820
|
+
campaignName: z56.string().trim().min(1).max(100).optional()
|
|
14694
14821
|
});
|
|
14695
14822
|
var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
|
|
14696
|
-
var MetaInput =
|
|
14697
|
-
taskId:
|
|
14823
|
+
var MetaInput = z56.object({
|
|
14824
|
+
taskId: z56.string().min(1),
|
|
14698
14825
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
14699
|
-
portfolioId:
|
|
14826
|
+
portfolioId: z56.string().trim().min(1),
|
|
14700
14827
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
14701
|
-
pageId:
|
|
14828
|
+
pageId: z56.string().trim().min(1),
|
|
14702
14829
|
adAccountId: McpAdAccountId,
|
|
14703
|
-
pixelId:
|
|
14704
|
-
landingUrl:
|
|
14830
|
+
pixelId: z56.string().min(1).optional(),
|
|
14831
|
+
landingUrl: z56.string().url().optional(),
|
|
14705
14832
|
/** Select which angles to publish by 0-based index. Omit to publish all
|
|
14706
14833
|
* successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
|
|
14707
|
-
angleIndexes:
|
|
14834
|
+
angleIndexes: z56.array(z56.number().int().nonnegative()).optional(),
|
|
14708
14835
|
campaignConfig: McpCampaignConfig.optional(),
|
|
14709
14836
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
14710
14837
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
14711
14838
|
* (Meta's primary-text limit). */
|
|
14712
|
-
primaryText:
|
|
14839
|
+
primaryText: z56.string().trim().min(1).max(500).optional(),
|
|
14713
14840
|
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
14714
14841
|
* (wa.me) instead of a landing page. */
|
|
14715
|
-
phoneNumber:
|
|
14842
|
+
phoneNumber: z56.string().min(8).max(32).optional()
|
|
14716
14843
|
});
|
|
14717
|
-
var GroupedTaskSource =
|
|
14718
|
-
type:
|
|
14719
|
-
taskId:
|
|
14720
|
-
angleIndex:
|
|
14721
|
-
videoVariant:
|
|
14844
|
+
var GroupedTaskSource = z56.object({
|
|
14845
|
+
type: z56.literal("task"),
|
|
14846
|
+
taskId: z56.string().min(1),
|
|
14847
|
+
angleIndex: z56.number().int().min(0).optional(),
|
|
14848
|
+
videoVariant: z56.enum([
|
|
14722
14849
|
"with_subtitles",
|
|
14723
14850
|
"without_subtitles"
|
|
14724
14851
|
]).optional(),
|
|
14725
|
-
imageVariantIndex:
|
|
14726
|
-
});
|
|
14727
|
-
var GroupedMediaSource =
|
|
14728
|
-
type:
|
|
14729
|
-
url:
|
|
14730
|
-
path:
|
|
14731
|
-
thumbnailUrl:
|
|
14732
|
-
thumbnailPath:
|
|
14852
|
+
imageVariantIndex: z56.number().int().min(0).optional()
|
|
14853
|
+
});
|
|
14854
|
+
var GroupedMediaSource = z56.object({
|
|
14855
|
+
type: z56.literal("media"),
|
|
14856
|
+
url: z56.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
|
|
14857
|
+
path: z56.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".'),
|
|
14858
|
+
thumbnailUrl: z56.string().url().optional(),
|
|
14859
|
+
thumbnailPath: z56.string().min(1).optional()
|
|
14733
14860
|
}).refine((value) => Boolean(value.url) !== Boolean(value.path), {
|
|
14734
14861
|
message: "media source needs exactly one of `url` or `path`"
|
|
14735
14862
|
}).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
|
|
14736
14863
|
message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
|
|
14737
14864
|
});
|
|
14738
|
-
var GroupedUploadedAssetSource =
|
|
14739
|
-
type:
|
|
14865
|
+
var GroupedUploadedAssetSource = z56.object({
|
|
14866
|
+
type: z56.literal("asset"),
|
|
14740
14867
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
14741
|
-
assetId:
|
|
14742
|
-
thumbnailAssetId:
|
|
14868
|
+
assetId: z56.string().uuid(),
|
|
14869
|
+
thumbnailAssetId: z56.string().uuid().optional()
|
|
14743
14870
|
});
|
|
14744
|
-
var GroupedCreative =
|
|
14745
|
-
type:
|
|
14871
|
+
var GroupedCreative = z56.object({
|
|
14872
|
+
type: z56.enum([
|
|
14746
14873
|
"image",
|
|
14747
14874
|
"video"
|
|
14748
14875
|
]),
|
|
14749
|
-
source:
|
|
14876
|
+
source: z56.union([
|
|
14750
14877
|
GroupedTaskSource,
|
|
14751
14878
|
GroupedMediaSource,
|
|
14752
14879
|
GroupedUploadedAssetSource
|
|
14753
14880
|
]),
|
|
14754
|
-
title:
|
|
14755
|
-
description:
|
|
14881
|
+
title: z56.string().max(120).optional(),
|
|
14882
|
+
description: z56.string().max(500).optional(),
|
|
14756
14883
|
cta: MetaCtaType.optional(),
|
|
14757
|
-
creativeId:
|
|
14884
|
+
creativeId: z56.string().min(1).optional()
|
|
14758
14885
|
});
|
|
14759
|
-
var GroupedCampaignConfigBase =
|
|
14886
|
+
var GroupedCampaignConfigBase = z56.object({
|
|
14760
14887
|
campaignType: MetaCampaignType.default("sales"),
|
|
14761
14888
|
optimizationMode: MetaOptimizationMode.default("advantage_plus"),
|
|
14762
14889
|
budgetMode: MetaBudgetMode.optional(),
|
|
14763
|
-
campaignDailyBudget:
|
|
14764
|
-
adSets:
|
|
14765
|
-
tempId:
|
|
14766
|
-
name:
|
|
14767
|
-
dailyBudget:
|
|
14768
|
-
creativeIds:
|
|
14890
|
+
campaignDailyBudget: z56.number().int().positive().optional(),
|
|
14891
|
+
adSets: z56.array(z56.object({
|
|
14892
|
+
tempId: z56.string().min(1).max(80),
|
|
14893
|
+
name: z56.string().min(1).max(100),
|
|
14894
|
+
dailyBudget: z56.number().int().positive().optional(),
|
|
14895
|
+
creativeIds: z56.array(z56.string().min(1)).min(1)
|
|
14769
14896
|
})).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
|
|
14770
14897
|
/**
|
|
14771
14898
|
* Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
|
|
@@ -14773,17 +14900,17 @@ var GroupedCampaignConfigBase = z55.object({
|
|
|
14773
14900
|
* opaque `invalid_literal` and made the WhatsApp destination — supported by
|
|
14774
14901
|
* the API since #849 — unreachable from this tool.
|
|
14775
14902
|
*/
|
|
14776
|
-
destination:
|
|
14777
|
-
|
|
14778
|
-
type:
|
|
14779
|
-
landingUrl:
|
|
14903
|
+
destination: z56.discriminatedUnion("type", [
|
|
14904
|
+
z56.object({
|
|
14905
|
+
type: z56.literal("landing"),
|
|
14906
|
+
landingUrl: z56.string().url()
|
|
14780
14907
|
}),
|
|
14781
|
-
|
|
14782
|
-
type:
|
|
14783
|
-
phoneNumber:
|
|
14908
|
+
z56.object({
|
|
14909
|
+
type: z56.literal("whatsapp"),
|
|
14910
|
+
phoneNumber: z56.string().min(8).max(32)
|
|
14784
14911
|
})
|
|
14785
14912
|
]),
|
|
14786
|
-
saveAsDefault:
|
|
14913
|
+
saveAsDefault: z56.boolean().default(false),
|
|
14787
14914
|
budgetPolicy: MetaBudgetPolicy.optional()
|
|
14788
14915
|
});
|
|
14789
14916
|
function resolveBudgetMode(value) {
|
|
@@ -14797,7 +14924,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
14797
14924
|
const budgetMode = resolveBudgetMode(value);
|
|
14798
14925
|
if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
|
|
14799
14926
|
ctx.addIssue({
|
|
14800
|
-
code:
|
|
14927
|
+
code: z56.ZodIssueCode.custom,
|
|
14801
14928
|
path: [
|
|
14802
14929
|
"campaignDailyBudget"
|
|
14803
14930
|
],
|
|
@@ -14808,7 +14935,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
14808
14935
|
value.adSets.forEach((adSet, index) => {
|
|
14809
14936
|
if (adSet.dailyBudget === void 0) {
|
|
14810
14937
|
ctx.addIssue({
|
|
14811
|
-
code:
|
|
14938
|
+
code: z56.ZodIssueCode.custom,
|
|
14812
14939
|
path: [
|
|
14813
14940
|
"adSets",
|
|
14814
14941
|
index,
|
|
@@ -14823,26 +14950,26 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
14823
14950
|
...value,
|
|
14824
14951
|
budgetMode: resolveBudgetMode(value)
|
|
14825
14952
|
}));
|
|
14826
|
-
var PublishCreativesToMetaInputBase =
|
|
14827
|
-
creatives:
|
|
14953
|
+
var PublishCreativesToMetaInputBase = z56.object({
|
|
14954
|
+
creatives: z56.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
|
|
14828
14955
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
14829
|
-
portfolioId:
|
|
14956
|
+
portfolioId: z56.string().trim().min(1),
|
|
14830
14957
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
14831
|
-
pageId:
|
|
14958
|
+
pageId: z56.string().trim().min(1),
|
|
14832
14959
|
adAccountId: McpAdAccountId,
|
|
14833
|
-
pixelId:
|
|
14960
|
+
pixelId: z56.string().min(1).optional(),
|
|
14834
14961
|
/** Required unless `campaignConfig.destination` is whatsapp — see the
|
|
14835
14962
|
* superRefine below. Mirrors the API's `UploadToMetaRequest`. */
|
|
14836
|
-
landingUrl:
|
|
14837
|
-
targetCountry:
|
|
14838
|
-
campaignName:
|
|
14963
|
+
landingUrl: z56.string().url().optional(),
|
|
14964
|
+
targetCountry: z56.string().length(2),
|
|
14965
|
+
campaignName: z56.string().trim().min(1).max(100),
|
|
14839
14966
|
campaignConfig: GroupedCampaignConfig.optional()
|
|
14840
14967
|
});
|
|
14841
14968
|
var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
|
|
14842
14969
|
const destination = value.campaignConfig?.destination;
|
|
14843
14970
|
if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl) {
|
|
14844
14971
|
ctx.addIssue({
|
|
14845
|
-
code:
|
|
14972
|
+
code: z56.ZodIssueCode.custom,
|
|
14846
14973
|
path: [
|
|
14847
14974
|
"landingUrl"
|
|
14848
14975
|
],
|
|
@@ -14851,7 +14978,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
14851
14978
|
}
|
|
14852
14979
|
if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
|
|
14853
14980
|
ctx.addIssue({
|
|
14854
|
-
code:
|
|
14981
|
+
code: z56.ZodIssueCode.custom,
|
|
14855
14982
|
path: [
|
|
14856
14983
|
"campaignConfig",
|
|
14857
14984
|
"destination",
|
|
@@ -14870,16 +14997,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
14870
14997
|
}
|
|
14871
14998
|
return value;
|
|
14872
14999
|
});
|
|
14873
|
-
var PresignUploadResponseSchema =
|
|
14874
|
-
uploadUrl:
|
|
15000
|
+
var PresignUploadResponseSchema = z56.object({
|
|
15001
|
+
uploadUrl: z56.string().url().refine((value) => {
|
|
14875
15002
|
const url = new URL(value);
|
|
14876
15003
|
return !url.username && !url.password && url.protocol === "https:";
|
|
14877
15004
|
}, "presigned upload URL must be HTTPS without embedded credentials"),
|
|
14878
|
-
publicUrl:
|
|
15005
|
+
publicUrl: z56.string().url().refine((value) => {
|
|
14879
15006
|
const url = new URL(value);
|
|
14880
15007
|
return !url.username && !url.password;
|
|
14881
15008
|
}, "public media URL must not contain embedded credentials"),
|
|
14882
|
-
stagingAssetId:
|
|
15009
|
+
stagingAssetId: z56.string().uuid()
|
|
14883
15010
|
});
|
|
14884
15011
|
async function uploadResolvedMedia(api, media, assetRole) {
|
|
14885
15012
|
if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
|
|
@@ -14904,16 +15031,16 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
|
|
|
14904
15031
|
return uploadResolvedMedia(api, media, assetRole);
|
|
14905
15032
|
}
|
|
14906
15033
|
__name(resolveAndUploadMedia, "resolveAndUploadMedia");
|
|
14907
|
-
var TikTokInput =
|
|
14908
|
-
taskId:
|
|
14909
|
-
advertiserId:
|
|
14910
|
-
pixelId:
|
|
14911
|
-
landingUrl:
|
|
14912
|
-
angleIndexes:
|
|
15034
|
+
var TikTokInput = z56.object({
|
|
15035
|
+
taskId: z56.string().min(1),
|
|
15036
|
+
advertiserId: z56.string().min(1),
|
|
15037
|
+
pixelId: z56.string().min(1).optional(),
|
|
15038
|
+
landingUrl: z56.string().url().optional(),
|
|
15039
|
+
angleIndexes: z56.array(z56.number().int().nonnegative()).optional(),
|
|
14913
15040
|
campaignConfig: McpCampaignConfig.optional(),
|
|
14914
15041
|
/** Override the ad's description (TikTok's body copy). If omitted,
|
|
14915
15042
|
* ProductMaker uses the auto-generated copy attached to the task. */
|
|
14916
|
-
primaryText:
|
|
15043
|
+
primaryText: z56.string().trim().min(1).max(500).optional()
|
|
14917
15044
|
});
|
|
14918
15045
|
function registerPublishTools(server, api, opts = {}) {
|
|
14919
15046
|
const transport = opts.transport ?? "http";
|
|
@@ -15163,38 +15290,38 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
|
|
|
15163
15290
|
|
|
15164
15291
|
// src/tools/meta-upload.ts
|
|
15165
15292
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
15166
|
-
import { z as
|
|
15167
|
-
var UploadSessionInputBase =
|
|
15168
|
-
mediaKind:
|
|
15293
|
+
import { z as z57 } from "zod";
|
|
15294
|
+
var UploadSessionInputBase = z57.object({
|
|
15295
|
+
mediaKind: z57.enum([
|
|
15169
15296
|
"image",
|
|
15170
15297
|
"video",
|
|
15171
15298
|
"mixed"
|
|
15172
15299
|
]).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."),
|
|
15173
|
-
assetRole:
|
|
15300
|
+
assetRole: z57.enum([
|
|
15174
15301
|
"media",
|
|
15175
15302
|
"thumbnail"
|
|
15176
15303
|
]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
|
|
15177
|
-
uploadPurpose:
|
|
15304
|
+
uploadPurpose: z57.enum([
|
|
15178
15305
|
"product_reference",
|
|
15179
15306
|
"creative",
|
|
15180
15307
|
"generic"
|
|
15181
15308
|
]).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."),
|
|
15182
|
-
maxFiles:
|
|
15309
|
+
maxFiles: z57.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
15183
15310
|
});
|
|
15184
|
-
var OpenAiFileReference =
|
|
15185
|
-
download_url:
|
|
15186
|
-
file_id:
|
|
15187
|
-
mime_type:
|
|
15188
|
-
file_name:
|
|
15311
|
+
var OpenAiFileReference = z57.object({
|
|
15312
|
+
download_url: z57.string().url().optional().describe("Optional host-provided download URL. The App prefers getFileDownloadUrl(file_id) and the server never fetches this URL."),
|
|
15313
|
+
file_id: z57.string().min(1),
|
|
15314
|
+
mime_type: z57.string().min(1).optional(),
|
|
15315
|
+
file_name: z57.string().min(1).optional()
|
|
15189
15316
|
});
|
|
15190
15317
|
var UploadSessionToolInputShape = {
|
|
15191
15318
|
...UploadSessionInputBase.shape,
|
|
15192
|
-
files:
|
|
15319
|
+
files: z57.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.")
|
|
15193
15320
|
};
|
|
15194
|
-
var UploadSessionToolInput =
|
|
15321
|
+
var UploadSessionToolInput = z57.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
15195
15322
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
15196
15323
|
ctx.addIssue({
|
|
15197
|
-
code:
|
|
15324
|
+
code: z57.ZodIssueCode.custom,
|
|
15198
15325
|
path: [
|
|
15199
15326
|
"mediaKind"
|
|
15200
15327
|
],
|
|
@@ -15203,7 +15330,7 @@ var UploadSessionToolInput = z56.object(UploadSessionToolInputShape).superRefine
|
|
|
15203
15330
|
}
|
|
15204
15331
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
15205
15332
|
ctx.addIssue({
|
|
15206
|
-
code:
|
|
15333
|
+
code: z57.ZodIssueCode.custom,
|
|
15207
15334
|
path: [
|
|
15208
15335
|
"maxFiles"
|
|
15209
15336
|
],
|
|
@@ -15212,7 +15339,7 @@ var UploadSessionToolInput = z56.object(UploadSessionToolInputShape).superRefine
|
|
|
15212
15339
|
}
|
|
15213
15340
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
|
|
15214
15341
|
ctx.addIssue({
|
|
15215
|
-
code:
|
|
15342
|
+
code: z57.ZodIssueCode.custom,
|
|
15216
15343
|
path: [
|
|
15217
15344
|
"maxFiles"
|
|
15218
15345
|
],
|
|
@@ -15220,38 +15347,38 @@ var UploadSessionToolInput = z56.object(UploadSessionToolInputShape).superRefine
|
|
|
15220
15347
|
});
|
|
15221
15348
|
}
|
|
15222
15349
|
});
|
|
15223
|
-
var UploadSessionResponse =
|
|
15224
|
-
sessionId:
|
|
15225
|
-
uploadPageUrl:
|
|
15226
|
-
mediaKind:
|
|
15350
|
+
var UploadSessionResponse = z57.object({
|
|
15351
|
+
sessionId: z57.string().uuid(),
|
|
15352
|
+
uploadPageUrl: z57.string().url(),
|
|
15353
|
+
mediaKind: z57.enum([
|
|
15227
15354
|
"image",
|
|
15228
15355
|
"video",
|
|
15229
15356
|
"mixed"
|
|
15230
15357
|
]),
|
|
15231
|
-
assetRole:
|
|
15358
|
+
assetRole: z57.enum([
|
|
15232
15359
|
"media",
|
|
15233
15360
|
"thumbnail"
|
|
15234
15361
|
]),
|
|
15235
|
-
maxFiles:
|
|
15236
|
-
expiresAt:
|
|
15362
|
+
maxFiles: z57.number().int().positive(),
|
|
15363
|
+
expiresAt: z57.string().datetime()
|
|
15237
15364
|
});
|
|
15238
|
-
var UploadStatusInput =
|
|
15239
|
-
sessionId:
|
|
15365
|
+
var UploadStatusInput = z57.object({
|
|
15366
|
+
sessionId: z57.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
15240
15367
|
});
|
|
15241
|
-
var UniversalUploadStatusResponse =
|
|
15242
|
-
|
|
15243
|
-
status:
|
|
15244
|
-
assets:
|
|
15368
|
+
var UniversalUploadStatusResponse = z57.discriminatedUnion("status", [
|
|
15369
|
+
z57.object({
|
|
15370
|
+
status: z57.literal("pending"),
|
|
15371
|
+
assets: z57.array(z57.never()).length(0)
|
|
15245
15372
|
}),
|
|
15246
|
-
|
|
15247
|
-
status:
|
|
15248
|
-
assets:
|
|
15249
|
-
assetId:
|
|
15250
|
-
mediaKind:
|
|
15373
|
+
z57.object({
|
|
15374
|
+
status: z57.literal("uploaded"),
|
|
15375
|
+
assets: z57.array(z57.object({
|
|
15376
|
+
assetId: z57.string().uuid(),
|
|
15377
|
+
mediaKind: z57.enum([
|
|
15251
15378
|
"image",
|
|
15252
15379
|
"video"
|
|
15253
15380
|
]),
|
|
15254
|
-
assetRole:
|
|
15381
|
+
assetRole: z57.enum([
|
|
15255
15382
|
"media",
|
|
15256
15383
|
"thumbnail"
|
|
15257
15384
|
])
|
|
@@ -15259,13 +15386,13 @@ var UniversalUploadStatusResponse = z56.discriminatedUnion("status", [
|
|
|
15259
15386
|
})
|
|
15260
15387
|
]);
|
|
15261
15388
|
var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
|
|
15262
|
-
uploadPurpose:
|
|
15389
|
+
uploadPurpose: z57.enum([
|
|
15263
15390
|
"product_reference",
|
|
15264
15391
|
"creative",
|
|
15265
15392
|
"generic"
|
|
15266
15393
|
]),
|
|
15267
|
-
checkToolName:
|
|
15268
|
-
resolveEndpoint:
|
|
15394
|
+
checkToolName: z57.literal("check_media_upload"),
|
|
15395
|
+
resolveEndpoint: z57.string().url()
|
|
15269
15396
|
});
|
|
15270
15397
|
function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
|
|
15271
15398
|
const url = new URL(uploadPageUrl);
|
|
@@ -15356,13 +15483,13 @@ function registerMediaUploadTools(server, api) {
|
|
|
15356
15483
|
__name(registerMediaUploadTools, "registerMediaUploadTools");
|
|
15357
15484
|
|
|
15358
15485
|
// src/tools/campaigns.ts
|
|
15359
|
-
import { z as
|
|
15360
|
-
var MetaStatusInput =
|
|
15361
|
-
campaignId:
|
|
15486
|
+
import { z as z58 } from "zod";
|
|
15487
|
+
var MetaStatusInput = z58.object({
|
|
15488
|
+
campaignId: z58.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
|
|
15362
15489
|
});
|
|
15363
|
-
var TikTokStatusInput =
|
|
15364
|
-
campaignId:
|
|
15365
|
-
advertiserId:
|
|
15490
|
+
var TikTokStatusInput = z58.object({
|
|
15491
|
+
campaignId: z58.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
|
|
15492
|
+
advertiserId: z58.string().min(1).describe("The same advertiserId used to publish the campaign.")
|
|
15366
15493
|
});
|
|
15367
15494
|
function registerCampaignTools(server, api) {
|
|
15368
15495
|
server.tool("get_meta_campaign_status", "Consulta el estado actual + m\xE9tricas lifetime (spend, impressions, clicks, reach) de una campa\xF1a Meta publicada. Llama esto DESPU\xC9S de `publish_to_meta` para confirmar que la campa\xF1a se cre\xF3 correctamente y para reportar performance al usuario. Es read-only \u2014 no modifica nada en Meta Ads Manager.", MetaStatusInput.shape, READS_EXTERNAL, async (input) => {
|
|
@@ -15459,10 +15586,10 @@ function renderTikTokStatusMarkdown(r) {
|
|
|
15459
15586
|
__name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
|
|
15460
15587
|
|
|
15461
15588
|
// ../../packages/product-economics/src/product-costing.ts
|
|
15462
|
-
import { z as
|
|
15589
|
+
import { z as z60 } from "zod";
|
|
15463
15590
|
|
|
15464
15591
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
15465
|
-
import { z as
|
|
15592
|
+
import { z as z59 } from "zod";
|
|
15466
15593
|
|
|
15467
15594
|
// ../../packages/product-economics/src/product-costing-shipping-references.json
|
|
15468
15595
|
var product_costing_shipping_references_default = {
|
|
@@ -15526,21 +15653,21 @@ var product_costing_shipping_references_default = {
|
|
|
15526
15653
|
};
|
|
15527
15654
|
|
|
15528
15655
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
15529
|
-
var ShippingReferenceSchema =
|
|
15530
|
-
reference:
|
|
15531
|
-
min:
|
|
15532
|
-
max:
|
|
15533
|
-
updatedAt:
|
|
15534
|
-
confidence:
|
|
15656
|
+
var ShippingReferenceSchema = z59.object({
|
|
15657
|
+
reference: z59.number().positive(),
|
|
15658
|
+
min: z59.number().nonnegative(),
|
|
15659
|
+
max: z59.number().positive(),
|
|
15660
|
+
updatedAt: z59.string().date(),
|
|
15661
|
+
confidence: z59.enum([
|
|
15535
15662
|
"high",
|
|
15536
15663
|
"medium",
|
|
15537
15664
|
"medium-low"
|
|
15538
15665
|
]),
|
|
15539
|
-
sources:
|
|
15666
|
+
sources: z59.array(z59.string().url().startsWith("https://")).min(1).max(3)
|
|
15540
15667
|
}).superRefine(({ reference, min, max }, context) => {
|
|
15541
15668
|
if (min > reference || reference > max) {
|
|
15542
15669
|
context.addIssue({
|
|
15543
|
-
code:
|
|
15670
|
+
code: z59.ZodIssueCode.custom,
|
|
15544
15671
|
message: "shipping_reference_outside_range",
|
|
15545
15672
|
path: [
|
|
15546
15673
|
"reference"
|
|
@@ -15548,7 +15675,7 @@ var ShippingReferenceSchema = z58.object({
|
|
|
15548
15675
|
});
|
|
15549
15676
|
}
|
|
15550
15677
|
});
|
|
15551
|
-
var SHIPPING_REFERENCES =
|
|
15678
|
+
var SHIPPING_REFERENCES = z59.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
|
|
15552
15679
|
var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
|
|
15553
15680
|
var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
|
|
15554
15681
|
"MX",
|
|
@@ -15730,18 +15857,18 @@ function getProductCostingCountryName(country) {
|
|
|
15730
15857
|
__name(getProductCostingCountryName, "getProductCostingCountryName");
|
|
15731
15858
|
|
|
15732
15859
|
// ../../packages/product-economics/src/product-costing.ts
|
|
15733
|
-
var ProductCostingInputSchema =
|
|
15734
|
-
country:
|
|
15735
|
-
supplierCost:
|
|
15736
|
-
shippingCost:
|
|
15737
|
-
returnRate:
|
|
15738
|
-
cancellationRate:
|
|
15739
|
-
adsManagerCpa:
|
|
15740
|
-
desiredMargin:
|
|
15860
|
+
var ProductCostingInputSchema = z60.object({
|
|
15861
|
+
country: z60.string().refine(isProductCostingCountryCode, "unsupported_country"),
|
|
15862
|
+
supplierCost: z60.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
|
|
15863
|
+
shippingCost: z60.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
|
|
15864
|
+
returnRate: z60.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
15865
|
+
cancellationRate: z60.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
15866
|
+
adsManagerCpa: z60.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
|
|
15867
|
+
desiredMargin: z60.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
|
|
15741
15868
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
15742
15869
|
if (returnRate + cancellationRate >= 1) {
|
|
15743
15870
|
context.addIssue({
|
|
15744
|
-
code:
|
|
15871
|
+
code: z60.ZodIssueCode.custom,
|
|
15745
15872
|
message: "delivery_rate_positive",
|
|
15746
15873
|
path: [
|
|
15747
15874
|
"cancellationRate"
|
|
@@ -15808,14 +15935,14 @@ function calculateProductCosting(rawInput) {
|
|
|
15808
15935
|
__name(calculateProductCosting, "calculateProductCosting");
|
|
15809
15936
|
|
|
15810
15937
|
// src/tools/product-costing.ts
|
|
15811
|
-
import { z as
|
|
15812
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
15813
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
15814
|
-
var ProductCostingToolInput =
|
|
15815
|
-
country:
|
|
15938
|
+
import { z as z61 } from "zod";
|
|
15939
|
+
var optionalAmount = /* @__PURE__ */ __name((description) => z61.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
|
|
15940
|
+
var optionalPercent = /* @__PURE__ */ __name((description) => z61.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
|
|
15941
|
+
var ProductCostingToolInput = z61.object({
|
|
15942
|
+
country: z61.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
15816
15943
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
15817
15944
|
}).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
|
|
15818
|
-
supplierCost:
|
|
15945
|
+
supplierCost: z61.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."),
|
|
15819
15946
|
supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
|
|
15820
15947
|
shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
|
|
15821
15948
|
shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
|
|
@@ -15947,7 +16074,7 @@ function formatPercent(value) {
|
|
|
15947
16074
|
__name(formatPercent, "formatPercent");
|
|
15948
16075
|
|
|
15949
16076
|
// src/tools/product-research.ts
|
|
15950
|
-
import { z as
|
|
16077
|
+
import { z as z62 } from "zod";
|
|
15951
16078
|
|
|
15952
16079
|
// src/tools/product-research-idempotency.ts
|
|
15953
16080
|
import { createHash as createHash3 } from "crypto";
|
|
@@ -16063,17 +16190,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
|
|
|
16063
16190
|
]);
|
|
16064
16191
|
var POLL_INTERVAL_MS = 5e3;
|
|
16065
16192
|
var MAX_WAIT_SECONDS = 120;
|
|
16066
|
-
var FindInput =
|
|
16193
|
+
var FindInput = z62.object({
|
|
16067
16194
|
targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
|
|
16068
16195
|
categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
|
|
16069
|
-
confirmed:
|
|
16070
|
-
waitSeconds:
|
|
16196
|
+
confirmed: z62.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
|
|
16197
|
+
waitSeconds: z62.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
|
|
16071
16198
|
});
|
|
16072
|
-
var GetInput =
|
|
16073
|
-
runId:
|
|
16199
|
+
var GetInput = z62.object({
|
|
16200
|
+
runId: z62.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
16074
16201
|
});
|
|
16075
|
-
var ListInput =
|
|
16076
|
-
limit:
|
|
16202
|
+
var ListInput = z62.object({
|
|
16203
|
+
limit: z62.number().int().min(1).max(20).default(10)
|
|
16077
16204
|
});
|
|
16078
16205
|
function textResult(text) {
|
|
16079
16206
|
return {
|
|
@@ -16165,14 +16292,14 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
16165
16292
|
__name(registerProductResearchTools, "registerProductResearchTools");
|
|
16166
16293
|
|
|
16167
16294
|
// src/tools/dropshipping-projects.ts
|
|
16168
|
-
import { z as
|
|
16169
|
-
var ProjectId =
|
|
16170
|
-
var DropshippingProjectStatus =
|
|
16295
|
+
import { z as z63 } from "zod";
|
|
16296
|
+
var ProjectId = z63.string().uuid();
|
|
16297
|
+
var DropshippingProjectStatus = z63.enum([
|
|
16171
16298
|
"active",
|
|
16172
16299
|
"completed",
|
|
16173
16300
|
"archived"
|
|
16174
16301
|
]);
|
|
16175
|
-
var DropshippingProjectPhase =
|
|
16302
|
+
var DropshippingProjectPhase = z63.enum([
|
|
16176
16303
|
"research",
|
|
16177
16304
|
"costing",
|
|
16178
16305
|
"media",
|
|
@@ -16181,21 +16308,21 @@ var DropshippingProjectPhase = z62.enum([
|
|
|
16181
16308
|
"advertising",
|
|
16182
16309
|
"complete"
|
|
16183
16310
|
]);
|
|
16184
|
-
var DropshippingRewardMilestone =
|
|
16311
|
+
var DropshippingRewardMilestone = z63.enum([
|
|
16185
16312
|
"product_selected",
|
|
16186
16313
|
"costing_saved",
|
|
16187
16314
|
"product_media_ready",
|
|
16188
16315
|
"creatives_completed",
|
|
16189
16316
|
"campaign_created"
|
|
16190
16317
|
]);
|
|
16191
|
-
var TargetCountry =
|
|
16318
|
+
var TargetCountry = z63.enum([
|
|
16192
16319
|
"CO",
|
|
16193
16320
|
"MX",
|
|
16194
16321
|
"PE",
|
|
16195
16322
|
"EC",
|
|
16196
16323
|
"CL"
|
|
16197
16324
|
]);
|
|
16198
|
-
var ResearchCategory =
|
|
16325
|
+
var ResearchCategory = z63.enum([
|
|
16199
16326
|
"auto",
|
|
16200
16327
|
"automotive",
|
|
16201
16328
|
"kitchen",
|
|
@@ -16210,7 +16337,7 @@ var ResearchCategory = z62.enum([
|
|
|
16210
16337
|
"garden",
|
|
16211
16338
|
"cleaning"
|
|
16212
16339
|
]);
|
|
16213
|
-
var HttpUrl3 =
|
|
16340
|
+
var HttpUrl3 = z63.string().url().max(2e3).refine((value) => {
|
|
16214
16341
|
try {
|
|
16215
16342
|
return [
|
|
16216
16343
|
"http:",
|
|
@@ -16220,43 +16347,43 @@ var HttpUrl3 = z62.string().url().max(2e3).refine((value) => {
|
|
|
16220
16347
|
return false;
|
|
16221
16348
|
}
|
|
16222
16349
|
}, "URL must use HTTP(S)");
|
|
16223
|
-
var ResearchCandidateOrigin =
|
|
16224
|
-
type:
|
|
16350
|
+
var ResearchCandidateOrigin = z63.object({
|
|
16351
|
+
type: z63.literal("research_candidate"),
|
|
16225
16352
|
runId: ProjectId,
|
|
16226
|
-
candidateSourceId:
|
|
16353
|
+
candidateSourceId: z63.string().min(1).max(160)
|
|
16227
16354
|
});
|
|
16228
|
-
var TaskOrigin =
|
|
16229
|
-
type:
|
|
16355
|
+
var TaskOrigin = z63.object({
|
|
16356
|
+
type: z63.literal("task"),
|
|
16230
16357
|
taskId: ProjectId
|
|
16231
16358
|
});
|
|
16232
|
-
var ManualOrigin =
|
|
16233
|
-
type:
|
|
16359
|
+
var ManualOrigin = z63.object({
|
|
16360
|
+
type: z63.literal("manual"),
|
|
16234
16361
|
clientRequestId: ProjectId,
|
|
16235
|
-
country:
|
|
16362
|
+
country: z63.string().min(2).max(3).optional()
|
|
16236
16363
|
});
|
|
16237
|
-
var StartProjectInput =
|
|
16238
|
-
origin:
|
|
16364
|
+
var StartProjectInput = z63.object({
|
|
16365
|
+
origin: z63.discriminatedUnion("type", [
|
|
16239
16366
|
ResearchCandidateOrigin,
|
|
16240
16367
|
TaskOrigin,
|
|
16241
16368
|
ManualOrigin
|
|
16242
16369
|
]),
|
|
16243
|
-
productName:
|
|
16370
|
+
productName: z63.string().trim().min(1).max(240).optional(),
|
|
16244
16371
|
productUrl: HttpUrl3.optional(),
|
|
16245
|
-
country:
|
|
16246
|
-
languageCode:
|
|
16372
|
+
country: z63.string().min(2).max(3).optional(),
|
|
16373
|
+
languageCode: z63.string().min(2).max(16).optional()
|
|
16247
16374
|
}).strict();
|
|
16248
|
-
var CostProjectInput =
|
|
16375
|
+
var CostProjectInput = z63.object({
|
|
16249
16376
|
projectId: ProjectId,
|
|
16250
|
-
version:
|
|
16251
|
-
country:
|
|
16252
|
-
supplierCost:
|
|
16253
|
-
shippingCost:
|
|
16254
|
-
returnRate:
|
|
16255
|
-
cancellationRate:
|
|
16256
|
-
adsManagerCpa:
|
|
16257
|
-
desiredMargin:
|
|
16258
|
-
});
|
|
16259
|
-
var GuideInput =
|
|
16377
|
+
version: z63.number().int().positive(),
|
|
16378
|
+
country: z63.string().trim().min(2).max(3),
|
|
16379
|
+
supplierCost: z63.number().finite().positive(),
|
|
16380
|
+
shippingCost: z63.number().finite().nonnegative(),
|
|
16381
|
+
returnRate: z63.number().finite().min(0).lt(1),
|
|
16382
|
+
cancellationRate: z63.number().finite().min(0).lt(1),
|
|
16383
|
+
adsManagerCpa: z63.number().finite().nonnegative(),
|
|
16384
|
+
desiredMargin: z63.number().finite().min(0).lt(1)
|
|
16385
|
+
});
|
|
16386
|
+
var GuideInput = z63.object({
|
|
16260
16387
|
projectId: ProjectId.optional()
|
|
16261
16388
|
}).strict();
|
|
16262
16389
|
var NEXT_ACTION_KINDS = [
|
|
@@ -16274,29 +16401,29 @@ var NEXT_ACTION_KINDS = [
|
|
|
16274
16401
|
"repair_meta_campaign",
|
|
16275
16402
|
"review_paused_campaign"
|
|
16276
16403
|
];
|
|
16277
|
-
var DropshippingProjectNextAction =
|
|
16278
|
-
kind:
|
|
16279
|
-
href:
|
|
16404
|
+
var DropshippingProjectNextAction = z63.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z63.object({
|
|
16405
|
+
kind: z63.literal(kind),
|
|
16406
|
+
href: z63.string().min(1)
|
|
16280
16407
|
})));
|
|
16281
|
-
var CostingInputSchema =
|
|
16282
|
-
country:
|
|
16283
|
-
supplierCost:
|
|
16284
|
-
shippingCost:
|
|
16285
|
-
returnRate:
|
|
16286
|
-
cancellationRate:
|
|
16287
|
-
adsManagerCpa:
|
|
16288
|
-
desiredMargin:
|
|
16408
|
+
var CostingInputSchema = z63.object({
|
|
16409
|
+
country: z63.string().min(2).max(3),
|
|
16410
|
+
supplierCost: z63.number().finite().positive(),
|
|
16411
|
+
shippingCost: z63.number().finite().nonnegative(),
|
|
16412
|
+
returnRate: z63.number().finite().min(0).lt(1),
|
|
16413
|
+
cancellationRate: z63.number().finite().min(0).lt(1),
|
|
16414
|
+
adsManagerCpa: z63.number().finite().nonnegative(),
|
|
16415
|
+
desiredMargin: z63.number().finite().min(0).lt(1)
|
|
16289
16416
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
16290
16417
|
if (returnRate + cancellationRate >= 1) context.addIssue({
|
|
16291
|
-
code:
|
|
16418
|
+
code: z63.ZodIssueCode.custom,
|
|
16292
16419
|
path: [
|
|
16293
16420
|
"cancellationRate"
|
|
16294
16421
|
]
|
|
16295
16422
|
});
|
|
16296
16423
|
});
|
|
16297
|
-
var FiniteCostingNumber =
|
|
16298
|
-
var CostingResultSchema =
|
|
16299
|
-
country:
|
|
16424
|
+
var FiniteCostingNumber = z63.number().finite();
|
|
16425
|
+
var CostingResultSchema = z63.object({
|
|
16426
|
+
country: z63.string().min(2).max(3),
|
|
16300
16427
|
deliveryRate: FiniteCostingNumber,
|
|
16301
16428
|
adjustedShippingCost: FiniteCostingNumber,
|
|
16302
16429
|
adjustedCpa: FiniteCostingNumber,
|
|
@@ -16309,44 +16436,44 @@ var CostingResultSchema = z62.object({
|
|
|
16309
16436
|
estimatedProfit: FiniteCostingNumber,
|
|
16310
16437
|
actualMargin: FiniteCostingNumber,
|
|
16311
16438
|
breakEvenAdsManagerCpa: FiniteCostingNumber,
|
|
16312
|
-
wasPriceAutoAdjusted:
|
|
16313
|
-
profitabilityStatus:
|
|
16314
|
-
});
|
|
16315
|
-
var RewardProgressSchema =
|
|
16316
|
-
campaignKey:
|
|
16317
|
-
totalCredits:
|
|
16318
|
-
earnedCredits:
|
|
16319
|
-
milestones:
|
|
16439
|
+
wasPriceAutoAdjusted: z63.boolean(),
|
|
16440
|
+
profitabilityStatus: z63.literal("healthy")
|
|
16441
|
+
});
|
|
16442
|
+
var RewardProgressSchema = z63.object({
|
|
16443
|
+
campaignKey: z63.literal("dropshipping-launch-v1"),
|
|
16444
|
+
totalCredits: z63.number().int().positive(),
|
|
16445
|
+
earnedCredits: z63.number().int().nonnegative(),
|
|
16446
|
+
milestones: z63.array(z63.object({
|
|
16320
16447
|
milestone: DropshippingRewardMilestone,
|
|
16321
|
-
credits:
|
|
16322
|
-
available:
|
|
16323
|
-
earned:
|
|
16448
|
+
credits: z63.number().int().positive(),
|
|
16449
|
+
available: z63.boolean().optional(),
|
|
16450
|
+
earned: z63.boolean(),
|
|
16324
16451
|
grantId: ProjectId.nullable(),
|
|
16325
|
-
grantedAt:
|
|
16452
|
+
grantedAt: z63.string().datetime().nullable()
|
|
16326
16453
|
})).length(DropshippingRewardMilestone.options.length)
|
|
16327
16454
|
});
|
|
16328
|
-
var ProjectResponseSchema =
|
|
16455
|
+
var ProjectResponseSchema = z63.object({
|
|
16329
16456
|
id: ProjectId,
|
|
16330
16457
|
taskId: ProjectId.nullable(),
|
|
16331
16458
|
status: DropshippingProjectStatus,
|
|
16332
|
-
originKey:
|
|
16459
|
+
originKey: z63.string().min(1),
|
|
16333
16460
|
researchRunId: ProjectId.nullable(),
|
|
16334
|
-
candidateSourceId:
|
|
16335
|
-
productName:
|
|
16461
|
+
candidateSourceId: z63.string().nullable(),
|
|
16462
|
+
productName: z63.string().nullable(),
|
|
16336
16463
|
productUrl: HttpUrl3.nullable(),
|
|
16337
16464
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
16338
|
-
targetCountry:
|
|
16339
|
-
languageCode:
|
|
16340
|
-
hasReferenceImage:
|
|
16465
|
+
targetCountry: z63.string().nullable(),
|
|
16466
|
+
languageCode: z63.string().nullable(),
|
|
16467
|
+
hasReferenceImage: z63.boolean(),
|
|
16341
16468
|
costingInput: CostingInputSchema.nullable(),
|
|
16342
16469
|
costingResult: CostingResultSchema.nullable(),
|
|
16343
|
-
costingVersion:
|
|
16344
|
-
version:
|
|
16470
|
+
costingVersion: z63.number().int().positive().nullable(),
|
|
16471
|
+
version: z63.number().int().positive(),
|
|
16345
16472
|
phase: DropshippingProjectPhase,
|
|
16346
16473
|
nextAction: DropshippingProjectNextAction.nullable(),
|
|
16347
16474
|
rewards: RewardProgressSchema,
|
|
16348
|
-
createdAt:
|
|
16349
|
-
updatedAt:
|
|
16475
|
+
createdAt: z63.string().datetime(),
|
|
16476
|
+
updatedAt: z63.string().datetime()
|
|
16350
16477
|
}).passthrough();
|
|
16351
16478
|
var NEXT_ACTION_GUIDANCE = {
|
|
16352
16479
|
cost_product: "Llama `cost_dropshipping_project` con el costo real del proveedor. Nunca lo inventes: p\xEDdeselo al usuario.",
|