@productmaker/mcp 3.4.0 → 3.4.1
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 +955 -880
- package/dist/stdio.js +943 -868
- package/package.json +1 -1
package/dist/stdio.js
CHANGED
|
@@ -264,7 +264,7 @@ var ApiClient = class {
|
|
|
264
264
|
};
|
|
265
265
|
|
|
266
266
|
// src/index.ts
|
|
267
|
-
var MCP_VERSION = "3.4.
|
|
267
|
+
var MCP_VERSION = "3.4.1";
|
|
268
268
|
|
|
269
269
|
// src/meta-upload-app.ts
|
|
270
270
|
import { readFileSync } from "fs";
|
|
@@ -336,7 +336,7 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
|
|
|
336
336
|
__name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
|
|
337
337
|
|
|
338
338
|
// src/tools/tasks.ts
|
|
339
|
-
import { z as
|
|
339
|
+
import { z as z49 } from "zod";
|
|
340
340
|
|
|
341
341
|
// src/resolve-image.ts
|
|
342
342
|
import { lookup as dnsLookup } from "dns/promises";
|
|
@@ -6199,6 +6199,10 @@ var TikTokCreateCampaignResponseSchema = z35.object({
|
|
|
6199
6199
|
adsManagerUrl: z35.string().optional()
|
|
6200
6200
|
});
|
|
6201
6201
|
|
|
6202
|
+
// ../../packages/types/src/pricing-gemini-omni.ts
|
|
6203
|
+
var GEMINI_OMNI_FLAT_OUR_COST_CENTS = 84;
|
|
6204
|
+
var GEMINI_OMNI_FLAT_USER_PRICE_CENTS = 168;
|
|
6205
|
+
|
|
6202
6206
|
// ../../packages/types/src/pricing.ts
|
|
6203
6207
|
var CREDITS_PER_USD_CENT = 10;
|
|
6204
6208
|
var CREDITS_PER_DOLLAR = 100 * CREDITS_PER_USD_CENT;
|
|
@@ -6607,6 +6611,18 @@ var DEFAULT_PRICING = {
|
|
|
6607
6611
|
ourCostCents: 120,
|
|
6608
6612
|
userPriceCents: 240
|
|
6609
6613
|
},
|
|
6614
|
+
// Gemini Omni Video (gemini-omni-video) — Mix primary generator since
|
|
6615
|
+
// 2026-08-18. FLAT per generation: 168 KIE credits = $0.84, identical at
|
|
6616
|
+
// 720p and 1080p and independent of the 3.5-10s trim window. Do NOT add
|
|
6617
|
+
// per-second overrides for this key — resolveSuccessBilling bills it flat.
|
|
6618
|
+
//
|
|
6619
|
+
// Shares the constants with the pre-submit ESTIMATOR (mix-cost.ts) rather
|
|
6620
|
+
// than repeating the numbers: a literal here that drifted from the estimator
|
|
6621
|
+
// would quote one price and charge another on every mix.
|
|
6622
|
+
"kie:gemini-omni-video": {
|
|
6623
|
+
ourCostCents: GEMINI_OMNI_FLAT_OUR_COST_CENTS,
|
|
6624
|
+
userPriceCents: GEMINI_OMNI_FLAT_USER_PRICE_CENTS
|
|
6625
|
+
},
|
|
6610
6626
|
"kie:video-lipsync-generation": {
|
|
6611
6627
|
ourCostCents: 45,
|
|
6612
6628
|
userPriceCents: 90
|
|
@@ -8570,7 +8586,57 @@ var FeatureSpec = z36.object({
|
|
|
8570
8586
|
});
|
|
8571
8587
|
|
|
8572
8588
|
// ../../packages/types/src/mix.ts
|
|
8589
|
+
import { z as z38 } from "zod";
|
|
8590
|
+
|
|
8591
|
+
// ../../packages/types/src/mix-degradation.ts
|
|
8573
8592
|
import { z as z37 } from "zod";
|
|
8593
|
+
var MIX_DEGRADATION_REASONS = [
|
|
8594
|
+
/**
|
|
8595
|
+
* At least one scene the mix PLANNED is missing from the delivered video, so
|
|
8596
|
+
* the result is shorter than the source. Set at assemble time by comparing
|
|
8597
|
+
* the concat set against the planned scene set — the scene's own code (if it
|
|
8598
|
+
* had one) never reaches the mix-level rollup, which only sees scenes that
|
|
8599
|
+
* SUCCEEDED, and that is exactly how a live 17.00s-of-20.00s delivery
|
|
8600
|
+
* shipped with degradedReason NULL and no banner at all.
|
|
8601
|
+
*
|
|
8602
|
+
* ORDERING: FIRST, above every refusal code. A short delivery must never be
|
|
8603
|
+
* MASKED. It used to sit below the three content refusals on the theory that
|
|
8604
|
+
* a refusal names something the user can change AND explains the missing
|
|
8605
|
+
* scene — but it does neither reliably: in a 3-scene mix where scene 1 fails
|
|
8606
|
+
* outright and scene 2 ships through Wan after a reference refusal, the
|
|
8607
|
+
* refusal copy reads "we used a lower-quality alternative", a claim about
|
|
8608
|
+
* QUALITY that says nothing about the video being shorter than what was paid
|
|
8609
|
+
* for, and that is actively wrong about the dropped scene (for which we used
|
|
8610
|
+
* nothing). Every other code in this list describes a scene that DID ship.
|
|
8611
|
+
*/
|
|
8612
|
+
"scenes_dropped",
|
|
8613
|
+
/** Google's safety filter rejected the user's reference photo. Deterministic. */
|
|
8614
|
+
"reference_rejected",
|
|
8615
|
+
/** Google refused the wording of the change description. */
|
|
8616
|
+
"prompt_rejected",
|
|
8617
|
+
/**
|
|
8618
|
+
* The provider refused the content but its message names neither the
|
|
8619
|
+
* reference nor the wording, so we cannot say which. Distinct from
|
|
8620
|
+
* 'provider_unavailable' on purpose: "unavailable" invites the user to retry
|
|
8621
|
+
* unchanged, which can never succeed against a content refusal and only
|
|
8622
|
+
* burns their credits. This code tells them something must change.
|
|
8623
|
+
*/
|
|
8624
|
+
"content_rejected",
|
|
8625
|
+
/**
|
|
8626
|
+
* The scene's length fell outside Gemini's usable 3.5s-10s trim window —
|
|
8627
|
+
* EITHER bound. Deliberately ONE code for both: the user controls neither
|
|
8628
|
+
* (scene segmentation is entirely ours), so "too short" and "too long" are
|
|
8629
|
+
* not differently actionable, and one honest explanation beats two that
|
|
8630
|
+
* both amount to "our segmentation produced a length the primary generator
|
|
8631
|
+
* cannot take".
|
|
8632
|
+
*/
|
|
8633
|
+
"scene_length_unsupported",
|
|
8634
|
+
/** Transient provider failures exhausted the budget. */
|
|
8635
|
+
"provider_unavailable"
|
|
8636
|
+
];
|
|
8637
|
+
var MixDegradationReasonSchema = z37.enum(MIX_DEGRADATION_REASONS);
|
|
8638
|
+
|
|
8639
|
+
// ../../packages/types/src/mix.ts
|
|
8574
8640
|
var MEDIA_TYPES = [
|
|
8575
8641
|
"video",
|
|
8576
8642
|
"image"
|
|
@@ -8608,38 +8674,38 @@ function isPublicHttpsUrl(raw) {
|
|
|
8608
8674
|
return true;
|
|
8609
8675
|
}
|
|
8610
8676
|
__name(isPublicHttpsUrl, "isPublicHttpsUrl");
|
|
8611
|
-
var PublicHttpsUrl =
|
|
8677
|
+
var PublicHttpsUrl = z38.string().url().refine(isPublicHttpsUrl, {
|
|
8612
8678
|
message: "must be a public HTTPS URL"
|
|
8613
8679
|
});
|
|
8614
|
-
var InternalAssetPath =
|
|
8615
|
-
var MixImageUrl =
|
|
8680
|
+
var InternalAssetPath = z38.string().regex(/^\/(?:api|v1)\/assets\/[A-Za-z0-9._~%/-]+$/, "must be a public HTTPS URL or an internal asset path");
|
|
8681
|
+
var MixImageUrl = z38.union([
|
|
8616
8682
|
PublicHttpsUrl,
|
|
8617
8683
|
InternalAssetPath
|
|
8618
8684
|
]);
|
|
8619
|
-
var MixAxes =
|
|
8620
|
-
product:
|
|
8621
|
-
person:
|
|
8622
|
-
setting:
|
|
8685
|
+
var MixAxes = z38.object({
|
|
8686
|
+
product: z38.boolean(),
|
|
8687
|
+
person: z38.boolean(),
|
|
8688
|
+
setting: z38.boolean()
|
|
8623
8689
|
});
|
|
8624
|
-
var MixReferences =
|
|
8625
|
-
product:
|
|
8626
|
-
person:
|
|
8627
|
-
setting:
|
|
8690
|
+
var MixReferences = z38.object({
|
|
8691
|
+
product: z38.array(PublicHttpsUrl).max(3, "at most 3 product references"),
|
|
8692
|
+
person: z38.array(PublicHttpsUrl).max(3, "at most 3 person references"),
|
|
8693
|
+
setting: z38.array(PublicHttpsUrl).max(3, "at most 3 setting references")
|
|
8628
8694
|
});
|
|
8629
|
-
var MixImageEdit =
|
|
8630
|
-
instruction:
|
|
8631
|
-
imageUrls:
|
|
8695
|
+
var MixImageEdit = z38.object({
|
|
8696
|
+
instruction: z38.string().min(1).max(600),
|
|
8697
|
+
imageUrls: z38.array(MixImageUrl).min(1).max(3)
|
|
8632
8698
|
});
|
|
8633
|
-
var MixRequest =
|
|
8634
|
-
mediaType:
|
|
8635
|
-
originalUrl:
|
|
8699
|
+
var MixRequest = z38.object({
|
|
8700
|
+
mediaType: z38.enum(MEDIA_TYPES),
|
|
8701
|
+
originalUrl: z38.union([
|
|
8636
8702
|
PublicHttpsUrl,
|
|
8637
8703
|
InternalAssetPath
|
|
8638
8704
|
]),
|
|
8639
8705
|
axes: MixAxes,
|
|
8640
8706
|
references: MixReferences,
|
|
8641
|
-
personText:
|
|
8642
|
-
settingText:
|
|
8707
|
+
personText: z38.string().max(500).optional(),
|
|
8708
|
+
settingText: z38.string().max(500).optional(),
|
|
8643
8709
|
/**
|
|
8644
8710
|
* Optional public URL of a user-uploaded audio file (mp3/wav). Wan Video
|
|
8645
8711
|
* Edit has no audio input and the mix never lipsyncs: the Wan output is
|
|
@@ -8648,11 +8714,11 @@ var MixRequest = z37.object({
|
|
|
8648
8714
|
* (mute + overlay). No per-scene slicing, no `reference_audio_urls`.
|
|
8649
8715
|
*/
|
|
8650
8716
|
audioUrl: PublicHttpsUrl.optional(),
|
|
8651
|
-
resolution:
|
|
8652
|
-
originalDurationSec:
|
|
8717
|
+
resolution: z38.enum(RESOLUTIONS).default("720p"),
|
|
8718
|
+
originalDurationSec: z38.number().positive().max(600).optional(),
|
|
8653
8719
|
image: MixImageEdit.optional(),
|
|
8654
|
-
sourceTaskId:
|
|
8655
|
-
sourceCreativeId:
|
|
8720
|
+
sourceTaskId: z38.string().max(64).optional(),
|
|
8721
|
+
sourceCreativeId: z38.string().max(64).optional()
|
|
8656
8722
|
}).superRefine((req, ctx) => {
|
|
8657
8723
|
if (req.mediaType === "image") {
|
|
8658
8724
|
if (!req.image) {
|
|
@@ -8686,18 +8752,18 @@ var MixRequest = z37.object({
|
|
|
8686
8752
|
});
|
|
8687
8753
|
}
|
|
8688
8754
|
});
|
|
8689
|
-
var ReferenceMap =
|
|
8690
|
-
product:
|
|
8691
|
-
start:
|
|
8692
|
-
end:
|
|
8755
|
+
var ReferenceMap = z38.object({
|
|
8756
|
+
product: z38.object({
|
|
8757
|
+
start: z38.number().int(),
|
|
8758
|
+
end: z38.number().int()
|
|
8693
8759
|
}).optional(),
|
|
8694
|
-
person:
|
|
8695
|
-
start:
|
|
8696
|
-
end:
|
|
8760
|
+
person: z38.object({
|
|
8761
|
+
start: z38.number().int(),
|
|
8762
|
+
end: z38.number().int()
|
|
8697
8763
|
}).optional(),
|
|
8698
|
-
setting:
|
|
8699
|
-
start:
|
|
8700
|
-
end:
|
|
8764
|
+
setting: z38.object({
|
|
8765
|
+
start: z38.number().int(),
|
|
8766
|
+
end: z38.number().int()
|
|
8701
8767
|
}).optional()
|
|
8702
8768
|
});
|
|
8703
8769
|
var SCENE_CLIP_TYPES = [
|
|
@@ -8713,39 +8779,39 @@ var INSTANCE_CARDINALITIES = [
|
|
|
8713
8779
|
"multiple_same",
|
|
8714
8780
|
"multiple_distinct"
|
|
8715
8781
|
];
|
|
8716
|
-
var SceneSegment =
|
|
8717
|
-
index:
|
|
8718
|
-
startTs:
|
|
8719
|
-
endTs:
|
|
8720
|
-
seedanceDuration:
|
|
8782
|
+
var SceneSegment = z38.object({
|
|
8783
|
+
index: z38.number().int().positive(),
|
|
8784
|
+
startTs: z38.number().nonnegative(),
|
|
8785
|
+
endTs: z38.number().positive(),
|
|
8786
|
+
seedanceDuration: z38.number().int().min(4).max(15),
|
|
8721
8787
|
// Pass 1 / Pass 2 outputs (all optional — populated when the rich analyzer
|
|
8722
8788
|
// runs and empty on fallback).
|
|
8723
|
-
action:
|
|
8724
|
-
motion:
|
|
8725
|
-
clipType:
|
|
8726
|
-
hasCharacter:
|
|
8727
|
-
faceVisible:
|
|
8789
|
+
action: z38.string().optional(),
|
|
8790
|
+
motion: z38.string().optional(),
|
|
8791
|
+
clipType: z38.enum(SCENE_CLIP_TYPES).optional(),
|
|
8792
|
+
hasCharacter: z38.boolean().optional(),
|
|
8793
|
+
faceVisible: z38.boolean().optional(),
|
|
8728
8794
|
// Pass 2 refinement — rich per-scene metadata used by buildMixPrompt.
|
|
8729
|
-
startState:
|
|
8730
|
-
endState:
|
|
8731
|
-
cameraMovement:
|
|
8732
|
-
emotion:
|
|
8733
|
-
productPlacement:
|
|
8734
|
-
productInteraction:
|
|
8735
|
-
settingDescription:
|
|
8736
|
-
dialogue:
|
|
8795
|
+
startState: z38.string().optional(),
|
|
8796
|
+
endState: z38.string().optional(),
|
|
8797
|
+
cameraMovement: z38.string().optional(),
|
|
8798
|
+
emotion: z38.string().optional(),
|
|
8799
|
+
productPlacement: z38.string().optional(),
|
|
8800
|
+
productInteraction: z38.string().optional(),
|
|
8801
|
+
settingDescription: z38.string().optional(),
|
|
8802
|
+
dialogue: z38.string().optional(),
|
|
8737
8803
|
// Main vs extras / noise (our addition on top of the script's schema).
|
|
8738
|
-
mainPersonDescription:
|
|
8739
|
-
mainProductDescription:
|
|
8740
|
-
personInstances:
|
|
8741
|
-
productInstances:
|
|
8804
|
+
mainPersonDescription: z38.string().optional(),
|
|
8805
|
+
mainProductDescription: z38.string().optional(),
|
|
8806
|
+
personInstances: z38.enum(INSTANCE_CARDINALITIES).optional(),
|
|
8807
|
+
productInstances: z38.enum(INSTANCE_CARDINALITIES).optional(),
|
|
8742
8808
|
/**
|
|
8743
8809
|
* Seconds of prev-clipType content absorbed at the start of this scene by
|
|
8744
8810
|
* Pass 2.7's clipType boundary margin. When > 0 and the scene is a
|
|
8745
8811
|
* pass-through (no Seedance), the concatenator prepends a held-still
|
|
8746
8812
|
* preamble (nano-banana-swapped first frame) to hide the leak.
|
|
8747
8813
|
*/
|
|
8748
|
-
absorbedMarginSec:
|
|
8814
|
+
absorbedMarginSec: z38.number().nonnegative().optional(),
|
|
8749
8815
|
/**
|
|
8750
8816
|
* True when the scene shows post-production graphics baked into the frame:
|
|
8751
8817
|
* caption/subtitle text, infographic overlay cards, or inset
|
|
@@ -8754,33 +8820,39 @@ var SceneSegment = z37.object({
|
|
|
8754
8820
|
* (mentioning nonexistent overlays gives the generator license to
|
|
8755
8821
|
* fabricate them).
|
|
8756
8822
|
*/
|
|
8757
|
-
hasOverlayGraphics:
|
|
8823
|
+
hasOverlayGraphics: z38.boolean().optional()
|
|
8758
8824
|
});
|
|
8759
|
-
var MixSceneResult =
|
|
8760
|
-
index:
|
|
8761
|
-
status:
|
|
8825
|
+
var MixSceneResult = z38.object({
|
|
8826
|
+
index: z38.number().int().positive(),
|
|
8827
|
+
status: z38.enum([
|
|
8762
8828
|
"queued",
|
|
8763
8829
|
"submitted",
|
|
8764
8830
|
"done",
|
|
8765
8831
|
"failed"
|
|
8766
8832
|
]),
|
|
8767
|
-
seedanceTaskId:
|
|
8768
|
-
videoUrl:
|
|
8769
|
-
error:
|
|
8770
|
-
|
|
8771
|
-
|
|
8772
|
-
|
|
8773
|
-
|
|
8833
|
+
seedanceTaskId: z38.string().optional(),
|
|
8834
|
+
videoUrl: z38.string().url().optional(),
|
|
8835
|
+
error: z38.string().optional(),
|
|
8836
|
+
degradedReason: MixDegradationReasonSchema.optional()
|
|
8837
|
+
});
|
|
8838
|
+
var MixResult = z38.object({
|
|
8839
|
+
mixTaskId: z38.string().uuid(),
|
|
8840
|
+
status: z38.enum([
|
|
8774
8841
|
"queued",
|
|
8775
8842
|
"processing",
|
|
8776
8843
|
"done",
|
|
8777
8844
|
"error"
|
|
8778
8845
|
]),
|
|
8779
|
-
resultUrl:
|
|
8780
|
-
scenes:
|
|
8781
|
-
failReason:
|
|
8846
|
+
resultUrl: z38.string().url().optional(),
|
|
8847
|
+
scenes: z38.array(MixSceneResult).default([]),
|
|
8848
|
+
failReason: z38.string().optional(),
|
|
8849
|
+
degradedReason: MixDegradationReasonSchema.optional()
|
|
8782
8850
|
});
|
|
8783
8851
|
|
|
8852
|
+
// ../../packages/types/src/mix-cost.ts
|
|
8853
|
+
var MAX_QA_RETRIES_PER_SCENE_UPPER_BOUND = 1;
|
|
8854
|
+
var MAX_BILLABLE_GENERATIONS_PER_BLOCK = 1 + MAX_QA_RETRIES_PER_SCENE_UPPER_BOUND;
|
|
8855
|
+
|
|
8784
8856
|
// ../../packages/types/src/product-delivery-format.ts
|
|
8785
8857
|
var DELIVERY_FAMILIES = [
|
|
8786
8858
|
"solid_dose",
|
|
@@ -8869,41 +8941,41 @@ var DECLARATION = DELIVERY_FAMILIES.map((family) => [
|
|
|
8869
8941
|
]);
|
|
8870
8942
|
|
|
8871
8943
|
// ../../packages/types/src/task-type.ts
|
|
8872
|
-
import { z as
|
|
8873
|
-
var TaskTypeSchema =
|
|
8944
|
+
import { z as z39 } from "zod";
|
|
8945
|
+
var TaskTypeSchema = z39.enum([
|
|
8874
8946
|
"product",
|
|
8875
8947
|
"service"
|
|
8876
8948
|
]);
|
|
8877
8949
|
|
|
8878
8950
|
// ../../packages/types/src/landing-regeneration.ts
|
|
8879
|
-
import { z as
|
|
8880
|
-
var LandingRegenerationStatus =
|
|
8951
|
+
import { z as z40 } from "zod";
|
|
8952
|
+
var LandingRegenerationStatus = z40.enum([
|
|
8881
8953
|
"queued",
|
|
8882
8954
|
"processing",
|
|
8883
8955
|
"published",
|
|
8884
8956
|
"failed"
|
|
8885
8957
|
]);
|
|
8886
|
-
var RegenerateLandingRoleResponse =
|
|
8887
|
-
ok:
|
|
8958
|
+
var RegenerateLandingRoleResponse = z40.object({
|
|
8959
|
+
ok: z40.literal(true),
|
|
8888
8960
|
role: LandingRole,
|
|
8889
|
-
promptIndex:
|
|
8890
|
-
operationId:
|
|
8961
|
+
promptIndex: z40.number().int().nonnegative(),
|
|
8962
|
+
operationId: z40.string().min(1)
|
|
8891
8963
|
});
|
|
8892
|
-
var LandingRegenerationStatusResponse =
|
|
8893
|
-
ok:
|
|
8894
|
-
operationId:
|
|
8964
|
+
var LandingRegenerationStatusResponse = z40.object({
|
|
8965
|
+
ok: z40.literal(true),
|
|
8966
|
+
operationId: z40.string().min(1),
|
|
8895
8967
|
role: LandingRole,
|
|
8896
8968
|
status: LandingRegenerationStatus,
|
|
8897
|
-
refunded:
|
|
8898
|
-
failureReason:
|
|
8899
|
-
publishedAssetKey:
|
|
8900
|
-
updatedAt:
|
|
8969
|
+
refunded: z40.boolean(),
|
|
8970
|
+
failureReason: z40.string().nullable(),
|
|
8971
|
+
publishedAssetKey: z40.string().nullable(),
|
|
8972
|
+
updatedAt: z40.string().datetime()
|
|
8901
8973
|
});
|
|
8902
8974
|
|
|
8903
8975
|
// ../../packages/types/src/video-edit.ts
|
|
8904
|
-
import { z as
|
|
8976
|
+
import { z as z41 } from "zod";
|
|
8905
8977
|
var MAX_SEGMENT_SECONDS = 3;
|
|
8906
|
-
var VideoEditStatusSchema =
|
|
8978
|
+
var VideoEditStatusSchema = z41.enum([
|
|
8907
8979
|
"pending",
|
|
8908
8980
|
"processing",
|
|
8909
8981
|
"assembling",
|
|
@@ -8912,9 +8984,9 @@ var VideoEditStatusSchema = z40.enum([
|
|
|
8912
8984
|
"discarded",
|
|
8913
8985
|
"failed"
|
|
8914
8986
|
]);
|
|
8915
|
-
var VideoEditTimeSectionSchema =
|
|
8916
|
-
startSec:
|
|
8917
|
-
endSec:
|
|
8987
|
+
var VideoEditTimeSectionSchema = z41.object({
|
|
8988
|
+
startSec: z41.number().min(0),
|
|
8989
|
+
endSec: z41.number().positive()
|
|
8918
8990
|
}).refine((v) => v.endSec > v.startSec, {
|
|
8919
8991
|
message: "endSec must be after startSec",
|
|
8920
8992
|
path: [
|
|
@@ -8926,45 +8998,45 @@ var VideoEditTimeSectionSchema = z40.object({
|
|
|
8926
8998
|
"endSec"
|
|
8927
8999
|
]
|
|
8928
9000
|
});
|
|
8929
|
-
var VideoEditRequestSchema =
|
|
8930
|
-
comment:
|
|
8931
|
-
sections:
|
|
9001
|
+
var VideoEditRequestSchema = z41.object({
|
|
9002
|
+
comment: z41.string().trim().min(1).max(2e3),
|
|
9003
|
+
sections: z41.array(VideoEditTimeSectionSchema).min(1).optional()
|
|
8932
9004
|
});
|
|
8933
|
-
var VideoEditModeSchema =
|
|
9005
|
+
var VideoEditModeSchema = z41.enum([
|
|
8934
9006
|
"wan_edit",
|
|
8935
9007
|
"regenerate"
|
|
8936
9008
|
]);
|
|
8937
|
-
var VideoRegenerationEngineSchema =
|
|
9009
|
+
var VideoRegenerationEngineSchema = z41.enum([
|
|
8938
9010
|
"free_text",
|
|
8939
9011
|
"free_image",
|
|
8940
9012
|
"single_call",
|
|
8941
9013
|
"multi_shot"
|
|
8942
9014
|
]);
|
|
8943
|
-
var VideoRegenerationRouteFingerprintSchema =
|
|
8944
|
-
var RegenerateEditRequestSchema =
|
|
8945
|
-
angleKey:
|
|
8946
|
-
comment:
|
|
9015
|
+
var VideoRegenerationRouteFingerprintSchema = z41.string().trim().min(1).max(128);
|
|
9016
|
+
var RegenerateEditRequestSchema = z41.object({
|
|
9017
|
+
angleKey: z41.string().min(1),
|
|
9018
|
+
comment: z41.string().min(1).max(2e3)
|
|
8947
9019
|
});
|
|
8948
9020
|
|
|
8949
9021
|
// ../../packages/types/src/uploaded-asset.ts
|
|
8950
|
-
import { z as
|
|
8951
|
-
var UploadedAssetMediaKind =
|
|
9022
|
+
import { z as z42 } from "zod";
|
|
9023
|
+
var UploadedAssetMediaKind = z42.enum([
|
|
8952
9024
|
"image",
|
|
8953
9025
|
"video"
|
|
8954
9026
|
]);
|
|
8955
|
-
var UploadedAssetSessionMediaKind =
|
|
9027
|
+
var UploadedAssetSessionMediaKind = z42.enum([
|
|
8956
9028
|
"image",
|
|
8957
9029
|
"video",
|
|
8958
9030
|
"mixed"
|
|
8959
9031
|
]);
|
|
8960
|
-
var UploadedAssetRole =
|
|
9032
|
+
var UploadedAssetRole = z42.enum([
|
|
8961
9033
|
"media",
|
|
8962
9034
|
"thumbnail"
|
|
8963
9035
|
]);
|
|
8964
9036
|
var UPLOADED_ASSET_MAX_FILES = 10;
|
|
8965
9037
|
var UPLOADED_ASSET_IMAGE_MAX_FILES = 5;
|
|
8966
|
-
var UploadedAssetId =
|
|
8967
|
-
var HttpsUrl =
|
|
9038
|
+
var UploadedAssetId = z42.string().uuid();
|
|
9039
|
+
var HttpsUrl = z42.string().url().refine((value) => {
|
|
8968
9040
|
try {
|
|
8969
9041
|
const url = new URL(value);
|
|
8970
9042
|
return url.protocol === "https:" && !url.username && !url.password;
|
|
@@ -8972,23 +9044,23 @@ var HttpsUrl = z41.string().url().refine((value) => {
|
|
|
8972
9044
|
return false;
|
|
8973
9045
|
}
|
|
8974
9046
|
}, "URL must use https");
|
|
8975
|
-
var UtcDateTime =
|
|
9047
|
+
var UtcDateTime = z42.string().datetime().refine((value) => {
|
|
8976
9048
|
const parts = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?Z$/.exec(value);
|
|
8977
9049
|
const timestamp = Date.parse(value);
|
|
8978
9050
|
if (!parts || Number.isNaN(timestamp)) return false;
|
|
8979
9051
|
const date = new Date(timestamp);
|
|
8980
9052
|
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]);
|
|
8981
9053
|
}, "datetime must be a valid UTC calendar instant");
|
|
8982
|
-
var UploadedAssetRef =
|
|
9054
|
+
var UploadedAssetRef = z42.object({
|
|
8983
9055
|
assetId: UploadedAssetId
|
|
8984
9056
|
}).strict();
|
|
8985
9057
|
var UploadedAssetCompletion = UploadedAssetRef.extend({
|
|
8986
9058
|
mediaKind: UploadedAssetMediaKind,
|
|
8987
9059
|
assetRole: UploadedAssetRole
|
|
8988
9060
|
}).strict();
|
|
8989
|
-
var UploadedAssetMetadata =
|
|
9061
|
+
var UploadedAssetMetadata = z42.object({
|
|
8990
9062
|
assetId: UploadedAssetId,
|
|
8991
|
-
ownerId:
|
|
9063
|
+
ownerId: z42.string().min(1),
|
|
8992
9064
|
mediaKind: UploadedAssetMediaKind,
|
|
8993
9065
|
assetRole: UploadedAssetRole,
|
|
8994
9066
|
createdAt: UtcDateTime,
|
|
@@ -8996,7 +9068,7 @@ var UploadedAssetMetadata = z41.object({
|
|
|
8996
9068
|
}).strict().superRefine((value, ctx) => {
|
|
8997
9069
|
if (Date.parse(value.expiresAt) <= Date.parse(value.createdAt)) {
|
|
8998
9070
|
ctx.addIssue({
|
|
8999
|
-
code:
|
|
9071
|
+
code: z42.ZodIssueCode.custom,
|
|
9000
9072
|
path: [
|
|
9001
9073
|
"expiresAt"
|
|
9002
9074
|
],
|
|
@@ -9004,27 +9076,27 @@ var UploadedAssetMetadata = z41.object({
|
|
|
9004
9076
|
});
|
|
9005
9077
|
}
|
|
9006
9078
|
});
|
|
9007
|
-
var MediaSourceRef =
|
|
9079
|
+
var MediaSourceRef = z42.object({
|
|
9008
9080
|
url: HttpsUrl.optional(),
|
|
9009
|
-
path:
|
|
9081
|
+
path: z42.string().min(1).optional(),
|
|
9010
9082
|
assetId: UploadedAssetId.optional()
|
|
9011
9083
|
}).strict().superRefine((value, ctx) => {
|
|
9012
9084
|
const sourceCount = Number(value.url !== void 0) + Number(value.path !== void 0) + Number(value.assetId !== void 0);
|
|
9013
9085
|
if (sourceCount !== 1) {
|
|
9014
9086
|
ctx.addIssue({
|
|
9015
|
-
code:
|
|
9087
|
+
code: z42.ZodIssueCode.custom,
|
|
9016
9088
|
message: "media source needs exactly one of url, path, or assetId"
|
|
9017
9089
|
});
|
|
9018
9090
|
}
|
|
9019
9091
|
});
|
|
9020
|
-
var UploadedAssetSessionRequest =
|
|
9092
|
+
var UploadedAssetSessionRequest = z42.object({
|
|
9021
9093
|
mediaKind: UploadedAssetSessionMediaKind,
|
|
9022
9094
|
assetRole: UploadedAssetRole.default("media"),
|
|
9023
|
-
maxFiles:
|
|
9095
|
+
maxFiles: z42.number().int().min(1).max(UPLOADED_ASSET_MAX_FILES).optional()
|
|
9024
9096
|
}).strict().superRefine((value, ctx) => {
|
|
9025
9097
|
if (value.mediaKind === "mixed" && value.assetRole === "thumbnail") {
|
|
9026
9098
|
ctx.addIssue({
|
|
9027
|
-
code:
|
|
9099
|
+
code: z42.ZodIssueCode.custom,
|
|
9028
9100
|
path: [
|
|
9029
9101
|
"mediaKind"
|
|
9030
9102
|
],
|
|
@@ -9033,7 +9105,7 @@ var UploadedAssetSessionRequest = z41.object({
|
|
|
9033
9105
|
}
|
|
9034
9106
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
9035
9107
|
ctx.addIssue({
|
|
9036
|
-
code:
|
|
9108
|
+
code: z42.ZodIssueCode.custom,
|
|
9037
9109
|
path: [
|
|
9038
9110
|
"maxFiles"
|
|
9039
9111
|
],
|
|
@@ -9042,7 +9114,7 @@ var UploadedAssetSessionRequest = z41.object({
|
|
|
9042
9114
|
}
|
|
9043
9115
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > UPLOADED_ASSET_IMAGE_MAX_FILES) {
|
|
9044
9116
|
ctx.addIssue({
|
|
9045
|
-
code:
|
|
9117
|
+
code: z42.ZodIssueCode.custom,
|
|
9046
9118
|
path: [
|
|
9047
9119
|
"maxFiles"
|
|
9048
9120
|
],
|
|
@@ -9051,7 +9123,7 @@ var UploadedAssetSessionRequest = z41.object({
|
|
|
9051
9123
|
}
|
|
9052
9124
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
9053
9125
|
ctx.addIssue({
|
|
9054
|
-
code:
|
|
9126
|
+
code: z42.ZodIssueCode.custom,
|
|
9055
9127
|
path: [
|
|
9056
9128
|
"mediaKind"
|
|
9057
9129
|
],
|
|
@@ -9059,32 +9131,32 @@ var UploadedAssetSessionRequest = z41.object({
|
|
|
9059
9131
|
});
|
|
9060
9132
|
}
|
|
9061
9133
|
});
|
|
9062
|
-
var UploadedAssetSessionStatus =
|
|
9063
|
-
|
|
9064
|
-
status:
|
|
9065
|
-
assets:
|
|
9134
|
+
var UploadedAssetSessionStatus = z42.discriminatedUnion("status", [
|
|
9135
|
+
z42.object({
|
|
9136
|
+
status: z42.literal("pending"),
|
|
9137
|
+
assets: z42.array(UploadedAssetCompletion).length(0)
|
|
9066
9138
|
}).strict(),
|
|
9067
|
-
|
|
9068
|
-
status:
|
|
9069
|
-
assets:
|
|
9139
|
+
z42.object({
|
|
9140
|
+
status: z42.literal("uploaded"),
|
|
9141
|
+
assets: z42.array(UploadedAssetCompletion).min(1).max(UPLOADED_ASSET_MAX_FILES)
|
|
9070
9142
|
}).strict()
|
|
9071
9143
|
]);
|
|
9072
|
-
var UploadedAssetAdoptionRequest =
|
|
9144
|
+
var UploadedAssetAdoptionRequest = z42.object({
|
|
9073
9145
|
assetId: UploadedAssetId,
|
|
9074
|
-
ownerId:
|
|
9075
|
-
consumer:
|
|
9076
|
-
idempotencyKey:
|
|
9146
|
+
ownerId: z42.string().min(1),
|
|
9147
|
+
consumer: z42.string().min(1).max(100),
|
|
9148
|
+
idempotencyKey: z42.string().min(1).max(255)
|
|
9077
9149
|
}).strict();
|
|
9078
9150
|
|
|
9079
9151
|
// ../../packages/types/src/dropshipping-project.ts
|
|
9080
|
-
import { z as
|
|
9081
|
-
var DropshippingProjectStatusSchema =
|
|
9152
|
+
import { z as z43 } from "zod";
|
|
9153
|
+
var DropshippingProjectStatusSchema = z43.enum([
|
|
9082
9154
|
"active",
|
|
9083
9155
|
"completed",
|
|
9084
9156
|
"archived"
|
|
9085
9157
|
]);
|
|
9086
9158
|
var DROPSHIPPING_LAUNCH_REWARD_CAMPAIGN = "dropshipping-launch-v1";
|
|
9087
|
-
var DropshippingRewardMilestoneSchema =
|
|
9159
|
+
var DropshippingRewardMilestoneSchema = z43.enum([
|
|
9088
9160
|
"product_selected",
|
|
9089
9161
|
"costing_saved",
|
|
9090
9162
|
"product_media_ready",
|
|
@@ -9099,21 +9171,21 @@ var DROPSHIPPING_LAUNCH_REWARD_CREDITS = {
|
|
|
9099
9171
|
campaign_created: 200
|
|
9100
9172
|
};
|
|
9101
9173
|
var DROPSHIPPING_LAUNCH_REWARD_TOTAL_CREDITS = Object.values(DROPSHIPPING_LAUNCH_REWARD_CREDITS).reduce((sum, credits) => sum + credits, 0);
|
|
9102
|
-
var DropshippingProjectRewardMilestoneStateSchema =
|
|
9174
|
+
var DropshippingProjectRewardMilestoneStateSchema = z43.object({
|
|
9103
9175
|
milestone: DropshippingRewardMilestoneSchema,
|
|
9104
|
-
credits:
|
|
9105
|
-
available:
|
|
9106
|
-
earned:
|
|
9107
|
-
grantId:
|
|
9108
|
-
grantedAt:
|
|
9109
|
-
});
|
|
9110
|
-
var DropshippingProjectRewardProgressSchema =
|
|
9111
|
-
campaignKey:
|
|
9112
|
-
totalCredits:
|
|
9113
|
-
earnedCredits:
|
|
9114
|
-
milestones:
|
|
9115
|
-
});
|
|
9116
|
-
var DropshippingProjectPhaseSchema =
|
|
9176
|
+
credits: z43.number().int().positive(),
|
|
9177
|
+
available: z43.boolean().optional(),
|
|
9178
|
+
earned: z43.boolean(),
|
|
9179
|
+
grantId: z43.string().uuid().nullable(),
|
|
9180
|
+
grantedAt: z43.string().datetime().nullable()
|
|
9181
|
+
});
|
|
9182
|
+
var DropshippingProjectRewardProgressSchema = z43.object({
|
|
9183
|
+
campaignKey: z43.literal(DROPSHIPPING_LAUNCH_REWARD_CAMPAIGN),
|
|
9184
|
+
totalCredits: z43.number().int().positive(),
|
|
9185
|
+
earnedCredits: z43.number().int().nonnegative(),
|
|
9186
|
+
milestones: z43.array(DropshippingProjectRewardMilestoneStateSchema).length(DropshippingRewardMilestoneSchema.options.length)
|
|
9187
|
+
});
|
|
9188
|
+
var DropshippingProjectPhaseSchema = z43.enum([
|
|
9117
9189
|
"research",
|
|
9118
9190
|
"costing",
|
|
9119
9191
|
"media",
|
|
@@ -9122,18 +9194,18 @@ var DropshippingProjectPhaseSchema = z42.enum([
|
|
|
9122
9194
|
"advertising",
|
|
9123
9195
|
"complete"
|
|
9124
9196
|
]);
|
|
9125
|
-
var DropshippingProjectCostingInputSchema =
|
|
9126
|
-
country:
|
|
9127
|
-
supplierCost:
|
|
9128
|
-
shippingCost:
|
|
9129
|
-
returnRate:
|
|
9130
|
-
cancellationRate:
|
|
9131
|
-
adsManagerCpa:
|
|
9132
|
-
desiredMargin:
|
|
9197
|
+
var DropshippingProjectCostingInputSchema = z43.object({
|
|
9198
|
+
country: z43.string().min(2).max(3),
|
|
9199
|
+
supplierCost: z43.number().finite().positive(),
|
|
9200
|
+
shippingCost: z43.number().finite().nonnegative(),
|
|
9201
|
+
returnRate: z43.number().finite().min(0).lt(1),
|
|
9202
|
+
cancellationRate: z43.number().finite().min(0).lt(1),
|
|
9203
|
+
adsManagerCpa: z43.number().finite().nonnegative(),
|
|
9204
|
+
desiredMargin: z43.number().finite().min(0).lt(1)
|
|
9133
9205
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
9134
9206
|
if (returnRate + cancellationRate >= 1) {
|
|
9135
9207
|
context.addIssue({
|
|
9136
|
-
code:
|
|
9208
|
+
code: z43.ZodIssueCode.custom,
|
|
9137
9209
|
path: [
|
|
9138
9210
|
"cancellationRate"
|
|
9139
9211
|
],
|
|
@@ -9141,24 +9213,24 @@ var DropshippingProjectCostingInputSchema = z42.object({
|
|
|
9141
9213
|
});
|
|
9142
9214
|
}
|
|
9143
9215
|
});
|
|
9144
|
-
var DropshippingProjectCostingResultSchema =
|
|
9145
|
-
country:
|
|
9146
|
-
deliveryRate:
|
|
9147
|
-
adjustedShippingCost:
|
|
9148
|
-
adjustedCpa:
|
|
9149
|
-
totalCost:
|
|
9150
|
-
suggestedPrice:
|
|
9151
|
-
baseCommercialPrice:
|
|
9152
|
-
minimumSafePrice:
|
|
9153
|
-
commercialPrice:
|
|
9154
|
-
comparisonPrice:
|
|
9155
|
-
estimatedProfit:
|
|
9156
|
-
actualMargin:
|
|
9157
|
-
breakEvenAdsManagerCpa:
|
|
9158
|
-
wasPriceAutoAdjusted:
|
|
9159
|
-
profitabilityStatus:
|
|
9160
|
-
});
|
|
9161
|
-
var HttpUrlSchema =
|
|
9216
|
+
var DropshippingProjectCostingResultSchema = z43.object({
|
|
9217
|
+
country: z43.string().min(2).max(3),
|
|
9218
|
+
deliveryRate: z43.number().finite(),
|
|
9219
|
+
adjustedShippingCost: z43.number().finite(),
|
|
9220
|
+
adjustedCpa: z43.number().finite(),
|
|
9221
|
+
totalCost: z43.number().finite(),
|
|
9222
|
+
suggestedPrice: z43.number().finite(),
|
|
9223
|
+
baseCommercialPrice: z43.number().finite(),
|
|
9224
|
+
minimumSafePrice: z43.number().finite(),
|
|
9225
|
+
commercialPrice: z43.number().finite(),
|
|
9226
|
+
comparisonPrice: z43.number().finite(),
|
|
9227
|
+
estimatedProfit: z43.number().finite(),
|
|
9228
|
+
actualMargin: z43.number().finite(),
|
|
9229
|
+
breakEvenAdsManagerCpa: z43.number().finite(),
|
|
9230
|
+
wasPriceAutoAdjusted: z43.boolean(),
|
|
9231
|
+
profitabilityStatus: z43.literal("healthy")
|
|
9232
|
+
});
|
|
9233
|
+
var HttpUrlSchema = z43.string().url().max(2e3).refine((value) => {
|
|
9162
9234
|
try {
|
|
9163
9235
|
return [
|
|
9164
9236
|
"http:",
|
|
@@ -9168,124 +9240,124 @@ var HttpUrlSchema = z42.string().url().max(2e3).refine((value) => {
|
|
|
9168
9240
|
return false;
|
|
9169
9241
|
}
|
|
9170
9242
|
}, "Product URL must use HTTP(S)");
|
|
9171
|
-
var ResearchCandidateOriginSchema =
|
|
9172
|
-
type:
|
|
9173
|
-
runId:
|
|
9174
|
-
candidateSourceId:
|
|
9175
|
-
});
|
|
9176
|
-
var TaskOriginSchema =
|
|
9177
|
-
type:
|
|
9178
|
-
taskId:
|
|
9179
|
-
});
|
|
9180
|
-
var ManualOriginSchema =
|
|
9181
|
-
type:
|
|
9182
|
-
clientRequestId:
|
|
9183
|
-
country:
|
|
9184
|
-
});
|
|
9185
|
-
var CreateDropshippingProjectRequestSchema =
|
|
9186
|
-
origin:
|
|
9243
|
+
var ResearchCandidateOriginSchema = z43.object({
|
|
9244
|
+
type: z43.literal("research_candidate"),
|
|
9245
|
+
runId: z43.string().uuid(),
|
|
9246
|
+
candidateSourceId: z43.string().min(1).max(160)
|
|
9247
|
+
});
|
|
9248
|
+
var TaskOriginSchema = z43.object({
|
|
9249
|
+
type: z43.literal("task"),
|
|
9250
|
+
taskId: z43.string().uuid()
|
|
9251
|
+
});
|
|
9252
|
+
var ManualOriginSchema = z43.object({
|
|
9253
|
+
type: z43.literal("manual"),
|
|
9254
|
+
clientRequestId: z43.string().uuid(),
|
|
9255
|
+
country: z43.string().min(2).max(3).optional()
|
|
9256
|
+
});
|
|
9257
|
+
var CreateDropshippingProjectRequestSchema = z43.object({
|
|
9258
|
+
origin: z43.discriminatedUnion("type", [
|
|
9187
9259
|
ResearchCandidateOriginSchema,
|
|
9188
9260
|
TaskOriginSchema,
|
|
9189
9261
|
ManualOriginSchema
|
|
9190
9262
|
]),
|
|
9191
|
-
productName:
|
|
9263
|
+
productName: z43.string().trim().min(1).max(240).optional(),
|
|
9192
9264
|
productUrl: HttpUrlSchema.optional(),
|
|
9193
|
-
country:
|
|
9194
|
-
languageCode:
|
|
9265
|
+
country: z43.string().min(2).max(3).optional(),
|
|
9266
|
+
languageCode: z43.string().min(2).max(16).optional()
|
|
9195
9267
|
}).strict();
|
|
9196
|
-
var SaveDropshippingProjectCostingRequestSchema =
|
|
9268
|
+
var SaveDropshippingProjectCostingRequestSchema = z43.object({
|
|
9197
9269
|
input: DropshippingProjectCostingInputSchema,
|
|
9198
|
-
version:
|
|
9270
|
+
version: z43.number().int().positive()
|
|
9199
9271
|
}).strict();
|
|
9200
|
-
var DropshippingProjectNextActionSchema =
|
|
9201
|
-
|
|
9202
|
-
kind:
|
|
9203
|
-
href:
|
|
9272
|
+
var DropshippingProjectNextActionSchema = z43.discriminatedUnion("kind", [
|
|
9273
|
+
z43.object({
|
|
9274
|
+
kind: z43.literal("cost_product"),
|
|
9275
|
+
href: z43.string().min(1)
|
|
9204
9276
|
}),
|
|
9205
|
-
|
|
9206
|
-
kind:
|
|
9207
|
-
href:
|
|
9277
|
+
z43.object({
|
|
9278
|
+
kind: z43.literal("provide_product_media"),
|
|
9279
|
+
href: z43.string().min(1)
|
|
9208
9280
|
}),
|
|
9209
|
-
|
|
9210
|
-
kind:
|
|
9211
|
-
href:
|
|
9281
|
+
z43.object({
|
|
9282
|
+
kind: z43.literal("generate_creatives"),
|
|
9283
|
+
href: z43.string().min(1)
|
|
9212
9284
|
}),
|
|
9213
|
-
|
|
9214
|
-
kind:
|
|
9215
|
-
href:
|
|
9285
|
+
z43.object({
|
|
9286
|
+
kind: z43.literal("wait_for_creatives"),
|
|
9287
|
+
href: z43.string().min(1)
|
|
9216
9288
|
}),
|
|
9217
|
-
|
|
9218
|
-
kind:
|
|
9219
|
-
href:
|
|
9289
|
+
z43.object({
|
|
9290
|
+
kind: z43.literal("repair_creatives"),
|
|
9291
|
+
href: z43.string().min(1)
|
|
9220
9292
|
}),
|
|
9221
|
-
|
|
9222
|
-
kind:
|
|
9223
|
-
href:
|
|
9293
|
+
z43.object({
|
|
9294
|
+
kind: z43.literal("complete_creative_set"),
|
|
9295
|
+
href: z43.string().min(1)
|
|
9224
9296
|
}),
|
|
9225
|
-
|
|
9226
|
-
kind:
|
|
9227
|
-
href:
|
|
9297
|
+
z43.object({
|
|
9298
|
+
kind: z43.literal("connect_shopify"),
|
|
9299
|
+
href: z43.string().min(1)
|
|
9228
9300
|
}),
|
|
9229
|
-
|
|
9230
|
-
kind:
|
|
9231
|
-
href:
|
|
9301
|
+
z43.object({
|
|
9302
|
+
kind: z43.literal("publish_storefront"),
|
|
9303
|
+
href: z43.string().min(1)
|
|
9232
9304
|
}),
|
|
9233
|
-
|
|
9234
|
-
kind:
|
|
9235
|
-
href:
|
|
9305
|
+
z43.object({
|
|
9306
|
+
kind: z43.literal("wait_for_storefront"),
|
|
9307
|
+
href: z43.string().min(1)
|
|
9236
9308
|
}),
|
|
9237
|
-
|
|
9238
|
-
kind:
|
|
9239
|
-
href:
|
|
9309
|
+
z43.object({
|
|
9310
|
+
kind: z43.literal("connect_meta"),
|
|
9311
|
+
href: z43.string().min(1)
|
|
9240
9312
|
}),
|
|
9241
|
-
|
|
9242
|
-
kind:
|
|
9243
|
-
href:
|
|
9313
|
+
z43.object({
|
|
9314
|
+
kind: z43.literal("create_meta_campaign"),
|
|
9315
|
+
href: z43.string().min(1)
|
|
9244
9316
|
}),
|
|
9245
|
-
|
|
9246
|
-
kind:
|
|
9247
|
-
href:
|
|
9317
|
+
z43.object({
|
|
9318
|
+
kind: z43.literal("repair_meta_campaign"),
|
|
9319
|
+
href: z43.string().min(1)
|
|
9248
9320
|
}),
|
|
9249
|
-
|
|
9250
|
-
kind:
|
|
9251
|
-
href:
|
|
9321
|
+
z43.object({
|
|
9322
|
+
kind: z43.literal("review_paused_campaign"),
|
|
9323
|
+
href: z43.string().min(1)
|
|
9252
9324
|
})
|
|
9253
9325
|
]);
|
|
9254
|
-
var DropshippingProjectResponseSchema =
|
|
9255
|
-
id:
|
|
9256
|
-
taskId:
|
|
9326
|
+
var DropshippingProjectResponseSchema = z43.object({
|
|
9327
|
+
id: z43.string().uuid(),
|
|
9328
|
+
taskId: z43.string().uuid().nullable(),
|
|
9257
9329
|
status: DropshippingProjectStatusSchema,
|
|
9258
|
-
originKey:
|
|
9259
|
-
researchRunId:
|
|
9260
|
-
candidateSourceId:
|
|
9261
|
-
productName:
|
|
9330
|
+
originKey: z43.string().min(1),
|
|
9331
|
+
researchRunId: z43.string().uuid().nullable(),
|
|
9332
|
+
candidateSourceId: z43.string().nullable(),
|
|
9333
|
+
productName: z43.string().nullable(),
|
|
9262
9334
|
productUrl: HttpUrlSchema.nullable(),
|
|
9263
|
-
referenceImageUrl:
|
|
9264
|
-
hasReferenceImage:
|
|
9265
|
-
targetCountry:
|
|
9266
|
-
languageCode:
|
|
9335
|
+
referenceImageUrl: z43.string().url().nullable(),
|
|
9336
|
+
hasReferenceImage: z43.boolean(),
|
|
9337
|
+
targetCountry: z43.string().nullable(),
|
|
9338
|
+
languageCode: z43.string().nullable(),
|
|
9267
9339
|
costingInput: DropshippingProjectCostingInputSchema.nullable(),
|
|
9268
9340
|
costingResult: DropshippingProjectCostingResultSchema.nullable(),
|
|
9269
|
-
costingVersion:
|
|
9270
|
-
version:
|
|
9341
|
+
costingVersion: z43.number().int().positive().nullable(),
|
|
9342
|
+
version: z43.number().int().positive(),
|
|
9271
9343
|
phase: DropshippingProjectPhaseSchema,
|
|
9272
9344
|
nextAction: DropshippingProjectNextActionSchema.nullable(),
|
|
9273
9345
|
rewards: DropshippingProjectRewardProgressSchema,
|
|
9274
|
-
createdAt:
|
|
9275
|
-
updatedAt:
|
|
9346
|
+
createdAt: z43.string().datetime(),
|
|
9347
|
+
updatedAt: z43.string().datetime()
|
|
9276
9348
|
});
|
|
9277
9349
|
|
|
9278
9350
|
// ../../packages/types/src/scene-subject-contract.ts
|
|
9279
|
-
import { z as
|
|
9280
|
-
var SceneSubjectContractSchema =
|
|
9281
|
-
maxPeople:
|
|
9282
|
-
minPeople:
|
|
9283
|
-
minDistinctPeople:
|
|
9284
|
-
maxHands:
|
|
9351
|
+
import { z as z44 } from "zod";
|
|
9352
|
+
var SceneSubjectContractSchema = z44.object({
|
|
9353
|
+
maxPeople: z44.number().int().min(1).max(10),
|
|
9354
|
+
minPeople: z44.number().int().min(0).max(10),
|
|
9355
|
+
minDistinctPeople: z44.number().int().min(0).max(10),
|
|
9356
|
+
maxHands: z44.number().int().min(0).max(20)
|
|
9285
9357
|
}).superRefine((value, ctx) => {
|
|
9286
9358
|
if (value.minPeople > value.maxPeople) {
|
|
9287
9359
|
ctx.addIssue({
|
|
9288
|
-
code:
|
|
9360
|
+
code: z44.ZodIssueCode.custom,
|
|
9289
9361
|
path: [
|
|
9290
9362
|
"minPeople"
|
|
9291
9363
|
],
|
|
@@ -9294,7 +9366,7 @@ var SceneSubjectContractSchema = z43.object({
|
|
|
9294
9366
|
}
|
|
9295
9367
|
if (value.minDistinctPeople > value.maxPeople) {
|
|
9296
9368
|
ctx.addIssue({
|
|
9297
|
-
code:
|
|
9369
|
+
code: z44.ZodIssueCode.custom,
|
|
9298
9370
|
path: [
|
|
9299
9371
|
"minDistinctPeople"
|
|
9300
9372
|
],
|
|
@@ -9303,7 +9375,7 @@ var SceneSubjectContractSchema = z43.object({
|
|
|
9303
9375
|
}
|
|
9304
9376
|
if (value.minDistinctPeople > value.minPeople) {
|
|
9305
9377
|
ctx.addIssue({
|
|
9306
|
-
code:
|
|
9378
|
+
code: z44.ZodIssueCode.custom,
|
|
9307
9379
|
path: [
|
|
9308
9380
|
"minDistinctPeople"
|
|
9309
9381
|
],
|
|
@@ -9313,7 +9385,7 @@ var SceneSubjectContractSchema = z43.object({
|
|
|
9313
9385
|
});
|
|
9314
9386
|
|
|
9315
9387
|
// ../../packages/types/src/service-creative.ts
|
|
9316
|
-
import { z as
|
|
9388
|
+
import { z as z45 } from "zod";
|
|
9317
9389
|
var SERVICE_CREATIVE_PUBLIC_PRESETS = [
|
|
9318
9390
|
"auto",
|
|
9319
9391
|
"ugc_dynamic",
|
|
@@ -9321,19 +9393,19 @@ var SERVICE_CREATIVE_PUBLIC_PRESETS = [
|
|
|
9321
9393
|
"cinematic",
|
|
9322
9394
|
"wild_card"
|
|
9323
9395
|
];
|
|
9324
|
-
var ServiceCreativePresetSchema =
|
|
9396
|
+
var ServiceCreativePresetSchema = z45.enum(SERVICE_CREATIVE_PUBLIC_PRESETS);
|
|
9325
9397
|
var SERVICE_REVIEW_MODES = [
|
|
9326
9398
|
"automatic",
|
|
9327
9399
|
"guided"
|
|
9328
9400
|
];
|
|
9329
|
-
var ServiceReviewModeSchema =
|
|
9401
|
+
var ServiceReviewModeSchema = z45.enum(SERVICE_REVIEW_MODES);
|
|
9330
9402
|
var SERVICE_HIGGSFIELD_MODES = [
|
|
9331
9403
|
"product_review",
|
|
9332
9404
|
"ugc_how_to",
|
|
9333
9405
|
"tv_spot",
|
|
9334
9406
|
"wild_card"
|
|
9335
9407
|
];
|
|
9336
|
-
var ServiceHiggsfieldModeSchema =
|
|
9408
|
+
var ServiceHiggsfieldModeSchema = z45.enum(SERVICE_HIGGSFIELD_MODES);
|
|
9337
9409
|
var SERVICE_MEDIA_ROLES = [
|
|
9338
9410
|
"screen_demo",
|
|
9339
9411
|
"ad_reference",
|
|
@@ -9341,20 +9413,20 @@ var SERVICE_MEDIA_ROLES = [
|
|
|
9341
9413
|
"presenter_reference",
|
|
9342
9414
|
"brand_asset"
|
|
9343
9415
|
];
|
|
9344
|
-
var ServiceMediaRoleSchema =
|
|
9345
|
-
var ServiceMediaAssetSchema =
|
|
9416
|
+
var ServiceMediaRoleSchema = z45.enum(SERVICE_MEDIA_ROLES);
|
|
9417
|
+
var ServiceMediaAssetSchema = z45.object({
|
|
9346
9418
|
role: ServiceMediaRoleSchema,
|
|
9347
|
-
s3Key:
|
|
9419
|
+
s3Key: z45.string().min(1),
|
|
9348
9420
|
/** HMAC ticket returned by the authenticated service-media presign route. */
|
|
9349
|
-
uploadToken:
|
|
9350
|
-
mimeType:
|
|
9351
|
-
durationSec:
|
|
9352
|
-
sourceName:
|
|
9421
|
+
uploadToken: z45.string().min(1).optional(),
|
|
9422
|
+
mimeType: z45.string().min(1),
|
|
9423
|
+
durationSec: z45.number().positive().max(30).optional(),
|
|
9424
|
+
sourceName: z45.string().max(255).optional()
|
|
9353
9425
|
}).superRefine((asset, ctx) => {
|
|
9354
9426
|
const isVideoRole = asset.role === "screen_demo" || asset.role === "ad_reference";
|
|
9355
9427
|
if (isVideoRole && !asset.mimeType.startsWith("video/")) {
|
|
9356
9428
|
ctx.addIssue({
|
|
9357
|
-
code:
|
|
9429
|
+
code: z45.ZodIssueCode.custom,
|
|
9358
9430
|
message: `${asset.role} requires video media`,
|
|
9359
9431
|
path: [
|
|
9360
9432
|
"mimeType"
|
|
@@ -9363,7 +9435,7 @@ var ServiceMediaAssetSchema = z44.object({
|
|
|
9363
9435
|
}
|
|
9364
9436
|
if (isVideoRole && asset.durationSec === void 0) {
|
|
9365
9437
|
ctx.addIssue({
|
|
9366
|
-
code:
|
|
9438
|
+
code: z45.ZodIssueCode.custom,
|
|
9367
9439
|
message: `${asset.role} requires durationSec`,
|
|
9368
9440
|
path: [
|
|
9369
9441
|
"durationSec"
|
|
@@ -9372,7 +9444,7 @@ var ServiceMediaAssetSchema = z44.object({
|
|
|
9372
9444
|
}
|
|
9373
9445
|
if (!isVideoRole && !asset.mimeType.startsWith("image/")) {
|
|
9374
9446
|
ctx.addIssue({
|
|
9375
|
-
code:
|
|
9447
|
+
code: z45.ZodIssueCode.custom,
|
|
9376
9448
|
message: `${asset.role} requires image media`,
|
|
9377
9449
|
path: [
|
|
9378
9450
|
"mimeType"
|
|
@@ -9380,13 +9452,13 @@ var ServiceMediaAssetSchema = z44.object({
|
|
|
9380
9452
|
});
|
|
9381
9453
|
}
|
|
9382
9454
|
});
|
|
9383
|
-
var ServiceMediaBundleSchema =
|
|
9384
|
-
assets:
|
|
9455
|
+
var ServiceMediaBundleSchema = z45.object({
|
|
9456
|
+
assets: z45.array(ServiceMediaAssetSchema).max(15).default([])
|
|
9385
9457
|
}).superRefine((bundle, ctx) => {
|
|
9386
9458
|
const adReferences = bundle.assets.filter((asset) => asset.role === "ad_reference");
|
|
9387
9459
|
if (adReferences.length > 5) {
|
|
9388
9460
|
ctx.addIssue({
|
|
9389
|
-
code:
|
|
9461
|
+
code: z45.ZodIssueCode.custom,
|
|
9390
9462
|
message: "A maximum of five ad_reference videos is allowed",
|
|
9391
9463
|
path: [
|
|
9392
9464
|
"assets"
|
|
@@ -9396,7 +9468,7 @@ var ServiceMediaBundleSchema = z44.object({
|
|
|
9396
9468
|
const screenDemos = bundle.assets.filter((asset) => asset.role === "screen_demo");
|
|
9397
9469
|
if (screenDemos.length > 3) {
|
|
9398
9470
|
ctx.addIssue({
|
|
9399
|
-
code:
|
|
9471
|
+
code: z45.ZodIssueCode.custom,
|
|
9400
9472
|
message: "A maximum of three screen_demo videos is allowed",
|
|
9401
9473
|
path: [
|
|
9402
9474
|
"assets"
|
|
@@ -9413,33 +9485,33 @@ var SERVICE_MEDIA_ANALYSIS_KINDS = [
|
|
|
9413
9485
|
"product",
|
|
9414
9486
|
"other"
|
|
9415
9487
|
];
|
|
9416
|
-
var ServiceMediaAnalysisKindSchema =
|
|
9417
|
-
var ServiceMediaAnalysisItemSchema =
|
|
9418
|
-
assetIndex:
|
|
9419
|
-
mediaType:
|
|
9488
|
+
var ServiceMediaAnalysisKindSchema = z45.enum(SERVICE_MEDIA_ANALYSIS_KINDS);
|
|
9489
|
+
var ServiceMediaAnalysisItemSchema = z45.object({
|
|
9490
|
+
assetIndex: z45.number().int().nonnegative(),
|
|
9491
|
+
mediaType: z45.enum([
|
|
9420
9492
|
"image",
|
|
9421
9493
|
"video"
|
|
9422
9494
|
]),
|
|
9423
9495
|
kind: ServiceMediaAnalysisKindSchema,
|
|
9424
|
-
description:
|
|
9425
|
-
tags:
|
|
9426
|
-
suggestedRoles:
|
|
9427
|
-
visiblePeople:
|
|
9428
|
-
ocrText:
|
|
9429
|
-
speechSummary:
|
|
9430
|
-
});
|
|
9431
|
-
var ServiceMediaAnalysisSchema =
|
|
9432
|
-
version:
|
|
9433
|
-
analyzedAt:
|
|
9434
|
-
pricingAction:
|
|
9435
|
-
assetFingerprint:
|
|
9496
|
+
description: z45.string().min(1).max(1200),
|
|
9497
|
+
tags: z45.array(z45.string().min(1).max(80)).max(12),
|
|
9498
|
+
suggestedRoles: z45.array(ServiceMediaRoleSchema).max(4),
|
|
9499
|
+
visiblePeople: z45.number().int().nonnegative().max(20).optional(),
|
|
9500
|
+
ocrText: z45.string().max(2e3).optional(),
|
|
9501
|
+
speechSummary: z45.string().max(2e3).optional()
|
|
9502
|
+
});
|
|
9503
|
+
var ServiceMediaAnalysisSchema = z45.object({
|
|
9504
|
+
version: z45.literal(1),
|
|
9505
|
+
analyzedAt: z45.string().datetime(),
|
|
9506
|
+
pricingAction: z45.literal("service-media-analysis"),
|
|
9507
|
+
assetFingerprint: z45.string().regex(/^[a-f0-9]{64}$/),
|
|
9436
9508
|
/** Language used for human-readable descriptions and tags. Optional for old checkpoints. */
|
|
9437
|
-
language:
|
|
9509
|
+
language: z45.enum([
|
|
9438
9510
|
"es",
|
|
9439
9511
|
"en",
|
|
9440
9512
|
"pt"
|
|
9441
9513
|
]).optional(),
|
|
9442
|
-
items:
|
|
9514
|
+
items: z45.array(ServiceMediaAnalysisItemSchema).max(15)
|
|
9443
9515
|
});
|
|
9444
9516
|
|
|
9445
9517
|
// ../../packages/types/src/productmaker-capability-registry.ts
|
|
@@ -9956,7 +10028,7 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
9956
10028
|
], [
|
|
9957
10029
|
"creative"
|
|
9958
10030
|
]),
|
|
9959
|
-
defineCapability("generate_landing", "
|
|
10031
|
+
defineCapability("generate_landing", "67520417176396516cd5ad358dca39f70a5c4a74169eecd85987217226c12251", "credit_consuming", "creative", [
|
|
9960
10032
|
"credit_consuming",
|
|
9961
10033
|
"state_change"
|
|
9962
10034
|
], [
|
|
@@ -10001,12 +10073,14 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
10001
10073
|
"competitorScanEnabled",
|
|
10002
10074
|
"landingStrategy",
|
|
10003
10075
|
"landingImageFormat",
|
|
10076
|
+
"pauseForAngleReview",
|
|
10004
10077
|
// MCP-only, like create_product_task's aiDecidesAll.
|
|
10005
10078
|
"aiDecidesAll"
|
|
10006
10079
|
], [
|
|
10007
10080
|
"competitorScanEnabled",
|
|
10008
10081
|
"landingStrategy",
|
|
10009
|
-
"landingImageFormat"
|
|
10082
|
+
"landingImageFormat",
|
|
10083
|
+
"pauseForAngleReview"
|
|
10010
10084
|
])
|
|
10011
10085
|
], [
|
|
10012
10086
|
"product_reference"
|
|
@@ -10522,8 +10596,8 @@ var PRODUCTMAKER_MCP_CAPABILITIES = toLegacyCapabilityCatalog(PRODUCTMAKER_MCP_C
|
|
|
10522
10596
|
var PRODUCTMAKER_MCP_CAPABILITY_NAMES = PRODUCTMAKER_MCP_CAPABILITY_REGISTRY.map((capability) => capability.name);
|
|
10523
10597
|
|
|
10524
10598
|
// ../../packages/types/src/actor.ts
|
|
10525
|
-
import { z as
|
|
10526
|
-
var ActorStatusSchema =
|
|
10599
|
+
import { z as z46 } from "zod";
|
|
10600
|
+
var ActorStatusSchema = z46.enum([
|
|
10527
10601
|
"draft",
|
|
10528
10602
|
"generating",
|
|
10529
10603
|
"ready",
|
|
@@ -10532,18 +10606,18 @@ var ActorStatusSchema = z45.enum([
|
|
|
10532
10606
|
var ACTOR_NAME_MAX_CHARS = 60;
|
|
10533
10607
|
var ACTOR_DESCRIPTION_MAX_CHARS = 600;
|
|
10534
10608
|
var ACTOR_CANDIDATE_COUNT = 4;
|
|
10535
|
-
var ActorGenderSchema =
|
|
10609
|
+
var ActorGenderSchema = z46.enum([
|
|
10536
10610
|
"female",
|
|
10537
10611
|
"male",
|
|
10538
10612
|
"non_binary"
|
|
10539
10613
|
]);
|
|
10540
|
-
var ActorSchema =
|
|
10541
|
-
id:
|
|
10542
|
-
name:
|
|
10543
|
-
description:
|
|
10614
|
+
var ActorSchema = z46.object({
|
|
10615
|
+
id: z46.string(),
|
|
10616
|
+
name: z46.string().min(1).max(ACTOR_NAME_MAX_CHARS),
|
|
10617
|
+
description: z46.string().max(ACTOR_DESCRIPTION_MAX_CHARS),
|
|
10544
10618
|
gender: ActorGenderSchema,
|
|
10545
|
-
voiceId:
|
|
10546
|
-
brandId:
|
|
10619
|
+
voiceId: z46.string().nullable().optional(),
|
|
10620
|
+
brandId: z46.string().nullable().optional(),
|
|
10547
10621
|
status: ActorStatusSchema,
|
|
10548
10622
|
/**
|
|
10549
10623
|
* A candidate-grid run is in flight RIGHT NOW.
|
|
@@ -10555,36 +10629,36 @@ var ActorSchema = z45.object({
|
|
|
10555
10629
|
* timestamp with a TTL, so an orphaned run reads as `false` instead of
|
|
10556
10630
|
* pinning the personaje forever.
|
|
10557
10631
|
*/
|
|
10558
|
-
generating:
|
|
10559
|
-
photoUrl:
|
|
10560
|
-
avatarUrl:
|
|
10561
|
-
candidateUrls:
|
|
10632
|
+
generating: z46.boolean().optional(),
|
|
10633
|
+
photoUrl: z46.string().url().nullable().optional(),
|
|
10634
|
+
avatarUrl: z46.string().url().nullable().optional(),
|
|
10635
|
+
candidateUrls: z46.array(z46.string().url()).optional(),
|
|
10562
10636
|
/** Indices of candidateUrls that failed the anatomy check (Task 6). */
|
|
10563
|
-
flaggedCandidateIndices:
|
|
10637
|
+
flaggedCandidateIndices: z46.array(z46.number().int()).optional()
|
|
10564
10638
|
});
|
|
10565
|
-
var CreateActorRequest =
|
|
10566
|
-
name:
|
|
10567
|
-
description:
|
|
10639
|
+
var CreateActorRequest = z46.object({
|
|
10640
|
+
name: z46.string().min(1).max(ACTOR_NAME_MAX_CHARS),
|
|
10641
|
+
description: z46.string().max(ACTOR_DESCRIPTION_MAX_CHARS).default(""),
|
|
10568
10642
|
gender: ActorGenderSchema,
|
|
10569
|
-
voiceId:
|
|
10570
|
-
brandId:
|
|
10571
|
-
sourcePhotoKey:
|
|
10643
|
+
voiceId: z46.string().optional(),
|
|
10644
|
+
brandId: z46.string().optional(),
|
|
10645
|
+
sourcePhotoKey: z46.string().optional()
|
|
10572
10646
|
}).refine((v) => v.description.trim().length > 0 || !!v.sourcePhotoKey, {
|
|
10573
10647
|
message: "Se necesita una descripci\xF3n o una foto"
|
|
10574
10648
|
});
|
|
10575
|
-
var UpdateActorRequest =
|
|
10576
|
-
name:
|
|
10577
|
-
description:
|
|
10649
|
+
var UpdateActorRequest = z46.object({
|
|
10650
|
+
name: z46.string().min(1).max(ACTOR_NAME_MAX_CHARS).optional(),
|
|
10651
|
+
description: z46.string().max(ACTOR_DESCRIPTION_MAX_CHARS).optional(),
|
|
10578
10652
|
gender: ActorGenderSchema.optional(),
|
|
10579
|
-
voiceId:
|
|
10580
|
-
brandId:
|
|
10653
|
+
voiceId: z46.string().nullable().optional(),
|
|
10654
|
+
brandId: z46.string().nullable().optional()
|
|
10581
10655
|
});
|
|
10582
|
-
var ApproveActorRequest =
|
|
10583
|
-
candidateIndex:
|
|
10656
|
+
var ApproveActorRequest = z46.object({
|
|
10657
|
+
candidateIndex: z46.number().int().min(0).max(ACTOR_CANDIDATE_COUNT - 1)
|
|
10584
10658
|
});
|
|
10585
10659
|
|
|
10586
10660
|
// ../../packages/types/src/referral-dashboard.ts
|
|
10587
|
-
import { z as
|
|
10661
|
+
import { z as z47 } from "zod";
|
|
10588
10662
|
var REFERRAL_DASHBOARD_RAW_STATUSES = [
|
|
10589
10663
|
"ACTIVE",
|
|
10590
10664
|
"PENDING",
|
|
@@ -10603,66 +10677,66 @@ var REFERRAL_DASHBOARD_PLAN_KINDS = [
|
|
|
10603
10677
|
"last",
|
|
10604
10678
|
"none"
|
|
10605
10679
|
];
|
|
10606
|
-
var ReferralDashboardRawStatusSchema =
|
|
10607
|
-
var ReferralDashboardStateSchema =
|
|
10608
|
-
var ReferralDashboardPlanKindSchema =
|
|
10609
|
-
var ReferralDashboardStatusSchema =
|
|
10680
|
+
var ReferralDashboardRawStatusSchema = z47.enum(REFERRAL_DASHBOARD_RAW_STATUSES);
|
|
10681
|
+
var ReferralDashboardStateSchema = z47.enum(REFERRAL_DASHBOARD_STATES);
|
|
10682
|
+
var ReferralDashboardPlanKindSchema = z47.enum(REFERRAL_DASHBOARD_PLAN_KINDS);
|
|
10683
|
+
var ReferralDashboardStatusSchema = z47.enum([
|
|
10610
10684
|
"all",
|
|
10611
10685
|
"active",
|
|
10612
10686
|
"pending",
|
|
10613
10687
|
"inactive"
|
|
10614
10688
|
]).default("all");
|
|
10615
|
-
var ReferralDashboardPlanSchema =
|
|
10616
|
-
var ReferralDashboardFiltersSchema =
|
|
10689
|
+
var ReferralDashboardPlanSchema = z47.string().trim().min(1).max(100).optional();
|
|
10690
|
+
var ReferralDashboardFiltersSchema = z47.object({
|
|
10617
10691
|
status: ReferralDashboardStatusSchema,
|
|
10618
10692
|
plan: ReferralDashboardPlanSchema
|
|
10619
10693
|
});
|
|
10620
|
-
var ReferralDashboardSubscriptionSchema =
|
|
10621
|
-
planName:
|
|
10694
|
+
var ReferralDashboardSubscriptionSchema = z47.object({
|
|
10695
|
+
planName: z47.string().nullable(),
|
|
10622
10696
|
planKind: ReferralDashboardPlanKindSchema,
|
|
10623
10697
|
rawStatus: ReferralDashboardRawStatusSchema.nullable(),
|
|
10624
10698
|
state: ReferralDashboardStateSchema,
|
|
10625
|
-
currentPeriodEnd:
|
|
10699
|
+
currentPeriodEnd: z47.string().datetime({
|
|
10626
10700
|
offset: true
|
|
10627
10701
|
}).nullable(),
|
|
10628
|
-
cancelAtPeriodEnd:
|
|
10702
|
+
cancelAtPeriodEnd: z47.boolean()
|
|
10629
10703
|
});
|
|
10630
|
-
var ReferralDashboardReferralSchema =
|
|
10631
|
-
id:
|
|
10632
|
-
registeredAt:
|
|
10704
|
+
var ReferralDashboardReferralSchema = z47.object({
|
|
10705
|
+
id: z47.string().min(1),
|
|
10706
|
+
registeredAt: z47.string().datetime({
|
|
10633
10707
|
offset: true
|
|
10634
10708
|
}),
|
|
10635
10709
|
// Kept in the response for compatibility with existing referral API clients.
|
|
10636
10710
|
// The referrer dashboard intentionally does not render these legacy fields.
|
|
10637
|
-
expiresAt:
|
|
10711
|
+
expiresAt: z47.string().datetime({
|
|
10638
10712
|
offset: true
|
|
10639
10713
|
}).nullable().optional(),
|
|
10640
|
-
status:
|
|
10641
|
-
referredUser:
|
|
10642
|
-
email:
|
|
10714
|
+
status: z47.string().min(1).optional(),
|
|
10715
|
+
referredUser: z47.object({
|
|
10716
|
+
email: z47.string().nullable()
|
|
10643
10717
|
}),
|
|
10644
10718
|
subscription: ReferralDashboardSubscriptionSchema
|
|
10645
10719
|
});
|
|
10646
|
-
var ReferralDashboardReferralsPageSchema =
|
|
10647
|
-
referrals:
|
|
10648
|
-
total:
|
|
10720
|
+
var ReferralDashboardReferralsPageSchema = z47.object({
|
|
10721
|
+
referrals: z47.array(ReferralDashboardReferralSchema),
|
|
10722
|
+
total: z47.number().int().nonnegative()
|
|
10649
10723
|
});
|
|
10650
|
-
var ReferralDashboardPlanBreakdownSchema =
|
|
10651
|
-
planName:
|
|
10652
|
-
count:
|
|
10724
|
+
var ReferralDashboardPlanBreakdownSchema = z47.object({
|
|
10725
|
+
planName: z47.string().nullable(),
|
|
10726
|
+
count: z47.number().int().nonnegative()
|
|
10653
10727
|
});
|
|
10654
|
-
var ReferralDashboardMonthlyRegistrationSchema =
|
|
10655
|
-
month:
|
|
10656
|
-
count:
|
|
10728
|
+
var ReferralDashboardMonthlyRegistrationSchema = z47.object({
|
|
10729
|
+
month: z47.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/),
|
|
10730
|
+
count: z47.number().int().nonnegative()
|
|
10657
10731
|
});
|
|
10658
|
-
var ReferralDashboardOverviewSchema =
|
|
10659
|
-
totalReferredUsers:
|
|
10660
|
-
activeUsers:
|
|
10661
|
-
pendingUsers:
|
|
10662
|
-
inactiveUsers:
|
|
10663
|
-
noPlanUsers:
|
|
10664
|
-
planBreakdown:
|
|
10665
|
-
monthlyRegistrations:
|
|
10732
|
+
var ReferralDashboardOverviewSchema = z47.object({
|
|
10733
|
+
totalReferredUsers: z47.number().int().nonnegative(),
|
|
10734
|
+
activeUsers: z47.number().int().nonnegative(),
|
|
10735
|
+
pendingUsers: z47.number().int().nonnegative(),
|
|
10736
|
+
inactiveUsers: z47.number().int().nonnegative(),
|
|
10737
|
+
noPlanUsers: z47.number().int().nonnegative(),
|
|
10738
|
+
planBreakdown: z47.array(ReferralDashboardPlanBreakdownSchema),
|
|
10739
|
+
monthlyRegistrations: z47.array(ReferralDashboardMonthlyRegistrationSchema).refine((months) => months.length === 6, "Expected six monthly registration buckets")
|
|
10666
10740
|
});
|
|
10667
10741
|
|
|
10668
10742
|
// src/resolve-media.ts
|
|
@@ -10905,10 +10979,10 @@ async function resolveMediaRef(ref, opts) {
|
|
|
10905
10979
|
__name(resolveMediaRef, "resolveMediaRef");
|
|
10906
10980
|
|
|
10907
10981
|
// src/tools/shared.ts
|
|
10908
|
-
import { z as
|
|
10909
|
-
var Lang =
|
|
10910
|
-
var Country =
|
|
10911
|
-
var LandingStrategyEnum =
|
|
10982
|
+
import { z as z48 } from "zod";
|
|
10983
|
+
var Lang = z48.string().min(2).max(10);
|
|
10984
|
+
var Country = z48.string().min(2).max(3);
|
|
10985
|
+
var LandingStrategyEnum = z48.enum([
|
|
10912
10986
|
"auto",
|
|
10913
10987
|
"classic",
|
|
10914
10988
|
"pain_solution",
|
|
@@ -10917,12 +10991,12 @@ var LandingStrategyEnum = z47.enum([
|
|
|
10917
10991
|
"offer_value",
|
|
10918
10992
|
"lifestyle_identity"
|
|
10919
10993
|
]);
|
|
10920
|
-
var LandingImageFormatEnum =
|
|
10994
|
+
var LandingImageFormatEnum = z48.enum([
|
|
10921
10995
|
"9:16",
|
|
10922
10996
|
"4:5",
|
|
10923
10997
|
"1:1"
|
|
10924
10998
|
]);
|
|
10925
|
-
var VideoPresetEnum =
|
|
10999
|
+
var VideoPresetEnum = z48.enum([
|
|
10926
11000
|
"auto",
|
|
10927
11001
|
"ugc_dynamic",
|
|
10928
11002
|
"ugc_how_to",
|
|
@@ -10935,7 +11009,7 @@ var VideoPresetEnum = z47.enum([
|
|
|
10935
11009
|
"pixar_problem",
|
|
10936
11010
|
"pixar_sassy"
|
|
10937
11011
|
]);
|
|
10938
|
-
var TaskCreativeVariantVideoPresetEnum =
|
|
11012
|
+
var TaskCreativeVariantVideoPresetEnum = z48.enum([
|
|
10939
11013
|
"auto",
|
|
10940
11014
|
"ugc_dynamic",
|
|
10941
11015
|
"ugc_how_to",
|
|
@@ -11006,7 +11080,7 @@ function resolveVideoPreset(preset) {
|
|
|
11006
11080
|
return VIDEO_PRESET_RESOLUTION[preset] ?? null;
|
|
11007
11081
|
}
|
|
11008
11082
|
__name(resolveVideoPreset, "resolveVideoPreset");
|
|
11009
|
-
var VideoTierEnum =
|
|
11083
|
+
var VideoTierEnum = z48.enum([
|
|
11010
11084
|
"basic"
|
|
11011
11085
|
]);
|
|
11012
11086
|
function resolveVideoTier(_tier) {
|
|
@@ -11021,17 +11095,17 @@ function resolveVideoFormatForDuration(durationSeconds) {
|
|
|
11021
11095
|
return durationSeconds === 30 ? "double_30s" : "single_15s";
|
|
11022
11096
|
}
|
|
11023
11097
|
__name(resolveVideoFormatForDuration, "resolveVideoFormatForDuration");
|
|
11024
|
-
var VideoResolutionEnum =
|
|
11098
|
+
var VideoResolutionEnum = z48.enum([
|
|
11025
11099
|
"480p",
|
|
11026
11100
|
"720p"
|
|
11027
11101
|
]);
|
|
11028
|
-
var VideoStyleEnum =
|
|
11102
|
+
var VideoStyleEnum = z48.enum([
|
|
11029
11103
|
"ugc",
|
|
11030
11104
|
"cartoon_3d",
|
|
11031
11105
|
"product_only",
|
|
11032
11106
|
"ai_dynamic"
|
|
11033
11107
|
]);
|
|
11034
|
-
var NarrativeStyleEnum =
|
|
11108
|
+
var NarrativeStyleEnum = z48.enum([
|
|
11035
11109
|
"review",
|
|
11036
11110
|
"ugc_how_to",
|
|
11037
11111
|
"problem_product_cta",
|
|
@@ -11048,7 +11122,7 @@ var NarrativeStyleEnum = z47.enum([
|
|
|
11048
11122
|
"ugc_skeptic_confession",
|
|
11049
11123
|
"ugc_demo_review"
|
|
11050
11124
|
]);
|
|
11051
|
-
var PublicNarrativeStyleEnum =
|
|
11125
|
+
var PublicNarrativeStyleEnum = z48.enum([
|
|
11052
11126
|
"review",
|
|
11053
11127
|
"ugc_how_to",
|
|
11054
11128
|
"ugc_unboxing_chaos",
|
|
@@ -11060,7 +11134,7 @@ var PublicNarrativeStyleEnum = z47.enum([
|
|
|
11060
11134
|
"animated_problem_pixar",
|
|
11061
11135
|
"sassy_product_pixar"
|
|
11062
11136
|
]);
|
|
11063
|
-
var VideoModelEnum =
|
|
11137
|
+
var VideoModelEnum = z48.enum([
|
|
11064
11138
|
"veo",
|
|
11065
11139
|
"wan",
|
|
11066
11140
|
"bytedance",
|
|
@@ -11068,29 +11142,29 @@ var VideoModelEnum = z47.enum([
|
|
|
11068
11142
|
"grok",
|
|
11069
11143
|
"kling"
|
|
11070
11144
|
]);
|
|
11071
|
-
var ProductReferenceUserChoiceEnum =
|
|
11145
|
+
var ProductReferenceUserChoiceEnum = z48.enum([
|
|
11072
11146
|
"same_product",
|
|
11073
11147
|
"variants",
|
|
11074
11148
|
"different_products",
|
|
11075
11149
|
"combo_distinct"
|
|
11076
11150
|
]);
|
|
11077
|
-
var ProductReferenceCandidateGroupingEnum =
|
|
11151
|
+
var ProductReferenceCandidateGroupingEnum = z48.enum([
|
|
11078
11152
|
"same_product_same_variant",
|
|
11079
11153
|
"same_product_different_variants",
|
|
11080
11154
|
"different_products",
|
|
11081
11155
|
"unclear"
|
|
11082
11156
|
]);
|
|
11083
|
-
var ProductReferenceScopeEnum =
|
|
11157
|
+
var ProductReferenceScopeEnum = z48.enum([
|
|
11084
11158
|
"base",
|
|
11085
11159
|
"video_view_pack"
|
|
11086
11160
|
]);
|
|
11087
|
-
var ProductReferenceResolutionDecisionEnum =
|
|
11161
|
+
var ProductReferenceResolutionDecisionEnum = z48.enum([
|
|
11088
11162
|
"approve",
|
|
11089
11163
|
"reject",
|
|
11090
11164
|
"observed_only",
|
|
11091
11165
|
"correct_view"
|
|
11092
11166
|
]);
|
|
11093
|
-
var ProductReferenceRejectionReasonEnum =
|
|
11167
|
+
var ProductReferenceRejectionReasonEnum = z48.enum([
|
|
11094
11168
|
"replacement_requested",
|
|
11095
11169
|
"wrong_product_identity",
|
|
11096
11170
|
"wrong_variant",
|
|
@@ -11101,13 +11175,13 @@ var ProductReferenceRejectionReasonEnum = z47.enum([
|
|
|
11101
11175
|
"not_a_product_photo",
|
|
11102
11176
|
"other"
|
|
11103
11177
|
]);
|
|
11104
|
-
var GapDurationChoiceMirror =
|
|
11105
|
-
angleIndex:
|
|
11106
|
-
recommendedSec:
|
|
11107
|
-
|
|
11108
|
-
|
|
11178
|
+
var GapDurationChoiceMirror = z48.object({
|
|
11179
|
+
angleIndex: z48.number().int().nonnegative(),
|
|
11180
|
+
recommendedSec: z48.union([
|
|
11181
|
+
z48.literal(15),
|
|
11182
|
+
z48.literal(30)
|
|
11109
11183
|
]),
|
|
11110
|
-
estimatedDeltaCredits:
|
|
11184
|
+
estimatedDeltaCredits: z48.number().int().nonnegative().optional()
|
|
11111
11185
|
});
|
|
11112
11186
|
function buildSelectedImageUrlsHash(urls) {
|
|
11113
11187
|
const input = [
|
|
@@ -11117,13 +11191,13 @@ function buildSelectedImageUrlsHash(urls) {
|
|
|
11117
11191
|
return `fnv1a:${hash.toString(16).padStart(8, "0")}:${urls.length}`;
|
|
11118
11192
|
}
|
|
11119
11193
|
__name(buildSelectedImageUrlsHash, "buildSelectedImageUrlsHash");
|
|
11120
|
-
var ImageCreativeStyleEnum =
|
|
11194
|
+
var ImageCreativeStyleEnum = z48.enum([
|
|
11121
11195
|
"studio",
|
|
11122
11196
|
"floating",
|
|
11123
11197
|
"ingredients",
|
|
11124
11198
|
"in_use"
|
|
11125
11199
|
]);
|
|
11126
|
-
var ImageCreativeArchetypeEnum =
|
|
11200
|
+
var ImageCreativeArchetypeEnum = z48.enum([
|
|
11127
11201
|
"direct_response_product_ad",
|
|
11128
11202
|
"hero_outcome",
|
|
11129
11203
|
"offer_value_prop",
|
|
@@ -11132,20 +11206,20 @@ var ImageCreativeArchetypeEnum = z47.enum([
|
|
|
11132
11206
|
"problem_solution",
|
|
11133
11207
|
"lifestyle_identity"
|
|
11134
11208
|
]);
|
|
11135
|
-
var ImageCreativeVisualTreatmentEnum =
|
|
11209
|
+
var ImageCreativeVisualTreatmentEnum = z48.enum([
|
|
11136
11210
|
"performance_product_ad",
|
|
11137
11211
|
"premium_dtc_carousel"
|
|
11138
11212
|
]);
|
|
11139
|
-
var ImageCreativeAspectRatioEnum =
|
|
11213
|
+
var ImageCreativeAspectRatioEnum = z48.enum([
|
|
11140
11214
|
"1:1",
|
|
11141
11215
|
"4:5",
|
|
11142
11216
|
"9:16",
|
|
11143
11217
|
"16:9"
|
|
11144
11218
|
]);
|
|
11145
|
-
var ImageRefSchema =
|
|
11146
|
-
url:
|
|
11147
|
-
path:
|
|
11148
|
-
assetId:
|
|
11219
|
+
var ImageRefSchema = z48.object({
|
|
11220
|
+
url: z48.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.'),
|
|
11221
|
+
path: z48.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`.'),
|
|
11222
|
+
assetId: z48.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.")
|
|
11149
11223
|
}).refine((v) => [
|
|
11150
11224
|
v.url,
|
|
11151
11225
|
v.path,
|
|
@@ -11153,11 +11227,11 @@ var ImageRefSchema = z47.object({
|
|
|
11153
11227
|
].filter(Boolean).length === 1, {
|
|
11154
11228
|
message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
|
|
11155
11229
|
});
|
|
11156
|
-
var ImagesInput =
|
|
11230
|
+
var ImagesInput = z48.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
|
|
11157
11231
|
const assetCount = images.filter((image) => Boolean(image.assetId)).length;
|
|
11158
11232
|
if (assetCount > 0 && assetCount !== images.length) {
|
|
11159
11233
|
ctx.addIssue({
|
|
11160
|
-
code:
|
|
11234
|
+
code: z48.ZodIssueCode.custom,
|
|
11161
11235
|
message: "all image entries must use assetId, or all must use URL/path sources"
|
|
11162
11236
|
});
|
|
11163
11237
|
}
|
|
@@ -11227,14 +11301,14 @@ async function submitCreative(api, opts) {
|
|
|
11227
11301
|
});
|
|
11228
11302
|
}
|
|
11229
11303
|
__name(submitCreative, "submitCreative");
|
|
11230
|
-
var ResearchTargetCountryEnum =
|
|
11304
|
+
var ResearchTargetCountryEnum = z48.enum([
|
|
11231
11305
|
"CO",
|
|
11232
11306
|
"MX",
|
|
11233
11307
|
"PE",
|
|
11234
11308
|
"EC",
|
|
11235
11309
|
"CL"
|
|
11236
11310
|
]);
|
|
11237
|
-
var ResearchCategoryEnum =
|
|
11311
|
+
var ResearchCategoryEnum = z48.enum([
|
|
11238
11312
|
"auto",
|
|
11239
11313
|
"automotive",
|
|
11240
11314
|
"kitchen",
|
|
@@ -11935,54 +12009,54 @@ function renderOutputsMarkdown(outputs) {
|
|
|
11935
12009
|
__name(renderOutputsMarkdown, "renderOutputsMarkdown");
|
|
11936
12010
|
|
|
11937
12011
|
// src/tools/tasks.ts
|
|
11938
|
-
var CreateProductTaskInput =
|
|
12012
|
+
var CreateProductTaskInput = z49.object({
|
|
11939
12013
|
images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
|
|
11940
|
-
projectId:
|
|
11941
|
-
productUrl:
|
|
12014
|
+
projectId: z49.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
|
|
12015
|
+
productUrl: z49.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."),
|
|
11942
12016
|
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.'),
|
|
11943
12017
|
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.'),
|
|
11944
|
-
price:
|
|
11945
|
-
compareAtPrice:
|
|
11946
|
-
offer:
|
|
11947
|
-
paymentMethods:
|
|
11948
|
-
productContext:
|
|
11949
|
-
productLabel:
|
|
12018
|
+
price: z49.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.'),
|
|
12019
|
+
compareAtPrice: z49.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".'),
|
|
12020
|
+
offer: z49.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.'),
|
|
12021
|
+
paymentMethods: z49.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.'),
|
|
12022
|
+
productContext: z49.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."),
|
|
12023
|
+
productLabel: z49.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.'),
|
|
11950
12024
|
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.'),
|
|
11951
|
-
durationSeconds:
|
|
11952
|
-
|
|
11953
|
-
|
|
12025
|
+
durationSeconds: z49.union([
|
|
12026
|
+
z49.literal(15),
|
|
12027
|
+
z49.literal(30)
|
|
11954
12028
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
11955
|
-
pauseForAngleReview:
|
|
11956
|
-
aiDecidesAll:
|
|
12029
|
+
pauseForAngleReview: z49.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."),
|
|
12030
|
+
aiDecidesAll: z49.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."),
|
|
11957
12031
|
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.'),
|
|
11958
12032
|
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).'),
|
|
11959
|
-
multiAngleVideos:
|
|
12033
|
+
multiAngleVideos: z49.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."),
|
|
11960
12034
|
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.'),
|
|
11961
|
-
outputs:
|
|
12035
|
+
outputs: z49.array(z49.enum([
|
|
11962
12036
|
"landing",
|
|
11963
12037
|
"video",
|
|
11964
12038
|
"image"
|
|
11965
12039
|
])).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.'),
|
|
11966
|
-
competitorScanEnabled:
|
|
11967
|
-
brandId:
|
|
11968
|
-
actorId:
|
|
11969
|
-
creativeDirection:
|
|
11970
|
-
headline:
|
|
11971
|
-
subheadline:
|
|
12040
|
+
competitorScanEnabled: z49.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."),
|
|
12041
|
+
brandId: z49.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."),
|
|
12042
|
+
actorId: z49.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."),
|
|
12043
|
+
creativeDirection: z49.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.'),
|
|
12044
|
+
headline: z49.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."),
|
|
12045
|
+
subheadline: z49.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."),
|
|
11972
12046
|
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".'),
|
|
11973
12047
|
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".')
|
|
11974
12048
|
}).strict();
|
|
11975
|
-
var CreateServiceVideoInput =
|
|
11976
|
-
landingUrl:
|
|
11977
|
-
additionalContext:
|
|
12049
|
+
var CreateServiceVideoInput = z49.object({
|
|
12050
|
+
landingUrl: z49.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
|
|
12051
|
+
additionalContext: z49.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
|
|
11978
12052
|
language: Lang.describe("Idioma del video: es, en o pt."),
|
|
11979
|
-
voiceId:
|
|
11980
|
-
brandId:
|
|
11981
|
-
reviewMode:
|
|
12053
|
+
voiceId: z49.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.'),
|
|
12054
|
+
brandId: z49.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
|
|
12055
|
+
reviewMode: z49.enum([
|
|
11982
12056
|
"automatic",
|
|
11983
12057
|
"guided"
|
|
11984
12058
|
]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
|
|
11985
|
-
videoPreset:
|
|
12059
|
+
videoPreset: z49.enum([
|
|
11986
12060
|
"auto",
|
|
11987
12061
|
"ugc_dynamic",
|
|
11988
12062
|
"ugc_how_to",
|
|
@@ -11990,51 +12064,51 @@ var CreateServiceVideoInput = z48.object({
|
|
|
11990
12064
|
"wild_card"
|
|
11991
12065
|
]).default("auto")
|
|
11992
12066
|
}).strict();
|
|
11993
|
-
var GetTaskStatusInput =
|
|
11994
|
-
taskId:
|
|
11995
|
-
waitSeconds:
|
|
11996
|
-
});
|
|
11997
|
-
var ListTasksInput =
|
|
11998
|
-
limit:
|
|
11999
|
-
offset:
|
|
12000
|
-
search:
|
|
12001
|
-
});
|
|
12002
|
-
var EditTaskDraftInput =
|
|
12003
|
-
taskId:
|
|
12004
|
-
angleIndex:
|
|
12005
|
-
angle:
|
|
12006
|
-
angle:
|
|
12007
|
-
buyerPersona:
|
|
12008
|
-
actor:
|
|
12009
|
-
actorId:
|
|
12010
|
-
gender:
|
|
12067
|
+
var GetTaskStatusInput = z49.object({
|
|
12068
|
+
taskId: z49.string().min(1),
|
|
12069
|
+
waitSeconds: z49.number().int().min(0).max(120).optional()
|
|
12070
|
+
});
|
|
12071
|
+
var ListTasksInput = z49.object({
|
|
12072
|
+
limit: z49.number().int().min(1).max(50).optional(),
|
|
12073
|
+
offset: z49.number().int().min(0).optional(),
|
|
12074
|
+
search: z49.string().optional()
|
|
12075
|
+
});
|
|
12076
|
+
var EditTaskDraftInput = z49.object({
|
|
12077
|
+
taskId: z49.string().min(1),
|
|
12078
|
+
angleIndex: z49.number().int().min(0),
|
|
12079
|
+
angle: z49.object({
|
|
12080
|
+
angle: z49.string().min(1).max(480),
|
|
12081
|
+
buyerPersona: z49.string().min(1).max(360),
|
|
12082
|
+
actor: z49.string().min(1).max(360).optional(),
|
|
12083
|
+
actorId: z49.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."),
|
|
12084
|
+
gender: z49.enum([
|
|
12011
12085
|
"female",
|
|
12012
12086
|
"male"
|
|
12013
12087
|
]).optional(),
|
|
12014
|
-
scriptNotes:
|
|
12088
|
+
scriptNotes: z49.string().max(2e3).optional()
|
|
12015
12089
|
})
|
|
12016
12090
|
});
|
|
12017
|
-
var PendingActionPayload =
|
|
12018
|
-
|
|
12019
|
-
kind:
|
|
12091
|
+
var PendingActionPayload = z49.discriminatedUnion("kind", [
|
|
12092
|
+
z49.object({
|
|
12093
|
+
kind: z49.literal("product_reference_set_approval"),
|
|
12020
12094
|
scope: ProductReferenceScopeEnum,
|
|
12021
|
-
scopeKey:
|
|
12022
|
-
scopeSnapshotId:
|
|
12023
|
-
expectedScopeHash:
|
|
12095
|
+
scopeKey: z49.string().min(1).max(120),
|
|
12096
|
+
scopeSnapshotId: z49.string().uuid(),
|
|
12097
|
+
expectedScopeHash: z49.string().min(1).max(128),
|
|
12024
12098
|
decision: ProductReferenceResolutionDecisionEnum,
|
|
12025
12099
|
reason: ProductReferenceRejectionReasonEnum.optional(),
|
|
12026
|
-
affectedRefKeys:
|
|
12027
|
-
recoveryAction:
|
|
12100
|
+
affectedRefKeys: z49.array(z49.string().min(1).max(200)).min(1).optional(),
|
|
12101
|
+
recoveryAction: z49.enum([
|
|
12028
12102
|
"remove",
|
|
12029
12103
|
"replace",
|
|
12030
12104
|
"upload",
|
|
12031
12105
|
"return_to_selection"
|
|
12032
12106
|
]).optional()
|
|
12033
12107
|
}),
|
|
12034
|
-
|
|
12035
|
-
kind:
|
|
12108
|
+
z49.object({
|
|
12109
|
+
kind: z49.literal("product_reference_confirmation"),
|
|
12036
12110
|
userChoice: ProductReferenceUserChoiceEnum.optional(),
|
|
12037
|
-
confirmedProductNames:
|
|
12111
|
+
confirmedProductNames: z49.array(z49.string().min(1).max(120)).min(2).max(8).optional(),
|
|
12038
12112
|
// SCOPED multi-scene opt-in — the ONLY way STANDARD ("Multiescena") is
|
|
12039
12113
|
// reachable via MCP. Valid ONLY together with userChoice='variants' (same
|
|
12040
12114
|
// product in several colors): renders one shot per color and stitches them,
|
|
@@ -12045,50 +12119,50 @@ var PendingActionPayload = z48.discriminatedUnion("kind", [
|
|
|
12045
12119
|
// safe because multi-scene IS the intended render for a color variant set,
|
|
12046
12120
|
// not a blind quality upsell. Maps to `videoTier: 'standard'` on the
|
|
12047
12121
|
// confirm call; the backend re-gates it (variants + variant_set only).
|
|
12048
|
-
useMultiSceneShowcase:
|
|
12122
|
+
useMultiSceneShowcase: z49.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".')
|
|
12049
12123
|
}),
|
|
12050
|
-
|
|
12051
|
-
kind:
|
|
12124
|
+
z49.object({
|
|
12125
|
+
kind: z49.literal("angle_review_approval"),
|
|
12052
12126
|
// All edits are optional — empty action body just approves the
|
|
12053
12127
|
// backend-generated draft as-is. Field shapes mirror the angle-review
|
|
12054
12128
|
// request contracts in @packages/types/wizard.ts; the handler routes to
|
|
12055
12129
|
// the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
|
|
12056
|
-
customAngle:
|
|
12130
|
+
customAngle: z49.string().min(1).max(480).optional(),
|
|
12057
12131
|
// Keep the shared MCP action within the strictest downstream contract:
|
|
12058
12132
|
// autopilot/image resume endpoints cap these fields at 1500 characters.
|
|
12059
|
-
painPoints:
|
|
12060
|
-
benefits:
|
|
12061
|
-
features:
|
|
12062
|
-
gapDurationSeconds:
|
|
12063
|
-
|
|
12064
|
-
|
|
12133
|
+
painPoints: z49.string().max(1500).optional(),
|
|
12134
|
+
benefits: z49.string().max(1500).optional(),
|
|
12135
|
+
features: z49.array(z49.string().min(1).max(300)).max(10).optional(),
|
|
12136
|
+
gapDurationSeconds: z49.union([
|
|
12137
|
+
z49.literal(15),
|
|
12138
|
+
z49.literal(30)
|
|
12065
12139
|
]).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.")
|
|
12066
12140
|
}),
|
|
12067
|
-
|
|
12068
|
-
kind:
|
|
12069
|
-
angleId:
|
|
12070
|
-
content:
|
|
12071
|
-
creativeDirection:
|
|
12072
|
-
actor:
|
|
12141
|
+
z49.object({
|
|
12142
|
+
kind: z49.literal("service_angle_approval"),
|
|
12143
|
+
angleId: z49.string().uuid(),
|
|
12144
|
+
content: z49.string().min(1).max(480).optional(),
|
|
12145
|
+
creativeDirection: z49.string().min(1).max(1500).optional(),
|
|
12146
|
+
actor: z49.string().min(1).max(360).optional()
|
|
12073
12147
|
}),
|
|
12074
|
-
|
|
12075
|
-
kind:
|
|
12076
|
-
voiceovers:
|
|
12077
|
-
visualDirections:
|
|
12148
|
+
z49.object({
|
|
12149
|
+
kind: z49.literal("service_script_approval"),
|
|
12150
|
+
voiceovers: z49.record(z49.string(), z49.string().min(1).max(600)).optional(),
|
|
12151
|
+
visualDirections: z49.record(z49.string(), z49.string().min(1).max(1200)).optional()
|
|
12078
12152
|
})
|
|
12079
12153
|
]);
|
|
12080
|
-
var ResolvePendingActionInput =
|
|
12081
|
-
taskId:
|
|
12154
|
+
var ResolvePendingActionInput = z49.object({
|
|
12155
|
+
taskId: z49.string().min(1),
|
|
12082
12156
|
action: PendingActionPayload
|
|
12083
12157
|
}).strict();
|
|
12084
12158
|
function resolveVariantConfirmVideoTier(action) {
|
|
12085
12159
|
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
12086
12160
|
}
|
|
12087
12161
|
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
12088
|
-
var StatusForResolveSchema =
|
|
12162
|
+
var StatusForResolveSchema = z49.object({
|
|
12089
12163
|
// Metadata used to select the backend resume contract. Older API responses
|
|
12090
12164
|
// may omit these fields, so the resolver keeps the generic fallback.
|
|
12091
|
-
kind:
|
|
12165
|
+
kind: z49.enum([
|
|
12092
12166
|
"autopilot",
|
|
12093
12167
|
"video",
|
|
12094
12168
|
"image",
|
|
@@ -12096,24 +12170,24 @@ var StatusForResolveSchema = z48.object({
|
|
|
12096
12170
|
"mix",
|
|
12097
12171
|
"service"
|
|
12098
12172
|
]).optional(),
|
|
12099
|
-
selectedOutputs:
|
|
12173
|
+
selectedOutputs: z49.array(z49.enum([
|
|
12100
12174
|
"landing",
|
|
12101
12175
|
"video",
|
|
12102
12176
|
"image"
|
|
12103
12177
|
])).optional(),
|
|
12104
|
-
videoAngleCount:
|
|
12105
|
-
ugcFormat:
|
|
12178
|
+
videoAngleCount: z49.number().int().min(1).max(3).optional(),
|
|
12179
|
+
ugcFormat: z49.enum([
|
|
12106
12180
|
"single_8s",
|
|
12107
12181
|
"single_15s",
|
|
12108
12182
|
"double_30s"
|
|
12109
12183
|
]).optional(),
|
|
12110
|
-
videoStyle:
|
|
12184
|
+
videoStyle: z49.enum([
|
|
12111
12185
|
"ugc",
|
|
12112
12186
|
"cartoon_3d",
|
|
12113
12187
|
"product_only",
|
|
12114
12188
|
"ai_dynamic"
|
|
12115
12189
|
]).optional(),
|
|
12116
|
-
videoModel:
|
|
12190
|
+
videoModel: z49.enum([
|
|
12117
12191
|
"veo",
|
|
12118
12192
|
"wan",
|
|
12119
12193
|
"bytedance",
|
|
@@ -12121,62 +12195,62 @@ var StatusForResolveSchema = z48.object({
|
|
|
12121
12195
|
"grok",
|
|
12122
12196
|
"kling"
|
|
12123
12197
|
]).optional(),
|
|
12124
|
-
videoTier:
|
|
12198
|
+
videoTier: z49.enum([
|
|
12125
12199
|
"legacy",
|
|
12126
12200
|
"standard",
|
|
12127
12201
|
"pro",
|
|
12128
12202
|
"single_call"
|
|
12129
12203
|
]).optional(),
|
|
12130
|
-
videoResolution:
|
|
12204
|
+
videoResolution: z49.enum([
|
|
12131
12205
|
"480p",
|
|
12132
12206
|
"720p"
|
|
12133
12207
|
]).optional(),
|
|
12134
12208
|
narrativeStyle: NarrativeStyleEnum.optional(),
|
|
12135
|
-
pendingUserAction:
|
|
12136
|
-
kind:
|
|
12137
|
-
candidateGrouping:
|
|
12138
|
-
selectedImageUrls:
|
|
12139
|
-
proposedProductNames:
|
|
12209
|
+
pendingUserAction: z49.object({
|
|
12210
|
+
kind: z49.string(),
|
|
12211
|
+
candidateGrouping: z49.string().optional(),
|
|
12212
|
+
selectedImageUrls: z49.array(z49.string()).optional(),
|
|
12213
|
+
proposedProductNames: z49.array(z49.string()).optional(),
|
|
12140
12214
|
// Adaptive reference questions are server-owned. Echo only the evidence
|
|
12141
12215
|
// identity and the choices shown by the current snapshot; never accept a
|
|
12142
12216
|
// client-supplied reference set as authorization.
|
|
12143
|
-
options:
|
|
12144
|
-
mode:
|
|
12217
|
+
options: z49.array(ProductReferenceUserChoiceEnum).max(4).optional(),
|
|
12218
|
+
mode: z49.enum([
|
|
12145
12219
|
"question",
|
|
12146
12220
|
"visual_recovery"
|
|
12147
12221
|
]).optional(),
|
|
12148
|
-
decisionKey:
|
|
12149
|
-
questionOrdinal:
|
|
12150
|
-
questionCeiling:
|
|
12151
|
-
|
|
12152
|
-
|
|
12222
|
+
decisionKey: z49.string().optional(),
|
|
12223
|
+
questionOrdinal: z49.number().int().min(1).max(5).optional(),
|
|
12224
|
+
questionCeiling: z49.union([
|
|
12225
|
+
z49.literal(3),
|
|
12226
|
+
z49.literal(5)
|
|
12153
12227
|
]).optional(),
|
|
12154
|
-
referenceEvidenceVersion:
|
|
12155
|
-
expectedEvidenceHash:
|
|
12156
|
-
question:
|
|
12157
|
-
prompt:
|
|
12158
|
-
helpText:
|
|
12159
|
-
options:
|
|
12228
|
+
referenceEvidenceVersion: z49.number().int().positive().optional(),
|
|
12229
|
+
expectedEvidenceHash: z49.string().optional(),
|
|
12230
|
+
question: z49.object({
|
|
12231
|
+
prompt: z49.string().min(1).max(240),
|
|
12232
|
+
helpText: z49.string().min(1).max(300).optional(),
|
|
12233
|
+
options: z49.array(z49.object({
|
|
12160
12234
|
value: ProductReferenceUserChoiceEnum,
|
|
12161
|
-
label:
|
|
12162
|
-
description:
|
|
12235
|
+
label: z49.string().min(1).max(120),
|
|
12236
|
+
description: z49.string().min(1).max(240).optional()
|
|
12163
12237
|
})).min(2).max(4)
|
|
12164
12238
|
}).optional(),
|
|
12165
12239
|
scope: ProductReferenceScopeEnum.optional(),
|
|
12166
|
-
scopeKey:
|
|
12167
|
-
scopeSnapshotId:
|
|
12168
|
-
scopeHash:
|
|
12169
|
-
baseReferenceSetHash:
|
|
12170
|
-
phase:
|
|
12240
|
+
scopeKey: z49.string().optional(),
|
|
12241
|
+
scopeSnapshotId: z49.string().uuid().optional(),
|
|
12242
|
+
scopeHash: z49.string().optional(),
|
|
12243
|
+
baseReferenceSetHash: z49.string().optional(),
|
|
12244
|
+
phase: z49.enum([
|
|
12171
12245
|
"preparation",
|
|
12172
12246
|
"final"
|
|
12173
12247
|
]).optional(),
|
|
12174
|
-
selectedRefKeys:
|
|
12175
|
-
allowedDecisions:
|
|
12176
|
-
customAngleDraft:
|
|
12177
|
-
painPointsDraft:
|
|
12178
|
-
benefitsDraft:
|
|
12179
|
-
featuresDraft:
|
|
12248
|
+
selectedRefKeys: z49.array(z49.string().min(1).max(200)).optional(),
|
|
12249
|
+
allowedDecisions: z49.array(ProductReferenceResolutionDecisionEnum).optional(),
|
|
12250
|
+
customAngleDraft: z49.string().optional(),
|
|
12251
|
+
painPointsDraft: z49.string().optional(),
|
|
12252
|
+
benefitsDraft: z49.string().optional(),
|
|
12253
|
+
featuresDraft: z49.array(z49.string()).optional(),
|
|
12180
12254
|
// Recommendation consumed only when the caller explicitly sends
|
|
12181
12255
|
// gapDurationSeconds: 30 in the angle approval action.
|
|
12182
12256
|
gapDurationChoice: GapDurationChoiceMirror.optional(),
|
|
@@ -12185,17 +12259,17 @@ var StatusForResolveSchema = z48.object({
|
|
|
12185
12259
|
// keys. `actorId` (the saved custom actor the picker stored) was silently
|
|
12186
12260
|
// dropped here, so the approval handler below could not echo it back on the
|
|
12187
12261
|
// PATCH — the selection looked accepted and reached no render.
|
|
12188
|
-
angles:
|
|
12189
|
-
id:
|
|
12190
|
-
content:
|
|
12191
|
-
creativeDirection:
|
|
12192
|
-
actor:
|
|
12193
|
-
actorId:
|
|
12262
|
+
angles: z49.array(z49.object({
|
|
12263
|
+
id: z49.string().uuid(),
|
|
12264
|
+
content: z49.string(),
|
|
12265
|
+
creativeDirection: z49.string(),
|
|
12266
|
+
actor: z49.string(),
|
|
12267
|
+
actorId: z49.string().nullable().optional()
|
|
12194
12268
|
}).passthrough()).optional(),
|
|
12195
|
-
panels:
|
|
12196
|
-
beatId:
|
|
12197
|
-
voiceover:
|
|
12198
|
-
visualDirection:
|
|
12269
|
+
panels: z49.array(z49.object({
|
|
12270
|
+
beatId: z49.string(),
|
|
12271
|
+
voiceover: z49.string(),
|
|
12272
|
+
visualDirection: z49.string()
|
|
12199
12273
|
}).passthrough()).optional()
|
|
12200
12274
|
}).optional()
|
|
12201
12275
|
}).passthrough();
|
|
@@ -12708,59 +12782,59 @@ __name(registerTaskTools, "registerTaskTools");
|
|
|
12708
12782
|
|
|
12709
12783
|
// src/tools/creatives.ts
|
|
12710
12784
|
import { randomUUID } from "crypto";
|
|
12711
|
-
import { z as
|
|
12785
|
+
import { z as z50 } from "zod";
|
|
12712
12786
|
var CreativeRefs = {
|
|
12713
12787
|
images: ImagesInput,
|
|
12714
12788
|
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.'),
|
|
12715
12789
|
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.'),
|
|
12716
|
-
price:
|
|
12717
|
-
offer:
|
|
12718
|
-
compareAtPrice:
|
|
12719
|
-
paymentMethods:
|
|
12720
|
-
productContext:
|
|
12721
|
-
productLabel:
|
|
12722
|
-
buyerPersona:
|
|
12723
|
-
isCombo:
|
|
12724
|
-
competitorScanEnabled:
|
|
12725
|
-
brandId:
|
|
12726
|
-
projectId:
|
|
12727
|
-
creativeDirection:
|
|
12728
|
-
headline:
|
|
12729
|
-
subheadline:
|
|
12790
|
+
price: z50.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.'),
|
|
12791
|
+
offer: z50.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.'),
|
|
12792
|
+
compareAtPrice: z50.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
|
|
12793
|
+
paymentMethods: z50.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.'),
|
|
12794
|
+
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."),
|
|
12795
|
+
productLabel: z50.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.'),
|
|
12796
|
+
buyerPersona: z50.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.'),
|
|
12797
|
+
isCombo: z50.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
|
|
12798
|
+
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."),
|
|
12799
|
+
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 el creativo."),
|
|
12800
|
+
projectId: z50.string().uuid().optional().describe("Opcional. ID de un proyecto guiado de dropshipping activo del usuario. Enlaza esta generaci\xF3n con su progreso y recompensas."),
|
|
12801
|
+
creativeDirection: z50.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.'),
|
|
12802
|
+
headline: z50.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."),
|
|
12803
|
+
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.")
|
|
12730
12804
|
};
|
|
12731
|
-
var VideoInput =
|
|
12805
|
+
var VideoInput = z50.object({
|
|
12732
12806
|
images: CreativeRefs.images,
|
|
12733
|
-
title:
|
|
12734
|
-
primaryAngle:
|
|
12807
|
+
title: z50.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
|
|
12808
|
+
primaryAngle: z50.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".'),
|
|
12735
12809
|
language: CreativeRefs.language,
|
|
12736
12810
|
country: CreativeRefs.country,
|
|
12737
|
-
aspectRatio:
|
|
12811
|
+
aspectRatio: z50.enum([
|
|
12738
12812
|
"9:16",
|
|
12739
12813
|
"16:9",
|
|
12740
12814
|
"Auto"
|
|
12741
12815
|
]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
|
|
12742
|
-
durationSeconds:
|
|
12743
|
-
|
|
12744
|
-
|
|
12816
|
+
durationSeconds: z50.union([
|
|
12817
|
+
z50.literal(15),
|
|
12818
|
+
z50.literal(30)
|
|
12745
12819
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
12746
12820
|
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).'),
|
|
12747
12821
|
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.'),
|
|
12748
12822
|
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).'),
|
|
12749
|
-
features:
|
|
12823
|
+
features: z50.array(z50.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
|
|
12750
12824
|
price: CreativeRefs.price,
|
|
12751
12825
|
offer: CreativeRefs.offer,
|
|
12752
12826
|
productContext: CreativeRefs.productContext,
|
|
12753
12827
|
productLabel: CreativeRefs.productLabel,
|
|
12754
|
-
cta:
|
|
12755
|
-
scriptNotes:
|
|
12756
|
-
pauseForVideoScriptReview:
|
|
12757
|
-
pauseForAngleReview:
|
|
12758
|
-
aiDecidesAll:
|
|
12828
|
+
cta: z50.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.'),
|
|
12829
|
+
scriptNotes: z50.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.'),
|
|
12830
|
+
pauseForVideoScriptReview: z50.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."),
|
|
12831
|
+
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. Default false."),
|
|
12832
|
+
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. Act\xEDvalo \xFAnicamente cuando el usuario pida expl\xEDcitamente que la IA decida todo o que no le pregunten m\xE1s. Default false."),
|
|
12759
12833
|
competitorScanEnabled: CreativeRefs.competitorScanEnabled,
|
|
12760
12834
|
brandId: CreativeRefs.brandId,
|
|
12761
12835
|
projectId: CreativeRefs.projectId
|
|
12762
12836
|
}).strict();
|
|
12763
|
-
var FreeVideoQualityEnum =
|
|
12837
|
+
var FreeVideoQualityEnum = z50.enum([
|
|
12764
12838
|
"economical",
|
|
12765
12839
|
"high_detail"
|
|
12766
12840
|
]);
|
|
@@ -12782,38 +12856,38 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
|
|
|
12782
12856
|
15
|
|
12783
12857
|
]
|
|
12784
12858
|
};
|
|
12785
|
-
var FreeVideoInput =
|
|
12859
|
+
var FreeVideoInput = z50.object({
|
|
12786
12860
|
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."),
|
|
12787
|
-
rawPrompt:
|
|
12861
|
+
rawPrompt: z50.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."),
|
|
12788
12862
|
quality: FreeVideoQualityEnum.describe('Calidad del video: "economical" = Econ\xF3mico o "high_detail" = Alto detalle.'),
|
|
12789
|
-
durationSeconds:
|
|
12863
|
+
durationSeconds: z50.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."),
|
|
12790
12864
|
videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
|
|
12791
|
-
generateAiMusic:
|
|
12792
|
-
addSubtitles:
|
|
12793
|
-
idempotencyKey:
|
|
12865
|
+
generateAiMusic: z50.boolean().default(false).describe("Opcional. Agrega m\xFAsica instrumental IA debajo del audio nativo. Default false."),
|
|
12866
|
+
addSubtitles: z50.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
|
|
12867
|
+
idempotencyKey: z50.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.")
|
|
12794
12868
|
}).strict();
|
|
12795
12869
|
var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
|
|
12796
12870
|
var archetypeList = ImageCreativeArchetypeEnum.options.join(" | ");
|
|
12797
12871
|
var visualTreatmentList = ImageCreativeVisualTreatmentEnum.options.join(" | ");
|
|
12798
12872
|
var aspectRatioList = ImageCreativeAspectRatioEnum.options.join(" | ");
|
|
12799
|
-
var ImageInput =
|
|
12873
|
+
var ImageInput = z50.object({
|
|
12800
12874
|
images: CreativeRefs.images,
|
|
12801
|
-
productTitle:
|
|
12802
|
-
primaryAngle:
|
|
12875
|
+
productTitle: z50.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
|
|
12876
|
+
primaryAngle: z50.string().min(1).describe('\xC1ngulo de venta principal. Ej. "Reduce arrugas en 14 d\xEDas".'),
|
|
12803
12877
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
12804
12878
|
language: CreativeRefs.language,
|
|
12805
12879
|
country: CreativeRefs.country,
|
|
12806
|
-
nVariants:
|
|
12807
|
-
imageModel:
|
|
12880
|
+
nVariants: z50.number().int().min(1).max(6).optional().describe("Opcional. N\xFAmero de variantes a generar (1-6). Default 3."),
|
|
12881
|
+
imageModel: z50.string().optional().describe('Opcional. Modelo de imagen. Ej. "gpt-image-2", "nano-banana-2". Om\xEDtelo para usar el default optimizado por costo/calidad.'),
|
|
12808
12882
|
imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
|
|
12809
12883
|
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).`),
|
|
12810
12884
|
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.`),
|
|
12811
|
-
styleMix:
|
|
12885
|
+
styleMix: z50.boolean().optional().describe("Opcional. Si true, las N variantes mezclan distintos imageStyle para A/B test. Si false/omitido, todas comparten estilo. Default false."),
|
|
12812
12886
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe(`Opcional. Relaci\xF3n de aspecto. Valores: ${aspectRatioList}. Default "4:5" (vertical Instagram feed).`),
|
|
12813
|
-
generateAdCopy:
|
|
12814
|
-
pauseForAngleReview:
|
|
12815
|
-
features:
|
|
12816
|
-
brandColors:
|
|
12887
|
+
generateAdCopy: z50.boolean().optional().describe("Opcional. Si true, tambi\xE9n genera headline/body/CTA para el ad. Default false."),
|
|
12888
|
+
pauseForAngleReview: z50.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."),
|
|
12889
|
+
features: z50.array(z50.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
|
|
12890
|
+
brandColors: z50.array(z50.string()).optional().describe('Opcional. Paleta de marca en hex. Ej. ["#FF6B35", "#004E89"]. Si se omite, la IA elige seg\xFAn el producto.'),
|
|
12817
12891
|
price: CreativeRefs.price,
|
|
12818
12892
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
12819
12893
|
offer: CreativeRefs.offer,
|
|
@@ -12827,17 +12901,17 @@ var ImageInput = z49.object({
|
|
|
12827
12901
|
headline: CreativeRefs.headline,
|
|
12828
12902
|
subheadline: CreativeRefs.subheadline
|
|
12829
12903
|
});
|
|
12830
|
-
var EditImageCreativeInput =
|
|
12831
|
-
taskId:
|
|
12832
|
-
variantIndex:
|
|
12833
|
-
instruction:
|
|
12904
|
+
var EditImageCreativeInput = z50.object({
|
|
12905
|
+
taskId: z50.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
|
|
12906
|
+
variantIndex: z50.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
|
|
12907
|
+
instruction: z50.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".')
|
|
12834
12908
|
});
|
|
12835
|
-
var LandingInput =
|
|
12836
|
-
aiDecidesAll:
|
|
12909
|
+
var LandingInput = z50.object({
|
|
12910
|
+
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. Act\xEDvalo \xFAnicamente cuando el usuario pida expl\xEDcitamente que la IA decida todo o que no le pregunten m\xE1s. Default false."),
|
|
12837
12911
|
images: CreativeRefs.images,
|
|
12838
12912
|
language: CreativeRefs.language,
|
|
12839
12913
|
country: CreativeRefs.country,
|
|
12840
|
-
salesAngle:
|
|
12914
|
+
salesAngle: z50.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.'),
|
|
12841
12915
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
12842
12916
|
price: CreativeRefs.price,
|
|
12843
12917
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
@@ -12852,6 +12926,7 @@ var LandingInput = z49.object({
|
|
|
12852
12926
|
creativeDirection: CreativeRefs.creativeDirection,
|
|
12853
12927
|
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".'),
|
|
12854
12928
|
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".'),
|
|
12929
|
+
pauseForAngleReview: z50.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."),
|
|
12855
12930
|
headline: CreativeRefs.headline,
|
|
12856
12931
|
subheadline: CreativeRefs.subheadline
|
|
12857
12932
|
});
|
|
@@ -12962,8 +13037,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
12962
13037
|
__name(registerCreativeTools, "registerCreativeTools");
|
|
12963
13038
|
|
|
12964
13039
|
// src/tools/creative-variants.ts
|
|
12965
|
-
import { z as
|
|
12966
|
-
var LandingSectionKeyEnum =
|
|
13040
|
+
import { z as z51 } from "zod";
|
|
13041
|
+
var LandingSectionKeyEnum = z51.enum([
|
|
12967
13042
|
"problem_hook",
|
|
12968
13043
|
"problem_cost",
|
|
12969
13044
|
"solution_mechanism",
|
|
@@ -13003,24 +13078,24 @@ var LandingSectionKeyEnum = z50.enum([
|
|
|
13003
13078
|
"lifestyle_fit",
|
|
13004
13079
|
"join_lifestyle"
|
|
13005
13080
|
]);
|
|
13006
|
-
var CreativeVariantKindEnum =
|
|
13081
|
+
var CreativeVariantKindEnum = z51.enum([
|
|
13007
13082
|
"video",
|
|
13008
13083
|
"image",
|
|
13009
13084
|
"landing"
|
|
13010
13085
|
]);
|
|
13011
|
-
var EstimateCreativeVariantInputBase =
|
|
13012
|
-
sourceTaskId:
|
|
13086
|
+
var EstimateCreativeVariantInputBase = z51.object({
|
|
13087
|
+
sourceTaskId: z51.string().uuid().describe("ID de la tarea original completada."),
|
|
13013
13088
|
kind: CreativeVariantKindEnum,
|
|
13014
13089
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
|
|
13015
13090
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
|
|
13016
|
-
nVariants:
|
|
13091
|
+
nVariants: z51.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
13017
13092
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
|
|
13018
|
-
instructions:
|
|
13093
|
+
instructions: z51.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.")
|
|
13019
13094
|
}).strict();
|
|
13020
13095
|
var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
13021
13096
|
if (input.kind === "video" && input.nVariants !== void 0) {
|
|
13022
13097
|
ctx.addIssue({
|
|
13023
|
-
code:
|
|
13098
|
+
code: z51.ZodIssueCode.custom,
|
|
13024
13099
|
path: [
|
|
13025
13100
|
"nVariants"
|
|
13026
13101
|
],
|
|
@@ -13030,7 +13105,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
13030
13105
|
if (input.kind !== "video") {
|
|
13031
13106
|
if (input.videoPreset !== void 0) {
|
|
13032
13107
|
ctx.addIssue({
|
|
13033
|
-
code:
|
|
13108
|
+
code: z51.ZodIssueCode.custom,
|
|
13034
13109
|
path: [
|
|
13035
13110
|
"videoPreset"
|
|
13036
13111
|
],
|
|
@@ -13039,7 +13114,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
13039
13114
|
}
|
|
13040
13115
|
if (input.videoResolution !== void 0) {
|
|
13041
13116
|
ctx.addIssue({
|
|
13042
|
-
code:
|
|
13117
|
+
code: z51.ZodIssueCode.custom,
|
|
13043
13118
|
path: [
|
|
13044
13119
|
"videoResolution"
|
|
13045
13120
|
],
|
|
@@ -13049,7 +13124,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
13049
13124
|
}
|
|
13050
13125
|
if (input.kind !== "image" && input.nVariants !== void 0) {
|
|
13051
13126
|
ctx.addIssue({
|
|
13052
|
-
code:
|
|
13127
|
+
code: z51.ZodIssueCode.custom,
|
|
13053
13128
|
path: [
|
|
13054
13129
|
"nVariants"
|
|
13055
13130
|
],
|
|
@@ -13059,7 +13134,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
13059
13134
|
if (input.kind !== "landing") {
|
|
13060
13135
|
if (input.sectionKey !== void 0) {
|
|
13061
13136
|
ctx.addIssue({
|
|
13062
|
-
code:
|
|
13137
|
+
code: z51.ZodIssueCode.custom,
|
|
13063
13138
|
path: [
|
|
13064
13139
|
"sectionKey"
|
|
13065
13140
|
],
|
|
@@ -13068,7 +13143,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
13068
13143
|
}
|
|
13069
13144
|
if (input.instructions !== void 0) {
|
|
13070
13145
|
ctx.addIssue({
|
|
13071
|
-
code:
|
|
13146
|
+
code: z51.ZodIssueCode.custom,
|
|
13072
13147
|
path: [
|
|
13073
13148
|
"instructions"
|
|
13074
13149
|
],
|
|
@@ -13077,31 +13152,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
13077
13152
|
}
|
|
13078
13153
|
}
|
|
13079
13154
|
});
|
|
13080
|
-
var CreateCreativeVariantInputBase =
|
|
13081
|
-
sourceTaskId:
|
|
13155
|
+
var CreateCreativeVariantInputBase = z51.object({
|
|
13156
|
+
sourceTaskId: z51.string().uuid().describe("ID de la tarea original completada."),
|
|
13082
13157
|
kind: CreativeVariantKindEnum,
|
|
13083
|
-
confirm:
|
|
13084
|
-
clientRequestId:
|
|
13085
|
-
angle:
|
|
13086
|
-
buyerPersona:
|
|
13087
|
-
scriptNotes:
|
|
13088
|
-
creativeDirection:
|
|
13158
|
+
confirm: z51.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
|
|
13159
|
+
clientRequestId: z51.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."),
|
|
13160
|
+
angle: z51.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
|
|
13161
|
+
buyerPersona: z51.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
|
|
13162
|
+
scriptNotes: z51.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
|
|
13163
|
+
creativeDirection: z51.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
|
|
13089
13164
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
|
|
13090
13165
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
|
|
13091
|
-
generateAiMusic:
|
|
13092
|
-
nVariants:
|
|
13166
|
+
generateAiMusic: z51.boolean().optional().describe("Opcional para video."),
|
|
13167
|
+
nVariants: z51.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
13093
13168
|
imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
|
|
13094
13169
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
|
|
13095
13170
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
|
|
13096
13171
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
|
|
13097
|
-
styleMix:
|
|
13172
|
+
styleMix: z51.boolean().optional().describe("Opcional para imagen."),
|
|
13098
13173
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
|
|
13099
|
-
instructions:
|
|
13174
|
+
instructions: z51.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.")
|
|
13100
13175
|
}).strict();
|
|
13101
13176
|
var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
13102
13177
|
if ((input.kind === "video" || input.kind === "image") && !input.angle) {
|
|
13103
13178
|
ctx.addIssue({
|
|
13104
|
-
code:
|
|
13179
|
+
code: z51.ZodIssueCode.custom,
|
|
13105
13180
|
path: [
|
|
13106
13181
|
"angle"
|
|
13107
13182
|
],
|
|
@@ -13110,7 +13185,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
13110
13185
|
}
|
|
13111
13186
|
if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
|
|
13112
13187
|
ctx.addIssue({
|
|
13113
|
-
code:
|
|
13188
|
+
code: z51.ZodIssueCode.custom,
|
|
13114
13189
|
path: [
|
|
13115
13190
|
"instructions"
|
|
13116
13191
|
],
|
|
@@ -13156,7 +13231,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
13156
13231
|
for (const field of fieldsByKind[input.kind]) {
|
|
13157
13232
|
if (input[field] !== void 0) {
|
|
13158
13233
|
ctx.addIssue({
|
|
13159
|
-
code:
|
|
13234
|
+
code: z51.ZodIssueCode.custom,
|
|
13160
13235
|
path: [
|
|
13161
13236
|
field
|
|
13162
13237
|
],
|
|
@@ -13273,27 +13348,27 @@ function registerCreativeVariantTools(server, api) {
|
|
|
13273
13348
|
__name(registerCreativeVariantTools, "registerCreativeVariantTools");
|
|
13274
13349
|
|
|
13275
13350
|
// src/tools/script-review.ts
|
|
13276
|
-
import { z as
|
|
13277
|
-
var GetVideoScriptInput =
|
|
13278
|
-
taskId:
|
|
13279
|
-
angleKey:
|
|
13351
|
+
import { z as z52 } from "zod";
|
|
13352
|
+
var GetVideoScriptInput = z52.object({
|
|
13353
|
+
taskId: z52.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
|
|
13354
|
+
angleKey: z52.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.')
|
|
13280
13355
|
}).strict();
|
|
13281
13356
|
var VIDEO_SCRIPT_APPROVAL_MAX_SCENES2 = 50;
|
|
13282
13357
|
var VIDEO_SCRIPT_APPROVAL_MAX_DIALOGUE_CHARS2 = 2e3;
|
|
13283
|
-
var ApproveSceneEdit =
|
|
13284
|
-
index:
|
|
13285
|
-
dialogue:
|
|
13358
|
+
var ApproveSceneEdit = z52.object({
|
|
13359
|
+
index: z52.number().int().nonnegative().describe("\xCDndice de la escena (0-based, mismo que devuelve get_video_script)."),
|
|
13360
|
+
dialogue: z52.string().min(1).max(VIDEO_SCRIPT_APPROVAL_MAX_DIALOGUE_CHARS2).refine((v) => v.trim().length > 0, {
|
|
13286
13361
|
message: "dialogue no puede ser s\xF3lo espacios"
|
|
13287
13362
|
}).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.")
|
|
13288
13363
|
}).strict();
|
|
13289
|
-
var ApproveVideoScriptInput =
|
|
13290
|
-
taskId:
|
|
13291
|
-
angleKey:
|
|
13292
|
-
scenes:
|
|
13364
|
+
var ApproveVideoScriptInput = z52.object({
|
|
13365
|
+
taskId: z52.string().min(1).describe("ID de la tarea."),
|
|
13366
|
+
angleKey: z52.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.'),
|
|
13367
|
+
scenes: z52.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.")
|
|
13293
13368
|
}).strict();
|
|
13294
|
-
var RegenerateVideoScriptInput =
|
|
13295
|
-
taskId:
|
|
13296
|
-
angleKey:
|
|
13369
|
+
var RegenerateVideoScriptInput = z52.object({
|
|
13370
|
+
taskId: z52.string().min(1).describe("ID de la tarea."),
|
|
13371
|
+
angleKey: z52.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.'),
|
|
13297
13372
|
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).')
|
|
13298
13373
|
}).strict();
|
|
13299
13374
|
function registerScriptReviewTools(server, api) {
|
|
@@ -13344,9 +13419,9 @@ function registerScriptReviewTools(server, api) {
|
|
|
13344
13419
|
__name(registerScriptReviewTools, "registerScriptReviewTools");
|
|
13345
13420
|
|
|
13346
13421
|
// src/tools/connections.ts
|
|
13347
|
-
import { z as
|
|
13422
|
+
import { z as z53 } from "zod";
|
|
13348
13423
|
function registerConnectionTools(server, api) {
|
|
13349
|
-
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.",
|
|
13424
|
+
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.", z53.object({}).shape, READS_INTERNAL, async () => {
|
|
13350
13425
|
try {
|
|
13351
13426
|
const r = await api.getJson("/v1/shopify/shops");
|
|
13352
13427
|
return asText(r);
|
|
@@ -13354,10 +13429,10 @@ function registerConnectionTools(server, api) {
|
|
|
13354
13429
|
throw translateError(e);
|
|
13355
13430
|
}
|
|
13356
13431
|
});
|
|
13357
|
-
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.',
|
|
13358
|
-
shopDomain:
|
|
13359
|
-
query:
|
|
13360
|
-
taskId:
|
|
13432
|
+
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.', z53.object({
|
|
13433
|
+
shopDomain: z53.string().min(3).max(120),
|
|
13434
|
+
query: z53.string().trim().max(120).optional(),
|
|
13435
|
+
taskId: z53.string().uuid().optional()
|
|
13361
13436
|
}).shape, READS_EXTERNAL, async ({ shopDomain, query, taskId }) => {
|
|
13362
13437
|
try {
|
|
13363
13438
|
const params = new URLSearchParams({
|
|
@@ -13371,7 +13446,7 @@ function registerConnectionTools(server, api) {
|
|
|
13371
13446
|
throw translateError(e);
|
|
13372
13447
|
}
|
|
13373
13448
|
});
|
|
13374
|
-
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.",
|
|
13449
|
+
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.", z53.object({}).shape, READS_EXTERNAL, async () => {
|
|
13375
13450
|
try {
|
|
13376
13451
|
const r = await api.getJson("/v1/facebook/ad-accounts");
|
|
13377
13452
|
return asText(r);
|
|
@@ -13381,7 +13456,7 @@ function registerConnectionTools(server, api) {
|
|
|
13381
13456
|
});
|
|
13382
13457
|
server.registerTool("list_meta_destinations", {
|
|
13383
13458
|
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.",
|
|
13384
|
-
inputSchema:
|
|
13459
|
+
inputSchema: z53.object({}).shape,
|
|
13385
13460
|
annotations: READS_EXTERNAL,
|
|
13386
13461
|
_meta: {
|
|
13387
13462
|
"openai/widgetAccessible": true
|
|
@@ -13394,7 +13469,7 @@ function registerConnectionTools(server, api) {
|
|
|
13394
13469
|
throw translateError(e);
|
|
13395
13470
|
}
|
|
13396
13471
|
});
|
|
13397
|
-
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.",
|
|
13472
|
+
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.", z53.object({}).shape, READS_EXTERNAL, async () => {
|
|
13398
13473
|
try {
|
|
13399
13474
|
const r = await api.getJson("/v1/tiktok/advertisers");
|
|
13400
13475
|
return asText(r);
|
|
@@ -13406,9 +13481,9 @@ function registerConnectionTools(server, api) {
|
|
|
13406
13481
|
__name(registerConnectionTools, "registerConnectionTools");
|
|
13407
13482
|
|
|
13408
13483
|
// src/tools/actors.ts
|
|
13409
|
-
import { z as
|
|
13484
|
+
import { z as z54 } from "zod";
|
|
13410
13485
|
function registerActorTools(server, api) {
|
|
13411
|
-
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.",
|
|
13486
|
+
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.", z54.object({}).shape, READS_INTERNAL, async () => {
|
|
13412
13487
|
try {
|
|
13413
13488
|
const rows = await api.getJson("/v1/actors");
|
|
13414
13489
|
const actors = (Array.isArray(rows) ? rows : []).filter((actor) => actor.status === "ready").map(({ id, name, description, gender, voiceId }) => ({
|
|
@@ -13429,39 +13504,39 @@ function registerActorTools(server, api) {
|
|
|
13429
13504
|
__name(registerActorTools, "registerActorTools");
|
|
13430
13505
|
|
|
13431
13506
|
// src/tools/publish.ts
|
|
13432
|
-
import { z as
|
|
13433
|
-
var ShopifyInput =
|
|
13434
|
-
taskId:
|
|
13435
|
-
shopDomain:
|
|
13507
|
+
import { z as z55 } from "zod";
|
|
13508
|
+
var ShopifyInput = z55.object({
|
|
13509
|
+
taskId: z55.string().min(1),
|
|
13510
|
+
shopDomain: z55.string().min(1),
|
|
13436
13511
|
/** Override: number of landing images to include. Default = ALL images the
|
|
13437
13512
|
* task generated (the MCP fetches /v1/results first to count). Bounded
|
|
13438
13513
|
* generously here; the backend validates each index against
|
|
13439
13514
|
* landing.images.length and rejects out-of-range. */
|
|
13440
|
-
numLandingImages:
|
|
13441
|
-
variantIndex:
|
|
13515
|
+
numLandingImages: z55.number().int().min(1).max(20).optional(),
|
|
13516
|
+
variantIndex: z55.number().int().min(0).optional(),
|
|
13442
13517
|
/** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
|
|
13443
13518
|
* When true, the landing renders variant-picker pills; when false, it ships
|
|
13444
13519
|
* a single-option product page. Defaults to false. */
|
|
13445
|
-
showVariantPicker:
|
|
13520
|
+
showVariantPicker: z55.boolean().optional(),
|
|
13446
13521
|
/** Default `auto` updates the product previously published for this task and
|
|
13447
13522
|
* shop. Use `existing` with targetProductId to choose another product, or
|
|
13448
13523
|
* `new` only when the user explicitly wants a duplicate/new listing. */
|
|
13449
|
-
publicationMode:
|
|
13524
|
+
publicationMode: z55.enum([
|
|
13450
13525
|
"auto",
|
|
13451
13526
|
"existing",
|
|
13452
13527
|
"new"
|
|
13453
13528
|
]).optional(),
|
|
13454
13529
|
/** Shopify product GID, numeric id, or admin product URL. Required when
|
|
13455
13530
|
* publicationMode is `existing`. */
|
|
13456
|
-
targetProductId:
|
|
13531
|
+
targetProductId: z55.string().trim().min(1).max(300).optional(),
|
|
13457
13532
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
13458
|
-
announcementBarEnabled:
|
|
13459
|
-
announcementBarText:
|
|
13533
|
+
announcementBarEnabled: z55.boolean().optional(),
|
|
13534
|
+
announcementBarText: z55.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional()
|
|
13460
13535
|
});
|
|
13461
13536
|
var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
|
|
13462
13537
|
if (value.announcementBarEnabled && !value.announcementBarText) {
|
|
13463
13538
|
ctx.addIssue({
|
|
13464
|
-
code:
|
|
13539
|
+
code: z55.ZodIssueCode.custom,
|
|
13465
13540
|
path: [
|
|
13466
13541
|
"announcementBarText"
|
|
13467
13542
|
],
|
|
@@ -13470,7 +13545,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
13470
13545
|
}
|
|
13471
13546
|
if (!value.announcementBarEnabled && value.announcementBarText) {
|
|
13472
13547
|
ctx.addIssue({
|
|
13473
|
-
code:
|
|
13548
|
+
code: z55.ZodIssueCode.custom,
|
|
13474
13549
|
path: [
|
|
13475
13550
|
"announcementBarText"
|
|
13476
13551
|
],
|
|
@@ -13484,90 +13559,90 @@ function parseShopifyInput(rawInput) {
|
|
|
13484
13559
|
return parsed.data;
|
|
13485
13560
|
}
|
|
13486
13561
|
__name(parseShopifyInput, "parseShopifyInput");
|
|
13487
|
-
var McpCampaignConfig =
|
|
13562
|
+
var McpCampaignConfig = z55.object({
|
|
13488
13563
|
/** ALWAYS in US dollars, whatever the ad account's currency is. ProductMaker
|
|
13489
13564
|
* converts to the account currency server-side. Do NOT pre-convert: on a COP
|
|
13490
13565
|
* account the user's "60.000 al día" is `dailyBudgetUsd: 15`, not 60000. */
|
|
13491
|
-
dailyBudgetUsd:
|
|
13566
|
+
dailyBudgetUsd: z55.number().positive().optional(),
|
|
13492
13567
|
/** ISO-3166-1 alpha-2 country codes. Meta accepts max 1 (single-country
|
|
13493
13568
|
* ad set). TikTok takes only the first entry. */
|
|
13494
|
-
targetCountries:
|
|
13495
|
-
campaignName:
|
|
13569
|
+
targetCountries: z55.array(z55.string().length(2)).max(1).optional(),
|
|
13570
|
+
campaignName: z55.string().trim().min(1).max(100).optional()
|
|
13496
13571
|
});
|
|
13497
13572
|
var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
|
|
13498
|
-
var MetaInput =
|
|
13499
|
-
taskId:
|
|
13573
|
+
var MetaInput = z55.object({
|
|
13574
|
+
taskId: z55.string().min(1),
|
|
13500
13575
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
13501
|
-
portfolioId:
|
|
13576
|
+
portfolioId: z55.string().trim().min(1),
|
|
13502
13577
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
13503
|
-
pageId:
|
|
13578
|
+
pageId: z55.string().trim().min(1),
|
|
13504
13579
|
adAccountId: McpAdAccountId,
|
|
13505
|
-
pixelId:
|
|
13506
|
-
landingUrl:
|
|
13580
|
+
pixelId: z55.string().min(1).optional(),
|
|
13581
|
+
landingUrl: z55.string().url().optional(),
|
|
13507
13582
|
/** Select which angles to publish by 0-based index. Omit to publish all
|
|
13508
13583
|
* successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
|
|
13509
|
-
angleIndexes:
|
|
13584
|
+
angleIndexes: z55.array(z55.number().int().nonnegative()).optional(),
|
|
13510
13585
|
campaignConfig: McpCampaignConfig.optional(),
|
|
13511
13586
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
13512
13587
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
13513
13588
|
* (Meta's primary-text limit). */
|
|
13514
|
-
primaryText:
|
|
13589
|
+
primaryText: z55.string().trim().min(1).max(500).optional(),
|
|
13515
13590
|
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
13516
13591
|
* (wa.me) instead of a landing page. */
|
|
13517
|
-
phoneNumber:
|
|
13592
|
+
phoneNumber: z55.string().min(8).max(32).optional()
|
|
13518
13593
|
});
|
|
13519
|
-
var GroupedTaskSource =
|
|
13520
|
-
type:
|
|
13521
|
-
taskId:
|
|
13522
|
-
angleIndex:
|
|
13523
|
-
videoVariant:
|
|
13594
|
+
var GroupedTaskSource = z55.object({
|
|
13595
|
+
type: z55.literal("task"),
|
|
13596
|
+
taskId: z55.string().min(1),
|
|
13597
|
+
angleIndex: z55.number().int().min(0).optional(),
|
|
13598
|
+
videoVariant: z55.enum([
|
|
13524
13599
|
"with_subtitles",
|
|
13525
13600
|
"without_subtitles"
|
|
13526
13601
|
]).optional(),
|
|
13527
|
-
imageVariantIndex:
|
|
13528
|
-
});
|
|
13529
|
-
var GroupedMediaSource =
|
|
13530
|
-
type:
|
|
13531
|
-
url:
|
|
13532
|
-
path:
|
|
13533
|
-
thumbnailUrl:
|
|
13534
|
-
thumbnailPath:
|
|
13602
|
+
imageVariantIndex: z55.number().int().min(0).optional()
|
|
13603
|
+
});
|
|
13604
|
+
var GroupedMediaSource = z55.object({
|
|
13605
|
+
type: z55.literal("media"),
|
|
13606
|
+
url: z55.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
|
|
13607
|
+
path: z55.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".'),
|
|
13608
|
+
thumbnailUrl: z55.string().url().optional(),
|
|
13609
|
+
thumbnailPath: z55.string().min(1).optional()
|
|
13535
13610
|
}).refine((value) => Boolean(value.url) !== Boolean(value.path), {
|
|
13536
13611
|
message: "media source needs exactly one of `url` or `path`"
|
|
13537
13612
|
}).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
|
|
13538
13613
|
message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
|
|
13539
13614
|
});
|
|
13540
|
-
var GroupedUploadedAssetSource =
|
|
13541
|
-
type:
|
|
13615
|
+
var GroupedUploadedAssetSource = z55.object({
|
|
13616
|
+
type: z55.literal("asset"),
|
|
13542
13617
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
13543
|
-
assetId:
|
|
13544
|
-
thumbnailAssetId:
|
|
13618
|
+
assetId: z55.string().uuid(),
|
|
13619
|
+
thumbnailAssetId: z55.string().uuid().optional()
|
|
13545
13620
|
});
|
|
13546
|
-
var GroupedCreative =
|
|
13547
|
-
type:
|
|
13621
|
+
var GroupedCreative = z55.object({
|
|
13622
|
+
type: z55.enum([
|
|
13548
13623
|
"image",
|
|
13549
13624
|
"video"
|
|
13550
13625
|
]),
|
|
13551
|
-
source:
|
|
13626
|
+
source: z55.union([
|
|
13552
13627
|
GroupedTaskSource,
|
|
13553
13628
|
GroupedMediaSource,
|
|
13554
13629
|
GroupedUploadedAssetSource
|
|
13555
13630
|
]),
|
|
13556
|
-
title:
|
|
13557
|
-
description:
|
|
13631
|
+
title: z55.string().max(120).optional(),
|
|
13632
|
+
description: z55.string().max(500).optional(),
|
|
13558
13633
|
cta: MetaCtaType.optional(),
|
|
13559
|
-
creativeId:
|
|
13634
|
+
creativeId: z55.string().min(1).optional()
|
|
13560
13635
|
});
|
|
13561
|
-
var GroupedCampaignConfigBase =
|
|
13636
|
+
var GroupedCampaignConfigBase = z55.object({
|
|
13562
13637
|
campaignType: MetaCampaignType.default("sales"),
|
|
13563
13638
|
optimizationMode: MetaOptimizationMode.default("advantage_plus"),
|
|
13564
13639
|
budgetMode: MetaBudgetMode.optional(),
|
|
13565
|
-
campaignDailyBudget:
|
|
13566
|
-
adSets:
|
|
13567
|
-
tempId:
|
|
13568
|
-
name:
|
|
13569
|
-
dailyBudget:
|
|
13570
|
-
creativeIds:
|
|
13640
|
+
campaignDailyBudget: z55.number().int().positive().optional(),
|
|
13641
|
+
adSets: z55.array(z55.object({
|
|
13642
|
+
tempId: z55.string().min(1).max(80),
|
|
13643
|
+
name: z55.string().min(1).max(100),
|
|
13644
|
+
dailyBudget: z55.number().int().positive().optional(),
|
|
13645
|
+
creativeIds: z55.array(z55.string().min(1)).min(1)
|
|
13571
13646
|
})).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
|
|
13572
13647
|
/**
|
|
13573
13648
|
* Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
|
|
@@ -13575,17 +13650,17 @@ var GroupedCampaignConfigBase = z54.object({
|
|
|
13575
13650
|
* opaque `invalid_literal` and made the WhatsApp destination — supported by
|
|
13576
13651
|
* the API since #849 — unreachable from this tool.
|
|
13577
13652
|
*/
|
|
13578
|
-
destination:
|
|
13579
|
-
|
|
13580
|
-
type:
|
|
13581
|
-
landingUrl:
|
|
13653
|
+
destination: z55.discriminatedUnion("type", [
|
|
13654
|
+
z55.object({
|
|
13655
|
+
type: z55.literal("landing"),
|
|
13656
|
+
landingUrl: z55.string().url()
|
|
13582
13657
|
}),
|
|
13583
|
-
|
|
13584
|
-
type:
|
|
13585
|
-
phoneNumber:
|
|
13658
|
+
z55.object({
|
|
13659
|
+
type: z55.literal("whatsapp"),
|
|
13660
|
+
phoneNumber: z55.string().min(8).max(32)
|
|
13586
13661
|
})
|
|
13587
13662
|
]),
|
|
13588
|
-
saveAsDefault:
|
|
13663
|
+
saveAsDefault: z55.boolean().default(false),
|
|
13589
13664
|
budgetPolicy: MetaBudgetPolicy.optional()
|
|
13590
13665
|
});
|
|
13591
13666
|
function resolveBudgetMode(value) {
|
|
@@ -13599,7 +13674,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
13599
13674
|
const budgetMode = resolveBudgetMode(value);
|
|
13600
13675
|
if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
|
|
13601
13676
|
ctx.addIssue({
|
|
13602
|
-
code:
|
|
13677
|
+
code: z55.ZodIssueCode.custom,
|
|
13603
13678
|
path: [
|
|
13604
13679
|
"campaignDailyBudget"
|
|
13605
13680
|
],
|
|
@@ -13610,7 +13685,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
13610
13685
|
value.adSets.forEach((adSet, index) => {
|
|
13611
13686
|
if (adSet.dailyBudget === void 0) {
|
|
13612
13687
|
ctx.addIssue({
|
|
13613
|
-
code:
|
|
13688
|
+
code: z55.ZodIssueCode.custom,
|
|
13614
13689
|
path: [
|
|
13615
13690
|
"adSets",
|
|
13616
13691
|
index,
|
|
@@ -13625,26 +13700,26 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
13625
13700
|
...value,
|
|
13626
13701
|
budgetMode: resolveBudgetMode(value)
|
|
13627
13702
|
}));
|
|
13628
|
-
var PublishCreativesToMetaInputBase =
|
|
13629
|
-
creatives:
|
|
13703
|
+
var PublishCreativesToMetaInputBase = z55.object({
|
|
13704
|
+
creatives: z55.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
|
|
13630
13705
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
13631
|
-
portfolioId:
|
|
13706
|
+
portfolioId: z55.string().trim().min(1),
|
|
13632
13707
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
13633
|
-
pageId:
|
|
13708
|
+
pageId: z55.string().trim().min(1),
|
|
13634
13709
|
adAccountId: McpAdAccountId,
|
|
13635
|
-
pixelId:
|
|
13710
|
+
pixelId: z55.string().min(1).optional(),
|
|
13636
13711
|
/** Required unless `campaignConfig.destination` is whatsapp — see the
|
|
13637
13712
|
* superRefine below. Mirrors the API's `UploadToMetaRequest`. */
|
|
13638
|
-
landingUrl:
|
|
13639
|
-
targetCountry:
|
|
13640
|
-
campaignName:
|
|
13713
|
+
landingUrl: z55.string().url().optional(),
|
|
13714
|
+
targetCountry: z55.string().length(2),
|
|
13715
|
+
campaignName: z55.string().trim().min(1).max(100),
|
|
13641
13716
|
campaignConfig: GroupedCampaignConfig.optional()
|
|
13642
13717
|
});
|
|
13643
13718
|
var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
|
|
13644
13719
|
const destination = value.campaignConfig?.destination;
|
|
13645
13720
|
if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl) {
|
|
13646
13721
|
ctx.addIssue({
|
|
13647
|
-
code:
|
|
13722
|
+
code: z55.ZodIssueCode.custom,
|
|
13648
13723
|
path: [
|
|
13649
13724
|
"landingUrl"
|
|
13650
13725
|
],
|
|
@@ -13653,7 +13728,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
13653
13728
|
}
|
|
13654
13729
|
if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
|
|
13655
13730
|
ctx.addIssue({
|
|
13656
|
-
code:
|
|
13731
|
+
code: z55.ZodIssueCode.custom,
|
|
13657
13732
|
path: [
|
|
13658
13733
|
"campaignConfig",
|
|
13659
13734
|
"destination",
|
|
@@ -13672,16 +13747,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
13672
13747
|
}
|
|
13673
13748
|
return value;
|
|
13674
13749
|
});
|
|
13675
|
-
var PresignUploadResponseSchema =
|
|
13676
|
-
uploadUrl:
|
|
13750
|
+
var PresignUploadResponseSchema = z55.object({
|
|
13751
|
+
uploadUrl: z55.string().url().refine((value) => {
|
|
13677
13752
|
const url = new URL(value);
|
|
13678
13753
|
return !url.username && !url.password && url.protocol === "https:";
|
|
13679
13754
|
}, "presigned upload URL must be HTTPS without embedded credentials"),
|
|
13680
|
-
publicUrl:
|
|
13755
|
+
publicUrl: z55.string().url().refine((value) => {
|
|
13681
13756
|
const url = new URL(value);
|
|
13682
13757
|
return !url.username && !url.password;
|
|
13683
13758
|
}, "public media URL must not contain embedded credentials"),
|
|
13684
|
-
stagingAssetId:
|
|
13759
|
+
stagingAssetId: z55.string().uuid()
|
|
13685
13760
|
});
|
|
13686
13761
|
async function uploadResolvedMedia(api, media, assetRole) {
|
|
13687
13762
|
if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
|
|
@@ -13706,16 +13781,16 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
|
|
|
13706
13781
|
return uploadResolvedMedia(api, media, assetRole);
|
|
13707
13782
|
}
|
|
13708
13783
|
__name(resolveAndUploadMedia, "resolveAndUploadMedia");
|
|
13709
|
-
var TikTokInput =
|
|
13710
|
-
taskId:
|
|
13711
|
-
advertiserId:
|
|
13712
|
-
pixelId:
|
|
13713
|
-
landingUrl:
|
|
13714
|
-
angleIndexes:
|
|
13784
|
+
var TikTokInput = z55.object({
|
|
13785
|
+
taskId: z55.string().min(1),
|
|
13786
|
+
advertiserId: z55.string().min(1),
|
|
13787
|
+
pixelId: z55.string().min(1).optional(),
|
|
13788
|
+
landingUrl: z55.string().url().optional(),
|
|
13789
|
+
angleIndexes: z55.array(z55.number().int().nonnegative()).optional(),
|
|
13715
13790
|
campaignConfig: McpCampaignConfig.optional(),
|
|
13716
13791
|
/** Override the ad's description (TikTok's body copy). If omitted,
|
|
13717
13792
|
* ProductMaker uses the auto-generated copy attached to the task. */
|
|
13718
|
-
primaryText:
|
|
13793
|
+
primaryText: z55.string().trim().min(1).max(500).optional()
|
|
13719
13794
|
});
|
|
13720
13795
|
function registerPublishTools(server, api, opts = {}) {
|
|
13721
13796
|
const transport = opts.transport ?? "http";
|
|
@@ -13965,38 +14040,38 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
|
|
|
13965
14040
|
|
|
13966
14041
|
// src/tools/meta-upload.ts
|
|
13967
14042
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
13968
|
-
import { z as
|
|
13969
|
-
var UploadSessionInputBase =
|
|
13970
|
-
mediaKind:
|
|
14043
|
+
import { z as z56 } from "zod";
|
|
14044
|
+
var UploadSessionInputBase = z56.object({
|
|
14045
|
+
mediaKind: z56.enum([
|
|
13971
14046
|
"image",
|
|
13972
14047
|
"video",
|
|
13973
14048
|
"mixed"
|
|
13974
14049
|
]).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."),
|
|
13975
|
-
assetRole:
|
|
14050
|
+
assetRole: z56.enum([
|
|
13976
14051
|
"media",
|
|
13977
14052
|
"thumbnail"
|
|
13978
14053
|
]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
|
|
13979
|
-
uploadPurpose:
|
|
14054
|
+
uploadPurpose: z56.enum([
|
|
13980
14055
|
"product_reference",
|
|
13981
14056
|
"creative",
|
|
13982
14057
|
"generic"
|
|
13983
14058
|
]).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."),
|
|
13984
|
-
maxFiles:
|
|
14059
|
+
maxFiles: z56.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
13985
14060
|
});
|
|
13986
|
-
var OpenAiFileReference =
|
|
13987
|
-
download_url:
|
|
13988
|
-
file_id:
|
|
13989
|
-
mime_type:
|
|
13990
|
-
file_name:
|
|
14061
|
+
var OpenAiFileReference = z56.object({
|
|
14062
|
+
download_url: z56.string().url().optional().describe("Optional host-provided download URL. The App prefers getFileDownloadUrl(file_id) and the server never fetches this URL."),
|
|
14063
|
+
file_id: z56.string().min(1),
|
|
14064
|
+
mime_type: z56.string().min(1).optional(),
|
|
14065
|
+
file_name: z56.string().min(1).optional()
|
|
13991
14066
|
});
|
|
13992
14067
|
var UploadSessionToolInputShape = {
|
|
13993
14068
|
...UploadSessionInputBase.shape,
|
|
13994
|
-
files:
|
|
14069
|
+
files: z56.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.")
|
|
13995
14070
|
};
|
|
13996
|
-
var UploadSessionToolInput =
|
|
14071
|
+
var UploadSessionToolInput = z56.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
13997
14072
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
13998
14073
|
ctx.addIssue({
|
|
13999
|
-
code:
|
|
14074
|
+
code: z56.ZodIssueCode.custom,
|
|
14000
14075
|
path: [
|
|
14001
14076
|
"mediaKind"
|
|
14002
14077
|
],
|
|
@@ -14005,7 +14080,7 @@ var UploadSessionToolInput = z55.object(UploadSessionToolInputShape).superRefine
|
|
|
14005
14080
|
}
|
|
14006
14081
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
14007
14082
|
ctx.addIssue({
|
|
14008
|
-
code:
|
|
14083
|
+
code: z56.ZodIssueCode.custom,
|
|
14009
14084
|
path: [
|
|
14010
14085
|
"maxFiles"
|
|
14011
14086
|
],
|
|
@@ -14014,7 +14089,7 @@ var UploadSessionToolInput = z55.object(UploadSessionToolInputShape).superRefine
|
|
|
14014
14089
|
}
|
|
14015
14090
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
|
|
14016
14091
|
ctx.addIssue({
|
|
14017
|
-
code:
|
|
14092
|
+
code: z56.ZodIssueCode.custom,
|
|
14018
14093
|
path: [
|
|
14019
14094
|
"maxFiles"
|
|
14020
14095
|
],
|
|
@@ -14022,38 +14097,38 @@ var UploadSessionToolInput = z55.object(UploadSessionToolInputShape).superRefine
|
|
|
14022
14097
|
});
|
|
14023
14098
|
}
|
|
14024
14099
|
});
|
|
14025
|
-
var UploadSessionResponse =
|
|
14026
|
-
sessionId:
|
|
14027
|
-
uploadPageUrl:
|
|
14028
|
-
mediaKind:
|
|
14100
|
+
var UploadSessionResponse = z56.object({
|
|
14101
|
+
sessionId: z56.string().uuid(),
|
|
14102
|
+
uploadPageUrl: z56.string().url(),
|
|
14103
|
+
mediaKind: z56.enum([
|
|
14029
14104
|
"image",
|
|
14030
14105
|
"video",
|
|
14031
14106
|
"mixed"
|
|
14032
14107
|
]),
|
|
14033
|
-
assetRole:
|
|
14108
|
+
assetRole: z56.enum([
|
|
14034
14109
|
"media",
|
|
14035
14110
|
"thumbnail"
|
|
14036
14111
|
]),
|
|
14037
|
-
maxFiles:
|
|
14038
|
-
expiresAt:
|
|
14112
|
+
maxFiles: z56.number().int().positive(),
|
|
14113
|
+
expiresAt: z56.string().datetime()
|
|
14039
14114
|
});
|
|
14040
|
-
var UploadStatusInput =
|
|
14041
|
-
sessionId:
|
|
14115
|
+
var UploadStatusInput = z56.object({
|
|
14116
|
+
sessionId: z56.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
14042
14117
|
});
|
|
14043
|
-
var UniversalUploadStatusResponse =
|
|
14044
|
-
|
|
14045
|
-
status:
|
|
14046
|
-
assets:
|
|
14118
|
+
var UniversalUploadStatusResponse = z56.discriminatedUnion("status", [
|
|
14119
|
+
z56.object({
|
|
14120
|
+
status: z56.literal("pending"),
|
|
14121
|
+
assets: z56.array(z56.never()).length(0)
|
|
14047
14122
|
}),
|
|
14048
|
-
|
|
14049
|
-
status:
|
|
14050
|
-
assets:
|
|
14051
|
-
assetId:
|
|
14052
|
-
mediaKind:
|
|
14123
|
+
z56.object({
|
|
14124
|
+
status: z56.literal("uploaded"),
|
|
14125
|
+
assets: z56.array(z56.object({
|
|
14126
|
+
assetId: z56.string().uuid(),
|
|
14127
|
+
mediaKind: z56.enum([
|
|
14053
14128
|
"image",
|
|
14054
14129
|
"video"
|
|
14055
14130
|
]),
|
|
14056
|
-
assetRole:
|
|
14131
|
+
assetRole: z56.enum([
|
|
14057
14132
|
"media",
|
|
14058
14133
|
"thumbnail"
|
|
14059
14134
|
])
|
|
@@ -14061,13 +14136,13 @@ var UniversalUploadStatusResponse = z55.discriminatedUnion("status", [
|
|
|
14061
14136
|
})
|
|
14062
14137
|
]);
|
|
14063
14138
|
var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
|
|
14064
|
-
uploadPurpose:
|
|
14139
|
+
uploadPurpose: z56.enum([
|
|
14065
14140
|
"product_reference",
|
|
14066
14141
|
"creative",
|
|
14067
14142
|
"generic"
|
|
14068
14143
|
]),
|
|
14069
|
-
checkToolName:
|
|
14070
|
-
resolveEndpoint:
|
|
14144
|
+
checkToolName: z56.literal("check_media_upload"),
|
|
14145
|
+
resolveEndpoint: z56.string().url()
|
|
14071
14146
|
});
|
|
14072
14147
|
function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
|
|
14073
14148
|
const url = new URL(uploadPageUrl);
|
|
@@ -14158,13 +14233,13 @@ function registerMediaUploadTools(server, api) {
|
|
|
14158
14233
|
__name(registerMediaUploadTools, "registerMediaUploadTools");
|
|
14159
14234
|
|
|
14160
14235
|
// src/tools/campaigns.ts
|
|
14161
|
-
import { z as
|
|
14162
|
-
var MetaStatusInput =
|
|
14163
|
-
campaignId:
|
|
14236
|
+
import { z as z57 } from "zod";
|
|
14237
|
+
var MetaStatusInput = z57.object({
|
|
14238
|
+
campaignId: z57.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
|
|
14164
14239
|
});
|
|
14165
|
-
var TikTokStatusInput =
|
|
14166
|
-
campaignId:
|
|
14167
|
-
advertiserId:
|
|
14240
|
+
var TikTokStatusInput = z57.object({
|
|
14241
|
+
campaignId: z57.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
|
|
14242
|
+
advertiserId: z57.string().min(1).describe("The same advertiserId used to publish the campaign.")
|
|
14168
14243
|
});
|
|
14169
14244
|
function registerCampaignTools(server, api) {
|
|
14170
14245
|
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) => {
|
|
@@ -14261,10 +14336,10 @@ function renderTikTokStatusMarkdown(r) {
|
|
|
14261
14336
|
__name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
|
|
14262
14337
|
|
|
14263
14338
|
// ../../packages/product-economics/src/product-costing.ts
|
|
14264
|
-
import { z as
|
|
14339
|
+
import { z as z59 } from "zod";
|
|
14265
14340
|
|
|
14266
14341
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
14267
|
-
import { z as
|
|
14342
|
+
import { z as z58 } from "zod";
|
|
14268
14343
|
|
|
14269
14344
|
// ../../packages/product-economics/src/product-costing-shipping-references.json
|
|
14270
14345
|
var product_costing_shipping_references_default = {
|
|
@@ -14328,21 +14403,21 @@ var product_costing_shipping_references_default = {
|
|
|
14328
14403
|
};
|
|
14329
14404
|
|
|
14330
14405
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
14331
|
-
var ShippingReferenceSchema =
|
|
14332
|
-
reference:
|
|
14333
|
-
min:
|
|
14334
|
-
max:
|
|
14335
|
-
updatedAt:
|
|
14336
|
-
confidence:
|
|
14406
|
+
var ShippingReferenceSchema = z58.object({
|
|
14407
|
+
reference: z58.number().positive(),
|
|
14408
|
+
min: z58.number().nonnegative(),
|
|
14409
|
+
max: z58.number().positive(),
|
|
14410
|
+
updatedAt: z58.string().date(),
|
|
14411
|
+
confidence: z58.enum([
|
|
14337
14412
|
"high",
|
|
14338
14413
|
"medium",
|
|
14339
14414
|
"medium-low"
|
|
14340
14415
|
]),
|
|
14341
|
-
sources:
|
|
14416
|
+
sources: z58.array(z58.string().url().startsWith("https://")).min(1).max(3)
|
|
14342
14417
|
}).superRefine(({ reference, min, max }, context) => {
|
|
14343
14418
|
if (min > reference || reference > max) {
|
|
14344
14419
|
context.addIssue({
|
|
14345
|
-
code:
|
|
14420
|
+
code: z58.ZodIssueCode.custom,
|
|
14346
14421
|
message: "shipping_reference_outside_range",
|
|
14347
14422
|
path: [
|
|
14348
14423
|
"reference"
|
|
@@ -14350,7 +14425,7 @@ var ShippingReferenceSchema = z57.object({
|
|
|
14350
14425
|
});
|
|
14351
14426
|
}
|
|
14352
14427
|
});
|
|
14353
|
-
var SHIPPING_REFERENCES =
|
|
14428
|
+
var SHIPPING_REFERENCES = z58.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
|
|
14354
14429
|
var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
|
|
14355
14430
|
var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
|
|
14356
14431
|
"MX",
|
|
@@ -14532,18 +14607,18 @@ function getProductCostingCountryName(country) {
|
|
|
14532
14607
|
__name(getProductCostingCountryName, "getProductCostingCountryName");
|
|
14533
14608
|
|
|
14534
14609
|
// ../../packages/product-economics/src/product-costing.ts
|
|
14535
|
-
var ProductCostingInputSchema =
|
|
14536
|
-
country:
|
|
14537
|
-
supplierCost:
|
|
14538
|
-
shippingCost:
|
|
14539
|
-
returnRate:
|
|
14540
|
-
cancellationRate:
|
|
14541
|
-
adsManagerCpa:
|
|
14542
|
-
desiredMargin:
|
|
14610
|
+
var ProductCostingInputSchema = z59.object({
|
|
14611
|
+
country: z59.string().refine(isProductCostingCountryCode, "unsupported_country"),
|
|
14612
|
+
supplierCost: z59.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
|
|
14613
|
+
shippingCost: z59.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
|
|
14614
|
+
returnRate: z59.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
14615
|
+
cancellationRate: z59.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
14616
|
+
adsManagerCpa: z59.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
|
|
14617
|
+
desiredMargin: z59.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
|
|
14543
14618
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
14544
14619
|
if (returnRate + cancellationRate >= 1) {
|
|
14545
14620
|
context.addIssue({
|
|
14546
|
-
code:
|
|
14621
|
+
code: z59.ZodIssueCode.custom,
|
|
14547
14622
|
message: "delivery_rate_positive",
|
|
14548
14623
|
path: [
|
|
14549
14624
|
"cancellationRate"
|
|
@@ -14610,14 +14685,14 @@ function calculateProductCosting(rawInput) {
|
|
|
14610
14685
|
__name(calculateProductCosting, "calculateProductCosting");
|
|
14611
14686
|
|
|
14612
14687
|
// src/tools/product-costing.ts
|
|
14613
|
-
import { z as
|
|
14614
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
14615
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
14616
|
-
var ProductCostingToolInput =
|
|
14617
|
-
country:
|
|
14688
|
+
import { z as z60 } from "zod";
|
|
14689
|
+
var optionalAmount = /* @__PURE__ */ __name((description) => z60.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
|
|
14690
|
+
var optionalPercent = /* @__PURE__ */ __name((description) => z60.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
|
|
14691
|
+
var ProductCostingToolInput = z60.object({
|
|
14692
|
+
country: z60.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
14618
14693
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
14619
14694
|
}).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
|
|
14620
|
-
supplierCost:
|
|
14695
|
+
supplierCost: z60.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."),
|
|
14621
14696
|
supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
|
|
14622
14697
|
shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
|
|
14623
14698
|
shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
|
|
@@ -14749,7 +14824,7 @@ function formatPercent(value) {
|
|
|
14749
14824
|
__name(formatPercent, "formatPercent");
|
|
14750
14825
|
|
|
14751
14826
|
// src/tools/product-research.ts
|
|
14752
|
-
import { z as
|
|
14827
|
+
import { z as z61 } from "zod";
|
|
14753
14828
|
|
|
14754
14829
|
// src/tools/product-research-idempotency.ts
|
|
14755
14830
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -14865,17 +14940,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
|
|
|
14865
14940
|
]);
|
|
14866
14941
|
var POLL_INTERVAL_MS = 5e3;
|
|
14867
14942
|
var MAX_WAIT_SECONDS = 120;
|
|
14868
|
-
var FindInput =
|
|
14943
|
+
var FindInput = z61.object({
|
|
14869
14944
|
targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
|
|
14870
14945
|
categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
|
|
14871
|
-
confirmed:
|
|
14872
|
-
waitSeconds:
|
|
14946
|
+
confirmed: z61.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
|
|
14947
|
+
waitSeconds: z61.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
|
|
14873
14948
|
});
|
|
14874
|
-
var GetInput =
|
|
14875
|
-
runId:
|
|
14949
|
+
var GetInput = z61.object({
|
|
14950
|
+
runId: z61.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
14876
14951
|
});
|
|
14877
|
-
var ListInput =
|
|
14878
|
-
limit:
|
|
14952
|
+
var ListInput = z61.object({
|
|
14953
|
+
limit: z61.number().int().min(1).max(20).default(10)
|
|
14879
14954
|
});
|
|
14880
14955
|
function textResult(text) {
|
|
14881
14956
|
return {
|
|
@@ -14967,14 +15042,14 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
14967
15042
|
__name(registerProductResearchTools, "registerProductResearchTools");
|
|
14968
15043
|
|
|
14969
15044
|
// src/tools/dropshipping-projects.ts
|
|
14970
|
-
import { z as
|
|
14971
|
-
var ProjectId =
|
|
14972
|
-
var DropshippingProjectStatus =
|
|
15045
|
+
import { z as z62 } from "zod";
|
|
15046
|
+
var ProjectId = z62.string().uuid();
|
|
15047
|
+
var DropshippingProjectStatus = z62.enum([
|
|
14973
15048
|
"active",
|
|
14974
15049
|
"completed",
|
|
14975
15050
|
"archived"
|
|
14976
15051
|
]);
|
|
14977
|
-
var DropshippingProjectPhase =
|
|
15052
|
+
var DropshippingProjectPhase = z62.enum([
|
|
14978
15053
|
"research",
|
|
14979
15054
|
"costing",
|
|
14980
15055
|
"media",
|
|
@@ -14983,21 +15058,21 @@ var DropshippingProjectPhase = z61.enum([
|
|
|
14983
15058
|
"advertising",
|
|
14984
15059
|
"complete"
|
|
14985
15060
|
]);
|
|
14986
|
-
var DropshippingRewardMilestone =
|
|
15061
|
+
var DropshippingRewardMilestone = z62.enum([
|
|
14987
15062
|
"product_selected",
|
|
14988
15063
|
"costing_saved",
|
|
14989
15064
|
"product_media_ready",
|
|
14990
15065
|
"creatives_completed",
|
|
14991
15066
|
"campaign_created"
|
|
14992
15067
|
]);
|
|
14993
|
-
var TargetCountry =
|
|
15068
|
+
var TargetCountry = z62.enum([
|
|
14994
15069
|
"CO",
|
|
14995
15070
|
"MX",
|
|
14996
15071
|
"PE",
|
|
14997
15072
|
"EC",
|
|
14998
15073
|
"CL"
|
|
14999
15074
|
]);
|
|
15000
|
-
var ResearchCategory =
|
|
15075
|
+
var ResearchCategory = z62.enum([
|
|
15001
15076
|
"auto",
|
|
15002
15077
|
"automotive",
|
|
15003
15078
|
"kitchen",
|
|
@@ -15012,7 +15087,7 @@ var ResearchCategory = z61.enum([
|
|
|
15012
15087
|
"garden",
|
|
15013
15088
|
"cleaning"
|
|
15014
15089
|
]);
|
|
15015
|
-
var HttpUrl3 =
|
|
15090
|
+
var HttpUrl3 = z62.string().url().max(2e3).refine((value) => {
|
|
15016
15091
|
try {
|
|
15017
15092
|
return [
|
|
15018
15093
|
"http:",
|
|
@@ -15022,43 +15097,43 @@ var HttpUrl3 = z61.string().url().max(2e3).refine((value) => {
|
|
|
15022
15097
|
return false;
|
|
15023
15098
|
}
|
|
15024
15099
|
}, "URL must use HTTP(S)");
|
|
15025
|
-
var ResearchCandidateOrigin =
|
|
15026
|
-
type:
|
|
15100
|
+
var ResearchCandidateOrigin = z62.object({
|
|
15101
|
+
type: z62.literal("research_candidate"),
|
|
15027
15102
|
runId: ProjectId,
|
|
15028
|
-
candidateSourceId:
|
|
15103
|
+
candidateSourceId: z62.string().min(1).max(160)
|
|
15029
15104
|
});
|
|
15030
|
-
var TaskOrigin =
|
|
15031
|
-
type:
|
|
15105
|
+
var TaskOrigin = z62.object({
|
|
15106
|
+
type: z62.literal("task"),
|
|
15032
15107
|
taskId: ProjectId
|
|
15033
15108
|
});
|
|
15034
|
-
var ManualOrigin =
|
|
15035
|
-
type:
|
|
15109
|
+
var ManualOrigin = z62.object({
|
|
15110
|
+
type: z62.literal("manual"),
|
|
15036
15111
|
clientRequestId: ProjectId,
|
|
15037
|
-
country:
|
|
15112
|
+
country: z62.string().min(2).max(3).optional()
|
|
15038
15113
|
});
|
|
15039
|
-
var StartProjectInput =
|
|
15040
|
-
origin:
|
|
15114
|
+
var StartProjectInput = z62.object({
|
|
15115
|
+
origin: z62.discriminatedUnion("type", [
|
|
15041
15116
|
ResearchCandidateOrigin,
|
|
15042
15117
|
TaskOrigin,
|
|
15043
15118
|
ManualOrigin
|
|
15044
15119
|
]),
|
|
15045
|
-
productName:
|
|
15120
|
+
productName: z62.string().trim().min(1).max(240).optional(),
|
|
15046
15121
|
productUrl: HttpUrl3.optional(),
|
|
15047
|
-
country:
|
|
15048
|
-
languageCode:
|
|
15122
|
+
country: z62.string().min(2).max(3).optional(),
|
|
15123
|
+
languageCode: z62.string().min(2).max(16).optional()
|
|
15049
15124
|
}).strict();
|
|
15050
|
-
var CostProjectInput =
|
|
15125
|
+
var CostProjectInput = z62.object({
|
|
15051
15126
|
projectId: ProjectId,
|
|
15052
|
-
version:
|
|
15053
|
-
country:
|
|
15054
|
-
supplierCost:
|
|
15055
|
-
shippingCost:
|
|
15056
|
-
returnRate:
|
|
15057
|
-
cancellationRate:
|
|
15058
|
-
adsManagerCpa:
|
|
15059
|
-
desiredMargin:
|
|
15060
|
-
});
|
|
15061
|
-
var GuideInput =
|
|
15127
|
+
version: z62.number().int().positive(),
|
|
15128
|
+
country: z62.string().trim().min(2).max(3),
|
|
15129
|
+
supplierCost: z62.number().finite().positive(),
|
|
15130
|
+
shippingCost: z62.number().finite().nonnegative(),
|
|
15131
|
+
returnRate: z62.number().finite().min(0).lt(1),
|
|
15132
|
+
cancellationRate: z62.number().finite().min(0).lt(1),
|
|
15133
|
+
adsManagerCpa: z62.number().finite().nonnegative(),
|
|
15134
|
+
desiredMargin: z62.number().finite().min(0).lt(1)
|
|
15135
|
+
});
|
|
15136
|
+
var GuideInput = z62.object({
|
|
15062
15137
|
projectId: ProjectId.optional()
|
|
15063
15138
|
}).strict();
|
|
15064
15139
|
var NEXT_ACTION_KINDS = [
|
|
@@ -15076,29 +15151,29 @@ var NEXT_ACTION_KINDS = [
|
|
|
15076
15151
|
"repair_meta_campaign",
|
|
15077
15152
|
"review_paused_campaign"
|
|
15078
15153
|
];
|
|
15079
|
-
var DropshippingProjectNextAction =
|
|
15080
|
-
kind:
|
|
15081
|
-
href:
|
|
15154
|
+
var DropshippingProjectNextAction = z62.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z62.object({
|
|
15155
|
+
kind: z62.literal(kind),
|
|
15156
|
+
href: z62.string().min(1)
|
|
15082
15157
|
})));
|
|
15083
|
-
var CostingInputSchema =
|
|
15084
|
-
country:
|
|
15085
|
-
supplierCost:
|
|
15086
|
-
shippingCost:
|
|
15087
|
-
returnRate:
|
|
15088
|
-
cancellationRate:
|
|
15089
|
-
adsManagerCpa:
|
|
15090
|
-
desiredMargin:
|
|
15158
|
+
var CostingInputSchema = z62.object({
|
|
15159
|
+
country: z62.string().min(2).max(3),
|
|
15160
|
+
supplierCost: z62.number().finite().positive(),
|
|
15161
|
+
shippingCost: z62.number().finite().nonnegative(),
|
|
15162
|
+
returnRate: z62.number().finite().min(0).lt(1),
|
|
15163
|
+
cancellationRate: z62.number().finite().min(0).lt(1),
|
|
15164
|
+
adsManagerCpa: z62.number().finite().nonnegative(),
|
|
15165
|
+
desiredMargin: z62.number().finite().min(0).lt(1)
|
|
15091
15166
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
15092
15167
|
if (returnRate + cancellationRate >= 1) context.addIssue({
|
|
15093
|
-
code:
|
|
15168
|
+
code: z62.ZodIssueCode.custom,
|
|
15094
15169
|
path: [
|
|
15095
15170
|
"cancellationRate"
|
|
15096
15171
|
]
|
|
15097
15172
|
});
|
|
15098
15173
|
});
|
|
15099
|
-
var FiniteCostingNumber =
|
|
15100
|
-
var CostingResultSchema =
|
|
15101
|
-
country:
|
|
15174
|
+
var FiniteCostingNumber = z62.number().finite();
|
|
15175
|
+
var CostingResultSchema = z62.object({
|
|
15176
|
+
country: z62.string().min(2).max(3),
|
|
15102
15177
|
deliveryRate: FiniteCostingNumber,
|
|
15103
15178
|
adjustedShippingCost: FiniteCostingNumber,
|
|
15104
15179
|
adjustedCpa: FiniteCostingNumber,
|
|
@@ -15111,44 +15186,44 @@ var CostingResultSchema = z61.object({
|
|
|
15111
15186
|
estimatedProfit: FiniteCostingNumber,
|
|
15112
15187
|
actualMargin: FiniteCostingNumber,
|
|
15113
15188
|
breakEvenAdsManagerCpa: FiniteCostingNumber,
|
|
15114
|
-
wasPriceAutoAdjusted:
|
|
15115
|
-
profitabilityStatus:
|
|
15116
|
-
});
|
|
15117
|
-
var RewardProgressSchema =
|
|
15118
|
-
campaignKey:
|
|
15119
|
-
totalCredits:
|
|
15120
|
-
earnedCredits:
|
|
15121
|
-
milestones:
|
|
15189
|
+
wasPriceAutoAdjusted: z62.boolean(),
|
|
15190
|
+
profitabilityStatus: z62.literal("healthy")
|
|
15191
|
+
});
|
|
15192
|
+
var RewardProgressSchema = z62.object({
|
|
15193
|
+
campaignKey: z62.literal("dropshipping-launch-v1"),
|
|
15194
|
+
totalCredits: z62.number().int().positive(),
|
|
15195
|
+
earnedCredits: z62.number().int().nonnegative(),
|
|
15196
|
+
milestones: z62.array(z62.object({
|
|
15122
15197
|
milestone: DropshippingRewardMilestone,
|
|
15123
|
-
credits:
|
|
15124
|
-
available:
|
|
15125
|
-
earned:
|
|
15198
|
+
credits: z62.number().int().positive(),
|
|
15199
|
+
available: z62.boolean().optional(),
|
|
15200
|
+
earned: z62.boolean(),
|
|
15126
15201
|
grantId: ProjectId.nullable(),
|
|
15127
|
-
grantedAt:
|
|
15202
|
+
grantedAt: z62.string().datetime().nullable()
|
|
15128
15203
|
})).length(DropshippingRewardMilestone.options.length)
|
|
15129
15204
|
});
|
|
15130
|
-
var ProjectResponseSchema =
|
|
15205
|
+
var ProjectResponseSchema = z62.object({
|
|
15131
15206
|
id: ProjectId,
|
|
15132
15207
|
taskId: ProjectId.nullable(),
|
|
15133
15208
|
status: DropshippingProjectStatus,
|
|
15134
|
-
originKey:
|
|
15209
|
+
originKey: z62.string().min(1),
|
|
15135
15210
|
researchRunId: ProjectId.nullable(),
|
|
15136
|
-
candidateSourceId:
|
|
15137
|
-
productName:
|
|
15211
|
+
candidateSourceId: z62.string().nullable(),
|
|
15212
|
+
productName: z62.string().nullable(),
|
|
15138
15213
|
productUrl: HttpUrl3.nullable(),
|
|
15139
15214
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
15140
|
-
targetCountry:
|
|
15141
|
-
languageCode:
|
|
15142
|
-
hasReferenceImage:
|
|
15215
|
+
targetCountry: z62.string().nullable(),
|
|
15216
|
+
languageCode: z62.string().nullable(),
|
|
15217
|
+
hasReferenceImage: z62.boolean(),
|
|
15143
15218
|
costingInput: CostingInputSchema.nullable(),
|
|
15144
15219
|
costingResult: CostingResultSchema.nullable(),
|
|
15145
|
-
costingVersion:
|
|
15146
|
-
version:
|
|
15220
|
+
costingVersion: z62.number().int().positive().nullable(),
|
|
15221
|
+
version: z62.number().int().positive(),
|
|
15147
15222
|
phase: DropshippingProjectPhase,
|
|
15148
15223
|
nextAction: DropshippingProjectNextAction.nullable(),
|
|
15149
15224
|
rewards: RewardProgressSchema,
|
|
15150
|
-
createdAt:
|
|
15151
|
-
updatedAt:
|
|
15225
|
+
createdAt: z62.string().datetime(),
|
|
15226
|
+
updatedAt: z62.string().datetime()
|
|
15152
15227
|
}).passthrough();
|
|
15153
15228
|
var NEXT_ACTION_GUIDANCE = {
|
|
15154
15229
|
cost_product: "Llama `cost_dropshipping_project` con el costo real del proveedor. Nunca lo inventes: p\xEDdeselo al usuario.",
|