@productmaker/mcp 7.2.0 → 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/http.js +792 -674
- package/dist/stdio.js +781 -663
- package/package.json +1 -1
package/dist/stdio.js
CHANGED
|
@@ -3631,11 +3631,12 @@ var FreeformLandingConfigSchema = z21.object({
|
|
|
3631
3631
|
showVariantPicker: z21.boolean().optional(),
|
|
3632
3632
|
/**
|
|
3633
3633
|
* Suppress the native Shopify buy form (the `BUY_FORM_MARKER` block). The page
|
|
3634
|
-
* CTAs already carry `data-cl-buy-trigger` → they open the
|
|
3635
|
-
* so on
|
|
3636
|
-
*
|
|
3637
|
-
*
|
|
3638
|
-
* (backward compatible with
|
|
3634
|
+
* CTAs already carry `data-cl-buy-trigger` → they open the installed COD
|
|
3635
|
+
* provider's popup (Releasit or EasySell), so on COD-provider stores the
|
|
3636
|
+
* native add-to-cart form is a redundant second buy path (it rendered as a
|
|
3637
|
+
* bare "price + Comprar" block). When true the assembler omits the marker
|
|
3638
|
+
* entirely. Undefined/false = keep the native form (backward compatible with
|
|
3639
|
+
* already-assembled configs).
|
|
3639
3640
|
*/
|
|
3640
3641
|
hideNativeBuyForm: z21.boolean().optional()
|
|
3641
3642
|
});
|
|
@@ -5423,6 +5424,17 @@ var CodeLandingThemeSetupResponse = z28.discriminatedUnion("status", [
|
|
|
5423
5424
|
themeEditorDeepLink: z28.string().url(),
|
|
5424
5425
|
shopDomain: z28.string()
|
|
5425
5426
|
}),
|
|
5427
|
+
z28.object({
|
|
5428
|
+
/**
|
|
5429
|
+
* The block is missing and the store has NO products yet. Shopify's theme
|
|
5430
|
+
* editor cannot add an app block to a product template with nothing to
|
|
5431
|
+
* preview (it answers "there is a problem with the app block"), so there
|
|
5432
|
+
* is deliberately no deep link: the seller publishes first, and the
|
|
5433
|
+
* publish response carries the link aimed at the product it created.
|
|
5434
|
+
*/
|
|
5435
|
+
status: z28.literal("setup_after_publish"),
|
|
5436
|
+
shopDomain: z28.string()
|
|
5437
|
+
}),
|
|
5426
5438
|
z28.object({
|
|
5427
5439
|
/** Not a code-landing task — the gate does not apply. */
|
|
5428
5440
|
status: z28.literal("not_applicable"),
|
|
@@ -6925,7 +6937,10 @@ var ChatParseEstimationOptions = z34.object({}).strict();
|
|
|
6925
6937
|
var CodeLandingEditEstimationOptions = z34.object({}).strict();
|
|
6926
6938
|
var ServiceCreativeEstimationOptions = z34.object({
|
|
6927
6939
|
mediaAssetCount: z34.number().int().min(0).max(8).optional(),
|
|
6928
|
-
uploadedVideoDurationSeconds: z34.number().min(0).max(240).optional()
|
|
6940
|
+
uploadedVideoDurationSeconds: z34.number().min(0).max(240).optional(),
|
|
6941
|
+
/** Quality the panels render at (its registry model sets the per-second
|
|
6942
|
+
* price). Absent = economy, the pre-quality service default. */
|
|
6943
|
+
videoQuality: VideoQuality.optional()
|
|
6929
6944
|
});
|
|
6930
6945
|
var ActorGridEstimationOptions = z34.object({}).strict();
|
|
6931
6946
|
var CostEstimationRequest = z34.discriminatedUnion("type", [
|
|
@@ -7695,7 +7710,18 @@ var KIE_SUBMIT_IMAGE_TASK_TARGETS = [
|
|
|
7695
7710
|
"rapid_master_anchor",
|
|
7696
7711
|
"clean_product_image",
|
|
7697
7712
|
"single_call_anchor",
|
|
7698
|
-
"product_view_reference"
|
|
7713
|
+
"product_view_reference",
|
|
7714
|
+
// Generated service-video presenter (text-to-image portrait). Task-owned, so
|
|
7715
|
+
// it lives here and not beside `actor_candidate`; it mirrors that target's
|
|
7716
|
+
// model, resolution and recovery policy. The fan-in resumes the service init
|
|
7717
|
+
// (`dispatchServiceActor`, refKey prefix `service_actor:`).
|
|
7718
|
+
"service_actor",
|
|
7719
|
+
// First frame of a generated service B-roll panel: image-to-image from the
|
|
7720
|
+
// service photo the planner cited, cleaned of overlaid text/graphics and
|
|
7721
|
+
// fitted to the shot. Mirrors `rapid_panel`'s model tier and recovery
|
|
7722
|
+
// policy. The same fan-in waits for the whole expected image set
|
|
7723
|
+
// (`dispatchServiceActor`, refKey prefix `service_broll_anchor:`).
|
|
7724
|
+
"service_broll_anchor"
|
|
7699
7725
|
];
|
|
7700
7726
|
var ACTOR_CANDIDATE_TARGET = "actor_candidate";
|
|
7701
7727
|
var ANY_KIE_SUBMIT_IMAGE_TARGETS = [
|
|
@@ -9617,6 +9643,12 @@ var DEFAULT_PRICING = {
|
|
|
9617
9643
|
ourCostCents: 0.01,
|
|
9618
9644
|
userPriceCents: 0.02
|
|
9619
9645
|
},
|
|
9646
|
+
// Service reels harvested from the business's own public profile (per second,
|
|
9647
|
+
// same Whisper-1 rate). Separate action so the ledger names the source.
|
|
9648
|
+
"openai:service-social-transcribe": {
|
|
9649
|
+
ourCostCents: 0.01,
|
|
9650
|
+
userPriceCents: 0.02
|
|
9651
|
+
},
|
|
9620
9652
|
// User-uploaded service reference/competitor analysis (per second, same Whisper-1 rate).
|
|
9621
9653
|
// This is a separate action because its ledger entries identify the analysis source.
|
|
9622
9654
|
"openai:service-reference-transcribe": {
|
|
@@ -10756,6 +10788,11 @@ var DECLARATION = DELIVERY_FAMILIES.map((family) => [
|
|
|
10756
10788
|
])
|
|
10757
10789
|
]);
|
|
10758
10790
|
|
|
10791
|
+
// ../../packages/types/src/seller-prohibitions.ts
|
|
10792
|
+
var MARKER = String.raw`(?:no|nunca|jam[aá]s|prohibido|evita[r]?)(?:\s*:)?\s`;
|
|
10793
|
+
var PROHIBITION_AT_START = new RegExp(String.raw`^(?:[-•*]\s*)?(${MARKER}[\s\S]*)$`, "iu");
|
|
10794
|
+
var PROHIBITION_AFTER_LABEL = new RegExp(String.raw`^(?:[-•*]\s*)?[^:.!?\n]{1,40}:\s*(${MARKER}[\s\S]*)$`, "iu");
|
|
10795
|
+
|
|
10759
10796
|
// ../../packages/types/src/task-type.ts
|
|
10760
10797
|
import { z as z50 } from "zod";
|
|
10761
10798
|
var TaskTypeSchema = z50.enum([
|
|
@@ -13337,7 +13374,7 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
13337
13374
|
"task",
|
|
13338
13375
|
"product"
|
|
13339
13376
|
]),
|
|
13340
|
-
defineCapability("create_service_video", "
|
|
13377
|
+
defineCapability("create_service_video", "863884c1af5de3e168cbbe825ea3961901c84dae1899ca400f8f7fa01df91c0a", "credit_consuming", "creative", [
|
|
13341
13378
|
"credit_consuming",
|
|
13342
13379
|
"state_change"
|
|
13343
13380
|
], [
|
|
@@ -13361,7 +13398,11 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
13361
13398
|
]),
|
|
13362
13399
|
slot("video_preset", false, [
|
|
13363
13400
|
"videoPreset"
|
|
13364
|
-
])
|
|
13401
|
+
]),
|
|
13402
|
+
// MCP-only for now: WhatsApp's service flow keeps the economy default.
|
|
13403
|
+
slot("video_quality", false, [
|
|
13404
|
+
"videoQuality"
|
|
13405
|
+
], [])
|
|
13365
13406
|
], [
|
|
13366
13407
|
"service_context"
|
|
13367
13408
|
], [
|
|
@@ -14900,6 +14941,81 @@ var WhatsAppPresentationManifestSchema = z67.object({
|
|
|
14900
14941
|
}
|
|
14901
14942
|
});
|
|
14902
14943
|
|
|
14944
|
+
// ../../packages/types/src/flight-recorder.ts
|
|
14945
|
+
import { z as z68 } from "zod";
|
|
14946
|
+
var FlightRecorderGenerationTypeSchema = z68.enum([
|
|
14947
|
+
"initial",
|
|
14948
|
+
"regeneration",
|
|
14949
|
+
"edit",
|
|
14950
|
+
"retry"
|
|
14951
|
+
]);
|
|
14952
|
+
var FlightRecorderProviderSchema = z68.enum([
|
|
14953
|
+
"kie",
|
|
14954
|
+
"fal"
|
|
14955
|
+
]);
|
|
14956
|
+
var FlightRecorderElementSchema = z68.object({
|
|
14957
|
+
name: z68.string().optional(),
|
|
14958
|
+
description: z68.string().optional(),
|
|
14959
|
+
frontalImageUrl: z68.string().optional(),
|
|
14960
|
+
referenceImageUrls: z68.array(z68.string()).optional(),
|
|
14961
|
+
videoUrl: z68.string().optional()
|
|
14962
|
+
});
|
|
14963
|
+
var FlightRecorderDistillationSchema = z68.object({
|
|
14964
|
+
actorGender: z68.enum([
|
|
14965
|
+
"female",
|
|
14966
|
+
"male",
|
|
14967
|
+
"mixed"
|
|
14968
|
+
]).or(z68.string()).optional(),
|
|
14969
|
+
voiceId: z68.string().optional(),
|
|
14970
|
+
cameraMotion: z68.string().optional()
|
|
14971
|
+
}).catchall(z68.unknown());
|
|
14972
|
+
var FlightRecorderEntrySchema = z68.object({
|
|
14973
|
+
schemaVersion: z68.literal(1).optional(),
|
|
14974
|
+
id: z68.string().min(1),
|
|
14975
|
+
taskId: z68.string().min(1),
|
|
14976
|
+
runId: z68.string().min(1),
|
|
14977
|
+
sequence: z68.number().int().nonnegative(),
|
|
14978
|
+
timestamp: z68.string().min(1),
|
|
14979
|
+
provider: FlightRecorderProviderSchema.or(z68.string()),
|
|
14980
|
+
model: z68.string().min(1),
|
|
14981
|
+
prompt: z68.string(),
|
|
14982
|
+
durationSeconds: z68.number().nonnegative(),
|
|
14983
|
+
aspectRatio: z68.string().optional(),
|
|
14984
|
+
resolution: z68.string().optional(),
|
|
14985
|
+
startImageUrl: z68.string().optional(),
|
|
14986
|
+
endImageUrl: z68.string().optional(),
|
|
14987
|
+
generateAudio: z68.boolean().optional(),
|
|
14988
|
+
// Correlation & pipeline metadata
|
|
14989
|
+
angleKey: z68.string().optional(),
|
|
14990
|
+
sceneIndex: z68.number().int().nonnegative().optional(),
|
|
14991
|
+
generationType: FlightRecorderGenerationTypeSchema,
|
|
14992
|
+
operationId: z68.string().min(1).optional(),
|
|
14993
|
+
revisionId: z68.string().min(1).optional(),
|
|
14994
|
+
attemptNumber: z68.number().int().nonnegative().default(1),
|
|
14995
|
+
// Elements & Distillation
|
|
14996
|
+
elements: z68.array(FlightRecorderElementSchema).optional(),
|
|
14997
|
+
distillation: FlightRecorderDistillationSchema.optional(),
|
|
14998
|
+
// Raw payload (sanitized of secrets)
|
|
14999
|
+
rawPayload: z68.record(z68.unknown())
|
|
15000
|
+
});
|
|
15001
|
+
var FlightRecorderQuerySchema = z68.object({
|
|
15002
|
+
taskId: z68.string().min(1),
|
|
15003
|
+
runId: z68.string().optional(),
|
|
15004
|
+
sceneIndex: z68.number().int().nonnegative().optional(),
|
|
15005
|
+
angleKey: z68.string().optional(),
|
|
15006
|
+
generationType: FlightRecorderGenerationTypeSchema.optional(),
|
|
15007
|
+
cursor: z68.number().int().nonnegative().optional(),
|
|
15008
|
+
limit: z68.number().int().positive().optional()
|
|
15009
|
+
});
|
|
15010
|
+
var FlightRecorderResponseSchema = z68.object({
|
|
15011
|
+
taskId: z68.string().min(1),
|
|
15012
|
+
runId: z68.string().min(1),
|
|
15013
|
+
entries: z68.array(FlightRecorderEntrySchema),
|
|
15014
|
+
lastCall: FlightRecorderEntrySchema.nullable(),
|
|
15015
|
+
count: z68.number().int().nonnegative(),
|
|
15016
|
+
nextCursor: z68.number().int().nonnegative().nullable()
|
|
15017
|
+
});
|
|
15018
|
+
|
|
14903
15019
|
// src/response-body.ts
|
|
14904
15020
|
var ResponseBodyTooLargeError = class extends Error {
|
|
14905
15021
|
static {
|
|
@@ -15139,7 +15255,7 @@ var ApiClient = class {
|
|
|
15139
15255
|
};
|
|
15140
15256
|
|
|
15141
15257
|
// src/index.ts
|
|
15142
|
-
var MCP_VERSION = "7.
|
|
15258
|
+
var MCP_VERSION = "7.3.0";
|
|
15143
15259
|
|
|
15144
15260
|
// src/meta-upload-app.ts
|
|
15145
15261
|
import { readFileSync } from "fs";
|
|
@@ -15211,7 +15327,7 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
|
|
|
15211
15327
|
__name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
|
|
15212
15328
|
|
|
15213
15329
|
// src/tools/tasks.ts
|
|
15214
|
-
import { z as
|
|
15330
|
+
import { z as z72 } from "zod";
|
|
15215
15331
|
|
|
15216
15332
|
// src/resolve-image.ts
|
|
15217
15333
|
import { lookup as dnsLookup } from "dns/promises";
|
|
@@ -15772,10 +15888,10 @@ async function resolveMediaRef(ref, opts) {
|
|
|
15772
15888
|
__name(resolveMediaRef, "resolveMediaRef");
|
|
15773
15889
|
|
|
15774
15890
|
// src/tools/shared.ts
|
|
15775
|
-
import { z as
|
|
15776
|
-
var Lang =
|
|
15777
|
-
var Country =
|
|
15778
|
-
var LandingStrategyEnum =
|
|
15891
|
+
import { z as z69 } from "zod";
|
|
15892
|
+
var Lang = z69.string().regex(/^[a-z]{2}(?:[-_][a-zA-Z]{2})?$/, "Usa un c\xF3digo de idioma BCP-47, por ejemplo es, en-US o pt-BR").max(10);
|
|
15893
|
+
var Country = z69.string().min(2).max(3);
|
|
15894
|
+
var LandingStrategyEnum = z69.enum([
|
|
15779
15895
|
"auto",
|
|
15780
15896
|
"classic",
|
|
15781
15897
|
"pain_solution",
|
|
@@ -15784,12 +15900,12 @@ var LandingStrategyEnum = z68.enum([
|
|
|
15784
15900
|
"offer_value",
|
|
15785
15901
|
"lifestyle_identity"
|
|
15786
15902
|
]);
|
|
15787
|
-
var LandingImageFormatEnum =
|
|
15903
|
+
var LandingImageFormatEnum = z69.enum([
|
|
15788
15904
|
"9:16",
|
|
15789
15905
|
"4:5",
|
|
15790
15906
|
"1:1"
|
|
15791
15907
|
]);
|
|
15792
|
-
var VideoPresetEnum =
|
|
15908
|
+
var VideoPresetEnum = z69.enum([
|
|
15793
15909
|
"auto",
|
|
15794
15910
|
"ugc_dynamic",
|
|
15795
15911
|
"ugc_how_to",
|
|
@@ -15802,21 +15918,21 @@ var VideoPresetEnum = z68.enum([
|
|
|
15802
15918
|
"pixar_problem",
|
|
15803
15919
|
"pixar_sassy"
|
|
15804
15920
|
]);
|
|
15805
|
-
var VideoStructureEnum =
|
|
15921
|
+
var VideoStructureEnum = z69.enum([
|
|
15806
15922
|
"single_take",
|
|
15807
15923
|
"multi_scene"
|
|
15808
15924
|
]);
|
|
15809
|
-
var VideoQualityEnum =
|
|
15925
|
+
var VideoQualityEnum = z69.enum([
|
|
15810
15926
|
"economy",
|
|
15811
15927
|
"medium",
|
|
15812
15928
|
"pro"
|
|
15813
15929
|
]);
|
|
15814
|
-
var VideoRouteIdEnum =
|
|
15930
|
+
var VideoRouteIdEnum = z69.enum([
|
|
15815
15931
|
"single_take",
|
|
15816
15932
|
"multi_scene",
|
|
15817
15933
|
"free"
|
|
15818
15934
|
]);
|
|
15819
|
-
var TaskCreativeVariantVideoPresetEnum =
|
|
15935
|
+
var TaskCreativeVariantVideoPresetEnum = z69.enum([
|
|
15820
15936
|
"auto",
|
|
15821
15937
|
"ugc_dynamic",
|
|
15822
15938
|
"ugc_how_to",
|
|
@@ -15887,7 +16003,7 @@ function resolveVideoPreset(preset) {
|
|
|
15887
16003
|
return VIDEO_PRESET_RESOLUTION[preset] ?? null;
|
|
15888
16004
|
}
|
|
15889
16005
|
__name(resolveVideoPreset, "resolveVideoPreset");
|
|
15890
|
-
var VideoTierEnum =
|
|
16006
|
+
var VideoTierEnum = z69.enum([
|
|
15891
16007
|
"basic"
|
|
15892
16008
|
]);
|
|
15893
16009
|
function resolveVideoTier(_tier) {
|
|
@@ -15927,22 +16043,22 @@ function assertSemanticVideoDurationCompatibility(structure, quality, durationSe
|
|
|
15927
16043
|
}
|
|
15928
16044
|
}
|
|
15929
16045
|
__name(assertSemanticVideoDurationCompatibility, "assertSemanticVideoDurationCompatibility");
|
|
15930
|
-
var VideoResolutionEnum =
|
|
16046
|
+
var VideoResolutionEnum = z69.enum([
|
|
15931
16047
|
"480p",
|
|
15932
16048
|
"720p"
|
|
15933
16049
|
]);
|
|
15934
|
-
var CreativeGenderEnum =
|
|
16050
|
+
var CreativeGenderEnum = z69.enum([
|
|
15935
16051
|
"female",
|
|
15936
16052
|
"male",
|
|
15937
16053
|
"mixed"
|
|
15938
16054
|
]);
|
|
15939
|
-
var VideoStyleEnum =
|
|
16055
|
+
var VideoStyleEnum = z69.enum([
|
|
15940
16056
|
"ugc",
|
|
15941
16057
|
"cartoon_3d",
|
|
15942
16058
|
"product_only",
|
|
15943
16059
|
"ai_dynamic"
|
|
15944
16060
|
]);
|
|
15945
|
-
var NarrativeStyleEnum =
|
|
16061
|
+
var NarrativeStyleEnum = z69.enum([
|
|
15946
16062
|
"review",
|
|
15947
16063
|
"ugc_how_to",
|
|
15948
16064
|
"problem_product_cta",
|
|
@@ -15960,7 +16076,7 @@ var NarrativeStyleEnum = z68.enum([
|
|
|
15960
16076
|
"ugc_demo_review",
|
|
15961
16077
|
"market"
|
|
15962
16078
|
]);
|
|
15963
|
-
var PublicNarrativeStyleEnum =
|
|
16079
|
+
var PublicNarrativeStyleEnum = z69.enum([
|
|
15964
16080
|
"review",
|
|
15965
16081
|
"ugc_how_to",
|
|
15966
16082
|
"ugc_unboxing_chaos",
|
|
@@ -15973,7 +16089,7 @@ var PublicNarrativeStyleEnum = z68.enum([
|
|
|
15973
16089
|
"sassy_product_pixar",
|
|
15974
16090
|
"market"
|
|
15975
16091
|
]);
|
|
15976
|
-
var VideoModelEnum =
|
|
16092
|
+
var VideoModelEnum = z69.enum([
|
|
15977
16093
|
"veo",
|
|
15978
16094
|
"wan",
|
|
15979
16095
|
"bytedance",
|
|
@@ -15981,29 +16097,29 @@ var VideoModelEnum = z68.enum([
|
|
|
15981
16097
|
"grok",
|
|
15982
16098
|
"kling"
|
|
15983
16099
|
]);
|
|
15984
|
-
var ProductReferenceUserChoiceEnum =
|
|
16100
|
+
var ProductReferenceUserChoiceEnum = z69.enum([
|
|
15985
16101
|
"same_product",
|
|
15986
16102
|
"variants",
|
|
15987
16103
|
"different_products",
|
|
15988
16104
|
"combo_distinct"
|
|
15989
16105
|
]);
|
|
15990
|
-
var ProductReferenceCandidateGroupingEnum =
|
|
16106
|
+
var ProductReferenceCandidateGroupingEnum = z69.enum([
|
|
15991
16107
|
"same_product_same_variant",
|
|
15992
16108
|
"same_product_different_variants",
|
|
15993
16109
|
"different_products",
|
|
15994
16110
|
"unclear"
|
|
15995
16111
|
]);
|
|
15996
|
-
var ProductReferenceScopeEnum =
|
|
16112
|
+
var ProductReferenceScopeEnum = z69.enum([
|
|
15997
16113
|
"base",
|
|
15998
16114
|
"video_view_pack"
|
|
15999
16115
|
]);
|
|
16000
|
-
var ProductReferenceResolutionDecisionEnum =
|
|
16116
|
+
var ProductReferenceResolutionDecisionEnum = z69.enum([
|
|
16001
16117
|
"approve",
|
|
16002
16118
|
"reject",
|
|
16003
16119
|
"observed_only",
|
|
16004
16120
|
"correct_view"
|
|
16005
16121
|
]);
|
|
16006
|
-
var ProductReferenceRejectionReasonEnum =
|
|
16122
|
+
var ProductReferenceRejectionReasonEnum = z69.enum([
|
|
16007
16123
|
"replacement_requested",
|
|
16008
16124
|
"wrong_product_identity",
|
|
16009
16125
|
"wrong_variant",
|
|
@@ -16014,13 +16130,13 @@ var ProductReferenceRejectionReasonEnum = z68.enum([
|
|
|
16014
16130
|
"not_a_product_photo",
|
|
16015
16131
|
"other"
|
|
16016
16132
|
]);
|
|
16017
|
-
var GapDurationChoiceMirror =
|
|
16018
|
-
angleIndex:
|
|
16019
|
-
recommendedSec:
|
|
16020
|
-
|
|
16021
|
-
|
|
16133
|
+
var GapDurationChoiceMirror = z69.object({
|
|
16134
|
+
angleIndex: z69.number().int().nonnegative(),
|
|
16135
|
+
recommendedSec: z69.union([
|
|
16136
|
+
z69.literal(15),
|
|
16137
|
+
z69.literal(30)
|
|
16022
16138
|
]),
|
|
16023
|
-
estimatedDeltaCredits:
|
|
16139
|
+
estimatedDeltaCredits: z69.number().int().nonnegative().optional()
|
|
16024
16140
|
});
|
|
16025
16141
|
function buildSelectedImageUrlsHash(urls) {
|
|
16026
16142
|
const input = [
|
|
@@ -16030,13 +16146,13 @@ function buildSelectedImageUrlsHash(urls) {
|
|
|
16030
16146
|
return `fnv1a:${hash.toString(16).padStart(8, "0")}:${urls.length}`;
|
|
16031
16147
|
}
|
|
16032
16148
|
__name(buildSelectedImageUrlsHash, "buildSelectedImageUrlsHash");
|
|
16033
|
-
var ImageCreativeStyleEnum =
|
|
16149
|
+
var ImageCreativeStyleEnum = z69.enum([
|
|
16034
16150
|
"studio",
|
|
16035
16151
|
"floating",
|
|
16036
16152
|
"ingredients",
|
|
16037
16153
|
"in_use"
|
|
16038
16154
|
]);
|
|
16039
|
-
var ImageCreativeArchetypeEnum =
|
|
16155
|
+
var ImageCreativeArchetypeEnum = z69.enum([
|
|
16040
16156
|
"direct_response_product_ad",
|
|
16041
16157
|
"hero_outcome",
|
|
16042
16158
|
"offer_value_prop",
|
|
@@ -16045,20 +16161,20 @@ var ImageCreativeArchetypeEnum = z68.enum([
|
|
|
16045
16161
|
"problem_solution",
|
|
16046
16162
|
"lifestyle_identity"
|
|
16047
16163
|
]);
|
|
16048
|
-
var ImageCreativeVisualTreatmentEnum =
|
|
16164
|
+
var ImageCreativeVisualTreatmentEnum = z69.enum([
|
|
16049
16165
|
"performance_product_ad",
|
|
16050
16166
|
"premium_dtc_carousel"
|
|
16051
16167
|
]);
|
|
16052
|
-
var ImageCreativeAspectRatioEnum =
|
|
16168
|
+
var ImageCreativeAspectRatioEnum = z69.enum([
|
|
16053
16169
|
"1:1",
|
|
16054
16170
|
"4:5",
|
|
16055
16171
|
"9:16",
|
|
16056
16172
|
"16:9"
|
|
16057
16173
|
]);
|
|
16058
|
-
var ImageRefSchema =
|
|
16059
|
-
url:
|
|
16060
|
-
path:
|
|
16061
|
-
assetId:
|
|
16174
|
+
var ImageRefSchema = z69.object({
|
|
16175
|
+
url: z69.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.'),
|
|
16176
|
+
path: z69.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`.'),
|
|
16177
|
+
assetId: z69.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.")
|
|
16062
16178
|
}).refine((v) => [
|
|
16063
16179
|
v.url,
|
|
16064
16180
|
v.path,
|
|
@@ -16066,11 +16182,11 @@ var ImageRefSchema = z68.object({
|
|
|
16066
16182
|
].filter(Boolean).length === 1, {
|
|
16067
16183
|
message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
|
|
16068
16184
|
});
|
|
16069
|
-
var ImagesInput =
|
|
16185
|
+
var ImagesInput = z69.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
|
|
16070
16186
|
const assetCount = images.filter((image) => Boolean(image.assetId)).length;
|
|
16071
16187
|
if (assetCount > 0 && assetCount !== images.length) {
|
|
16072
16188
|
ctx.addIssue({
|
|
16073
|
-
code:
|
|
16189
|
+
code: z69.ZodIssueCode.custom,
|
|
16074
16190
|
message: "all image entries must use assetId, or all must use URL/path sources"
|
|
16075
16191
|
});
|
|
16076
16192
|
}
|
|
@@ -16138,14 +16254,14 @@ async function submitCreative(api, opts) {
|
|
|
16138
16254
|
});
|
|
16139
16255
|
}
|
|
16140
16256
|
__name(submitCreative, "submitCreative");
|
|
16141
|
-
var ResearchTargetCountryEnum =
|
|
16257
|
+
var ResearchTargetCountryEnum = z69.enum([
|
|
16142
16258
|
"CO",
|
|
16143
16259
|
"MX",
|
|
16144
16260
|
"PE",
|
|
16145
16261
|
"EC",
|
|
16146
16262
|
"CL"
|
|
16147
16263
|
]);
|
|
16148
|
-
var ResearchCategoryEnum =
|
|
16264
|
+
var ResearchCategoryEnum = z69.enum([
|
|
16149
16265
|
"auto",
|
|
16150
16266
|
"automotive",
|
|
16151
16267
|
"kitchen",
|
|
@@ -16196,7 +16312,7 @@ var OVERWRITES_EXTERNAL = {
|
|
|
16196
16312
|
idempotentHint: false,
|
|
16197
16313
|
openWorldHint: true
|
|
16198
16314
|
};
|
|
16199
|
-
var DailyControlStatusEnum =
|
|
16315
|
+
var DailyControlStatusEnum = z69.enum([
|
|
16200
16316
|
"ok",
|
|
16201
16317
|
"sales_unavailable",
|
|
16202
16318
|
"timezone_unavailable",
|
|
@@ -16209,19 +16325,19 @@ var DailyControlStatusEnum = z68.enum([
|
|
|
16209
16325
|
"product_missing",
|
|
16210
16326
|
"store_unreachable"
|
|
16211
16327
|
]);
|
|
16212
|
-
var DailyControlLightEnum =
|
|
16328
|
+
var DailyControlLightEnum = z69.enum([
|
|
16213
16329
|
"green",
|
|
16214
16330
|
"amber",
|
|
16215
16331
|
"red",
|
|
16216
16332
|
"none"
|
|
16217
16333
|
]);
|
|
16218
|
-
var DailyControlVerdictEnum =
|
|
16334
|
+
var DailyControlVerdictEnum = z69.enum([
|
|
16219
16335
|
"scale",
|
|
16220
16336
|
"hold",
|
|
16221
16337
|
"kill",
|
|
16222
16338
|
"insufficient_sample"
|
|
16223
16339
|
]);
|
|
16224
|
-
var DailyControlSourceEnum =
|
|
16340
|
+
var DailyControlSourceEnum = z69.enum([
|
|
16225
16341
|
"shopify",
|
|
16226
16342
|
"shopify_settling",
|
|
16227
16343
|
"user",
|
|
@@ -17362,29 +17478,29 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
|
|
|
17362
17478
|
__name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
|
|
17363
17479
|
|
|
17364
17480
|
// src/tools/media-presentation.ts
|
|
17365
|
-
import { z as
|
|
17366
|
-
var HttpsPresentationUrlSchema =
|
|
17481
|
+
import { z as z70 } from "zod";
|
|
17482
|
+
var HttpsPresentationUrlSchema = z70.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
|
|
17367
17483
|
var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
|
|
17368
17484
|
const hostname = new URL(value).hostname.toLowerCase();
|
|
17369
17485
|
return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
|
|
17370
17486
|
}, "preview URL must be owned by ProductMaker");
|
|
17371
|
-
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) =>
|
|
17372
|
-
var PresentationImageSchema =
|
|
17373
|
-
kind:
|
|
17487
|
+
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z70.number().int().positive().max(maximum), "positiveIntAtMost");
|
|
17488
|
+
var PresentationImageSchema = z70.object({
|
|
17489
|
+
kind: z70.literal("image"),
|
|
17374
17490
|
url: HttpsPresentationUrlSchema,
|
|
17375
|
-
mimeType:
|
|
17491
|
+
mimeType: z70.enum([
|
|
17376
17492
|
"image/jpeg",
|
|
17377
17493
|
"image/png"
|
|
17378
17494
|
]),
|
|
17379
17495
|
byteSize: positiveIntAtMost(5 * 1024 * 1024),
|
|
17380
17496
|
width: positiveIntAtMost(16384),
|
|
17381
17497
|
height: positiveIntAtMost(16384),
|
|
17382
|
-
alt:
|
|
17498
|
+
alt: z70.string().trim().min(1).max(240)
|
|
17383
17499
|
}).strict();
|
|
17384
17500
|
var McpMediaPresentationSchema = PresentationImageSchema;
|
|
17385
|
-
var GalleryImageSchema =
|
|
17501
|
+
var GalleryImageSchema = z70.object({
|
|
17386
17502
|
url: ProductMakerPreviewUrlSchema,
|
|
17387
|
-
alt:
|
|
17503
|
+
alt: z70.string().trim().min(1).max(240)
|
|
17388
17504
|
});
|
|
17389
17505
|
var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
17390
17506
|
async function imageBlocks(image, transport) {
|
|
@@ -17534,10 +17650,10 @@ ${summary}`,
|
|
|
17534
17650
|
__name(requirePaidCreativeConfirmation, "requirePaidCreativeConfirmation");
|
|
17535
17651
|
|
|
17536
17652
|
// src/tools/winning-product-image.ts
|
|
17537
|
-
import { z as
|
|
17538
|
-
var WinnerReferenceInput =
|
|
17539
|
-
runId:
|
|
17540
|
-
candidateSourceId:
|
|
17653
|
+
import { z as z71 } from "zod";
|
|
17654
|
+
var WinnerReferenceInput = z71.object({
|
|
17655
|
+
runId: z71.string().uuid(),
|
|
17656
|
+
candidateSourceId: z71.string().trim().min(1).max(160)
|
|
17541
17657
|
}).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
|
|
17542
17658
|
async function resolveWinnerImages(api, winnerReference, images) {
|
|
17543
17659
|
if (!winnerReference) return images;
|
|
@@ -17574,188 +17690,189 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
|
|
|
17574
17690
|
var createServiceVideoGuidance = getProductMakerCapabilityModelGuidance("create_service_video");
|
|
17575
17691
|
var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
|
|
17576
17692
|
var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
|
|
17577
|
-
var CreateProductTaskInput =
|
|
17693
|
+
var CreateProductTaskInput = z72.object({
|
|
17578
17694
|
images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
|
|
17579
17695
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
17580
|
-
projectId:
|
|
17581
|
-
productUrl:
|
|
17696
|
+
projectId: z72.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
|
|
17697
|
+
productUrl: z72.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."),
|
|
17582
17698
|
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.'),
|
|
17583
17699
|
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.'),
|
|
17584
|
-
price:
|
|
17585
|
-
compareAtPrice:
|
|
17586
|
-
offer:
|
|
17587
|
-
paymentMethods:
|
|
17588
|
-
productContext:
|
|
17589
|
-
productLabel:
|
|
17700
|
+
price: z72.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.'),
|
|
17701
|
+
compareAtPrice: z72.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".'),
|
|
17702
|
+
offer: z72.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.'),
|
|
17703
|
+
paymentMethods: z72.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.'),
|
|
17704
|
+
productContext: z72.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."),
|
|
17705
|
+
productLabel: z72.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.'),
|
|
17590
17706
|
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), excepto "problem_solution", que requiere 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" (idea imposible: un truco visual que en la vida real no podr\xEDa pasar, y al cierre la invitaci\xF3n a comprar), "pixar_problem" (problema animado 3D), "pixar_sassy" (producto que habla). Si el usuario pide algo fuera de esta lista, p\xEDdele una opci\xF3n v\xE1lida.'),
|
|
17591
|
-
durationSeconds:
|
|
17592
|
-
|
|
17593
|
-
|
|
17707
|
+
durationSeconds: z72.union([
|
|
17708
|
+
z72.literal(15),
|
|
17709
|
+
z72.literal(30)
|
|
17594
17710
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
17595
|
-
pauseForAngleReview:
|
|
17596
|
-
aiDecidesAll:
|
|
17711
|
+
pauseForAngleReview: z72.boolean().optional().describe("Compatibilidad heredada. MCP deriva esta pausa de aiDecidesAll: manual siempre pausa y autom\xE1tico siempre la omite. No uses este campo para saltar reviews."),
|
|
17712
|
+
aiDecidesAll: z72.boolean().optional().describe("Mapea el toggle web \u201CDejar que la IA decida todo\u201D. Si true, ProductMaker omite reviews. Act\xEDvalo \xFAnicamente cuando el usuario lo pida expl\xEDcitamente. Omitido/false = reviews conversacionales."),
|
|
17597
17713
|
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.'),
|
|
17598
17714
|
videoStructure: VideoStructureEnum.default("single_take").describe('Opcional. Formato: "single_take" = Un solo clip (generado completo; puede incluir cambios de plano) o "multi_scene" = Multiescena. Default: single_take.'),
|
|
17599
17715
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
17600
17716
|
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).'),
|
|
17601
|
-
videoAngleCount:
|
|
17717
|
+
videoAngleCount: z72.number().int().min(1).max(3).optional().describe("Cantidad de videos a renderizar: 1, 2 o 3. REQUERIDO cuando outputs incluye video (o se omite outputs, cuyo default incluye video); om\xEDtelo s\xF3lo cuando no se generar\xE1 video. Preg\xFAntalo incluso con aiDecidesAll=true porque cambia el costo."),
|
|
17602
17718
|
angleNarratives: PublicNarrativeStyleEnum.array().max(3).optional().describe('Opcional. Narrativa POR \xC1NGULO (posicional). Valores actuales: "review", "ugc_how_to", "ugc_unboxing_chaos", "problem_product_cta" (problema concreto, producto como soluci\xF3n y CTA), "product_showcase", "wearable_showcase", "cinematic", "wild_card", "animated_problem_pixar", "sassy_product_pixar", "market" (narrativa an\xE1lisis de mercado: adapta el video a los patrones ganadores estudiados de la competencia; requiere competitorScanEnabled: true). angleNarratives[i] fuerza la narrativa del \xE1ngulo i; las posiciones restantes las elige la IA. La lista no puede superar videoAngleCount.'),
|
|
17603
|
-
outputs:
|
|
17719
|
+
outputs: z72.array(z72.enum([
|
|
17604
17720
|
"landing",
|
|
17605
17721
|
"video",
|
|
17606
17722
|
"image"
|
|
17607
17723
|
])).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). ${createProductTaskSingleOutputDescription}`),
|
|
17608
|
-
competitorScanEnabled:
|
|
17609
|
-
replicateWinnerWhenFound:
|
|
17610
|
-
brandId:
|
|
17611
|
-
actorId:
|
|
17724
|
+
competitorScanEnabled: z72.boolean().optional().describe("Opcional. Debe enviarse true solo despu\xE9s de que el usuario acepte estudiar la competencia (o si solicita la narrativa an\xE1lisis de mercado). Si la tarea incluye video, true analiza anuncios de la competencia y desbloquea la narrativa an\xE1lisis de mercado; si el estudio no encuentra datos suficientes, degrada al planner cl\xE1sico. Omitir no autoriza el estudio profundo."),
|
|
17725
|
+
replicateWinnerWhenFound: z72.boolean().optional().describe("Conserva la preferencia de copiar un ganador si existe. false estudia el mercado sin reemplazar un \xE1ngulo por el anuncio ganador. No a\xF1ade una pregunta obligatoria."),
|
|
17726
|
+
brandId: z72.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."),
|
|
17727
|
+
actorId: z72.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."),
|
|
17612
17728
|
creativeGender: CreativeGenderEnum.optional().describe('Opcional. QUI\xC9N APARECE EN PANTALLA en todos los creativos de la task: el presentador del video, las personas fotografiadas en la landing y la persona del anuncio. NO es la voz. M\xE1ndalo en cuanto el usuario lo diga en cualquier momento de la conversaci\xF3n y con cualquier redacci\xF3n ("quiero una mujer", "que salga un hombre", "esto es para hombres"): si no lo mandas, el g\xE9nero lo inventa la IA y el usuario recibe lo contrario de lo que pidi\xF3 sin ning\xFAn aviso. "mixed" solo cuando pida expl\xEDcitamente ambos. Si adem\xE1s mandas actorId, el personaje guardado manda sobre este campo.'),
|
|
17613
|
-
creativeDirection:
|
|
17614
|
-
headline:
|
|
17615
|
-
subheadline:
|
|
17729
|
+
creativeDirection: z72.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.'),
|
|
17730
|
+
headline: z72.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."),
|
|
17731
|
+
subheadline: z72.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."),
|
|
17616
17732
|
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".'),
|
|
17617
17733
|
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".')
|
|
17618
17734
|
}).strict();
|
|
17619
|
-
var CreateServiceVideoInput =
|
|
17620
|
-
landingUrl:
|
|
17621
|
-
additionalContext:
|
|
17735
|
+
var CreateServiceVideoInput = z72.object({
|
|
17736
|
+
landingUrl: z72.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
|
|
17737
|
+
additionalContext: z72.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
|
|
17622
17738
|
language: Lang.describe("Idioma del video: es, en o pt."),
|
|
17623
|
-
voiceId:
|
|
17624
|
-
brandId:
|
|
17625
|
-
reviewMode:
|
|
17739
|
+
voiceId: z72.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.'),
|
|
17740
|
+
brandId: z72.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
|
|
17741
|
+
reviewMode: z72.enum([
|
|
17626
17742
|
"automatic",
|
|
17627
17743
|
"guided"
|
|
17628
17744
|
]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
|
|
17629
|
-
videoPreset:
|
|
17745
|
+
videoPreset: z72.enum([
|
|
17630
17746
|
"auto",
|
|
17631
17747
|
"ugc_dynamic",
|
|
17632
17748
|
"ugc_how_to",
|
|
17633
17749
|
"cinematic",
|
|
17634
17750
|
"wild_card"
|
|
17635
|
-
]).default("auto")
|
|
17751
|
+
]).default("auto"),
|
|
17752
|
+
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.')
|
|
17636
17753
|
}).strict();
|
|
17637
|
-
var GetTaskStatusInput =
|
|
17638
|
-
taskId:
|
|
17639
|
-
waitSeconds:
|
|
17754
|
+
var GetTaskStatusInput = z72.object({
|
|
17755
|
+
taskId: z72.string().min(1),
|
|
17756
|
+
waitSeconds: z72.number().int().min(0).max(120).optional()
|
|
17640
17757
|
});
|
|
17641
|
-
var ListTasksInput =
|
|
17642
|
-
limit:
|
|
17643
|
-
offset:
|
|
17644
|
-
search:
|
|
17758
|
+
var ListTasksInput = z72.object({
|
|
17759
|
+
limit: z72.number().int().min(1).max(50).optional(),
|
|
17760
|
+
offset: z72.number().int().min(0).optional(),
|
|
17761
|
+
search: z72.string().optional()
|
|
17645
17762
|
});
|
|
17646
17763
|
var MCP_REVIEW_LIST_FIELD_MAX = 1500;
|
|
17647
17764
|
var MCP_REVIEW_FEATURE_ITEM_MAX = 240;
|
|
17648
|
-
var EditTaskDraftInput =
|
|
17649
|
-
taskId:
|
|
17650
|
-
angleIndex:
|
|
17651
|
-
angle:
|
|
17652
|
-
angle:
|
|
17653
|
-
buyerPersona:
|
|
17654
|
-
actor:
|
|
17655
|
-
actorId:
|
|
17656
|
-
gender:
|
|
17765
|
+
var EditTaskDraftInput = z72.object({
|
|
17766
|
+
taskId: z72.string().min(1),
|
|
17767
|
+
angleIndex: z72.number().int().min(0),
|
|
17768
|
+
angle: z72.object({
|
|
17769
|
+
angle: z72.string().min(1).max(480),
|
|
17770
|
+
buyerPersona: z72.string().min(1).max(360),
|
|
17771
|
+
actor: z72.string().min(1).max(360).optional(),
|
|
17772
|
+
actorId: z72.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."),
|
|
17773
|
+
gender: z72.enum([
|
|
17657
17774
|
"female",
|
|
17658
17775
|
"male"
|
|
17659
17776
|
]).optional(),
|
|
17660
|
-
scriptNotes:
|
|
17777
|
+
scriptNotes: z72.string().max(2e3).optional()
|
|
17661
17778
|
})
|
|
17662
17779
|
});
|
|
17663
|
-
var PendingActionPayload =
|
|
17664
|
-
|
|
17665
|
-
kind:
|
|
17780
|
+
var PendingActionPayload = z72.discriminatedUnion("kind", [
|
|
17781
|
+
z72.object({
|
|
17782
|
+
kind: z72.literal("product_reference_set_approval"),
|
|
17666
17783
|
scope: ProductReferenceScopeEnum.optional(),
|
|
17667
|
-
scopeKey:
|
|
17668
|
-
scopeSnapshotId:
|
|
17669
|
-
expectedScopeHash:
|
|
17784
|
+
scopeKey: z72.string().min(1).max(120).optional(),
|
|
17785
|
+
scopeSnapshotId: z72.string().uuid().optional(),
|
|
17786
|
+
expectedScopeHash: z72.string().min(1).max(128).optional(),
|
|
17670
17787
|
decision: ProductReferenceResolutionDecisionEnum,
|
|
17671
17788
|
reason: ProductReferenceRejectionReasonEnum.optional(),
|
|
17672
|
-
affectedRefKeys:
|
|
17673
|
-
affectedPhotoNumbers:
|
|
17674
|
-
recoveryAction:
|
|
17789
|
+
affectedRefKeys: z72.array(z72.string().min(1).max(200)).min(1).optional(),
|
|
17790
|
+
affectedPhotoNumbers: z72.array(z72.number().int().positive()).min(1).optional(),
|
|
17791
|
+
recoveryAction: z72.enum([
|
|
17675
17792
|
"remove",
|
|
17676
17793
|
"replace",
|
|
17677
17794
|
"upload",
|
|
17678
17795
|
"return_to_selection"
|
|
17679
17796
|
]).optional()
|
|
17680
17797
|
}),
|
|
17681
|
-
|
|
17682
|
-
kind:
|
|
17683
|
-
selectedPhotoNumbers:
|
|
17798
|
+
z72.object({
|
|
17799
|
+
kind: z72.literal("product_reference_confirmation"),
|
|
17800
|
+
selectedPhotoNumbers: z72.array(z72.number().int().positive().max(5)).min(1).max(5).optional().describe("Opcional. N\xFAmeros visibles de las fotos que el usuario quiere conservar; las dem\xE1s se deseleccionan. Debe quedar al menos una."),
|
|
17684
17801
|
userChoice: ProductReferenceUserChoiceEnum.optional(),
|
|
17685
|
-
confirmedProductNames:
|
|
17802
|
+
confirmedProductNames: z72.array(z72.string().min(1).max(120)).min(2).max(8).optional(),
|
|
17686
17803
|
videoStructure: VideoStructureEnum.optional().describe("Opcional. Formato para reanudar el video: single_take (Un solo clip, generado completo; puede incluir cambios de plano) o multi_scene (Multiescena). El backend vuelve a validar que sea compatible con el agrupamiento confirmado."),
|
|
17687
17804
|
videoQuality: VideoQualityEnum.optional().describe("Opcional. Calidad para reanudar el video: economy (Econ\xF3mico), medium (Medio) o pro. El proveedor se elige internamente y el backend vuelve a cotizar la ruta."),
|
|
17688
|
-
useMultiSceneShowcase:
|
|
17805
|
+
useMultiSceneShowcase: z72.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
|
|
17689
17806
|
}),
|
|
17690
|
-
|
|
17691
|
-
kind:
|
|
17807
|
+
z72.object({
|
|
17808
|
+
kind: z72.literal("angle_review_approval"),
|
|
17692
17809
|
// All edits are optional — empty action body just approves the
|
|
17693
17810
|
// backend-generated draft as-is. Field shapes mirror the angle-review
|
|
17694
17811
|
// request contracts in @packages/types/wizard.ts; the handler routes to
|
|
17695
17812
|
// the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
|
|
17696
|
-
customAngle:
|
|
17813
|
+
customAngle: z72.string().min(1).max(480).optional(),
|
|
17697
17814
|
// Keep the shared MCP action within the strictest downstream contract:
|
|
17698
17815
|
// autopilot/image resume endpoints cap these fields at 1500 characters.
|
|
17699
|
-
painPoints:
|
|
17700
|
-
benefits:
|
|
17816
|
+
painPoints: z72.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
17817
|
+
benefits: z72.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
17701
17818
|
// Same policy as the two fields above: the strictest downstream contract
|
|
17702
17819
|
// wins. The image endpoint caps each feature at 240 while landing/video
|
|
17703
17820
|
// accept 300, and this single action routes to whichever the task is — so
|
|
17704
17821
|
// accepting 300 here turns a 250-character feature on an image task into
|
|
17705
17822
|
// an opaque HTTP 400 after the model already believed it had been saved.
|
|
17706
|
-
features:
|
|
17707
|
-
buyerPersona:
|
|
17823
|
+
features: z72.array(z72.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
|
|
17824
|
+
buyerPersona: z72.string().min(1).max(360).optional(),
|
|
17708
17825
|
narrativeStyle: PublicNarrativeStyleEnum.optional().describe('Narrativa del video. "problem_product_cta" (Problema y Soluci\xF3n) requiere Multiescena de 30s: en un video de 15s en formato Un solo clip el servidor la rechaza.'),
|
|
17709
|
-
actor:
|
|
17710
|
-
actorId:
|
|
17711
|
-
creativeDirection:
|
|
17712
|
-
selectedAngleNumbers:
|
|
17713
|
-
angleEdits:
|
|
17714
|
-
angleNumber:
|
|
17715
|
-
narrativeSelection:
|
|
17826
|
+
actor: z72.string().min(1).max(360).optional().describe("Nueva descripci\xF3n del presentador. Al enviarla sin actorId, se elimina autom\xE1ticamente cualquier actor guardado previo de esos \xE1ngulos."),
|
|
17827
|
+
actorId: z72.string().max(120).nullable().optional(),
|
|
17828
|
+
creativeDirection: z72.string().max(2e3).optional(),
|
|
17829
|
+
selectedAngleNumbers: z72.array(z72.number().int().positive()).min(1).max(3).optional().describe("N\xFAmeros visibles (1-based) de los \xE1ngulos que el usuario quiere renderizar. Deben ser \xFAnicos, existir en la review y no superar el videoAngleCount autorizado."),
|
|
17830
|
+
angleEdits: z72.array(z72.object({
|
|
17831
|
+
angleNumber: z72.number().int().positive(),
|
|
17832
|
+
narrativeSelection: z72.enum([
|
|
17716
17833
|
"market",
|
|
17717
17834
|
"guided"
|
|
17718
17835
|
]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
|
|
17719
|
-
angle:
|
|
17720
|
-
buyerPersona:
|
|
17836
|
+
angle: z72.string().min(1).max(480).optional(),
|
|
17837
|
+
buyerPersona: z72.string().min(1).max(360).optional(),
|
|
17721
17838
|
narrativeStyle: PublicNarrativeStyleEnum.optional().describe('Narrativa del video. "problem_product_cta" (Problema y Soluci\xF3n) requiere Multiescena de 30s: en un video de 15s en formato Un solo clip el servidor la rechaza.'),
|
|
17722
|
-
actor:
|
|
17723
|
-
actorId:
|
|
17724
|
-
creativeDirection:
|
|
17839
|
+
actor: z72.string().min(1).max(360).optional(),
|
|
17840
|
+
actorId: z72.string().max(120).nullable().optional(),
|
|
17841
|
+
creativeDirection: z72.string().max(2e3).optional()
|
|
17725
17842
|
}).strict()).max(3).optional().describe("Ediciones independientes por n\xFAmero visible de \xE1ngulo. S\xF3lo se aceptan para \xE1ngulos incluidos en selectedAngleNumbers (o en la selecci\xF3n por defecto)."),
|
|
17726
|
-
gapDurationSeconds:
|
|
17727
|
-
|
|
17728
|
-
|
|
17843
|
+
gapDurationSeconds: z72.union([
|
|
17844
|
+
z72.literal(15),
|
|
17845
|
+
z72.literal(30)
|
|
17729
17846
|
]).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.")
|
|
17730
17847
|
}),
|
|
17731
|
-
|
|
17732
|
-
kind:
|
|
17733
|
-
angleId:
|
|
17734
|
-
angleNumber:
|
|
17735
|
-
content:
|
|
17736
|
-
creativeDirection:
|
|
17737
|
-
actor:
|
|
17848
|
+
z72.object({
|
|
17849
|
+
kind: z72.literal("service_angle_approval"),
|
|
17850
|
+
angleId: z72.string().uuid().optional(),
|
|
17851
|
+
angleNumber: z72.number().int().positive().optional(),
|
|
17852
|
+
content: z72.string().min(1).max(480).optional(),
|
|
17853
|
+
creativeDirection: z72.string().min(1).max(1500).optional(),
|
|
17854
|
+
actor: z72.string().min(1).max(360).optional()
|
|
17738
17855
|
}),
|
|
17739
|
-
|
|
17740
|
-
kind:
|
|
17741
|
-
voiceovers:
|
|
17742
|
-
visualDirections:
|
|
17743
|
-
voiceoversByScene:
|
|
17744
|
-
visualDirectionsByScene:
|
|
17856
|
+
z72.object({
|
|
17857
|
+
kind: z72.literal("service_script_approval"),
|
|
17858
|
+
voiceovers: z72.record(z72.string(), z72.string().min(1).max(600)).optional(),
|
|
17859
|
+
visualDirections: z72.record(z72.string(), z72.string().min(1).max(1200)).optional(),
|
|
17860
|
+
voiceoversByScene: z72.record(z72.string(), z72.string().min(1).max(600)).optional(),
|
|
17861
|
+
visualDirectionsByScene: z72.record(z72.string(), z72.string().min(1).max(1200)).optional()
|
|
17745
17862
|
})
|
|
17746
17863
|
]);
|
|
17747
|
-
var ResolvePendingActionInput =
|
|
17748
|
-
taskId:
|
|
17864
|
+
var ResolvePendingActionInput = z72.object({
|
|
17865
|
+
taskId: z72.string().min(1),
|
|
17749
17866
|
action: PendingActionPayload
|
|
17750
17867
|
}).strict();
|
|
17751
17868
|
function resolveVariantConfirmVideoTier(action) {
|
|
17752
17869
|
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
17753
17870
|
}
|
|
17754
17871
|
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
17755
|
-
var StatusForResolveSchema =
|
|
17872
|
+
var StatusForResolveSchema = z72.object({
|
|
17756
17873
|
// Metadata used to select the backend resume contract. Older API responses
|
|
17757
17874
|
// may omit these fields, so the resolver keeps the generic fallback.
|
|
17758
|
-
kind:
|
|
17875
|
+
kind: z72.enum([
|
|
17759
17876
|
"autopilot",
|
|
17760
17877
|
"video",
|
|
17761
17878
|
"image",
|
|
@@ -17763,18 +17880,18 @@ var StatusForResolveSchema = z71.object({
|
|
|
17763
17880
|
"mix",
|
|
17764
17881
|
"service"
|
|
17765
17882
|
]).optional(),
|
|
17766
|
-
selectedOutputs:
|
|
17883
|
+
selectedOutputs: z72.array(z72.enum([
|
|
17767
17884
|
"landing",
|
|
17768
17885
|
"video",
|
|
17769
17886
|
"image"
|
|
17770
17887
|
])).optional(),
|
|
17771
|
-
videoAngleCount:
|
|
17772
|
-
ugcFormat:
|
|
17888
|
+
videoAngleCount: z72.number().int().min(1).max(3).optional(),
|
|
17889
|
+
ugcFormat: z72.enum([
|
|
17773
17890
|
"single_8s",
|
|
17774
17891
|
"single_15s",
|
|
17775
17892
|
"double_30s"
|
|
17776
17893
|
]).optional(),
|
|
17777
|
-
videoStyle:
|
|
17894
|
+
videoStyle: z72.enum([
|
|
17778
17895
|
"ugc",
|
|
17779
17896
|
"cartoon_3d",
|
|
17780
17897
|
"product_only",
|
|
@@ -17783,7 +17900,7 @@ var StatusForResolveSchema = z71.object({
|
|
|
17783
17900
|
videoStructure: VideoStructureEnum.optional(),
|
|
17784
17901
|
videoQuality: VideoQualityEnum.optional(),
|
|
17785
17902
|
videoRouteId: VideoRouteIdEnum.optional(),
|
|
17786
|
-
videoModel:
|
|
17903
|
+
videoModel: z72.enum([
|
|
17787
17904
|
"veo",
|
|
17788
17905
|
"wan",
|
|
17789
17906
|
"bytedance",
|
|
@@ -17791,71 +17908,71 @@ var StatusForResolveSchema = z71.object({
|
|
|
17791
17908
|
"grok",
|
|
17792
17909
|
"kling"
|
|
17793
17910
|
]).optional(),
|
|
17794
|
-
videoTier:
|
|
17911
|
+
videoTier: z72.enum([
|
|
17795
17912
|
"legacy",
|
|
17796
17913
|
"standard",
|
|
17797
17914
|
"pro",
|
|
17798
17915
|
"single_call"
|
|
17799
17916
|
]).optional(),
|
|
17800
|
-
videoResolution:
|
|
17917
|
+
videoResolution: z72.enum([
|
|
17801
17918
|
"480p",
|
|
17802
17919
|
"720p"
|
|
17803
17920
|
]).optional(),
|
|
17804
17921
|
narrativeStyle: NarrativeStyleEnum.optional(),
|
|
17805
|
-
pauseForVideoScriptReview:
|
|
17806
|
-
pendingUserAction:
|
|
17807
|
-
kind:
|
|
17808
|
-
candidateGrouping:
|
|
17809
|
-
selectedImageUrls:
|
|
17810
|
-
proposedProductNames:
|
|
17922
|
+
pauseForVideoScriptReview: z72.boolean().optional(),
|
|
17923
|
+
pendingUserAction: z72.object({
|
|
17924
|
+
kind: z72.string(),
|
|
17925
|
+
candidateGrouping: z72.string().optional(),
|
|
17926
|
+
selectedImageUrls: z72.array(z72.string()).optional(),
|
|
17927
|
+
proposedProductNames: z72.array(z72.string()).optional(),
|
|
17811
17928
|
// Adaptive reference questions are server-owned. Echo only the evidence
|
|
17812
17929
|
// identity and the choices shown by the current snapshot; never accept a
|
|
17813
17930
|
// client-supplied reference set as authorization.
|
|
17814
|
-
options:
|
|
17815
|
-
mode:
|
|
17931
|
+
options: z72.array(ProductReferenceUserChoiceEnum).max(4).optional(),
|
|
17932
|
+
mode: z72.enum([
|
|
17816
17933
|
"question",
|
|
17817
17934
|
"visual_recovery"
|
|
17818
17935
|
]).optional(),
|
|
17819
17936
|
/** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
|
|
17820
|
-
canKeepSelection:
|
|
17821
|
-
decisionKey:
|
|
17822
|
-
questionOrdinal:
|
|
17823
|
-
questionCeiling:
|
|
17824
|
-
|
|
17825
|
-
|
|
17937
|
+
canKeepSelection: z72.boolean().optional(),
|
|
17938
|
+
decisionKey: z72.string().optional(),
|
|
17939
|
+
questionOrdinal: z72.number().int().min(1).max(5).optional(),
|
|
17940
|
+
questionCeiling: z72.union([
|
|
17941
|
+
z72.literal(3),
|
|
17942
|
+
z72.literal(5)
|
|
17826
17943
|
]).optional(),
|
|
17827
|
-
referenceEvidenceVersion:
|
|
17828
|
-
expectedEvidenceHash:
|
|
17829
|
-
question:
|
|
17830
|
-
prompt:
|
|
17831
|
-
helpText:
|
|
17832
|
-
options:
|
|
17944
|
+
referenceEvidenceVersion: z72.number().int().positive().optional(),
|
|
17945
|
+
expectedEvidenceHash: z72.string().optional(),
|
|
17946
|
+
question: z72.object({
|
|
17947
|
+
prompt: z72.string().min(1).max(240),
|
|
17948
|
+
helpText: z72.string().min(1).max(300).optional(),
|
|
17949
|
+
options: z72.array(z72.object({
|
|
17833
17950
|
value: ProductReferenceUserChoiceEnum,
|
|
17834
|
-
label:
|
|
17835
|
-
description:
|
|
17951
|
+
label: z72.string().min(1).max(120),
|
|
17952
|
+
description: z72.string().min(1).max(240).optional()
|
|
17836
17953
|
})).min(2).max(4)
|
|
17837
17954
|
}).optional(),
|
|
17838
17955
|
scope: ProductReferenceScopeEnum.optional(),
|
|
17839
|
-
scopeKey:
|
|
17840
|
-
scopeSnapshotId:
|
|
17841
|
-
scopeHash:
|
|
17842
|
-
baseReferenceSetHash:
|
|
17843
|
-
phase:
|
|
17956
|
+
scopeKey: z72.string().optional(),
|
|
17957
|
+
scopeSnapshotId: z72.string().uuid().optional(),
|
|
17958
|
+
scopeHash: z72.string().optional(),
|
|
17959
|
+
baseReferenceSetHash: z72.string().optional(),
|
|
17960
|
+
phase: z72.enum([
|
|
17844
17961
|
"preparation",
|
|
17845
17962
|
"final"
|
|
17846
17963
|
]).optional(),
|
|
17847
|
-
selectedRefKeys:
|
|
17848
|
-
allowedDecisions:
|
|
17849
|
-
previews:
|
|
17850
|
-
refKey:
|
|
17964
|
+
selectedRefKeys: z72.array(z72.string().min(1).max(200)).optional(),
|
|
17965
|
+
allowedDecisions: z72.array(ProductReferenceResolutionDecisionEnum).optional(),
|
|
17966
|
+
previews: z72.array(z72.object({
|
|
17967
|
+
refKey: z72.string().min(1).max(200)
|
|
17851
17968
|
}).passthrough()).optional(),
|
|
17852
|
-
customAngleDraft:
|
|
17853
|
-
painPointsDraft:
|
|
17854
|
-
benefitsDraft:
|
|
17855
|
-
featuresDraft:
|
|
17856
|
-
angleOptions:
|
|
17857
|
-
index:
|
|
17858
|
-
angle:
|
|
17969
|
+
customAngleDraft: z72.string().optional(),
|
|
17970
|
+
painPointsDraft: z72.string().optional(),
|
|
17971
|
+
benefitsDraft: z72.string().optional(),
|
|
17972
|
+
featuresDraft: z72.array(z72.string()).optional(),
|
|
17973
|
+
angleOptions: z72.array(z72.object({
|
|
17974
|
+
index: z72.number().int().nonnegative(),
|
|
17975
|
+
angle: z72.string().min(1)
|
|
17859
17976
|
}).passthrough()).min(1).max(5).optional(),
|
|
17860
17977
|
// Recommendation consumed only when the caller explicitly sends
|
|
17861
17978
|
// gapDurationSeconds: 30 in the angle approval action.
|
|
@@ -17865,17 +17982,17 @@ var StatusForResolveSchema = z71.object({
|
|
|
17865
17982
|
// keys. `actorId` (the saved custom actor the picker stored) was silently
|
|
17866
17983
|
// dropped here, so the approval handler below could not echo it back on the
|
|
17867
17984
|
// PATCH — the selection looked accepted and reached no render.
|
|
17868
|
-
angles:
|
|
17869
|
-
id:
|
|
17870
|
-
content:
|
|
17871
|
-
creativeDirection:
|
|
17872
|
-
actor:
|
|
17873
|
-
actorId:
|
|
17985
|
+
angles: z72.array(z72.object({
|
|
17986
|
+
id: z72.string().uuid(),
|
|
17987
|
+
content: z72.string(),
|
|
17988
|
+
creativeDirection: z72.string(),
|
|
17989
|
+
actor: z72.string(),
|
|
17990
|
+
actorId: z72.string().nullable().optional()
|
|
17874
17991
|
}).passthrough()).optional(),
|
|
17875
|
-
panels:
|
|
17876
|
-
beatId:
|
|
17877
|
-
voiceover:
|
|
17878
|
-
visualDirection:
|
|
17992
|
+
panels: z72.array(z72.object({
|
|
17993
|
+
beatId: z72.string(),
|
|
17994
|
+
voiceover: z72.string(),
|
|
17995
|
+
visualDirection: z72.string()
|
|
17879
17996
|
}).passthrough()).optional()
|
|
17880
17997
|
}).optional()
|
|
17881
17998
|
}).passthrough();
|
|
@@ -18101,6 +18218,7 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
18101
18218
|
voiceId: input.voiceId
|
|
18102
18219
|
} : {},
|
|
18103
18220
|
videoPreset: input.videoPreset,
|
|
18221
|
+
videoQuality: input.videoQuality,
|
|
18104
18222
|
reviewMode: input.reviewMode,
|
|
18105
18223
|
...input.brandId ? {
|
|
18106
18224
|
brandId: input.brandId
|
|
@@ -18705,7 +18823,7 @@ __name(registerTaskTools, "registerTaskTools");
|
|
|
18705
18823
|
|
|
18706
18824
|
// src/tools/creatives.ts
|
|
18707
18825
|
import { randomUUID } from "crypto";
|
|
18708
|
-
import { z as
|
|
18826
|
+
import { z as z73 } from "zod";
|
|
18709
18827
|
var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
|
|
18710
18828
|
var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
|
|
18711
18829
|
var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
|
|
@@ -18715,70 +18833,70 @@ var CreativeRefs = {
|
|
|
18715
18833
|
images: ImagesInput,
|
|
18716
18834
|
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.'),
|
|
18717
18835
|
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.'),
|
|
18718
|
-
price:
|
|
18719
|
-
offer:
|
|
18720
|
-
compareAtPrice:
|
|
18721
|
-
productContext:
|
|
18722
|
-
productLabel:
|
|
18723
|
-
buyerPersona:
|
|
18724
|
-
isCombo:
|
|
18725
|
-
competitorScanEnabled:
|
|
18726
|
-
brandId:
|
|
18836
|
+
price: z73.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.'),
|
|
18837
|
+
offer: z73.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.'),
|
|
18838
|
+
compareAtPrice: z73.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
|
|
18839
|
+
productContext: z73.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."),
|
|
18840
|
+
productLabel: z73.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.'),
|
|
18841
|
+
buyerPersona: z73.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.'),
|
|
18842
|
+
isCombo: z73.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
|
|
18843
|
+
competitorScanEnabled: z73.boolean().optional().describe("Opcional. Debe enviarse true solo despu\xE9s de que el usuario acepte estudiar la competencia (o si solicita la narrativa an\xE1lisis de mercado). En video, true analiza anuncios de la competencia y desbloquea la narrativa an\xE1lisis de mercado; si el estudio no encuentra datos suficientes, degrada al planner cl\xE1sico. Omitir no autoriza el estudio profundo."),
|
|
18844
|
+
brandId: z73.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.")
|
|
18727
18845
|
};
|
|
18728
|
-
var VideoPresenter =
|
|
18729
|
-
|
|
18730
|
-
mode:
|
|
18846
|
+
var VideoPresenter = z73.discriminatedUnion("mode", [
|
|
18847
|
+
z73.object({
|
|
18848
|
+
mode: z73.literal("none")
|
|
18731
18849
|
}).strict(),
|
|
18732
|
-
|
|
18733
|
-
mode:
|
|
18734
|
-
actorId:
|
|
18850
|
+
z73.object({
|
|
18851
|
+
mode: z73.literal("saved_actor"),
|
|
18852
|
+
actorId: z73.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
|
|
18735
18853
|
}).strict(),
|
|
18736
|
-
|
|
18737
|
-
mode:
|
|
18738
|
-
description:
|
|
18854
|
+
z73.object({
|
|
18855
|
+
mode: z73.literal("described"),
|
|
18856
|
+
description: z73.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
|
|
18739
18857
|
}).strict()
|
|
18740
18858
|
]);
|
|
18741
|
-
var VideoCreativeSetup =
|
|
18742
|
-
|
|
18743
|
-
mode:
|
|
18859
|
+
var VideoCreativeSetup = z73.discriminatedUnion("mode", [
|
|
18860
|
+
z73.object({
|
|
18861
|
+
mode: z73.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
|
|
18744
18862
|
}).strict(),
|
|
18745
|
-
|
|
18746
|
-
mode:
|
|
18863
|
+
z73.object({
|
|
18864
|
+
mode: z73.literal("guided"),
|
|
18747
18865
|
videoPreset: VideoPresetEnum.default("auto").describe('Narrativa opcional. Con estudio de mercado no la preguntes: se usa "auto" y el estudio define la estructura. Sin estudio conserva la elecci\xF3n del usuario. "problem_solution" requiere 30s.'),
|
|
18748
|
-
buyerPersona:
|
|
18866
|
+
buyerPersona: z73.string().trim().min(1).max(360),
|
|
18749
18867
|
presenter: VideoPresenter,
|
|
18750
|
-
creativeDirection:
|
|
18868
|
+
creativeDirection: z73.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
|
|
18751
18869
|
}).strict()
|
|
18752
18870
|
]);
|
|
18753
|
-
var VideoInput =
|
|
18871
|
+
var VideoInput = z73.object({
|
|
18754
18872
|
images: CreativeRefs.images.optional(),
|
|
18755
18873
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
18756
|
-
title:
|
|
18757
|
-
primaryAngle:
|
|
18874
|
+
title: z73.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
|
|
18875
|
+
primaryAngle: z73.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".'),
|
|
18758
18876
|
language: CreativeRefs.language,
|
|
18759
18877
|
country: CreativeRefs.country,
|
|
18760
|
-
aspectRatio:
|
|
18878
|
+
aspectRatio: z73.enum([
|
|
18761
18879
|
"9:16",
|
|
18762
18880
|
"16:9",
|
|
18763
18881
|
"Auto"
|
|
18764
18882
|
]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
|
|
18765
|
-
durationSeconds:
|
|
18766
|
-
videoAngleCount:
|
|
18883
|
+
durationSeconds: z73.number().int().min(4).max(30).default(15).describe("Opcional. Duraci\xF3n objetivo: Un solo clip Econ\xF3mico o Medio usa 15s; Un solo clip Pro usa 15s o 30s; Multiescena usa 15s o 30s totales. La combinaci\xF3n de formato y calidad determina la ruta y el costo."),
|
|
18884
|
+
videoAngleCount: z73.number().int().min(1).max(3).describe("Cantidad de videos a renderizar: 1, 2 o 3. Es una decisi\xF3n de costo obligatoria: preg\xFAntala incluso cuando creativeSetup.mode=automatic."),
|
|
18767
18885
|
angleNarratives: PublicNarrativeStyleEnum.array().max(3).optional().describe('Opcional. Narrativa POR \xC1NGULO (posicional). Valores actuales: "review", "ugc_how_to", "ugc_unboxing_chaos", "problem_product_cta" (problema concreto, producto como soluci\xF3n y CTA), "product_showcase", "wearable_showcase", "cinematic", "wild_card", "animated_problem_pixar", "sassy_product_pixar", "market" (narrativa an\xE1lisis de mercado: adapta el video a los patrones ganadores estudiados de la competencia; requiere competitorScanEnabled: true). angleNarratives[i] fuerza la narrativa del \xE1ngulo i; las posiciones restantes las elige la IA. La lista no puede superar videoAngleCount.'),
|
|
18768
18886
|
creativeSetup: VideoCreativeSetup.describe("Configuraci\xF3n creativa obligatoria. En guided pregunta narrativa, p\xFAblico, presentador y direcci\xF3n antes de confirmar. Usa automatic s\xF3lo si el usuario deleg\xF3 todo expl\xEDcitamente."),
|
|
18769
18887
|
videoStructure: VideoStructureEnum.default("single_take").describe('Opcional. Formato: "single_take" = Un solo clip (generado completo; puede incluir cambios de plano) o "multi_scene" = Multiescena (varias tomas concatenadas). Default: single_take.'),
|
|
18770
18888
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
|
|
18771
18889
|
videoResolution: VideoResolutionEnum.optional().describe('Opcional. Resoluci\xF3n del render: "480p" o "720p". Si se omite, se usa 480p; elige 720p expl\xEDcitamente si necesitas m\xE1s nitidez.'),
|
|
18772
|
-
features:
|
|
18890
|
+
features: z73.array(z73.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
|
|
18773
18891
|
price: CreativeRefs.price,
|
|
18774
18892
|
offer: CreativeRefs.offer,
|
|
18775
18893
|
productContext: CreativeRefs.productContext,
|
|
18776
18894
|
productLabel: CreativeRefs.productLabel,
|
|
18777
|
-
cta:
|
|
18778
|
-
scriptNotes:
|
|
18895
|
+
cta: z73.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.'),
|
|
18896
|
+
scriptNotes: z73.string().optional().describe('Opcional. Notas/restricciones para el guion (la IA las usa al redactar). Ej. "No mencionar la marca X", "Tono divertido, no cl\xEDnico", "Mencionar 2x1". NO es el guion literal: creativeSetup.mode=guided activa siempre la revisi\xF3n palabra-por-palabra con get_video_script / approve_video_script.'),
|
|
18779
18897
|
creativeGender: CreativeGenderEnum.optional().describe('Opcional. QUI\xC9N APARECE EN PANTALLA en el video: mujer ("female"), hombre ("male") o ambos ("mixed"). NO es la voz; cuando se fija, la voz se alinea sola con el personaje. M\xE1ndalo en cuanto el usuario diga qui\xE9n debe SALIR en el video, con cualquier redacci\xF3n ("quiero una mujer", "que salga un hombre", "protagonista femenina"): si no lo mandas, el g\xE9nero lo inventa la IA y el usuario puede recibir lo contrario de lo que pidi\xF3 sin ning\xFAn aviso. NO lo mandes cuando hable del P\xDABLICO COMPRADOR ("esto es para hombres", "mi p\xFAblico son mujeres", "va dirigido a mam\xE1s"): eso es a qui\xE9n se le vende, no qui\xE9n act\xFAa, y fijarlo ah\xED pinea un protagonista que nadie pidi\xF3. "mixed" solo cuando pida expl\xEDcitamente ambos, y ten en cuenta que no garantiza una mezcla: no fija ning\xFAn g\xE9nero y cada creativo elige su protagonista. No lo preguntes como paso obligatorio. Si creativeSetup.presenter.mode="saved_actor", el personaje guardado manda sobre este campo.'),
|
|
18780
18898
|
competitorScanEnabled: CreativeRefs.competitorScanEnabled,
|
|
18781
|
-
replicateWinnerWhenFound:
|
|
18899
|
+
replicateWinnerWhenFound: z73.boolean().optional().describe("Conserva la preferencia de copiar un ganador si existe. false permite estudiar el mercado sin reemplazar un \xE1ngulo por el anuncio ganador. No a\xF1adas una pregunta obligatoria para este campo."),
|
|
18782
18900
|
brandId: CreativeRefs.brandId
|
|
18783
18901
|
}).strict();
|
|
18784
18902
|
var FreeVideoQualityEnum = VideoQualityEnum;
|
|
@@ -18796,7 +18914,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
|
|
|
18796
18914
|
length: 29
|
|
18797
18915
|
}, (_, index) => index + 2)
|
|
18798
18916
|
};
|
|
18799
|
-
var FreeVideoModelIdEnum =
|
|
18917
|
+
var FreeVideoModelIdEnum = z73.enum([
|
|
18800
18918
|
"grok-imagine-video-1-5-preview",
|
|
18801
18919
|
"minimax-h3/reference-to-video",
|
|
18802
18920
|
"wan/3-0-video",
|
|
@@ -18807,70 +18925,70 @@ var FREE_SELECTABLE_MODEL_IDS = [
|
|
|
18807
18925
|
"minimax-h3/reference-to-video",
|
|
18808
18926
|
"wan/3-0-video"
|
|
18809
18927
|
];
|
|
18810
|
-
var FreeVideoInput =
|
|
18928
|
+
var FreeVideoInput = z73.object({
|
|
18811
18929
|
images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
|
|
18812
|
-
rawPrompt:
|
|
18930
|
+
rawPrompt: z73.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."),
|
|
18813
18931
|
language: CreativeRefs.language,
|
|
18814
18932
|
quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
|
|
18815
18933
|
// Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
|
|
18816
18934
|
// parsed ONLY so the handler can reject it with a message naming its
|
|
18817
18935
|
// replacement — dropping it silently would turn a caller's explicit
|
|
18818
18936
|
// Pro++ pick into a quiet fallback to Wan.
|
|
18819
|
-
freeProModel:
|
|
18937
|
+
freeProModel: z73.enum([
|
|
18820
18938
|
"wan",
|
|
18821
18939
|
"seedance"
|
|
18822
18940
|
]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
|
|
18823
18941
|
modelId: FreeVideoModelIdEnum.optional().describe('Opcional. Elige expl\xEDcitamente el modelo del registro en vez del default de la calidad: "grok-imagine-video-1-5-preview" (Grok 1.5), "minimax-h3/reference-to-video" (H3 Max) o "wan/3-0-video" (Wan 3.0). Om\xEDtelo para usar el modelo por defecto de la calidad elegida. El modelo determina la duraci\xF3n permitida (Grok 6/8/10/15s, H3 Max 4-15s, Wan 2-30s) y el precio. "bytedance/seedance-2-5" est\xE1 inactivo y se rechaza con un error claro, nunca un 500.'),
|
|
18824
|
-
durationSeconds:
|
|
18942
|
+
durationSeconds: z73.number().int().min(2).max(30).describe("Duraci\xF3n exacta. Econ\xF3mico: 6, 8, 10 o 15s; Medio: enteros de 4 a 15s; Pro Wan: 2 a 30s; Pro++ Seedance: 4 a 30s."),
|
|
18825
18943
|
videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
|
|
18826
|
-
generateAiMusic:
|
|
18827
|
-
addSubtitles:
|
|
18828
|
-
idempotencyKey:
|
|
18944
|
+
generateAiMusic: z73.boolean().default(false).describe("Opcional. Agrega m\xFAsica instrumental IA debajo del audio nativo. Default false."),
|
|
18945
|
+
addSubtitles: z73.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
|
|
18946
|
+
idempotencyKey: z73.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.")
|
|
18829
18947
|
}).strict();
|
|
18830
18948
|
var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
|
|
18831
|
-
var ImageCreativeSetup =
|
|
18832
|
-
|
|
18833
|
-
mode:
|
|
18949
|
+
var ImageCreativeSetup = z73.discriminatedUnion("mode", [
|
|
18950
|
+
z73.object({
|
|
18951
|
+
mode: z73.literal("automatic")
|
|
18834
18952
|
}).strict(),
|
|
18835
|
-
|
|
18836
|
-
mode:
|
|
18837
|
-
creativeArchetype:
|
|
18953
|
+
z73.object({
|
|
18954
|
+
mode: z73.literal("guided"),
|
|
18955
|
+
creativeArchetype: z73.union([
|
|
18838
18956
|
ImageCreativeArchetypeEnum,
|
|
18839
|
-
|
|
18957
|
+
z73.literal("ai_decides")
|
|
18840
18958
|
]),
|
|
18841
|
-
visualTreatment:
|
|
18959
|
+
visualTreatment: z73.union([
|
|
18842
18960
|
ImageCreativeVisualTreatmentEnum,
|
|
18843
|
-
|
|
18961
|
+
z73.literal("ai_decides")
|
|
18844
18962
|
]),
|
|
18845
18963
|
aspectRatio: ImageCreativeAspectRatioEnum,
|
|
18846
|
-
nVariants:
|
|
18847
|
-
|
|
18848
|
-
|
|
18849
|
-
|
|
18850
|
-
|
|
18851
|
-
|
|
18964
|
+
nVariants: z73.union([
|
|
18965
|
+
z73.literal(1),
|
|
18966
|
+
z73.literal(2),
|
|
18967
|
+
z73.literal(3),
|
|
18968
|
+
z73.literal(4),
|
|
18969
|
+
z73.literal(6)
|
|
18852
18970
|
]),
|
|
18853
|
-
imageModel:
|
|
18971
|
+
imageModel: z73.enum([
|
|
18854
18972
|
"gpt-image-2-5:1k",
|
|
18855
18973
|
"gpt-image-2-5:2k",
|
|
18856
18974
|
"gpt-image-2:1k",
|
|
18857
18975
|
"gpt-image-2:2k"
|
|
18858
18976
|
]),
|
|
18859
|
-
styleMix:
|
|
18860
|
-
generateAdCopy:
|
|
18861
|
-
competitorScanEnabled:
|
|
18862
|
-
productContext:
|
|
18863
|
-
creativeDirection:
|
|
18864
|
-
brandColors:
|
|
18865
|
-
headline:
|
|
18866
|
-
subheadline:
|
|
18977
|
+
styleMix: z73.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
|
|
18978
|
+
generateAdCopy: z73.boolean(),
|
|
18979
|
+
competitorScanEnabled: z73.boolean(),
|
|
18980
|
+
productContext: z73.string().trim().min(1).max(3e3).nullable(),
|
|
18981
|
+
creativeDirection: z73.string().trim().min(1).max(500).nullable(),
|
|
18982
|
+
brandColors: z73.string().trim().min(1).max(240).nullable().describe('Colores en lenguaje natural, igual que en el chat web. Ej. "Azul y Dorado". null significa sin colores espec\xEDficos.'),
|
|
18983
|
+
headline: z73.string().trim().min(1).max(120).nullable(),
|
|
18984
|
+
subheadline: z73.string().trim().min(1).max(160).nullable()
|
|
18867
18985
|
}).strict()
|
|
18868
18986
|
]).superRefine((setup, context) => {
|
|
18869
18987
|
if (setup.mode !== "guided") return;
|
|
18870
18988
|
const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
|
|
18871
18989
|
if (needsStyleMix && setup.styleMix === null) {
|
|
18872
18990
|
context.addIssue({
|
|
18873
|
-
code:
|
|
18991
|
+
code: z73.ZodIssueCode.custom,
|
|
18874
18992
|
path: [
|
|
18875
18993
|
"styleMix"
|
|
18876
18994
|
],
|
|
@@ -18879,7 +18997,7 @@ var ImageCreativeSetup = z72.discriminatedUnion("mode", [
|
|
|
18879
18997
|
}
|
|
18880
18998
|
if (!needsStyleMix && setup.styleMix !== null) {
|
|
18881
18999
|
context.addIssue({
|
|
18882
|
-
code:
|
|
19000
|
+
code: z73.ZodIssueCode.custom,
|
|
18883
19001
|
path: [
|
|
18884
19002
|
"styleMix"
|
|
18885
19003
|
],
|
|
@@ -18888,7 +19006,7 @@ var ImageCreativeSetup = z72.discriminatedUnion("mode", [
|
|
|
18888
19006
|
}
|
|
18889
19007
|
if ((setup.imageModel === "gpt-image-2:2k" || setup.imageModel === "gpt-image-2-5:2k") && setup.aspectRatio === "4:5") {
|
|
18890
19008
|
context.addIssue({
|
|
18891
|
-
code:
|
|
19009
|
+
code: z73.ZodIssueCode.custom,
|
|
18892
19010
|
path: [
|
|
18893
19011
|
"aspectRatio"
|
|
18894
19012
|
],
|
|
@@ -18896,53 +19014,53 @@ var ImageCreativeSetup = z72.discriminatedUnion("mode", [
|
|
|
18896
19014
|
});
|
|
18897
19015
|
}
|
|
18898
19016
|
});
|
|
18899
|
-
var LandingCreativeSetup =
|
|
18900
|
-
|
|
18901
|
-
mode:
|
|
19017
|
+
var LandingCreativeSetup = z73.discriminatedUnion("mode", [
|
|
19018
|
+
z73.object({
|
|
19019
|
+
mode: z73.literal("automatic")
|
|
18902
19020
|
}).strict(),
|
|
18903
|
-
|
|
18904
|
-
mode:
|
|
19021
|
+
z73.object({
|
|
19022
|
+
mode: z73.literal("guided"),
|
|
18905
19023
|
landingStrategy: LandingStrategyEnum,
|
|
18906
19024
|
landingImageFormat: LandingImageFormatEnum,
|
|
18907
|
-
competitorScanEnabled:
|
|
18908
|
-
paymentMethods:
|
|
18909
|
-
productContext:
|
|
18910
|
-
creativeDirection:
|
|
18911
|
-
headline:
|
|
18912
|
-
subheadline:
|
|
19025
|
+
competitorScanEnabled: z73.boolean(),
|
|
19026
|
+
paymentMethods: z73.string().trim().min(1).max(240).nullable(),
|
|
19027
|
+
productContext: z73.string().trim().min(1).max(3e3).nullable(),
|
|
19028
|
+
creativeDirection: z73.string().trim().min(1).max(500).nullable(),
|
|
19029
|
+
headline: z73.string().trim().min(1).max(120).nullable(),
|
|
19030
|
+
subheadline: z73.string().trim().min(1).max(160).nullable()
|
|
18913
19031
|
}).strict()
|
|
18914
19032
|
]);
|
|
18915
|
-
var ImageInput =
|
|
19033
|
+
var ImageInput = z73.object({
|
|
18916
19034
|
images: CreativeRefs.images.optional(),
|
|
18917
19035
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
18918
|
-
productTitle:
|
|
18919
|
-
primaryAngle:
|
|
19036
|
+
productTitle: z73.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
|
|
19037
|
+
primaryAngle: z73.string().min(1).optional().describe('Opcional. \xC1ngulo de venta principal. Si se omite, ProductMaker lo genera y creativeSetup.mode="guided" lo muestra para revisi\xF3n antes de crear las im\xE1genes.'),
|
|
18920
19038
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
18921
19039
|
language: CreativeRefs.language,
|
|
18922
19040
|
country: CreativeRefs.country,
|
|
18923
19041
|
creativeSetup: ImageCreativeSetup.describe("Configuraci\xF3n obligatoria equivalente al wizard web. Usa guided salvo que el usuario delegue expl\xEDcitamente todo; presenta las decisiones guiadas en un \xFAnico checklist compacto."),
|
|
18924
19042
|
imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
|
|
18925
|
-
features:
|
|
19043
|
+
features: z73.array(z73.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
|
|
18926
19044
|
price: CreativeRefs.price,
|
|
18927
|
-
omitPrice:
|
|
19045
|
+
omitPrice: z73.boolean().optional().describe("Pon true \xFAnicamente cuando el usuario pida expl\xEDcitamente una imagen sin precio. Evita que el backend reutilice un precio extra\xEDdo del producto. No lo combines con price ni compareAtPrice."),
|
|
18928
19046
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
18929
19047
|
offer: CreativeRefs.offer,
|
|
18930
19048
|
productLabel: CreativeRefs.productLabel,
|
|
18931
19049
|
isCombo: CreativeRefs.isCombo,
|
|
18932
19050
|
brandId: CreativeRefs.brandId
|
|
18933
19051
|
});
|
|
18934
|
-
var EditImageCreativeInput =
|
|
18935
|
-
taskId:
|
|
18936
|
-
variantIndex:
|
|
18937
|
-
instruction:
|
|
19052
|
+
var EditImageCreativeInput = z73.object({
|
|
19053
|
+
taskId: z73.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
|
|
19054
|
+
variantIndex: z73.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
|
|
19055
|
+
instruction: z73.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".')
|
|
18938
19056
|
});
|
|
18939
|
-
var LandingInput =
|
|
19057
|
+
var LandingInput = z73.object({
|
|
18940
19058
|
images: CreativeRefs.images.optional(),
|
|
18941
19059
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
18942
19060
|
language: CreativeRefs.language,
|
|
18943
19061
|
country: CreativeRefs.country,
|
|
18944
19062
|
creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
|
|
18945
|
-
salesAngle:
|
|
19063
|
+
salesAngle: z73.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.'),
|
|
18946
19064
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
18947
19065
|
price: CreativeRefs.price,
|
|
18948
19066
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
@@ -19204,10 +19322,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
19204
19322
|
__name(registerCreativeTools, "registerCreativeTools");
|
|
19205
19323
|
|
|
19206
19324
|
// src/tools/creative-variants.ts
|
|
19207
|
-
import { z as
|
|
19325
|
+
import { z as z74 } from "zod";
|
|
19208
19326
|
var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
|
|
19209
19327
|
var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
|
|
19210
|
-
var LandingSectionKeyEnum =
|
|
19328
|
+
var LandingSectionKeyEnum = z74.enum([
|
|
19211
19329
|
"problem_hook",
|
|
19212
19330
|
"problem_cost",
|
|
19213
19331
|
"solution_mechanism",
|
|
@@ -19247,24 +19365,24 @@ var LandingSectionKeyEnum = z73.enum([
|
|
|
19247
19365
|
"lifestyle_fit",
|
|
19248
19366
|
"join_lifestyle"
|
|
19249
19367
|
]);
|
|
19250
|
-
var CreativeVariantKindEnum =
|
|
19368
|
+
var CreativeVariantKindEnum = z74.enum([
|
|
19251
19369
|
"video",
|
|
19252
19370
|
"image",
|
|
19253
19371
|
"landing"
|
|
19254
19372
|
]);
|
|
19255
|
-
var EstimateCreativeVariantInputBase =
|
|
19256
|
-
sourceTaskId:
|
|
19373
|
+
var EstimateCreativeVariantInputBase = z74.object({
|
|
19374
|
+
sourceTaskId: z74.string().uuid().describe("ID de la tarea original completada."),
|
|
19257
19375
|
kind: CreativeVariantKindEnum,
|
|
19258
19376
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
|
|
19259
19377
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
|
|
19260
|
-
nVariants:
|
|
19378
|
+
nVariants: z74.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
19261
19379
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
|
|
19262
|
-
instructions:
|
|
19380
|
+
instructions: z74.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.")
|
|
19263
19381
|
}).strict();
|
|
19264
19382
|
var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
19265
19383
|
if (input.kind === "video" && input.nVariants !== void 0) {
|
|
19266
19384
|
ctx.addIssue({
|
|
19267
|
-
code:
|
|
19385
|
+
code: z74.ZodIssueCode.custom,
|
|
19268
19386
|
path: [
|
|
19269
19387
|
"nVariants"
|
|
19270
19388
|
],
|
|
@@ -19274,7 +19392,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
19274
19392
|
if (input.kind !== "video") {
|
|
19275
19393
|
if (input.videoPreset !== void 0) {
|
|
19276
19394
|
ctx.addIssue({
|
|
19277
|
-
code:
|
|
19395
|
+
code: z74.ZodIssueCode.custom,
|
|
19278
19396
|
path: [
|
|
19279
19397
|
"videoPreset"
|
|
19280
19398
|
],
|
|
@@ -19283,7 +19401,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
19283
19401
|
}
|
|
19284
19402
|
if (input.videoResolution !== void 0) {
|
|
19285
19403
|
ctx.addIssue({
|
|
19286
|
-
code:
|
|
19404
|
+
code: z74.ZodIssueCode.custom,
|
|
19287
19405
|
path: [
|
|
19288
19406
|
"videoResolution"
|
|
19289
19407
|
],
|
|
@@ -19293,7 +19411,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
19293
19411
|
}
|
|
19294
19412
|
if (input.kind !== "image" && input.nVariants !== void 0) {
|
|
19295
19413
|
ctx.addIssue({
|
|
19296
|
-
code:
|
|
19414
|
+
code: z74.ZodIssueCode.custom,
|
|
19297
19415
|
path: [
|
|
19298
19416
|
"nVariants"
|
|
19299
19417
|
],
|
|
@@ -19303,7 +19421,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
19303
19421
|
if (input.kind !== "landing") {
|
|
19304
19422
|
if (input.sectionKey !== void 0) {
|
|
19305
19423
|
ctx.addIssue({
|
|
19306
|
-
code:
|
|
19424
|
+
code: z74.ZodIssueCode.custom,
|
|
19307
19425
|
path: [
|
|
19308
19426
|
"sectionKey"
|
|
19309
19427
|
],
|
|
@@ -19312,7 +19430,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
19312
19430
|
}
|
|
19313
19431
|
if (input.instructions !== void 0) {
|
|
19314
19432
|
ctx.addIssue({
|
|
19315
|
-
code:
|
|
19433
|
+
code: z74.ZodIssueCode.custom,
|
|
19316
19434
|
path: [
|
|
19317
19435
|
"instructions"
|
|
19318
19436
|
],
|
|
@@ -19321,31 +19439,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
19321
19439
|
}
|
|
19322
19440
|
}
|
|
19323
19441
|
});
|
|
19324
|
-
var CreateCreativeVariantInputBase =
|
|
19325
|
-
sourceTaskId:
|
|
19442
|
+
var CreateCreativeVariantInputBase = z74.object({
|
|
19443
|
+
sourceTaskId: z74.string().uuid().describe("ID de la tarea original completada."),
|
|
19326
19444
|
kind: CreativeVariantKindEnum,
|
|
19327
|
-
confirm:
|
|
19328
|
-
clientRequestId:
|
|
19329
|
-
angle:
|
|
19330
|
-
buyerPersona:
|
|
19331
|
-
scriptNotes:
|
|
19332
|
-
creativeDirection:
|
|
19445
|
+
confirm: z74.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
|
|
19446
|
+
clientRequestId: z74.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."),
|
|
19447
|
+
angle: z74.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
|
|
19448
|
+
buyerPersona: z74.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
|
|
19449
|
+
scriptNotes: z74.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
|
|
19450
|
+
creativeDirection: z74.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
|
|
19333
19451
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
|
|
19334
19452
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
|
|
19335
|
-
generateAiMusic:
|
|
19336
|
-
nVariants:
|
|
19453
|
+
generateAiMusic: z74.boolean().optional().describe("Opcional para video."),
|
|
19454
|
+
nVariants: z74.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
19337
19455
|
imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
|
|
19338
19456
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
|
|
19339
19457
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
|
|
19340
19458
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
|
|
19341
|
-
styleMix:
|
|
19459
|
+
styleMix: z74.boolean().optional().describe("Opcional para imagen."),
|
|
19342
19460
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
|
|
19343
|
-
instructions:
|
|
19461
|
+
instructions: z74.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.")
|
|
19344
19462
|
}).strict();
|
|
19345
19463
|
var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
19346
19464
|
if ((input.kind === "video" || input.kind === "image") && !input.angle) {
|
|
19347
19465
|
ctx.addIssue({
|
|
19348
|
-
code:
|
|
19466
|
+
code: z74.ZodIssueCode.custom,
|
|
19349
19467
|
path: [
|
|
19350
19468
|
"angle"
|
|
19351
19469
|
],
|
|
@@ -19354,7 +19472,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
19354
19472
|
}
|
|
19355
19473
|
if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
|
|
19356
19474
|
ctx.addIssue({
|
|
19357
|
-
code:
|
|
19475
|
+
code: z74.ZodIssueCode.custom,
|
|
19358
19476
|
path: [
|
|
19359
19477
|
"instructions"
|
|
19360
19478
|
],
|
|
@@ -19400,7 +19518,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
19400
19518
|
for (const field of fieldsByKind[input.kind]) {
|
|
19401
19519
|
if (input[field] !== void 0) {
|
|
19402
19520
|
ctx.addIssue({
|
|
19403
|
-
code:
|
|
19521
|
+
code: z74.ZodIssueCode.custom,
|
|
19404
19522
|
path: [
|
|
19405
19523
|
field
|
|
19406
19524
|
],
|
|
@@ -19517,32 +19635,32 @@ function registerCreativeVariantTools(server, api) {
|
|
|
19517
19635
|
__name(registerCreativeVariantTools, "registerCreativeVariantTools");
|
|
19518
19636
|
|
|
19519
19637
|
// src/tools/script-review.ts
|
|
19520
|
-
import { z as
|
|
19638
|
+
import { z as z75 } from "zod";
|
|
19521
19639
|
var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
|
|
19522
19640
|
var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
|
|
19523
19641
|
var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
|
|
19524
|
-
var GetVideoScriptInput =
|
|
19525
|
-
taskId:
|
|
19526
|
-
angleKey:
|
|
19642
|
+
var GetVideoScriptInput = z75.object({
|
|
19643
|
+
taskId: z75.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
|
|
19644
|
+
angleKey: z75.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.')
|
|
19527
19645
|
}).strict();
|
|
19528
19646
|
var VIDEO_SCRIPT_APPROVAL_MAX_SCENES2 = 50;
|
|
19529
19647
|
var VIDEO_SCRIPT_APPROVAL_MAX_DIALOGUE_CHARS2 = 2e3;
|
|
19530
|
-
var ApproveSceneEdit =
|
|
19531
|
-
index:
|
|
19532
|
-
dialogue:
|
|
19648
|
+
var ApproveSceneEdit = z75.object({
|
|
19649
|
+
index: z75.number().int().nonnegative().describe("\xCDndice de la escena (0-based, mismo que devuelve get_video_script)."),
|
|
19650
|
+
dialogue: z75.string().min(1).max(VIDEO_SCRIPT_APPROVAL_MAX_DIALOGUE_CHARS2).refine((v) => v.trim().length > 0, {
|
|
19533
19651
|
message: "dialogue no puede ser s\xF3lo espacios"
|
|
19534
19652
|
}).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.")
|
|
19535
19653
|
}).strict();
|
|
19536
|
-
var ApproveVideoScriptInput =
|
|
19537
|
-
taskId:
|
|
19538
|
-
angleKey:
|
|
19539
|
-
scenes:
|
|
19654
|
+
var ApproveVideoScriptInput = z75.object({
|
|
19655
|
+
taskId: z75.string().min(1).describe("ID de la tarea."),
|
|
19656
|
+
angleKey: z75.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.'),
|
|
19657
|
+
scenes: z75.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.")
|
|
19540
19658
|
}).strict();
|
|
19541
|
-
var RegenerateVideoScriptInput =
|
|
19542
|
-
taskId:
|
|
19543
|
-
angleKey:
|
|
19659
|
+
var RegenerateVideoScriptInput = z75.object({
|
|
19660
|
+
taskId: z75.string().min(1).describe("ID de la tarea."),
|
|
19661
|
+
angleKey: z75.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.'),
|
|
19544
19662
|
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).'),
|
|
19545
|
-
narrativeSelection:
|
|
19663
|
+
narrativeSelection: z75.enum([
|
|
19546
19664
|
"market",
|
|
19547
19665
|
"guided"
|
|
19548
19666
|
]).optional().describe("Elecci\xF3n expl\xEDcita del usuario: market usa el estudio de mercado disponible; guided usa la narrativa elegida. Omitir conserva el comportamiento existente.")
|
|
@@ -19623,14 +19741,14 @@ function registerScriptReviewTools(server, api) {
|
|
|
19623
19741
|
__name(registerScriptReviewTools, "registerScriptReviewTools");
|
|
19624
19742
|
|
|
19625
19743
|
// src/tools/connections.ts
|
|
19626
|
-
import { z as
|
|
19744
|
+
import { z as z76 } from "zod";
|
|
19627
19745
|
var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
|
|
19628
19746
|
var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
|
|
19629
19747
|
var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
|
|
19630
19748
|
var listMetaDestinationsGuidance = getProductMakerCapabilityModelGuidance("list_meta_destinations");
|
|
19631
19749
|
var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list_tiktok_advertisers");
|
|
19632
19750
|
function registerConnectionTools(server, api) {
|
|
19633
|
-
server.tool("list_shopify_shops", listShopifyShopsGuidance.summary + " Si la lista est\xE1 vac\xEDa, dile al usuario que conecte una tienda en productmaker.app/integrations antes de intentar publicar.",
|
|
19751
|
+
server.tool("list_shopify_shops", listShopifyShopsGuidance.summary + " Si la lista est\xE1 vac\xEDa, dile al usuario que conecte una tienda en productmaker.app/integrations antes de intentar publicar.", z76.object({}).shape, READS_INTERNAL, async () => {
|
|
19634
19752
|
try {
|
|
19635
19753
|
const r = await api.getJson("/v1/shopify/shops");
|
|
19636
19754
|
return asText(r);
|
|
@@ -19638,10 +19756,10 @@ function registerConnectionTools(server, api) {
|
|
|
19638
19756
|
throw translateError(e);
|
|
19639
19757
|
}
|
|
19640
19758
|
});
|
|
19641
|
-
server.tool("list_shopify_products", listShopifyProductsGuidance.summary + ' Usa el `id` devuelto junto con `publicationMode="existing"` en `publish_to_shopify`. Si `taskId` se proporciona, la respuesta tambi\xE9n indica el producto publicado actualmente para esa tarea y tienda. No modifica Shopify.',
|
|
19642
|
-
shopDomain:
|
|
19643
|
-
query:
|
|
19644
|
-
taskId:
|
|
19759
|
+
server.tool("list_shopify_products", listShopifyProductsGuidance.summary + ' Usa el `id` devuelto junto con `publicationMode="existing"` en `publish_to_shopify`. Si `taskId` se proporciona, la respuesta tambi\xE9n indica el producto publicado actualmente para esa tarea y tienda. No modifica Shopify.', z76.object({
|
|
19760
|
+
shopDomain: z76.string().min(3).max(120),
|
|
19761
|
+
query: z76.string().trim().max(120).optional(),
|
|
19762
|
+
taskId: z76.string().uuid().optional()
|
|
19645
19763
|
}).shape, READS_EXTERNAL, async ({ shopDomain, query, taskId }) => {
|
|
19646
19764
|
try {
|
|
19647
19765
|
const params = new URLSearchParams({
|
|
@@ -19655,7 +19773,7 @@ function registerConnectionTools(server, api) {
|
|
|
19655
19773
|
throw translateError(e);
|
|
19656
19774
|
}
|
|
19657
19775
|
});
|
|
19658
|
-
server.tool("list_meta_ad_accounts", listMetaAdAccountsGuidance.summary + " Para publicar, prefiere `list_meta_destinations`, que tambi\xE9n devuelve el portfolio y las p\xE1ginas disponibles. Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar Meta en productmaker.app/integrations.",
|
|
19776
|
+
server.tool("list_meta_ad_accounts", listMetaAdAccountsGuidance.summary + " Para publicar, prefiere `list_meta_destinations`, que tambi\xE9n devuelve el portfolio y las p\xE1ginas disponibles. Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar Meta en productmaker.app/integrations.", z76.object({}).shape, READS_EXTERNAL, async () => {
|
|
19659
19777
|
try {
|
|
19660
19778
|
const r = await api.getJson("/v1/facebook/ad-accounts");
|
|
19661
19779
|
return asText(r);
|
|
@@ -19665,7 +19783,7 @@ function registerConnectionTools(server, api) {
|
|
|
19665
19783
|
});
|
|
19666
19784
|
server.registerTool("list_meta_destinations", {
|
|
19667
19785
|
description: listMetaDestinationsGuidance.summary + " Es obligatorio llamar esta herramienta antes de publicar, mostrar las opciones y enviar al publicador el `portfolioId`, `adAccountId` y `pageId` elegidos; nunca elijas silenciosamente la primera p\xE1gina o cuenta. No modifica Meta.",
|
|
19668
|
-
inputSchema:
|
|
19786
|
+
inputSchema: z76.object({}).shape,
|
|
19669
19787
|
annotations: READS_EXTERNAL,
|
|
19670
19788
|
_meta: {
|
|
19671
19789
|
"openai/widgetAccessible": true
|
|
@@ -19678,7 +19796,7 @@ function registerConnectionTools(server, api) {
|
|
|
19678
19796
|
throw translateError(e);
|
|
19679
19797
|
}
|
|
19680
19798
|
});
|
|
19681
|
-
server.tool("list_tiktok_advertisers", listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
|
|
19799
|
+
server.tool("list_tiktok_advertisers", listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.", z76.object({}).shape, READS_EXTERNAL, async () => {
|
|
19682
19800
|
try {
|
|
19683
19801
|
const r = await api.getJson("/v1/tiktok/advertisers");
|
|
19684
19802
|
return asText(r);
|
|
@@ -19690,10 +19808,10 @@ function registerConnectionTools(server, api) {
|
|
|
19690
19808
|
__name(registerConnectionTools, "registerConnectionTools");
|
|
19691
19809
|
|
|
19692
19810
|
// src/tools/actors.ts
|
|
19693
|
-
import { z as
|
|
19811
|
+
import { z as z77 } from "zod";
|
|
19694
19812
|
var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
|
|
19695
19813
|
function registerActorTools(server, api) {
|
|
19696
|
-
server.tool("list_actors", listActorsGuidance.summary + " 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.",
|
|
19814
|
+
server.tool("list_actors", listActorsGuidance.summary + " 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.", z77.object({}).shape, READS_INTERNAL, async () => {
|
|
19697
19815
|
try {
|
|
19698
19816
|
const rows = await api.getJson("/v1/actors");
|
|
19699
19817
|
const actors = (Array.isArray(rows) ? rows : []).filter((actor) => actor.status === "ready").map(({ id, name, description, gender, voiceId }) => ({
|
|
@@ -19714,7 +19832,7 @@ function registerActorTools(server, api) {
|
|
|
19714
19832
|
__name(registerActorTools, "registerActorTools");
|
|
19715
19833
|
|
|
19716
19834
|
// src/tools/publish.ts
|
|
19717
|
-
import { z as
|
|
19835
|
+
import { z as z78 } from "zod";
|
|
19718
19836
|
|
|
19719
19837
|
// src/tools/stable-uuid.ts
|
|
19720
19838
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -19786,40 +19904,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
|
|
|
19786
19904
|
var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
|
|
19787
19905
|
var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
|
|
19788
19906
|
var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
|
|
19789
|
-
var ShopifyInput =
|
|
19790
|
-
taskId:
|
|
19791
|
-
shopDomain:
|
|
19907
|
+
var ShopifyInput = z78.object({
|
|
19908
|
+
taskId: z78.string().min(1),
|
|
19909
|
+
shopDomain: z78.string().min(1),
|
|
19792
19910
|
/** Override: number of landing images to include. Default = ALL images the
|
|
19793
19911
|
* task generated (the MCP fetches /v1/results first to count). Bounded
|
|
19794
19912
|
* generously here; the backend validates each index against
|
|
19795
19913
|
* landing.images.length and rejects out-of-range. */
|
|
19796
|
-
numLandingImages:
|
|
19797
|
-
variantIndex:
|
|
19914
|
+
numLandingImages: z78.number().int().min(1).max(20).optional(),
|
|
19915
|
+
variantIndex: z78.number().int().min(0).optional(),
|
|
19798
19916
|
/** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
|
|
19799
19917
|
* When true, the landing renders variant-picker pills; when false, it ships
|
|
19800
19918
|
* a single-option product page. Defaults to false. */
|
|
19801
|
-
showVariantPicker:
|
|
19919
|
+
showVariantPicker: z78.boolean().optional(),
|
|
19802
19920
|
/** Default `auto` updates the product previously published for this task and
|
|
19803
19921
|
* shop. Use `existing` with targetProductId to choose another product, or
|
|
19804
19922
|
* `new` only when the user explicitly wants a duplicate/new listing. */
|
|
19805
|
-
publicationMode:
|
|
19923
|
+
publicationMode: z78.enum([
|
|
19806
19924
|
"auto",
|
|
19807
19925
|
"existing",
|
|
19808
19926
|
"new"
|
|
19809
19927
|
]).optional(),
|
|
19810
19928
|
/** Shopify product GID, numeric id, or admin product URL. Required when
|
|
19811
19929
|
* publicationMode is `existing`. */
|
|
19812
|
-
targetProductId:
|
|
19930
|
+
targetProductId: z78.string().trim().min(1).max(300).optional(),
|
|
19813
19931
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
19814
|
-
announcementBarEnabled:
|
|
19815
|
-
announcementBarText:
|
|
19932
|
+
announcementBarEnabled: z78.boolean().optional(),
|
|
19933
|
+
announcementBarText: z78.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
|
|
19816
19934
|
commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
|
|
19817
|
-
confirmed:
|
|
19935
|
+
confirmed: z78.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
|
|
19818
19936
|
});
|
|
19819
19937
|
var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
|
|
19820
19938
|
if (value.commerceCorrection && value.confirmed !== true) {
|
|
19821
19939
|
ctx.addIssue({
|
|
19822
|
-
code:
|
|
19940
|
+
code: z78.ZodIssueCode.custom,
|
|
19823
19941
|
path: [
|
|
19824
19942
|
"confirmed"
|
|
19825
19943
|
],
|
|
@@ -19828,7 +19946,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
19828
19946
|
}
|
|
19829
19947
|
if (value.announcementBarEnabled && !value.announcementBarText) {
|
|
19830
19948
|
ctx.addIssue({
|
|
19831
|
-
code:
|
|
19949
|
+
code: z78.ZodIssueCode.custom,
|
|
19832
19950
|
path: [
|
|
19833
19951
|
"announcementBarText"
|
|
19834
19952
|
],
|
|
@@ -19837,7 +19955,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
19837
19955
|
}
|
|
19838
19956
|
if (!value.announcementBarEnabled && value.announcementBarText) {
|
|
19839
19957
|
ctx.addIssue({
|
|
19840
|
-
code:
|
|
19958
|
+
code: z78.ZodIssueCode.custom,
|
|
19841
19959
|
path: [
|
|
19842
19960
|
"announcementBarText"
|
|
19843
19961
|
],
|
|
@@ -19851,91 +19969,91 @@ function parseShopifyInput(rawInput) {
|
|
|
19851
19969
|
return parsed.data;
|
|
19852
19970
|
}
|
|
19853
19971
|
__name(parseShopifyInput, "parseShopifyInput");
|
|
19854
|
-
var McpCampaignConfig =
|
|
19972
|
+
var McpCampaignConfig = z78.object({
|
|
19855
19973
|
/** ALWAYS in US dollars, whatever the ad account's currency is. ProductMaker
|
|
19856
19974
|
* converts to the account currency server-side. Do NOT pre-convert: on a COP
|
|
19857
19975
|
* account the user's "60.000 al día" is `dailyBudgetUsd: 15`, not 60000. */
|
|
19858
|
-
dailyBudgetUsd:
|
|
19976
|
+
dailyBudgetUsd: z78.number().positive().optional(),
|
|
19859
19977
|
/** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
|
|
19860
19978
|
* normalizes at validation). Meta accepts max 1 (single-country ad set).
|
|
19861
19979
|
* TikTok takes only the first entry. */
|
|
19862
|
-
targetCountries:
|
|
19863
|
-
campaignName:
|
|
19980
|
+
targetCountries: z78.array(CountryIso2Schema).max(1).optional(),
|
|
19981
|
+
campaignName: z78.string().trim().min(1).max(100).optional()
|
|
19864
19982
|
});
|
|
19865
19983
|
var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
|
|
19866
|
-
var MetaInput =
|
|
19867
|
-
taskId:
|
|
19984
|
+
var MetaInput = z78.object({
|
|
19985
|
+
taskId: z78.string().min(1),
|
|
19868
19986
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
19869
|
-
portfolioId:
|
|
19987
|
+
portfolioId: z78.string().trim().min(1),
|
|
19870
19988
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
19871
|
-
pageId:
|
|
19989
|
+
pageId: z78.string().trim().min(1),
|
|
19872
19990
|
adAccountId: McpAdAccountId,
|
|
19873
|
-
pixelId:
|
|
19874
|
-
landingUrl:
|
|
19991
|
+
pixelId: z78.string().min(1).optional(),
|
|
19992
|
+
landingUrl: z78.string().url().optional(),
|
|
19875
19993
|
/** Select which angles to publish by 0-based index. Omit to publish all
|
|
19876
19994
|
* successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
|
|
19877
|
-
angleIndexes:
|
|
19995
|
+
angleIndexes: z78.array(z78.number().int().nonnegative()).optional(),
|
|
19878
19996
|
campaignConfig: McpCampaignConfig.optional(),
|
|
19879
19997
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
19880
19998
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
19881
19999
|
* (Meta's primary-text limit). */
|
|
19882
|
-
primaryText:
|
|
20000
|
+
primaryText: z78.string().trim().min(1).max(500).optional(),
|
|
19883
20001
|
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
19884
20002
|
* (wa.me) instead of a landing page. */
|
|
19885
|
-
phoneNumber:
|
|
20003
|
+
phoneNumber: z78.string().min(8).max(32).optional()
|
|
19886
20004
|
});
|
|
19887
|
-
var GroupedTaskSource =
|
|
19888
|
-
type:
|
|
19889
|
-
taskId:
|
|
19890
|
-
angleIndex:
|
|
19891
|
-
videoVariant:
|
|
20005
|
+
var GroupedTaskSource = z78.object({
|
|
20006
|
+
type: z78.literal("task"),
|
|
20007
|
+
taskId: z78.string().min(1),
|
|
20008
|
+
angleIndex: z78.number().int().min(0).optional(),
|
|
20009
|
+
videoVariant: z78.enum([
|
|
19892
20010
|
"with_subtitles",
|
|
19893
20011
|
"without_subtitles"
|
|
19894
20012
|
]).optional(),
|
|
19895
|
-
imageVariantIndex:
|
|
19896
|
-
});
|
|
19897
|
-
var GroupedMediaSource =
|
|
19898
|
-
type:
|
|
19899
|
-
url:
|
|
19900
|
-
path:
|
|
19901
|
-
thumbnailUrl:
|
|
19902
|
-
thumbnailPath:
|
|
20013
|
+
imageVariantIndex: z78.number().int().min(0).optional()
|
|
20014
|
+
});
|
|
20015
|
+
var GroupedMediaSource = z78.object({
|
|
20016
|
+
type: z78.literal("media"),
|
|
20017
|
+
url: z78.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
|
|
20018
|
+
path: z78.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".'),
|
|
20019
|
+
thumbnailUrl: z78.string().url().optional(),
|
|
20020
|
+
thumbnailPath: z78.string().min(1).optional()
|
|
19903
20021
|
}).refine((value) => Boolean(value.url) !== Boolean(value.path), {
|
|
19904
20022
|
message: "media source needs exactly one of `url` or `path`"
|
|
19905
20023
|
}).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
|
|
19906
20024
|
message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
|
|
19907
20025
|
});
|
|
19908
|
-
var GroupedUploadedAssetSource =
|
|
19909
|
-
type:
|
|
20026
|
+
var GroupedUploadedAssetSource = z78.object({
|
|
20027
|
+
type: z78.literal("asset"),
|
|
19910
20028
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
19911
|
-
assetId:
|
|
19912
|
-
thumbnailAssetId:
|
|
20029
|
+
assetId: z78.string().uuid(),
|
|
20030
|
+
thumbnailAssetId: z78.string().uuid().optional()
|
|
19913
20031
|
});
|
|
19914
|
-
var GroupedCreative =
|
|
19915
|
-
type:
|
|
20032
|
+
var GroupedCreative = z78.object({
|
|
20033
|
+
type: z78.enum([
|
|
19916
20034
|
"image",
|
|
19917
20035
|
"video"
|
|
19918
20036
|
]),
|
|
19919
|
-
source:
|
|
20037
|
+
source: z78.union([
|
|
19920
20038
|
GroupedTaskSource,
|
|
19921
20039
|
GroupedMediaSource,
|
|
19922
20040
|
GroupedUploadedAssetSource
|
|
19923
20041
|
]),
|
|
19924
|
-
title:
|
|
19925
|
-
description:
|
|
20042
|
+
title: z78.string().max(120).optional(),
|
|
20043
|
+
description: z78.string().max(500).optional(),
|
|
19926
20044
|
cta: MetaCtaType.optional(),
|
|
19927
|
-
creativeId:
|
|
20045
|
+
creativeId: z78.string().min(1).optional()
|
|
19928
20046
|
});
|
|
19929
|
-
var GroupedCampaignConfigBase =
|
|
20047
|
+
var GroupedCampaignConfigBase = z78.object({
|
|
19930
20048
|
campaignType: MetaCampaignType.default("sales"),
|
|
19931
20049
|
optimizationMode: MetaOptimizationMode.default("advantage_plus"),
|
|
19932
20050
|
budgetMode: MetaBudgetMode.optional(),
|
|
19933
|
-
campaignDailyBudget:
|
|
19934
|
-
adSets:
|
|
19935
|
-
tempId:
|
|
19936
|
-
name:
|
|
19937
|
-
dailyBudget:
|
|
19938
|
-
creativeIds:
|
|
20051
|
+
campaignDailyBudget: z78.number().int().positive().optional(),
|
|
20052
|
+
adSets: z78.array(z78.object({
|
|
20053
|
+
tempId: z78.string().min(1).max(80),
|
|
20054
|
+
name: z78.string().min(1).max(100),
|
|
20055
|
+
dailyBudget: z78.number().int().positive().optional(),
|
|
20056
|
+
creativeIds: z78.array(z78.string().min(1)).min(1)
|
|
19939
20057
|
})).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
|
|
19940
20058
|
/**
|
|
19941
20059
|
* Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
|
|
@@ -19943,17 +20061,17 @@ var GroupedCampaignConfigBase = z77.object({
|
|
|
19943
20061
|
* opaque `invalid_literal` and made the WhatsApp destination — supported by
|
|
19944
20062
|
* the API since #849 — unreachable from this tool.
|
|
19945
20063
|
*/
|
|
19946
|
-
destination:
|
|
19947
|
-
|
|
19948
|
-
type:
|
|
19949
|
-
landingUrl:
|
|
20064
|
+
destination: z78.discriminatedUnion("type", [
|
|
20065
|
+
z78.object({
|
|
20066
|
+
type: z78.literal("landing"),
|
|
20067
|
+
landingUrl: z78.string().url()
|
|
19950
20068
|
}),
|
|
19951
|
-
|
|
19952
|
-
type:
|
|
19953
|
-
phoneNumber:
|
|
20069
|
+
z78.object({
|
|
20070
|
+
type: z78.literal("whatsapp"),
|
|
20071
|
+
phoneNumber: z78.string().min(8).max(32)
|
|
19954
20072
|
})
|
|
19955
20073
|
]),
|
|
19956
|
-
saveAsDefault:
|
|
20074
|
+
saveAsDefault: z78.boolean().default(false),
|
|
19957
20075
|
budgetPolicy: MetaBudgetPolicy.optional()
|
|
19958
20076
|
});
|
|
19959
20077
|
function resolveBudgetMode(value) {
|
|
@@ -19967,7 +20085,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
19967
20085
|
const budgetMode = resolveBudgetMode(value);
|
|
19968
20086
|
if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
|
|
19969
20087
|
ctx.addIssue({
|
|
19970
|
-
code:
|
|
20088
|
+
code: z78.ZodIssueCode.custom,
|
|
19971
20089
|
path: [
|
|
19972
20090
|
"campaignDailyBudget"
|
|
19973
20091
|
],
|
|
@@ -19978,7 +20096,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
19978
20096
|
value.adSets.forEach((adSet, index) => {
|
|
19979
20097
|
if (adSet.dailyBudget === void 0) {
|
|
19980
20098
|
ctx.addIssue({
|
|
19981
|
-
code:
|
|
20099
|
+
code: z78.ZodIssueCode.custom,
|
|
19982
20100
|
path: [
|
|
19983
20101
|
"adSets",
|
|
19984
20102
|
index,
|
|
@@ -19993,28 +20111,28 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
19993
20111
|
...value,
|
|
19994
20112
|
budgetMode: resolveBudgetMode(value)
|
|
19995
20113
|
}));
|
|
19996
|
-
var PublishCreativesToMetaInputBase =
|
|
19997
|
-
creatives:
|
|
20114
|
+
var PublishCreativesToMetaInputBase = z78.object({
|
|
20115
|
+
creatives: z78.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
|
|
19998
20116
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
19999
|
-
portfolioId:
|
|
20117
|
+
portfolioId: z78.string().trim().min(1),
|
|
20000
20118
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
20001
|
-
pageId:
|
|
20119
|
+
pageId: z78.string().trim().min(1),
|
|
20002
20120
|
adAccountId: McpAdAccountId,
|
|
20003
|
-
pixelId:
|
|
20121
|
+
pixelId: z78.string().min(1).optional(),
|
|
20004
20122
|
/** Required unless `campaignConfig.destination` is whatsapp — see the
|
|
20005
20123
|
* superRefine below. Mirrors the API's `FacebookCreateCampaignFromTasksBodySchema`. */
|
|
20006
|
-
landingUrl:
|
|
20124
|
+
landingUrl: z78.string().url().optional(),
|
|
20007
20125
|
/** ISO-2 code or resolvable country name — mirrors the API contract
|
|
20008
20126
|
* (CountryIso2Schema), which normalizes names to alpha-2 at validation. */
|
|
20009
20127
|
targetCountry: CountryIso2Schema,
|
|
20010
|
-
campaignName:
|
|
20128
|
+
campaignName: z78.string().trim().min(1).max(100),
|
|
20011
20129
|
campaignConfig: GroupedCampaignConfig.optional()
|
|
20012
20130
|
});
|
|
20013
20131
|
var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
|
|
20014
20132
|
const destination = value.campaignConfig?.destination;
|
|
20015
20133
|
if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl) {
|
|
20016
20134
|
ctx.addIssue({
|
|
20017
|
-
code:
|
|
20135
|
+
code: z78.ZodIssueCode.custom,
|
|
20018
20136
|
path: [
|
|
20019
20137
|
"landingUrl"
|
|
20020
20138
|
],
|
|
@@ -20023,7 +20141,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
20023
20141
|
}
|
|
20024
20142
|
if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
|
|
20025
20143
|
ctx.addIssue({
|
|
20026
|
-
code:
|
|
20144
|
+
code: z78.ZodIssueCode.custom,
|
|
20027
20145
|
path: [
|
|
20028
20146
|
"campaignConfig",
|
|
20029
20147
|
"destination",
|
|
@@ -20042,16 +20160,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
20042
20160
|
}
|
|
20043
20161
|
return value;
|
|
20044
20162
|
});
|
|
20045
|
-
var PresignUploadResponseSchema =
|
|
20046
|
-
uploadUrl:
|
|
20163
|
+
var PresignUploadResponseSchema = z78.object({
|
|
20164
|
+
uploadUrl: z78.string().url().refine((value) => {
|
|
20047
20165
|
const url = new URL(value);
|
|
20048
20166
|
return !url.username && !url.password && url.protocol === "https:";
|
|
20049
20167
|
}, "presigned upload URL must be HTTPS without embedded credentials"),
|
|
20050
|
-
publicUrl:
|
|
20168
|
+
publicUrl: z78.string().url().refine((value) => {
|
|
20051
20169
|
const url = new URL(value);
|
|
20052
20170
|
return !url.username && !url.password;
|
|
20053
20171
|
}, "public media URL must not contain embedded credentials"),
|
|
20054
|
-
stagingAssetId:
|
|
20172
|
+
stagingAssetId: z78.string().uuid()
|
|
20055
20173
|
});
|
|
20056
20174
|
async function uploadResolvedMedia(api, media, assetRole) {
|
|
20057
20175
|
if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
|
|
@@ -20076,16 +20194,16 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
|
|
|
20076
20194
|
return uploadResolvedMedia(api, media, assetRole);
|
|
20077
20195
|
}
|
|
20078
20196
|
__name(resolveAndUploadMedia, "resolveAndUploadMedia");
|
|
20079
|
-
var TikTokInput =
|
|
20080
|
-
taskId:
|
|
20081
|
-
advertiserId:
|
|
20082
|
-
pixelId:
|
|
20083
|
-
landingUrl:
|
|
20084
|
-
angleIndexes:
|
|
20197
|
+
var TikTokInput = z78.object({
|
|
20198
|
+
taskId: z78.string().min(1),
|
|
20199
|
+
advertiserId: z78.string().min(1),
|
|
20200
|
+
pixelId: z78.string().min(1).optional(),
|
|
20201
|
+
landingUrl: z78.string().url().optional(),
|
|
20202
|
+
angleIndexes: z78.array(z78.number().int().nonnegative()).optional(),
|
|
20085
20203
|
campaignConfig: McpCampaignConfig.optional(),
|
|
20086
20204
|
/** Override the ad's description (TikTok's body copy). If omitted,
|
|
20087
20205
|
* ProductMaker uses the auto-generated copy attached to the task. */
|
|
20088
|
-
primaryText:
|
|
20206
|
+
primaryText: z78.string().trim().min(1).max(500).optional()
|
|
20089
20207
|
});
|
|
20090
20208
|
function registerPublishTools(server, api, opts = {}) {
|
|
20091
20209
|
const transport = opts.transport ?? "http";
|
|
@@ -20413,39 +20531,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
|
|
|
20413
20531
|
|
|
20414
20532
|
// src/tools/meta-upload.ts
|
|
20415
20533
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
20416
|
-
import { z as
|
|
20534
|
+
import { z as z79 } from "zod";
|
|
20417
20535
|
var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
|
|
20418
|
-
var UploadSessionInputBase =
|
|
20419
|
-
mediaKind:
|
|
20536
|
+
var UploadSessionInputBase = z79.object({
|
|
20537
|
+
mediaKind: z79.enum([
|
|
20420
20538
|
"image",
|
|
20421
20539
|
"video",
|
|
20422
20540
|
"mixed"
|
|
20423
20541
|
]).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."),
|
|
20424
|
-
assetRole:
|
|
20542
|
+
assetRole: z79.enum([
|
|
20425
20543
|
"media",
|
|
20426
20544
|
"thumbnail"
|
|
20427
20545
|
]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
|
|
20428
|
-
uploadPurpose:
|
|
20546
|
+
uploadPurpose: z79.enum([
|
|
20429
20547
|
"product_reference",
|
|
20430
20548
|
"creative",
|
|
20431
20549
|
"generic"
|
|
20432
20550
|
]).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."),
|
|
20433
|
-
maxFiles:
|
|
20551
|
+
maxFiles: z79.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
20434
20552
|
});
|
|
20435
|
-
var OpenAiFileReference =
|
|
20436
|
-
download_url:
|
|
20437
|
-
file_id:
|
|
20438
|
-
mime_type:
|
|
20439
|
-
file_name:
|
|
20553
|
+
var OpenAiFileReference = z79.object({
|
|
20554
|
+
download_url: z79.string().url().optional().describe("Optional host-provided download URL. The App prefers getFileDownloadUrl(file_id) and the server never fetches this URL."),
|
|
20555
|
+
file_id: z79.string().min(1),
|
|
20556
|
+
mime_type: z79.string().min(1).optional(),
|
|
20557
|
+
file_name: z79.string().min(1).optional()
|
|
20440
20558
|
});
|
|
20441
20559
|
var UploadSessionToolInputShape = {
|
|
20442
20560
|
...UploadSessionInputBase.shape,
|
|
20443
|
-
files:
|
|
20561
|
+
files: z79.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.")
|
|
20444
20562
|
};
|
|
20445
|
-
var UploadSessionToolInput =
|
|
20563
|
+
var UploadSessionToolInput = z79.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
20446
20564
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
20447
20565
|
ctx.addIssue({
|
|
20448
|
-
code:
|
|
20566
|
+
code: z79.ZodIssueCode.custom,
|
|
20449
20567
|
path: [
|
|
20450
20568
|
"mediaKind"
|
|
20451
20569
|
],
|
|
@@ -20454,7 +20572,7 @@ var UploadSessionToolInput = z78.object(UploadSessionToolInputShape).superRefine
|
|
|
20454
20572
|
}
|
|
20455
20573
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
20456
20574
|
ctx.addIssue({
|
|
20457
|
-
code:
|
|
20575
|
+
code: z79.ZodIssueCode.custom,
|
|
20458
20576
|
path: [
|
|
20459
20577
|
"maxFiles"
|
|
20460
20578
|
],
|
|
@@ -20463,7 +20581,7 @@ var UploadSessionToolInput = z78.object(UploadSessionToolInputShape).superRefine
|
|
|
20463
20581
|
}
|
|
20464
20582
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
|
|
20465
20583
|
ctx.addIssue({
|
|
20466
|
-
code:
|
|
20584
|
+
code: z79.ZodIssueCode.custom,
|
|
20467
20585
|
path: [
|
|
20468
20586
|
"maxFiles"
|
|
20469
20587
|
],
|
|
@@ -20471,38 +20589,38 @@ var UploadSessionToolInput = z78.object(UploadSessionToolInputShape).superRefine
|
|
|
20471
20589
|
});
|
|
20472
20590
|
}
|
|
20473
20591
|
});
|
|
20474
|
-
var UploadSessionResponse =
|
|
20475
|
-
sessionId:
|
|
20476
|
-
uploadPageUrl:
|
|
20477
|
-
mediaKind:
|
|
20592
|
+
var UploadSessionResponse = z79.object({
|
|
20593
|
+
sessionId: z79.string().uuid(),
|
|
20594
|
+
uploadPageUrl: z79.string().url(),
|
|
20595
|
+
mediaKind: z79.enum([
|
|
20478
20596
|
"image",
|
|
20479
20597
|
"video",
|
|
20480
20598
|
"mixed"
|
|
20481
20599
|
]),
|
|
20482
|
-
assetRole:
|
|
20600
|
+
assetRole: z79.enum([
|
|
20483
20601
|
"media",
|
|
20484
20602
|
"thumbnail"
|
|
20485
20603
|
]),
|
|
20486
|
-
maxFiles:
|
|
20487
|
-
expiresAt:
|
|
20604
|
+
maxFiles: z79.number().int().positive(),
|
|
20605
|
+
expiresAt: z79.string().datetime()
|
|
20488
20606
|
});
|
|
20489
|
-
var UploadStatusInput =
|
|
20490
|
-
sessionId:
|
|
20607
|
+
var UploadStatusInput = z79.object({
|
|
20608
|
+
sessionId: z79.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
20491
20609
|
});
|
|
20492
|
-
var UniversalUploadStatusResponse =
|
|
20493
|
-
|
|
20494
|
-
status:
|
|
20495
|
-
assets:
|
|
20610
|
+
var UniversalUploadStatusResponse = z79.discriminatedUnion("status", [
|
|
20611
|
+
z79.object({
|
|
20612
|
+
status: z79.literal("pending"),
|
|
20613
|
+
assets: z79.array(z79.never()).length(0)
|
|
20496
20614
|
}),
|
|
20497
|
-
|
|
20498
|
-
status:
|
|
20499
|
-
assets:
|
|
20500
|
-
assetId:
|
|
20501
|
-
mediaKind:
|
|
20615
|
+
z79.object({
|
|
20616
|
+
status: z79.literal("uploaded"),
|
|
20617
|
+
assets: z79.array(z79.object({
|
|
20618
|
+
assetId: z79.string().uuid(),
|
|
20619
|
+
mediaKind: z79.enum([
|
|
20502
20620
|
"image",
|
|
20503
20621
|
"video"
|
|
20504
20622
|
]),
|
|
20505
|
-
assetRole:
|
|
20623
|
+
assetRole: z79.enum([
|
|
20506
20624
|
"media",
|
|
20507
20625
|
"thumbnail"
|
|
20508
20626
|
])
|
|
@@ -20510,13 +20628,13 @@ var UniversalUploadStatusResponse = z78.discriminatedUnion("status", [
|
|
|
20510
20628
|
})
|
|
20511
20629
|
]);
|
|
20512
20630
|
var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
|
|
20513
|
-
uploadPurpose:
|
|
20631
|
+
uploadPurpose: z79.enum([
|
|
20514
20632
|
"product_reference",
|
|
20515
20633
|
"creative",
|
|
20516
20634
|
"generic"
|
|
20517
20635
|
]),
|
|
20518
|
-
checkToolName:
|
|
20519
|
-
resolveEndpoint:
|
|
20636
|
+
checkToolName: z79.literal("check_media_upload"),
|
|
20637
|
+
resolveEndpoint: z79.string().url()
|
|
20520
20638
|
});
|
|
20521
20639
|
function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
|
|
20522
20640
|
const url = new URL(uploadPageUrl);
|
|
@@ -20607,15 +20725,15 @@ function registerMediaUploadTools(server, api) {
|
|
|
20607
20725
|
__name(registerMediaUploadTools, "registerMediaUploadTools");
|
|
20608
20726
|
|
|
20609
20727
|
// src/tools/campaigns.ts
|
|
20610
|
-
import { z as
|
|
20728
|
+
import { z as z80 } from "zod";
|
|
20611
20729
|
var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
|
|
20612
20730
|
var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
|
|
20613
|
-
var MetaStatusInput =
|
|
20614
|
-
campaignId:
|
|
20731
|
+
var MetaStatusInput = z80.object({
|
|
20732
|
+
campaignId: z80.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
|
|
20615
20733
|
});
|
|
20616
|
-
var TikTokStatusInput =
|
|
20617
|
-
campaignId:
|
|
20618
|
-
advertiserId:
|
|
20734
|
+
var TikTokStatusInput = z80.object({
|
|
20735
|
+
campaignId: z80.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
|
|
20736
|
+
advertiserId: z80.string().min(1).describe("The same advertiserId used to publish the campaign.")
|
|
20619
20737
|
});
|
|
20620
20738
|
function registerCampaignTools(server, api) {
|
|
20621
20739
|
server.tool("get_meta_campaign_status", getMetaCampaignStatusGuidance.summary + " 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) => {
|
|
@@ -20712,10 +20830,10 @@ function renderTikTokStatusMarkdown(r) {
|
|
|
20712
20830
|
__name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
|
|
20713
20831
|
|
|
20714
20832
|
// ../../packages/product-economics/src/product-costing.ts
|
|
20715
|
-
import { z as
|
|
20833
|
+
import { z as z82 } from "zod";
|
|
20716
20834
|
|
|
20717
20835
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
20718
|
-
import { z as
|
|
20836
|
+
import { z as z81 } from "zod";
|
|
20719
20837
|
|
|
20720
20838
|
// ../../packages/product-economics/src/product-costing-shipping-references.json
|
|
20721
20839
|
var product_costing_shipping_references_default = {
|
|
@@ -20779,21 +20897,21 @@ var product_costing_shipping_references_default = {
|
|
|
20779
20897
|
};
|
|
20780
20898
|
|
|
20781
20899
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
20782
|
-
var ShippingReferenceSchema =
|
|
20783
|
-
reference:
|
|
20784
|
-
min:
|
|
20785
|
-
max:
|
|
20786
|
-
updatedAt:
|
|
20787
|
-
confidence:
|
|
20900
|
+
var ShippingReferenceSchema = z81.object({
|
|
20901
|
+
reference: z81.number().positive(),
|
|
20902
|
+
min: z81.number().nonnegative(),
|
|
20903
|
+
max: z81.number().positive(),
|
|
20904
|
+
updatedAt: z81.string().date(),
|
|
20905
|
+
confidence: z81.enum([
|
|
20788
20906
|
"high",
|
|
20789
20907
|
"medium",
|
|
20790
20908
|
"medium-low"
|
|
20791
20909
|
]),
|
|
20792
|
-
sources:
|
|
20910
|
+
sources: z81.array(z81.string().url().startsWith("https://")).min(1).max(3)
|
|
20793
20911
|
}).superRefine(({ reference, min, max }, context) => {
|
|
20794
20912
|
if (min > reference || reference > max) {
|
|
20795
20913
|
context.addIssue({
|
|
20796
|
-
code:
|
|
20914
|
+
code: z81.ZodIssueCode.custom,
|
|
20797
20915
|
message: "shipping_reference_outside_range",
|
|
20798
20916
|
path: [
|
|
20799
20917
|
"reference"
|
|
@@ -20801,7 +20919,7 @@ var ShippingReferenceSchema = z80.object({
|
|
|
20801
20919
|
});
|
|
20802
20920
|
}
|
|
20803
20921
|
});
|
|
20804
|
-
var SHIPPING_REFERENCES =
|
|
20922
|
+
var SHIPPING_REFERENCES = z81.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
|
|
20805
20923
|
var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
|
|
20806
20924
|
var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
|
|
20807
20925
|
"MX",
|
|
@@ -20983,18 +21101,18 @@ function getProductCostingCountryName(country) {
|
|
|
20983
21101
|
__name(getProductCostingCountryName, "getProductCostingCountryName");
|
|
20984
21102
|
|
|
20985
21103
|
// ../../packages/product-economics/src/product-costing.ts
|
|
20986
|
-
var ProductCostingInputSchema =
|
|
20987
|
-
country:
|
|
20988
|
-
supplierCost:
|
|
20989
|
-
shippingCost:
|
|
20990
|
-
returnRate:
|
|
20991
|
-
cancellationRate:
|
|
20992
|
-
adsManagerCpa:
|
|
20993
|
-
desiredMargin:
|
|
21104
|
+
var ProductCostingInputSchema = z82.object({
|
|
21105
|
+
country: z82.string().refine(isProductCostingCountryCode, "unsupported_country"),
|
|
21106
|
+
supplierCost: z82.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
|
|
21107
|
+
shippingCost: z82.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
|
|
21108
|
+
returnRate: z82.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
21109
|
+
cancellationRate: z82.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
21110
|
+
adsManagerCpa: z82.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
|
|
21111
|
+
desiredMargin: z82.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
|
|
20994
21112
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
20995
21113
|
if (returnRate + cancellationRate >= 1) {
|
|
20996
21114
|
context.addIssue({
|
|
20997
|
-
code:
|
|
21115
|
+
code: z82.ZodIssueCode.custom,
|
|
20998
21116
|
message: "delivery_rate_positive",
|
|
20999
21117
|
path: [
|
|
21000
21118
|
"cancellationRate"
|
|
@@ -21091,15 +21209,15 @@ function calculateProductCosting(rawInput) {
|
|
|
21091
21209
|
__name(calculateProductCosting, "calculateProductCosting");
|
|
21092
21210
|
|
|
21093
21211
|
// src/tools/product-costing.ts
|
|
21094
|
-
import { z as
|
|
21212
|
+
import { z as z83 } from "zod";
|
|
21095
21213
|
var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
|
|
21096
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
21097
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
21098
|
-
var ProductCostingToolInput =
|
|
21099
|
-
country:
|
|
21214
|
+
var optionalAmount = /* @__PURE__ */ __name((description) => z83.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
|
|
21215
|
+
var optionalPercent = /* @__PURE__ */ __name((description) => z83.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
|
|
21216
|
+
var ProductCostingToolInput = z83.object({
|
|
21217
|
+
country: z83.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
21100
21218
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
21101
21219
|
}).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
|
|
21102
|
-
supplierCost:
|
|
21220
|
+
supplierCost: z83.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."),
|
|
21103
21221
|
supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
|
|
21104
21222
|
shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
|
|
21105
21223
|
shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
|
|
@@ -21258,7 +21376,7 @@ function formatPercent(value) {
|
|
|
21258
21376
|
__name(formatPercent, "formatPercent");
|
|
21259
21377
|
|
|
21260
21378
|
// src/tools/product-research.ts
|
|
21261
|
-
import { z as
|
|
21379
|
+
import { z as z84 } from "zod";
|
|
21262
21380
|
|
|
21263
21381
|
// src/tools/product-research-idempotency.ts
|
|
21264
21382
|
var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
|
|
@@ -21629,17 +21747,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
|
|
|
21629
21747
|
]);
|
|
21630
21748
|
var POLL_INTERVAL_MS = 5e3;
|
|
21631
21749
|
var MAX_WAIT_SECONDS = 120;
|
|
21632
|
-
var FindInput =
|
|
21750
|
+
var FindInput = z84.object({
|
|
21633
21751
|
targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
|
|
21634
21752
|
categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
|
|
21635
|
-
confirmed:
|
|
21636
|
-
waitSeconds:
|
|
21753
|
+
confirmed: z84.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
|
|
21754
|
+
waitSeconds: z84.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
|
|
21637
21755
|
});
|
|
21638
|
-
var GetInput =
|
|
21639
|
-
runId:
|
|
21756
|
+
var GetInput = z84.object({
|
|
21757
|
+
runId: z84.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
21640
21758
|
});
|
|
21641
|
-
var ListInput =
|
|
21642
|
-
limit:
|
|
21759
|
+
var ListInput = z84.object({
|
|
21760
|
+
limit: z84.number().int().min(1).max(20).default(10)
|
|
21643
21761
|
});
|
|
21644
21762
|
function textResult(text) {
|
|
21645
21763
|
return {
|
|
@@ -21762,17 +21880,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
21762
21880
|
__name(registerProductResearchTools, "registerProductResearchTools");
|
|
21763
21881
|
|
|
21764
21882
|
// src/tools/dropshipping-projects.ts
|
|
21765
|
-
import { z as
|
|
21883
|
+
import { z as z85 } from "zod";
|
|
21766
21884
|
var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
|
|
21767
21885
|
var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
|
|
21768
21886
|
var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
|
|
21769
|
-
var ProjectId =
|
|
21770
|
-
var DropshippingProjectStatus =
|
|
21887
|
+
var ProjectId = z85.string().uuid();
|
|
21888
|
+
var DropshippingProjectStatus = z85.enum([
|
|
21771
21889
|
"active",
|
|
21772
21890
|
"completed",
|
|
21773
21891
|
"archived"
|
|
21774
21892
|
]);
|
|
21775
|
-
var DropshippingProjectPhase =
|
|
21893
|
+
var DropshippingProjectPhase = z85.enum([
|
|
21776
21894
|
"research",
|
|
21777
21895
|
"costing",
|
|
21778
21896
|
"media",
|
|
@@ -21781,21 +21899,21 @@ var DropshippingProjectPhase = z84.enum([
|
|
|
21781
21899
|
"advertising",
|
|
21782
21900
|
"complete"
|
|
21783
21901
|
]);
|
|
21784
|
-
var DropshippingRewardMilestone =
|
|
21902
|
+
var DropshippingRewardMilestone = z85.enum([
|
|
21785
21903
|
"product_selected",
|
|
21786
21904
|
"costing_saved",
|
|
21787
21905
|
"product_media_ready",
|
|
21788
21906
|
"creatives_completed",
|
|
21789
21907
|
"campaign_created"
|
|
21790
21908
|
]);
|
|
21791
|
-
var TargetCountry =
|
|
21909
|
+
var TargetCountry = z85.enum([
|
|
21792
21910
|
"CO",
|
|
21793
21911
|
"MX",
|
|
21794
21912
|
"PE",
|
|
21795
21913
|
"EC",
|
|
21796
21914
|
"CL"
|
|
21797
21915
|
]);
|
|
21798
|
-
var ResearchCategory =
|
|
21916
|
+
var ResearchCategory = z85.enum([
|
|
21799
21917
|
"auto",
|
|
21800
21918
|
"automotive",
|
|
21801
21919
|
"kitchen",
|
|
@@ -21810,7 +21928,7 @@ var ResearchCategory = z84.enum([
|
|
|
21810
21928
|
"garden",
|
|
21811
21929
|
"cleaning"
|
|
21812
21930
|
]);
|
|
21813
|
-
var HttpUrl3 =
|
|
21931
|
+
var HttpUrl3 = z85.string().url().max(2e3).refine((value) => {
|
|
21814
21932
|
try {
|
|
21815
21933
|
return [
|
|
21816
21934
|
"http:",
|
|
@@ -21820,45 +21938,45 @@ var HttpUrl3 = z84.string().url().max(2e3).refine((value) => {
|
|
|
21820
21938
|
return false;
|
|
21821
21939
|
}
|
|
21822
21940
|
}, "URL must use HTTP(S)");
|
|
21823
|
-
var ResearchCandidateOrigin =
|
|
21824
|
-
type:
|
|
21941
|
+
var ResearchCandidateOrigin = z85.object({
|
|
21942
|
+
type: z85.literal("research_candidate"),
|
|
21825
21943
|
runId: ProjectId,
|
|
21826
|
-
candidateSourceId:
|
|
21944
|
+
candidateSourceId: z85.string().min(1).max(160)
|
|
21827
21945
|
});
|
|
21828
|
-
var TaskOrigin =
|
|
21829
|
-
type:
|
|
21946
|
+
var TaskOrigin = z85.object({
|
|
21947
|
+
type: z85.literal("task"),
|
|
21830
21948
|
taskId: ProjectId
|
|
21831
21949
|
});
|
|
21832
|
-
var ManualOrigin =
|
|
21833
|
-
type:
|
|
21950
|
+
var ManualOrigin = z85.object({
|
|
21951
|
+
type: z85.literal("manual"),
|
|
21834
21952
|
clientRequestId: ProjectId,
|
|
21835
|
-
country:
|
|
21953
|
+
country: z85.string().min(2).max(3).optional()
|
|
21836
21954
|
});
|
|
21837
|
-
var StartProjectInput =
|
|
21838
|
-
origin:
|
|
21955
|
+
var StartProjectInput = z85.object({
|
|
21956
|
+
origin: z85.discriminatedUnion("type", [
|
|
21839
21957
|
ResearchCandidateOrigin,
|
|
21840
21958
|
TaskOrigin,
|
|
21841
21959
|
ManualOrigin
|
|
21842
21960
|
]),
|
|
21843
|
-
productName:
|
|
21961
|
+
productName: z85.string().trim().min(1).max(240).optional(),
|
|
21844
21962
|
productUrl: HttpUrl3.optional(),
|
|
21845
|
-
country:
|
|
21846
|
-
languageCode:
|
|
21963
|
+
country: z85.string().min(2).max(3).optional(),
|
|
21964
|
+
languageCode: z85.string().min(2).max(16).optional()
|
|
21847
21965
|
}).strict();
|
|
21848
|
-
var CostProjectInput =
|
|
21966
|
+
var CostProjectInput = z85.object({
|
|
21849
21967
|
projectId: ProjectId,
|
|
21850
|
-
version:
|
|
21851
|
-
country:
|
|
21968
|
+
version: z85.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
|
|
21969
|
+
country: z85.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
21852
21970
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
21853
21971
|
}).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
|
|
21854
|
-
supplierCost:
|
|
21855
|
-
shippingCost:
|
|
21856
|
-
returnRate:
|
|
21857
|
-
cancellationRate:
|
|
21858
|
-
adsManagerCpa:
|
|
21859
|
-
desiredMargin:
|
|
21860
|
-
});
|
|
21861
|
-
var GuideInput =
|
|
21972
|
+
supplierCost: z85.number().finite().positive().describe("Costo real de una unidad con el proveedor, en la moneda del pa\xEDs. \xDANICO dato que debes pedirle al usuario: nunca lo inventes."),
|
|
21973
|
+
shippingCost: z85.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
|
|
21974
|
+
returnRate: z85.number().finite().min(0).lt(1).optional().describe("Fracci\xF3n de pedidos devueltos (0.25 = 25%). Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
21975
|
+
cancellationRate: z85.number().finite().min(0).lt(1).optional().describe("Fracci\xF3n de pedidos cancelados (0.15 = 15%). Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
21976
|
+
adsManagerCpa: z85.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
21977
|
+
desiredMargin: z85.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
|
|
21978
|
+
});
|
|
21979
|
+
var GuideInput = z85.object({
|
|
21862
21980
|
projectId: ProjectId.optional()
|
|
21863
21981
|
}).strict();
|
|
21864
21982
|
var NEXT_ACTION_KINDS = [
|
|
@@ -21876,29 +21994,29 @@ var NEXT_ACTION_KINDS = [
|
|
|
21876
21994
|
"repair_meta_campaign",
|
|
21877
21995
|
"review_paused_campaign"
|
|
21878
21996
|
];
|
|
21879
|
-
var DropshippingProjectNextAction =
|
|
21880
|
-
kind:
|
|
21881
|
-
href:
|
|
21997
|
+
var DropshippingProjectNextAction = z85.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z85.object({
|
|
21998
|
+
kind: z85.literal(kind),
|
|
21999
|
+
href: z85.string().min(1)
|
|
21882
22000
|
})));
|
|
21883
|
-
var CostingInputSchema =
|
|
21884
|
-
country:
|
|
21885
|
-
supplierCost:
|
|
21886
|
-
shippingCost:
|
|
21887
|
-
returnRate:
|
|
21888
|
-
cancellationRate:
|
|
21889
|
-
adsManagerCpa:
|
|
21890
|
-
desiredMargin:
|
|
22001
|
+
var CostingInputSchema = z85.object({
|
|
22002
|
+
country: z85.string().min(2).max(3),
|
|
22003
|
+
supplierCost: z85.number().finite().positive(),
|
|
22004
|
+
shippingCost: z85.number().finite().nonnegative(),
|
|
22005
|
+
returnRate: z85.number().finite().min(0).lt(1),
|
|
22006
|
+
cancellationRate: z85.number().finite().min(0).lt(1),
|
|
22007
|
+
adsManagerCpa: z85.number().finite().nonnegative(),
|
|
22008
|
+
desiredMargin: z85.number().finite().min(0).lt(1)
|
|
21891
22009
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
21892
22010
|
if (returnRate + cancellationRate >= 1) context.addIssue({
|
|
21893
|
-
code:
|
|
22011
|
+
code: z85.ZodIssueCode.custom,
|
|
21894
22012
|
path: [
|
|
21895
22013
|
"cancellationRate"
|
|
21896
22014
|
]
|
|
21897
22015
|
});
|
|
21898
22016
|
});
|
|
21899
|
-
var FiniteCostingNumber =
|
|
21900
|
-
var CostingResultSchema =
|
|
21901
|
-
country:
|
|
22017
|
+
var FiniteCostingNumber = z85.number().finite();
|
|
22018
|
+
var CostingResultSchema = z85.object({
|
|
22019
|
+
country: z85.string().min(2).max(3),
|
|
21902
22020
|
deliveryRate: FiniteCostingNumber,
|
|
21903
22021
|
adjustedShippingCost: FiniteCostingNumber,
|
|
21904
22022
|
adjustedCpa: FiniteCostingNumber,
|
|
@@ -21911,45 +22029,45 @@ var CostingResultSchema = z84.object({
|
|
|
21911
22029
|
estimatedProfit: FiniteCostingNumber,
|
|
21912
22030
|
actualMargin: FiniteCostingNumber,
|
|
21913
22031
|
breakEvenAdsManagerCpa: FiniteCostingNumber,
|
|
21914
|
-
wasPriceAutoAdjusted:
|
|
21915
|
-
profitabilityStatus:
|
|
21916
|
-
});
|
|
21917
|
-
var RewardProgressSchema =
|
|
21918
|
-
campaignKey:
|
|
21919
|
-
totalCredits:
|
|
21920
|
-
earnedCredits:
|
|
21921
|
-
milestones:
|
|
22032
|
+
wasPriceAutoAdjusted: z85.boolean(),
|
|
22033
|
+
profitabilityStatus: z85.literal("healthy")
|
|
22034
|
+
});
|
|
22035
|
+
var RewardProgressSchema = z85.object({
|
|
22036
|
+
campaignKey: z85.literal("dropshipping-launch-v1"),
|
|
22037
|
+
totalCredits: z85.number().int().positive(),
|
|
22038
|
+
earnedCredits: z85.number().int().nonnegative(),
|
|
22039
|
+
milestones: z85.array(z85.object({
|
|
21922
22040
|
milestone: DropshippingRewardMilestone,
|
|
21923
|
-
credits:
|
|
21924
|
-
available:
|
|
21925
|
-
earned:
|
|
22041
|
+
credits: z85.number().int().positive(),
|
|
22042
|
+
available: z85.boolean().optional(),
|
|
22043
|
+
earned: z85.boolean(),
|
|
21926
22044
|
grantId: ProjectId.nullable(),
|
|
21927
|
-
grantedAt:
|
|
22045
|
+
grantedAt: z85.string().datetime().nullable()
|
|
21928
22046
|
})).length(DropshippingRewardMilestone.options.length)
|
|
21929
22047
|
});
|
|
21930
|
-
var ProjectResponseSchema =
|
|
22048
|
+
var ProjectResponseSchema = z85.object({
|
|
21931
22049
|
id: ProjectId,
|
|
21932
22050
|
taskId: ProjectId.nullable(),
|
|
21933
22051
|
status: DropshippingProjectStatus,
|
|
21934
|
-
originKey:
|
|
22052
|
+
originKey: z85.string().min(1),
|
|
21935
22053
|
researchRunId: ProjectId.nullable(),
|
|
21936
|
-
candidateSourceId:
|
|
21937
|
-
productName:
|
|
22054
|
+
candidateSourceId: z85.string().nullable(),
|
|
22055
|
+
productName: z85.string().nullable(),
|
|
21938
22056
|
productUrl: HttpUrl3.nullable(),
|
|
21939
22057
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
21940
|
-
targetCountry:
|
|
21941
|
-
languageCode:
|
|
21942
|
-
hasReferenceImage:
|
|
21943
|
-
hasWinnerReferenceImage:
|
|
22058
|
+
targetCountry: z85.string().nullable(),
|
|
22059
|
+
languageCode: z85.string().nullable(),
|
|
22060
|
+
hasReferenceImage: z85.boolean(),
|
|
22061
|
+
hasWinnerReferenceImage: z85.boolean(),
|
|
21944
22062
|
costingInput: CostingInputSchema.nullable(),
|
|
21945
22063
|
costingResult: CostingResultSchema.nullable(),
|
|
21946
|
-
costingVersion:
|
|
21947
|
-
version:
|
|
22064
|
+
costingVersion: z85.number().int().positive().nullable(),
|
|
22065
|
+
version: z85.number().int().positive(),
|
|
21948
22066
|
phase: DropshippingProjectPhase,
|
|
21949
22067
|
nextAction: DropshippingProjectNextAction.nullable(),
|
|
21950
22068
|
rewards: RewardProgressSchema,
|
|
21951
|
-
createdAt:
|
|
21952
|
-
updatedAt:
|
|
22069
|
+
createdAt: z85.string().datetime(),
|
|
22070
|
+
updatedAt: z85.string().datetime()
|
|
21953
22071
|
}).passthrough();
|
|
21954
22072
|
var NEXT_ACTION_GUIDANCE = {
|
|
21955
22073
|
cost_product: "Llama `cost_dropshipping_project` con el costo real del proveedor. Nunca lo inventes: p\xEDdeselo al usuario. Es el \xDANICO dato que debes pedirle: omite env\xEDo, devoluciones, cancelaciones, CPA y margen para que ProductMaker use los valores gu\xEDa del pa\xEDs, y luego dile al usuario cu\xE1les us\xF3 por si quiere corregirlos.",
|
|
@@ -22067,58 +22185,58 @@ function registerDropshippingProjectTools(server, api) {
|
|
|
22067
22185
|
__name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
|
|
22068
22186
|
|
|
22069
22187
|
// src/tools/daily-control.ts
|
|
22070
|
-
import { z as
|
|
22188
|
+
import { z as z86 } from "zod";
|
|
22071
22189
|
var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
|
|
22072
22190
|
var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
|
|
22073
22191
|
var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
|
|
22074
|
-
var ProviderCampaignIdentifier =
|
|
22075
|
-
var DateOnly =
|
|
22076
|
-
var DailyControlInput =
|
|
22192
|
+
var ProviderCampaignIdentifier = z86.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
|
|
22193
|
+
var DateOnly = z86.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
22194
|
+
var DailyControlInput = z86.object({
|
|
22077
22195
|
date: DateOnly.optional().describe("D\xEDa final de la ventana (YYYY-MM-DD). Si se omite, la ventana termina AYER en UTC \u2014 nunca hoy, porque el d\xEDa en curso est\xE1 incompleto \u2014 y el servidor puede correrla un d\xEDa m\xE1s atr\xE1s si en la zona horaria de la tienda ese d\xEDa todav\xEDa no ha cerrado."),
|
|
22078
|
-
days:
|
|
22079
|
-
projectId:
|
|
22196
|
+
days: z86.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
22197
|
+
projectId: z86.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
|
|
22080
22198
|
}).strict();
|
|
22081
|
-
var LinkCampaignInput =
|
|
22082
|
-
projectId:
|
|
22083
|
-
provider:
|
|
22199
|
+
var LinkCampaignInput = z86.object({
|
|
22200
|
+
projectId: z86.string().uuid(),
|
|
22201
|
+
provider: z86.enum([
|
|
22084
22202
|
"meta",
|
|
22085
22203
|
"tiktok"
|
|
22086
22204
|
]),
|
|
22087
22205
|
accountId: ProviderCampaignIdentifier.describe("Cuenta publicitaria del proveedor. Para Meta el servidor la IGNORA y deriva la cuenta real de la campa\xF1a \u2014 se sigue pidiendo aqu\xED solo porque TikTok s\xED la necesita para resolver la campa\xF1a."),
|
|
22088
22206
|
campaignId: ProviderCampaignIdentifier
|
|
22089
22207
|
}).strict();
|
|
22090
|
-
var ReportReturnsInput =
|
|
22091
|
-
projectId:
|
|
22208
|
+
var ReportReturnsInput = z86.object({
|
|
22209
|
+
projectId: z86.string().uuid(),
|
|
22092
22210
|
date: DateOnly,
|
|
22093
|
-
returnedOrders:
|
|
22094
|
-
note:
|
|
22211
|
+
returnedOrders: z86.number().int().min(0).max(1e5),
|
|
22212
|
+
note: z86.string().trim().max(280).optional()
|
|
22095
22213
|
}).strict();
|
|
22096
|
-
var DailyControlStatusMirror = DailyControlStatusEnum.or(
|
|
22097
|
-
var DailyControlLightMirror = DailyControlLightEnum.or(
|
|
22098
|
-
var DailyControlSourceMirror = DailyControlSourceEnum.or(
|
|
22099
|
-
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(
|
|
22100
|
-
var DailyControlDayMirror =
|
|
22101
|
-
date:
|
|
22102
|
-
returnedOrders:
|
|
22214
|
+
var DailyControlStatusMirror = DailyControlStatusEnum.or(z86.string());
|
|
22215
|
+
var DailyControlLightMirror = DailyControlLightEnum.or(z86.string());
|
|
22216
|
+
var DailyControlSourceMirror = DailyControlSourceEnum.or(z86.string());
|
|
22217
|
+
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z86.string());
|
|
22218
|
+
var DailyControlDayMirror = z86.object({
|
|
22219
|
+
date: z86.string(),
|
|
22220
|
+
returnedOrders: z86.number(),
|
|
22103
22221
|
returnedSource: DailyControlSourceMirror,
|
|
22104
22222
|
cancelledSource: DailyControlSourceMirror,
|
|
22105
|
-
hasEstimates:
|
|
22223
|
+
hasEstimates: z86.boolean(),
|
|
22106
22224
|
light: DailyControlLightMirror
|
|
22107
22225
|
}).passthrough();
|
|
22108
|
-
var DailyControlProductMirror =
|
|
22109
|
-
projectId:
|
|
22110
|
-
productName:
|
|
22226
|
+
var DailyControlProductMirror = z86.object({
|
|
22227
|
+
projectId: z86.string().uuid(),
|
|
22228
|
+
productName: z86.string().nullable(),
|
|
22111
22229
|
status: DailyControlStatusMirror,
|
|
22112
|
-
statusMessage:
|
|
22113
|
-
days:
|
|
22230
|
+
statusMessage: z86.string().nullable(),
|
|
22231
|
+
days: z86.array(DailyControlDayMirror),
|
|
22114
22232
|
verdict: DailyControlVerdictMirror.nullable(),
|
|
22115
|
-
rationale:
|
|
22233
|
+
rationale: z86.string().nullable()
|
|
22116
22234
|
}).passthrough();
|
|
22117
|
-
var DailyControlResponseMirror =
|
|
22118
|
-
since:
|
|
22119
|
-
until:
|
|
22120
|
-
products:
|
|
22121
|
-
archivedProjectSpend:
|
|
22235
|
+
var DailyControlResponseMirror = z86.object({
|
|
22236
|
+
since: z86.string(),
|
|
22237
|
+
until: z86.string(),
|
|
22238
|
+
products: z86.array(DailyControlProductMirror),
|
|
22239
|
+
archivedProjectSpend: z86.array(z86.unknown())
|
|
22122
22240
|
}).passthrough();
|
|
22123
22241
|
var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
|
|
22124
22242
|
function withWarnings(response) {
|
|
@@ -22202,42 +22320,42 @@ function registerDailyControlTools(server, api) {
|
|
|
22202
22320
|
__name(registerDailyControlTools, "registerDailyControlTools");
|
|
22203
22321
|
|
|
22204
22322
|
// src/tools/product-control.ts
|
|
22205
|
-
import { z as
|
|
22323
|
+
import { z as z87 } from "zod";
|
|
22206
22324
|
var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
|
|
22207
22325
|
var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
|
|
22208
22326
|
var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
|
|
22209
22327
|
var setProductCostingGuidance = getProductMakerCapabilityModelGuidance("set_product_costing");
|
|
22210
22328
|
var reportProductCountsGuidance = getProductMakerCapabilityModelGuidance("report_product_counts");
|
|
22211
|
-
var DateOnly2 =
|
|
22329
|
+
var DateOnly2 = z87.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
22212
22330
|
var IMPORT_BATCH_MAX2 = 50;
|
|
22213
|
-
var ProductControlListInput =
|
|
22214
|
-
days:
|
|
22331
|
+
var ProductControlListInput = z87.object({
|
|
22332
|
+
days: z87.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
22215
22333
|
date: DateOnly2.optional().describe("D\xEDa final de la ventana (YYYY-MM-DD). Si se omite, termina en el \xFAltimo d\xEDa cerrado \u2014 nunca hoy, que est\xE1 incompleto."),
|
|
22216
|
-
shopDomain:
|
|
22334
|
+
shopDomain: z87.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
22217
22335
|
}).strict();
|
|
22218
|
-
var ImportableProductsInput =
|
|
22219
|
-
q:
|
|
22220
|
-
after:
|
|
22221
|
-
shopDomain:
|
|
22336
|
+
var ImportableProductsInput = z87.object({
|
|
22337
|
+
q: z87.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
|
|
22338
|
+
after: z87.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
|
|
22339
|
+
shopDomain: z87.string().min(1).optional()
|
|
22222
22340
|
}).strict();
|
|
22223
|
-
var ImportProductControlsInput =
|
|
22224
|
-
shopifyProductIds:
|
|
22341
|
+
var ImportProductControlsInput = z87.object({
|
|
22342
|
+
shopifyProductIds: z87.array(z87.string().min(1).max(64)).min(1).max(IMPORT_BATCH_MAX2).describe("Identificadores tal como vinieron de list_importable_products. NO los inventes ni los deduzcas del t\xEDtulo."),
|
|
22225
22343
|
// Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
|
|
22226
22344
|
// sin decir a cuál archivaría el producto bajo la tienda equivocada.
|
|
22227
|
-
shopDomain:
|
|
22345
|
+
shopDomain: z87.string().min(1)
|
|
22228
22346
|
}).strict();
|
|
22229
|
-
var SetProductCostingInput =
|
|
22230
|
-
shopDomain:
|
|
22231
|
-
shopifyProductId:
|
|
22232
|
-
targetCountry:
|
|
22233
|
-
supplierCost:
|
|
22234
|
-
shippingCost:
|
|
22235
|
-
returnRate:
|
|
22236
|
-
cancellationRate:
|
|
22347
|
+
var SetProductCostingInput = z87.object({
|
|
22348
|
+
shopDomain: z87.string().min(1),
|
|
22349
|
+
shopifyProductId: z87.string().min(1).max(64),
|
|
22350
|
+
targetCountry: z87.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
|
|
22351
|
+
supplierCost: z87.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
|
|
22352
|
+
shippingCost: z87.number().finite().nonnegative(),
|
|
22353
|
+
returnRate: z87.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
|
|
22354
|
+
cancellationRate: z87.number().finite().min(0).lt(1)
|
|
22237
22355
|
}).strict();
|
|
22238
|
-
var Count =
|
|
22239
|
-
var ReportProductCountsInput =
|
|
22240
|
-
productControlId:
|
|
22356
|
+
var Count = z87.number().int().min(0).max(1e5).nullable().optional();
|
|
22357
|
+
var ReportProductCountsInput = z87.object({
|
|
22358
|
+
productControlId: z87.string().uuid().describe("El identificador que devuelve get_product_control."),
|
|
22241
22359
|
date: DateOnly2,
|
|
22242
22360
|
orders: Count.describe("Pedidos que entraron ese d\xEDa."),
|
|
22243
22361
|
cancelledOrders: Count,
|