@productmaker/mcp 12.1.2 → 12.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/http.js +1053 -888
- package/dist/stdio.js +1040 -875
- package/package.json +1 -1
package/dist/http.js
CHANGED
|
@@ -2766,9 +2766,9 @@ var ClassicLandingSelectionSnapshotSchema = z18.object({
|
|
|
2766
2766
|
}).strict().superRefine((snapshot, ctx) => {
|
|
2767
2767
|
if (snapshot.images) {
|
|
2768
2768
|
const selectedImages = snapshot.blocks.filter((block) => block.kind === "image");
|
|
2769
|
-
const ids = snapshot.images.map((
|
|
2769
|
+
const ids = snapshot.images.map((image2) => classicLandingBlockId({
|
|
2770
2770
|
kind: "image",
|
|
2771
|
-
...
|
|
2771
|
+
...image2
|
|
2772
2772
|
}));
|
|
2773
2773
|
if (new Set(ids).size !== ids.length || ids.length !== selectedImages.length || selectedImages.some((block) => !ids.includes(classicLandingBlockId(block)))) ctx.addIssue({
|
|
2774
2774
|
code: z18.ZodIssueCode.custom,
|
|
@@ -15716,9 +15716,9 @@ var MotionGraphicsVoiceDirectionSchema = z78.object({
|
|
|
15716
15716
|
pace: z78.enum(MOTION_GRAPHICS_VOICE_PACES)
|
|
15717
15717
|
}).strict();
|
|
15718
15718
|
var AUDIO_TAG = /\[(?:sighs|laughs softly|short pause|emphatic|whispers|gasps|hesitant|warmly)\]/g;
|
|
15719
|
-
function motionGraphicsTaggedSpeechMatches(
|
|
15719
|
+
function motionGraphicsTaggedSpeechMatches(text4, tagged) {
|
|
15720
15720
|
const normalize = /* @__PURE__ */ __name((value) => value.normalize("NFC").replace(/\s+/g, " ").trim(), "normalize");
|
|
15721
|
-
return normalize(tagged.replace(AUDIO_TAG, "")) === normalize(
|
|
15721
|
+
return normalize(tagged.replace(AUDIO_TAG, "")) === normalize(text4);
|
|
15722
15722
|
}
|
|
15723
15723
|
__name(motionGraphicsTaggedSpeechMatches, "motionGraphicsTaggedSpeechMatches");
|
|
15724
15724
|
var MotionGraphicsTaggedSpeechSchema = z78.string().trim().min(1).max(1200);
|
|
@@ -21890,10 +21890,10 @@ var GENDER_ALIASES = {
|
|
|
21890
21890
|
};
|
|
21891
21891
|
function matchAlias(raw, aliases) {
|
|
21892
21892
|
if (typeof raw !== "string") return void 0;
|
|
21893
|
-
const
|
|
21894
|
-
const exact = aliases[
|
|
21893
|
+
const text4 = raw.trim().toLowerCase();
|
|
21894
|
+
const exact = aliases[text4];
|
|
21895
21895
|
if (exact) return exact;
|
|
21896
|
-
const words = new Set(
|
|
21896
|
+
const words = new Set(text4.split(/[^a-z]+/).filter(Boolean));
|
|
21897
21897
|
for (const [alias, value] of Object.entries(aliases)) {
|
|
21898
21898
|
if (words.has(alias)) return value;
|
|
21899
21899
|
}
|
|
@@ -23785,26 +23785,122 @@ var WebsiteCaptureResearchSchema = z116.object({
|
|
|
23785
23785
|
});
|
|
23786
23786
|
|
|
23787
23787
|
// ../../packages/types/src/demo-mode.ts
|
|
23788
|
-
import { z as
|
|
23788
|
+
import { z as z119 } from "zod";
|
|
23789
23789
|
|
|
23790
|
-
// ../../packages/types/src/demo-mode-
|
|
23790
|
+
// ../../packages/types/src/demo-mode-product.ts
|
|
23791
23791
|
import { z as z117 } from "zod";
|
|
23792
|
-
var
|
|
23793
|
-
|
|
23794
|
-
|
|
23795
|
-
|
|
23796
|
-
|
|
23797
|
-
|
|
23798
|
-
|
|
23792
|
+
var text3 = z117.string().trim().min(1).max(2e5);
|
|
23793
|
+
var nullableText = z117.string().max(2e5).nullable();
|
|
23794
|
+
var image = z117.object({
|
|
23795
|
+
provider: text3,
|
|
23796
|
+
model: text3,
|
|
23797
|
+
prompt: z117.string().max(2e5),
|
|
23798
|
+
imageUrl: text3,
|
|
23799
|
+
width: z117.number().int().positive(),
|
|
23800
|
+
height: z117.number().int().positive(),
|
|
23801
|
+
adCopy: nullableText,
|
|
23802
|
+
rawResponse: z117.unknown()
|
|
23803
|
+
});
|
|
23804
|
+
var ProductDemoSnapshotSchema = z117.object({
|
|
23805
|
+
/** Optional only for packs frozen before seller review drafts were captured. */
|
|
23806
|
+
customAngleOverride: nullableText.optional(),
|
|
23807
|
+
painPoints: nullableText.optional(),
|
|
23808
|
+
benefits: nullableText.optional(),
|
|
23809
|
+
product: z117.object({
|
|
23810
|
+
title: text3,
|
|
23811
|
+
price: nullableText,
|
|
23812
|
+
country: nullableText,
|
|
23813
|
+
features: z117.array(text3).max(100),
|
|
23814
|
+
form: nullableText,
|
|
23815
|
+
details: z117.unknown(),
|
|
23816
|
+
isCombo: z117.boolean(),
|
|
23817
|
+
comboItems: z117.unknown(),
|
|
23818
|
+
images: z117.array(text3).min(1).max(50),
|
|
23819
|
+
cleanImages: z117.array(text3).max(50),
|
|
23820
|
+
cleanImagesMeta: z117.unknown()
|
|
23821
|
+
}),
|
|
23822
|
+
angles: z117.array(z117.object({
|
|
23823
|
+
content: text3,
|
|
23824
|
+
buyerPersona: nullableText,
|
|
23825
|
+
actor: nullableText,
|
|
23826
|
+
scriptNotes: nullableText
|
|
23827
|
+
})).min(1).max(10),
|
|
23828
|
+
videos: z117.array(z117.object({
|
|
23829
|
+
/** Present only for explicit multi-template packs; legacy arrays keep selection-order playback. */
|
|
23830
|
+
reviewAngleIndex: z117.number().int().min(0).max(9).optional(),
|
|
23831
|
+
provider: text3,
|
|
23832
|
+
model: text3,
|
|
23833
|
+
script: text3,
|
|
23834
|
+
prompt: z117.string().max(2e5),
|
|
23835
|
+
imageUrl: text3,
|
|
23836
|
+
durationSeconds: z117.number().int().positive().nullable(),
|
|
23837
|
+
format: VideoFormat,
|
|
23838
|
+
resultUrls: z117.array(text3).min(1).max(10),
|
|
23839
|
+
rawResponse: z117.unknown(),
|
|
23840
|
+
adCopy: nullableText
|
|
23841
|
+
})).min(1).max(10),
|
|
23842
|
+
landingImages: z117.array(z117.object({
|
|
23843
|
+
role: LandingRole,
|
|
23844
|
+
indexNum: z117.number().int().min(1),
|
|
23845
|
+
url: text3,
|
|
23846
|
+
width: z117.number().int().positive(),
|
|
23847
|
+
height: z117.number().int().positive(),
|
|
23848
|
+
notes: nullableText
|
|
23849
|
+
})).max(20),
|
|
23850
|
+
landingConfig: z117.unknown(),
|
|
23851
|
+
image,
|
|
23852
|
+
productUseSheet: z117.unknown(),
|
|
23853
|
+
productTruth: z117.unknown(),
|
|
23854
|
+
productReference: z117.object({
|
|
23855
|
+
referenceEvidenceVersion: z117.number().int().nonnegative(),
|
|
23856
|
+
planVersion: z117.number().int().positive(),
|
|
23857
|
+
baseReferenceSetHash: text3,
|
|
23858
|
+
referenceSet: z117.unknown(),
|
|
23859
|
+
preparationPlan: z117.unknown(),
|
|
23860
|
+
canonicalIdentityAnchors: z117.unknown()
|
|
23861
|
+
})
|
|
23862
|
+
});
|
|
23863
|
+
var ProductDemoPhaseSchema = z117.enum([
|
|
23864
|
+
"preparing",
|
|
23865
|
+
"angles",
|
|
23866
|
+
"preparing_scripts",
|
|
23867
|
+
"scripts",
|
|
23868
|
+
"generating",
|
|
23869
|
+
"done"
|
|
23870
|
+
]);
|
|
23871
|
+
var ProductDemoJobPhaseSchema = z117.enum([
|
|
23872
|
+
"preparing",
|
|
23873
|
+
"scripts",
|
|
23874
|
+
"generating"
|
|
23875
|
+
]);
|
|
23876
|
+
var ProductDemoTaskStateSchema = z117.object({
|
|
23877
|
+
admitted: z117.boolean().default(false),
|
|
23878
|
+
phase: ProductDemoPhaseSchema,
|
|
23879
|
+
waitMs: z117.number().int().positive(),
|
|
23880
|
+
snapshot: ProductDemoSnapshotSchema,
|
|
23881
|
+
selectedAngleIndices: z117.array(z117.number().int().min(0).max(9)).max(10),
|
|
23882
|
+
chargeCents: z117.number().int().min(0).max(1e5),
|
|
23883
|
+
maxCents: z117.number().int().min(0).optional()
|
|
23884
|
+
});
|
|
23885
|
+
|
|
23886
|
+
// ../../packages/types/src/demo-mode-service-page-assets.ts
|
|
23887
|
+
import { z as z118 } from "zod";
|
|
23888
|
+
var DemoServicePageAssetSourceSchema = z118.object({
|
|
23889
|
+
pageId: z118.string().uuid(),
|
|
23890
|
+
ownerId: z118.string().min(1),
|
|
23891
|
+
assets: z118.array(z118.object({
|
|
23892
|
+
id: z118.string().uuid(),
|
|
23893
|
+
storageKey: z118.string().min(1).max(1024),
|
|
23894
|
+
mediaType: z118.enum([
|
|
23799
23895
|
"image/webp",
|
|
23800
23896
|
"video/mp4"
|
|
23801
23897
|
]),
|
|
23802
|
-
byteSize:
|
|
23803
|
-
width:
|
|
23804
|
-
height:
|
|
23805
|
-
contentHash:
|
|
23898
|
+
byteSize: z118.number().int().positive().max(32 * 1024 * 1024),
|
|
23899
|
+
width: z118.number().int().positive().max(1920),
|
|
23900
|
+
height: z118.number().int().positive().max(1920),
|
|
23901
|
+
contentHash: z118.string().regex(/^[a-f0-9]{64}$/i),
|
|
23806
23902
|
sourceKind: ServicePageSourceKindSchema,
|
|
23807
|
-
approvedAt:
|
|
23903
|
+
approvedAt: z118.string().datetime()
|
|
23808
23904
|
}).strict()).max(24)
|
|
23809
23905
|
}).strict();
|
|
23810
23906
|
|
|
@@ -23813,9 +23909,10 @@ var DEMO_MODE_FLOWS = [
|
|
|
23813
23909
|
"brand",
|
|
23814
23910
|
"servicePage",
|
|
23815
23911
|
"motion",
|
|
23816
|
-
"image"
|
|
23912
|
+
"image",
|
|
23913
|
+
"product"
|
|
23817
23914
|
];
|
|
23818
|
-
var DemoModeFlowSchema =
|
|
23915
|
+
var DemoModeFlowSchema = z119.enum(DEMO_MODE_FLOWS);
|
|
23819
23916
|
var DEMO_MODE_STEPS = [
|
|
23820
23917
|
"running",
|
|
23821
23918
|
"research",
|
|
@@ -23828,108 +23925,166 @@ var DEMO_MODE_STEPS = [
|
|
|
23828
23925
|
"final",
|
|
23829
23926
|
"watchdog"
|
|
23830
23927
|
];
|
|
23831
|
-
var DemoModeStepSchema =
|
|
23928
|
+
var DemoModeStepSchema = z119.enum(DEMO_MODE_STEPS);
|
|
23832
23929
|
var DEMO_MODE_WAIT_SECONDS = {
|
|
23833
23930
|
min: 30,
|
|
23834
23931
|
max: 450,
|
|
23835
23932
|
default: 150
|
|
23836
23933
|
};
|
|
23837
|
-
var
|
|
23838
|
-
|
|
23839
|
-
|
|
23840
|
-
|
|
23841
|
-
|
|
23842
|
-
|
|
23843
|
-
|
|
23934
|
+
var DEMO_MODE_DEFAULT_CHARGE_CENTS = {
|
|
23935
|
+
brand: 100,
|
|
23936
|
+
servicePage: 300,
|
|
23937
|
+
motion: 1500,
|
|
23938
|
+
image: 200,
|
|
23939
|
+
product: 1500
|
|
23940
|
+
};
|
|
23941
|
+
var centsSchema = z119.number().int().min(0).max(1e5);
|
|
23942
|
+
var emailSchema = z119.string().trim().toLowerCase().email();
|
|
23943
|
+
var DEMO_MODE_OPTIONAL_MOTION_TEMPLATE_KEYS = [
|
|
23944
|
+
"motionVariantTaskId",
|
|
23945
|
+
"motionThirdTaskId"
|
|
23946
|
+
];
|
|
23947
|
+
var DEMO_MODE_OPTIONAL_PRODUCT_VIDEO_TEMPLATE_KEYS = [
|
|
23948
|
+
"productVideoVariantTaskId",
|
|
23949
|
+
"productVideoThirdTaskId"
|
|
23950
|
+
];
|
|
23951
|
+
var DEMO_MODE_PRODUCT_VIDEO_TEMPLATE_KEYS = [
|
|
23952
|
+
"productVideoTaskId",
|
|
23953
|
+
...DEMO_MODE_OPTIONAL_PRODUCT_VIDEO_TEMPLATE_KEYS
|
|
23954
|
+
];
|
|
23955
|
+
var DEMO_MODE_PRODUCT_TEMPLATE_KEYS = [
|
|
23956
|
+
"productLandingTaskId",
|
|
23957
|
+
"productVideoTaskId",
|
|
23958
|
+
"productImageTaskId"
|
|
23959
|
+
];
|
|
23960
|
+
var DEMO_MODE_PRODUCT_ALL_TEMPLATE_KEYS = [
|
|
23961
|
+
...DEMO_MODE_PRODUCT_TEMPLATE_KEYS,
|
|
23962
|
+
...DEMO_MODE_OPTIONAL_PRODUCT_VIDEO_TEMPLATE_KEYS
|
|
23963
|
+
];
|
|
23964
|
+
var DEMO_MODE_OPTIONAL_TEMPLATE_KEYS = [
|
|
23965
|
+
...DEMO_MODE_OPTIONAL_MOTION_TEMPLATE_KEYS,
|
|
23966
|
+
...DEMO_MODE_PRODUCT_ALL_TEMPLATE_KEYS
|
|
23967
|
+
];
|
|
23968
|
+
var optionalTemplateId = z119.preprocess((value) => value === "" ? void 0 : value, z119.string().uuid().optional());
|
|
23969
|
+
var DemoModeTemplatesSchema = z119.object({
|
|
23970
|
+
brandId: z119.string().uuid(),
|
|
23971
|
+
servicePageId: z119.string().uuid(),
|
|
23972
|
+
motionTaskId: z119.string().uuid(),
|
|
23844
23973
|
motionVariantTaskId: optionalTemplateId,
|
|
23845
23974
|
motionThirdTaskId: optionalTemplateId,
|
|
23846
|
-
imageTaskId:
|
|
23847
|
-
|
|
23848
|
-
|
|
23849
|
-
|
|
23850
|
-
|
|
23975
|
+
imageTaskId: z119.string().uuid(),
|
|
23976
|
+
productLandingTaskId: optionalTemplateId,
|
|
23977
|
+
productVideoTaskId: optionalTemplateId,
|
|
23978
|
+
productVideoVariantTaskId: optionalTemplateId,
|
|
23979
|
+
productVideoThirdTaskId: optionalTemplateId,
|
|
23980
|
+
productImageTaskId: optionalTemplateId
|
|
23981
|
+
});
|
|
23982
|
+
var DemoModeEditableObjectSchema = z119.object({
|
|
23983
|
+
productsEnabled: z119.boolean().default(false),
|
|
23984
|
+
enabled: z119.boolean(),
|
|
23985
|
+
emails: z119.array(emailSchema).max(50).transform((list) => [
|
|
23851
23986
|
...new Set(list)
|
|
23852
23987
|
]),
|
|
23853
|
-
waitSeconds:
|
|
23854
|
-
chargeCents:
|
|
23988
|
+
waitSeconds: z119.number().int().min(DEMO_MODE_WAIT_SECONDS.min).max(DEMO_MODE_WAIT_SECONDS.max),
|
|
23989
|
+
chargeCents: z119.object({
|
|
23855
23990
|
brand: centsSchema,
|
|
23856
23991
|
servicePage: centsSchema,
|
|
23857
23992
|
motion: centsSchema,
|
|
23858
|
-
image: centsSchema
|
|
23993
|
+
image: centsSchema,
|
|
23994
|
+
product: centsSchema.default(DEMO_MODE_DEFAULT_CHARGE_CENTS.product)
|
|
23859
23995
|
}),
|
|
23860
23996
|
templates: DemoModeTemplatesSchema
|
|
23861
23997
|
});
|
|
23862
|
-
var
|
|
23863
|
-
|
|
23864
|
-
|
|
23998
|
+
var DemoModeEditableSchema = DemoModeEditableObjectSchema.superRefine((value, ctx) => {
|
|
23999
|
+
if (!value.productsEnabled) return;
|
|
24000
|
+
for (const key of DEMO_MODE_PRODUCT_TEMPLATE_KEYS) {
|
|
24001
|
+
if (!value.templates[key]) ctx.addIssue({
|
|
24002
|
+
code: z119.ZodIssueCode.custom,
|
|
24003
|
+
path: [
|
|
24004
|
+
"templates",
|
|
24005
|
+
key
|
|
24006
|
+
],
|
|
24007
|
+
message: "Product demo requires all three templates"
|
|
24008
|
+
});
|
|
24009
|
+
}
|
|
24010
|
+
});
|
|
24011
|
+
var nullableString = z119.string().nullable();
|
|
24012
|
+
var DemoModeSnapshotSchema = z119.object({
|
|
24013
|
+
product: ProductDemoSnapshotSchema.optional(),
|
|
24014
|
+
brand: z119.object({
|
|
23865
24015
|
/** Columnas de identidad de `Brand` listas para un `update` (sin id/userId/slug/estado/fechas). */
|
|
23866
|
-
identity:
|
|
23867
|
-
productSamples:
|
|
23868
|
-
name:
|
|
23869
|
-
priceCents:
|
|
24016
|
+
identity: z119.record(z119.unknown()),
|
|
24017
|
+
productSamples: z119.array(z119.object({
|
|
24018
|
+
name: z119.string(),
|
|
24019
|
+
priceCents: z119.number().int().nullable(),
|
|
23870
24020
|
currency: nullableString,
|
|
23871
|
-
imageKey:
|
|
24021
|
+
imageKey: z119.string(),
|
|
23872
24022
|
productUrl: nullableString,
|
|
23873
|
-
position:
|
|
24023
|
+
position: z119.number().int()
|
|
23874
24024
|
})),
|
|
23875
|
-
personas:
|
|
23876
|
-
name:
|
|
24025
|
+
personas: z119.array(z119.object({
|
|
24026
|
+
name: z119.string(),
|
|
23877
24027
|
demographics: nullableString,
|
|
23878
24028
|
painPoints: nullableString,
|
|
23879
24029
|
motivations: nullableString,
|
|
23880
24030
|
objections: nullableString,
|
|
23881
24031
|
gender: nullableString,
|
|
23882
|
-
isDefault:
|
|
24032
|
+
isDefault: z119.boolean()
|
|
23883
24033
|
}))
|
|
23884
24034
|
}),
|
|
23885
|
-
servicePage:
|
|
23886
|
-
facts:
|
|
23887
|
-
review:
|
|
23888
|
-
artifact:
|
|
24035
|
+
servicePage: z119.object({
|
|
24036
|
+
facts: z119.unknown(),
|
|
24037
|
+
review: z119.unknown(),
|
|
24038
|
+
artifact: z119.unknown(),
|
|
23889
24039
|
/** Optional only for snapshots saved before page-owned demo media. */
|
|
23890
24040
|
assetSource: DemoServicePageAssetSourceSchema.optional()
|
|
23891
24041
|
}),
|
|
23892
|
-
motion:
|
|
24042
|
+
motion: z119.object({
|
|
23893
24043
|
outputs: MotionGraphicsOutputsSchema,
|
|
23894
24044
|
/**
|
|
23895
24045
|
* La captura REAL de la web de la plantilla (nunca una fabricada por la
|
|
23896
24046
|
* demo). Null cuando la plantilla no tiene ninguna: la captura demo nunca
|
|
23897
24047
|
* va live, así que el servicio usa `DEMO_MODE_PLACEHOLDER_CAPTURE`.
|
|
23898
24048
|
*/
|
|
23899
|
-
capture:
|
|
23900
|
-
bundleKey:
|
|
23901
|
-
sha256:
|
|
23902
|
-
uploadBytes:
|
|
24049
|
+
capture: z119.object({
|
|
24050
|
+
bundleKey: z119.string(),
|
|
24051
|
+
sha256: z119.string(),
|
|
24052
|
+
uploadBytes: z119.number().int().nullable(),
|
|
23903
24053
|
previewKey: nullableString
|
|
23904
24054
|
}).nullable()
|
|
23905
24055
|
}),
|
|
23906
|
-
image:
|
|
23907
|
-
provider:
|
|
23908
|
-
model:
|
|
23909
|
-
prompt:
|
|
23910
|
-
imageUrl:
|
|
23911
|
-
width:
|
|
23912
|
-
height:
|
|
24056
|
+
image: z119.object({
|
|
24057
|
+
provider: z119.string(),
|
|
24058
|
+
model: z119.string(),
|
|
24059
|
+
prompt: z119.string(),
|
|
24060
|
+
imageUrl: z119.string(),
|
|
24061
|
+
width: z119.number().int(),
|
|
24062
|
+
height: z119.number().int(),
|
|
23913
24063
|
adCopy: nullableString,
|
|
23914
|
-
rawResponse:
|
|
24064
|
+
rawResponse: z119.unknown()
|
|
23915
24065
|
})
|
|
23916
24066
|
});
|
|
23917
|
-
var DemoModeConfigSchema =
|
|
24067
|
+
var DemoModeConfigSchema = DemoModeEditableObjectSchema.extend({
|
|
23918
24068
|
snapshot: DemoModeSnapshotSchema.nullable(),
|
|
23919
|
-
snapshotAt:
|
|
24069
|
+
snapshotAt: z119.string().datetime().nullable()
|
|
23920
24070
|
});
|
|
23921
|
-
var DemoModeAdminViewSchema =
|
|
24071
|
+
var DemoModeAdminViewSchema = DemoModeEditableObjectSchema.extend({
|
|
23922
24072
|
// Sin configurar, la API devuelve ids vacíos ("" no es uuid): la vista los
|
|
23923
24073
|
// admite; el PUT sí exige uuid (`DemoModeEditableSchema`).
|
|
23924
|
-
templates:
|
|
23925
|
-
brandId:
|
|
23926
|
-
servicePageId:
|
|
23927
|
-
motionTaskId:
|
|
23928
|
-
motionVariantTaskId:
|
|
23929
|
-
motionThirdTaskId:
|
|
23930
|
-
imageTaskId:
|
|
24074
|
+
templates: z119.object({
|
|
24075
|
+
brandId: z119.string(),
|
|
24076
|
+
servicePageId: z119.string(),
|
|
24077
|
+
motionTaskId: z119.string(),
|
|
24078
|
+
motionVariantTaskId: z119.string().optional(),
|
|
24079
|
+
motionThirdTaskId: z119.string().optional(),
|
|
24080
|
+
imageTaskId: z119.string(),
|
|
24081
|
+
productLandingTaskId: z119.string().optional(),
|
|
24082
|
+
productVideoTaskId: z119.string().optional(),
|
|
24083
|
+
productVideoVariantTaskId: z119.string().optional(),
|
|
24084
|
+
productVideoThirdTaskId: z119.string().optional(),
|
|
24085
|
+
productImageTaskId: z119.string().optional()
|
|
23931
24086
|
}),
|
|
23932
|
-
snapshotAt:
|
|
24087
|
+
snapshotAt: z119.string().nullable()
|
|
23933
24088
|
});
|
|
23934
24089
|
var DEMO_MODE_TEMPLATE_PROBLEMS = [
|
|
23935
24090
|
"not_found",
|
|
@@ -23938,35 +24093,45 @@ var DEMO_MODE_TEMPLATE_PROBLEMS = [
|
|
|
23938
24093
|
"artifact_invalid",
|
|
23939
24094
|
"task_not_done",
|
|
23940
24095
|
"no_video",
|
|
23941
|
-
"no_creative"
|
|
24096
|
+
"no_creative",
|
|
24097
|
+
"product_invalid",
|
|
24098
|
+
"product_mismatch",
|
|
24099
|
+
"no_angles",
|
|
24100
|
+
"no_landing"
|
|
23942
24101
|
];
|
|
23943
|
-
var DemoModeTemplateVerdictSchema =
|
|
23944
|
-
|
|
23945
|
-
ok:
|
|
24102
|
+
var DemoModeTemplateVerdictSchema = z119.discriminatedUnion("ok", [
|
|
24103
|
+
z119.object({
|
|
24104
|
+
ok: z119.literal(true)
|
|
23946
24105
|
}),
|
|
23947
|
-
|
|
23948
|
-
ok:
|
|
23949
|
-
problem:
|
|
24106
|
+
z119.object({
|
|
24107
|
+
ok: z119.literal(false),
|
|
24108
|
+
problem: z119.enum(DEMO_MODE_TEMPLATE_PROBLEMS)
|
|
23950
24109
|
})
|
|
23951
24110
|
]);
|
|
23952
|
-
var DemoModeValidationSchema =
|
|
24111
|
+
var DemoModeValidationSchema = z119.object({
|
|
23953
24112
|
brandId: DemoModeTemplateVerdictSchema,
|
|
23954
24113
|
servicePageId: DemoModeTemplateVerdictSchema,
|
|
23955
24114
|
motionTaskId: DemoModeTemplateVerdictSchema,
|
|
23956
24115
|
motionVariantTaskId: DemoModeTemplateVerdictSchema.optional(),
|
|
23957
24116
|
motionThirdTaskId: DemoModeTemplateVerdictSchema.optional(),
|
|
23958
|
-
imageTaskId: DemoModeTemplateVerdictSchema
|
|
23959
|
-
|
|
23960
|
-
|
|
24117
|
+
imageTaskId: DemoModeTemplateVerdictSchema,
|
|
24118
|
+
productLandingTaskId: DemoModeTemplateVerdictSchema.optional(),
|
|
24119
|
+
productVideoTaskId: DemoModeTemplateVerdictSchema.optional(),
|
|
24120
|
+
productVideoVariantTaskId: DemoModeTemplateVerdictSchema.optional(),
|
|
24121
|
+
productVideoThirdTaskId: DemoModeTemplateVerdictSchema.optional(),
|
|
24122
|
+
productImageTaskId: DemoModeTemplateVerdictSchema.optional()
|
|
24123
|
+
});
|
|
24124
|
+
var DemoModeJobSchema = z119.object({
|
|
23961
24125
|
flow: DemoModeFlowSchema,
|
|
24126
|
+
productPhase: ProductDemoJobPhaseSchema.optional(),
|
|
23962
24127
|
step: DemoModeStepSchema,
|
|
23963
24128
|
/** brandId | servicePageOperationId | taskId según el flujo. */
|
|
23964
|
-
targetId:
|
|
23965
|
-
userId:
|
|
24129
|
+
targetId: z119.string().uuid(),
|
|
24130
|
+
userId: z119.string().min(1),
|
|
23966
24131
|
/** Solo marca: la generación de extracción que el guion completa. */
|
|
23967
|
-
generation:
|
|
24132
|
+
generation: z119.number().int().positive().optional(),
|
|
23968
24133
|
/** Solo `final`/`watchdog`: la parte del snapshot de ESTE flujo, congelada al empezar. */
|
|
23969
|
-
result:
|
|
24134
|
+
result: z119.unknown().optional()
|
|
23970
24135
|
});
|
|
23971
24136
|
|
|
23972
24137
|
// src/http.ts
|
|
@@ -24144,8 +24309,8 @@ async function readResponseText(response, maxBytes) {
|
|
|
24144
24309
|
}
|
|
24145
24310
|
__name(readResponseText, "readResponseText");
|
|
24146
24311
|
async function readResponseJson(response, maxBytes) {
|
|
24147
|
-
const
|
|
24148
|
-
return JSON.parse(
|
|
24312
|
+
const text4 = await readResponseText(response, maxBytes);
|
|
24313
|
+
return JSON.parse(text4);
|
|
24149
24314
|
}
|
|
24150
24315
|
__name(readResponseJson, "readResponseJson");
|
|
24151
24316
|
|
|
@@ -24478,23 +24643,23 @@ import { InsufficientScopeError, InvalidTokenError } from "@modelcontextprotocol
|
|
|
24478
24643
|
import { createRemoteJWKSet as createRemoteJWKSet2, jwtVerify as jwtVerify2 } from "jose";
|
|
24479
24644
|
|
|
24480
24645
|
// src/auth/oauth-config.ts
|
|
24481
|
-
import { z as
|
|
24646
|
+
import { z as z120 } from "zod";
|
|
24482
24647
|
var MCP_RESOURCE = new URL("https://mcp.productmaker.app/mcp");
|
|
24483
24648
|
var MCP_SCOPE = "mcp:access";
|
|
24484
24649
|
var REFRESH_SCOPE = "offline_access";
|
|
24485
24650
|
var STATIC_CLIENT_ISSUER = new URL(MCP_RESOURCE.origin);
|
|
24486
|
-
var oauthEnvSchema =
|
|
24487
|
-
MCP_REMOTE_AUTH_MODE:
|
|
24488
|
-
MCP_AUTH0_ISSUER:
|
|
24489
|
-
MCP_AUTH0_AUDIENCE:
|
|
24651
|
+
var oauthEnvSchema = z120.object({
|
|
24652
|
+
MCP_REMOTE_AUTH_MODE: z120.literal("oauth"),
|
|
24653
|
+
MCP_AUTH0_ISSUER: z120.string().trim().min(1),
|
|
24654
|
+
MCP_AUTH0_AUDIENCE: z120.string().trim().refine((value) => value === MCP_RESOURCE.href, {
|
|
24490
24655
|
message: `must equal ${MCP_RESOURCE.href}`
|
|
24491
24656
|
}),
|
|
24492
|
-
MCP_AUTH0_CLIENT_ID:
|
|
24493
|
-
MCP_AUTH0_CLIENT_SECRET:
|
|
24494
|
-
PM_API_AUDIENCE:
|
|
24495
|
-
AUTH0_AUDIENCE:
|
|
24496
|
-
MCP_STATIC_CLIENT_ID:
|
|
24497
|
-
MCP_STATIC_CLIENT_SECRET:
|
|
24657
|
+
MCP_AUTH0_CLIENT_ID: z120.string().trim().min(1),
|
|
24658
|
+
MCP_AUTH0_CLIENT_SECRET: z120.string().trim().min(1),
|
|
24659
|
+
PM_API_AUDIENCE: z120.string().trim().min(1),
|
|
24660
|
+
AUTH0_AUDIENCE: z120.string().trim().min(1),
|
|
24661
|
+
MCP_STATIC_CLIENT_ID: z120.string().trim().min(1).optional(),
|
|
24662
|
+
MCP_STATIC_CLIENT_SECRET: z120.string().trim().min(1).optional()
|
|
24498
24663
|
});
|
|
24499
24664
|
function formatZodIssues(error) {
|
|
24500
24665
|
return error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ");
|
|
@@ -25883,7 +26048,7 @@ var ApiClient = class {
|
|
|
25883
26048
|
};
|
|
25884
26049
|
|
|
25885
26050
|
// src/index.ts
|
|
25886
|
-
var MCP_VERSION = "12.1.
|
|
26051
|
+
var MCP_VERSION = "12.1.4";
|
|
25887
26052
|
|
|
25888
26053
|
// src/meta-upload-app.ts
|
|
25889
26054
|
import { readFileSync } from "fs";
|
|
@@ -25980,12 +26145,12 @@ function buildTaskResultsView(media, proxyBaseUrl) {
|
|
|
25980
26145
|
return null;
|
|
25981
26146
|
}
|
|
25982
26147
|
}, "safeUrl");
|
|
25983
|
-
const images = media.images.flatMap((
|
|
25984
|
-
const url = safeUrl(
|
|
26148
|
+
const images = media.images.flatMap((image2, index) => {
|
|
26149
|
+
const url = safeUrl(image2.url);
|
|
25985
26150
|
return url ? [
|
|
25986
26151
|
{
|
|
25987
26152
|
url,
|
|
25988
|
-
alt:
|
|
26153
|
+
alt: image2.alt?.slice(0, 160) ?? `ProductMaker image ${index + 1}`
|
|
25989
26154
|
}
|
|
25990
26155
|
] : [];
|
|
25991
26156
|
});
|
|
@@ -26070,7 +26235,7 @@ function registerTaskResultsAppResource(server, proxyBaseUrl) {
|
|
|
26070
26235
|
__name(registerTaskResultsAppResource, "registerTaskResultsAppResource");
|
|
26071
26236
|
|
|
26072
26237
|
// src/tools/tasks.ts
|
|
26073
|
-
import { z as
|
|
26238
|
+
import { z as z126 } from "zod";
|
|
26074
26239
|
|
|
26075
26240
|
// src/resolve-image.ts
|
|
26076
26241
|
import { lookup as dnsLookup } from "dns/promises";
|
|
@@ -26631,9 +26796,9 @@ async function resolveMediaRef(ref, opts) {
|
|
|
26631
26796
|
__name(resolveMediaRef, "resolveMediaRef");
|
|
26632
26797
|
|
|
26633
26798
|
// src/tools/shared.ts
|
|
26634
|
-
import { z as
|
|
26635
|
-
var Lang =
|
|
26636
|
-
var Country =
|
|
26799
|
+
import { z as z121 } from "zod";
|
|
26800
|
+
var Lang = z121.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);
|
|
26801
|
+
var Country = z121.string().min(2).max(3);
|
|
26637
26802
|
var LandingStrategyEnum = LandingStrategySchema;
|
|
26638
26803
|
var LandingImageFormatEnum = LandingImageFormatSchema;
|
|
26639
26804
|
var VideoPresetEnum = VideoPreset.extract([
|
|
@@ -26737,7 +26902,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
|
|
|
26737
26902
|
return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
|
|
26738
26903
|
}
|
|
26739
26904
|
__name(animationStyleApplies, "animationStyleApplies");
|
|
26740
|
-
var VideoTierEnum =
|
|
26905
|
+
var VideoTierEnum = z121.enum([
|
|
26741
26906
|
"basic"
|
|
26742
26907
|
]);
|
|
26743
26908
|
function resolveVideoTier(_tier) {
|
|
@@ -26795,10 +26960,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
|
|
|
26795
26960
|
var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
|
|
26796
26961
|
var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
|
|
26797
26962
|
var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
|
|
26798
|
-
var ImageRefSchema =
|
|
26799
|
-
url:
|
|
26800
|
-
path:
|
|
26801
|
-
assetId:
|
|
26963
|
+
var ImageRefSchema = z121.object({
|
|
26964
|
+
url: z121.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.'),
|
|
26965
|
+
path: z121.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`.'),
|
|
26966
|
+
assetId: z121.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.")
|
|
26802
26967
|
}).refine((v) => [
|
|
26803
26968
|
v.url,
|
|
26804
26969
|
v.path,
|
|
@@ -26806,18 +26971,18 @@ var ImageRefSchema = z120.object({
|
|
|
26806
26971
|
].filter(Boolean).length === 1, {
|
|
26807
26972
|
message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
|
|
26808
26973
|
});
|
|
26809
|
-
var ImagesInput =
|
|
26810
|
-
const assetCount = images.filter((
|
|
26974
|
+
var ImagesInput = z121.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
|
|
26975
|
+
const assetCount = images.filter((image2) => Boolean(image2.assetId)).length;
|
|
26811
26976
|
if (assetCount > 0 && assetCount !== images.length) {
|
|
26812
26977
|
ctx.addIssue({
|
|
26813
|
-
code:
|
|
26978
|
+
code: z121.ZodIssueCode.custom,
|
|
26814
26979
|
message: "all image entries must use assetId, or all must use URL/path sources"
|
|
26815
26980
|
});
|
|
26816
26981
|
}
|
|
26817
26982
|
}).describe('1 a 5 fotos del MISMO producto. La PRIMERA es la principal (hero); las dem\xE1s son \xE1ngulos adicionales. NO mezcles productos distintos en una sola llamada.\n\nCada entrada tiene EXACTAMENTE uno de:\n\u2022 `url` \u2014 URL p\xFAblica HTTPS (Shopify CDN, Cloudinary). Prefi\xE9rela si la foto ya est\xE1 hospedada.\n\u2022 `path` \u2014 Ruta del archivo en el computador del usuario (ej. "/Users/maria/Desktop/foto.jpg", "~/Downloads/camiseta.png"). \xDAsala cuando el usuario te dijo d\xF3nde guard\xF3 la foto. Solo MCP local \u2014 el cliente web rechaza paths.\n\n\u2022 `assetId` \u2014 ID opaco devuelto por `check_media_upload`. En MCP remoto, si el usuario quiere usar una foto de su laptop, llama `request_media_upload` y no pidas una ruta local ni URL.\n\nNo mezcles assetId con URL/path en la misma llamada. Los paths se conservan solo para MCP local por stdio.');
|
|
26818
26983
|
function uploadedAssetIds(images) {
|
|
26819
|
-
if (!images.length || !images.every((
|
|
26820
|
-
return images.map((
|
|
26984
|
+
if (!images.length || !images.every((image2) => Boolean(image2.assetId))) return null;
|
|
26985
|
+
return images.map((image2) => image2.assetId);
|
|
26821
26986
|
}
|
|
26822
26987
|
__name(uploadedAssetIds, "uploadedAssetIds");
|
|
26823
26988
|
function asText(value) {
|
|
@@ -26891,14 +27056,14 @@ async function submitCreative(api, opts) {
|
|
|
26891
27056
|
});
|
|
26892
27057
|
}
|
|
26893
27058
|
__name(submitCreative, "submitCreative");
|
|
26894
|
-
var ResearchTargetCountryEnum =
|
|
27059
|
+
var ResearchTargetCountryEnum = z121.enum([
|
|
26895
27060
|
"CO",
|
|
26896
27061
|
"MX",
|
|
26897
27062
|
"PE",
|
|
26898
27063
|
"EC",
|
|
26899
27064
|
"CL"
|
|
26900
27065
|
]);
|
|
26901
|
-
var ResearchCategoryEnum =
|
|
27066
|
+
var ResearchCategoryEnum = z121.enum([
|
|
26902
27067
|
"auto",
|
|
26903
27068
|
"automotive",
|
|
26904
27069
|
"kitchen",
|
|
@@ -27693,7 +27858,7 @@ function approveRefusalMessage(reason) {
|
|
|
27693
27858
|
__name(approveRefusalMessage, "approveRefusalMessage");
|
|
27694
27859
|
|
|
27695
27860
|
// src/tools/task-outputs.ts
|
|
27696
|
-
import { z as
|
|
27861
|
+
import { z as z122 } from "zod";
|
|
27697
27862
|
|
|
27698
27863
|
// src/tools/conversational-review-format.ts
|
|
27699
27864
|
function escapeMarkdownText(value) {
|
|
@@ -27824,12 +27989,12 @@ function serviceVideoResultMedia(result) {
|
|
|
27824
27989
|
};
|
|
27825
27990
|
}
|
|
27826
27991
|
__name(serviceVideoResultMedia, "serviceVideoResultMedia");
|
|
27827
|
-
var CreativeVariantIdentity =
|
|
27828
|
-
variantTaskId:
|
|
27829
|
-
sourceTaskId:
|
|
27992
|
+
var CreativeVariantIdentity = z122.object({
|
|
27993
|
+
variantTaskId: z122.string().uuid(),
|
|
27994
|
+
sourceTaskId: z122.string().uuid(),
|
|
27830
27995
|
kind: TaskCreativeVariantKind,
|
|
27831
27996
|
status: TaskStatusSchema,
|
|
27832
|
-
error:
|
|
27997
|
+
error: z122.string().optional()
|
|
27833
27998
|
});
|
|
27834
27999
|
function proxifyOutputs(outputs, proxyBaseUrl) {
|
|
27835
28000
|
if (!proxyBaseUrl || !isProxyEnabled()) return outputs;
|
|
@@ -28433,59 +28598,59 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
|
|
|
28433
28598
|
__name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
|
|
28434
28599
|
|
|
28435
28600
|
// src/tools/media-presentation.ts
|
|
28436
|
-
import { z as
|
|
28437
|
-
var HttpsPresentationUrlSchema =
|
|
28601
|
+
import { z as z123 } from "zod";
|
|
28602
|
+
var HttpsPresentationUrlSchema = z123.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
|
|
28438
28603
|
var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
|
|
28439
28604
|
const hostname = new URL(value).hostname.toLowerCase();
|
|
28440
28605
|
return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
|
|
28441
28606
|
}, "preview URL must be owned by ProductMaker");
|
|
28442
|
-
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) =>
|
|
28443
|
-
var PresentationImageSchema =
|
|
28444
|
-
kind:
|
|
28607
|
+
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z123.number().int().positive().max(maximum), "positiveIntAtMost");
|
|
28608
|
+
var PresentationImageSchema = z123.object({
|
|
28609
|
+
kind: z123.literal("image"),
|
|
28445
28610
|
url: HttpsPresentationUrlSchema,
|
|
28446
|
-
mimeType:
|
|
28611
|
+
mimeType: z123.enum([
|
|
28447
28612
|
"image/jpeg",
|
|
28448
28613
|
"image/png"
|
|
28449
28614
|
]),
|
|
28450
28615
|
byteSize: positiveIntAtMost(5 * 1024 * 1024),
|
|
28451
28616
|
width: positiveIntAtMost(16384),
|
|
28452
28617
|
height: positiveIntAtMost(16384),
|
|
28453
|
-
alt:
|
|
28618
|
+
alt: z123.string().trim().min(1).max(240)
|
|
28454
28619
|
}).strict();
|
|
28455
28620
|
var McpMediaPresentationSchema = PresentationImageSchema;
|
|
28456
|
-
var GalleryImageSchema =
|
|
28621
|
+
var GalleryImageSchema = z123.object({
|
|
28457
28622
|
url: ProductMakerPreviewUrlSchema,
|
|
28458
|
-
alt:
|
|
28623
|
+
alt: z123.string().trim().min(1).max(240)
|
|
28459
28624
|
});
|
|
28460
28625
|
var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
28461
|
-
async function imageBlocks(
|
|
28626
|
+
async function imageBlocks(image2, transport) {
|
|
28462
28627
|
const portableFallback = [
|
|
28463
28628
|
{
|
|
28464
28629
|
type: "resource_link",
|
|
28465
|
-
uri:
|
|
28466
|
-
name:
|
|
28467
|
-
...
|
|
28468
|
-
mimeType:
|
|
28630
|
+
uri: image2.url,
|
|
28631
|
+
name: image2.alt,
|
|
28632
|
+
...image2.mimeType ? {
|
|
28633
|
+
mimeType: image2.mimeType
|
|
28469
28634
|
} : {},
|
|
28470
|
-
...
|
|
28471
|
-
size:
|
|
28635
|
+
...image2.byteSize ? {
|
|
28636
|
+
size: image2.byteSize
|
|
28472
28637
|
} : {}
|
|
28473
28638
|
},
|
|
28474
28639
|
{
|
|
28475
28640
|
type: "text",
|
|
28476
|
-
text: `Si no ves la imagen, \xE1brela aqu\xED: ${
|
|
28641
|
+
text: `Si no ves la imagen, \xE1brela aqu\xED: ${image2.url}`
|
|
28477
28642
|
}
|
|
28478
28643
|
];
|
|
28479
28644
|
try {
|
|
28480
28645
|
const [resolved] = await resolveImages([
|
|
28481
28646
|
{
|
|
28482
|
-
url:
|
|
28647
|
+
url: image2.url
|
|
28483
28648
|
}
|
|
28484
28649
|
], {
|
|
28485
28650
|
transport,
|
|
28486
|
-
maxBytes:
|
|
28651
|
+
maxBytes: image2.byteSize ?? MCP_GALLERY_IMAGE_MAX_BYTES
|
|
28487
28652
|
});
|
|
28488
|
-
if (!resolved ||
|
|
28653
|
+
if (!resolved || image2.mimeType && resolved.mimetype !== image2.mimeType || resolved.buffer.byteLength > (image2.byteSize ?? MCP_GALLERY_IMAGE_MAX_BYTES)) {
|
|
28489
28654
|
return portableFallback;
|
|
28490
28655
|
}
|
|
28491
28656
|
return [
|
|
@@ -28512,12 +28677,12 @@ async function buildMcpMediaPresentationContent(rawPresentation, transport = "ht
|
|
|
28512
28677
|
];
|
|
28513
28678
|
}
|
|
28514
28679
|
__name(buildMcpMediaPresentationContent, "buildMcpMediaPresentationContent");
|
|
28515
|
-
var OwnedImagePreviewSchema =
|
|
28680
|
+
var OwnedImagePreviewSchema = z123.object({
|
|
28516
28681
|
url: HttpsPresentationUrlSchema.refine((value) => {
|
|
28517
28682
|
const url = new URL(value);
|
|
28518
28683
|
return !url.username && !url.password && !isPrivateHost(url.hostname);
|
|
28519
28684
|
}, "Preview URL must be public HTTPS without credentials"),
|
|
28520
|
-
alt:
|
|
28685
|
+
alt: z123.string().trim().min(1).max(240)
|
|
28521
28686
|
});
|
|
28522
28687
|
async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
|
|
28523
28688
|
const preview2 = OwnedImagePreviewSchema.safeParse(rawPreview);
|
|
@@ -28593,24 +28758,24 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
|
|
|
28593
28758
|
}
|
|
28594
28759
|
];
|
|
28595
28760
|
}
|
|
28596
|
-
const
|
|
28761
|
+
const image2 = parsed.data;
|
|
28597
28762
|
const heading = {
|
|
28598
28763
|
type: "text",
|
|
28599
|
-
text: `Foto ${index + 1}: ${
|
|
28764
|
+
text: `Foto ${index + 1}: ${image2.alt}`
|
|
28600
28765
|
};
|
|
28601
28766
|
const fallback = {
|
|
28602
28767
|
type: "resource_link",
|
|
28603
|
-
uri:
|
|
28604
|
-
name: `Abrir foto ${index + 1}: ${
|
|
28768
|
+
uri: image2.url,
|
|
28769
|
+
name: `Abrir foto ${index + 1}: ${image2.alt}`
|
|
28605
28770
|
};
|
|
28606
28771
|
const textFallback = {
|
|
28607
28772
|
type: "text",
|
|
28608
|
-
text: `Si no ves la foto ${index + 1}, \xE1brela aqu\xED: ${
|
|
28773
|
+
text: `Si no ves la foto ${index + 1}, \xE1brela aqu\xED: ${image2.url}`
|
|
28609
28774
|
};
|
|
28610
28775
|
try {
|
|
28611
28776
|
const [resolved] = await resolveImages([
|
|
28612
28777
|
{
|
|
28613
|
-
url:
|
|
28778
|
+
url: image2.url
|
|
28614
28779
|
}
|
|
28615
28780
|
], {
|
|
28616
28781
|
transport,
|
|
@@ -28712,7 +28877,7 @@ async function observeMcpMediaDelivery(fingerprint, work) {
|
|
|
28712
28877
|
__name(observeMcpMediaDelivery, "observeMcpMediaDelivery");
|
|
28713
28878
|
|
|
28714
28879
|
// src/tools/animated-video.ts
|
|
28715
|
-
import { z as
|
|
28880
|
+
import { z as z124 } from "zod";
|
|
28716
28881
|
|
|
28717
28882
|
// src/tools/paid-confirmation.ts
|
|
28718
28883
|
function describeMarketStudyChoice(enabled) {
|
|
@@ -28961,30 +29126,30 @@ function hookVariantsLabel(count) {
|
|
|
28961
29126
|
return count === 1 ? "1 versi\xF3n del gancho" : `${count} versiones del gancho`;
|
|
28962
29127
|
}
|
|
28963
29128
|
__name(hookVariantsLabel, "hookVariantsLabel");
|
|
28964
|
-
var DurationInput =
|
|
28965
|
-
var CreateAnimatedVideoInput =
|
|
28966
|
-
action:
|
|
29129
|
+
var DurationInput = z124.union(MOTION_GRAPHICS_DURATIONS.map((d) => z124.literal(d)));
|
|
29130
|
+
var CreateAnimatedVideoInput = z124.object({
|
|
29131
|
+
action: z124.enum([
|
|
28967
29132
|
"prepare",
|
|
28968
29133
|
"status",
|
|
28969
29134
|
"cancel",
|
|
28970
29135
|
"generate"
|
|
28971
29136
|
]).default("prepare").describe("prepare inicia una captura gratuita; status consulta websiteCaptureId; cancel la cancela; generate requiere captura ready y confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrar vista previa y precio."),
|
|
28972
|
-
brandId:
|
|
28973
|
-
websiteCaptureId:
|
|
28974
|
-
generationRequestId:
|
|
28975
|
-
confirmed:
|
|
29137
|
+
brandId: z124.string().uuid().optional().describe("ID de un servicio propio y listo (de create_brand). Obligatorio al preparar y crear videos nuevos. Conserva el mismo brandId en reintentos; si recuperas una generaci\xF3n hist\xF3rica aceptada sin este campo, om\xEDtelo como en la petici\xF3n original. status/cancel no lo necesitan."),
|
|
29138
|
+
websiteCaptureId: z124.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
|
|
29139
|
+
generationRequestId: z124.string().uuid().optional().describe("Identidad opcional de una generaci\xF3n confirmada. Repite el mismo UUID al recuperar una respuesta perdida; usa otro \xFAnicamente cuando el usuario pida y confirme otro video, nunca por un error de transporte."),
|
|
29140
|
+
confirmed: z124.boolean().optional().describe("Solo true despu\xE9s de que el usuario confirme esta captura, formato, duraci\xF3n, idioma y precio. Obligatorio para generate; preparar no genera ni cobra."),
|
|
28976
29141
|
// Plain text, not `.url()`: users type «cal.com», and the web accepts it.
|
|
28977
29142
|
// normalizeWebAddress (shared with the web) adds https:// and refuses
|
|
28978
29143
|
// anything that is not a public http(s) address.
|
|
28979
|
-
landingUrl:
|
|
29144
|
+
landingUrl: z124.string().trim().min(1).optional().describe("Enlace p\xFAblico de la p\xE1gina del servicio, como lo dio el usuario (\xABcal.com\xBB o \xABhttps://cal.com\xBB). El video sale de lo que muestra esa p\xE1gina: su marca, colores y mensajes."),
|
|
28980
29145
|
format: MotionGraphicsFormatSchema.optional().describe('Formato: "vertical" (9:16, Reels/TikTok), "square" (1:1, feed) u "horizontal" (16:9, YouTube/web). Si el usuario no lo dijo, PREG\xDANTALE.'),
|
|
28981
29146
|
durationSec: DurationInput.optional().describe(`Duraci\xF3n en segundos: ${MOTION_GRAPHICS_DURATIONS.join(", ")}. Fija el precio (ver la descripci\xF3n de la herramienta). Si el usuario no la dijo, PREG\xDANTALE.`),
|
|
28982
29147
|
language: MotionGraphicsLanguageSchema.optional().describe('Idioma de los textos del video: "es", "en" o "pt".'),
|
|
28983
29148
|
videoQuality: MotionGraphicsVideoQualitySchema.default(DEFAULT_MOTION_GRAPHICS_VIDEO_QUALITY).describe('Calidad IA: "economy" (econ\xF3mica) o "pro" (alta, por defecto). Afecta el precio de los clips IA.'),
|
|
28984
29149
|
videoResolution: MotionGraphicsVideoResolutionSchema.default(DEFAULT_MOTION_GRAPHICS_VIDEO_RESOLUTION).describe('Resoluci\xF3n: "480p" (por defecto), "720p" o "1080p". 1080p solo est\xE1 disponible con videoQuality="pro".'),
|
|
28985
|
-
notes:
|
|
29150
|
+
notes: z124.string().trim().max(MOTION_GRAPHICS_NOTES_MAX_CHARS).optional().describe("Opcional. Idea creativa, escenarios, acciones, di\xE1logo, voz o m\xFAsica en lenguaje natural. El director puede hacer solo motion graphics, escenas reales o escenas imposibles seg\xFAn la idea; las frases gu\xEDan el guion sin garantizar reproducci\xF3n exacta."),
|
|
28986
29151
|
hookVariants: MotionGraphicsHookVariantsSchema.optional().describe(`Opcional. Cantidad de videos independientes, de 1 a ${MOTION_GRAPHICS_HOOK_VARIANTS_MAX} (por defecto 1). Cada uno tiene su propio \xE1ngulo, guion y estilo visual, respetando notes, y reserva el precio completo de un video (ver la descripci\xF3n); \xFAsalo solo si el usuario lo pide.`),
|
|
28987
|
-
music:
|
|
29152
|
+
music: z124.boolean().optional().describe("Opcional. M\xFAsica y efectos dirigidos seg\xFAn el negocio y el video (por defecto true), con una copia adicional solo con voces. false entrega solo voces, sin m\xFAsica ni efectos a\xF1adidos ni el cargo de m\xFAsica. \xDAsalo solo si el usuario lo pide.")
|
|
28988
29153
|
}).strict();
|
|
28989
29154
|
function captureNextAction(capture) {
|
|
28990
29155
|
if (capture.status === "ready") return "Muestra la vista previa al usuario y confirma formato, duraci\xF3n, idioma, calidad IA, resoluci\xF3n y precio. Solo despu\xE9s llama create_animated_video con action=generate, este websiteCaptureId y confirmed=true.";
|
|
@@ -29037,33 +29202,33 @@ var FORMAT_LABELS = {
|
|
|
29037
29202
|
square: "cuadrado 1:1",
|
|
29038
29203
|
horizontal: "horizontal 16:9"
|
|
29039
29204
|
};
|
|
29040
|
-
var AnimatedVideoResultSchema =
|
|
29041
|
-
status:
|
|
29205
|
+
var AnimatedVideoResultSchema = z124.object({
|
|
29206
|
+
status: z124.enum([
|
|
29042
29207
|
"pending",
|
|
29043
29208
|
"done",
|
|
29044
29209
|
"error"
|
|
29045
29210
|
]),
|
|
29046
|
-
serviceMode:
|
|
29047
|
-
finalMp4Url:
|
|
29048
|
-
adCopy:
|
|
29049
|
-
adCopies:
|
|
29050
|
-
error:
|
|
29051
|
-
motionGraphics:
|
|
29211
|
+
serviceMode: z124.literal("motion_graphics"),
|
|
29212
|
+
finalMp4Url: z124.string().optional(),
|
|
29213
|
+
adCopy: z124.string().optional(),
|
|
29214
|
+
adCopies: z124.array(z124.string()).optional(),
|
|
29215
|
+
error: z124.string().optional(),
|
|
29216
|
+
motionGraphics: z124.object({
|
|
29052
29217
|
stage: MotionGraphicsStageSchema,
|
|
29053
29218
|
format: MotionGraphicsFormatSchema,
|
|
29054
|
-
durationSec:
|
|
29055
|
-
width:
|
|
29056
|
-
height:
|
|
29219
|
+
durationSec: z124.number(),
|
|
29220
|
+
width: z124.number().optional(),
|
|
29221
|
+
height: z124.number().optional(),
|
|
29057
29222
|
language: MotionGraphicsLanguageSchema.optional(),
|
|
29058
29223
|
videoQuality: MotionGraphicsVideoQualitySchema.optional().catch(void 0),
|
|
29059
29224
|
videoResolution: MotionGraphicsVideoResolutionSchema.optional().catch(void 0),
|
|
29060
|
-
creativeBatch:
|
|
29225
|
+
creativeBatch: z124.object({
|
|
29061
29226
|
index: MotionGraphicsHookVariantsSchema,
|
|
29062
29227
|
count: MotionGraphicsHookVariantsSchema,
|
|
29063
|
-
tasks:
|
|
29064
|
-
taskId:
|
|
29228
|
+
tasks: z124.array(z124.object({
|
|
29229
|
+
taskId: z124.string().uuid(),
|
|
29065
29230
|
index: MotionGraphicsHookVariantsSchema,
|
|
29066
|
-
status:
|
|
29231
|
+
status: z124.enum([
|
|
29067
29232
|
"queued",
|
|
29068
29233
|
"processing",
|
|
29069
29234
|
"done",
|
|
@@ -29071,29 +29236,29 @@ var AnimatedVideoResultSchema = z123.object({
|
|
|
29071
29236
|
])
|
|
29072
29237
|
})).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX)
|
|
29073
29238
|
}).optional().catch(void 0),
|
|
29074
|
-
queuedAt:
|
|
29075
|
-
jobsAhead:
|
|
29076
|
-
stageStartedAt:
|
|
29077
|
-
renderProgress:
|
|
29239
|
+
queuedAt: z124.string().optional(),
|
|
29240
|
+
jobsAhead: z124.number().int().nonnegative().optional(),
|
|
29241
|
+
stageStartedAt: z124.string().optional(),
|
|
29242
|
+
renderProgress: z124.number().optional(),
|
|
29078
29243
|
// AI clip fields (absent on a video paid before clips, or from an API
|
|
29079
29244
|
// that predates them). Lenient: an unreadable value is dropped
|
|
29080
29245
|
// instead of hiding the status.
|
|
29081
|
-
clipCount:
|
|
29082
|
-
clipsUsed:
|
|
29083
|
-
clipPriceCents:
|
|
29084
|
-
clipsRefunded:
|
|
29246
|
+
clipCount: z124.number().int().nonnegative().optional().catch(void 0),
|
|
29247
|
+
clipsUsed: z124.number().int().nonnegative().optional().catch(void 0),
|
|
29248
|
+
clipPriceCents: z124.number().finite().nonnegative().optional().catch(void 0),
|
|
29249
|
+
clipsRefunded: z124.number().int().nonnegative().optional().catch(void 0),
|
|
29085
29250
|
// Hook versions (absent from an API or a video before them): the
|
|
29086
29251
|
// count ordered and, once done, the signed URLs of the EXTRA versions
|
|
29087
29252
|
// (hook 2, hook 3); `finalMp4Url` is hook 1.
|
|
29088
|
-
hookVariants:
|
|
29089
|
-
cleanVideoUrl:
|
|
29090
|
-
cleanVariantUrls:
|
|
29091
|
-
variantUrls:
|
|
29253
|
+
hookVariants: z124.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
|
|
29254
|
+
cleanVideoUrl: z124.string().url().optional().catch(void 0),
|
|
29255
|
+
cleanVariantUrls: z124.array(z124.string().url()).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
|
|
29256
|
+
variantUrls: z124.array(z124.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
|
|
29092
29257
|
// Extra hook versions given back, as the task recorded it once the
|
|
29093
29258
|
// refunds landed (absent until then, and from an API before it).
|
|
29094
|
-
variantsRefunded:
|
|
29095
|
-
activity:
|
|
29096
|
-
previewUrl:
|
|
29259
|
+
variantsRefunded: z124.number().int().nonnegative().optional().catch(void 0),
|
|
29260
|
+
activity: z124.array(MotionGraphicsActivitySchema).optional().catch(void 0),
|
|
29261
|
+
previewUrl: z124.string().optional()
|
|
29097
29262
|
}).passthrough()
|
|
29098
29263
|
}).passthrough();
|
|
29099
29264
|
function parseAnimatedVideoResult(value) {
|
|
@@ -29146,10 +29311,10 @@ function toAgentFacingAnimatedVideo(result) {
|
|
|
29146
29311
|
...hasSiteText && activity ? {
|
|
29147
29312
|
activity: activity.map((item) => {
|
|
29148
29313
|
if (!SITE_TEXT_CODES.has(item.code) || !item.text) return item;
|
|
29149
|
-
const { text:
|
|
29314
|
+
const { text: text4, ...rest } = item;
|
|
29150
29315
|
return {
|
|
29151
29316
|
...rest,
|
|
29152
|
-
untrustedSiteText:
|
|
29317
|
+
untrustedSiteText: text4
|
|
29153
29318
|
};
|
|
29154
29319
|
})
|
|
29155
29320
|
} : {}
|
|
@@ -29372,7 +29537,7 @@ function registerAnimatedVideoTools(server, api) {
|
|
|
29372
29537
|
nowMs: 0
|
|
29373
29538
|
})
|
|
29374
29539
|
});
|
|
29375
|
-
const parsedTaskIds =
|
|
29540
|
+
const parsedTaskIds = z124.array(z124.string().uuid()).min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).safeParse(created.taskIds);
|
|
29376
29541
|
const taskIds = parsedTaskIds.success && parsedTaskIds.data[0] === created.taskId ? parsedTaskIds.data : void 0;
|
|
29377
29542
|
const receipt = {
|
|
29378
29543
|
taskId: created.taskId,
|
|
@@ -29414,10 +29579,10 @@ function registerAnimatedVideoTools(server, api) {
|
|
|
29414
29579
|
__name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
|
|
29415
29580
|
|
|
29416
29581
|
// src/tools/winning-product-image.ts
|
|
29417
|
-
import { z as
|
|
29418
|
-
var WinnerReferenceInput =
|
|
29419
|
-
runId:
|
|
29420
|
-
candidateSourceId:
|
|
29582
|
+
import { z as z125 } from "zod";
|
|
29583
|
+
var WinnerReferenceInput = z125.object({
|
|
29584
|
+
runId: z125.string().uuid(),
|
|
29585
|
+
candidateSourceId: z125.string().trim().min(1).max(160)
|
|
29421
29586
|
}).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
|
|
29422
29587
|
async function resolveWinnerImages(api, winnerReference, images) {
|
|
29423
29588
|
if (!winnerReference) return images;
|
|
@@ -29428,9 +29593,9 @@ async function resolveWinnerImages(api, winnerReference, images) {
|
|
|
29428
29593
|
},
|
|
29429
29594
|
...images ?? []
|
|
29430
29595
|
];
|
|
29431
|
-
const unique = combined.filter((
|
|
29596
|
+
const unique = combined.filter((image2, index, all) => all.findIndex((candidate) => candidate.assetId === image2.assetId) === index);
|
|
29432
29597
|
if (unique.length > 5) throw new Error("M\xE1ximo 5 fotos del producto en total.");
|
|
29433
|
-
if (!unique.every((
|
|
29598
|
+
if (!unique.every((image2) => Boolean(image2.assetId))) {
|
|
29434
29599
|
throw new Error("Cuando reutilizas la foto encontrada, carga las fotos adicionales con request_media_upload.");
|
|
29435
29600
|
}
|
|
29436
29601
|
return unique;
|
|
@@ -29454,62 +29619,62 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
|
|
|
29454
29619
|
var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
|
|
29455
29620
|
var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
|
|
29456
29621
|
var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
|
|
29457
|
-
var CreateProductTaskInput =
|
|
29622
|
+
var CreateProductTaskInput = z126.object({
|
|
29458
29623
|
images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
|
|
29459
29624
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
29460
|
-
projectId:
|
|
29461
|
-
productUrl:
|
|
29625
|
+
projectId: z126.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
|
|
29626
|
+
productUrl: z126.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."),
|
|
29462
29627
|
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.'),
|
|
29463
29628
|
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.'),
|
|
29464
|
-
price:
|
|
29465
|
-
compareAtPrice:
|
|
29466
|
-
offer:
|
|
29467
|
-
paymentMethods:
|
|
29468
|
-
productContext:
|
|
29469
|
-
productLabel:
|
|
29629
|
+
price: z126.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.'),
|
|
29630
|
+
compareAtPrice: z126.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".'),
|
|
29631
|
+
offer: z126.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.'),
|
|
29632
|
+
paymentMethods: z126.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.'),
|
|
29633
|
+
productContext: z126.string().max(PRODUCT_CONTEXT_MAX_CHARS).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."),
|
|
29634
|
+
productLabel: z126.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.'),
|
|
29470
29635
|
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); "problem_solution" en single_call abre sin el producto y el producto entra por referencia en su beat de soluci\xF3n. 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.'),
|
|
29471
29636
|
animationStyle: AnimationStyleEnum.optional().describe('Opcional. Estilo visual SOLO para presets animados ("pixar_problem" o "pixar_sassy") \u2014 la API lo rechaza con cualquier otro preset. Opciones: "pixar_3d" (default, look 3D de pel\xEDcula animada), "claymation" (plastilina stop-motion artesanal), "wes_anderson" (tableau sim\xE9trico pastel), "sci_fi" (futurista con HUDs y ne\xF3n), "realista" (fotorrealista, fiel al producto). Si el usuario pide un look animado sin nombrar el estilo, omite el campo.'),
|
|
29472
|
-
durationSeconds:
|
|
29473
|
-
|
|
29474
|
-
|
|
29637
|
+
durationSeconds: z126.union([
|
|
29638
|
+
z126.literal(15),
|
|
29639
|
+
z126.literal(30)
|
|
29475
29640
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
29476
|
-
pauseForAngleReview:
|
|
29477
|
-
aiDecidesAll:
|
|
29641
|
+
pauseForAngleReview: z126.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."),
|
|
29642
|
+
aiDecidesAll: z126.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."),
|
|
29478
29643
|
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.'),
|
|
29479
29644
|
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.'),
|
|
29480
29645
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
29481
29646
|
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).'),
|
|
29482
|
-
videoAngleCount:
|
|
29647
|
+
videoAngleCount: z126.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."),
|
|
29483
29648
|
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.'),
|
|
29484
|
-
outputs:
|
|
29649
|
+
outputs: z126.array(z126.enum([
|
|
29485
29650
|
"landing",
|
|
29486
29651
|
"video",
|
|
29487
29652
|
"image"
|
|
29488
29653
|
])).min(1).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}`),
|
|
29489
|
-
includeInitialLandingGif:
|
|
29490
|
-
competitorScanEnabled:
|
|
29654
|
+
includeInitialLandingGif: z126.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
|
|
29655
|
+
competitorScanEnabled: z126.boolean().optional().describe("Opcional. Default false: omitirlo significa SIN estudio de mercado. Antes de crear, llama estimate_market_study_cost con kind=product_task, muestra al usuario el costo con y sin estudio y preg\xFAntale si lo quiere; env\xEDa true solo si lo acepta (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."),
|
|
29491
29656
|
generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, efectos y m\xFAsica sobre cada video entregado (variante with_ai_edit; se cobra al entregar, por video). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro"; false/omitido = sin edici\xF3n.'),
|
|
29492
|
-
replicateWinnerWhenFound:
|
|
29493
|
-
brandId:
|
|
29494
|
-
actorId:
|
|
29657
|
+
replicateWinnerWhenFound: z126.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."),
|
|
29658
|
+
brandId: z126.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."),
|
|
29659
|
+
actorId: z126.string().trim().min(1).max(120).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."),
|
|
29495
29660
|
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.'),
|
|
29496
|
-
creativeDirection:
|
|
29497
|
-
headline:
|
|
29498
|
-
subheadline:
|
|
29661
|
+
creativeDirection: z126.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.'),
|
|
29662
|
+
headline: z126.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."),
|
|
29663
|
+
subheadline: z126.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."),
|
|
29499
29664
|
landingStrategy: LandingStrategyEnum.optional().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".'),
|
|
29500
29665
|
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".')
|
|
29501
29666
|
}).strict();
|
|
29502
|
-
var CreateServiceVideoInput =
|
|
29503
|
-
landingUrl:
|
|
29504
|
-
additionalContext:
|
|
29667
|
+
var CreateServiceVideoInput = z126.object({
|
|
29668
|
+
landingUrl: z126.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
|
|
29669
|
+
additionalContext: z126.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
|
|
29505
29670
|
language: Lang.describe("Idioma del video: es, en o pt."),
|
|
29506
|
-
voiceId:
|
|
29507
|
-
brandId:
|
|
29508
|
-
reviewMode:
|
|
29671
|
+
voiceId: z126.string().trim().min(1).pipe(VoiceId).optional().describe('Opcional. Voz para toda la narraci\xF3n. Usa "auto" para que la IA la alinee con el presentador. Las voces del banco compartido fueron retiradas.'),
|
|
29672
|
+
brandId: z126.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
|
|
29673
|
+
reviewMode: z126.enum([
|
|
29509
29674
|
"automatic",
|
|
29510
29675
|
"guided"
|
|
29511
29676
|
]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
|
|
29512
|
-
videoPreset:
|
|
29677
|
+
videoPreset: z126.enum([
|
|
29513
29678
|
"auto",
|
|
29514
29679
|
"ugc_dynamic",
|
|
29515
29680
|
"ugc_how_to",
|
|
@@ -29519,128 +29684,128 @@ var CreateServiceVideoInput = z125.object({
|
|
|
29519
29684
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
29520
29685
|
videoResolution: VideoResolutionEnum.default("480p").describe('Opcional. Resoluci\xF3n: "480p" o "720p". 720p cuesta m\xE1s por segundo y solo est\xE1 disponible en "economy" y "pro" (Medio = 768P). Default: 480p.')
|
|
29521
29686
|
}).strict();
|
|
29522
|
-
var GetTaskStatusInput =
|
|
29523
|
-
taskId:
|
|
29524
|
-
waitSeconds:
|
|
29687
|
+
var GetTaskStatusInput = z126.object({
|
|
29688
|
+
taskId: z126.string().min(1),
|
|
29689
|
+
waitSeconds: z126.number().int().min(0).max(120).optional()
|
|
29525
29690
|
});
|
|
29526
|
-
var ListTasksInput =
|
|
29527
|
-
limit:
|
|
29528
|
-
offset:
|
|
29529
|
-
search:
|
|
29691
|
+
var ListTasksInput = z126.object({
|
|
29692
|
+
limit: z126.number().int().min(1).max(50).optional(),
|
|
29693
|
+
offset: z126.number().int().min(0).optional(),
|
|
29694
|
+
search: z126.string().optional()
|
|
29530
29695
|
});
|
|
29531
29696
|
var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
|
|
29532
29697
|
var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
|
|
29533
|
-
var EditTaskDraftInput =
|
|
29534
|
-
taskId:
|
|
29535
|
-
angleIndex:
|
|
29536
|
-
angle:
|
|
29537
|
-
angle:
|
|
29538
|
-
buyerPersona:
|
|
29539
|
-
actor:
|
|
29540
|
-
actorId:
|
|
29541
|
-
gender:
|
|
29698
|
+
var EditTaskDraftInput = z126.object({
|
|
29699
|
+
taskId: z126.string().min(1),
|
|
29700
|
+
angleIndex: z126.number().int().min(0),
|
|
29701
|
+
angle: z126.object({
|
|
29702
|
+
angle: z126.string().min(1).max(480),
|
|
29703
|
+
buyerPersona: z126.string().min(1).max(360),
|
|
29704
|
+
actor: z126.string().min(1).max(360).optional(),
|
|
29705
|
+
actorId: z126.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."),
|
|
29706
|
+
gender: z126.enum([
|
|
29542
29707
|
"female",
|
|
29543
29708
|
"male"
|
|
29544
29709
|
]).optional(),
|
|
29545
|
-
scriptNotes:
|
|
29710
|
+
scriptNotes: z126.string().max(2e3).optional()
|
|
29546
29711
|
})
|
|
29547
29712
|
});
|
|
29548
|
-
var PendingActionPayload =
|
|
29549
|
-
|
|
29550
|
-
kind:
|
|
29713
|
+
var PendingActionPayload = z126.discriminatedUnion("kind", [
|
|
29714
|
+
z126.object({
|
|
29715
|
+
kind: z126.literal("product_reference_set_approval"),
|
|
29551
29716
|
scope: ProductReferenceScopeEnum.optional(),
|
|
29552
|
-
scopeKey:
|
|
29553
|
-
scopeSnapshotId:
|
|
29554
|
-
expectedScopeHash:
|
|
29717
|
+
scopeKey: z126.string().min(1).max(120).optional(),
|
|
29718
|
+
scopeSnapshotId: z126.string().uuid().optional(),
|
|
29719
|
+
expectedScopeHash: z126.string().min(1).max(128).optional(),
|
|
29555
29720
|
decision: ProductReferenceResolutionDecisionEnum,
|
|
29556
29721
|
reason: ProductReferenceRejectionReasonEnum.optional(),
|
|
29557
|
-
affectedRefKeys:
|
|
29558
|
-
affectedPhotoNumbers:
|
|
29559
|
-
recoveryAction:
|
|
29722
|
+
affectedRefKeys: z126.array(z126.string().min(1).max(200)).min(1).optional(),
|
|
29723
|
+
affectedPhotoNumbers: z126.array(z126.number().int().positive()).min(1).optional(),
|
|
29724
|
+
recoveryAction: z126.enum([
|
|
29560
29725
|
"remove",
|
|
29561
29726
|
"replace",
|
|
29562
29727
|
"upload",
|
|
29563
29728
|
"return_to_selection"
|
|
29564
29729
|
]).optional()
|
|
29565
29730
|
}),
|
|
29566
|
-
|
|
29567
|
-
kind:
|
|
29568
|
-
selectedPhotoNumbers:
|
|
29731
|
+
z126.object({
|
|
29732
|
+
kind: z126.literal("product_reference_confirmation"),
|
|
29733
|
+
selectedPhotoNumbers: z126.array(z126.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."),
|
|
29569
29734
|
userChoice: ProductReferenceUserChoiceEnum.optional(),
|
|
29570
|
-
confirmedProductNames:
|
|
29735
|
+
confirmedProductNames: z126.array(z126.string().min(1).max(120)).min(2).max(8).optional(),
|
|
29571
29736
|
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."),
|
|
29572
29737
|
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."),
|
|
29573
|
-
useMultiSceneShowcase:
|
|
29738
|
+
useMultiSceneShowcase: z126.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
|
|
29574
29739
|
}),
|
|
29575
|
-
|
|
29576
|
-
kind:
|
|
29740
|
+
z126.object({
|
|
29741
|
+
kind: z126.literal("angle_review_approval"),
|
|
29577
29742
|
// All edits are optional — empty action body just approves the
|
|
29578
29743
|
// backend-generated draft as-is. Field shapes mirror the angle-review
|
|
29579
29744
|
// request contracts in @packages/types/wizard.ts; the handler routes to
|
|
29580
29745
|
// the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
|
|
29581
|
-
customAngle:
|
|
29746
|
+
customAngle: z126.string().min(1).max(480).optional(),
|
|
29582
29747
|
// Keep the shared MCP action within the strictest downstream contract:
|
|
29583
29748
|
// autopilot/image resume endpoints cap these fields at 1500 characters.
|
|
29584
|
-
painPoints:
|
|
29585
|
-
benefits:
|
|
29749
|
+
painPoints: z126.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
29750
|
+
benefits: z126.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
29586
29751
|
// Same policy as the two fields above: the strictest downstream contract
|
|
29587
29752
|
// wins. The image endpoint caps each feature at 240 while landing/video
|
|
29588
29753
|
// accept 300, and this single action routes to whichever the task is — so
|
|
29589
29754
|
// accepting 300 here turns a 250-character feature on an image task into
|
|
29590
29755
|
// an opaque HTTP 400 after the model already believed it had been saved.
|
|
29591
|
-
features:
|
|
29592
|
-
buyerPersona:
|
|
29756
|
+
features: z126.array(z126.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
|
|
29757
|
+
buyerPersona: z126.string().min(1).max(360).optional(),
|
|
29593
29758
|
narrativeStyle: PublicNarrativeStyleEnum.optional().describe('Narrativa del video. "problem_product_cta" (Problema y Soluci\xF3n) funciona en ambos formatos \u2014 en Un solo clip abre sin producto y el producto entra por referencia en su beat. La familia storyteller ("animated_storyteller", "animated_inner_journey", "animated_object_soul", "animated_timeline") no est\xE1 disponible por ahora.'),
|
|
29594
|
-
actor:
|
|
29595
|
-
actorId:
|
|
29596
|
-
creativeDirection:
|
|
29597
|
-
selectedAngleNumbers:
|
|
29598
|
-
angleEdits:
|
|
29599
|
-
angleNumber:
|
|
29600
|
-
narrativeSelection:
|
|
29759
|
+
actor: z126.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."),
|
|
29760
|
+
actorId: z126.string().max(120).nullable().optional(),
|
|
29761
|
+
creativeDirection: z126.string().max(2e3).optional(),
|
|
29762
|
+
selectedAngleNumbers: z126.array(z126.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."),
|
|
29763
|
+
angleEdits: z126.array(z126.object({
|
|
29764
|
+
angleNumber: z126.number().int().positive(),
|
|
29765
|
+
narrativeSelection: z126.enum([
|
|
29601
29766
|
"market",
|
|
29602
29767
|
"guided"
|
|
29603
29768
|
]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
|
|
29604
|
-
angle:
|
|
29605
|
-
buyerPersona:
|
|
29769
|
+
angle: z126.string().min(1).max(480).optional(),
|
|
29770
|
+
buyerPersona: z126.string().min(1).max(360).optional(),
|
|
29606
29771
|
narrativeStyle: PublicNarrativeStyleEnum.optional().describe('Narrativa del video. "problem_product_cta" (Problema y Soluci\xF3n) funciona en ambos formatos \u2014 en Un solo clip abre sin producto y el producto entra por referencia en su beat. La familia storyteller ("animated_storyteller", "animated_inner_journey", "animated_object_soul", "animated_timeline") no est\xE1 disponible por ahora.'),
|
|
29607
|
-
actor:
|
|
29608
|
-
actorId:
|
|
29609
|
-
creativeDirection:
|
|
29772
|
+
actor: z126.string().min(1).max(360).optional(),
|
|
29773
|
+
actorId: z126.string().max(120).nullable().optional(),
|
|
29774
|
+
creativeDirection: z126.string().max(2e3).optional()
|
|
29610
29775
|
}).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)."),
|
|
29611
|
-
gapDurationSeconds:
|
|
29612
|
-
|
|
29613
|
-
|
|
29776
|
+
gapDurationSeconds: z126.union([
|
|
29777
|
+
z126.literal(15),
|
|
29778
|
+
z126.literal(30)
|
|
29614
29779
|
]).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.")
|
|
29615
29780
|
}),
|
|
29616
|
-
|
|
29617
|
-
kind:
|
|
29618
|
-
angleId:
|
|
29619
|
-
angleNumber:
|
|
29620
|
-
content:
|
|
29621
|
-
creativeDirection:
|
|
29622
|
-
actor:
|
|
29781
|
+
z126.object({
|
|
29782
|
+
kind: z126.literal("service_angle_approval"),
|
|
29783
|
+
angleId: z126.string().uuid().optional(),
|
|
29784
|
+
angleNumber: z126.number().int().positive().optional(),
|
|
29785
|
+
content: z126.string().min(1).max(480).optional(),
|
|
29786
|
+
creativeDirection: z126.string().min(1).max(1500).optional(),
|
|
29787
|
+
actor: z126.string().min(1).max(360).optional()
|
|
29623
29788
|
}),
|
|
29624
|
-
|
|
29625
|
-
kind:
|
|
29626
|
-
voiceovers:
|
|
29627
|
-
visualDirections:
|
|
29628
|
-
voiceoversByScene:
|
|
29629
|
-
visualDirectionsByScene:
|
|
29789
|
+
z126.object({
|
|
29790
|
+
kind: z126.literal("service_script_approval"),
|
|
29791
|
+
voiceovers: z126.record(z126.string(), z126.string().min(1).max(600)).optional(),
|
|
29792
|
+
visualDirections: z126.record(z126.string(), z126.string().min(1).max(1200)).optional(),
|
|
29793
|
+
voiceoversByScene: z126.record(z126.string(), z126.string().min(1).max(600)).optional(),
|
|
29794
|
+
visualDirectionsByScene: z126.record(z126.string(), z126.string().min(1).max(1200)).optional()
|
|
29630
29795
|
})
|
|
29631
29796
|
]);
|
|
29632
|
-
var ResolvePendingActionInput =
|
|
29633
|
-
taskId:
|
|
29797
|
+
var ResolvePendingActionInput = z126.object({
|
|
29798
|
+
taskId: z126.string().min(1),
|
|
29634
29799
|
action: PendingActionPayload
|
|
29635
29800
|
}).strict();
|
|
29636
29801
|
function resolveVariantConfirmVideoTier(action) {
|
|
29637
29802
|
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
29638
29803
|
}
|
|
29639
29804
|
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
29640
|
-
var StatusForResolveSchema =
|
|
29805
|
+
var StatusForResolveSchema = z126.object({
|
|
29641
29806
|
// Metadata used to select the backend resume contract. Older API responses
|
|
29642
29807
|
// may omit these fields, so the resolver keeps the generic fallback.
|
|
29643
|
-
kind:
|
|
29808
|
+
kind: z126.enum([
|
|
29644
29809
|
"autopilot",
|
|
29645
29810
|
"video",
|
|
29646
29811
|
"image",
|
|
@@ -29648,18 +29813,18 @@ var StatusForResolveSchema = z125.object({
|
|
|
29648
29813
|
"mix",
|
|
29649
29814
|
"service"
|
|
29650
29815
|
]).optional(),
|
|
29651
|
-
selectedOutputs:
|
|
29816
|
+
selectedOutputs: z126.array(z126.enum([
|
|
29652
29817
|
"landing",
|
|
29653
29818
|
"video",
|
|
29654
29819
|
"image"
|
|
29655
29820
|
])).optional(),
|
|
29656
|
-
videoAngleCount:
|
|
29657
|
-
ugcFormat:
|
|
29821
|
+
videoAngleCount: z126.number().int().min(1).max(3).optional(),
|
|
29822
|
+
ugcFormat: z126.enum([
|
|
29658
29823
|
"single_8s",
|
|
29659
29824
|
"single_15s",
|
|
29660
29825
|
"double_30s"
|
|
29661
29826
|
]).optional(),
|
|
29662
|
-
videoStyle:
|
|
29827
|
+
videoStyle: z126.enum([
|
|
29663
29828
|
"ugc",
|
|
29664
29829
|
"cartoon_3d",
|
|
29665
29830
|
"product_only",
|
|
@@ -29669,13 +29834,13 @@ var StatusForResolveSchema = z125.object({
|
|
|
29669
29834
|
videoQuality: VideoQualityEnum.optional(),
|
|
29670
29835
|
videoRouteId: VideoRouteIdEnum.optional(),
|
|
29671
29836
|
videoModel: TaskVideoModelEnum.optional(),
|
|
29672
|
-
videoTier:
|
|
29837
|
+
videoTier: z126.enum([
|
|
29673
29838
|
"legacy",
|
|
29674
29839
|
"standard",
|
|
29675
29840
|
"pro",
|
|
29676
29841
|
"single_call"
|
|
29677
29842
|
]).optional(),
|
|
29678
|
-
videoResolution:
|
|
29843
|
+
videoResolution: z126.enum([
|
|
29679
29844
|
"480p",
|
|
29680
29845
|
"720p"
|
|
29681
29846
|
]).optional(),
|
|
@@ -29683,60 +29848,60 @@ var StatusForResolveSchema = z125.object({
|
|
|
29683
29848
|
// A task created before a narrative was blocked/hidden must still parse,
|
|
29684
29849
|
// or resolve_pending_action could never approve it.
|
|
29685
29850
|
narrativeStyle: NarrativeStyle.optional(),
|
|
29686
|
-
pauseForVideoScriptReview:
|
|
29687
|
-
pendingUserAction:
|
|
29688
|
-
kind:
|
|
29689
|
-
candidateGrouping:
|
|
29690
|
-
selectedImageUrls:
|
|
29691
|
-
proposedProductNames:
|
|
29851
|
+
pauseForVideoScriptReview: z126.boolean().optional(),
|
|
29852
|
+
pendingUserAction: z126.object({
|
|
29853
|
+
kind: z126.string(),
|
|
29854
|
+
candidateGrouping: z126.string().optional(),
|
|
29855
|
+
selectedImageUrls: z126.array(z126.string()).optional(),
|
|
29856
|
+
proposedProductNames: z126.array(z126.string()).optional(),
|
|
29692
29857
|
// Adaptive reference questions are server-owned. Echo only the evidence
|
|
29693
29858
|
// identity and the choices shown by the current snapshot; never accept a
|
|
29694
29859
|
// client-supplied reference set as authorization.
|
|
29695
|
-
options:
|
|
29696
|
-
mode:
|
|
29860
|
+
options: z126.array(ProductReferenceUserChoiceEnum).max(4).optional(),
|
|
29861
|
+
mode: z126.enum([
|
|
29697
29862
|
"question",
|
|
29698
29863
|
"visual_recovery"
|
|
29699
29864
|
]).optional(),
|
|
29700
29865
|
/** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
|
|
29701
|
-
canKeepSelection:
|
|
29702
|
-
decisionKey:
|
|
29703
|
-
questionOrdinal:
|
|
29704
|
-
questionCeiling:
|
|
29705
|
-
|
|
29706
|
-
|
|
29866
|
+
canKeepSelection: z126.boolean().optional(),
|
|
29867
|
+
decisionKey: z126.string().optional(),
|
|
29868
|
+
questionOrdinal: z126.number().int().min(1).max(5).optional(),
|
|
29869
|
+
questionCeiling: z126.union([
|
|
29870
|
+
z126.literal(3),
|
|
29871
|
+
z126.literal(5)
|
|
29707
29872
|
]).optional(),
|
|
29708
|
-
referenceEvidenceVersion:
|
|
29709
|
-
expectedEvidenceHash:
|
|
29710
|
-
question:
|
|
29711
|
-
prompt:
|
|
29712
|
-
helpText:
|
|
29713
|
-
options:
|
|
29873
|
+
referenceEvidenceVersion: z126.number().int().positive().optional(),
|
|
29874
|
+
expectedEvidenceHash: z126.string().optional(),
|
|
29875
|
+
question: z126.object({
|
|
29876
|
+
prompt: z126.string().min(1).max(240),
|
|
29877
|
+
helpText: z126.string().min(1).max(300).optional(),
|
|
29878
|
+
options: z126.array(z126.object({
|
|
29714
29879
|
value: ProductReferenceUserChoiceEnum,
|
|
29715
|
-
label:
|
|
29716
|
-
description:
|
|
29880
|
+
label: z126.string().min(1).max(120),
|
|
29881
|
+
description: z126.string().min(1).max(240).optional()
|
|
29717
29882
|
})).min(2).max(4)
|
|
29718
29883
|
}).optional(),
|
|
29719
29884
|
scope: ProductReferenceScopeEnum.optional(),
|
|
29720
|
-
scopeKey:
|
|
29721
|
-
scopeSnapshotId:
|
|
29722
|
-
scopeHash:
|
|
29723
|
-
baseReferenceSetHash:
|
|
29724
|
-
phase:
|
|
29885
|
+
scopeKey: z126.string().optional(),
|
|
29886
|
+
scopeSnapshotId: z126.string().uuid().optional(),
|
|
29887
|
+
scopeHash: z126.string().optional(),
|
|
29888
|
+
baseReferenceSetHash: z126.string().optional(),
|
|
29889
|
+
phase: z126.enum([
|
|
29725
29890
|
"preparation",
|
|
29726
29891
|
"final"
|
|
29727
29892
|
]).optional(),
|
|
29728
|
-
selectedRefKeys:
|
|
29729
|
-
allowedDecisions:
|
|
29730
|
-
previews:
|
|
29731
|
-
refKey:
|
|
29893
|
+
selectedRefKeys: z126.array(z126.string().min(1).max(200)).optional(),
|
|
29894
|
+
allowedDecisions: z126.array(ProductReferenceResolutionDecisionEnum).optional(),
|
|
29895
|
+
previews: z126.array(z126.object({
|
|
29896
|
+
refKey: z126.string().min(1).max(200)
|
|
29732
29897
|
}).passthrough()).optional(),
|
|
29733
|
-
customAngleDraft:
|
|
29734
|
-
painPointsDraft:
|
|
29735
|
-
benefitsDraft:
|
|
29736
|
-
featuresDraft:
|
|
29737
|
-
angleOptions:
|
|
29738
|
-
index:
|
|
29739
|
-
angle:
|
|
29898
|
+
customAngleDraft: z126.string().optional(),
|
|
29899
|
+
painPointsDraft: z126.string().optional(),
|
|
29900
|
+
benefitsDraft: z126.string().optional(),
|
|
29901
|
+
featuresDraft: z126.array(z126.string()).optional(),
|
|
29902
|
+
angleOptions: z126.array(z126.object({
|
|
29903
|
+
index: z126.number().int().nonnegative(),
|
|
29904
|
+
angle: z126.string().min(1)
|
|
29740
29905
|
}).passthrough()).min(1).max(5).optional(),
|
|
29741
29906
|
// Recommendation consumed only when the caller explicitly sends
|
|
29742
29907
|
// gapDurationSeconds: 30 in the angle approval action.
|
|
@@ -29746,17 +29911,17 @@ var StatusForResolveSchema = z125.object({
|
|
|
29746
29911
|
// keys. `actorId` (the saved custom actor the picker stored) was silently
|
|
29747
29912
|
// dropped here, so the approval handler below could not echo it back on the
|
|
29748
29913
|
// PATCH — the selection looked accepted and reached no render.
|
|
29749
|
-
angles:
|
|
29750
|
-
id:
|
|
29751
|
-
content:
|
|
29752
|
-
creativeDirection:
|
|
29753
|
-
actor:
|
|
29754
|
-
actorId:
|
|
29914
|
+
angles: z126.array(z126.object({
|
|
29915
|
+
id: z126.string().uuid(),
|
|
29916
|
+
content: z126.string(),
|
|
29917
|
+
creativeDirection: z126.string(),
|
|
29918
|
+
actor: z126.string(),
|
|
29919
|
+
actorId: z126.string().nullable().optional()
|
|
29755
29920
|
}).passthrough()).optional(),
|
|
29756
|
-
panels:
|
|
29757
|
-
beatId:
|
|
29758
|
-
voiceover:
|
|
29759
|
-
visualDirection:
|
|
29921
|
+
panels: z126.array(z126.object({
|
|
29922
|
+
beatId: z126.string(),
|
|
29923
|
+
voiceover: z126.string(),
|
|
29924
|
+
visualDirection: z126.string()
|
|
29760
29925
|
}).passthrough()).optional()
|
|
29761
29926
|
}).optional()
|
|
29762
29927
|
}).passthrough();
|
|
@@ -30109,8 +30274,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
30109
30274
|
server.registerTool("verify_landing_commerce", {
|
|
30110
30275
|
description: getProductMakerCapabilityModelGuidance("verify_landing_commerce").summary + " Verifica una correcci\xF3n manual de precios, tachados o packs de una landing editable existente. Solo relee Shopify y los recibos externos; no cambia precios, inventario, SKU ni compra una edici\xF3n. Pasa taskId y editId de la edici\xF3n ya conocida; nunca inventes IDs ni pidas repetir el cambio. Devuelve el estado can\xF3nico por proveedor: conserva el aviso pendiente hasta confirmar los valores reales. Solo despu\xE9s de confirmar todos los valores, el servidor puede volver a habilitar la compra. Web guardada no demuestra publicaci\xF3n p\xFAblica ni checkout; muestra las correcciones y enlaces pendientes sin c\xF3digos t\xE9cnicos. La disponibilidad del editor conserva sus permisos actuales.",
|
|
30111
30276
|
inputSchema: {
|
|
30112
|
-
taskId:
|
|
30113
|
-
editId:
|
|
30277
|
+
taskId: z126.string().uuid(),
|
|
30278
|
+
editId: z126.string().uuid()
|
|
30114
30279
|
},
|
|
30115
30280
|
annotations: OVERWRITES_EXTERNAL
|
|
30116
30281
|
}, async (input) => {
|
|
@@ -30302,15 +30467,15 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
30302
30467
|
const rawOutputs = await fetchTaskOutputs(api, input.taskId, {
|
|
30303
30468
|
signal
|
|
30304
30469
|
});
|
|
30305
|
-
const imageContent = await buildMcpGeneratedImageContent(rawOutputs.images.map((
|
|
30306
|
-
url:
|
|
30470
|
+
const imageContent = await buildMcpGeneratedImageContent(rawOutputs.images.map((image2, i) => ({
|
|
30471
|
+
url: image2.url,
|
|
30307
30472
|
alt: `Imagen ${i + 1}`
|
|
30308
30473
|
})), transport);
|
|
30309
30474
|
const outputs = proxifyOutputs(rawOutputs, proxyBaseUrl);
|
|
30310
30475
|
const media = {
|
|
30311
30476
|
images: [
|
|
30312
|
-
...outputs.images.map((
|
|
30313
|
-
url:
|
|
30477
|
+
...outputs.images.map((image2, i) => ({
|
|
30478
|
+
url: image2.url,
|
|
30314
30479
|
alt: `Imagen ${i + 1}`
|
|
30315
30480
|
})),
|
|
30316
30481
|
...outputs.landing.sections.map((section) => ({
|
|
@@ -30381,16 +30546,16 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
30381
30546
|
if (input.search) qs.set("search", input.search);
|
|
30382
30547
|
const path3 = `/v1/tasks${qs.toString() ? "?" + qs.toString() : ""}`;
|
|
30383
30548
|
const r = await api.getJson(path3);
|
|
30384
|
-
const page =
|
|
30385
|
-
items:
|
|
30549
|
+
const page = z126.object({
|
|
30550
|
+
items: z126.array(z126.unknown())
|
|
30386
30551
|
}).passthrough().safeParse(r);
|
|
30387
30552
|
if (!page.success) return asText(r);
|
|
30388
30553
|
return asText({
|
|
30389
30554
|
...page.data,
|
|
30390
30555
|
items: page.data.items.map((item) => {
|
|
30391
|
-
const servicePage =
|
|
30392
|
-
taskId:
|
|
30393
|
-
resourceType:
|
|
30556
|
+
const servicePage = z126.object({
|
|
30557
|
+
taskId: z126.string().uuid(),
|
|
30558
|
+
resourceType: z126.literal("service_page")
|
|
30394
30559
|
}).passthrough().safeParse(item);
|
|
30395
30560
|
if (!servicePage.success) return item;
|
|
30396
30561
|
return {
|
|
@@ -30880,28 +31045,28 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
30880
31045
|
__name(registerTaskTools, "registerTaskTools");
|
|
30881
31046
|
|
|
30882
31047
|
// src/tools/brands.ts
|
|
30883
|
-
import { z as
|
|
31048
|
+
import { z as z127 } from "zod";
|
|
30884
31049
|
var guidance2 = getProductMakerCapabilityModelGuidance("create_brand");
|
|
30885
31050
|
var BRAND_START_REPLAY_WINDOW_MS = 15 * 60 * 1e3;
|
|
30886
31051
|
var BRAND_NOTES_MAX_CHARS = 2e4;
|
|
30887
31052
|
var BRAND_AMBIGUOUS_REQUEST_RETENTION_MS = 24 * 60 * 60 * 1e3;
|
|
30888
31053
|
var BRAND_CREATION_REQUEST_LIMIT = 500;
|
|
30889
31054
|
var brandCreationRequests = /* @__PURE__ */ new Map();
|
|
30890
|
-
var CreateBrandInput =
|
|
30891
|
-
action:
|
|
31055
|
+
var CreateBrandInput = z127.object({
|
|
31056
|
+
action: z127.enum([
|
|
30892
31057
|
"start",
|
|
30893
31058
|
"status",
|
|
30894
31059
|
"list"
|
|
30895
31060
|
]).default("start").describe("start cotiza (sin confirmed) o inicia (confirmed=true) el an\xE1lisis; status consulta brandId hasta ready o failed; list muestra las marcas que el usuario ya tiene."),
|
|
30896
|
-
sourceUrl:
|
|
30897
|
-
businessNotes:
|
|
30898
|
-
language:
|
|
31061
|
+
sourceUrl: z127.string().trim().min(1).max(BRAND_SOURCE_URL_MAX_LENGTH).optional().describe("Instagram, Facebook, TikTok o web p\xFAblica del negocio, como la dio el usuario (\xAB@sanlucasbarberia\xBB, \xABinstagram.com/sanlucasbarberia\xBB, \xABmibarberia.com\xBB). Obligatorio para start."),
|
|
31062
|
+
businessNotes: z127.string().trim().max(BRAND_NOTES_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cuente de su negocio en el chat (servicios y precios, WhatsApp, ciudad o zona, horarios). Se guarda como documento del negocio y llega tal cual a la marca y a su landing. Copia sus palabras; no inventes datos."),
|
|
31063
|
+
language: z127.enum([
|
|
30899
31064
|
"es",
|
|
30900
31065
|
"en",
|
|
30901
31066
|
"pt"
|
|
30902
31067
|
]).optional().describe("Idioma de la conversaci\xF3n. Solo se usa si la p\xE1gina del negocio no deja claro su idioma."),
|
|
30903
|
-
confirmed:
|
|
30904
|
-
brandId:
|
|
31068
|
+
confirmed: z127.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, start solo cotiza y no cobra."),
|
|
31069
|
+
brandId: z127.string().uuid().optional().describe("ID de la marca. Obligatorio para status; no lo inventes.")
|
|
30905
31070
|
}).strict();
|
|
30906
31071
|
function normalizeBrandSourceUrl(raw) {
|
|
30907
31072
|
const value = raw.trim();
|
|
@@ -31185,31 +31350,31 @@ __name(registerBrandTools, "registerBrandTools");
|
|
|
31185
31350
|
|
|
31186
31351
|
// src/tools/service-landing.ts
|
|
31187
31352
|
import { createHash as createHash4, randomUUID } from "crypto";
|
|
31188
|
-
import { z as
|
|
31353
|
+
import { z as z128 } from "zod";
|
|
31189
31354
|
var guidance3 = getProductMakerCapabilityModelGuidance("create_service_landing");
|
|
31190
31355
|
var SERVICE_LANDING_KEY_NAMESPACE = "6f1d8c2a-3b4e-5f60-8a7b-9c0d1e2f3a4b";
|
|
31191
31356
|
var SERVICE_LANDING_INFO_MAX_CHARS = 2e4;
|
|
31192
|
-
var CreateServiceLandingInput =
|
|
31193
|
-
action:
|
|
31357
|
+
var CreateServiceLandingInput = z128.object({
|
|
31358
|
+
action: z128.enum([
|
|
31194
31359
|
"prepare",
|
|
31195
31360
|
"build",
|
|
31196
31361
|
"status",
|
|
31197
31362
|
"publish"
|
|
31198
31363
|
]).default("prepare").describe("prepare (gratis) crea o retoma la landing de la marca y da el precio; build (pagado, confirmed=true) genera la p\xE1gina directamente con la marca y los datos guardados; status sigue el avance; publish la publica y devuelve su enlace."),
|
|
31199
|
-
brandId:
|
|
31200
|
-
servicePageId:
|
|
31201
|
-
businessInfo:
|
|
31202
|
-
confirmed:
|
|
31203
|
-
maxCredits:
|
|
31204
|
-
operationId:
|
|
31205
|
-
slug:
|
|
31364
|
+
brandId: z128.string().uuid().optional().describe("ID de la marca (de create_brand). Obligatorio para prepare. Nunca un taskId de producto."),
|
|
31365
|
+
servicePageId: z128.string().uuid().optional().describe("ID de la landing que devolvi\xF3 prepare. Obligatorio para build, status y publish."),
|
|
31366
|
+
businessInfo: z128.string().trim().max(SERVICE_LANDING_INFO_MAX_CHARS).optional().describe("Opcional. Lo que el usuario cont\xF3 del negocio y no estaba en su marca: servicios y precios, WhatsApp o tel\xE9fono, ciudad o zona, horarios. Copia sus palabras; no inventes datos."),
|
|
31367
|
+
confirmed: z128.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio total y que el usuario acepte. Obligatorio para build."),
|
|
31368
|
+
maxCredits: z128.number().int().positive().optional().describe("El total en cr\xE9ditos que el usuario acept\xF3 (el que devolvi\xF3 prepare). Obligatorio para build: ninguna etapa se inicia si su precio supera este total."),
|
|
31369
|
+
operationId: z128.string().uuid().optional().describe("Opcional en status: la operaci\xF3n que devolvi\xF3 build."),
|
|
31370
|
+
slug: z128.string().trim().toLowerCase().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(64).optional().describe("Opcional en publish: la direcci\xF3n corta de la p\xE1gina (ej. sanlucas-barberia). Si falta se usa la sugerida desde el nombre del negocio.")
|
|
31206
31371
|
}).strict();
|
|
31207
31372
|
function serviceKey(...parts) {
|
|
31208
31373
|
return deriveUuidV5(parts.join(":"), SERVICE_LANDING_KEY_NAMESPACE);
|
|
31209
31374
|
}
|
|
31210
31375
|
__name(serviceKey, "serviceKey");
|
|
31211
|
-
function textHash(
|
|
31212
|
-
return createHash4("sha256").update(
|
|
31376
|
+
function textHash(text4) {
|
|
31377
|
+
return createHash4("sha256").update(text4, "utf8").digest("hex").slice(0, 16);
|
|
31213
31378
|
}
|
|
31214
31379
|
__name(textHash, "textHash");
|
|
31215
31380
|
function quoteRange(quote) {
|
|
@@ -31577,7 +31742,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
31577
31742
|
__name(registerServiceLandingTools, "registerServiceLandingTools");
|
|
31578
31743
|
|
|
31579
31744
|
// src/tools/service-images.ts
|
|
31580
|
-
import { z as
|
|
31745
|
+
import { z as z129 } from "zod";
|
|
31581
31746
|
var guidance4 = getProductMakerCapabilityModelGuidance("create_service_images");
|
|
31582
31747
|
var SERVICE_IMAGE_FORMATS = [
|
|
31583
31748
|
"4:5",
|
|
@@ -31590,23 +31755,23 @@ var LANGUAGE_TAGS = {
|
|
|
31590
31755
|
en: "en-US",
|
|
31591
31756
|
pt: "pt-BR"
|
|
31592
31757
|
};
|
|
31593
|
-
var CreateServiceImagesInput =
|
|
31594
|
-
brandId:
|
|
31595
|
-
instruction:
|
|
31596
|
-
delegateToAi:
|
|
31597
|
-
format:
|
|
31598
|
-
count:
|
|
31599
|
-
quality:
|
|
31758
|
+
var CreateServiceImagesInput = z129.object({
|
|
31759
|
+
brandId: z129.string().uuid().optional().describe("ID de un servicio propio y listo (de create_brand), obligatorio para cotizar y crear im\xE1genes nuevas. En un retry hist\xF3rico ya confirmado que originalmente no ten\xEDa este campo, conserva la petici\xF3n original. Nunca un taskId de producto."),
|
|
31760
|
+
instruction: z129.string().trim().max(4e3).optional().describe("Opcional. Qu\xE9 servicio o promoci\xF3n mostrar, con las palabras del usuario (ej. \xABcorte + barba a $35.000 los martes\xBB). Si se omite, la IA propone la imagen usando la informaci\xF3n del servicio."),
|
|
31761
|
+
delegateToAi: z129.boolean().optional().describe("true si el usuario prefiere que la IA elija qu\xE9 mostrar a partir de su servicio. Tambi\xE9n se delega cuando instruction est\xE1 vac\xEDo."),
|
|
31762
|
+
format: z129.enum(SERVICE_IMAGE_FORMATS).optional().describe('Formato: "4:5" (feed, por defecto), "9:16" (historias/reels) o "1:1" (cuadrado).'),
|
|
31763
|
+
count: z129.number().int().min(1).max(SERVICE_IMAGE_MAX_COUNT).optional().describe("Cu\xE1ntas im\xE1genes, de 1 a 3 (por defecto 1)."),
|
|
31764
|
+
quality: z129.enum([
|
|
31600
31765
|
"standard",
|
|
31601
31766
|
"high"
|
|
31602
31767
|
]).optional().describe('Calidad: "standard" (por defecto) o "high" (m\xE1s cara; no disponible en 4:5).'),
|
|
31603
|
-
language:
|
|
31768
|
+
language: z129.enum([
|
|
31604
31769
|
"es",
|
|
31605
31770
|
"en",
|
|
31606
31771
|
"pt"
|
|
31607
31772
|
]).optional().describe("Idioma de los textos de la imagen (por defecto es)."),
|
|
31608
|
-
adCopy:
|
|
31609
|
-
confirmed:
|
|
31773
|
+
adCopy: z129.boolean().optional().describe("Compatibilidad con clientes anteriores: el copy para publicar siempre est\xE1 incluido en cada imagen de servicios."),
|
|
31774
|
+
confirmed: z129.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, solo cotiza y no cobra.")
|
|
31610
31775
|
}).strict();
|
|
31611
31776
|
function serviceImageModel(quality) {
|
|
31612
31777
|
return quality === "high" ? AD_CREATIVE_MODELS.PREMIUM : AD_CREATIVE_MODELS.STANDARD;
|
|
@@ -31723,7 +31888,7 @@ function registerServiceImageTools(server, api, options = {}) {
|
|
|
31723
31888
|
nextAction: "Dile al usuario que est\xE1s creando sus im\xE1genes. Llama get_task_status con este taskId (waitSeconds=45) hasta done (trae las im\xE1genes reales de ProductMaker) o error. Muestra los recursos de imagen devueltos directamente en el chat. Nunca generes ni recrees una imagen sustituta con otra herramienta. Si la vista previa falla, explica el fallo y conserva los enlaces protegidos devueltos."
|
|
31724
31889
|
});
|
|
31725
31890
|
} catch (error) {
|
|
31726
|
-
if (error instanceof
|
|
31891
|
+
if (error instanceof z129.ZodError) throw invalidInputFromZod(error);
|
|
31727
31892
|
throw translateError(error);
|
|
31728
31893
|
}
|
|
31729
31894
|
});
|
|
@@ -31731,7 +31896,7 @@ function registerServiceImageTools(server, api, options = {}) {
|
|
|
31731
31896
|
__name(registerServiceImageTools, "registerServiceImageTools");
|
|
31732
31897
|
|
|
31733
31898
|
// src/tools/creatives.ts
|
|
31734
|
-
import { z as
|
|
31899
|
+
import { z as z130 } from "zod";
|
|
31735
31900
|
var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
|
|
31736
31901
|
var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
|
|
31737
31902
|
var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
|
|
@@ -31742,72 +31907,72 @@ var CreativeRefs = {
|
|
|
31742
31907
|
images: ImagesInput,
|
|
31743
31908
|
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.'),
|
|
31744
31909
|
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.'),
|
|
31745
|
-
price:
|
|
31746
|
-
offer:
|
|
31747
|
-
compareAtPrice:
|
|
31748
|
-
productContext:
|
|
31749
|
-
productLabel:
|
|
31750
|
-
buyerPersona:
|
|
31751
|
-
isCombo:
|
|
31752
|
-
competitorScanEnabled:
|
|
31753
|
-
brandId:
|
|
31910
|
+
price: z130.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.'),
|
|
31911
|
+
offer: z130.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.'),
|
|
31912
|
+
compareAtPrice: z130.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
|
|
31913
|
+
productContext: z130.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."),
|
|
31914
|
+
productLabel: z130.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.'),
|
|
31915
|
+
buyerPersona: z130.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.'),
|
|
31916
|
+
isCombo: z130.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
|
|
31917
|
+
competitorScanEnabled: z130.boolean().optional().describe("Opcional. Default false: omitirlo significa SIN estudio de mercado. Antes de crear, llama estimate_market_study_cost, muestra al usuario el costo con y sin estudio y preg\xFAntale si lo quiere; env\xEDa true solo si lo acepta (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."),
|
|
31918
|
+
brandId: z130.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.")
|
|
31754
31919
|
};
|
|
31755
|
-
var VideoPresenter =
|
|
31756
|
-
|
|
31757
|
-
mode:
|
|
31920
|
+
var VideoPresenter = z130.discriminatedUnion("mode", [
|
|
31921
|
+
z130.object({
|
|
31922
|
+
mode: z130.literal("none")
|
|
31758
31923
|
}).strict(),
|
|
31759
|
-
|
|
31760
|
-
mode:
|
|
31761
|
-
actorId:
|
|
31924
|
+
z130.object({
|
|
31925
|
+
mode: z130.literal("saved_actor"),
|
|
31926
|
+
actorId: z130.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
|
|
31762
31927
|
}).strict(),
|
|
31763
|
-
|
|
31764
|
-
mode:
|
|
31765
|
-
description:
|
|
31928
|
+
z130.object({
|
|
31929
|
+
mode: z130.literal("described"),
|
|
31930
|
+
description: z130.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
|
|
31766
31931
|
}).strict()
|
|
31767
31932
|
]);
|
|
31768
|
-
var VideoCreativeSetup =
|
|
31769
|
-
|
|
31770
|
-
mode:
|
|
31933
|
+
var VideoCreativeSetup = z130.discriminatedUnion("mode", [
|
|
31934
|
+
z130.object({
|
|
31935
|
+
mode: z130.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
|
|
31771
31936
|
}).strict(),
|
|
31772
|
-
|
|
31773
|
-
mode:
|
|
31937
|
+
z130.object({
|
|
31938
|
+
mode: z130.literal("guided"),
|
|
31774
31939
|
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. Todas las narrativas funcionan en Un solo clip y Multiescena.'),
|
|
31775
|
-
buyerPersona:
|
|
31940
|
+
buyerPersona: z130.string().trim().min(1).max(360),
|
|
31776
31941
|
animationStyle: AnimationStyleEnum.optional().describe('Opcional. Estilo visual SOLO para presets animados ("pixar_problem" o "pixar_sassy") \u2014 la API lo rechaza con cualquier otro preset. Opciones: "pixar_3d" (default, look 3D de pel\xEDcula animada), "claymation" (plastilina stop-motion artesanal), "wes_anderson" (tableau sim\xE9trico pastel), "sci_fi" (futurista con HUDs y ne\xF3n), "realista" (fotorrealista, fiel al producto). Si el usuario pide un look animado sin nombrar el estilo, omite el campo.'),
|
|
31777
31942
|
presenter: VideoPresenter,
|
|
31778
|
-
creativeDirection:
|
|
31943
|
+
creativeDirection: z130.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
|
|
31779
31944
|
}).strict()
|
|
31780
31945
|
]);
|
|
31781
|
-
var VideoInput =
|
|
31946
|
+
var VideoInput = z130.object({
|
|
31782
31947
|
images: CreativeRefs.images.optional(),
|
|
31783
31948
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
31784
|
-
title:
|
|
31785
|
-
primaryAngle:
|
|
31949
|
+
title: z130.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
|
|
31950
|
+
primaryAngle: z130.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".'),
|
|
31786
31951
|
language: CreativeRefs.language,
|
|
31787
31952
|
country: CreativeRefs.country,
|
|
31788
|
-
aspectRatio:
|
|
31953
|
+
aspectRatio: z130.enum([
|
|
31789
31954
|
"9:16",
|
|
31790
31955
|
"16:9",
|
|
31791
31956
|
"Auto"
|
|
31792
31957
|
]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
|
|
31793
31958
|
generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, efectos y m\xFAsica sobre cada video entregado (variante with_ai_edit; se cobra al entregar, por video). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro"; false/omitido = sin edici\xF3n.'),
|
|
31794
|
-
durationSeconds:
|
|
31795
|
-
videoAngleCount:
|
|
31959
|
+
durationSeconds: z130.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."),
|
|
31960
|
+
videoAngleCount: z130.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."),
|
|
31796
31961
|
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.'),
|
|
31797
31962
|
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."),
|
|
31798
31963
|
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.'),
|
|
31799
31964
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
|
|
31800
31965
|
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.'),
|
|
31801
|
-
features:
|
|
31966
|
+
features: z130.array(z130.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
|
|
31802
31967
|
price: CreativeRefs.price,
|
|
31803
31968
|
offer: CreativeRefs.offer,
|
|
31804
31969
|
productContext: CreativeRefs.productContext,
|
|
31805
31970
|
productLabel: CreativeRefs.productLabel,
|
|
31806
|
-
cta:
|
|
31807
|
-
scriptNotes:
|
|
31971
|
+
cta: z130.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.'),
|
|
31972
|
+
scriptNotes: z130.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.'),
|
|
31808
31973
|
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.'),
|
|
31809
31974
|
competitorScanEnabled: CreativeRefs.competitorScanEnabled,
|
|
31810
|
-
replicateWinnerWhenFound:
|
|
31975
|
+
replicateWinnerWhenFound: z130.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."),
|
|
31811
31976
|
brandId: CreativeRefs.brandId
|
|
31812
31977
|
}).strict();
|
|
31813
31978
|
var FreeVideoQualityEnum = VideoQualityEnum;
|
|
@@ -31825,7 +31990,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
|
|
|
31825
31990
|
length: 29
|
|
31826
31991
|
}, (_, index) => index + 2)
|
|
31827
31992
|
};
|
|
31828
|
-
var FreeVideoModelIdEnum =
|
|
31993
|
+
var FreeVideoModelIdEnum = z130.enum([
|
|
31829
31994
|
"grok-imagine-video-1-5-preview",
|
|
31830
31995
|
"minimax-h3/reference-to-video",
|
|
31831
31996
|
"wan/3-0-video",
|
|
@@ -31836,66 +32001,66 @@ var FREE_SELECTABLE_MODEL_IDS = [
|
|
|
31836
32001
|
"minimax-h3/reference-to-video",
|
|
31837
32002
|
"wan/3-0-video"
|
|
31838
32003
|
];
|
|
31839
|
-
var FreeVideoInput =
|
|
32004
|
+
var FreeVideoInput = z130.object({
|
|
31840
32005
|
images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
|
|
31841
|
-
rawPrompt:
|
|
32006
|
+
rawPrompt: z130.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."),
|
|
31842
32007
|
language: CreativeRefs.language,
|
|
31843
32008
|
quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
|
|
31844
32009
|
// Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
|
|
31845
32010
|
// parsed ONLY so the handler can reject it with a message naming its
|
|
31846
32011
|
// replacement — dropping it silently would turn a caller's explicit
|
|
31847
32012
|
// Pro++ pick into a quiet fallback to Wan.
|
|
31848
|
-
freeProModel:
|
|
32013
|
+
freeProModel: z130.enum([
|
|
31849
32014
|
"wan",
|
|
31850
32015
|
"seedance"
|
|
31851
32016
|
]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
|
|
31852
32017
|
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.'),
|
|
31853
|
-
durationSeconds:
|
|
32018
|
+
durationSeconds: z130.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."),
|
|
31854
32019
|
videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
|
|
31855
|
-
generateAiMusic:
|
|
32020
|
+
generateAiMusic: z130.boolean().default(false).describe('Opcional. Agrega m\xFAsica instrumental IA debajo del audio nativo. Default false. Equivale a generateAiEdit (nivel "pro"): la Edici\xF3n con IA trae su propia m\xFAsica.'),
|
|
31856
32021
|
generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, gr\xE1ficos y m\xFAsica sobre el video ya entregado (variante with_ai_edit; se cobra al entregar). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro". Default sin edici\xF3n.'),
|
|
31857
|
-
addSubtitles:
|
|
31858
|
-
idempotencyKey:
|
|
32022
|
+
addSubtitles: z130.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
|
|
32023
|
+
idempotencyKey: z130.string().uuid().optional().describe("Opcional. Se acepta por compatibilidad pero se ignora: la identidad del reintento se deriva autom\xE1ticamente de los argumentos sem\xE1nticos, as\xED que un retry con los mismos argumentos ya es idempotente sin este campo.")
|
|
31859
32024
|
}).strict();
|
|
31860
32025
|
var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
|
|
31861
|
-
var ImageCreativeSetup =
|
|
31862
|
-
|
|
31863
|
-
mode:
|
|
32026
|
+
var ImageCreativeSetup = z130.discriminatedUnion("mode", [
|
|
32027
|
+
z130.object({
|
|
32028
|
+
mode: z130.literal("automatic")
|
|
31864
32029
|
}).strict(),
|
|
31865
|
-
|
|
31866
|
-
mode:
|
|
31867
|
-
creativeArchetype:
|
|
32030
|
+
z130.object({
|
|
32031
|
+
mode: z130.literal("guided"),
|
|
32032
|
+
creativeArchetype: z130.union([
|
|
31868
32033
|
ImageCreativeArchetypeEnum,
|
|
31869
|
-
|
|
32034
|
+
z130.literal("ai_decides")
|
|
31870
32035
|
]),
|
|
31871
|
-
visualTreatment:
|
|
32036
|
+
visualTreatment: z130.union([
|
|
31872
32037
|
ImageCreativeVisualTreatmentEnum,
|
|
31873
|
-
|
|
32038
|
+
z130.literal("ai_decides")
|
|
31874
32039
|
]),
|
|
31875
32040
|
aspectRatio: ImageCreativeAspectRatioEnum,
|
|
31876
|
-
nVariants:
|
|
31877
|
-
|
|
31878
|
-
|
|
31879
|
-
|
|
31880
|
-
|
|
31881
|
-
|
|
32041
|
+
nVariants: z130.union([
|
|
32042
|
+
z130.literal(1),
|
|
32043
|
+
z130.literal(2),
|
|
32044
|
+
z130.literal(3),
|
|
32045
|
+
z130.literal(4),
|
|
32046
|
+
z130.literal(6)
|
|
31882
32047
|
]),
|
|
31883
|
-
imageModel:
|
|
31884
|
-
styleMix:
|
|
31885
|
-
generateAdCopy:
|
|
31886
|
-
competitorScanEnabled:
|
|
31887
|
-
productContext:
|
|
31888
|
-
creativeDirection:
|
|
31889
|
-
brandColors:
|
|
31890
|
-
headline:
|
|
31891
|
-
subheadline:
|
|
32048
|
+
imageModel: z130.enum(PUBLIC_IMAGE_QUALITY_INPUTS).describe('Calidad: "image:1k" (Est\xE1ndar) o "image:2k" (Premium). Los tokens gpt-image-2-5:{1k,2k} y gpt-image-2:{1k,2k} se siguen aceptando.'),
|
|
32049
|
+
styleMix: z130.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
|
|
32050
|
+
generateAdCopy: z130.boolean(),
|
|
32051
|
+
competitorScanEnabled: z130.boolean(),
|
|
32052
|
+
productContext: z130.string().trim().min(1).max(3e3).nullable(),
|
|
32053
|
+
creativeDirection: z130.string().trim().min(1).max(500).nullable(),
|
|
32054
|
+
brandColors: z130.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.'),
|
|
32055
|
+
headline: z130.string().trim().min(1).max(120).nullable(),
|
|
32056
|
+
subheadline: z130.string().trim().min(1).max(160).nullable()
|
|
31892
32057
|
}).strict()
|
|
31893
32058
|
]).superRefine((setup, context) => {
|
|
31894
32059
|
if (setup.mode !== "guided") return;
|
|
31895
32060
|
const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
|
|
31896
32061
|
if (needsStyleMix && setup.styleMix === null) {
|
|
31897
32062
|
context.addIssue({
|
|
31898
|
-
code:
|
|
32063
|
+
code: z130.ZodIssueCode.custom,
|
|
31899
32064
|
path: [
|
|
31900
32065
|
"styleMix"
|
|
31901
32066
|
],
|
|
@@ -31904,7 +32069,7 @@ var ImageCreativeSetup = z129.discriminatedUnion("mode", [
|
|
|
31904
32069
|
}
|
|
31905
32070
|
if (!needsStyleMix && setup.styleMix !== null) {
|
|
31906
32071
|
context.addIssue({
|
|
31907
|
-
code:
|
|
32072
|
+
code: z130.ZodIssueCode.custom,
|
|
31908
32073
|
path: [
|
|
31909
32074
|
"styleMix"
|
|
31910
32075
|
],
|
|
@@ -31913,7 +32078,7 @@ var ImageCreativeSetup = z129.discriminatedUnion("mode", [
|
|
|
31913
32078
|
}
|
|
31914
32079
|
if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
|
|
31915
32080
|
context.addIssue({
|
|
31916
|
-
code:
|
|
32081
|
+
code: z130.ZodIssueCode.custom,
|
|
31917
32082
|
path: [
|
|
31918
32083
|
"aspectRatio"
|
|
31919
32084
|
],
|
|
@@ -31921,55 +32086,55 @@ var ImageCreativeSetup = z129.discriminatedUnion("mode", [
|
|
|
31921
32086
|
});
|
|
31922
32087
|
}
|
|
31923
32088
|
});
|
|
31924
|
-
var LandingCreativeSetup =
|
|
31925
|
-
|
|
31926
|
-
mode:
|
|
32089
|
+
var LandingCreativeSetup = z130.discriminatedUnion("mode", [
|
|
32090
|
+
z130.object({
|
|
32091
|
+
mode: z130.literal("automatic")
|
|
31927
32092
|
}).strict(),
|
|
31928
|
-
|
|
31929
|
-
mode:
|
|
32093
|
+
z130.object({
|
|
32094
|
+
mode: z130.literal("guided"),
|
|
31930
32095
|
landingStrategy: LandingStrategyEnum,
|
|
31931
32096
|
landingImageFormat: LandingImageFormatEnum,
|
|
31932
|
-
competitorScanEnabled:
|
|
31933
|
-
paymentMethods:
|
|
31934
|
-
productContext:
|
|
31935
|
-
creativeDirection:
|
|
31936
|
-
headline:
|
|
31937
|
-
subheadline:
|
|
32097
|
+
competitorScanEnabled: z130.boolean(),
|
|
32098
|
+
paymentMethods: z130.string().trim().min(1).max(240).nullable(),
|
|
32099
|
+
productContext: z130.string().trim().min(1).max(3e3).nullable(),
|
|
32100
|
+
creativeDirection: z130.string().trim().min(1).max(500).nullable(),
|
|
32101
|
+
headline: z130.string().trim().min(1).max(120).nullable(),
|
|
32102
|
+
subheadline: z130.string().trim().min(1).max(160).nullable()
|
|
31938
32103
|
}).strict()
|
|
31939
32104
|
]);
|
|
31940
|
-
var ImageInput =
|
|
32105
|
+
var ImageInput = z130.object({
|
|
31941
32106
|
images: CreativeRefs.images.optional(),
|
|
31942
32107
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
31943
|
-
productTitle:
|
|
31944
|
-
primaryAngle:
|
|
32108
|
+
productTitle: z130.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
|
|
32109
|
+
primaryAngle: z130.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.'),
|
|
31945
32110
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
31946
32111
|
language: CreativeRefs.language,
|
|
31947
32112
|
country: CreativeRefs.country,
|
|
31948
32113
|
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."),
|
|
31949
32114
|
imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
|
|
31950
|
-
features:
|
|
32115
|
+
features: z130.array(z130.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
|
|
31951
32116
|
price: CreativeRefs.price,
|
|
31952
|
-
omitPrice:
|
|
32117
|
+
omitPrice: z130.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."),
|
|
31953
32118
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
31954
32119
|
offer: CreativeRefs.offer,
|
|
31955
32120
|
productLabel: CreativeRefs.productLabel,
|
|
31956
32121
|
isCombo: CreativeRefs.isCombo,
|
|
31957
32122
|
brandId: CreativeRefs.brandId
|
|
31958
32123
|
});
|
|
31959
|
-
var EditImageCreativeInput =
|
|
31960
|
-
taskId:
|
|
31961
|
-
variantIndex:
|
|
31962
|
-
clientRequestId:
|
|
31963
|
-
instruction:
|
|
32124
|
+
var EditImageCreativeInput = z130.object({
|
|
32125
|
+
taskId: z130.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
|
|
32126
|
+
variantIndex: z130.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
|
|
32127
|
+
clientRequestId: z130.string().min(1).max(160).optional().describe("Identidad estable de esta correcci\xF3n; reutil\xEDzala al reconciliar una respuesta perdida, no para otra instrucci\xF3n."),
|
|
32128
|
+
instruction: z130.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".')
|
|
31964
32129
|
});
|
|
31965
|
-
var LandingInput =
|
|
31966
|
-
includeInitialLandingGif:
|
|
32130
|
+
var LandingInput = z130.object({
|
|
32131
|
+
includeInitialLandingGif: z130.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
|
|
31967
32132
|
images: CreativeRefs.images.optional(),
|
|
31968
32133
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
31969
32134
|
language: CreativeRefs.language,
|
|
31970
32135
|
country: CreativeRefs.country,
|
|
31971
32136
|
creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
|
|
31972
|
-
salesAngle:
|
|
32137
|
+
salesAngle: z130.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.'),
|
|
31973
32138
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
31974
32139
|
price: CreativeRefs.price,
|
|
31975
32140
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
@@ -32251,8 +32416,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
32251
32416
|
server.registerTool("get_image_edit_status", {
|
|
32252
32417
|
description: imageEditStatusGuidance.summary,
|
|
32253
32418
|
inputSchema: {
|
|
32254
|
-
taskId:
|
|
32255
|
-
operationId:
|
|
32419
|
+
taskId: z130.string().uuid(),
|
|
32420
|
+
operationId: z130.string().uuid()
|
|
32256
32421
|
},
|
|
32257
32422
|
annotations: READS_INTERNAL
|
|
32258
32423
|
}, async (input) => {
|
|
@@ -32309,10 +32474,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
32309
32474
|
__name(registerCreativeTools, "registerCreativeTools");
|
|
32310
32475
|
|
|
32311
32476
|
// src/tools/creative-variants.ts
|
|
32312
|
-
import { z as
|
|
32477
|
+
import { z as z131 } from "zod";
|
|
32313
32478
|
var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
|
|
32314
32479
|
var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
|
|
32315
|
-
var LandingSectionKeyEnum =
|
|
32480
|
+
var LandingSectionKeyEnum = z131.enum([
|
|
32316
32481
|
"problem_hook",
|
|
32317
32482
|
"problem_cost",
|
|
32318
32483
|
"solution_mechanism",
|
|
@@ -32352,24 +32517,24 @@ var LandingSectionKeyEnum = z130.enum([
|
|
|
32352
32517
|
"lifestyle_fit",
|
|
32353
32518
|
"join_lifestyle"
|
|
32354
32519
|
]);
|
|
32355
|
-
var CreativeVariantKindEnum =
|
|
32520
|
+
var CreativeVariantKindEnum = z131.enum([
|
|
32356
32521
|
"video",
|
|
32357
32522
|
"image",
|
|
32358
32523
|
"landing"
|
|
32359
32524
|
]);
|
|
32360
|
-
var EstimateCreativeVariantInputBase =
|
|
32361
|
-
sourceTaskId:
|
|
32525
|
+
var EstimateCreativeVariantInputBase = z131.object({
|
|
32526
|
+
sourceTaskId: z131.string().uuid().describe("ID de la tarea original completada."),
|
|
32362
32527
|
kind: CreativeVariantKindEnum,
|
|
32363
32528
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
|
|
32364
32529
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
|
|
32365
|
-
nVariants:
|
|
32530
|
+
nVariants: z131.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
32366
32531
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
|
|
32367
|
-
instructions:
|
|
32532
|
+
instructions: z131.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.")
|
|
32368
32533
|
}).strict();
|
|
32369
32534
|
var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
32370
32535
|
if (input.kind === "video" && input.nVariants !== void 0) {
|
|
32371
32536
|
ctx.addIssue({
|
|
32372
|
-
code:
|
|
32537
|
+
code: z131.ZodIssueCode.custom,
|
|
32373
32538
|
path: [
|
|
32374
32539
|
"nVariants"
|
|
32375
32540
|
],
|
|
@@ -32379,7 +32544,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
32379
32544
|
if (input.kind !== "video") {
|
|
32380
32545
|
if (input.videoPreset !== void 0) {
|
|
32381
32546
|
ctx.addIssue({
|
|
32382
|
-
code:
|
|
32547
|
+
code: z131.ZodIssueCode.custom,
|
|
32383
32548
|
path: [
|
|
32384
32549
|
"videoPreset"
|
|
32385
32550
|
],
|
|
@@ -32388,7 +32553,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
32388
32553
|
}
|
|
32389
32554
|
if (input.videoResolution !== void 0) {
|
|
32390
32555
|
ctx.addIssue({
|
|
32391
|
-
code:
|
|
32556
|
+
code: z131.ZodIssueCode.custom,
|
|
32392
32557
|
path: [
|
|
32393
32558
|
"videoResolution"
|
|
32394
32559
|
],
|
|
@@ -32398,7 +32563,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
32398
32563
|
}
|
|
32399
32564
|
if (input.kind !== "image" && input.nVariants !== void 0) {
|
|
32400
32565
|
ctx.addIssue({
|
|
32401
|
-
code:
|
|
32566
|
+
code: z131.ZodIssueCode.custom,
|
|
32402
32567
|
path: [
|
|
32403
32568
|
"nVariants"
|
|
32404
32569
|
],
|
|
@@ -32408,7 +32573,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
32408
32573
|
if (input.kind !== "landing") {
|
|
32409
32574
|
if (input.sectionKey !== void 0) {
|
|
32410
32575
|
ctx.addIssue({
|
|
32411
|
-
code:
|
|
32576
|
+
code: z131.ZodIssueCode.custom,
|
|
32412
32577
|
path: [
|
|
32413
32578
|
"sectionKey"
|
|
32414
32579
|
],
|
|
@@ -32417,7 +32582,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
32417
32582
|
}
|
|
32418
32583
|
if (input.instructions !== void 0) {
|
|
32419
32584
|
ctx.addIssue({
|
|
32420
|
-
code:
|
|
32585
|
+
code: z131.ZodIssueCode.custom,
|
|
32421
32586
|
path: [
|
|
32422
32587
|
"instructions"
|
|
32423
32588
|
],
|
|
@@ -32426,31 +32591,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
32426
32591
|
}
|
|
32427
32592
|
}
|
|
32428
32593
|
});
|
|
32429
|
-
var CreateCreativeVariantInputBase =
|
|
32430
|
-
sourceTaskId:
|
|
32594
|
+
var CreateCreativeVariantInputBase = z131.object({
|
|
32595
|
+
sourceTaskId: z131.string().uuid().describe("ID de la tarea original completada."),
|
|
32431
32596
|
kind: CreativeVariantKindEnum,
|
|
32432
|
-
confirm:
|
|
32433
|
-
clientRequestId:
|
|
32434
|
-
angle:
|
|
32435
|
-
buyerPersona:
|
|
32436
|
-
scriptNotes:
|
|
32437
|
-
creativeDirection:
|
|
32597
|
+
confirm: z131.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
|
|
32598
|
+
clientRequestId: z131.string().uuid().describe("UUID estable para esta intenci\xF3n (obligatorio por compatibilidad de contrato; el servidor deriva la identidad real del request desde los argumentos sem\xE1nticos, as\xED que un UUID nuevo en un retry NO crea una variante duplicada). Si la API devuelve status=error, una nueva generaci\xF3n exige otra confirmaci\xF3n."),
|
|
32599
|
+
angle: z131.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
|
|
32600
|
+
buyerPersona: z131.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
|
|
32601
|
+
scriptNotes: z131.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
|
|
32602
|
+
creativeDirection: z131.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
|
|
32438
32603
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
|
|
32439
32604
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
|
|
32440
|
-
generateAiMusic:
|
|
32441
|
-
nVariants:
|
|
32605
|
+
generateAiMusic: z131.boolean().optional().describe("Opcional para video."),
|
|
32606
|
+
nVariants: z131.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
32442
32607
|
imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
|
|
32443
32608
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
|
|
32444
32609
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
|
|
32445
32610
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
|
|
32446
|
-
styleMix:
|
|
32611
|
+
styleMix: z131.boolean().optional().describe("Opcional para imagen."),
|
|
32447
32612
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
|
|
32448
|
-
instructions:
|
|
32613
|
+
instructions: z131.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.")
|
|
32449
32614
|
}).strict();
|
|
32450
32615
|
var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
32451
32616
|
if ((input.kind === "video" || input.kind === "image") && !input.angle) {
|
|
32452
32617
|
ctx.addIssue({
|
|
32453
|
-
code:
|
|
32618
|
+
code: z131.ZodIssueCode.custom,
|
|
32454
32619
|
path: [
|
|
32455
32620
|
"angle"
|
|
32456
32621
|
],
|
|
@@ -32459,7 +32624,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
32459
32624
|
}
|
|
32460
32625
|
if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
|
|
32461
32626
|
ctx.addIssue({
|
|
32462
|
-
code:
|
|
32627
|
+
code: z131.ZodIssueCode.custom,
|
|
32463
32628
|
path: [
|
|
32464
32629
|
"instructions"
|
|
32465
32630
|
],
|
|
@@ -32505,7 +32670,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
32505
32670
|
for (const field of fieldsByKind[input.kind]) {
|
|
32506
32671
|
if (input[field] !== void 0) {
|
|
32507
32672
|
ctx.addIssue({
|
|
32508
|
-
code:
|
|
32673
|
+
code: z131.ZodIssueCode.custom,
|
|
32509
32674
|
path: [
|
|
32510
32675
|
field
|
|
32511
32676
|
],
|
|
@@ -32663,13 +32828,13 @@ function registerCreativeVariantTools(server, api) {
|
|
|
32663
32828
|
__name(registerCreativeVariantTools, "registerCreativeVariantTools");
|
|
32664
32829
|
|
|
32665
32830
|
// src/tools/script-review.ts
|
|
32666
|
-
import { z as
|
|
32831
|
+
import { z as z132 } from "zod";
|
|
32667
32832
|
var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
|
|
32668
32833
|
var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
|
|
32669
32834
|
var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
|
|
32670
|
-
var GetVideoScriptInput =
|
|
32671
|
-
taskId:
|
|
32672
|
-
angleKey:
|
|
32835
|
+
var GetVideoScriptInput = z132.object({
|
|
32836
|
+
taskId: z132.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
|
|
32837
|
+
angleKey: z132.string().min(1).optional().describe('Clave persistida del \xE1ngulo cuyo guion se quiere leer (formato "angle_0", "angle_1", ...). Usa exactamente el angleKey recibido en reviewNextAction.calls al aprobar \xE1ngulos, incluso si s\xF3lo elegiste uno. Si se omite, el backend resuelve a "angle_0" literal; elegir el segundo candidato no crea angle_0. No derives esta clave del n\xFAmero visible del candidato.')
|
|
32673
32838
|
}).strict();
|
|
32674
32839
|
var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
|
|
32675
32840
|
var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
|
|
@@ -32774,7 +32939,7 @@ Consulta get_task_status con esta tarea antes de reintentar. Si la tarea termin\
|
|
|
32774
32939
|
__name(registerScriptReviewTools, "registerScriptReviewTools");
|
|
32775
32940
|
|
|
32776
32941
|
// src/tools/connections.ts
|
|
32777
|
-
import { z as
|
|
32942
|
+
import { z as z133 } from "zod";
|
|
32778
32943
|
var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
|
|
32779
32944
|
var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
|
|
32780
32945
|
var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
|
|
@@ -32783,7 +32948,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
|
|
|
32783
32948
|
function registerConnectionTools(server, api) {
|
|
32784
32949
|
server.registerTool("list_shopify_shops", {
|
|
32785
32950
|
description: listShopifyShopsGuidance.summary + " Si la lista est\xE1 vac\xEDa, dile al usuario que conecte una tienda en productmaker.app/integrations antes de intentar publicar.",
|
|
32786
|
-
inputSchema:
|
|
32951
|
+
inputSchema: z133.object({}).shape,
|
|
32787
32952
|
annotations: READS_INTERNAL
|
|
32788
32953
|
}, async () => {
|
|
32789
32954
|
try {
|
|
@@ -32795,10 +32960,10 @@ function registerConnectionTools(server, api) {
|
|
|
32795
32960
|
});
|
|
32796
32961
|
server.registerTool("list_shopify_products", {
|
|
32797
32962
|
description: 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.',
|
|
32798
|
-
inputSchema:
|
|
32799
|
-
shopDomain:
|
|
32800
|
-
query:
|
|
32801
|
-
taskId:
|
|
32963
|
+
inputSchema: z133.object({
|
|
32964
|
+
shopDomain: z133.string().min(3).max(120),
|
|
32965
|
+
query: z133.string().trim().max(120).optional(),
|
|
32966
|
+
taskId: z133.string().uuid().optional()
|
|
32802
32967
|
}).shape,
|
|
32803
32968
|
annotations: READS_EXTERNAL
|
|
32804
32969
|
}, async ({ shopDomain, query, taskId }) => {
|
|
@@ -32816,7 +32981,7 @@ function registerConnectionTools(server, api) {
|
|
|
32816
32981
|
});
|
|
32817
32982
|
server.registerTool("list_meta_ad_accounts", {
|
|
32818
32983
|
description: 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.",
|
|
32819
|
-
inputSchema:
|
|
32984
|
+
inputSchema: z133.object({}).shape,
|
|
32820
32985
|
annotations: READS_EXTERNAL
|
|
32821
32986
|
}, async () => {
|
|
32822
32987
|
try {
|
|
@@ -32828,7 +32993,7 @@ function registerConnectionTools(server, api) {
|
|
|
32828
32993
|
});
|
|
32829
32994
|
server.registerTool("list_meta_destinations", {
|
|
32830
32995
|
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.",
|
|
32831
|
-
inputSchema:
|
|
32996
|
+
inputSchema: z133.object({}).shape,
|
|
32832
32997
|
annotations: READS_EXTERNAL,
|
|
32833
32998
|
_meta: {
|
|
32834
32999
|
"openai/widgetAccessible": true
|
|
@@ -32843,7 +33008,7 @@ function registerConnectionTools(server, api) {
|
|
|
32843
33008
|
});
|
|
32844
33009
|
server.registerTool("list_tiktok_advertisers", {
|
|
32845
33010
|
description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
|
|
32846
|
-
inputSchema:
|
|
33011
|
+
inputSchema: z133.object({}).shape,
|
|
32847
33012
|
annotations: READS_EXTERNAL
|
|
32848
33013
|
}, async () => {
|
|
32849
33014
|
try {
|
|
@@ -32857,7 +33022,7 @@ function registerConnectionTools(server, api) {
|
|
|
32857
33022
|
__name(registerConnectionTools, "registerConnectionTools");
|
|
32858
33023
|
|
|
32859
33024
|
// src/tools/actors.ts
|
|
32860
|
-
import { z as
|
|
33025
|
+
import { z as z134 } from "zod";
|
|
32861
33026
|
var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
|
|
32862
33027
|
var actorVoiceGuidance = {
|
|
32863
33028
|
capabilities: getProductMakerCapabilityModelGuidance("get_actor_voice_capabilities"),
|
|
@@ -32897,7 +33062,7 @@ function sanitizeVoiceResult(value) {
|
|
|
32897
33062
|
__name(sanitizeVoiceResult, "sanitizeVoiceResult");
|
|
32898
33063
|
function registerActorTools(server, api) {
|
|
32899
33064
|
const actor = {
|
|
32900
|
-
actorId:
|
|
33065
|
+
actorId: z134.string().min(1).max(64)
|
|
32901
33066
|
};
|
|
32902
33067
|
const safe = /* @__PURE__ */ __name(async (request) => {
|
|
32903
33068
|
try {
|
|
@@ -32926,8 +33091,8 @@ function registerActorTools(server, api) {
|
|
|
32926
33091
|
inputSchema: {
|
|
32927
33092
|
...actor,
|
|
32928
33093
|
draft: ActorVoiceDraftSchema,
|
|
32929
|
-
requestKey:
|
|
32930
|
-
acceptedQuoteId:
|
|
33094
|
+
requestKey: z134.string().trim().min(1).max(128),
|
|
33095
|
+
acceptedQuoteId: z134.string().trim().min(1).max(128)
|
|
32931
33096
|
},
|
|
32932
33097
|
annotations: CREATES_PAID
|
|
32933
33098
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews`, body)));
|
|
@@ -32935,7 +33100,7 @@ function registerActorTools(server, api) {
|
|
|
32935
33100
|
description: actorVoiceGuidance.get.summary,
|
|
32936
33101
|
inputSchema: {
|
|
32937
33102
|
...actor,
|
|
32938
|
-
candidateId:
|
|
33103
|
+
candidateId: z134.string().min(1).max(64)
|
|
32939
33104
|
},
|
|
32940
33105
|
// Polling can resume the first paid submission of an accepted quote.
|
|
32941
33106
|
// The immutable candidate/operation key keeps recovery idempotent.
|
|
@@ -32948,16 +33113,16 @@ function registerActorTools(server, api) {
|
|
|
32948
33113
|
description: actorVoiceGuidance.approve.summary,
|
|
32949
33114
|
inputSchema: {
|
|
32950
33115
|
...actor,
|
|
32951
|
-
candidateId:
|
|
32952
|
-
expectedRevision:
|
|
32953
|
-
expectedApprovedRevision:
|
|
33116
|
+
candidateId: z134.string().min(1).max(64),
|
|
33117
|
+
expectedRevision: z134.number().int().positive(),
|
|
33118
|
+
expectedApprovedRevision: z134.number().int().positive().nullable().optional()
|
|
32954
33119
|
},
|
|
32955
33120
|
// Replaces the selected voice and withdraws the old catalog grants.
|
|
32956
33121
|
annotations: OVERWRITES_INTERNAL
|
|
32957
33122
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/approve`, body)));
|
|
32958
33123
|
server.registerTool("list_actors", {
|
|
32959
33124
|
description: listActorsGuidance.summary + " Devuelve id, nombre, descripci\xF3n, g\xE9nero y voz privada del personaje. Cuando el personaje tiene una voz personalizada, `voice.identityId` y `voice.revision` identifican la versi\xF3n aprobada \u2014 conserva la revisi\xF3n al llamar `approve_actor_voice` (expectedApprovedRevision) para reemplazarla. Los IDs de proveedor nunca se exponen por MCP. 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.",
|
|
32960
|
-
inputSchema:
|
|
33125
|
+
inputSchema: z134.object({}).shape,
|
|
32961
33126
|
annotations: READS_INTERNAL
|
|
32962
33127
|
}, async () => {
|
|
32963
33128
|
try {
|
|
@@ -32990,7 +33155,7 @@ function registerActorTools(server, api) {
|
|
|
32990
33155
|
__name(registerActorTools, "registerActorTools");
|
|
32991
33156
|
|
|
32992
33157
|
// src/tools/publish.ts
|
|
32993
|
-
import { z as
|
|
33158
|
+
import { z as z135 } from "zod";
|
|
32994
33159
|
|
|
32995
33160
|
// src/tools/meta-publish-attempt-id.ts
|
|
32996
33161
|
var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
|
|
@@ -33029,40 +33194,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
|
|
|
33029
33194
|
var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
|
|
33030
33195
|
var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
|
|
33031
33196
|
var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
|
|
33032
|
-
var ShopifyInput =
|
|
33033
|
-
taskId:
|
|
33034
|
-
shopDomain:
|
|
33197
|
+
var ShopifyInput = z135.object({
|
|
33198
|
+
taskId: z135.string().min(1),
|
|
33199
|
+
shopDomain: z135.string().min(1),
|
|
33035
33200
|
/** Override: number of landing images to include. Default = ALL images the
|
|
33036
33201
|
* task generated (the MCP fetches /v1/results first to count). Bounded
|
|
33037
33202
|
* generously here; the backend validates each index against
|
|
33038
33203
|
* landing.images.length and rejects out-of-range. */
|
|
33039
|
-
numLandingImages:
|
|
33040
|
-
variantIndex:
|
|
33204
|
+
numLandingImages: z135.number().int().min(1).max(20).optional(),
|
|
33205
|
+
variantIndex: z135.number().int().min(0).optional(),
|
|
33041
33206
|
/** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
|
|
33042
33207
|
* When true, the landing renders variant-picker pills; when false, it ships
|
|
33043
33208
|
* a single-option product page. Defaults to false. */
|
|
33044
|
-
showVariantPicker:
|
|
33209
|
+
showVariantPicker: z135.boolean().optional(),
|
|
33045
33210
|
/** Default `auto` updates the product previously published for this task and
|
|
33046
33211
|
* shop. Use `existing` with targetProductId to choose another product, or
|
|
33047
33212
|
* `new` only when the user explicitly wants a duplicate/new listing. */
|
|
33048
|
-
publicationMode:
|
|
33213
|
+
publicationMode: z135.enum([
|
|
33049
33214
|
"auto",
|
|
33050
33215
|
"existing",
|
|
33051
33216
|
"new"
|
|
33052
33217
|
]).optional(),
|
|
33053
33218
|
/** Shopify product GID, numeric id, or admin product URL. Required when
|
|
33054
33219
|
* publicationMode is `existing`. */
|
|
33055
|
-
targetProductId:
|
|
33220
|
+
targetProductId: z135.string().trim().min(1).max(300).optional(),
|
|
33056
33221
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
33057
|
-
announcementBarEnabled:
|
|
33058
|
-
announcementBarText:
|
|
33222
|
+
announcementBarEnabled: z135.boolean().optional(),
|
|
33223
|
+
announcementBarText: z135.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
|
|
33059
33224
|
commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
|
|
33060
|
-
confirmed:
|
|
33225
|
+
confirmed: z135.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
|
|
33061
33226
|
});
|
|
33062
33227
|
var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
|
|
33063
33228
|
if (value.commerceCorrection && value.confirmed !== true) {
|
|
33064
33229
|
ctx.addIssue({
|
|
33065
|
-
code:
|
|
33230
|
+
code: z135.ZodIssueCode.custom,
|
|
33066
33231
|
path: [
|
|
33067
33232
|
"confirmed"
|
|
33068
33233
|
],
|
|
@@ -33071,7 +33236,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
33071
33236
|
}
|
|
33072
33237
|
if (value.announcementBarEnabled && !value.announcementBarText) {
|
|
33073
33238
|
ctx.addIssue({
|
|
33074
|
-
code:
|
|
33239
|
+
code: z135.ZodIssueCode.custom,
|
|
33075
33240
|
path: [
|
|
33076
33241
|
"announcementBarText"
|
|
33077
33242
|
],
|
|
@@ -33080,7 +33245,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
33080
33245
|
}
|
|
33081
33246
|
if (!value.announcementBarEnabled && value.announcementBarText) {
|
|
33082
33247
|
ctx.addIssue({
|
|
33083
|
-
code:
|
|
33248
|
+
code: z135.ZodIssueCode.custom,
|
|
33084
33249
|
path: [
|
|
33085
33250
|
"announcementBarText"
|
|
33086
33251
|
],
|
|
@@ -33094,90 +33259,90 @@ function parseShopifyInput(rawInput) {
|
|
|
33094
33259
|
return parsed.data;
|
|
33095
33260
|
}
|
|
33096
33261
|
__name(parseShopifyInput, "parseShopifyInput");
|
|
33097
|
-
var McpCampaignConfig =
|
|
33262
|
+
var McpCampaignConfig = z135.object({
|
|
33098
33263
|
/** Legacy USD amount. Meta retains its existing conversion; the TikTok
|
|
33099
33264
|
* schema below restricts this input to USD advertiser accounts. */
|
|
33100
|
-
dailyBudgetUsd:
|
|
33265
|
+
dailyBudgetUsd: z135.number().positive().optional(),
|
|
33101
33266
|
/** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
|
|
33102
33267
|
* normalizes at validation). Meta accepts max 1 (single-country ad set).
|
|
33103
33268
|
* TikTok takes only the first entry. */
|
|
33104
|
-
targetCountries:
|
|
33105
|
-
campaignName:
|
|
33269
|
+
targetCountries: z135.array(CountryIso2Schema).max(1).optional(),
|
|
33270
|
+
campaignName: z135.string().trim().min(1).max(100).optional()
|
|
33106
33271
|
});
|
|
33107
33272
|
var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
|
|
33108
|
-
var MetaInput =
|
|
33109
|
-
taskId:
|
|
33273
|
+
var MetaInput = z135.object({
|
|
33274
|
+
taskId: z135.string().min(1),
|
|
33110
33275
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
33111
|
-
portfolioId:
|
|
33276
|
+
portfolioId: z135.string().trim().min(1),
|
|
33112
33277
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
33113
|
-
pageId:
|
|
33278
|
+
pageId: z135.string().trim().min(1),
|
|
33114
33279
|
adAccountId: McpAdAccountId,
|
|
33115
|
-
pixelId:
|
|
33116
|
-
landingUrl:
|
|
33280
|
+
pixelId: z135.string().min(1).optional(),
|
|
33281
|
+
landingUrl: z135.string().url().optional(),
|
|
33117
33282
|
/** Select which angles to publish by 0-based index. Omit to publish all
|
|
33118
33283
|
* successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
|
|
33119
|
-
angleIndexes:
|
|
33284
|
+
angleIndexes: z135.array(z135.number().int().nonnegative()).optional(),
|
|
33120
33285
|
campaignConfig: McpCampaignConfig.optional(),
|
|
33121
33286
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
33122
33287
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
33123
33288
|
* (Meta's primary-text limit). */
|
|
33124
|
-
primaryText:
|
|
33289
|
+
primaryText: z135.string().trim().min(1).max(500).optional(),
|
|
33125
33290
|
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
33126
33291
|
* (wa.me) instead of a landing page. */
|
|
33127
|
-
phoneNumber:
|
|
33292
|
+
phoneNumber: z135.string().min(8).max(32).optional()
|
|
33128
33293
|
});
|
|
33129
|
-
var GroupedTaskSource =
|
|
33130
|
-
type:
|
|
33131
|
-
taskId:
|
|
33132
|
-
angleIndex:
|
|
33133
|
-
videoVariant:
|
|
33294
|
+
var GroupedTaskSource = z135.object({
|
|
33295
|
+
type: z135.literal("task"),
|
|
33296
|
+
taskId: z135.string().min(1),
|
|
33297
|
+
angleIndex: z135.number().int().min(0).optional(),
|
|
33298
|
+
videoVariant: z135.enum([
|
|
33134
33299
|
"with_subtitles",
|
|
33135
33300
|
"without_subtitles"
|
|
33136
33301
|
]).optional(),
|
|
33137
|
-
imageVariantIndex:
|
|
33138
|
-
});
|
|
33139
|
-
var GroupedMediaSource =
|
|
33140
|
-
type:
|
|
33141
|
-
url:
|
|
33142
|
-
path:
|
|
33143
|
-
thumbnailUrl:
|
|
33144
|
-
thumbnailPath:
|
|
33302
|
+
imageVariantIndex: z135.number().int().min(0).optional()
|
|
33303
|
+
});
|
|
33304
|
+
var GroupedMediaSource = z135.object({
|
|
33305
|
+
type: z135.literal("media"),
|
|
33306
|
+
url: z135.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
|
|
33307
|
+
path: z135.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".'),
|
|
33308
|
+
thumbnailUrl: z135.string().url().optional(),
|
|
33309
|
+
thumbnailPath: z135.string().min(1).optional()
|
|
33145
33310
|
}).refine((value) => Boolean(value.url) !== Boolean(value.path), {
|
|
33146
33311
|
message: "media source needs exactly one of `url` or `path`"
|
|
33147
33312
|
}).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
|
|
33148
33313
|
message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
|
|
33149
33314
|
});
|
|
33150
|
-
var GroupedUploadedAssetSource =
|
|
33151
|
-
type:
|
|
33315
|
+
var GroupedUploadedAssetSource = z135.object({
|
|
33316
|
+
type: z135.literal("asset"),
|
|
33152
33317
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
33153
|
-
assetId:
|
|
33154
|
-
thumbnailAssetId:
|
|
33318
|
+
assetId: z135.string().uuid(),
|
|
33319
|
+
thumbnailAssetId: z135.string().uuid().optional()
|
|
33155
33320
|
});
|
|
33156
|
-
var GroupedCreative =
|
|
33157
|
-
type:
|
|
33321
|
+
var GroupedCreative = z135.object({
|
|
33322
|
+
type: z135.enum([
|
|
33158
33323
|
"image",
|
|
33159
33324
|
"video"
|
|
33160
33325
|
]),
|
|
33161
|
-
source:
|
|
33326
|
+
source: z135.union([
|
|
33162
33327
|
GroupedTaskSource,
|
|
33163
33328
|
GroupedMediaSource,
|
|
33164
33329
|
GroupedUploadedAssetSource
|
|
33165
33330
|
]),
|
|
33166
|
-
title:
|
|
33167
|
-
description:
|
|
33331
|
+
title: z135.string().max(120).optional(),
|
|
33332
|
+
description: z135.string().max(500).optional(),
|
|
33168
33333
|
cta: MetaCtaType.optional(),
|
|
33169
|
-
creativeId:
|
|
33334
|
+
creativeId: z135.string().min(1).optional()
|
|
33170
33335
|
});
|
|
33171
|
-
var GroupedCampaignConfigBase =
|
|
33336
|
+
var GroupedCampaignConfigBase = z135.object({
|
|
33172
33337
|
campaignType: MetaCampaignType.default("sales"),
|
|
33173
33338
|
optimizationMode: MetaOptimizationMode.default("advantage_plus"),
|
|
33174
33339
|
budgetMode: MetaBudgetMode.optional(),
|
|
33175
|
-
campaignDailyBudget:
|
|
33176
|
-
adSets:
|
|
33177
|
-
tempId:
|
|
33178
|
-
name:
|
|
33179
|
-
dailyBudget:
|
|
33180
|
-
creativeIds:
|
|
33340
|
+
campaignDailyBudget: z135.number().int().positive().optional(),
|
|
33341
|
+
adSets: z135.array(z135.object({
|
|
33342
|
+
tempId: z135.string().min(1).max(80),
|
|
33343
|
+
name: z135.string().min(1).max(100),
|
|
33344
|
+
dailyBudget: z135.number().int().positive().optional(),
|
|
33345
|
+
creativeIds: z135.array(z135.string().min(1)).min(1)
|
|
33181
33346
|
})).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
|
|
33182
33347
|
/**
|
|
33183
33348
|
* Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
|
|
@@ -33185,17 +33350,17 @@ var GroupedCampaignConfigBase = z134.object({
|
|
|
33185
33350
|
* opaque `invalid_literal` and made the WhatsApp destination — supported by
|
|
33186
33351
|
* the API since #849 — unreachable from this tool.
|
|
33187
33352
|
*/
|
|
33188
|
-
destination:
|
|
33189
|
-
|
|
33190
|
-
type:
|
|
33191
|
-
landingUrl:
|
|
33353
|
+
destination: z135.discriminatedUnion("type", [
|
|
33354
|
+
z135.object({
|
|
33355
|
+
type: z135.literal("landing"),
|
|
33356
|
+
landingUrl: z135.string().url()
|
|
33192
33357
|
}),
|
|
33193
|
-
|
|
33194
|
-
type:
|
|
33195
|
-
phoneNumber:
|
|
33358
|
+
z135.object({
|
|
33359
|
+
type: z135.literal("whatsapp"),
|
|
33360
|
+
phoneNumber: z135.string().min(8).max(32)
|
|
33196
33361
|
})
|
|
33197
33362
|
]),
|
|
33198
|
-
saveAsDefault:
|
|
33363
|
+
saveAsDefault: z135.boolean().default(false),
|
|
33199
33364
|
budgetPolicy: MetaBudgetPolicy.optional()
|
|
33200
33365
|
});
|
|
33201
33366
|
function resolveBudgetMode(value) {
|
|
@@ -33209,7 +33374,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
33209
33374
|
const budgetMode = resolveBudgetMode(value);
|
|
33210
33375
|
if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
|
|
33211
33376
|
ctx.addIssue({
|
|
33212
|
-
code:
|
|
33377
|
+
code: z135.ZodIssueCode.custom,
|
|
33213
33378
|
path: [
|
|
33214
33379
|
"campaignDailyBudget"
|
|
33215
33380
|
],
|
|
@@ -33220,7 +33385,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
33220
33385
|
value.adSets.forEach((adSet, index) => {
|
|
33221
33386
|
if (adSet.dailyBudget === void 0) {
|
|
33222
33387
|
ctx.addIssue({
|
|
33223
|
-
code:
|
|
33388
|
+
code: z135.ZodIssueCode.custom,
|
|
33224
33389
|
path: [
|
|
33225
33390
|
"adSets",
|
|
33226
33391
|
index,
|
|
@@ -33235,25 +33400,25 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
33235
33400
|
...value,
|
|
33236
33401
|
budgetMode: resolveBudgetMode(value)
|
|
33237
33402
|
}));
|
|
33238
|
-
var PublishCreativesToMetaInputBase =
|
|
33239
|
-
creatives:
|
|
33403
|
+
var PublishCreativesToMetaInputBase = z135.object({
|
|
33404
|
+
creatives: z135.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
|
|
33240
33405
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
33241
|
-
portfolioId:
|
|
33406
|
+
portfolioId: z135.string().trim().min(1),
|
|
33242
33407
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
33243
|
-
pageId:
|
|
33408
|
+
pageId: z135.string().trim().min(1),
|
|
33244
33409
|
adAccountId: McpAdAccountId,
|
|
33245
|
-
pixelId:
|
|
33410
|
+
pixelId: z135.string().min(1).optional(),
|
|
33246
33411
|
/** Required unless `campaignConfig.destination` is whatsapp or a creative
|
|
33247
33412
|
* comes from a task (the API then lands on the published service landing
|
|
33248
33413
|
* of its service tasks) — see the superRefine below. Mirrors the API's
|
|
33249
33414
|
* `FacebookCreateCampaignFromTasksBodySchema`. */
|
|
33250
|
-
landingUrl:
|
|
33415
|
+
landingUrl: z135.string().url().optional(),
|
|
33251
33416
|
/** ISO-2 code or resolvable country name — mirrors the API contract
|
|
33252
33417
|
* (CountryIso2Schema), which normalizes names to alpha-2 at validation.
|
|
33253
33418
|
* Omitted: the brand country of its service tasks (the API answers
|
|
33254
33419
|
* META_NO_TARGET_COUNTRY when it has none); "US" for products. */
|
|
33255
33420
|
targetCountry: CountryIso2Schema.optional(),
|
|
33256
|
-
campaignName:
|
|
33421
|
+
campaignName: z135.string().trim().min(1).max(100),
|
|
33257
33422
|
campaignConfig: GroupedCampaignConfig.optional()
|
|
33258
33423
|
});
|
|
33259
33424
|
var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
|
|
@@ -33261,7 +33426,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
33261
33426
|
const hasTaskCreative = value.creatives.some((creative) => creative.source.type === "task");
|
|
33262
33427
|
if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl && !hasTaskCreative) {
|
|
33263
33428
|
ctx.addIssue({
|
|
33264
|
-
code:
|
|
33429
|
+
code: z135.ZodIssueCode.custom,
|
|
33265
33430
|
path: [
|
|
33266
33431
|
"landingUrl"
|
|
33267
33432
|
],
|
|
@@ -33270,7 +33435,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
33270
33435
|
}
|
|
33271
33436
|
if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
|
|
33272
33437
|
ctx.addIssue({
|
|
33273
|
-
code:
|
|
33438
|
+
code: z135.ZodIssueCode.custom,
|
|
33274
33439
|
path: [
|
|
33275
33440
|
"campaignConfig",
|
|
33276
33441
|
"destination",
|
|
@@ -33289,16 +33454,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
33289
33454
|
}
|
|
33290
33455
|
return value;
|
|
33291
33456
|
});
|
|
33292
|
-
var PresignUploadResponseSchema =
|
|
33293
|
-
uploadUrl:
|
|
33457
|
+
var PresignUploadResponseSchema = z135.object({
|
|
33458
|
+
uploadUrl: z135.string().url().refine((value) => {
|
|
33294
33459
|
const url = new URL(value);
|
|
33295
33460
|
return !url.username && !url.password && url.protocol === "https:";
|
|
33296
33461
|
}, "presigned upload URL must be HTTPS without embedded credentials"),
|
|
33297
|
-
publicUrl:
|
|
33462
|
+
publicUrl: z135.string().url().refine((value) => {
|
|
33298
33463
|
const url = new URL(value);
|
|
33299
33464
|
return !url.username && !url.password;
|
|
33300
33465
|
}, "public media URL must not contain embedded credentials"),
|
|
33301
|
-
stagingAssetId:
|
|
33466
|
+
stagingAssetId: z135.string().uuid()
|
|
33302
33467
|
});
|
|
33303
33468
|
async function uploadResolvedMedia(api, media, assetRole) {
|
|
33304
33469
|
if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
|
|
@@ -33324,14 +33489,14 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
|
|
|
33324
33489
|
}
|
|
33325
33490
|
__name(resolveAndUploadMedia, "resolveAndUploadMedia");
|
|
33326
33491
|
var TikTokMcpCampaignConfig = McpCampaignConfig.extend({
|
|
33327
|
-
dailyBudgetUsd:
|
|
33328
|
-
dailyBudget:
|
|
33492
|
+
dailyBudgetUsd: z135.number().finite().positive().optional().describe("Legacy USD amount, supported only for USD advertiser accounts. No FX conversion."),
|
|
33493
|
+
dailyBudget: z135.number().finite().positive().optional().describe("Daily budget in the selected advertiser currency major units; pass budgetCurrency together."),
|
|
33329
33494
|
budgetCurrency: TikTokBudgetCurrencySchema.optional(),
|
|
33330
33495
|
destination: TikTokCampaignDestinationSchema.optional()
|
|
33331
33496
|
}).superRefine((value, ctx) => {
|
|
33332
33497
|
if (value.dailyBudgetUsd !== void 0 && (value.dailyBudget !== void 0 || value.budgetCurrency !== void 0)) {
|
|
33333
33498
|
ctx.addIssue({
|
|
33334
|
-
code:
|
|
33499
|
+
code: z135.ZodIssueCode.custom,
|
|
33335
33500
|
path: [
|
|
33336
33501
|
"dailyBudgetUsd"
|
|
33337
33502
|
],
|
|
@@ -33340,7 +33505,7 @@ var TikTokMcpCampaignConfig = McpCampaignConfig.extend({
|
|
|
33340
33505
|
}
|
|
33341
33506
|
if (value.dailyBudget !== void 0 !== (value.budgetCurrency !== void 0)) {
|
|
33342
33507
|
ctx.addIssue({
|
|
33343
|
-
code:
|
|
33508
|
+
code: z135.ZodIssueCode.custom,
|
|
33344
33509
|
path: [
|
|
33345
33510
|
"budgetCurrency"
|
|
33346
33511
|
],
|
|
@@ -33348,16 +33513,16 @@ var TikTokMcpCampaignConfig = McpCampaignConfig.extend({
|
|
|
33348
33513
|
});
|
|
33349
33514
|
}
|
|
33350
33515
|
});
|
|
33351
|
-
var TikTokInput =
|
|
33352
|
-
taskId:
|
|
33353
|
-
advertiserId:
|
|
33354
|
-
pixelId:
|
|
33355
|
-
landingUrl:
|
|
33356
|
-
angleIndexes:
|
|
33516
|
+
var TikTokInput = z135.object({
|
|
33517
|
+
taskId: z135.string().min(1),
|
|
33518
|
+
advertiserId: z135.string().min(1),
|
|
33519
|
+
pixelId: z135.string().min(1).optional(),
|
|
33520
|
+
landingUrl: z135.string().url().optional(),
|
|
33521
|
+
angleIndexes: z135.array(z135.number().int().nonnegative()).optional(),
|
|
33357
33522
|
campaignConfig: TikTokMcpCampaignConfig.optional(),
|
|
33358
33523
|
/** Override the ad's description (TikTok's body copy). If omitted,
|
|
33359
33524
|
* ProductMaker uses the auto-generated copy attached to the task. */
|
|
33360
|
-
primaryText:
|
|
33525
|
+
primaryText: z135.string().trim().min(1).max(500).optional()
|
|
33361
33526
|
});
|
|
33362
33527
|
function registerPublishTools(server, api, opts = {}) {
|
|
33363
33528
|
const transport = opts.transport ?? "http";
|
|
@@ -33716,39 +33881,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
|
|
|
33716
33881
|
|
|
33717
33882
|
// src/tools/meta-upload.ts
|
|
33718
33883
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
33719
|
-
import { z as
|
|
33884
|
+
import { z as z136 } from "zod";
|
|
33720
33885
|
var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
|
|
33721
|
-
var UploadSessionInputBase =
|
|
33722
|
-
mediaKind:
|
|
33886
|
+
var UploadSessionInputBase = z136.object({
|
|
33887
|
+
mediaKind: z136.enum([
|
|
33723
33888
|
"image",
|
|
33724
33889
|
"video",
|
|
33725
33890
|
"mixed"
|
|
33726
33891
|
]).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."),
|
|
33727
|
-
assetRole:
|
|
33892
|
+
assetRole: z136.enum([
|
|
33728
33893
|
"media",
|
|
33729
33894
|
"thumbnail"
|
|
33730
33895
|
]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
|
|
33731
|
-
uploadPurpose:
|
|
33896
|
+
uploadPurpose: z136.enum([
|
|
33732
33897
|
"product_reference",
|
|
33733
33898
|
"creative",
|
|
33734
33899
|
"generic"
|
|
33735
33900
|
]).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."),
|
|
33736
|
-
maxFiles:
|
|
33901
|
+
maxFiles: z136.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
33737
33902
|
});
|
|
33738
|
-
var OpenAiFileReference =
|
|
33739
|
-
download_url:
|
|
33740
|
-
file_id:
|
|
33741
|
-
mime_type:
|
|
33742
|
-
file_name:
|
|
33903
|
+
var OpenAiFileReference = z136.object({
|
|
33904
|
+
download_url: z136.string().url().describe("Required by ChatGPT's openai/fileParams schema. The App prefers getFileDownloadUrl(file_id) for a fresh URL, and the server never fetches this value."),
|
|
33905
|
+
file_id: z136.string().min(1),
|
|
33906
|
+
mime_type: z136.string().min(1).optional(),
|
|
33907
|
+
file_name: z136.string().min(1).optional()
|
|
33743
33908
|
});
|
|
33744
33909
|
var UploadSessionToolInputShape = {
|
|
33745
33910
|
...UploadSessionInputBase.shape,
|
|
33746
|
-
files:
|
|
33911
|
+
files: z136.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.")
|
|
33747
33912
|
};
|
|
33748
|
-
var UploadSessionToolInput =
|
|
33913
|
+
var UploadSessionToolInput = z136.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
33749
33914
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
33750
33915
|
ctx.addIssue({
|
|
33751
|
-
code:
|
|
33916
|
+
code: z136.ZodIssueCode.custom,
|
|
33752
33917
|
path: [
|
|
33753
33918
|
"mediaKind"
|
|
33754
33919
|
],
|
|
@@ -33757,7 +33922,7 @@ var UploadSessionToolInput = z135.object(UploadSessionToolInputShape).superRefin
|
|
|
33757
33922
|
}
|
|
33758
33923
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
33759
33924
|
ctx.addIssue({
|
|
33760
|
-
code:
|
|
33925
|
+
code: z136.ZodIssueCode.custom,
|
|
33761
33926
|
path: [
|
|
33762
33927
|
"maxFiles"
|
|
33763
33928
|
],
|
|
@@ -33766,7 +33931,7 @@ var UploadSessionToolInput = z135.object(UploadSessionToolInputShape).superRefin
|
|
|
33766
33931
|
}
|
|
33767
33932
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
|
|
33768
33933
|
ctx.addIssue({
|
|
33769
|
-
code:
|
|
33934
|
+
code: z136.ZodIssueCode.custom,
|
|
33770
33935
|
path: [
|
|
33771
33936
|
"maxFiles"
|
|
33772
33937
|
],
|
|
@@ -33774,38 +33939,38 @@ var UploadSessionToolInput = z135.object(UploadSessionToolInputShape).superRefin
|
|
|
33774
33939
|
});
|
|
33775
33940
|
}
|
|
33776
33941
|
});
|
|
33777
|
-
var UploadSessionResponse =
|
|
33778
|
-
sessionId:
|
|
33779
|
-
uploadPageUrl:
|
|
33780
|
-
mediaKind:
|
|
33942
|
+
var UploadSessionResponse = z136.object({
|
|
33943
|
+
sessionId: z136.string().uuid(),
|
|
33944
|
+
uploadPageUrl: z136.string().url(),
|
|
33945
|
+
mediaKind: z136.enum([
|
|
33781
33946
|
"image",
|
|
33782
33947
|
"video",
|
|
33783
33948
|
"mixed"
|
|
33784
33949
|
]),
|
|
33785
|
-
assetRole:
|
|
33950
|
+
assetRole: z136.enum([
|
|
33786
33951
|
"media",
|
|
33787
33952
|
"thumbnail"
|
|
33788
33953
|
]),
|
|
33789
|
-
maxFiles:
|
|
33790
|
-
expiresAt:
|
|
33954
|
+
maxFiles: z136.number().int().positive(),
|
|
33955
|
+
expiresAt: z136.string().datetime()
|
|
33791
33956
|
});
|
|
33792
|
-
var UploadStatusInput =
|
|
33793
|
-
sessionId:
|
|
33957
|
+
var UploadStatusInput = z136.object({
|
|
33958
|
+
sessionId: z136.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
33794
33959
|
});
|
|
33795
|
-
var UniversalUploadStatusResponse =
|
|
33796
|
-
|
|
33797
|
-
status:
|
|
33798
|
-
assets:
|
|
33960
|
+
var UniversalUploadStatusResponse = z136.discriminatedUnion("status", [
|
|
33961
|
+
z136.object({
|
|
33962
|
+
status: z136.literal("pending"),
|
|
33963
|
+
assets: z136.array(z136.never()).length(0)
|
|
33799
33964
|
}),
|
|
33800
|
-
|
|
33801
|
-
status:
|
|
33802
|
-
assets:
|
|
33803
|
-
assetId:
|
|
33804
|
-
mediaKind:
|
|
33965
|
+
z136.object({
|
|
33966
|
+
status: z136.literal("uploaded"),
|
|
33967
|
+
assets: z136.array(z136.object({
|
|
33968
|
+
assetId: z136.string().uuid(),
|
|
33969
|
+
mediaKind: z136.enum([
|
|
33805
33970
|
"image",
|
|
33806
33971
|
"video"
|
|
33807
33972
|
]),
|
|
33808
|
-
assetRole:
|
|
33973
|
+
assetRole: z136.enum([
|
|
33809
33974
|
"media",
|
|
33810
33975
|
"thumbnail"
|
|
33811
33976
|
])
|
|
@@ -33813,13 +33978,13 @@ var UniversalUploadStatusResponse = z135.discriminatedUnion("status", [
|
|
|
33813
33978
|
})
|
|
33814
33979
|
]);
|
|
33815
33980
|
var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
|
|
33816
|
-
uploadPurpose:
|
|
33981
|
+
uploadPurpose: z136.enum([
|
|
33817
33982
|
"product_reference",
|
|
33818
33983
|
"creative",
|
|
33819
33984
|
"generic"
|
|
33820
33985
|
]),
|
|
33821
|
-
checkToolName:
|
|
33822
|
-
resolveEndpoint:
|
|
33986
|
+
checkToolName: z136.literal("check_media_upload"),
|
|
33987
|
+
resolveEndpoint: z136.string().url()
|
|
33823
33988
|
});
|
|
33824
33989
|
function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
|
|
33825
33990
|
const url = new URL(uploadPageUrl);
|
|
@@ -33910,15 +34075,15 @@ function registerMediaUploadTools(server, api) {
|
|
|
33910
34075
|
__name(registerMediaUploadTools, "registerMediaUploadTools");
|
|
33911
34076
|
|
|
33912
34077
|
// src/tools/campaigns.ts
|
|
33913
|
-
import { z as
|
|
34078
|
+
import { z as z137 } from "zod";
|
|
33914
34079
|
var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
|
|
33915
34080
|
var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
|
|
33916
|
-
var MetaStatusInput =
|
|
33917
|
-
campaignId:
|
|
34081
|
+
var MetaStatusInput = z137.object({
|
|
34082
|
+
campaignId: z137.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
|
|
33918
34083
|
});
|
|
33919
|
-
var TikTokStatusInput =
|
|
33920
|
-
campaignId:
|
|
33921
|
-
advertiserId:
|
|
34084
|
+
var TikTokStatusInput = z137.object({
|
|
34085
|
+
campaignId: z137.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
|
|
34086
|
+
advertiserId: z137.string().min(1).describe("The same advertiserId used to publish the campaign.")
|
|
33922
34087
|
});
|
|
33923
34088
|
function registerCampaignTools(server, api) {
|
|
33924
34089
|
server.registerTool("get_meta_campaign_status", {
|
|
@@ -34023,10 +34188,10 @@ function renderTikTokStatusMarkdown(r) {
|
|
|
34023
34188
|
__name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
|
|
34024
34189
|
|
|
34025
34190
|
// ../../packages/product-economics/src/product-costing.ts
|
|
34026
|
-
import { z as
|
|
34191
|
+
import { z as z139 } from "zod";
|
|
34027
34192
|
|
|
34028
34193
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
34029
|
-
import { z as
|
|
34194
|
+
import { z as z138 } from "zod";
|
|
34030
34195
|
|
|
34031
34196
|
// ../../packages/product-economics/src/product-costing-shipping-references.json
|
|
34032
34197
|
var product_costing_shipping_references_default = {
|
|
@@ -34090,21 +34255,21 @@ var product_costing_shipping_references_default = {
|
|
|
34090
34255
|
};
|
|
34091
34256
|
|
|
34092
34257
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
34093
|
-
var ShippingReferenceSchema =
|
|
34094
|
-
reference:
|
|
34095
|
-
min:
|
|
34096
|
-
max:
|
|
34097
|
-
updatedAt:
|
|
34098
|
-
confidence:
|
|
34258
|
+
var ShippingReferenceSchema = z138.object({
|
|
34259
|
+
reference: z138.number().positive(),
|
|
34260
|
+
min: z138.number().nonnegative(),
|
|
34261
|
+
max: z138.number().positive(),
|
|
34262
|
+
updatedAt: z138.string().date(),
|
|
34263
|
+
confidence: z138.enum([
|
|
34099
34264
|
"high",
|
|
34100
34265
|
"medium",
|
|
34101
34266
|
"medium-low"
|
|
34102
34267
|
]),
|
|
34103
|
-
sources:
|
|
34268
|
+
sources: z138.array(z138.string().url().startsWith("https://")).min(1).max(3)
|
|
34104
34269
|
}).superRefine(({ reference, min, max }, context) => {
|
|
34105
34270
|
if (min > reference || reference > max) {
|
|
34106
34271
|
context.addIssue({
|
|
34107
|
-
code:
|
|
34272
|
+
code: z138.ZodIssueCode.custom,
|
|
34108
34273
|
message: "shipping_reference_outside_range",
|
|
34109
34274
|
path: [
|
|
34110
34275
|
"reference"
|
|
@@ -34112,7 +34277,7 @@ var ShippingReferenceSchema = z137.object({
|
|
|
34112
34277
|
});
|
|
34113
34278
|
}
|
|
34114
34279
|
});
|
|
34115
|
-
var SHIPPING_REFERENCES =
|
|
34280
|
+
var SHIPPING_REFERENCES = z138.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
|
|
34116
34281
|
var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
|
|
34117
34282
|
var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
|
|
34118
34283
|
"MX",
|
|
@@ -34294,18 +34459,18 @@ function getProductCostingCountryName(country) {
|
|
|
34294
34459
|
__name(getProductCostingCountryName, "getProductCostingCountryName");
|
|
34295
34460
|
|
|
34296
34461
|
// ../../packages/product-economics/src/product-costing.ts
|
|
34297
|
-
var ProductCostingInputSchema =
|
|
34298
|
-
country:
|
|
34299
|
-
supplierCost:
|
|
34300
|
-
shippingCost:
|
|
34301
|
-
returnRate:
|
|
34302
|
-
cancellationRate:
|
|
34303
|
-
adsManagerCpa:
|
|
34304
|
-
desiredMargin:
|
|
34462
|
+
var ProductCostingInputSchema = z139.object({
|
|
34463
|
+
country: z139.string().refine(isProductCostingCountryCode, "unsupported_country"),
|
|
34464
|
+
supplierCost: z139.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
|
|
34465
|
+
shippingCost: z139.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
|
|
34466
|
+
returnRate: z139.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
34467
|
+
cancellationRate: z139.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
34468
|
+
adsManagerCpa: z139.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
|
|
34469
|
+
desiredMargin: z139.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
|
|
34305
34470
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
34306
34471
|
if (returnRate + cancellationRate >= 1) {
|
|
34307
34472
|
context.addIssue({
|
|
34308
|
-
code:
|
|
34473
|
+
code: z139.ZodIssueCode.custom,
|
|
34309
34474
|
message: "delivery_rate_positive",
|
|
34310
34475
|
path: [
|
|
34311
34476
|
"cancellationRate"
|
|
@@ -34402,15 +34567,15 @@ function calculateProductCosting(rawInput) {
|
|
|
34402
34567
|
__name(calculateProductCosting, "calculateProductCosting");
|
|
34403
34568
|
|
|
34404
34569
|
// src/tools/product-costing.ts
|
|
34405
|
-
import { z as
|
|
34570
|
+
import { z as z140 } from "zod";
|
|
34406
34571
|
var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
|
|
34407
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
34408
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
34409
|
-
var ProductCostingToolInput =
|
|
34410
|
-
country:
|
|
34572
|
+
var optionalAmount = /* @__PURE__ */ __name((description) => z140.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
|
|
34573
|
+
var optionalPercent = /* @__PURE__ */ __name((description) => z140.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
|
|
34574
|
+
var ProductCostingToolInput = z140.object({
|
|
34575
|
+
country: z140.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
34411
34576
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
34412
34577
|
}).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
|
|
34413
|
-
supplierCost:
|
|
34578
|
+
supplierCost: z140.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."),
|
|
34414
34579
|
supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
|
|
34415
34580
|
shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
|
|
34416
34581
|
shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
|
|
@@ -34573,7 +34738,7 @@ function formatPercent(value) {
|
|
|
34573
34738
|
__name(formatPercent, "formatPercent");
|
|
34574
34739
|
|
|
34575
34740
|
// src/tools/product-research.ts
|
|
34576
|
-
import { z as
|
|
34741
|
+
import { z as z141 } from "zod";
|
|
34577
34742
|
|
|
34578
34743
|
// src/tools/product-research-idempotency.ts
|
|
34579
34744
|
var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
|
|
@@ -34944,35 +35109,35 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
|
|
|
34944
35109
|
]);
|
|
34945
35110
|
var POLL_INTERVAL_MS = 5e3;
|
|
34946
35111
|
var MAX_WAIT_SECONDS = 120;
|
|
34947
|
-
var FindInput =
|
|
35112
|
+
var FindInput = z141.object({
|
|
34948
35113
|
targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
|
|
34949
35114
|
categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
|
|
34950
|
-
confirmed:
|
|
34951
|
-
waitSeconds:
|
|
35115
|
+
confirmed: z141.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
|
|
35116
|
+
waitSeconds: z141.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
|
|
34952
35117
|
});
|
|
34953
|
-
var GetInput =
|
|
34954
|
-
runId:
|
|
35118
|
+
var GetInput = z141.object({
|
|
35119
|
+
runId: z141.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
34955
35120
|
});
|
|
34956
|
-
var ListInput =
|
|
34957
|
-
limit:
|
|
35121
|
+
var ListInput = z141.object({
|
|
35122
|
+
limit: z141.number().int().min(1).max(20).default(10)
|
|
34958
35123
|
});
|
|
34959
|
-
function textResult(
|
|
35124
|
+
function textResult(text4) {
|
|
34960
35125
|
return {
|
|
34961
35126
|
content: [
|
|
34962
35127
|
{
|
|
34963
35128
|
type: "text",
|
|
34964
|
-
text:
|
|
35129
|
+
text: text4
|
|
34965
35130
|
}
|
|
34966
35131
|
]
|
|
34967
35132
|
};
|
|
34968
35133
|
}
|
|
34969
35134
|
__name(textResult, "textResult");
|
|
34970
|
-
function researchResult(run,
|
|
35135
|
+
function researchResult(run, text4) {
|
|
34971
35136
|
return {
|
|
34972
35137
|
content: [
|
|
34973
35138
|
{
|
|
34974
35139
|
type: "text",
|
|
34975
|
-
text:
|
|
35140
|
+
text: text4
|
|
34976
35141
|
}
|
|
34977
35142
|
],
|
|
34978
35143
|
structuredContent: run
|
|
@@ -35093,17 +35258,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
35093
35258
|
__name(registerProductResearchTools, "registerProductResearchTools");
|
|
35094
35259
|
|
|
35095
35260
|
// src/tools/dropshipping-projects.ts
|
|
35096
|
-
import { z as
|
|
35261
|
+
import { z as z142 } from "zod";
|
|
35097
35262
|
var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
|
|
35098
35263
|
var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
|
|
35099
35264
|
var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
|
|
35100
|
-
var ProjectId =
|
|
35101
|
-
var DropshippingProjectStatus =
|
|
35265
|
+
var ProjectId = z142.string().uuid();
|
|
35266
|
+
var DropshippingProjectStatus = z142.enum([
|
|
35102
35267
|
"active",
|
|
35103
35268
|
"completed",
|
|
35104
35269
|
"archived"
|
|
35105
35270
|
]);
|
|
35106
|
-
var DropshippingProjectPhase =
|
|
35271
|
+
var DropshippingProjectPhase = z142.enum([
|
|
35107
35272
|
"research",
|
|
35108
35273
|
"costing",
|
|
35109
35274
|
"media",
|
|
@@ -35112,21 +35277,21 @@ var DropshippingProjectPhase = z141.enum([
|
|
|
35112
35277
|
"advertising",
|
|
35113
35278
|
"complete"
|
|
35114
35279
|
]);
|
|
35115
|
-
var DropshippingRewardMilestone =
|
|
35280
|
+
var DropshippingRewardMilestone = z142.enum([
|
|
35116
35281
|
"product_selected",
|
|
35117
35282
|
"costing_saved",
|
|
35118
35283
|
"product_media_ready",
|
|
35119
35284
|
"creatives_completed",
|
|
35120
35285
|
"campaign_created"
|
|
35121
35286
|
]);
|
|
35122
|
-
var TargetCountry =
|
|
35287
|
+
var TargetCountry = z142.enum([
|
|
35123
35288
|
"CO",
|
|
35124
35289
|
"MX",
|
|
35125
35290
|
"PE",
|
|
35126
35291
|
"EC",
|
|
35127
35292
|
"CL"
|
|
35128
35293
|
]);
|
|
35129
|
-
var ResearchCategory =
|
|
35294
|
+
var ResearchCategory = z142.enum([
|
|
35130
35295
|
"auto",
|
|
35131
35296
|
"automotive",
|
|
35132
35297
|
"kitchen",
|
|
@@ -35141,7 +35306,7 @@ var ResearchCategory = z141.enum([
|
|
|
35141
35306
|
"garden",
|
|
35142
35307
|
"cleaning"
|
|
35143
35308
|
]);
|
|
35144
|
-
var HttpUrl3 =
|
|
35309
|
+
var HttpUrl3 = z142.string().url().max(2e3).refine((value) => {
|
|
35145
35310
|
try {
|
|
35146
35311
|
return [
|
|
35147
35312
|
"http:",
|
|
@@ -35151,45 +35316,45 @@ var HttpUrl3 = z141.string().url().max(2e3).refine((value) => {
|
|
|
35151
35316
|
return false;
|
|
35152
35317
|
}
|
|
35153
35318
|
}, "URL must use HTTP(S)");
|
|
35154
|
-
var ResearchCandidateOrigin =
|
|
35155
|
-
type:
|
|
35319
|
+
var ResearchCandidateOrigin = z142.object({
|
|
35320
|
+
type: z142.literal("research_candidate"),
|
|
35156
35321
|
runId: ProjectId,
|
|
35157
|
-
candidateSourceId:
|
|
35322
|
+
candidateSourceId: z142.string().min(1).max(160)
|
|
35158
35323
|
});
|
|
35159
|
-
var TaskOrigin =
|
|
35160
|
-
type:
|
|
35324
|
+
var TaskOrigin = z142.object({
|
|
35325
|
+
type: z142.literal("task"),
|
|
35161
35326
|
taskId: ProjectId
|
|
35162
35327
|
});
|
|
35163
|
-
var ManualOrigin =
|
|
35164
|
-
type:
|
|
35328
|
+
var ManualOrigin = z142.object({
|
|
35329
|
+
type: z142.literal("manual"),
|
|
35165
35330
|
clientRequestId: ProjectId,
|
|
35166
|
-
country:
|
|
35331
|
+
country: z142.string().min(2).max(3).optional()
|
|
35167
35332
|
});
|
|
35168
|
-
var StartProjectInput =
|
|
35169
|
-
origin:
|
|
35333
|
+
var StartProjectInput = z142.object({
|
|
35334
|
+
origin: z142.discriminatedUnion("type", [
|
|
35170
35335
|
ResearchCandidateOrigin,
|
|
35171
35336
|
TaskOrigin,
|
|
35172
35337
|
ManualOrigin
|
|
35173
35338
|
]),
|
|
35174
|
-
productName:
|
|
35339
|
+
productName: z142.string().trim().min(1).max(240).optional(),
|
|
35175
35340
|
productUrl: HttpUrl3.optional(),
|
|
35176
|
-
country:
|
|
35177
|
-
languageCode:
|
|
35341
|
+
country: z142.string().min(2).max(3).optional(),
|
|
35342
|
+
languageCode: z142.string().min(2).max(16).optional()
|
|
35178
35343
|
}).strict();
|
|
35179
|
-
var CostProjectInput =
|
|
35344
|
+
var CostProjectInput = z142.object({
|
|
35180
35345
|
projectId: ProjectId,
|
|
35181
|
-
version:
|
|
35182
|
-
country:
|
|
35346
|
+
version: z142.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
|
|
35347
|
+
country: z142.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
35183
35348
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
35184
35349
|
}).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
|
|
35185
|
-
supplierCost:
|
|
35186
|
-
shippingCost:
|
|
35187
|
-
returnRate:
|
|
35188
|
-
cancellationRate:
|
|
35189
|
-
adsManagerCpa:
|
|
35190
|
-
desiredMargin:
|
|
35191
|
-
});
|
|
35192
|
-
var GuideInput =
|
|
35350
|
+
supplierCost: z142.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."),
|
|
35351
|
+
shippingCost: z142.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
|
|
35352
|
+
returnRate: z142.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."),
|
|
35353
|
+
cancellationRate: z142.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."),
|
|
35354
|
+
adsManagerCpa: z142.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
35355
|
+
desiredMargin: z142.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
|
|
35356
|
+
});
|
|
35357
|
+
var GuideInput = z142.object({
|
|
35193
35358
|
projectId: ProjectId.optional()
|
|
35194
35359
|
}).strict();
|
|
35195
35360
|
var NEXT_ACTION_KINDS = [
|
|
@@ -35207,29 +35372,29 @@ var NEXT_ACTION_KINDS = [
|
|
|
35207
35372
|
"repair_meta_campaign",
|
|
35208
35373
|
"review_paused_campaign"
|
|
35209
35374
|
];
|
|
35210
|
-
var DropshippingProjectNextAction =
|
|
35211
|
-
kind:
|
|
35212
|
-
href:
|
|
35375
|
+
var DropshippingProjectNextAction = z142.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z142.object({
|
|
35376
|
+
kind: z142.literal(kind),
|
|
35377
|
+
href: z142.string().min(1)
|
|
35213
35378
|
})));
|
|
35214
|
-
var CostingInputSchema =
|
|
35215
|
-
country:
|
|
35216
|
-
supplierCost:
|
|
35217
|
-
shippingCost:
|
|
35218
|
-
returnRate:
|
|
35219
|
-
cancellationRate:
|
|
35220
|
-
adsManagerCpa:
|
|
35221
|
-
desiredMargin:
|
|
35379
|
+
var CostingInputSchema = z142.object({
|
|
35380
|
+
country: z142.string().min(2).max(3),
|
|
35381
|
+
supplierCost: z142.number().finite().positive(),
|
|
35382
|
+
shippingCost: z142.number().finite().nonnegative(),
|
|
35383
|
+
returnRate: z142.number().finite().min(0).lt(1),
|
|
35384
|
+
cancellationRate: z142.number().finite().min(0).lt(1),
|
|
35385
|
+
adsManagerCpa: z142.number().finite().nonnegative(),
|
|
35386
|
+
desiredMargin: z142.number().finite().min(0).lt(1)
|
|
35222
35387
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
35223
35388
|
if (returnRate + cancellationRate >= 1) context.addIssue({
|
|
35224
|
-
code:
|
|
35389
|
+
code: z142.ZodIssueCode.custom,
|
|
35225
35390
|
path: [
|
|
35226
35391
|
"cancellationRate"
|
|
35227
35392
|
]
|
|
35228
35393
|
});
|
|
35229
35394
|
});
|
|
35230
|
-
var FiniteCostingNumber =
|
|
35231
|
-
var CostingResultSchema =
|
|
35232
|
-
country:
|
|
35395
|
+
var FiniteCostingNumber = z142.number().finite();
|
|
35396
|
+
var CostingResultSchema = z142.object({
|
|
35397
|
+
country: z142.string().min(2).max(3),
|
|
35233
35398
|
deliveryRate: FiniteCostingNumber,
|
|
35234
35399
|
adjustedShippingCost: FiniteCostingNumber,
|
|
35235
35400
|
adjustedCpa: FiniteCostingNumber,
|
|
@@ -35242,45 +35407,45 @@ var CostingResultSchema = z141.object({
|
|
|
35242
35407
|
estimatedProfit: FiniteCostingNumber,
|
|
35243
35408
|
actualMargin: FiniteCostingNumber,
|
|
35244
35409
|
breakEvenAdsManagerCpa: FiniteCostingNumber,
|
|
35245
|
-
wasPriceAutoAdjusted:
|
|
35246
|
-
profitabilityStatus:
|
|
35247
|
-
});
|
|
35248
|
-
var RewardProgressSchema =
|
|
35249
|
-
campaignKey:
|
|
35250
|
-
totalCredits:
|
|
35251
|
-
earnedCredits:
|
|
35252
|
-
milestones:
|
|
35410
|
+
wasPriceAutoAdjusted: z142.boolean(),
|
|
35411
|
+
profitabilityStatus: z142.literal("healthy")
|
|
35412
|
+
});
|
|
35413
|
+
var RewardProgressSchema = z142.object({
|
|
35414
|
+
campaignKey: z142.literal("dropshipping-launch-v1"),
|
|
35415
|
+
totalCredits: z142.number().int().positive(),
|
|
35416
|
+
earnedCredits: z142.number().int().nonnegative(),
|
|
35417
|
+
milestones: z142.array(z142.object({
|
|
35253
35418
|
milestone: DropshippingRewardMilestone,
|
|
35254
|
-
credits:
|
|
35255
|
-
available:
|
|
35256
|
-
earned:
|
|
35419
|
+
credits: z142.number().int().positive(),
|
|
35420
|
+
available: z142.boolean().optional(),
|
|
35421
|
+
earned: z142.boolean(),
|
|
35257
35422
|
grantId: ProjectId.nullable(),
|
|
35258
|
-
grantedAt:
|
|
35423
|
+
grantedAt: z142.string().datetime().nullable()
|
|
35259
35424
|
})).length(DropshippingRewardMilestone.options.length)
|
|
35260
35425
|
});
|
|
35261
|
-
var ProjectResponseSchema =
|
|
35426
|
+
var ProjectResponseSchema = z142.object({
|
|
35262
35427
|
id: ProjectId,
|
|
35263
35428
|
taskId: ProjectId.nullable(),
|
|
35264
35429
|
status: DropshippingProjectStatus,
|
|
35265
|
-
originKey:
|
|
35430
|
+
originKey: z142.string().min(1),
|
|
35266
35431
|
researchRunId: ProjectId.nullable(),
|
|
35267
|
-
candidateSourceId:
|
|
35268
|
-
productName:
|
|
35432
|
+
candidateSourceId: z142.string().nullable(),
|
|
35433
|
+
productName: z142.string().nullable(),
|
|
35269
35434
|
productUrl: HttpUrl3.nullable(),
|
|
35270
35435
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
35271
|
-
targetCountry:
|
|
35272
|
-
languageCode:
|
|
35273
|
-
hasReferenceImage:
|
|
35274
|
-
hasWinnerReferenceImage:
|
|
35436
|
+
targetCountry: z142.string().nullable(),
|
|
35437
|
+
languageCode: z142.string().nullable(),
|
|
35438
|
+
hasReferenceImage: z142.boolean(),
|
|
35439
|
+
hasWinnerReferenceImage: z142.boolean(),
|
|
35275
35440
|
costingInput: CostingInputSchema.nullable(),
|
|
35276
35441
|
costingResult: CostingResultSchema.nullable(),
|
|
35277
|
-
costingVersion:
|
|
35278
|
-
version:
|
|
35442
|
+
costingVersion: z142.number().int().positive().nullable(),
|
|
35443
|
+
version: z142.number().int().positive(),
|
|
35279
35444
|
phase: DropshippingProjectPhase,
|
|
35280
35445
|
nextAction: DropshippingProjectNextAction.nullable(),
|
|
35281
35446
|
rewards: RewardProgressSchema,
|
|
35282
|
-
createdAt:
|
|
35283
|
-
updatedAt:
|
|
35447
|
+
createdAt: z142.string().datetime(),
|
|
35448
|
+
updatedAt: z142.string().datetime()
|
|
35284
35449
|
}).passthrough();
|
|
35285
35450
|
var NEXT_ACTION_GUIDANCE = {
|
|
35286
35451
|
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.",
|
|
@@ -35400,58 +35565,58 @@ function registerDropshippingProjectTools(server, api) {
|
|
|
35400
35565
|
__name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
|
|
35401
35566
|
|
|
35402
35567
|
// src/tools/daily-control.ts
|
|
35403
|
-
import { z as
|
|
35568
|
+
import { z as z143 } from "zod";
|
|
35404
35569
|
var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
|
|
35405
35570
|
var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
|
|
35406
35571
|
var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
|
|
35407
|
-
var ProviderCampaignIdentifier =
|
|
35408
|
-
var DateOnly =
|
|
35409
|
-
var DailyControlInput =
|
|
35572
|
+
var ProviderCampaignIdentifier = z143.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
|
|
35573
|
+
var DateOnly = z143.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
35574
|
+
var DailyControlInput = z143.object({
|
|
35410
35575
|
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."),
|
|
35411
|
-
days:
|
|
35412
|
-
projectId:
|
|
35576
|
+
days: z143.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
35577
|
+
projectId: z143.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
|
|
35413
35578
|
}).strict();
|
|
35414
|
-
var LinkCampaignInput =
|
|
35415
|
-
projectId:
|
|
35416
|
-
provider:
|
|
35579
|
+
var LinkCampaignInput = z143.object({
|
|
35580
|
+
projectId: z143.string().uuid(),
|
|
35581
|
+
provider: z143.enum([
|
|
35417
35582
|
"meta",
|
|
35418
35583
|
"tiktok"
|
|
35419
35584
|
]),
|
|
35420
35585
|
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."),
|
|
35421
35586
|
campaignId: ProviderCampaignIdentifier
|
|
35422
35587
|
}).strict();
|
|
35423
|
-
var ReportReturnsInput =
|
|
35424
|
-
projectId:
|
|
35588
|
+
var ReportReturnsInput = z143.object({
|
|
35589
|
+
projectId: z143.string().uuid(),
|
|
35425
35590
|
date: DateOnly,
|
|
35426
|
-
returnedOrders:
|
|
35427
|
-
note:
|
|
35428
|
-
}).strict();
|
|
35429
|
-
var DailyControlStatusMirror = DailyControlStatusEnum.or(
|
|
35430
|
-
var DailyControlLightMirror = DailyControlLightEnum.or(
|
|
35431
|
-
var DailyControlSourceMirror = DailyControlSourceEnum.or(
|
|
35432
|
-
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(
|
|
35433
|
-
var DailyControlDayMirror =
|
|
35434
|
-
date:
|
|
35435
|
-
returnedOrders:
|
|
35591
|
+
returnedOrders: z143.number().int().min(0).max(1e5),
|
|
35592
|
+
note: z143.string().trim().max(280).optional()
|
|
35593
|
+
}).strict();
|
|
35594
|
+
var DailyControlStatusMirror = DailyControlStatusEnum.or(z143.string());
|
|
35595
|
+
var DailyControlLightMirror = DailyControlLightEnum.or(z143.string());
|
|
35596
|
+
var DailyControlSourceMirror = DailyControlSourceEnum.or(z143.string());
|
|
35597
|
+
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z143.string());
|
|
35598
|
+
var DailyControlDayMirror = z143.object({
|
|
35599
|
+
date: z143.string(),
|
|
35600
|
+
returnedOrders: z143.number(),
|
|
35436
35601
|
returnedSource: DailyControlSourceMirror,
|
|
35437
35602
|
cancelledSource: DailyControlSourceMirror,
|
|
35438
|
-
hasEstimates:
|
|
35603
|
+
hasEstimates: z143.boolean(),
|
|
35439
35604
|
light: DailyControlLightMirror
|
|
35440
35605
|
}).passthrough();
|
|
35441
|
-
var DailyControlProductMirror =
|
|
35442
|
-
projectId:
|
|
35443
|
-
productName:
|
|
35606
|
+
var DailyControlProductMirror = z143.object({
|
|
35607
|
+
projectId: z143.string().uuid(),
|
|
35608
|
+
productName: z143.string().nullable(),
|
|
35444
35609
|
status: DailyControlStatusMirror,
|
|
35445
|
-
statusMessage:
|
|
35446
|
-
days:
|
|
35610
|
+
statusMessage: z143.string().nullable(),
|
|
35611
|
+
days: z143.array(DailyControlDayMirror),
|
|
35447
35612
|
verdict: DailyControlVerdictMirror.nullable(),
|
|
35448
|
-
rationale:
|
|
35613
|
+
rationale: z143.string().nullable()
|
|
35449
35614
|
}).passthrough();
|
|
35450
|
-
var DailyControlResponseMirror =
|
|
35451
|
-
since:
|
|
35452
|
-
until:
|
|
35453
|
-
products:
|
|
35454
|
-
archivedProjectSpend:
|
|
35615
|
+
var DailyControlResponseMirror = z143.object({
|
|
35616
|
+
since: z143.string(),
|
|
35617
|
+
until: z143.string(),
|
|
35618
|
+
products: z143.array(DailyControlProductMirror),
|
|
35619
|
+
archivedProjectSpend: z143.array(z143.unknown())
|
|
35455
35620
|
}).passthrough();
|
|
35456
35621
|
var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
|
|
35457
35622
|
function withWarnings(response) {
|
|
@@ -35526,7 +35691,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
|
|
|
35526
35691
|
// src/tools/product-control.ts
|
|
35527
35692
|
import { readFile, stat } from "fs/promises";
|
|
35528
35693
|
import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
|
|
35529
|
-
import { z as
|
|
35694
|
+
import { z as z144 } from "zod";
|
|
35530
35695
|
var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
|
|
35531
35696
|
var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
|
|
35532
35697
|
var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
|
|
@@ -35539,36 +35704,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
|
|
|
35539
35704
|
var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
|
|
35540
35705
|
var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
|
|
35541
35706
|
var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
|
|
35542
|
-
var DateOnly2 =
|
|
35707
|
+
var DateOnly2 = z144.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
35543
35708
|
var IMPORT_BATCH_MAX2 = 50;
|
|
35544
|
-
var ProductControlListInput =
|
|
35545
|
-
days:
|
|
35709
|
+
var ProductControlListInput = z144.object({
|
|
35710
|
+
days: z144.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
35546
35711
|
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."),
|
|
35547
|
-
shopDomain:
|
|
35712
|
+
shopDomain: z144.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
35548
35713
|
}).strict();
|
|
35549
|
-
var ImportableProductsInput =
|
|
35550
|
-
q:
|
|
35551
|
-
after:
|
|
35552
|
-
shopDomain:
|
|
35714
|
+
var ImportableProductsInput = z144.object({
|
|
35715
|
+
q: z144.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
|
|
35716
|
+
after: z144.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
|
|
35717
|
+
shopDomain: z144.string().min(1).optional()
|
|
35553
35718
|
}).strict();
|
|
35554
|
-
var ImportProductControlsInput =
|
|
35555
|
-
shopifyProductIds:
|
|
35719
|
+
var ImportProductControlsInput = z144.object({
|
|
35720
|
+
shopifyProductIds: z144.array(z144.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."),
|
|
35556
35721
|
// Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
|
|
35557
35722
|
// sin decir a cuál archivaría el producto bajo la tienda equivocada.
|
|
35558
|
-
shopDomain:
|
|
35559
|
-
}).strict();
|
|
35560
|
-
var SetProductCostingInput =
|
|
35561
|
-
shopDomain:
|
|
35562
|
-
shopifyProductId:
|
|
35563
|
-
targetCountry:
|
|
35564
|
-
supplierCost:
|
|
35565
|
-
shippingCost:
|
|
35566
|
-
returnRate:
|
|
35567
|
-
cancellationRate:
|
|
35568
|
-
}).strict();
|
|
35569
|
-
var Count =
|
|
35570
|
-
var ReportProductCountsInput =
|
|
35571
|
-
productControlId:
|
|
35723
|
+
shopDomain: z144.string().min(1)
|
|
35724
|
+
}).strict();
|
|
35725
|
+
var SetProductCostingInput = z144.object({
|
|
35726
|
+
shopDomain: z144.string().min(1),
|
|
35727
|
+
shopifyProductId: z144.string().min(1).max(64),
|
|
35728
|
+
targetCountry: z144.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
|
|
35729
|
+
supplierCost: z144.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
|
|
35730
|
+
shippingCost: z144.number().finite().nonnegative(),
|
|
35731
|
+
returnRate: z144.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
|
|
35732
|
+
cancellationRate: z144.number().finite().min(0).lt(1)
|
|
35733
|
+
}).strict();
|
|
35734
|
+
var Count = z144.number().int().min(0).max(1e5).nullable().optional();
|
|
35735
|
+
var ReportProductCountsInput = z144.object({
|
|
35736
|
+
productControlId: z144.string().uuid().describe("El identificador que devuelve get_product_control."),
|
|
35572
35737
|
date: DateOnly2,
|
|
35573
35738
|
orders: Count.describe("Pedidos que entraron ese d\xEDa."),
|
|
35574
35739
|
cancelledOrders: Count,
|
|
@@ -35578,36 +35743,36 @@ var ReportProductCountsInput = z143.object({
|
|
|
35578
35743
|
}).strict();
|
|
35579
35744
|
var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
|
|
35580
35745
|
var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
|
|
35581
|
-
var ImportOrdersFileInput =
|
|
35746
|
+
var ImportOrdersFileInput = z144.object({
|
|
35582
35747
|
/** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
|
|
35583
|
-
path:
|
|
35584
|
-
operationId:
|
|
35748
|
+
path: z144.string().min(1),
|
|
35749
|
+
operationId: z144.string().uuid().optional(),
|
|
35585
35750
|
/** Solo mirar: devuelve el resumen y no escribe nada. */
|
|
35586
|
-
dryRun:
|
|
35751
|
+
dryRun: z144.boolean().optional()
|
|
35587
35752
|
}).strict();
|
|
35588
|
-
var CreateOperationInput =
|
|
35589
|
-
countryCode:
|
|
35590
|
-
label:
|
|
35753
|
+
var CreateOperationInput = z144.object({
|
|
35754
|
+
countryCode: z144.string().length(2),
|
|
35755
|
+
label: z144.string().trim().min(1).max(60).optional()
|
|
35591
35756
|
}).strict();
|
|
35592
|
-
var MergeProductsInput =
|
|
35593
|
-
sourceId:
|
|
35594
|
-
targetId:
|
|
35757
|
+
var MergeProductsInput = z144.object({
|
|
35758
|
+
sourceId: z144.string().uuid(),
|
|
35759
|
+
targetId: z144.string().uuid()
|
|
35595
35760
|
}).strict();
|
|
35596
|
-
var SetMonthlyExpenseInput =
|
|
35597
|
-
month:
|
|
35761
|
+
var SetMonthlyExpenseInput = z144.object({
|
|
35762
|
+
month: z144.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
35598
35763
|
label: SaveMonthlyExpenseSchema.shape.label,
|
|
35599
|
-
amount:
|
|
35600
|
-
operationId:
|
|
35764
|
+
amount: z144.number().finite().min(0),
|
|
35765
|
+
operationId: z144.string().uuid().optional()
|
|
35601
35766
|
}).strict();
|
|
35602
|
-
var SetAdSpendInput =
|
|
35603
|
-
month:
|
|
35604
|
-
operationId:
|
|
35767
|
+
var SetAdSpendInput = z144.object({
|
|
35768
|
+
month: z144.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
35769
|
+
operationId: z144.string().uuid().optional(),
|
|
35605
35770
|
/** null RETIRA la corrección; cero afirma que no pautó. */
|
|
35606
|
-
amount:
|
|
35771
|
+
amount: z144.number().finite().min(0).nullable()
|
|
35607
35772
|
}).strict();
|
|
35608
|
-
var GetFinancesInput =
|
|
35609
|
-
month:
|
|
35610
|
-
operationId:
|
|
35773
|
+
var GetFinancesInput = z144.object({
|
|
35774
|
+
month: z144.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional().describe("Mes en YYYY-MM. Si se omite, el mes en curso. Solo mes calendario."),
|
|
35775
|
+
operationId: z144.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
|
|
35611
35776
|
}).strict();
|
|
35612
35777
|
function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
35613
35778
|
server.registerTool("get_product_control", {
|
|
@@ -35799,28 +35964,28 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
|
35799
35964
|
__name(registerProductControlTools, "registerProductControlTools");
|
|
35800
35965
|
|
|
35801
35966
|
// src/tools/market-study-estimate.ts
|
|
35802
|
-
import { z as
|
|
35967
|
+
import { z as z145 } from "zod";
|
|
35803
35968
|
var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
|
|
35804
|
-
var ProductTaskOutputEnum =
|
|
35969
|
+
var ProductTaskOutputEnum = z145.enum([
|
|
35805
35970
|
"landing",
|
|
35806
35971
|
"video",
|
|
35807
35972
|
"image"
|
|
35808
35973
|
]);
|
|
35809
|
-
var EstimateMarketStudyInput =
|
|
35810
|
-
kind:
|
|
35974
|
+
var EstimateMarketStudyInput = z145.object({
|
|
35975
|
+
kind: z145.enum([
|
|
35811
35976
|
"video",
|
|
35812
35977
|
"product_task"
|
|
35813
35978
|
]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
|
|
35814
|
-
videoAngleCount:
|
|
35815
|
-
durationSeconds:
|
|
35979
|
+
videoAngleCount: z145.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
|
|
35980
|
+
durationSeconds: z145.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
|
|
35816
35981
|
videoStructure: VideoStructureEnum.default("single_take"),
|
|
35817
35982
|
videoQuality: VideoQualityEnum.default("economy"),
|
|
35818
35983
|
videoResolution: VideoResolutionEnum.default("480p"),
|
|
35819
|
-
productImageCount:
|
|
35984
|
+
productImageCount: z145.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
|
|
35820
35985
|
outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
|
|
35821
|
-
generateAiMusic:
|
|
35986
|
+
generateAiMusic: z145.boolean().optional(),
|
|
35822
35987
|
generateAiEdit: AiEditRequestSchema.optional(),
|
|
35823
|
-
replicateWinnerWhenFound:
|
|
35988
|
+
replicateWinnerWhenFound: z145.boolean().optional().describe("La misma preferencia que enviar\xE1s al crear. false excluye la reserva de r\xE9plica del ganador de la cotizaci\xF3n con estudio.")
|
|
35824
35989
|
}).strict();
|
|
35825
35990
|
function buildMarketStudyEstimateRequests(input) {
|
|
35826
35991
|
const quotesVideo = input.kind === "video" || (input.outputs ?? [
|