@productmaker/mcp 11.3.2 → 11.3.3
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 +4 -0
- package/dist/http.js +925 -742
- package/dist/stdio.js +914 -731
- package/package.json +1 -1
package/dist/http.js
CHANGED
|
@@ -21600,8 +21600,33 @@ var ServicePageGenerateRequestSchema = z100.object({
|
|
|
21600
21600
|
instruction: ServicePageEditInstructionSchema.optional(),
|
|
21601
21601
|
attachmentRefs: ServicePageAttachmentRefsSchema.optional()
|
|
21602
21602
|
}).strict();
|
|
21603
|
+
var SERVICE_PAGE_CREATION_MAX_ATTEMPTS = 3;
|
|
21604
|
+
var ServicePageCreationMarkerSchema = z100.object({
|
|
21605
|
+
rootOperationId: z100.string().uuid().optional(),
|
|
21606
|
+
attempt: z100.number().int().min(1).max(SERVICE_PAGE_CREATION_MAX_ATTEMPTS)
|
|
21607
|
+
}).strict();
|
|
21608
|
+
var ServicePageCreationEstimateRequestSchema = z100.object({
|
|
21609
|
+
textCharacters: z100.number().int().min(0).max(1e6),
|
|
21610
|
+
documentBytes: z100.number().int().min(0).max(1e8),
|
|
21611
|
+
imageCount: z100.number().int().min(0).max(50),
|
|
21612
|
+
instagram: z100.boolean()
|
|
21613
|
+
}).strict();
|
|
21614
|
+
var ServicePageCreationEstimateResponseSchema = z100.object({
|
|
21615
|
+
estimatedMinCostCredits: z100.number().int().nonnegative(),
|
|
21616
|
+
estimatedMaxCostCredits: z100.number().int().nonnegative()
|
|
21617
|
+
}).strict();
|
|
21618
|
+
var ServicePageCreationStatusSchema = z100.object({
|
|
21619
|
+
status: z100.enum([
|
|
21620
|
+
"idle",
|
|
21621
|
+
"running",
|
|
21622
|
+
"failed"
|
|
21623
|
+
]),
|
|
21624
|
+
errorCode: z100.string().max(64).optional()
|
|
21625
|
+
}).strict();
|
|
21603
21626
|
var ServicePageFactExtractionRequestSchema = ServicePageGenerateRequestSchema.omit({
|
|
21604
21627
|
instruction: true
|
|
21628
|
+
}).extend({
|
|
21629
|
+
continueWith: z100.literal("generation").optional()
|
|
21605
21630
|
});
|
|
21606
21631
|
var ServicePageOperationStatusSchema = z100.enum([
|
|
21607
21632
|
"queued",
|
|
@@ -22246,6 +22271,159 @@ var WebsiteCaptureResearchSchema = z107.object({
|
|
|
22246
22271
|
})
|
|
22247
22272
|
});
|
|
22248
22273
|
|
|
22274
|
+
// ../../packages/types/src/demo-mode.ts
|
|
22275
|
+
import { z as z108 } from "zod";
|
|
22276
|
+
var DEMO_MODE_FLOWS = [
|
|
22277
|
+
"brand",
|
|
22278
|
+
"servicePage",
|
|
22279
|
+
"motion",
|
|
22280
|
+
"image"
|
|
22281
|
+
];
|
|
22282
|
+
var DemoModeFlowSchema = z108.enum(DEMO_MODE_FLOWS);
|
|
22283
|
+
var DEMO_MODE_STEPS = [
|
|
22284
|
+
"running",
|
|
22285
|
+
"research",
|
|
22286
|
+
"design",
|
|
22287
|
+
"render_0",
|
|
22288
|
+
"render_33",
|
|
22289
|
+
"render_66",
|
|
22290
|
+
"render_100",
|
|
22291
|
+
"review",
|
|
22292
|
+
"final",
|
|
22293
|
+
"watchdog"
|
|
22294
|
+
];
|
|
22295
|
+
var DemoModeStepSchema = z108.enum(DEMO_MODE_STEPS);
|
|
22296
|
+
var DEMO_MODE_WAIT_SECONDS = {
|
|
22297
|
+
min: 30,
|
|
22298
|
+
max: 450,
|
|
22299
|
+
default: 150
|
|
22300
|
+
};
|
|
22301
|
+
var centsSchema = z108.number().int().min(0).max(1e5);
|
|
22302
|
+
var emailSchema = z108.string().trim().toLowerCase().email();
|
|
22303
|
+
var DemoModeTemplatesSchema = z108.object({
|
|
22304
|
+
brandId: z108.string().uuid(),
|
|
22305
|
+
servicePageId: z108.string().uuid(),
|
|
22306
|
+
motionTaskId: z108.string().uuid(),
|
|
22307
|
+
imageTaskId: z108.string().uuid()
|
|
22308
|
+
});
|
|
22309
|
+
var DemoModeEditableSchema = z108.object({
|
|
22310
|
+
enabled: z108.boolean(),
|
|
22311
|
+
emails: z108.array(emailSchema).max(50).transform((list) => [
|
|
22312
|
+
...new Set(list)
|
|
22313
|
+
]),
|
|
22314
|
+
waitSeconds: z108.number().int().min(DEMO_MODE_WAIT_SECONDS.min).max(DEMO_MODE_WAIT_SECONDS.max),
|
|
22315
|
+
chargeCents: z108.object({
|
|
22316
|
+
brand: centsSchema,
|
|
22317
|
+
servicePage: centsSchema,
|
|
22318
|
+
motion: centsSchema,
|
|
22319
|
+
image: centsSchema
|
|
22320
|
+
}),
|
|
22321
|
+
templates: DemoModeTemplatesSchema
|
|
22322
|
+
});
|
|
22323
|
+
var nullableString = z108.string().nullable();
|
|
22324
|
+
var DemoModeSnapshotSchema = z108.object({
|
|
22325
|
+
brand: z108.object({
|
|
22326
|
+
/** Columnas de identidad de `Brand` listas para un `update` (sin id/userId/slug/estado/fechas). */
|
|
22327
|
+
identity: z108.record(z108.unknown()),
|
|
22328
|
+
productSamples: z108.array(z108.object({
|
|
22329
|
+
name: z108.string(),
|
|
22330
|
+
priceCents: z108.number().int().nullable(),
|
|
22331
|
+
currency: nullableString,
|
|
22332
|
+
imageKey: z108.string(),
|
|
22333
|
+
productUrl: nullableString,
|
|
22334
|
+
position: z108.number().int()
|
|
22335
|
+
})),
|
|
22336
|
+
personas: z108.array(z108.object({
|
|
22337
|
+
name: z108.string(),
|
|
22338
|
+
demographics: nullableString,
|
|
22339
|
+
painPoints: nullableString,
|
|
22340
|
+
motivations: nullableString,
|
|
22341
|
+
objections: nullableString,
|
|
22342
|
+
gender: nullableString,
|
|
22343
|
+
isDefault: z108.boolean()
|
|
22344
|
+
}))
|
|
22345
|
+
}),
|
|
22346
|
+
servicePage: z108.object({
|
|
22347
|
+
facts: z108.unknown(),
|
|
22348
|
+
review: z108.unknown(),
|
|
22349
|
+
artifact: z108.unknown()
|
|
22350
|
+
}),
|
|
22351
|
+
motion: z108.object({
|
|
22352
|
+
outputs: MotionGraphicsOutputsSchema,
|
|
22353
|
+
/**
|
|
22354
|
+
* La captura REAL de la web de la plantilla (nunca una fabricada por la
|
|
22355
|
+
* demo). Null cuando la plantilla no tiene ninguna: la captura demo nunca
|
|
22356
|
+
* va live, así que el servicio usa `DEMO_MODE_PLACEHOLDER_CAPTURE`.
|
|
22357
|
+
*/
|
|
22358
|
+
capture: z108.object({
|
|
22359
|
+
bundleKey: z108.string(),
|
|
22360
|
+
sha256: z108.string(),
|
|
22361
|
+
uploadBytes: z108.number().int().nullable(),
|
|
22362
|
+
previewKey: nullableString
|
|
22363
|
+
}).nullable()
|
|
22364
|
+
}),
|
|
22365
|
+
image: z108.object({
|
|
22366
|
+
provider: z108.string(),
|
|
22367
|
+
model: z108.string(),
|
|
22368
|
+
prompt: z108.string(),
|
|
22369
|
+
imageUrl: z108.string(),
|
|
22370
|
+
width: z108.number().int(),
|
|
22371
|
+
height: z108.number().int(),
|
|
22372
|
+
adCopy: nullableString,
|
|
22373
|
+
rawResponse: z108.unknown()
|
|
22374
|
+
})
|
|
22375
|
+
});
|
|
22376
|
+
var DemoModeConfigSchema = DemoModeEditableSchema.extend({
|
|
22377
|
+
snapshot: DemoModeSnapshotSchema.nullable(),
|
|
22378
|
+
snapshotAt: z108.string().datetime().nullable()
|
|
22379
|
+
});
|
|
22380
|
+
var DemoModeAdminViewSchema = DemoModeEditableSchema.extend({
|
|
22381
|
+
// Sin configurar, la API devuelve ids vacíos ("" no es uuid): la vista los
|
|
22382
|
+
// admite; el PUT sí exige uuid (`DemoModeEditableSchema`).
|
|
22383
|
+
templates: z108.object({
|
|
22384
|
+
brandId: z108.string(),
|
|
22385
|
+
servicePageId: z108.string(),
|
|
22386
|
+
motionTaskId: z108.string(),
|
|
22387
|
+
imageTaskId: z108.string()
|
|
22388
|
+
}),
|
|
22389
|
+
snapshotAt: z108.string().nullable()
|
|
22390
|
+
});
|
|
22391
|
+
var DEMO_MODE_TEMPLATE_PROBLEMS = [
|
|
22392
|
+
"not_found",
|
|
22393
|
+
"brand_not_ready",
|
|
22394
|
+
"no_artifact",
|
|
22395
|
+
"artifact_invalid",
|
|
22396
|
+
"task_not_done",
|
|
22397
|
+
"no_video",
|
|
22398
|
+
"no_creative"
|
|
22399
|
+
];
|
|
22400
|
+
var DemoModeTemplateVerdictSchema = z108.discriminatedUnion("ok", [
|
|
22401
|
+
z108.object({
|
|
22402
|
+
ok: z108.literal(true)
|
|
22403
|
+
}),
|
|
22404
|
+
z108.object({
|
|
22405
|
+
ok: z108.literal(false),
|
|
22406
|
+
problem: z108.enum(DEMO_MODE_TEMPLATE_PROBLEMS)
|
|
22407
|
+
})
|
|
22408
|
+
]);
|
|
22409
|
+
var DemoModeValidationSchema = z108.object({
|
|
22410
|
+
brandId: DemoModeTemplateVerdictSchema,
|
|
22411
|
+
servicePageId: DemoModeTemplateVerdictSchema,
|
|
22412
|
+
motionTaskId: DemoModeTemplateVerdictSchema,
|
|
22413
|
+
imageTaskId: DemoModeTemplateVerdictSchema
|
|
22414
|
+
});
|
|
22415
|
+
var DemoModeJobSchema = z108.object({
|
|
22416
|
+
flow: DemoModeFlowSchema,
|
|
22417
|
+
step: DemoModeStepSchema,
|
|
22418
|
+
/** brandId | servicePageOperationId | taskId según el flujo. */
|
|
22419
|
+
targetId: z108.string().uuid(),
|
|
22420
|
+
userId: z108.string().min(1),
|
|
22421
|
+
/** Solo marca: la generación de extracción que el guion completa. */
|
|
22422
|
+
generation: z108.number().int().positive().optional(),
|
|
22423
|
+
/** Solo `final`/`watchdog`: la parte del snapshot de ESTE flujo, congelada al empezar. */
|
|
22424
|
+
result: z108.unknown().optional()
|
|
22425
|
+
});
|
|
22426
|
+
|
|
22249
22427
|
// src/http.ts
|
|
22250
22428
|
import express4 from "express";
|
|
22251
22429
|
import rateLimit2 from "express-rate-limit";
|
|
@@ -22755,23 +22933,23 @@ import { InsufficientScopeError, InvalidTokenError } from "@modelcontextprotocol
|
|
|
22755
22933
|
import { createRemoteJWKSet as createRemoteJWKSet2, jwtVerify as jwtVerify2 } from "jose";
|
|
22756
22934
|
|
|
22757
22935
|
// src/auth/oauth-config.ts
|
|
22758
|
-
import { z as
|
|
22936
|
+
import { z as z109 } from "zod";
|
|
22759
22937
|
var MCP_RESOURCE = new URL("https://mcp.productmaker.app/mcp");
|
|
22760
22938
|
var MCP_SCOPE = "mcp:access";
|
|
22761
22939
|
var REFRESH_SCOPE = "offline_access";
|
|
22762
22940
|
var STATIC_CLIENT_ISSUER = new URL(MCP_RESOURCE.origin);
|
|
22763
|
-
var oauthEnvSchema =
|
|
22764
|
-
MCP_REMOTE_AUTH_MODE:
|
|
22765
|
-
MCP_AUTH0_ISSUER:
|
|
22766
|
-
MCP_AUTH0_AUDIENCE:
|
|
22941
|
+
var oauthEnvSchema = z109.object({
|
|
22942
|
+
MCP_REMOTE_AUTH_MODE: z109.literal("oauth"),
|
|
22943
|
+
MCP_AUTH0_ISSUER: z109.string().trim().min(1),
|
|
22944
|
+
MCP_AUTH0_AUDIENCE: z109.string().trim().refine((value) => value === MCP_RESOURCE.href, {
|
|
22767
22945
|
message: `must equal ${MCP_RESOURCE.href}`
|
|
22768
22946
|
}),
|
|
22769
|
-
MCP_AUTH0_CLIENT_ID:
|
|
22770
|
-
MCP_AUTH0_CLIENT_SECRET:
|
|
22771
|
-
PM_API_AUDIENCE:
|
|
22772
|
-
AUTH0_AUDIENCE:
|
|
22773
|
-
MCP_STATIC_CLIENT_ID:
|
|
22774
|
-
MCP_STATIC_CLIENT_SECRET:
|
|
22947
|
+
MCP_AUTH0_CLIENT_ID: z109.string().trim().min(1),
|
|
22948
|
+
MCP_AUTH0_CLIENT_SECRET: z109.string().trim().min(1),
|
|
22949
|
+
PM_API_AUDIENCE: z109.string().trim().min(1),
|
|
22950
|
+
AUTH0_AUDIENCE: z109.string().trim().min(1),
|
|
22951
|
+
MCP_STATIC_CLIENT_ID: z109.string().trim().min(1).optional(),
|
|
22952
|
+
MCP_STATIC_CLIENT_SECRET: z109.string().trim().min(1).optional()
|
|
22775
22953
|
});
|
|
22776
22954
|
function formatZodIssues(error) {
|
|
22777
22955
|
return error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ");
|
|
@@ -23927,7 +24105,7 @@ var ApiClient = class {
|
|
|
23927
24105
|
};
|
|
23928
24106
|
|
|
23929
24107
|
// src/index.ts
|
|
23930
|
-
var MCP_VERSION = "11.3.
|
|
24108
|
+
var MCP_VERSION = "11.3.3";
|
|
23931
24109
|
|
|
23932
24110
|
// src/meta-upload-app.ts
|
|
23933
24111
|
import { readFileSync } from "fs";
|
|
@@ -23999,7 +24177,7 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
|
|
|
23999
24177
|
__name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
|
|
24000
24178
|
|
|
24001
24179
|
// src/tools/tasks.ts
|
|
24002
|
-
import { z as
|
|
24180
|
+
import { z as z114 } from "zod";
|
|
24003
24181
|
|
|
24004
24182
|
// src/resolve-image.ts
|
|
24005
24183
|
import { lookup as dnsLookup } from "dns/promises";
|
|
@@ -24560,9 +24738,9 @@ async function resolveMediaRef(ref, opts) {
|
|
|
24560
24738
|
__name(resolveMediaRef, "resolveMediaRef");
|
|
24561
24739
|
|
|
24562
24740
|
// src/tools/shared.ts
|
|
24563
|
-
import { z as
|
|
24564
|
-
var Lang =
|
|
24565
|
-
var Country =
|
|
24741
|
+
import { z as z110 } from "zod";
|
|
24742
|
+
var Lang = z110.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);
|
|
24743
|
+
var Country = z110.string().min(2).max(3);
|
|
24566
24744
|
var LandingStrategyEnum = LandingStrategySchema;
|
|
24567
24745
|
var LandingImageFormatEnum = LandingImageFormatSchema;
|
|
24568
24746
|
var VideoPresetEnum = VideoPreset.extract([
|
|
@@ -24666,7 +24844,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
|
|
|
24666
24844
|
return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
|
|
24667
24845
|
}
|
|
24668
24846
|
__name(animationStyleApplies, "animationStyleApplies");
|
|
24669
|
-
var VideoTierEnum =
|
|
24847
|
+
var VideoTierEnum = z110.enum([
|
|
24670
24848
|
"basic"
|
|
24671
24849
|
]);
|
|
24672
24850
|
function resolveVideoTier(_tier) {
|
|
@@ -24724,10 +24902,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
|
|
|
24724
24902
|
var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
|
|
24725
24903
|
var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
|
|
24726
24904
|
var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
|
|
24727
|
-
var ImageRefSchema =
|
|
24728
|
-
url:
|
|
24729
|
-
path:
|
|
24730
|
-
assetId:
|
|
24905
|
+
var ImageRefSchema = z110.object({
|
|
24906
|
+
url: z110.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.'),
|
|
24907
|
+
path: z110.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`.'),
|
|
24908
|
+
assetId: z110.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.")
|
|
24731
24909
|
}).refine((v) => [
|
|
24732
24910
|
v.url,
|
|
24733
24911
|
v.path,
|
|
@@ -24735,11 +24913,11 @@ var ImageRefSchema = z109.object({
|
|
|
24735
24913
|
].filter(Boolean).length === 1, {
|
|
24736
24914
|
message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
|
|
24737
24915
|
});
|
|
24738
|
-
var ImagesInput =
|
|
24916
|
+
var ImagesInput = z110.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
|
|
24739
24917
|
const assetCount = images.filter((image) => Boolean(image.assetId)).length;
|
|
24740
24918
|
if (assetCount > 0 && assetCount !== images.length) {
|
|
24741
24919
|
ctx.addIssue({
|
|
24742
|
-
code:
|
|
24920
|
+
code: z110.ZodIssueCode.custom,
|
|
24743
24921
|
message: "all image entries must use assetId, or all must use URL/path sources"
|
|
24744
24922
|
});
|
|
24745
24923
|
}
|
|
@@ -24789,16 +24967,24 @@ async function submitCreative(api, opts) {
|
|
|
24789
24967
|
...img,
|
|
24790
24968
|
filename: `image-${i}.png`
|
|
24791
24969
|
}));
|
|
24792
|
-
const r = await api.postMultipart(
|
|
24793
|
-
|
|
24794
|
-
|
|
24795
|
-
|
|
24796
|
-
|
|
24797
|
-
|
|
24798
|
-
|
|
24799
|
-
|
|
24800
|
-
|
|
24801
|
-
|
|
24970
|
+
const r = await api.postMultipart(
|
|
24971
|
+
opts.path,
|
|
24972
|
+
{
|
|
24973
|
+
images: parts
|
|
24974
|
+
},
|
|
24975
|
+
// assetIds stays an array so postMultipart appends one `assetIds` field per
|
|
24976
|
+
// id: `flatten` would comma-join them into a single non-UUID value and the
|
|
24977
|
+
// API rejects every multi-photo upload with "assetId must be a valid UUID".
|
|
24978
|
+
{
|
|
24979
|
+
...flatten(rest),
|
|
24980
|
+
...assetIds ? {
|
|
24981
|
+
assetIds
|
|
24982
|
+
} : {}
|
|
24983
|
+
},
|
|
24984
|
+
opts.idempotencyKey ? {
|
|
24985
|
+
idempotencyKey: opts.idempotencyKey
|
|
24986
|
+
} : void 0
|
|
24987
|
+
);
|
|
24802
24988
|
const taskId = r.taskId ?? r.jobId;
|
|
24803
24989
|
return asText({
|
|
24804
24990
|
taskId,
|
|
@@ -24812,14 +24998,14 @@ async function submitCreative(api, opts) {
|
|
|
24812
24998
|
});
|
|
24813
24999
|
}
|
|
24814
25000
|
__name(submitCreative, "submitCreative");
|
|
24815
|
-
var ResearchTargetCountryEnum =
|
|
25001
|
+
var ResearchTargetCountryEnum = z110.enum([
|
|
24816
25002
|
"CO",
|
|
24817
25003
|
"MX",
|
|
24818
25004
|
"PE",
|
|
24819
25005
|
"EC",
|
|
24820
25006
|
"CL"
|
|
24821
25007
|
]);
|
|
24822
|
-
var ResearchCategoryEnum =
|
|
25008
|
+
var ResearchCategoryEnum = z110.enum([
|
|
24823
25009
|
"auto",
|
|
24824
25010
|
"automotive",
|
|
24825
25011
|
"kitchen",
|
|
@@ -26131,29 +26317,29 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
|
|
|
26131
26317
|
__name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
|
|
26132
26318
|
|
|
26133
26319
|
// src/tools/media-presentation.ts
|
|
26134
|
-
import { z as
|
|
26135
|
-
var HttpsPresentationUrlSchema =
|
|
26320
|
+
import { z as z111 } from "zod";
|
|
26321
|
+
var HttpsPresentationUrlSchema = z111.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
|
|
26136
26322
|
var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
|
|
26137
26323
|
const hostname = new URL(value).hostname.toLowerCase();
|
|
26138
26324
|
return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
|
|
26139
26325
|
}, "preview URL must be owned by ProductMaker");
|
|
26140
|
-
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) =>
|
|
26141
|
-
var PresentationImageSchema =
|
|
26142
|
-
kind:
|
|
26326
|
+
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z111.number().int().positive().max(maximum), "positiveIntAtMost");
|
|
26327
|
+
var PresentationImageSchema = z111.object({
|
|
26328
|
+
kind: z111.literal("image"),
|
|
26143
26329
|
url: HttpsPresentationUrlSchema,
|
|
26144
|
-
mimeType:
|
|
26330
|
+
mimeType: z111.enum([
|
|
26145
26331
|
"image/jpeg",
|
|
26146
26332
|
"image/png"
|
|
26147
26333
|
]),
|
|
26148
26334
|
byteSize: positiveIntAtMost(5 * 1024 * 1024),
|
|
26149
26335
|
width: positiveIntAtMost(16384),
|
|
26150
26336
|
height: positiveIntAtMost(16384),
|
|
26151
|
-
alt:
|
|
26337
|
+
alt: z111.string().trim().min(1).max(240)
|
|
26152
26338
|
}).strict();
|
|
26153
26339
|
var McpMediaPresentationSchema = PresentationImageSchema;
|
|
26154
|
-
var GalleryImageSchema =
|
|
26340
|
+
var GalleryImageSchema = z111.object({
|
|
26155
26341
|
url: ProductMakerPreviewUrlSchema,
|
|
26156
|
-
alt:
|
|
26342
|
+
alt: z111.string().trim().min(1).max(240)
|
|
26157
26343
|
});
|
|
26158
26344
|
var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
26159
26345
|
async function imageBlocks(image, transport) {
|
|
@@ -26210,12 +26396,12 @@ async function buildMcpMediaPresentationContent(rawPresentation, transport = "ht
|
|
|
26210
26396
|
];
|
|
26211
26397
|
}
|
|
26212
26398
|
__name(buildMcpMediaPresentationContent, "buildMcpMediaPresentationContent");
|
|
26213
|
-
var OwnedImagePreviewSchema =
|
|
26399
|
+
var OwnedImagePreviewSchema = z111.object({
|
|
26214
26400
|
url: HttpsPresentationUrlSchema.refine((value) => {
|
|
26215
26401
|
const url = new URL(value);
|
|
26216
26402
|
return !url.username && !url.password && !isPrivateHost(url.hostname);
|
|
26217
26403
|
}, "Preview URL must be public HTTPS without credentials"),
|
|
26218
|
-
alt:
|
|
26404
|
+
alt: z111.string().trim().min(1).max(240)
|
|
26219
26405
|
});
|
|
26220
26406
|
async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
|
|
26221
26407
|
const preview2 = OwnedImagePreviewSchema.safeParse(rawPreview);
|
|
@@ -26298,7 +26484,7 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
|
|
|
26298
26484
|
__name(buildMcpImageGalleryContent, "buildMcpImageGalleryContent");
|
|
26299
26485
|
|
|
26300
26486
|
// src/tools/animated-video.ts
|
|
26301
|
-
import { z as
|
|
26487
|
+
import { z as z112 } from "zod";
|
|
26302
26488
|
|
|
26303
26489
|
// src/tools/paid-confirmation.ts
|
|
26304
26490
|
function describeMarketStudyChoice(enabled) {
|
|
@@ -26548,27 +26734,27 @@ function hookVariantsLabel(count) {
|
|
|
26548
26734
|
return count === 1 ? "1 versi\xF3n del gancho" : `${count} versiones del gancho`;
|
|
26549
26735
|
}
|
|
26550
26736
|
__name(hookVariantsLabel, "hookVariantsLabel");
|
|
26551
|
-
var DurationInput =
|
|
26552
|
-
var CreateAnimatedVideoInput =
|
|
26553
|
-
action:
|
|
26737
|
+
var DurationInput = z112.union(MOTION_GRAPHICS_DURATIONS.map((d) => z112.literal(d)));
|
|
26738
|
+
var CreateAnimatedVideoInput = z112.object({
|
|
26739
|
+
action: z112.enum([
|
|
26554
26740
|
"prepare",
|
|
26555
26741
|
"status",
|
|
26556
26742
|
"cancel",
|
|
26557
26743
|
"generate"
|
|
26558
26744
|
]).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."),
|
|
26559
|
-
websiteCaptureId:
|
|
26560
|
-
generationRequestId:
|
|
26561
|
-
confirmed:
|
|
26745
|
+
websiteCaptureId: z112.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
|
|
26746
|
+
generationRequestId: z112.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."),
|
|
26747
|
+
confirmed: z112.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."),
|
|
26562
26748
|
// Plain text, not `.url()`: users type «cal.com», and the web accepts it.
|
|
26563
26749
|
// normalizeWebAddress (shared with the web) adds https:// and refuses
|
|
26564
26750
|
// anything that is not a public http(s) address.
|
|
26565
|
-
landingUrl:
|
|
26751
|
+
landingUrl: z112.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."),
|
|
26566
26752
|
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.'),
|
|
26567
26753
|
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.`),
|
|
26568
26754
|
language: MotionGraphicsLanguageSchema.optional().describe('Idioma de los textos del video: "es", "en" o "pt".'),
|
|
26569
|
-
notes:
|
|
26755
|
+
notes: z112.string().trim().max(MOTION_GRAPHICS_NOTES_MAX_CHARS).optional().describe("Opcional. Indicaciones para el video en lenguaje natural (ej. enf\xF3cate en los precios, tono m\xE1s formal, menciona la prueba gratis)."),
|
|
26570
26756
|
hookVariants: MotionGraphicsHookVariantsSchema.optional().describe(`Opcional. Versiones del gancho: el mismo video con distintas aperturas para probar cu\xE1l funciona mejor, de 1 a ${MOTION_GRAPHICS_HOOK_VARIANTS_MAX} (por defecto 1). Cada versi\xF3n extra tiene precio (ver la descripci\xF3n de la herramienta); \xFAsalo solo si el usuario lo pide.`),
|
|
26571
|
-
music:
|
|
26757
|
+
music: z112.boolean().optional().describe("Opcional. M\xFAsica de fondo (por defecto true). false hace el video sin m\xFAsica, m\xE1s crudo, estilo UGC: quedan la voz y los efectos de sonido. Mismo precio. \xDAsalo solo si el usuario lo pide.")
|
|
26572
26758
|
}).strict();
|
|
26573
26759
|
function captureNextAction(capture) {
|
|
26574
26760
|
if (capture.status === "ready") return "Muestra la vista previa al usuario y confirma formato, duraci\xF3n, idioma y precio. Solo despu\xE9s llama create_animated_video con action=generate, este websiteCaptureId y confirmed=true.";
|
|
@@ -26601,43 +26787,43 @@ var FORMAT_LABELS = {
|
|
|
26601
26787
|
square: "cuadrado 1:1",
|
|
26602
26788
|
horizontal: "horizontal 16:9"
|
|
26603
26789
|
};
|
|
26604
|
-
var AnimatedVideoResultSchema =
|
|
26605
|
-
status:
|
|
26790
|
+
var AnimatedVideoResultSchema = z112.object({
|
|
26791
|
+
status: z112.enum([
|
|
26606
26792
|
"pending",
|
|
26607
26793
|
"done",
|
|
26608
26794
|
"error"
|
|
26609
26795
|
]),
|
|
26610
|
-
serviceMode:
|
|
26611
|
-
finalMp4Url:
|
|
26612
|
-
error:
|
|
26613
|
-
motionGraphics:
|
|
26796
|
+
serviceMode: z112.literal("motion_graphics"),
|
|
26797
|
+
finalMp4Url: z112.string().optional(),
|
|
26798
|
+
error: z112.string().optional(),
|
|
26799
|
+
motionGraphics: z112.object({
|
|
26614
26800
|
stage: MotionGraphicsStageSchema,
|
|
26615
26801
|
format: MotionGraphicsFormatSchema,
|
|
26616
|
-
durationSec:
|
|
26617
|
-
width:
|
|
26618
|
-
height:
|
|
26802
|
+
durationSec: z112.number(),
|
|
26803
|
+
width: z112.number().optional(),
|
|
26804
|
+
height: z112.number().optional(),
|
|
26619
26805
|
language: MotionGraphicsLanguageSchema.optional(),
|
|
26620
|
-
queuedAt:
|
|
26621
|
-
jobsAhead:
|
|
26622
|
-
stageStartedAt:
|
|
26623
|
-
renderProgress:
|
|
26806
|
+
queuedAt: z112.string().optional(),
|
|
26807
|
+
jobsAhead: z112.number().int().nonnegative().optional(),
|
|
26808
|
+
stageStartedAt: z112.string().optional(),
|
|
26809
|
+
renderProgress: z112.number().optional(),
|
|
26624
26810
|
// AI clip fields (absent on a video paid before clips, or from an API
|
|
26625
26811
|
// that predates them). Lenient: an unreadable value is dropped
|
|
26626
26812
|
// instead of hiding the status.
|
|
26627
|
-
clipCount:
|
|
26628
|
-
clipsUsed:
|
|
26629
|
-
clipPriceCents:
|
|
26630
|
-
clipsRefunded:
|
|
26813
|
+
clipCount: z112.number().int().nonnegative().optional().catch(void 0),
|
|
26814
|
+
clipsUsed: z112.number().int().nonnegative().optional().catch(void 0),
|
|
26815
|
+
clipPriceCents: z112.number().finite().nonnegative().optional().catch(void 0),
|
|
26816
|
+
clipsRefunded: z112.number().int().nonnegative().optional().catch(void 0),
|
|
26631
26817
|
// Hook versions (absent from an API or a video before them): the
|
|
26632
26818
|
// count ordered and, once done, the signed URLs of the EXTRA versions
|
|
26633
26819
|
// (hook 2, hook 3); `finalMp4Url` is hook 1.
|
|
26634
|
-
hookVariants:
|
|
26635
|
-
variantUrls:
|
|
26820
|
+
hookVariants: z112.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
|
|
26821
|
+
variantUrls: z112.array(z112.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
|
|
26636
26822
|
// Extra hook versions given back, as the task recorded it once the
|
|
26637
26823
|
// refunds landed (absent until then, and from an API before it).
|
|
26638
|
-
variantsRefunded:
|
|
26639
|
-
activity:
|
|
26640
|
-
previewUrl:
|
|
26824
|
+
variantsRefunded: z112.number().int().nonnegative().optional().catch(void 0),
|
|
26825
|
+
activity: z112.array(MotionGraphicsActivitySchema).optional().catch(void 0),
|
|
26826
|
+
previewUrl: z112.string().optional()
|
|
26641
26827
|
}).passthrough()
|
|
26642
26828
|
}).passthrough();
|
|
26643
26829
|
function parseAnimatedVideoResult(value) {
|
|
@@ -26893,10 +27079,10 @@ function registerAnimatedVideoTools(server, api) {
|
|
|
26893
27079
|
__name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
|
|
26894
27080
|
|
|
26895
27081
|
// src/tools/winning-product-image.ts
|
|
26896
|
-
import { z as
|
|
26897
|
-
var WinnerReferenceInput =
|
|
26898
|
-
runId:
|
|
26899
|
-
candidateSourceId:
|
|
27082
|
+
import { z as z113 } from "zod";
|
|
27083
|
+
var WinnerReferenceInput = z113.object({
|
|
27084
|
+
runId: z113.string().uuid(),
|
|
27085
|
+
candidateSourceId: z113.string().trim().min(1).max(160)
|
|
26900
27086
|
}).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
|
|
26901
27087
|
async function resolveWinnerImages(api, winnerReference, images) {
|
|
26902
27088
|
if (!winnerReference) return images;
|
|
@@ -26933,62 +27119,62 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
|
|
|
26933
27119
|
var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
|
|
26934
27120
|
var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
|
|
26935
27121
|
var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
|
|
26936
|
-
var CreateProductTaskInput =
|
|
27122
|
+
var CreateProductTaskInput = z114.object({
|
|
26937
27123
|
images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
|
|
26938
27124
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
26939
|
-
projectId:
|
|
26940
|
-
productUrl:
|
|
27125
|
+
projectId: z114.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
|
|
27126
|
+
productUrl: z114.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."),
|
|
26941
27127
|
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.'),
|
|
26942
27128
|
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.'),
|
|
26943
|
-
price:
|
|
26944
|
-
compareAtPrice:
|
|
26945
|
-
offer:
|
|
26946
|
-
paymentMethods:
|
|
26947
|
-
productContext:
|
|
26948
|
-
productLabel:
|
|
27129
|
+
price: z114.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.'),
|
|
27130
|
+
compareAtPrice: z114.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".'),
|
|
27131
|
+
offer: z114.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.'),
|
|
27132
|
+
paymentMethods: z114.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.'),
|
|
27133
|
+
productContext: z114.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."),
|
|
27134
|
+
productLabel: z114.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.'),
|
|
26949
27135
|
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.'),
|
|
26950
27136
|
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.'),
|
|
26951
|
-
durationSeconds:
|
|
26952
|
-
|
|
26953
|
-
|
|
27137
|
+
durationSeconds: z114.union([
|
|
27138
|
+
z114.literal(15),
|
|
27139
|
+
z114.literal(30)
|
|
26954
27140
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
26955
|
-
pauseForAngleReview:
|
|
26956
|
-
aiDecidesAll:
|
|
27141
|
+
pauseForAngleReview: z114.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."),
|
|
27142
|
+
aiDecidesAll: z114.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."),
|
|
26957
27143
|
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.'),
|
|
26958
27144
|
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.'),
|
|
26959
27145
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
26960
27146
|
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).'),
|
|
26961
|
-
videoAngleCount:
|
|
27147
|
+
videoAngleCount: z114.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."),
|
|
26962
27148
|
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.'),
|
|
26963
|
-
outputs:
|
|
27149
|
+
outputs: z114.array(z114.enum([
|
|
26964
27150
|
"landing",
|
|
26965
27151
|
"video",
|
|
26966
27152
|
"image"
|
|
26967
27153
|
])).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}`),
|
|
26968
|
-
includeInitialLandingGif:
|
|
26969
|
-
competitorScanEnabled:
|
|
27154
|
+
includeInitialLandingGif: z114.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."),
|
|
27155
|
+
competitorScanEnabled: z114.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."),
|
|
26970
27156
|
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.'),
|
|
26971
|
-
replicateWinnerWhenFound:
|
|
26972
|
-
brandId:
|
|
26973
|
-
actorId:
|
|
27157
|
+
replicateWinnerWhenFound: z114.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."),
|
|
27158
|
+
brandId: z114.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."),
|
|
27159
|
+
actorId: z114.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."),
|
|
26974
27160
|
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.'),
|
|
26975
|
-
creativeDirection:
|
|
26976
|
-
headline:
|
|
26977
|
-
subheadline:
|
|
27161
|
+
creativeDirection: z114.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.'),
|
|
27162
|
+
headline: z114.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."),
|
|
27163
|
+
subheadline: z114.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."),
|
|
26978
27164
|
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".'),
|
|
26979
27165
|
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".')
|
|
26980
27166
|
}).strict();
|
|
26981
|
-
var CreateServiceVideoInput =
|
|
26982
|
-
landingUrl:
|
|
26983
|
-
additionalContext:
|
|
27167
|
+
var CreateServiceVideoInput = z114.object({
|
|
27168
|
+
landingUrl: z114.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
|
|
27169
|
+
additionalContext: z114.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
|
|
26984
27170
|
language: Lang.describe("Idioma del video: es, en o pt."),
|
|
26985
|
-
voiceId:
|
|
26986
|
-
brandId:
|
|
26987
|
-
reviewMode:
|
|
27171
|
+
voiceId: z114.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.'),
|
|
27172
|
+
brandId: z114.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
|
|
27173
|
+
reviewMode: z114.enum([
|
|
26988
27174
|
"automatic",
|
|
26989
27175
|
"guided"
|
|
26990
27176
|
]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
|
|
26991
|
-
videoPreset:
|
|
27177
|
+
videoPreset: z114.enum([
|
|
26992
27178
|
"auto",
|
|
26993
27179
|
"ugc_dynamic",
|
|
26994
27180
|
"ugc_how_to",
|
|
@@ -26998,128 +27184,128 @@ var CreateServiceVideoInput = z113.object({
|
|
|
26998
27184
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
26999
27185
|
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.')
|
|
27000
27186
|
}).strict();
|
|
27001
|
-
var GetTaskStatusInput =
|
|
27002
|
-
taskId:
|
|
27003
|
-
waitSeconds:
|
|
27187
|
+
var GetTaskStatusInput = z114.object({
|
|
27188
|
+
taskId: z114.string().min(1),
|
|
27189
|
+
waitSeconds: z114.number().int().min(0).max(120).optional()
|
|
27004
27190
|
});
|
|
27005
|
-
var ListTasksInput =
|
|
27006
|
-
limit:
|
|
27007
|
-
offset:
|
|
27008
|
-
search:
|
|
27191
|
+
var ListTasksInput = z114.object({
|
|
27192
|
+
limit: z114.number().int().min(1).max(50).optional(),
|
|
27193
|
+
offset: z114.number().int().min(0).optional(),
|
|
27194
|
+
search: z114.string().optional()
|
|
27009
27195
|
});
|
|
27010
27196
|
var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
|
|
27011
27197
|
var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
|
|
27012
|
-
var EditTaskDraftInput =
|
|
27013
|
-
taskId:
|
|
27014
|
-
angleIndex:
|
|
27015
|
-
angle:
|
|
27016
|
-
angle:
|
|
27017
|
-
buyerPersona:
|
|
27018
|
-
actor:
|
|
27019
|
-
actorId:
|
|
27020
|
-
gender:
|
|
27198
|
+
var EditTaskDraftInput = z114.object({
|
|
27199
|
+
taskId: z114.string().min(1),
|
|
27200
|
+
angleIndex: z114.number().int().min(0),
|
|
27201
|
+
angle: z114.object({
|
|
27202
|
+
angle: z114.string().min(1).max(480),
|
|
27203
|
+
buyerPersona: z114.string().min(1).max(360),
|
|
27204
|
+
actor: z114.string().min(1).max(360).optional(),
|
|
27205
|
+
actorId: z114.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."),
|
|
27206
|
+
gender: z114.enum([
|
|
27021
27207
|
"female",
|
|
27022
27208
|
"male"
|
|
27023
27209
|
]).optional(),
|
|
27024
|
-
scriptNotes:
|
|
27210
|
+
scriptNotes: z114.string().max(2e3).optional()
|
|
27025
27211
|
})
|
|
27026
27212
|
});
|
|
27027
|
-
var PendingActionPayload =
|
|
27028
|
-
|
|
27029
|
-
kind:
|
|
27213
|
+
var PendingActionPayload = z114.discriminatedUnion("kind", [
|
|
27214
|
+
z114.object({
|
|
27215
|
+
kind: z114.literal("product_reference_set_approval"),
|
|
27030
27216
|
scope: ProductReferenceScopeEnum.optional(),
|
|
27031
|
-
scopeKey:
|
|
27032
|
-
scopeSnapshotId:
|
|
27033
|
-
expectedScopeHash:
|
|
27217
|
+
scopeKey: z114.string().min(1).max(120).optional(),
|
|
27218
|
+
scopeSnapshotId: z114.string().uuid().optional(),
|
|
27219
|
+
expectedScopeHash: z114.string().min(1).max(128).optional(),
|
|
27034
27220
|
decision: ProductReferenceResolutionDecisionEnum,
|
|
27035
27221
|
reason: ProductReferenceRejectionReasonEnum.optional(),
|
|
27036
|
-
affectedRefKeys:
|
|
27037
|
-
affectedPhotoNumbers:
|
|
27038
|
-
recoveryAction:
|
|
27222
|
+
affectedRefKeys: z114.array(z114.string().min(1).max(200)).min(1).optional(),
|
|
27223
|
+
affectedPhotoNumbers: z114.array(z114.number().int().positive()).min(1).optional(),
|
|
27224
|
+
recoveryAction: z114.enum([
|
|
27039
27225
|
"remove",
|
|
27040
27226
|
"replace",
|
|
27041
27227
|
"upload",
|
|
27042
27228
|
"return_to_selection"
|
|
27043
27229
|
]).optional()
|
|
27044
27230
|
}),
|
|
27045
|
-
|
|
27046
|
-
kind:
|
|
27047
|
-
selectedPhotoNumbers:
|
|
27231
|
+
z114.object({
|
|
27232
|
+
kind: z114.literal("product_reference_confirmation"),
|
|
27233
|
+
selectedPhotoNumbers: z114.array(z114.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."),
|
|
27048
27234
|
userChoice: ProductReferenceUserChoiceEnum.optional(),
|
|
27049
|
-
confirmedProductNames:
|
|
27235
|
+
confirmedProductNames: z114.array(z114.string().min(1).max(120)).min(2).max(8).optional(),
|
|
27050
27236
|
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."),
|
|
27051
27237
|
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."),
|
|
27052
|
-
useMultiSceneShowcase:
|
|
27238
|
+
useMultiSceneShowcase: z114.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
|
|
27053
27239
|
}),
|
|
27054
|
-
|
|
27055
|
-
kind:
|
|
27240
|
+
z114.object({
|
|
27241
|
+
kind: z114.literal("angle_review_approval"),
|
|
27056
27242
|
// All edits are optional — empty action body just approves the
|
|
27057
27243
|
// backend-generated draft as-is. Field shapes mirror the angle-review
|
|
27058
27244
|
// request contracts in @packages/types/wizard.ts; the handler routes to
|
|
27059
27245
|
// the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
|
|
27060
|
-
customAngle:
|
|
27246
|
+
customAngle: z114.string().min(1).max(480).optional(),
|
|
27061
27247
|
// Keep the shared MCP action within the strictest downstream contract:
|
|
27062
27248
|
// autopilot/image resume endpoints cap these fields at 1500 characters.
|
|
27063
|
-
painPoints:
|
|
27064
|
-
benefits:
|
|
27249
|
+
painPoints: z114.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
27250
|
+
benefits: z114.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
27065
27251
|
// Same policy as the two fields above: the strictest downstream contract
|
|
27066
27252
|
// wins. The image endpoint caps each feature at 240 while landing/video
|
|
27067
27253
|
// accept 300, and this single action routes to whichever the task is — so
|
|
27068
27254
|
// accepting 300 here turns a 250-character feature on an image task into
|
|
27069
27255
|
// an opaque HTTP 400 after the model already believed it had been saved.
|
|
27070
|
-
features:
|
|
27071
|
-
buyerPersona:
|
|
27256
|
+
features: z114.array(z114.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
|
|
27257
|
+
buyerPersona: z114.string().min(1).max(360).optional(),
|
|
27072
27258
|
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.'),
|
|
27073
|
-
actor:
|
|
27074
|
-
actorId:
|
|
27075
|
-
creativeDirection:
|
|
27076
|
-
selectedAngleNumbers:
|
|
27077
|
-
angleEdits:
|
|
27078
|
-
angleNumber:
|
|
27079
|
-
narrativeSelection:
|
|
27259
|
+
actor: z114.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."),
|
|
27260
|
+
actorId: z114.string().max(120).nullable().optional(),
|
|
27261
|
+
creativeDirection: z114.string().max(2e3).optional(),
|
|
27262
|
+
selectedAngleNumbers: z114.array(z114.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."),
|
|
27263
|
+
angleEdits: z114.array(z114.object({
|
|
27264
|
+
angleNumber: z114.number().int().positive(),
|
|
27265
|
+
narrativeSelection: z114.enum([
|
|
27080
27266
|
"market",
|
|
27081
27267
|
"guided"
|
|
27082
27268
|
]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
|
|
27083
|
-
angle:
|
|
27084
|
-
buyerPersona:
|
|
27269
|
+
angle: z114.string().min(1).max(480).optional(),
|
|
27270
|
+
buyerPersona: z114.string().min(1).max(360).optional(),
|
|
27085
27271
|
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.'),
|
|
27086
|
-
actor:
|
|
27087
|
-
actorId:
|
|
27088
|
-
creativeDirection:
|
|
27272
|
+
actor: z114.string().min(1).max(360).optional(),
|
|
27273
|
+
actorId: z114.string().max(120).nullable().optional(),
|
|
27274
|
+
creativeDirection: z114.string().max(2e3).optional()
|
|
27089
27275
|
}).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)."),
|
|
27090
|
-
gapDurationSeconds:
|
|
27091
|
-
|
|
27092
|
-
|
|
27276
|
+
gapDurationSeconds: z114.union([
|
|
27277
|
+
z114.literal(15),
|
|
27278
|
+
z114.literal(30)
|
|
27093
27279
|
]).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.")
|
|
27094
27280
|
}),
|
|
27095
|
-
|
|
27096
|
-
kind:
|
|
27097
|
-
angleId:
|
|
27098
|
-
angleNumber:
|
|
27099
|
-
content:
|
|
27100
|
-
creativeDirection:
|
|
27101
|
-
actor:
|
|
27281
|
+
z114.object({
|
|
27282
|
+
kind: z114.literal("service_angle_approval"),
|
|
27283
|
+
angleId: z114.string().uuid().optional(),
|
|
27284
|
+
angleNumber: z114.number().int().positive().optional(),
|
|
27285
|
+
content: z114.string().min(1).max(480).optional(),
|
|
27286
|
+
creativeDirection: z114.string().min(1).max(1500).optional(),
|
|
27287
|
+
actor: z114.string().min(1).max(360).optional()
|
|
27102
27288
|
}),
|
|
27103
|
-
|
|
27104
|
-
kind:
|
|
27105
|
-
voiceovers:
|
|
27106
|
-
visualDirections:
|
|
27107
|
-
voiceoversByScene:
|
|
27108
|
-
visualDirectionsByScene:
|
|
27289
|
+
z114.object({
|
|
27290
|
+
kind: z114.literal("service_script_approval"),
|
|
27291
|
+
voiceovers: z114.record(z114.string(), z114.string().min(1).max(600)).optional(),
|
|
27292
|
+
visualDirections: z114.record(z114.string(), z114.string().min(1).max(1200)).optional(),
|
|
27293
|
+
voiceoversByScene: z114.record(z114.string(), z114.string().min(1).max(600)).optional(),
|
|
27294
|
+
visualDirectionsByScene: z114.record(z114.string(), z114.string().min(1).max(1200)).optional()
|
|
27109
27295
|
})
|
|
27110
27296
|
]);
|
|
27111
|
-
var ResolvePendingActionInput =
|
|
27112
|
-
taskId:
|
|
27297
|
+
var ResolvePendingActionInput = z114.object({
|
|
27298
|
+
taskId: z114.string().min(1),
|
|
27113
27299
|
action: PendingActionPayload
|
|
27114
27300
|
}).strict();
|
|
27115
27301
|
function resolveVariantConfirmVideoTier(action) {
|
|
27116
27302
|
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
27117
27303
|
}
|
|
27118
27304
|
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
27119
|
-
var StatusForResolveSchema =
|
|
27305
|
+
var StatusForResolveSchema = z114.object({
|
|
27120
27306
|
// Metadata used to select the backend resume contract. Older API responses
|
|
27121
27307
|
// may omit these fields, so the resolver keeps the generic fallback.
|
|
27122
|
-
kind:
|
|
27308
|
+
kind: z114.enum([
|
|
27123
27309
|
"autopilot",
|
|
27124
27310
|
"video",
|
|
27125
27311
|
"image",
|
|
@@ -27127,18 +27313,18 @@ var StatusForResolveSchema = z113.object({
|
|
|
27127
27313
|
"mix",
|
|
27128
27314
|
"service"
|
|
27129
27315
|
]).optional(),
|
|
27130
|
-
selectedOutputs:
|
|
27316
|
+
selectedOutputs: z114.array(z114.enum([
|
|
27131
27317
|
"landing",
|
|
27132
27318
|
"video",
|
|
27133
27319
|
"image"
|
|
27134
27320
|
])).optional(),
|
|
27135
|
-
videoAngleCount:
|
|
27136
|
-
ugcFormat:
|
|
27321
|
+
videoAngleCount: z114.number().int().min(1).max(3).optional(),
|
|
27322
|
+
ugcFormat: z114.enum([
|
|
27137
27323
|
"single_8s",
|
|
27138
27324
|
"single_15s",
|
|
27139
27325
|
"double_30s"
|
|
27140
27326
|
]).optional(),
|
|
27141
|
-
videoStyle:
|
|
27327
|
+
videoStyle: z114.enum([
|
|
27142
27328
|
"ugc",
|
|
27143
27329
|
"cartoon_3d",
|
|
27144
27330
|
"product_only",
|
|
@@ -27148,13 +27334,13 @@ var StatusForResolveSchema = z113.object({
|
|
|
27148
27334
|
videoQuality: VideoQualityEnum.optional(),
|
|
27149
27335
|
videoRouteId: VideoRouteIdEnum.optional(),
|
|
27150
27336
|
videoModel: TaskVideoModelEnum.optional(),
|
|
27151
|
-
videoTier:
|
|
27337
|
+
videoTier: z114.enum([
|
|
27152
27338
|
"legacy",
|
|
27153
27339
|
"standard",
|
|
27154
27340
|
"pro",
|
|
27155
27341
|
"single_call"
|
|
27156
27342
|
]).optional(),
|
|
27157
|
-
videoResolution:
|
|
27343
|
+
videoResolution: z114.enum([
|
|
27158
27344
|
"480p",
|
|
27159
27345
|
"720p"
|
|
27160
27346
|
]).optional(),
|
|
@@ -27162,60 +27348,60 @@ var StatusForResolveSchema = z113.object({
|
|
|
27162
27348
|
// A task created before a narrative was blocked/hidden must still parse,
|
|
27163
27349
|
// or resolve_pending_action could never approve it.
|
|
27164
27350
|
narrativeStyle: NarrativeStyle.optional(),
|
|
27165
|
-
pauseForVideoScriptReview:
|
|
27166
|
-
pendingUserAction:
|
|
27167
|
-
kind:
|
|
27168
|
-
candidateGrouping:
|
|
27169
|
-
selectedImageUrls:
|
|
27170
|
-
proposedProductNames:
|
|
27351
|
+
pauseForVideoScriptReview: z114.boolean().optional(),
|
|
27352
|
+
pendingUserAction: z114.object({
|
|
27353
|
+
kind: z114.string(),
|
|
27354
|
+
candidateGrouping: z114.string().optional(),
|
|
27355
|
+
selectedImageUrls: z114.array(z114.string()).optional(),
|
|
27356
|
+
proposedProductNames: z114.array(z114.string()).optional(),
|
|
27171
27357
|
// Adaptive reference questions are server-owned. Echo only the evidence
|
|
27172
27358
|
// identity and the choices shown by the current snapshot; never accept a
|
|
27173
27359
|
// client-supplied reference set as authorization.
|
|
27174
|
-
options:
|
|
27175
|
-
mode:
|
|
27360
|
+
options: z114.array(ProductReferenceUserChoiceEnum).max(4).optional(),
|
|
27361
|
+
mode: z114.enum([
|
|
27176
27362
|
"question",
|
|
27177
27363
|
"visual_recovery"
|
|
27178
27364
|
]).optional(),
|
|
27179
27365
|
/** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
|
|
27180
|
-
canKeepSelection:
|
|
27181
|
-
decisionKey:
|
|
27182
|
-
questionOrdinal:
|
|
27183
|
-
questionCeiling:
|
|
27184
|
-
|
|
27185
|
-
|
|
27366
|
+
canKeepSelection: z114.boolean().optional(),
|
|
27367
|
+
decisionKey: z114.string().optional(),
|
|
27368
|
+
questionOrdinal: z114.number().int().min(1).max(5).optional(),
|
|
27369
|
+
questionCeiling: z114.union([
|
|
27370
|
+
z114.literal(3),
|
|
27371
|
+
z114.literal(5)
|
|
27186
27372
|
]).optional(),
|
|
27187
|
-
referenceEvidenceVersion:
|
|
27188
|
-
expectedEvidenceHash:
|
|
27189
|
-
question:
|
|
27190
|
-
prompt:
|
|
27191
|
-
helpText:
|
|
27192
|
-
options:
|
|
27373
|
+
referenceEvidenceVersion: z114.number().int().positive().optional(),
|
|
27374
|
+
expectedEvidenceHash: z114.string().optional(),
|
|
27375
|
+
question: z114.object({
|
|
27376
|
+
prompt: z114.string().min(1).max(240),
|
|
27377
|
+
helpText: z114.string().min(1).max(300).optional(),
|
|
27378
|
+
options: z114.array(z114.object({
|
|
27193
27379
|
value: ProductReferenceUserChoiceEnum,
|
|
27194
|
-
label:
|
|
27195
|
-
description:
|
|
27380
|
+
label: z114.string().min(1).max(120),
|
|
27381
|
+
description: z114.string().min(1).max(240).optional()
|
|
27196
27382
|
})).min(2).max(4)
|
|
27197
27383
|
}).optional(),
|
|
27198
27384
|
scope: ProductReferenceScopeEnum.optional(),
|
|
27199
|
-
scopeKey:
|
|
27200
|
-
scopeSnapshotId:
|
|
27201
|
-
scopeHash:
|
|
27202
|
-
baseReferenceSetHash:
|
|
27203
|
-
phase:
|
|
27385
|
+
scopeKey: z114.string().optional(),
|
|
27386
|
+
scopeSnapshotId: z114.string().uuid().optional(),
|
|
27387
|
+
scopeHash: z114.string().optional(),
|
|
27388
|
+
baseReferenceSetHash: z114.string().optional(),
|
|
27389
|
+
phase: z114.enum([
|
|
27204
27390
|
"preparation",
|
|
27205
27391
|
"final"
|
|
27206
27392
|
]).optional(),
|
|
27207
|
-
selectedRefKeys:
|
|
27208
|
-
allowedDecisions:
|
|
27209
|
-
previews:
|
|
27210
|
-
refKey:
|
|
27393
|
+
selectedRefKeys: z114.array(z114.string().min(1).max(200)).optional(),
|
|
27394
|
+
allowedDecisions: z114.array(ProductReferenceResolutionDecisionEnum).optional(),
|
|
27395
|
+
previews: z114.array(z114.object({
|
|
27396
|
+
refKey: z114.string().min(1).max(200)
|
|
27211
27397
|
}).passthrough()).optional(),
|
|
27212
|
-
customAngleDraft:
|
|
27213
|
-
painPointsDraft:
|
|
27214
|
-
benefitsDraft:
|
|
27215
|
-
featuresDraft:
|
|
27216
|
-
angleOptions:
|
|
27217
|
-
index:
|
|
27218
|
-
angle:
|
|
27398
|
+
customAngleDraft: z114.string().optional(),
|
|
27399
|
+
painPointsDraft: z114.string().optional(),
|
|
27400
|
+
benefitsDraft: z114.string().optional(),
|
|
27401
|
+
featuresDraft: z114.array(z114.string()).optional(),
|
|
27402
|
+
angleOptions: z114.array(z114.object({
|
|
27403
|
+
index: z114.number().int().nonnegative(),
|
|
27404
|
+
angle: z114.string().min(1)
|
|
27219
27405
|
}).passthrough()).min(1).max(5).optional(),
|
|
27220
27406
|
// Recommendation consumed only when the caller explicitly sends
|
|
27221
27407
|
// gapDurationSeconds: 30 in the angle approval action.
|
|
@@ -27225,17 +27411,17 @@ var StatusForResolveSchema = z113.object({
|
|
|
27225
27411
|
// keys. `actorId` (the saved custom actor the picker stored) was silently
|
|
27226
27412
|
// dropped here, so the approval handler below could not echo it back on the
|
|
27227
27413
|
// PATCH — the selection looked accepted and reached no render.
|
|
27228
|
-
angles:
|
|
27229
|
-
id:
|
|
27230
|
-
content:
|
|
27231
|
-
creativeDirection:
|
|
27232
|
-
actor:
|
|
27233
|
-
actorId:
|
|
27414
|
+
angles: z114.array(z114.object({
|
|
27415
|
+
id: z114.string().uuid(),
|
|
27416
|
+
content: z114.string(),
|
|
27417
|
+
creativeDirection: z114.string(),
|
|
27418
|
+
actor: z114.string(),
|
|
27419
|
+
actorId: z114.string().nullable().optional()
|
|
27234
27420
|
}).passthrough()).optional(),
|
|
27235
|
-
panels:
|
|
27236
|
-
beatId:
|
|
27237
|
-
voiceover:
|
|
27238
|
-
visualDirection:
|
|
27421
|
+
panels: z114.array(z114.object({
|
|
27422
|
+
beatId: z114.string(),
|
|
27423
|
+
voiceover: z114.string(),
|
|
27424
|
+
visualDirection: z114.string()
|
|
27239
27425
|
}).passthrough()).optional()
|
|
27240
27426
|
}).optional()
|
|
27241
27427
|
}).passthrough();
|
|
@@ -27587,8 +27773,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
27587
27773
|
server.registerTool("verify_landing_commerce", {
|
|
27588
27774
|
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.",
|
|
27589
27775
|
inputSchema: {
|
|
27590
|
-
taskId:
|
|
27591
|
-
editId:
|
|
27776
|
+
taskId: z114.string().uuid(),
|
|
27777
|
+
editId: z114.string().uuid()
|
|
27592
27778
|
},
|
|
27593
27779
|
annotations: OVERWRITES_EXTERNAL
|
|
27594
27780
|
}, async (input) => {
|
|
@@ -28234,25 +28420,25 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
28234
28420
|
__name(registerTaskTools, "registerTaskTools");
|
|
28235
28421
|
|
|
28236
28422
|
// src/tools/brands.ts
|
|
28237
|
-
import { z as
|
|
28423
|
+
import { z as z115 } from "zod";
|
|
28238
28424
|
var guidance2 = getProductMakerCapabilityModelGuidance("create_brand");
|
|
28239
28425
|
var BRAND_START_REPLAY_WINDOW_MS = 15 * 60 * 1e3;
|
|
28240
28426
|
var BRAND_NOTES_MAX_CHARS = 2e4;
|
|
28241
|
-
var CreateBrandInput =
|
|
28242
|
-
action:
|
|
28427
|
+
var CreateBrandInput = z115.object({
|
|
28428
|
+
action: z115.enum([
|
|
28243
28429
|
"start",
|
|
28244
28430
|
"status",
|
|
28245
28431
|
"list"
|
|
28246
28432
|
]).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."),
|
|
28247
|
-
sourceUrl:
|
|
28248
|
-
businessNotes:
|
|
28249
|
-
language:
|
|
28433
|
+
sourceUrl: z115.string().trim().min(1).max(500).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."),
|
|
28434
|
+
businessNotes: z115.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."),
|
|
28435
|
+
language: z115.enum([
|
|
28250
28436
|
"es",
|
|
28251
28437
|
"en",
|
|
28252
28438
|
"pt"
|
|
28253
28439
|
]).optional().describe("Idioma de la conversaci\xF3n. Solo se usa si la p\xE1gina del negocio no deja claro su idioma."),
|
|
28254
|
-
confirmed:
|
|
28255
|
-
brandId:
|
|
28440
|
+
confirmed: z115.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, start solo cotiza y no cobra."),
|
|
28441
|
+
brandId: z115.string().uuid().optional().describe("ID de la marca. Obligatorio para status; no lo inventes.")
|
|
28256
28442
|
}).strict();
|
|
28257
28443
|
function normalizeBrandSourceUrl(raw) {
|
|
28258
28444
|
const value = raw.trim();
|
|
@@ -28492,24 +28678,24 @@ __name(registerBrandTools, "registerBrandTools");
|
|
|
28492
28678
|
|
|
28493
28679
|
// src/tools/service-landing.ts
|
|
28494
28680
|
import { createHash as createHash4 } from "crypto";
|
|
28495
|
-
import { z as
|
|
28681
|
+
import { z as z116 } from "zod";
|
|
28496
28682
|
var guidance3 = getProductMakerCapabilityModelGuidance("create_service_landing");
|
|
28497
28683
|
var SERVICE_LANDING_KEY_NAMESPACE = "6f1d8c2a-3b4e-5f60-8a7b-9c0d1e2f3a4b";
|
|
28498
28684
|
var SERVICE_LANDING_INFO_MAX_CHARS = 2e4;
|
|
28499
|
-
var CreateServiceLandingInput =
|
|
28500
|
-
action:
|
|
28685
|
+
var CreateServiceLandingInput = z116.object({
|
|
28686
|
+
action: z116.enum([
|
|
28501
28687
|
"prepare",
|
|
28502
28688
|
"build",
|
|
28503
28689
|
"status",
|
|
28504
28690
|
"publish"
|
|
28505
28691
|
]).default("prepare").describe("prepare (gratis) crea o retoma la landing de la marca y da el precio; build (pagado, confirmed=true) lee los datos del negocio y luego crea la p\xE1gina; status sigue el avance; publish la publica y devuelve su enlace."),
|
|
28506
|
-
brandId:
|
|
28507
|
-
servicePageId:
|
|
28508
|
-
businessInfo:
|
|
28509
|
-
confirmed:
|
|
28510
|
-
maxCredits:
|
|
28511
|
-
operationId:
|
|
28512
|
-
slug:
|
|
28692
|
+
brandId: z116.string().uuid().optional().describe("ID de la marca (de create_brand). Obligatorio para prepare. Nunca un taskId de producto."),
|
|
28693
|
+
servicePageId: z116.string().uuid().optional().describe("ID de la landing que devolvi\xF3 prepare. Obligatorio para build, status y publish."),
|
|
28694
|
+
businessInfo: z116.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."),
|
|
28695
|
+
confirmed: z116.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio total y que el usuario acepte. Obligatorio para build."),
|
|
28696
|
+
maxCredits: z116.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."),
|
|
28697
|
+
operationId: z116.string().uuid().optional().describe("Opcional en status: la operaci\xF3n que devolvi\xF3 build."),
|
|
28698
|
+
slug: z116.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.")
|
|
28513
28699
|
}).strict();
|
|
28514
28700
|
var SERVICE_LANDING_MAX_BUILD_ATTEMPTS = 10;
|
|
28515
28701
|
function serviceKey(...parts) {
|
|
@@ -28731,9 +28917,6 @@ function registerServiceLandingTools(server, api) {
|
|
|
28731
28917
|
let operation2 = null;
|
|
28732
28918
|
if (input.operationId) {
|
|
28733
28919
|
operation2 = await api.getJson(`/v1/service-pages/operations/${encodeURIComponent(input.operationId)}`);
|
|
28734
|
-
if (operation2.recoverable && (operation2.status === "failed" || operation2.status === "requires_reconciliation")) {
|
|
28735
|
-
operation2 = await api.postJson(`${pagePath(input.servicePageId)}/operations/${encodeURIComponent(operation2.opId)}/recover`, {});
|
|
28736
|
-
}
|
|
28737
28920
|
if (operation2.status === "queued" || operation2.status === "running") {
|
|
28738
28921
|
return asText({
|
|
28739
28922
|
servicePageId: input.servicePageId,
|
|
@@ -28750,7 +28933,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
28750
28933
|
status: "in_review",
|
|
28751
28934
|
// Unknown on purpose: the charge is exactly what is being
|
|
28752
28935
|
// confirmed. Settlement only charges a completed step.
|
|
28753
|
-
nextAction: "Esta etapa qued\xF3 en revisi\xF3n por un problema temporal:
|
|
28936
|
+
nextAction: "Esta etapa qued\xF3 en revisi\xF3n por un problema temporal: el servidor est\xE1 confirmando si se complet\xF3 y la resuelve solo. Si no se completa, se devuelve lo cobrado. Dile al usuario que sus datos est\xE1n guardados; vuelve a llamar action=status con el mismo operationId en unos minutos (si no se complet\xF3, pasa a fallida y la reintentas con build). No inicies otra etapa mientras tanto."
|
|
28754
28937
|
});
|
|
28755
28938
|
}
|
|
28756
28939
|
if (operation2.status !== "succeeded") {
|
|
@@ -28845,7 +29028,7 @@ function registerServiceLandingTools(server, api) {
|
|
|
28845
29028
|
__name(registerServiceLandingTools, "registerServiceLandingTools");
|
|
28846
29029
|
|
|
28847
29030
|
// src/tools/service-images.ts
|
|
28848
|
-
import { z as
|
|
29031
|
+
import { z as z117 } from "zod";
|
|
28849
29032
|
var guidance4 = getProductMakerCapabilityModelGuidance("create_service_images");
|
|
28850
29033
|
var SERVICE_IMAGE_FORMATS = [
|
|
28851
29034
|
"4:5",
|
|
@@ -28858,23 +29041,23 @@ var LANGUAGE_TAGS = {
|
|
|
28858
29041
|
en: "en-US",
|
|
28859
29042
|
pt: "pt-BR"
|
|
28860
29043
|
};
|
|
28861
|
-
var CreateServiceImagesInput =
|
|
28862
|
-
brandId:
|
|
28863
|
-
instruction:
|
|
28864
|
-
delegateToAi:
|
|
28865
|
-
format:
|
|
28866
|
-
count:
|
|
28867
|
-
quality:
|
|
29044
|
+
var CreateServiceImagesInput = z117.object({
|
|
29045
|
+
brandId: z117.string().uuid().optional().describe("ID de la marca (de create_brand). Recomendado: da nombre, colores, tono y servicios. Nunca un taskId de producto."),
|
|
29046
|
+
instruction: z117.string().trim().max(4e3).optional().describe("Qu\xE9 servicio o promoci\xF3n mostrar, con las palabras del usuario (ej. \xABcorte + barba a $35.000 los martes\xBB). Si el usuario deja que la IA decida, om\xEDtelo y usa delegateToAi=true."),
|
|
29047
|
+
delegateToAi: z117.boolean().optional().describe("true si el usuario prefiere que la IA elija qu\xE9 mostrar a partir de su marca."),
|
|
29048
|
+
format: z117.enum(SERVICE_IMAGE_FORMATS).optional().describe('Formato: "4:5" (feed, por defecto), "9:16" (historias/reels) o "1:1" (cuadrado).'),
|
|
29049
|
+
count: z117.number().int().min(1).max(SERVICE_IMAGE_MAX_COUNT).optional().describe("Cu\xE1ntas im\xE1genes, de 1 a 3 (por defecto 1)."),
|
|
29050
|
+
quality: z117.enum([
|
|
28868
29051
|
"standard",
|
|
28869
29052
|
"high"
|
|
28870
29053
|
]).optional().describe('Calidad: "standard" (por defecto) o "high" (m\xE1s cara; no disponible en 4:5).'),
|
|
28871
|
-
language:
|
|
29054
|
+
language: z117.enum([
|
|
28872
29055
|
"es",
|
|
28873
29056
|
"en",
|
|
28874
29057
|
"pt"
|
|
28875
29058
|
]).optional().describe("Idioma de los textos de la imagen (por defecto es)."),
|
|
28876
|
-
adCopy:
|
|
28877
|
-
confirmed:
|
|
29059
|
+
adCopy: z117.boolean().optional().describe("Opcional. true agrega textos para el anuncio (titular y descripci\xF3n). Por defecto false."),
|
|
29060
|
+
confirmed: z117.boolean().optional().describe("Solo true despu\xE9s de mostrar el precio y que el usuario acepte. Sin confirmed, solo cotiza y no cobra.")
|
|
28878
29061
|
}).strict();
|
|
28879
29062
|
function serviceImageModel(quality) {
|
|
28880
29063
|
return quality === "high" ? AD_CREATIVE_MODELS.PREMIUM : AD_CREATIVE_MODELS.STANDARD;
|
|
@@ -28985,7 +29168,7 @@ function registerServiceImageTools(server, api, options = {}) {
|
|
|
28985
29168
|
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) o error."
|
|
28986
29169
|
});
|
|
28987
29170
|
} catch (error) {
|
|
28988
|
-
if (error instanceof
|
|
29171
|
+
if (error instanceof z117.ZodError) throw invalidInputFromZod(error);
|
|
28989
29172
|
throw translateError(error);
|
|
28990
29173
|
}
|
|
28991
29174
|
});
|
|
@@ -28993,7 +29176,7 @@ function registerServiceImageTools(server, api, options = {}) {
|
|
|
28993
29176
|
__name(registerServiceImageTools, "registerServiceImageTools");
|
|
28994
29177
|
|
|
28995
29178
|
// src/tools/creatives.ts
|
|
28996
|
-
import { z as
|
|
29179
|
+
import { z as z118 } from "zod";
|
|
28997
29180
|
var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
|
|
28998
29181
|
var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
|
|
28999
29182
|
var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
|
|
@@ -29004,72 +29187,72 @@ var CreativeRefs = {
|
|
|
29004
29187
|
images: ImagesInput,
|
|
29005
29188
|
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.'),
|
|
29006
29189
|
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.'),
|
|
29007
|
-
price:
|
|
29008
|
-
offer:
|
|
29009
|
-
compareAtPrice:
|
|
29010
|
-
productContext:
|
|
29011
|
-
productLabel:
|
|
29012
|
-
buyerPersona:
|
|
29013
|
-
isCombo:
|
|
29014
|
-
competitorScanEnabled:
|
|
29015
|
-
brandId:
|
|
29190
|
+
price: z118.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.'),
|
|
29191
|
+
offer: z118.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.'),
|
|
29192
|
+
compareAtPrice: z118.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
|
|
29193
|
+
productContext: z118.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."),
|
|
29194
|
+
productLabel: z118.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.'),
|
|
29195
|
+
buyerPersona: z118.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.'),
|
|
29196
|
+
isCombo: z118.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
|
|
29197
|
+
competitorScanEnabled: z118.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."),
|
|
29198
|
+
brandId: z118.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.")
|
|
29016
29199
|
};
|
|
29017
|
-
var VideoPresenter =
|
|
29018
|
-
|
|
29019
|
-
mode:
|
|
29200
|
+
var VideoPresenter = z118.discriminatedUnion("mode", [
|
|
29201
|
+
z118.object({
|
|
29202
|
+
mode: z118.literal("none")
|
|
29020
29203
|
}).strict(),
|
|
29021
|
-
|
|
29022
|
-
mode:
|
|
29023
|
-
actorId:
|
|
29204
|
+
z118.object({
|
|
29205
|
+
mode: z118.literal("saved_actor"),
|
|
29206
|
+
actorId: z118.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
|
|
29024
29207
|
}).strict(),
|
|
29025
|
-
|
|
29026
|
-
mode:
|
|
29027
|
-
description:
|
|
29208
|
+
z118.object({
|
|
29209
|
+
mode: z118.literal("described"),
|
|
29210
|
+
description: z118.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
|
|
29028
29211
|
}).strict()
|
|
29029
29212
|
]);
|
|
29030
|
-
var VideoCreativeSetup =
|
|
29031
|
-
|
|
29032
|
-
mode:
|
|
29213
|
+
var VideoCreativeSetup = z118.discriminatedUnion("mode", [
|
|
29214
|
+
z118.object({
|
|
29215
|
+
mode: z118.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
|
|
29033
29216
|
}).strict(),
|
|
29034
|
-
|
|
29035
|
-
mode:
|
|
29217
|
+
z118.object({
|
|
29218
|
+
mode: z118.literal("guided"),
|
|
29036
29219
|
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.'),
|
|
29037
|
-
buyerPersona:
|
|
29220
|
+
buyerPersona: z118.string().trim().min(1).max(360),
|
|
29038
29221
|
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.'),
|
|
29039
29222
|
presenter: VideoPresenter,
|
|
29040
|
-
creativeDirection:
|
|
29223
|
+
creativeDirection: z118.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
|
|
29041
29224
|
}).strict()
|
|
29042
29225
|
]);
|
|
29043
|
-
var VideoInput =
|
|
29226
|
+
var VideoInput = z118.object({
|
|
29044
29227
|
images: CreativeRefs.images.optional(),
|
|
29045
29228
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
29046
|
-
title:
|
|
29047
|
-
primaryAngle:
|
|
29229
|
+
title: z118.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
|
|
29230
|
+
primaryAngle: z118.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".'),
|
|
29048
29231
|
language: CreativeRefs.language,
|
|
29049
29232
|
country: CreativeRefs.country,
|
|
29050
|
-
aspectRatio:
|
|
29233
|
+
aspectRatio: z118.enum([
|
|
29051
29234
|
"9:16",
|
|
29052
29235
|
"16:9",
|
|
29053
29236
|
"Auto"
|
|
29054
29237
|
]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
|
|
29055
29238
|
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.'),
|
|
29056
|
-
durationSeconds:
|
|
29057
|
-
videoAngleCount:
|
|
29239
|
+
durationSeconds: z118.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."),
|
|
29240
|
+
videoAngleCount: z118.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."),
|
|
29058
29241
|
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.'),
|
|
29059
29242
|
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."),
|
|
29060
29243
|
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.'),
|
|
29061
29244
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
|
|
29062
29245
|
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.'),
|
|
29063
|
-
features:
|
|
29246
|
+
features: z118.array(z118.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
|
|
29064
29247
|
price: CreativeRefs.price,
|
|
29065
29248
|
offer: CreativeRefs.offer,
|
|
29066
29249
|
productContext: CreativeRefs.productContext,
|
|
29067
29250
|
productLabel: CreativeRefs.productLabel,
|
|
29068
|
-
cta:
|
|
29069
|
-
scriptNotes:
|
|
29251
|
+
cta: z118.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.'),
|
|
29252
|
+
scriptNotes: z118.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.'),
|
|
29070
29253
|
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.'),
|
|
29071
29254
|
competitorScanEnabled: CreativeRefs.competitorScanEnabled,
|
|
29072
|
-
replicateWinnerWhenFound:
|
|
29255
|
+
replicateWinnerWhenFound: z118.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."),
|
|
29073
29256
|
brandId: CreativeRefs.brandId
|
|
29074
29257
|
}).strict();
|
|
29075
29258
|
var FreeVideoQualityEnum = VideoQualityEnum;
|
|
@@ -29087,7 +29270,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
|
|
|
29087
29270
|
length: 29
|
|
29088
29271
|
}, (_, index) => index + 2)
|
|
29089
29272
|
};
|
|
29090
|
-
var FreeVideoModelIdEnum =
|
|
29273
|
+
var FreeVideoModelIdEnum = z118.enum([
|
|
29091
29274
|
"grok-imagine-video-1-5-preview",
|
|
29092
29275
|
"minimax-h3/reference-to-video",
|
|
29093
29276
|
"wan/3-0-video",
|
|
@@ -29098,66 +29281,66 @@ var FREE_SELECTABLE_MODEL_IDS = [
|
|
|
29098
29281
|
"minimax-h3/reference-to-video",
|
|
29099
29282
|
"wan/3-0-video"
|
|
29100
29283
|
];
|
|
29101
|
-
var FreeVideoInput =
|
|
29284
|
+
var FreeVideoInput = z118.object({
|
|
29102
29285
|
images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
|
|
29103
|
-
rawPrompt:
|
|
29286
|
+
rawPrompt: z118.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."),
|
|
29104
29287
|
language: CreativeRefs.language,
|
|
29105
29288
|
quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
|
|
29106
29289
|
// Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
|
|
29107
29290
|
// parsed ONLY so the handler can reject it with a message naming its
|
|
29108
29291
|
// replacement — dropping it silently would turn a caller's explicit
|
|
29109
29292
|
// Pro++ pick into a quiet fallback to Wan.
|
|
29110
|
-
freeProModel:
|
|
29293
|
+
freeProModel: z118.enum([
|
|
29111
29294
|
"wan",
|
|
29112
29295
|
"seedance"
|
|
29113
29296
|
]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
|
|
29114
29297
|
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.'),
|
|
29115
|
-
durationSeconds:
|
|
29298
|
+
durationSeconds: z118.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."),
|
|
29116
29299
|
videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
|
|
29117
|
-
generateAiMusic:
|
|
29300
|
+
generateAiMusic: z118.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.'),
|
|
29118
29301
|
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.'),
|
|
29119
|
-
addSubtitles:
|
|
29120
|
-
idempotencyKey:
|
|
29302
|
+
addSubtitles: z118.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
|
|
29303
|
+
idempotencyKey: z118.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.")
|
|
29121
29304
|
}).strict();
|
|
29122
29305
|
var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
|
|
29123
|
-
var ImageCreativeSetup =
|
|
29124
|
-
|
|
29125
|
-
mode:
|
|
29306
|
+
var ImageCreativeSetup = z118.discriminatedUnion("mode", [
|
|
29307
|
+
z118.object({
|
|
29308
|
+
mode: z118.literal("automatic")
|
|
29126
29309
|
}).strict(),
|
|
29127
|
-
|
|
29128
|
-
mode:
|
|
29129
|
-
creativeArchetype:
|
|
29310
|
+
z118.object({
|
|
29311
|
+
mode: z118.literal("guided"),
|
|
29312
|
+
creativeArchetype: z118.union([
|
|
29130
29313
|
ImageCreativeArchetypeEnum,
|
|
29131
|
-
|
|
29314
|
+
z118.literal("ai_decides")
|
|
29132
29315
|
]),
|
|
29133
|
-
visualTreatment:
|
|
29316
|
+
visualTreatment: z118.union([
|
|
29134
29317
|
ImageCreativeVisualTreatmentEnum,
|
|
29135
|
-
|
|
29318
|
+
z118.literal("ai_decides")
|
|
29136
29319
|
]),
|
|
29137
29320
|
aspectRatio: ImageCreativeAspectRatioEnum,
|
|
29138
|
-
nVariants:
|
|
29139
|
-
|
|
29140
|
-
|
|
29141
|
-
|
|
29142
|
-
|
|
29143
|
-
|
|
29321
|
+
nVariants: z118.union([
|
|
29322
|
+
z118.literal(1),
|
|
29323
|
+
z118.literal(2),
|
|
29324
|
+
z118.literal(3),
|
|
29325
|
+
z118.literal(4),
|
|
29326
|
+
z118.literal(6)
|
|
29144
29327
|
]),
|
|
29145
|
-
imageModel:
|
|
29146
|
-
styleMix:
|
|
29147
|
-
generateAdCopy:
|
|
29148
|
-
competitorScanEnabled:
|
|
29149
|
-
productContext:
|
|
29150
|
-
creativeDirection:
|
|
29151
|
-
brandColors:
|
|
29152
|
-
headline:
|
|
29153
|
-
subheadline:
|
|
29328
|
+
imageModel: z118.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.'),
|
|
29329
|
+
styleMix: z118.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
|
|
29330
|
+
generateAdCopy: z118.boolean(),
|
|
29331
|
+
competitorScanEnabled: z118.boolean(),
|
|
29332
|
+
productContext: z118.string().trim().min(1).max(3e3).nullable(),
|
|
29333
|
+
creativeDirection: z118.string().trim().min(1).max(500).nullable(),
|
|
29334
|
+
brandColors: z118.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.'),
|
|
29335
|
+
headline: z118.string().trim().min(1).max(120).nullable(),
|
|
29336
|
+
subheadline: z118.string().trim().min(1).max(160).nullable()
|
|
29154
29337
|
}).strict()
|
|
29155
29338
|
]).superRefine((setup, context) => {
|
|
29156
29339
|
if (setup.mode !== "guided") return;
|
|
29157
29340
|
const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
|
|
29158
29341
|
if (needsStyleMix && setup.styleMix === null) {
|
|
29159
29342
|
context.addIssue({
|
|
29160
|
-
code:
|
|
29343
|
+
code: z118.ZodIssueCode.custom,
|
|
29161
29344
|
path: [
|
|
29162
29345
|
"styleMix"
|
|
29163
29346
|
],
|
|
@@ -29166,7 +29349,7 @@ var ImageCreativeSetup = z117.discriminatedUnion("mode", [
|
|
|
29166
29349
|
}
|
|
29167
29350
|
if (!needsStyleMix && setup.styleMix !== null) {
|
|
29168
29351
|
context.addIssue({
|
|
29169
|
-
code:
|
|
29352
|
+
code: z118.ZodIssueCode.custom,
|
|
29170
29353
|
path: [
|
|
29171
29354
|
"styleMix"
|
|
29172
29355
|
],
|
|
@@ -29175,7 +29358,7 @@ var ImageCreativeSetup = z117.discriminatedUnion("mode", [
|
|
|
29175
29358
|
}
|
|
29176
29359
|
if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
|
|
29177
29360
|
context.addIssue({
|
|
29178
|
-
code:
|
|
29361
|
+
code: z118.ZodIssueCode.custom,
|
|
29179
29362
|
path: [
|
|
29180
29363
|
"aspectRatio"
|
|
29181
29364
|
],
|
|
@@ -29183,55 +29366,55 @@ var ImageCreativeSetup = z117.discriminatedUnion("mode", [
|
|
|
29183
29366
|
});
|
|
29184
29367
|
}
|
|
29185
29368
|
});
|
|
29186
|
-
var LandingCreativeSetup =
|
|
29187
|
-
|
|
29188
|
-
mode:
|
|
29369
|
+
var LandingCreativeSetup = z118.discriminatedUnion("mode", [
|
|
29370
|
+
z118.object({
|
|
29371
|
+
mode: z118.literal("automatic")
|
|
29189
29372
|
}).strict(),
|
|
29190
|
-
|
|
29191
|
-
mode:
|
|
29373
|
+
z118.object({
|
|
29374
|
+
mode: z118.literal("guided"),
|
|
29192
29375
|
landingStrategy: LandingStrategyEnum,
|
|
29193
29376
|
landingImageFormat: LandingImageFormatEnum,
|
|
29194
|
-
competitorScanEnabled:
|
|
29195
|
-
paymentMethods:
|
|
29196
|
-
productContext:
|
|
29197
|
-
creativeDirection:
|
|
29198
|
-
headline:
|
|
29199
|
-
subheadline:
|
|
29377
|
+
competitorScanEnabled: z118.boolean(),
|
|
29378
|
+
paymentMethods: z118.string().trim().min(1).max(240).nullable(),
|
|
29379
|
+
productContext: z118.string().trim().min(1).max(3e3).nullable(),
|
|
29380
|
+
creativeDirection: z118.string().trim().min(1).max(500).nullable(),
|
|
29381
|
+
headline: z118.string().trim().min(1).max(120).nullable(),
|
|
29382
|
+
subheadline: z118.string().trim().min(1).max(160).nullable()
|
|
29200
29383
|
}).strict()
|
|
29201
29384
|
]);
|
|
29202
|
-
var ImageInput =
|
|
29385
|
+
var ImageInput = z118.object({
|
|
29203
29386
|
images: CreativeRefs.images.optional(),
|
|
29204
29387
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
29205
|
-
productTitle:
|
|
29206
|
-
primaryAngle:
|
|
29388
|
+
productTitle: z118.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
|
|
29389
|
+
primaryAngle: z118.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.'),
|
|
29207
29390
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
29208
29391
|
language: CreativeRefs.language,
|
|
29209
29392
|
country: CreativeRefs.country,
|
|
29210
29393
|
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."),
|
|
29211
29394
|
imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
|
|
29212
|
-
features:
|
|
29395
|
+
features: z118.array(z118.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
|
|
29213
29396
|
price: CreativeRefs.price,
|
|
29214
|
-
omitPrice:
|
|
29397
|
+
omitPrice: z118.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."),
|
|
29215
29398
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
29216
29399
|
offer: CreativeRefs.offer,
|
|
29217
29400
|
productLabel: CreativeRefs.productLabel,
|
|
29218
29401
|
isCombo: CreativeRefs.isCombo,
|
|
29219
29402
|
brandId: CreativeRefs.brandId
|
|
29220
29403
|
});
|
|
29221
|
-
var EditImageCreativeInput =
|
|
29222
|
-
taskId:
|
|
29223
|
-
variantIndex:
|
|
29224
|
-
clientRequestId:
|
|
29225
|
-
instruction:
|
|
29404
|
+
var EditImageCreativeInput = z118.object({
|
|
29405
|
+
taskId: z118.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
|
|
29406
|
+
variantIndex: z118.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
|
|
29407
|
+
clientRequestId: z118.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."),
|
|
29408
|
+
instruction: z118.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".')
|
|
29226
29409
|
});
|
|
29227
|
-
var LandingInput =
|
|
29228
|
-
includeInitialLandingGif:
|
|
29410
|
+
var LandingInput = z118.object({
|
|
29411
|
+
includeInitialLandingGif: z118.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."),
|
|
29229
29412
|
images: CreativeRefs.images.optional(),
|
|
29230
29413
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
29231
29414
|
language: CreativeRefs.language,
|
|
29232
29415
|
country: CreativeRefs.country,
|
|
29233
29416
|
creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
|
|
29234
|
-
salesAngle:
|
|
29417
|
+
salesAngle: z118.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.'),
|
|
29235
29418
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
29236
29419
|
price: CreativeRefs.price,
|
|
29237
29420
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
@@ -29513,8 +29696,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
29513
29696
|
server.registerTool("get_image_edit_status", {
|
|
29514
29697
|
description: imageEditStatusGuidance.summary,
|
|
29515
29698
|
inputSchema: {
|
|
29516
|
-
taskId:
|
|
29517
|
-
operationId:
|
|
29699
|
+
taskId: z118.string().uuid(),
|
|
29700
|
+
operationId: z118.string().uuid()
|
|
29518
29701
|
},
|
|
29519
29702
|
annotations: READS_INTERNAL
|
|
29520
29703
|
}, async (input) => {
|
|
@@ -29571,10 +29754,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
29571
29754
|
__name(registerCreativeTools, "registerCreativeTools");
|
|
29572
29755
|
|
|
29573
29756
|
// src/tools/creative-variants.ts
|
|
29574
|
-
import { z as
|
|
29757
|
+
import { z as z119 } from "zod";
|
|
29575
29758
|
var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
|
|
29576
29759
|
var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
|
|
29577
|
-
var LandingSectionKeyEnum =
|
|
29760
|
+
var LandingSectionKeyEnum = z119.enum([
|
|
29578
29761
|
"problem_hook",
|
|
29579
29762
|
"problem_cost",
|
|
29580
29763
|
"solution_mechanism",
|
|
@@ -29614,24 +29797,24 @@ var LandingSectionKeyEnum = z118.enum([
|
|
|
29614
29797
|
"lifestyle_fit",
|
|
29615
29798
|
"join_lifestyle"
|
|
29616
29799
|
]);
|
|
29617
|
-
var CreativeVariantKindEnum =
|
|
29800
|
+
var CreativeVariantKindEnum = z119.enum([
|
|
29618
29801
|
"video",
|
|
29619
29802
|
"image",
|
|
29620
29803
|
"landing"
|
|
29621
29804
|
]);
|
|
29622
|
-
var EstimateCreativeVariantInputBase =
|
|
29623
|
-
sourceTaskId:
|
|
29805
|
+
var EstimateCreativeVariantInputBase = z119.object({
|
|
29806
|
+
sourceTaskId: z119.string().uuid().describe("ID de la tarea original completada."),
|
|
29624
29807
|
kind: CreativeVariantKindEnum,
|
|
29625
29808
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
|
|
29626
29809
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
|
|
29627
|
-
nVariants:
|
|
29810
|
+
nVariants: z119.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
29628
29811
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
|
|
29629
|
-
instructions:
|
|
29812
|
+
instructions: z119.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.")
|
|
29630
29813
|
}).strict();
|
|
29631
29814
|
var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
29632
29815
|
if (input.kind === "video" && input.nVariants !== void 0) {
|
|
29633
29816
|
ctx.addIssue({
|
|
29634
|
-
code:
|
|
29817
|
+
code: z119.ZodIssueCode.custom,
|
|
29635
29818
|
path: [
|
|
29636
29819
|
"nVariants"
|
|
29637
29820
|
],
|
|
@@ -29641,7 +29824,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
29641
29824
|
if (input.kind !== "video") {
|
|
29642
29825
|
if (input.videoPreset !== void 0) {
|
|
29643
29826
|
ctx.addIssue({
|
|
29644
|
-
code:
|
|
29827
|
+
code: z119.ZodIssueCode.custom,
|
|
29645
29828
|
path: [
|
|
29646
29829
|
"videoPreset"
|
|
29647
29830
|
],
|
|
@@ -29650,7 +29833,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
29650
29833
|
}
|
|
29651
29834
|
if (input.videoResolution !== void 0) {
|
|
29652
29835
|
ctx.addIssue({
|
|
29653
|
-
code:
|
|
29836
|
+
code: z119.ZodIssueCode.custom,
|
|
29654
29837
|
path: [
|
|
29655
29838
|
"videoResolution"
|
|
29656
29839
|
],
|
|
@@ -29660,7 +29843,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
29660
29843
|
}
|
|
29661
29844
|
if (input.kind !== "image" && input.nVariants !== void 0) {
|
|
29662
29845
|
ctx.addIssue({
|
|
29663
|
-
code:
|
|
29846
|
+
code: z119.ZodIssueCode.custom,
|
|
29664
29847
|
path: [
|
|
29665
29848
|
"nVariants"
|
|
29666
29849
|
],
|
|
@@ -29670,7 +29853,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
29670
29853
|
if (input.kind !== "landing") {
|
|
29671
29854
|
if (input.sectionKey !== void 0) {
|
|
29672
29855
|
ctx.addIssue({
|
|
29673
|
-
code:
|
|
29856
|
+
code: z119.ZodIssueCode.custom,
|
|
29674
29857
|
path: [
|
|
29675
29858
|
"sectionKey"
|
|
29676
29859
|
],
|
|
@@ -29679,7 +29862,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
29679
29862
|
}
|
|
29680
29863
|
if (input.instructions !== void 0) {
|
|
29681
29864
|
ctx.addIssue({
|
|
29682
|
-
code:
|
|
29865
|
+
code: z119.ZodIssueCode.custom,
|
|
29683
29866
|
path: [
|
|
29684
29867
|
"instructions"
|
|
29685
29868
|
],
|
|
@@ -29688,31 +29871,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
29688
29871
|
}
|
|
29689
29872
|
}
|
|
29690
29873
|
});
|
|
29691
|
-
var CreateCreativeVariantInputBase =
|
|
29692
|
-
sourceTaskId:
|
|
29874
|
+
var CreateCreativeVariantInputBase = z119.object({
|
|
29875
|
+
sourceTaskId: z119.string().uuid().describe("ID de la tarea original completada."),
|
|
29693
29876
|
kind: CreativeVariantKindEnum,
|
|
29694
|
-
confirm:
|
|
29695
|
-
clientRequestId:
|
|
29696
|
-
angle:
|
|
29697
|
-
buyerPersona:
|
|
29698
|
-
scriptNotes:
|
|
29699
|
-
creativeDirection:
|
|
29877
|
+
confirm: z119.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
|
|
29878
|
+
clientRequestId: z119.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."),
|
|
29879
|
+
angle: z119.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
|
|
29880
|
+
buyerPersona: z119.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
|
|
29881
|
+
scriptNotes: z119.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
|
|
29882
|
+
creativeDirection: z119.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
|
|
29700
29883
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
|
|
29701
29884
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
|
|
29702
|
-
generateAiMusic:
|
|
29703
|
-
nVariants:
|
|
29885
|
+
generateAiMusic: z119.boolean().optional().describe("Opcional para video."),
|
|
29886
|
+
nVariants: z119.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
29704
29887
|
imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
|
|
29705
29888
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
|
|
29706
29889
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
|
|
29707
29890
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
|
|
29708
|
-
styleMix:
|
|
29891
|
+
styleMix: z119.boolean().optional().describe("Opcional para imagen."),
|
|
29709
29892
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
|
|
29710
|
-
instructions:
|
|
29893
|
+
instructions: z119.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.")
|
|
29711
29894
|
}).strict();
|
|
29712
29895
|
var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
29713
29896
|
if ((input.kind === "video" || input.kind === "image") && !input.angle) {
|
|
29714
29897
|
ctx.addIssue({
|
|
29715
|
-
code:
|
|
29898
|
+
code: z119.ZodIssueCode.custom,
|
|
29716
29899
|
path: [
|
|
29717
29900
|
"angle"
|
|
29718
29901
|
],
|
|
@@ -29721,7 +29904,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
29721
29904
|
}
|
|
29722
29905
|
if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
|
|
29723
29906
|
ctx.addIssue({
|
|
29724
|
-
code:
|
|
29907
|
+
code: z119.ZodIssueCode.custom,
|
|
29725
29908
|
path: [
|
|
29726
29909
|
"instructions"
|
|
29727
29910
|
],
|
|
@@ -29767,7 +29950,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
29767
29950
|
for (const field of fieldsByKind[input.kind]) {
|
|
29768
29951
|
if (input[field] !== void 0) {
|
|
29769
29952
|
ctx.addIssue({
|
|
29770
|
-
code:
|
|
29953
|
+
code: z119.ZodIssueCode.custom,
|
|
29771
29954
|
path: [
|
|
29772
29955
|
field
|
|
29773
29956
|
],
|
|
@@ -29900,13 +30083,13 @@ function registerCreativeVariantTools(server, api) {
|
|
|
29900
30083
|
__name(registerCreativeVariantTools, "registerCreativeVariantTools");
|
|
29901
30084
|
|
|
29902
30085
|
// src/tools/script-review.ts
|
|
29903
|
-
import { z as
|
|
30086
|
+
import { z as z120 } from "zod";
|
|
29904
30087
|
var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
|
|
29905
30088
|
var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
|
|
29906
30089
|
var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
|
|
29907
|
-
var GetVideoScriptInput =
|
|
29908
|
-
taskId:
|
|
29909
|
-
angleKey:
|
|
30090
|
+
var GetVideoScriptInput = z120.object({
|
|
30091
|
+
taskId: z120.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
|
|
30092
|
+
angleKey: z120.string().min(1).optional().describe('Clave del \xE1ngulo cuyo guion se quiere leer (formato "angle_0", "angle_1", ...). REQUERIDO para tareas multi-angle: si se omite, el backend resuelve a "angle_0" LITERAL (no "el primer pendiente"), as\xED que en multi-angle donde angle_0 ya est\xE9 aprobado/saltado obtendr\xEDas status="approved" y nunca alcanzar\xEDas el \xE1ngulo realmente pendiente. Para single-angle puede omitirse.')
|
|
29910
30093
|
}).strict();
|
|
29911
30094
|
var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
|
|
29912
30095
|
var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
|
|
@@ -29989,7 +30172,7 @@ function registerScriptReviewTools(server, api) {
|
|
|
29989
30172
|
__name(registerScriptReviewTools, "registerScriptReviewTools");
|
|
29990
30173
|
|
|
29991
30174
|
// src/tools/connections.ts
|
|
29992
|
-
import { z as
|
|
30175
|
+
import { z as z121 } from "zod";
|
|
29993
30176
|
var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
|
|
29994
30177
|
var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
|
|
29995
30178
|
var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
|
|
@@ -29998,7 +30181,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
|
|
|
29998
30181
|
function registerConnectionTools(server, api) {
|
|
29999
30182
|
server.registerTool("list_shopify_shops", {
|
|
30000
30183
|
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.",
|
|
30001
|
-
inputSchema:
|
|
30184
|
+
inputSchema: z121.object({}).shape,
|
|
30002
30185
|
annotations: READS_INTERNAL
|
|
30003
30186
|
}, async () => {
|
|
30004
30187
|
try {
|
|
@@ -30010,10 +30193,10 @@ function registerConnectionTools(server, api) {
|
|
|
30010
30193
|
});
|
|
30011
30194
|
server.registerTool("list_shopify_products", {
|
|
30012
30195
|
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.',
|
|
30013
|
-
inputSchema:
|
|
30014
|
-
shopDomain:
|
|
30015
|
-
query:
|
|
30016
|
-
taskId:
|
|
30196
|
+
inputSchema: z121.object({
|
|
30197
|
+
shopDomain: z121.string().min(3).max(120),
|
|
30198
|
+
query: z121.string().trim().max(120).optional(),
|
|
30199
|
+
taskId: z121.string().uuid().optional()
|
|
30017
30200
|
}).shape,
|
|
30018
30201
|
annotations: READS_EXTERNAL
|
|
30019
30202
|
}, async ({ shopDomain, query, taskId }) => {
|
|
@@ -30031,7 +30214,7 @@ function registerConnectionTools(server, api) {
|
|
|
30031
30214
|
});
|
|
30032
30215
|
server.registerTool("list_meta_ad_accounts", {
|
|
30033
30216
|
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.",
|
|
30034
|
-
inputSchema:
|
|
30217
|
+
inputSchema: z121.object({}).shape,
|
|
30035
30218
|
annotations: READS_EXTERNAL
|
|
30036
30219
|
}, async () => {
|
|
30037
30220
|
try {
|
|
@@ -30043,7 +30226,7 @@ function registerConnectionTools(server, api) {
|
|
|
30043
30226
|
});
|
|
30044
30227
|
server.registerTool("list_meta_destinations", {
|
|
30045
30228
|
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.",
|
|
30046
|
-
inputSchema:
|
|
30229
|
+
inputSchema: z121.object({}).shape,
|
|
30047
30230
|
annotations: READS_EXTERNAL,
|
|
30048
30231
|
_meta: {
|
|
30049
30232
|
"openai/widgetAccessible": true
|
|
@@ -30058,7 +30241,7 @@ function registerConnectionTools(server, api) {
|
|
|
30058
30241
|
});
|
|
30059
30242
|
server.registerTool("list_tiktok_advertisers", {
|
|
30060
30243
|
description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
|
|
30061
|
-
inputSchema:
|
|
30244
|
+
inputSchema: z121.object({}).shape,
|
|
30062
30245
|
annotations: READS_EXTERNAL
|
|
30063
30246
|
}, async () => {
|
|
30064
30247
|
try {
|
|
@@ -30072,7 +30255,7 @@ function registerConnectionTools(server, api) {
|
|
|
30072
30255
|
__name(registerConnectionTools, "registerConnectionTools");
|
|
30073
30256
|
|
|
30074
30257
|
// src/tools/actors.ts
|
|
30075
|
-
import { z as
|
|
30258
|
+
import { z as z122 } from "zod";
|
|
30076
30259
|
var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
|
|
30077
30260
|
var actorVoiceGuidance = {
|
|
30078
30261
|
capabilities: getProductMakerCapabilityModelGuidance("get_actor_voice_capabilities"),
|
|
@@ -30112,7 +30295,7 @@ function sanitizeVoiceResult(value) {
|
|
|
30112
30295
|
__name(sanitizeVoiceResult, "sanitizeVoiceResult");
|
|
30113
30296
|
function registerActorTools(server, api) {
|
|
30114
30297
|
const actor = {
|
|
30115
|
-
actorId:
|
|
30298
|
+
actorId: z122.string().min(1).max(64)
|
|
30116
30299
|
};
|
|
30117
30300
|
const safe = /* @__PURE__ */ __name(async (request) => {
|
|
30118
30301
|
try {
|
|
@@ -30141,8 +30324,8 @@ function registerActorTools(server, api) {
|
|
|
30141
30324
|
inputSchema: {
|
|
30142
30325
|
...actor,
|
|
30143
30326
|
draft: ActorVoiceDraftSchema,
|
|
30144
|
-
requestKey:
|
|
30145
|
-
acceptedQuoteId:
|
|
30327
|
+
requestKey: z122.string().trim().min(1).max(128),
|
|
30328
|
+
acceptedQuoteId: z122.string().trim().min(1).max(128)
|
|
30146
30329
|
},
|
|
30147
30330
|
annotations: CREATES_PAID
|
|
30148
30331
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews`, body)));
|
|
@@ -30150,7 +30333,7 @@ function registerActorTools(server, api) {
|
|
|
30150
30333
|
description: actorVoiceGuidance.get.summary,
|
|
30151
30334
|
inputSchema: {
|
|
30152
30335
|
...actor,
|
|
30153
|
-
candidateId:
|
|
30336
|
+
candidateId: z122.string().min(1).max(64)
|
|
30154
30337
|
},
|
|
30155
30338
|
// Polling can resume the first paid submission of an accepted quote.
|
|
30156
30339
|
// The immutable candidate/operation key keeps recovery idempotent.
|
|
@@ -30163,16 +30346,16 @@ function registerActorTools(server, api) {
|
|
|
30163
30346
|
description: actorVoiceGuidance.approve.summary,
|
|
30164
30347
|
inputSchema: {
|
|
30165
30348
|
...actor,
|
|
30166
|
-
candidateId:
|
|
30167
|
-
expectedRevision:
|
|
30168
|
-
expectedApprovedRevision:
|
|
30349
|
+
candidateId: z122.string().min(1).max(64),
|
|
30350
|
+
expectedRevision: z122.number().int().positive(),
|
|
30351
|
+
expectedApprovedRevision: z122.number().int().positive().nullable().optional()
|
|
30169
30352
|
},
|
|
30170
30353
|
// Replaces the selected voice and withdraws the old catalog grants.
|
|
30171
30354
|
annotations: OVERWRITES_INTERNAL
|
|
30172
30355
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/approve`, body)));
|
|
30173
30356
|
server.registerTool("list_actors", {
|
|
30174
30357
|
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.",
|
|
30175
|
-
inputSchema:
|
|
30358
|
+
inputSchema: z122.object({}).shape,
|
|
30176
30359
|
annotations: READS_INTERNAL
|
|
30177
30360
|
}, async () => {
|
|
30178
30361
|
try {
|
|
@@ -30205,7 +30388,7 @@ function registerActorTools(server, api) {
|
|
|
30205
30388
|
__name(registerActorTools, "registerActorTools");
|
|
30206
30389
|
|
|
30207
30390
|
// src/tools/publish.ts
|
|
30208
|
-
import { z as
|
|
30391
|
+
import { z as z123 } from "zod";
|
|
30209
30392
|
|
|
30210
30393
|
// src/tools/meta-publish-attempt-id.ts
|
|
30211
30394
|
var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
|
|
@@ -30244,40 +30427,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
|
|
|
30244
30427
|
var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
|
|
30245
30428
|
var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
|
|
30246
30429
|
var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
|
|
30247
|
-
var ShopifyInput =
|
|
30248
|
-
taskId:
|
|
30249
|
-
shopDomain:
|
|
30430
|
+
var ShopifyInput = z123.object({
|
|
30431
|
+
taskId: z123.string().min(1),
|
|
30432
|
+
shopDomain: z123.string().min(1),
|
|
30250
30433
|
/** Override: number of landing images to include. Default = ALL images the
|
|
30251
30434
|
* task generated (the MCP fetches /v1/results first to count). Bounded
|
|
30252
30435
|
* generously here; the backend validates each index against
|
|
30253
30436
|
* landing.images.length and rejects out-of-range. */
|
|
30254
|
-
numLandingImages:
|
|
30255
|
-
variantIndex:
|
|
30437
|
+
numLandingImages: z123.number().int().min(1).max(20).optional(),
|
|
30438
|
+
variantIndex: z123.number().int().min(0).optional(),
|
|
30256
30439
|
/** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
|
|
30257
30440
|
* When true, the landing renders variant-picker pills; when false, it ships
|
|
30258
30441
|
* a single-option product page. Defaults to false. */
|
|
30259
|
-
showVariantPicker:
|
|
30442
|
+
showVariantPicker: z123.boolean().optional(),
|
|
30260
30443
|
/** Default `auto` updates the product previously published for this task and
|
|
30261
30444
|
* shop. Use `existing` with targetProductId to choose another product, or
|
|
30262
30445
|
* `new` only when the user explicitly wants a duplicate/new listing. */
|
|
30263
|
-
publicationMode:
|
|
30446
|
+
publicationMode: z123.enum([
|
|
30264
30447
|
"auto",
|
|
30265
30448
|
"existing",
|
|
30266
30449
|
"new"
|
|
30267
30450
|
]).optional(),
|
|
30268
30451
|
/** Shopify product GID, numeric id, or admin product URL. Required when
|
|
30269
30452
|
* publicationMode is `existing`. */
|
|
30270
|
-
targetProductId:
|
|
30453
|
+
targetProductId: z123.string().trim().min(1).max(300).optional(),
|
|
30271
30454
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
30272
|
-
announcementBarEnabled:
|
|
30273
|
-
announcementBarText:
|
|
30455
|
+
announcementBarEnabled: z123.boolean().optional(),
|
|
30456
|
+
announcementBarText: z123.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
|
|
30274
30457
|
commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
|
|
30275
|
-
confirmed:
|
|
30458
|
+
confirmed: z123.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
|
|
30276
30459
|
});
|
|
30277
30460
|
var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
|
|
30278
30461
|
if (value.commerceCorrection && value.confirmed !== true) {
|
|
30279
30462
|
ctx.addIssue({
|
|
30280
|
-
code:
|
|
30463
|
+
code: z123.ZodIssueCode.custom,
|
|
30281
30464
|
path: [
|
|
30282
30465
|
"confirmed"
|
|
30283
30466
|
],
|
|
@@ -30286,7 +30469,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
30286
30469
|
}
|
|
30287
30470
|
if (value.announcementBarEnabled && !value.announcementBarText) {
|
|
30288
30471
|
ctx.addIssue({
|
|
30289
|
-
code:
|
|
30472
|
+
code: z123.ZodIssueCode.custom,
|
|
30290
30473
|
path: [
|
|
30291
30474
|
"announcementBarText"
|
|
30292
30475
|
],
|
|
@@ -30295,7 +30478,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
30295
30478
|
}
|
|
30296
30479
|
if (!value.announcementBarEnabled && value.announcementBarText) {
|
|
30297
30480
|
ctx.addIssue({
|
|
30298
|
-
code:
|
|
30481
|
+
code: z123.ZodIssueCode.custom,
|
|
30299
30482
|
path: [
|
|
30300
30483
|
"announcementBarText"
|
|
30301
30484
|
],
|
|
@@ -30309,91 +30492,91 @@ function parseShopifyInput(rawInput) {
|
|
|
30309
30492
|
return parsed.data;
|
|
30310
30493
|
}
|
|
30311
30494
|
__name(parseShopifyInput, "parseShopifyInput");
|
|
30312
|
-
var McpCampaignConfig =
|
|
30495
|
+
var McpCampaignConfig = z123.object({
|
|
30313
30496
|
/** ALWAYS in US dollars, whatever the ad account's currency is. ProductMaker
|
|
30314
30497
|
* converts to the account currency server-side. Do NOT pre-convert: on a COP
|
|
30315
30498
|
* account the user's "60.000 al día" is `dailyBudgetUsd: 15`, not 60000. */
|
|
30316
|
-
dailyBudgetUsd:
|
|
30499
|
+
dailyBudgetUsd: z123.number().positive().optional(),
|
|
30317
30500
|
/** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
|
|
30318
30501
|
* normalizes at validation). Meta accepts max 1 (single-country ad set).
|
|
30319
30502
|
* TikTok takes only the first entry. */
|
|
30320
|
-
targetCountries:
|
|
30321
|
-
campaignName:
|
|
30503
|
+
targetCountries: z123.array(CountryIso2Schema).max(1).optional(),
|
|
30504
|
+
campaignName: z123.string().trim().min(1).max(100).optional()
|
|
30322
30505
|
});
|
|
30323
30506
|
var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
|
|
30324
|
-
var MetaInput =
|
|
30325
|
-
taskId:
|
|
30507
|
+
var MetaInput = z123.object({
|
|
30508
|
+
taskId: z123.string().min(1),
|
|
30326
30509
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
30327
|
-
portfolioId:
|
|
30510
|
+
portfolioId: z123.string().trim().min(1),
|
|
30328
30511
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
30329
|
-
pageId:
|
|
30512
|
+
pageId: z123.string().trim().min(1),
|
|
30330
30513
|
adAccountId: McpAdAccountId,
|
|
30331
|
-
pixelId:
|
|
30332
|
-
landingUrl:
|
|
30514
|
+
pixelId: z123.string().min(1).optional(),
|
|
30515
|
+
landingUrl: z123.string().url().optional(),
|
|
30333
30516
|
/** Select which angles to publish by 0-based index. Omit to publish all
|
|
30334
30517
|
* successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
|
|
30335
|
-
angleIndexes:
|
|
30518
|
+
angleIndexes: z123.array(z123.number().int().nonnegative()).optional(),
|
|
30336
30519
|
campaignConfig: McpCampaignConfig.optional(),
|
|
30337
30520
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
30338
30521
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
30339
30522
|
* (Meta's primary-text limit). */
|
|
30340
|
-
primaryText:
|
|
30523
|
+
primaryText: z123.string().trim().min(1).max(500).optional(),
|
|
30341
30524
|
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
30342
30525
|
* (wa.me) instead of a landing page. */
|
|
30343
|
-
phoneNumber:
|
|
30526
|
+
phoneNumber: z123.string().min(8).max(32).optional()
|
|
30344
30527
|
});
|
|
30345
|
-
var GroupedTaskSource =
|
|
30346
|
-
type:
|
|
30347
|
-
taskId:
|
|
30348
|
-
angleIndex:
|
|
30349
|
-
videoVariant:
|
|
30528
|
+
var GroupedTaskSource = z123.object({
|
|
30529
|
+
type: z123.literal("task"),
|
|
30530
|
+
taskId: z123.string().min(1),
|
|
30531
|
+
angleIndex: z123.number().int().min(0).optional(),
|
|
30532
|
+
videoVariant: z123.enum([
|
|
30350
30533
|
"with_subtitles",
|
|
30351
30534
|
"without_subtitles"
|
|
30352
30535
|
]).optional(),
|
|
30353
|
-
imageVariantIndex:
|
|
30354
|
-
});
|
|
30355
|
-
var GroupedMediaSource =
|
|
30356
|
-
type:
|
|
30357
|
-
url:
|
|
30358
|
-
path:
|
|
30359
|
-
thumbnailUrl:
|
|
30360
|
-
thumbnailPath:
|
|
30536
|
+
imageVariantIndex: z123.number().int().min(0).optional()
|
|
30537
|
+
});
|
|
30538
|
+
var GroupedMediaSource = z123.object({
|
|
30539
|
+
type: z123.literal("media"),
|
|
30540
|
+
url: z123.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
|
|
30541
|
+
path: z123.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".'),
|
|
30542
|
+
thumbnailUrl: z123.string().url().optional(),
|
|
30543
|
+
thumbnailPath: z123.string().min(1).optional()
|
|
30361
30544
|
}).refine((value) => Boolean(value.url) !== Boolean(value.path), {
|
|
30362
30545
|
message: "media source needs exactly one of `url` or `path`"
|
|
30363
30546
|
}).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
|
|
30364
30547
|
message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
|
|
30365
30548
|
});
|
|
30366
|
-
var GroupedUploadedAssetSource =
|
|
30367
|
-
type:
|
|
30549
|
+
var GroupedUploadedAssetSource = z123.object({
|
|
30550
|
+
type: z123.literal("asset"),
|
|
30368
30551
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
30369
|
-
assetId:
|
|
30370
|
-
thumbnailAssetId:
|
|
30552
|
+
assetId: z123.string().uuid(),
|
|
30553
|
+
thumbnailAssetId: z123.string().uuid().optional()
|
|
30371
30554
|
});
|
|
30372
|
-
var GroupedCreative =
|
|
30373
|
-
type:
|
|
30555
|
+
var GroupedCreative = z123.object({
|
|
30556
|
+
type: z123.enum([
|
|
30374
30557
|
"image",
|
|
30375
30558
|
"video"
|
|
30376
30559
|
]),
|
|
30377
|
-
source:
|
|
30560
|
+
source: z123.union([
|
|
30378
30561
|
GroupedTaskSource,
|
|
30379
30562
|
GroupedMediaSource,
|
|
30380
30563
|
GroupedUploadedAssetSource
|
|
30381
30564
|
]),
|
|
30382
|
-
title:
|
|
30383
|
-
description:
|
|
30565
|
+
title: z123.string().max(120).optional(),
|
|
30566
|
+
description: z123.string().max(500).optional(),
|
|
30384
30567
|
cta: MetaCtaType.optional(),
|
|
30385
|
-
creativeId:
|
|
30568
|
+
creativeId: z123.string().min(1).optional()
|
|
30386
30569
|
});
|
|
30387
|
-
var GroupedCampaignConfigBase =
|
|
30570
|
+
var GroupedCampaignConfigBase = z123.object({
|
|
30388
30571
|
campaignType: MetaCampaignType.default("sales"),
|
|
30389
30572
|
optimizationMode: MetaOptimizationMode.default("advantage_plus"),
|
|
30390
30573
|
budgetMode: MetaBudgetMode.optional(),
|
|
30391
|
-
campaignDailyBudget:
|
|
30392
|
-
adSets:
|
|
30393
|
-
tempId:
|
|
30394
|
-
name:
|
|
30395
|
-
dailyBudget:
|
|
30396
|
-
creativeIds:
|
|
30574
|
+
campaignDailyBudget: z123.number().int().positive().optional(),
|
|
30575
|
+
adSets: z123.array(z123.object({
|
|
30576
|
+
tempId: z123.string().min(1).max(80),
|
|
30577
|
+
name: z123.string().min(1).max(100),
|
|
30578
|
+
dailyBudget: z123.number().int().positive().optional(),
|
|
30579
|
+
creativeIds: z123.array(z123.string().min(1)).min(1)
|
|
30397
30580
|
})).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
|
|
30398
30581
|
/**
|
|
30399
30582
|
* Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
|
|
@@ -30401,17 +30584,17 @@ var GroupedCampaignConfigBase = z122.object({
|
|
|
30401
30584
|
* opaque `invalid_literal` and made the WhatsApp destination — supported by
|
|
30402
30585
|
* the API since #849 — unreachable from this tool.
|
|
30403
30586
|
*/
|
|
30404
|
-
destination:
|
|
30405
|
-
|
|
30406
|
-
type:
|
|
30407
|
-
landingUrl:
|
|
30587
|
+
destination: z123.discriminatedUnion("type", [
|
|
30588
|
+
z123.object({
|
|
30589
|
+
type: z123.literal("landing"),
|
|
30590
|
+
landingUrl: z123.string().url()
|
|
30408
30591
|
}),
|
|
30409
|
-
|
|
30410
|
-
type:
|
|
30411
|
-
phoneNumber:
|
|
30592
|
+
z123.object({
|
|
30593
|
+
type: z123.literal("whatsapp"),
|
|
30594
|
+
phoneNumber: z123.string().min(8).max(32)
|
|
30412
30595
|
})
|
|
30413
30596
|
]),
|
|
30414
|
-
saveAsDefault:
|
|
30597
|
+
saveAsDefault: z123.boolean().default(false),
|
|
30415
30598
|
budgetPolicy: MetaBudgetPolicy.optional()
|
|
30416
30599
|
});
|
|
30417
30600
|
function resolveBudgetMode(value) {
|
|
@@ -30425,7 +30608,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
30425
30608
|
const budgetMode = resolveBudgetMode(value);
|
|
30426
30609
|
if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
|
|
30427
30610
|
ctx.addIssue({
|
|
30428
|
-
code:
|
|
30611
|
+
code: z123.ZodIssueCode.custom,
|
|
30429
30612
|
path: [
|
|
30430
30613
|
"campaignDailyBudget"
|
|
30431
30614
|
],
|
|
@@ -30436,7 +30619,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
30436
30619
|
value.adSets.forEach((adSet, index) => {
|
|
30437
30620
|
if (adSet.dailyBudget === void 0) {
|
|
30438
30621
|
ctx.addIssue({
|
|
30439
|
-
code:
|
|
30622
|
+
code: z123.ZodIssueCode.custom,
|
|
30440
30623
|
path: [
|
|
30441
30624
|
"adSets",
|
|
30442
30625
|
index,
|
|
@@ -30451,28 +30634,28 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
30451
30634
|
...value,
|
|
30452
30635
|
budgetMode: resolveBudgetMode(value)
|
|
30453
30636
|
}));
|
|
30454
|
-
var PublishCreativesToMetaInputBase =
|
|
30455
|
-
creatives:
|
|
30637
|
+
var PublishCreativesToMetaInputBase = z123.object({
|
|
30638
|
+
creatives: z123.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
|
|
30456
30639
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
30457
|
-
portfolioId:
|
|
30640
|
+
portfolioId: z123.string().trim().min(1),
|
|
30458
30641
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
30459
|
-
pageId:
|
|
30642
|
+
pageId: z123.string().trim().min(1),
|
|
30460
30643
|
adAccountId: McpAdAccountId,
|
|
30461
|
-
pixelId:
|
|
30644
|
+
pixelId: z123.string().min(1).optional(),
|
|
30462
30645
|
/** Required unless `campaignConfig.destination` is whatsapp — see the
|
|
30463
30646
|
* superRefine below. Mirrors the API's `FacebookCreateCampaignFromTasksBodySchema`. */
|
|
30464
|
-
landingUrl:
|
|
30647
|
+
landingUrl: z123.string().url().optional(),
|
|
30465
30648
|
/** ISO-2 code or resolvable country name — mirrors the API contract
|
|
30466
30649
|
* (CountryIso2Schema), which normalizes names to alpha-2 at validation. */
|
|
30467
30650
|
targetCountry: CountryIso2Schema,
|
|
30468
|
-
campaignName:
|
|
30651
|
+
campaignName: z123.string().trim().min(1).max(100),
|
|
30469
30652
|
campaignConfig: GroupedCampaignConfig.optional()
|
|
30470
30653
|
});
|
|
30471
30654
|
var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
|
|
30472
30655
|
const destination = value.campaignConfig?.destination;
|
|
30473
30656
|
if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl) {
|
|
30474
30657
|
ctx.addIssue({
|
|
30475
|
-
code:
|
|
30658
|
+
code: z123.ZodIssueCode.custom,
|
|
30476
30659
|
path: [
|
|
30477
30660
|
"landingUrl"
|
|
30478
30661
|
],
|
|
@@ -30481,7 +30664,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
30481
30664
|
}
|
|
30482
30665
|
if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
|
|
30483
30666
|
ctx.addIssue({
|
|
30484
|
-
code:
|
|
30667
|
+
code: z123.ZodIssueCode.custom,
|
|
30485
30668
|
path: [
|
|
30486
30669
|
"campaignConfig",
|
|
30487
30670
|
"destination",
|
|
@@ -30500,16 +30683,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
30500
30683
|
}
|
|
30501
30684
|
return value;
|
|
30502
30685
|
});
|
|
30503
|
-
var PresignUploadResponseSchema =
|
|
30504
|
-
uploadUrl:
|
|
30686
|
+
var PresignUploadResponseSchema = z123.object({
|
|
30687
|
+
uploadUrl: z123.string().url().refine((value) => {
|
|
30505
30688
|
const url = new URL(value);
|
|
30506
30689
|
return !url.username && !url.password && url.protocol === "https:";
|
|
30507
30690
|
}, "presigned upload URL must be HTTPS without embedded credentials"),
|
|
30508
|
-
publicUrl:
|
|
30691
|
+
publicUrl: z123.string().url().refine((value) => {
|
|
30509
30692
|
const url = new URL(value);
|
|
30510
30693
|
return !url.username && !url.password;
|
|
30511
30694
|
}, "public media URL must not contain embedded credentials"),
|
|
30512
|
-
stagingAssetId:
|
|
30695
|
+
stagingAssetId: z123.string().uuid()
|
|
30513
30696
|
});
|
|
30514
30697
|
async function uploadResolvedMedia(api, media, assetRole) {
|
|
30515
30698
|
if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
|
|
@@ -30534,16 +30717,16 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
|
|
|
30534
30717
|
return uploadResolvedMedia(api, media, assetRole);
|
|
30535
30718
|
}
|
|
30536
30719
|
__name(resolveAndUploadMedia, "resolveAndUploadMedia");
|
|
30537
|
-
var TikTokInput =
|
|
30538
|
-
taskId:
|
|
30539
|
-
advertiserId:
|
|
30540
|
-
pixelId:
|
|
30541
|
-
landingUrl:
|
|
30542
|
-
angleIndexes:
|
|
30720
|
+
var TikTokInput = z123.object({
|
|
30721
|
+
taskId: z123.string().min(1),
|
|
30722
|
+
advertiserId: z123.string().min(1),
|
|
30723
|
+
pixelId: z123.string().min(1).optional(),
|
|
30724
|
+
landingUrl: z123.string().url().optional(),
|
|
30725
|
+
angleIndexes: z123.array(z123.number().int().nonnegative()).optional(),
|
|
30543
30726
|
campaignConfig: McpCampaignConfig.optional(),
|
|
30544
30727
|
/** Override the ad's description (TikTok's body copy). If omitted,
|
|
30545
30728
|
* ProductMaker uses the auto-generated copy attached to the task. */
|
|
30546
|
-
primaryText:
|
|
30729
|
+
primaryText: z123.string().trim().min(1).max(500).optional()
|
|
30547
30730
|
});
|
|
30548
30731
|
function registerPublishTools(server, api, opts = {}) {
|
|
30549
30732
|
const transport = opts.transport ?? "http";
|
|
@@ -30895,39 +31078,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
|
|
|
30895
31078
|
|
|
30896
31079
|
// src/tools/meta-upload.ts
|
|
30897
31080
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
30898
|
-
import { z as
|
|
31081
|
+
import { z as z124 } from "zod";
|
|
30899
31082
|
var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
|
|
30900
|
-
var UploadSessionInputBase =
|
|
30901
|
-
mediaKind:
|
|
31083
|
+
var UploadSessionInputBase = z124.object({
|
|
31084
|
+
mediaKind: z124.enum([
|
|
30902
31085
|
"image",
|
|
30903
31086
|
"video",
|
|
30904
31087
|
"mixed"
|
|
30905
31088
|
]).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."),
|
|
30906
|
-
assetRole:
|
|
31089
|
+
assetRole: z124.enum([
|
|
30907
31090
|
"media",
|
|
30908
31091
|
"thumbnail"
|
|
30909
31092
|
]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
|
|
30910
|
-
uploadPurpose:
|
|
31093
|
+
uploadPurpose: z124.enum([
|
|
30911
31094
|
"product_reference",
|
|
30912
31095
|
"creative",
|
|
30913
31096
|
"generic"
|
|
30914
31097
|
]).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."),
|
|
30915
|
-
maxFiles:
|
|
31098
|
+
maxFiles: z124.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
30916
31099
|
});
|
|
30917
|
-
var OpenAiFileReference =
|
|
30918
|
-
download_url:
|
|
30919
|
-
file_id:
|
|
30920
|
-
mime_type:
|
|
30921
|
-
file_name:
|
|
31100
|
+
var OpenAiFileReference = z124.object({
|
|
31101
|
+
download_url: z124.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."),
|
|
31102
|
+
file_id: z124.string().min(1),
|
|
31103
|
+
mime_type: z124.string().min(1).optional(),
|
|
31104
|
+
file_name: z124.string().min(1).optional()
|
|
30922
31105
|
});
|
|
30923
31106
|
var UploadSessionToolInputShape = {
|
|
30924
31107
|
...UploadSessionInputBase.shape,
|
|
30925
|
-
files:
|
|
31108
|
+
files: z124.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.")
|
|
30926
31109
|
};
|
|
30927
|
-
var UploadSessionToolInput =
|
|
31110
|
+
var UploadSessionToolInput = z124.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
30928
31111
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
30929
31112
|
ctx.addIssue({
|
|
30930
|
-
code:
|
|
31113
|
+
code: z124.ZodIssueCode.custom,
|
|
30931
31114
|
path: [
|
|
30932
31115
|
"mediaKind"
|
|
30933
31116
|
],
|
|
@@ -30936,7 +31119,7 @@ var UploadSessionToolInput = z123.object(UploadSessionToolInputShape).superRefin
|
|
|
30936
31119
|
}
|
|
30937
31120
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
30938
31121
|
ctx.addIssue({
|
|
30939
|
-
code:
|
|
31122
|
+
code: z124.ZodIssueCode.custom,
|
|
30940
31123
|
path: [
|
|
30941
31124
|
"maxFiles"
|
|
30942
31125
|
],
|
|
@@ -30945,7 +31128,7 @@ var UploadSessionToolInput = z123.object(UploadSessionToolInputShape).superRefin
|
|
|
30945
31128
|
}
|
|
30946
31129
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
|
|
30947
31130
|
ctx.addIssue({
|
|
30948
|
-
code:
|
|
31131
|
+
code: z124.ZodIssueCode.custom,
|
|
30949
31132
|
path: [
|
|
30950
31133
|
"maxFiles"
|
|
30951
31134
|
],
|
|
@@ -30953,38 +31136,38 @@ var UploadSessionToolInput = z123.object(UploadSessionToolInputShape).superRefin
|
|
|
30953
31136
|
});
|
|
30954
31137
|
}
|
|
30955
31138
|
});
|
|
30956
|
-
var UploadSessionResponse =
|
|
30957
|
-
sessionId:
|
|
30958
|
-
uploadPageUrl:
|
|
30959
|
-
mediaKind:
|
|
31139
|
+
var UploadSessionResponse = z124.object({
|
|
31140
|
+
sessionId: z124.string().uuid(),
|
|
31141
|
+
uploadPageUrl: z124.string().url(),
|
|
31142
|
+
mediaKind: z124.enum([
|
|
30960
31143
|
"image",
|
|
30961
31144
|
"video",
|
|
30962
31145
|
"mixed"
|
|
30963
31146
|
]),
|
|
30964
|
-
assetRole:
|
|
31147
|
+
assetRole: z124.enum([
|
|
30965
31148
|
"media",
|
|
30966
31149
|
"thumbnail"
|
|
30967
31150
|
]),
|
|
30968
|
-
maxFiles:
|
|
30969
|
-
expiresAt:
|
|
31151
|
+
maxFiles: z124.number().int().positive(),
|
|
31152
|
+
expiresAt: z124.string().datetime()
|
|
30970
31153
|
});
|
|
30971
|
-
var UploadStatusInput =
|
|
30972
|
-
sessionId:
|
|
31154
|
+
var UploadStatusInput = z124.object({
|
|
31155
|
+
sessionId: z124.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
30973
31156
|
});
|
|
30974
|
-
var UniversalUploadStatusResponse =
|
|
30975
|
-
|
|
30976
|
-
status:
|
|
30977
|
-
assets:
|
|
31157
|
+
var UniversalUploadStatusResponse = z124.discriminatedUnion("status", [
|
|
31158
|
+
z124.object({
|
|
31159
|
+
status: z124.literal("pending"),
|
|
31160
|
+
assets: z124.array(z124.never()).length(0)
|
|
30978
31161
|
}),
|
|
30979
|
-
|
|
30980
|
-
status:
|
|
30981
|
-
assets:
|
|
30982
|
-
assetId:
|
|
30983
|
-
mediaKind:
|
|
31162
|
+
z124.object({
|
|
31163
|
+
status: z124.literal("uploaded"),
|
|
31164
|
+
assets: z124.array(z124.object({
|
|
31165
|
+
assetId: z124.string().uuid(),
|
|
31166
|
+
mediaKind: z124.enum([
|
|
30984
31167
|
"image",
|
|
30985
31168
|
"video"
|
|
30986
31169
|
]),
|
|
30987
|
-
assetRole:
|
|
31170
|
+
assetRole: z124.enum([
|
|
30988
31171
|
"media",
|
|
30989
31172
|
"thumbnail"
|
|
30990
31173
|
])
|
|
@@ -30992,13 +31175,13 @@ var UniversalUploadStatusResponse = z123.discriminatedUnion("status", [
|
|
|
30992
31175
|
})
|
|
30993
31176
|
]);
|
|
30994
31177
|
var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
|
|
30995
|
-
uploadPurpose:
|
|
31178
|
+
uploadPurpose: z124.enum([
|
|
30996
31179
|
"product_reference",
|
|
30997
31180
|
"creative",
|
|
30998
31181
|
"generic"
|
|
30999
31182
|
]),
|
|
31000
|
-
checkToolName:
|
|
31001
|
-
resolveEndpoint:
|
|
31183
|
+
checkToolName: z124.literal("check_media_upload"),
|
|
31184
|
+
resolveEndpoint: z124.string().url()
|
|
31002
31185
|
});
|
|
31003
31186
|
function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
|
|
31004
31187
|
const url = new URL(uploadPageUrl);
|
|
@@ -31089,15 +31272,15 @@ function registerMediaUploadTools(server, api) {
|
|
|
31089
31272
|
__name(registerMediaUploadTools, "registerMediaUploadTools");
|
|
31090
31273
|
|
|
31091
31274
|
// src/tools/campaigns.ts
|
|
31092
|
-
import { z as
|
|
31275
|
+
import { z as z125 } from "zod";
|
|
31093
31276
|
var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
|
|
31094
31277
|
var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
|
|
31095
|
-
var MetaStatusInput =
|
|
31096
|
-
campaignId:
|
|
31278
|
+
var MetaStatusInput = z125.object({
|
|
31279
|
+
campaignId: z125.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
|
|
31097
31280
|
});
|
|
31098
|
-
var TikTokStatusInput =
|
|
31099
|
-
campaignId:
|
|
31100
|
-
advertiserId:
|
|
31281
|
+
var TikTokStatusInput = z125.object({
|
|
31282
|
+
campaignId: z125.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
|
|
31283
|
+
advertiserId: z125.string().min(1).describe("The same advertiserId used to publish the campaign.")
|
|
31101
31284
|
});
|
|
31102
31285
|
function registerCampaignTools(server, api) {
|
|
31103
31286
|
server.registerTool("get_meta_campaign_status", {
|
|
@@ -31202,10 +31385,10 @@ function renderTikTokStatusMarkdown(r) {
|
|
|
31202
31385
|
__name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
|
|
31203
31386
|
|
|
31204
31387
|
// ../../packages/product-economics/src/product-costing.ts
|
|
31205
|
-
import { z as
|
|
31388
|
+
import { z as z127 } from "zod";
|
|
31206
31389
|
|
|
31207
31390
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
31208
|
-
import { z as
|
|
31391
|
+
import { z as z126 } from "zod";
|
|
31209
31392
|
|
|
31210
31393
|
// ../../packages/product-economics/src/product-costing-shipping-references.json
|
|
31211
31394
|
var product_costing_shipping_references_default = {
|
|
@@ -31269,21 +31452,21 @@ var product_costing_shipping_references_default = {
|
|
|
31269
31452
|
};
|
|
31270
31453
|
|
|
31271
31454
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
31272
|
-
var ShippingReferenceSchema =
|
|
31273
|
-
reference:
|
|
31274
|
-
min:
|
|
31275
|
-
max:
|
|
31276
|
-
updatedAt:
|
|
31277
|
-
confidence:
|
|
31455
|
+
var ShippingReferenceSchema = z126.object({
|
|
31456
|
+
reference: z126.number().positive(),
|
|
31457
|
+
min: z126.number().nonnegative(),
|
|
31458
|
+
max: z126.number().positive(),
|
|
31459
|
+
updatedAt: z126.string().date(),
|
|
31460
|
+
confidence: z126.enum([
|
|
31278
31461
|
"high",
|
|
31279
31462
|
"medium",
|
|
31280
31463
|
"medium-low"
|
|
31281
31464
|
]),
|
|
31282
|
-
sources:
|
|
31465
|
+
sources: z126.array(z126.string().url().startsWith("https://")).min(1).max(3)
|
|
31283
31466
|
}).superRefine(({ reference, min, max }, context) => {
|
|
31284
31467
|
if (min > reference || reference > max) {
|
|
31285
31468
|
context.addIssue({
|
|
31286
|
-
code:
|
|
31469
|
+
code: z126.ZodIssueCode.custom,
|
|
31287
31470
|
message: "shipping_reference_outside_range",
|
|
31288
31471
|
path: [
|
|
31289
31472
|
"reference"
|
|
@@ -31291,7 +31474,7 @@ var ShippingReferenceSchema = z125.object({
|
|
|
31291
31474
|
});
|
|
31292
31475
|
}
|
|
31293
31476
|
});
|
|
31294
|
-
var SHIPPING_REFERENCES =
|
|
31477
|
+
var SHIPPING_REFERENCES = z126.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
|
|
31295
31478
|
var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
|
|
31296
31479
|
var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
|
|
31297
31480
|
"MX",
|
|
@@ -31473,18 +31656,18 @@ function getProductCostingCountryName(country) {
|
|
|
31473
31656
|
__name(getProductCostingCountryName, "getProductCostingCountryName");
|
|
31474
31657
|
|
|
31475
31658
|
// ../../packages/product-economics/src/product-costing.ts
|
|
31476
|
-
var ProductCostingInputSchema =
|
|
31477
|
-
country:
|
|
31478
|
-
supplierCost:
|
|
31479
|
-
shippingCost:
|
|
31480
|
-
returnRate:
|
|
31481
|
-
cancellationRate:
|
|
31482
|
-
adsManagerCpa:
|
|
31483
|
-
desiredMargin:
|
|
31659
|
+
var ProductCostingInputSchema = z127.object({
|
|
31660
|
+
country: z127.string().refine(isProductCostingCountryCode, "unsupported_country"),
|
|
31661
|
+
supplierCost: z127.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
|
|
31662
|
+
shippingCost: z127.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
|
|
31663
|
+
returnRate: z127.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
31664
|
+
cancellationRate: z127.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
31665
|
+
adsManagerCpa: z127.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
|
|
31666
|
+
desiredMargin: z127.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
|
|
31484
31667
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
31485
31668
|
if (returnRate + cancellationRate >= 1) {
|
|
31486
31669
|
context.addIssue({
|
|
31487
|
-
code:
|
|
31670
|
+
code: z127.ZodIssueCode.custom,
|
|
31488
31671
|
message: "delivery_rate_positive",
|
|
31489
31672
|
path: [
|
|
31490
31673
|
"cancellationRate"
|
|
@@ -31581,15 +31764,15 @@ function calculateProductCosting(rawInput) {
|
|
|
31581
31764
|
__name(calculateProductCosting, "calculateProductCosting");
|
|
31582
31765
|
|
|
31583
31766
|
// src/tools/product-costing.ts
|
|
31584
|
-
import { z as
|
|
31767
|
+
import { z as z128 } from "zod";
|
|
31585
31768
|
var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
|
|
31586
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
31587
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
31588
|
-
var ProductCostingToolInput =
|
|
31589
|
-
country:
|
|
31769
|
+
var optionalAmount = /* @__PURE__ */ __name((description) => z128.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
|
|
31770
|
+
var optionalPercent = /* @__PURE__ */ __name((description) => z128.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
|
|
31771
|
+
var ProductCostingToolInput = z128.object({
|
|
31772
|
+
country: z128.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
31590
31773
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
31591
31774
|
}).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
|
|
31592
|
-
supplierCost:
|
|
31775
|
+
supplierCost: z128.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."),
|
|
31593
31776
|
supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
|
|
31594
31777
|
shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
|
|
31595
31778
|
shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
|
|
@@ -31752,7 +31935,7 @@ function formatPercent(value) {
|
|
|
31752
31935
|
__name(formatPercent, "formatPercent");
|
|
31753
31936
|
|
|
31754
31937
|
// src/tools/product-research.ts
|
|
31755
|
-
import { z as
|
|
31938
|
+
import { z as z129 } from "zod";
|
|
31756
31939
|
|
|
31757
31940
|
// src/tools/product-research-idempotency.ts
|
|
31758
31941
|
var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
|
|
@@ -32123,17 +32306,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
|
|
|
32123
32306
|
]);
|
|
32124
32307
|
var POLL_INTERVAL_MS = 5e3;
|
|
32125
32308
|
var MAX_WAIT_SECONDS = 120;
|
|
32126
|
-
var FindInput =
|
|
32309
|
+
var FindInput = z129.object({
|
|
32127
32310
|
targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
|
|
32128
32311
|
categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
|
|
32129
|
-
confirmed:
|
|
32130
|
-
waitSeconds:
|
|
32312
|
+
confirmed: z129.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
|
|
32313
|
+
waitSeconds: z129.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
|
|
32131
32314
|
});
|
|
32132
|
-
var GetInput =
|
|
32133
|
-
runId:
|
|
32315
|
+
var GetInput = z129.object({
|
|
32316
|
+
runId: z129.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
32134
32317
|
});
|
|
32135
|
-
var ListInput =
|
|
32136
|
-
limit:
|
|
32318
|
+
var ListInput = z129.object({
|
|
32319
|
+
limit: z129.number().int().min(1).max(20).default(10)
|
|
32137
32320
|
});
|
|
32138
32321
|
function textResult(text2) {
|
|
32139
32322
|
return {
|
|
@@ -32272,17 +32455,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
32272
32455
|
__name(registerProductResearchTools, "registerProductResearchTools");
|
|
32273
32456
|
|
|
32274
32457
|
// src/tools/dropshipping-projects.ts
|
|
32275
|
-
import { z as
|
|
32458
|
+
import { z as z130 } from "zod";
|
|
32276
32459
|
var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
|
|
32277
32460
|
var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
|
|
32278
32461
|
var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
|
|
32279
|
-
var ProjectId =
|
|
32280
|
-
var DropshippingProjectStatus =
|
|
32462
|
+
var ProjectId = z130.string().uuid();
|
|
32463
|
+
var DropshippingProjectStatus = z130.enum([
|
|
32281
32464
|
"active",
|
|
32282
32465
|
"completed",
|
|
32283
32466
|
"archived"
|
|
32284
32467
|
]);
|
|
32285
|
-
var DropshippingProjectPhase =
|
|
32468
|
+
var DropshippingProjectPhase = z130.enum([
|
|
32286
32469
|
"research",
|
|
32287
32470
|
"costing",
|
|
32288
32471
|
"media",
|
|
@@ -32291,21 +32474,21 @@ var DropshippingProjectPhase = z129.enum([
|
|
|
32291
32474
|
"advertising",
|
|
32292
32475
|
"complete"
|
|
32293
32476
|
]);
|
|
32294
|
-
var DropshippingRewardMilestone =
|
|
32477
|
+
var DropshippingRewardMilestone = z130.enum([
|
|
32295
32478
|
"product_selected",
|
|
32296
32479
|
"costing_saved",
|
|
32297
32480
|
"product_media_ready",
|
|
32298
32481
|
"creatives_completed",
|
|
32299
32482
|
"campaign_created"
|
|
32300
32483
|
]);
|
|
32301
|
-
var TargetCountry =
|
|
32484
|
+
var TargetCountry = z130.enum([
|
|
32302
32485
|
"CO",
|
|
32303
32486
|
"MX",
|
|
32304
32487
|
"PE",
|
|
32305
32488
|
"EC",
|
|
32306
32489
|
"CL"
|
|
32307
32490
|
]);
|
|
32308
|
-
var ResearchCategory =
|
|
32491
|
+
var ResearchCategory = z130.enum([
|
|
32309
32492
|
"auto",
|
|
32310
32493
|
"automotive",
|
|
32311
32494
|
"kitchen",
|
|
@@ -32320,7 +32503,7 @@ var ResearchCategory = z129.enum([
|
|
|
32320
32503
|
"garden",
|
|
32321
32504
|
"cleaning"
|
|
32322
32505
|
]);
|
|
32323
|
-
var HttpUrl3 =
|
|
32506
|
+
var HttpUrl3 = z130.string().url().max(2e3).refine((value) => {
|
|
32324
32507
|
try {
|
|
32325
32508
|
return [
|
|
32326
32509
|
"http:",
|
|
@@ -32330,45 +32513,45 @@ var HttpUrl3 = z129.string().url().max(2e3).refine((value) => {
|
|
|
32330
32513
|
return false;
|
|
32331
32514
|
}
|
|
32332
32515
|
}, "URL must use HTTP(S)");
|
|
32333
|
-
var ResearchCandidateOrigin =
|
|
32334
|
-
type:
|
|
32516
|
+
var ResearchCandidateOrigin = z130.object({
|
|
32517
|
+
type: z130.literal("research_candidate"),
|
|
32335
32518
|
runId: ProjectId,
|
|
32336
|
-
candidateSourceId:
|
|
32519
|
+
candidateSourceId: z130.string().min(1).max(160)
|
|
32337
32520
|
});
|
|
32338
|
-
var TaskOrigin =
|
|
32339
|
-
type:
|
|
32521
|
+
var TaskOrigin = z130.object({
|
|
32522
|
+
type: z130.literal("task"),
|
|
32340
32523
|
taskId: ProjectId
|
|
32341
32524
|
});
|
|
32342
|
-
var ManualOrigin =
|
|
32343
|
-
type:
|
|
32525
|
+
var ManualOrigin = z130.object({
|
|
32526
|
+
type: z130.literal("manual"),
|
|
32344
32527
|
clientRequestId: ProjectId,
|
|
32345
|
-
country:
|
|
32528
|
+
country: z130.string().min(2).max(3).optional()
|
|
32346
32529
|
});
|
|
32347
|
-
var StartProjectInput =
|
|
32348
|
-
origin:
|
|
32530
|
+
var StartProjectInput = z130.object({
|
|
32531
|
+
origin: z130.discriminatedUnion("type", [
|
|
32349
32532
|
ResearchCandidateOrigin,
|
|
32350
32533
|
TaskOrigin,
|
|
32351
32534
|
ManualOrigin
|
|
32352
32535
|
]),
|
|
32353
|
-
productName:
|
|
32536
|
+
productName: z130.string().trim().min(1).max(240).optional(),
|
|
32354
32537
|
productUrl: HttpUrl3.optional(),
|
|
32355
|
-
country:
|
|
32356
|
-
languageCode:
|
|
32538
|
+
country: z130.string().min(2).max(3).optional(),
|
|
32539
|
+
languageCode: z130.string().min(2).max(16).optional()
|
|
32357
32540
|
}).strict();
|
|
32358
|
-
var CostProjectInput =
|
|
32541
|
+
var CostProjectInput = z130.object({
|
|
32359
32542
|
projectId: ProjectId,
|
|
32360
|
-
version:
|
|
32361
|
-
country:
|
|
32543
|
+
version: z130.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
|
|
32544
|
+
country: z130.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
32362
32545
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
32363
32546
|
}).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
|
|
32364
|
-
supplierCost:
|
|
32365
|
-
shippingCost:
|
|
32366
|
-
returnRate:
|
|
32367
|
-
cancellationRate:
|
|
32368
|
-
adsManagerCpa:
|
|
32369
|
-
desiredMargin:
|
|
32370
|
-
});
|
|
32371
|
-
var GuideInput =
|
|
32547
|
+
supplierCost: z130.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."),
|
|
32548
|
+
shippingCost: z130.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
|
|
32549
|
+
returnRate: z130.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."),
|
|
32550
|
+
cancellationRate: z130.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."),
|
|
32551
|
+
adsManagerCpa: z130.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
32552
|
+
desiredMargin: z130.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
|
|
32553
|
+
});
|
|
32554
|
+
var GuideInput = z130.object({
|
|
32372
32555
|
projectId: ProjectId.optional()
|
|
32373
32556
|
}).strict();
|
|
32374
32557
|
var NEXT_ACTION_KINDS = [
|
|
@@ -32386,29 +32569,29 @@ var NEXT_ACTION_KINDS = [
|
|
|
32386
32569
|
"repair_meta_campaign",
|
|
32387
32570
|
"review_paused_campaign"
|
|
32388
32571
|
];
|
|
32389
|
-
var DropshippingProjectNextAction =
|
|
32390
|
-
kind:
|
|
32391
|
-
href:
|
|
32572
|
+
var DropshippingProjectNextAction = z130.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z130.object({
|
|
32573
|
+
kind: z130.literal(kind),
|
|
32574
|
+
href: z130.string().min(1)
|
|
32392
32575
|
})));
|
|
32393
|
-
var CostingInputSchema =
|
|
32394
|
-
country:
|
|
32395
|
-
supplierCost:
|
|
32396
|
-
shippingCost:
|
|
32397
|
-
returnRate:
|
|
32398
|
-
cancellationRate:
|
|
32399
|
-
adsManagerCpa:
|
|
32400
|
-
desiredMargin:
|
|
32576
|
+
var CostingInputSchema = z130.object({
|
|
32577
|
+
country: z130.string().min(2).max(3),
|
|
32578
|
+
supplierCost: z130.number().finite().positive(),
|
|
32579
|
+
shippingCost: z130.number().finite().nonnegative(),
|
|
32580
|
+
returnRate: z130.number().finite().min(0).lt(1),
|
|
32581
|
+
cancellationRate: z130.number().finite().min(0).lt(1),
|
|
32582
|
+
adsManagerCpa: z130.number().finite().nonnegative(),
|
|
32583
|
+
desiredMargin: z130.number().finite().min(0).lt(1)
|
|
32401
32584
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
32402
32585
|
if (returnRate + cancellationRate >= 1) context.addIssue({
|
|
32403
|
-
code:
|
|
32586
|
+
code: z130.ZodIssueCode.custom,
|
|
32404
32587
|
path: [
|
|
32405
32588
|
"cancellationRate"
|
|
32406
32589
|
]
|
|
32407
32590
|
});
|
|
32408
32591
|
});
|
|
32409
|
-
var FiniteCostingNumber =
|
|
32410
|
-
var CostingResultSchema =
|
|
32411
|
-
country:
|
|
32592
|
+
var FiniteCostingNumber = z130.number().finite();
|
|
32593
|
+
var CostingResultSchema = z130.object({
|
|
32594
|
+
country: z130.string().min(2).max(3),
|
|
32412
32595
|
deliveryRate: FiniteCostingNumber,
|
|
32413
32596
|
adjustedShippingCost: FiniteCostingNumber,
|
|
32414
32597
|
adjustedCpa: FiniteCostingNumber,
|
|
@@ -32421,45 +32604,45 @@ var CostingResultSchema = z129.object({
|
|
|
32421
32604
|
estimatedProfit: FiniteCostingNumber,
|
|
32422
32605
|
actualMargin: FiniteCostingNumber,
|
|
32423
32606
|
breakEvenAdsManagerCpa: FiniteCostingNumber,
|
|
32424
|
-
wasPriceAutoAdjusted:
|
|
32425
|
-
profitabilityStatus:
|
|
32426
|
-
});
|
|
32427
|
-
var RewardProgressSchema =
|
|
32428
|
-
campaignKey:
|
|
32429
|
-
totalCredits:
|
|
32430
|
-
earnedCredits:
|
|
32431
|
-
milestones:
|
|
32607
|
+
wasPriceAutoAdjusted: z130.boolean(),
|
|
32608
|
+
profitabilityStatus: z130.literal("healthy")
|
|
32609
|
+
});
|
|
32610
|
+
var RewardProgressSchema = z130.object({
|
|
32611
|
+
campaignKey: z130.literal("dropshipping-launch-v1"),
|
|
32612
|
+
totalCredits: z130.number().int().positive(),
|
|
32613
|
+
earnedCredits: z130.number().int().nonnegative(),
|
|
32614
|
+
milestones: z130.array(z130.object({
|
|
32432
32615
|
milestone: DropshippingRewardMilestone,
|
|
32433
|
-
credits:
|
|
32434
|
-
available:
|
|
32435
|
-
earned:
|
|
32616
|
+
credits: z130.number().int().positive(),
|
|
32617
|
+
available: z130.boolean().optional(),
|
|
32618
|
+
earned: z130.boolean(),
|
|
32436
32619
|
grantId: ProjectId.nullable(),
|
|
32437
|
-
grantedAt:
|
|
32620
|
+
grantedAt: z130.string().datetime().nullable()
|
|
32438
32621
|
})).length(DropshippingRewardMilestone.options.length)
|
|
32439
32622
|
});
|
|
32440
|
-
var ProjectResponseSchema =
|
|
32623
|
+
var ProjectResponseSchema = z130.object({
|
|
32441
32624
|
id: ProjectId,
|
|
32442
32625
|
taskId: ProjectId.nullable(),
|
|
32443
32626
|
status: DropshippingProjectStatus,
|
|
32444
|
-
originKey:
|
|
32627
|
+
originKey: z130.string().min(1),
|
|
32445
32628
|
researchRunId: ProjectId.nullable(),
|
|
32446
|
-
candidateSourceId:
|
|
32447
|
-
productName:
|
|
32629
|
+
candidateSourceId: z130.string().nullable(),
|
|
32630
|
+
productName: z130.string().nullable(),
|
|
32448
32631
|
productUrl: HttpUrl3.nullable(),
|
|
32449
32632
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
32450
|
-
targetCountry:
|
|
32451
|
-
languageCode:
|
|
32452
|
-
hasReferenceImage:
|
|
32453
|
-
hasWinnerReferenceImage:
|
|
32633
|
+
targetCountry: z130.string().nullable(),
|
|
32634
|
+
languageCode: z130.string().nullable(),
|
|
32635
|
+
hasReferenceImage: z130.boolean(),
|
|
32636
|
+
hasWinnerReferenceImage: z130.boolean(),
|
|
32454
32637
|
costingInput: CostingInputSchema.nullable(),
|
|
32455
32638
|
costingResult: CostingResultSchema.nullable(),
|
|
32456
|
-
costingVersion:
|
|
32457
|
-
version:
|
|
32639
|
+
costingVersion: z130.number().int().positive().nullable(),
|
|
32640
|
+
version: z130.number().int().positive(),
|
|
32458
32641
|
phase: DropshippingProjectPhase,
|
|
32459
32642
|
nextAction: DropshippingProjectNextAction.nullable(),
|
|
32460
32643
|
rewards: RewardProgressSchema,
|
|
32461
|
-
createdAt:
|
|
32462
|
-
updatedAt:
|
|
32644
|
+
createdAt: z130.string().datetime(),
|
|
32645
|
+
updatedAt: z130.string().datetime()
|
|
32463
32646
|
}).passthrough();
|
|
32464
32647
|
var NEXT_ACTION_GUIDANCE = {
|
|
32465
32648
|
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.",
|
|
@@ -32579,58 +32762,58 @@ function registerDropshippingProjectTools(server, api) {
|
|
|
32579
32762
|
__name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
|
|
32580
32763
|
|
|
32581
32764
|
// src/tools/daily-control.ts
|
|
32582
|
-
import { z as
|
|
32765
|
+
import { z as z131 } from "zod";
|
|
32583
32766
|
var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
|
|
32584
32767
|
var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
|
|
32585
32768
|
var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
|
|
32586
|
-
var ProviderCampaignIdentifier =
|
|
32587
|
-
var DateOnly =
|
|
32588
|
-
var DailyControlInput =
|
|
32769
|
+
var ProviderCampaignIdentifier = z131.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
|
|
32770
|
+
var DateOnly = z131.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
32771
|
+
var DailyControlInput = z131.object({
|
|
32589
32772
|
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."),
|
|
32590
|
-
days:
|
|
32591
|
-
projectId:
|
|
32773
|
+
days: z131.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
32774
|
+
projectId: z131.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
|
|
32592
32775
|
}).strict();
|
|
32593
|
-
var LinkCampaignInput =
|
|
32594
|
-
projectId:
|
|
32595
|
-
provider:
|
|
32776
|
+
var LinkCampaignInput = z131.object({
|
|
32777
|
+
projectId: z131.string().uuid(),
|
|
32778
|
+
provider: z131.enum([
|
|
32596
32779
|
"meta",
|
|
32597
32780
|
"tiktok"
|
|
32598
32781
|
]),
|
|
32599
32782
|
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."),
|
|
32600
32783
|
campaignId: ProviderCampaignIdentifier
|
|
32601
32784
|
}).strict();
|
|
32602
|
-
var ReportReturnsInput =
|
|
32603
|
-
projectId:
|
|
32785
|
+
var ReportReturnsInput = z131.object({
|
|
32786
|
+
projectId: z131.string().uuid(),
|
|
32604
32787
|
date: DateOnly,
|
|
32605
|
-
returnedOrders:
|
|
32606
|
-
note:
|
|
32788
|
+
returnedOrders: z131.number().int().min(0).max(1e5),
|
|
32789
|
+
note: z131.string().trim().max(280).optional()
|
|
32607
32790
|
}).strict();
|
|
32608
|
-
var DailyControlStatusMirror = DailyControlStatusEnum.or(
|
|
32609
|
-
var DailyControlLightMirror = DailyControlLightEnum.or(
|
|
32610
|
-
var DailyControlSourceMirror = DailyControlSourceEnum.or(
|
|
32611
|
-
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(
|
|
32612
|
-
var DailyControlDayMirror =
|
|
32613
|
-
date:
|
|
32614
|
-
returnedOrders:
|
|
32791
|
+
var DailyControlStatusMirror = DailyControlStatusEnum.or(z131.string());
|
|
32792
|
+
var DailyControlLightMirror = DailyControlLightEnum.or(z131.string());
|
|
32793
|
+
var DailyControlSourceMirror = DailyControlSourceEnum.or(z131.string());
|
|
32794
|
+
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z131.string());
|
|
32795
|
+
var DailyControlDayMirror = z131.object({
|
|
32796
|
+
date: z131.string(),
|
|
32797
|
+
returnedOrders: z131.number(),
|
|
32615
32798
|
returnedSource: DailyControlSourceMirror,
|
|
32616
32799
|
cancelledSource: DailyControlSourceMirror,
|
|
32617
|
-
hasEstimates:
|
|
32800
|
+
hasEstimates: z131.boolean(),
|
|
32618
32801
|
light: DailyControlLightMirror
|
|
32619
32802
|
}).passthrough();
|
|
32620
|
-
var DailyControlProductMirror =
|
|
32621
|
-
projectId:
|
|
32622
|
-
productName:
|
|
32803
|
+
var DailyControlProductMirror = z131.object({
|
|
32804
|
+
projectId: z131.string().uuid(),
|
|
32805
|
+
productName: z131.string().nullable(),
|
|
32623
32806
|
status: DailyControlStatusMirror,
|
|
32624
|
-
statusMessage:
|
|
32625
|
-
days:
|
|
32807
|
+
statusMessage: z131.string().nullable(),
|
|
32808
|
+
days: z131.array(DailyControlDayMirror),
|
|
32626
32809
|
verdict: DailyControlVerdictMirror.nullable(),
|
|
32627
|
-
rationale:
|
|
32810
|
+
rationale: z131.string().nullable()
|
|
32628
32811
|
}).passthrough();
|
|
32629
|
-
var DailyControlResponseMirror =
|
|
32630
|
-
since:
|
|
32631
|
-
until:
|
|
32632
|
-
products:
|
|
32633
|
-
archivedProjectSpend:
|
|
32812
|
+
var DailyControlResponseMirror = z131.object({
|
|
32813
|
+
since: z131.string(),
|
|
32814
|
+
until: z131.string(),
|
|
32815
|
+
products: z131.array(DailyControlProductMirror),
|
|
32816
|
+
archivedProjectSpend: z131.array(z131.unknown())
|
|
32634
32817
|
}).passthrough();
|
|
32635
32818
|
var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
|
|
32636
32819
|
function withWarnings(response) {
|
|
@@ -32705,7 +32888,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
|
|
|
32705
32888
|
// src/tools/product-control.ts
|
|
32706
32889
|
import { readFile, stat } from "fs/promises";
|
|
32707
32890
|
import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
|
|
32708
|
-
import { z as
|
|
32891
|
+
import { z as z132 } from "zod";
|
|
32709
32892
|
var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
|
|
32710
32893
|
var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
|
|
32711
32894
|
var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
|
|
@@ -32718,36 +32901,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
|
|
|
32718
32901
|
var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
|
|
32719
32902
|
var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
|
|
32720
32903
|
var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
|
|
32721
|
-
var DateOnly2 =
|
|
32904
|
+
var DateOnly2 = z132.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
32722
32905
|
var IMPORT_BATCH_MAX2 = 50;
|
|
32723
|
-
var ProductControlListInput =
|
|
32724
|
-
days:
|
|
32906
|
+
var ProductControlListInput = z132.object({
|
|
32907
|
+
days: z132.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
32725
32908
|
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."),
|
|
32726
|
-
shopDomain:
|
|
32909
|
+
shopDomain: z132.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
32727
32910
|
}).strict();
|
|
32728
|
-
var ImportableProductsInput =
|
|
32729
|
-
q:
|
|
32730
|
-
after:
|
|
32731
|
-
shopDomain:
|
|
32911
|
+
var ImportableProductsInput = z132.object({
|
|
32912
|
+
q: z132.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
|
|
32913
|
+
after: z132.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
|
|
32914
|
+
shopDomain: z132.string().min(1).optional()
|
|
32732
32915
|
}).strict();
|
|
32733
|
-
var ImportProductControlsInput =
|
|
32734
|
-
shopifyProductIds:
|
|
32916
|
+
var ImportProductControlsInput = z132.object({
|
|
32917
|
+
shopifyProductIds: z132.array(z132.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."),
|
|
32735
32918
|
// Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
|
|
32736
32919
|
// sin decir a cuál archivaría el producto bajo la tienda equivocada.
|
|
32737
|
-
shopDomain:
|
|
32920
|
+
shopDomain: z132.string().min(1)
|
|
32738
32921
|
}).strict();
|
|
32739
|
-
var SetProductCostingInput =
|
|
32740
|
-
shopDomain:
|
|
32741
|
-
shopifyProductId:
|
|
32742
|
-
targetCountry:
|
|
32743
|
-
supplierCost:
|
|
32744
|
-
shippingCost:
|
|
32745
|
-
returnRate:
|
|
32746
|
-
cancellationRate:
|
|
32922
|
+
var SetProductCostingInput = z132.object({
|
|
32923
|
+
shopDomain: z132.string().min(1),
|
|
32924
|
+
shopifyProductId: z132.string().min(1).max(64),
|
|
32925
|
+
targetCountry: z132.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
|
|
32926
|
+
supplierCost: z132.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
|
|
32927
|
+
shippingCost: z132.number().finite().nonnegative(),
|
|
32928
|
+
returnRate: z132.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
|
|
32929
|
+
cancellationRate: z132.number().finite().min(0).lt(1)
|
|
32747
32930
|
}).strict();
|
|
32748
|
-
var Count =
|
|
32749
|
-
var ReportProductCountsInput =
|
|
32750
|
-
productControlId:
|
|
32931
|
+
var Count = z132.number().int().min(0).max(1e5).nullable().optional();
|
|
32932
|
+
var ReportProductCountsInput = z132.object({
|
|
32933
|
+
productControlId: z132.string().uuid().describe("El identificador que devuelve get_product_control."),
|
|
32751
32934
|
date: DateOnly2,
|
|
32752
32935
|
orders: Count.describe("Pedidos que entraron ese d\xEDa."),
|
|
32753
32936
|
cancelledOrders: Count,
|
|
@@ -32757,36 +32940,36 @@ var ReportProductCountsInput = z131.object({
|
|
|
32757
32940
|
}).strict();
|
|
32758
32941
|
var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
|
|
32759
32942
|
var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
|
|
32760
|
-
var ImportOrdersFileInput =
|
|
32943
|
+
var ImportOrdersFileInput = z132.object({
|
|
32761
32944
|
/** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
|
|
32762
|
-
path:
|
|
32763
|
-
operationId:
|
|
32945
|
+
path: z132.string().min(1),
|
|
32946
|
+
operationId: z132.string().uuid().optional(),
|
|
32764
32947
|
/** Solo mirar: devuelve el resumen y no escribe nada. */
|
|
32765
|
-
dryRun:
|
|
32948
|
+
dryRun: z132.boolean().optional()
|
|
32766
32949
|
}).strict();
|
|
32767
|
-
var CreateOperationInput =
|
|
32768
|
-
countryCode:
|
|
32769
|
-
label:
|
|
32950
|
+
var CreateOperationInput = z132.object({
|
|
32951
|
+
countryCode: z132.string().length(2),
|
|
32952
|
+
label: z132.string().trim().min(1).max(60).optional()
|
|
32770
32953
|
}).strict();
|
|
32771
|
-
var MergeProductsInput =
|
|
32772
|
-
sourceId:
|
|
32773
|
-
targetId:
|
|
32954
|
+
var MergeProductsInput = z132.object({
|
|
32955
|
+
sourceId: z132.string().uuid(),
|
|
32956
|
+
targetId: z132.string().uuid()
|
|
32774
32957
|
}).strict();
|
|
32775
|
-
var SetMonthlyExpenseInput =
|
|
32776
|
-
month:
|
|
32958
|
+
var SetMonthlyExpenseInput = z132.object({
|
|
32959
|
+
month: z132.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
32777
32960
|
label: SaveMonthlyExpenseSchema.shape.label,
|
|
32778
|
-
amount:
|
|
32779
|
-
operationId:
|
|
32961
|
+
amount: z132.number().finite().min(0),
|
|
32962
|
+
operationId: z132.string().uuid().optional()
|
|
32780
32963
|
}).strict();
|
|
32781
|
-
var SetAdSpendInput =
|
|
32782
|
-
month:
|
|
32783
|
-
operationId:
|
|
32964
|
+
var SetAdSpendInput = z132.object({
|
|
32965
|
+
month: z132.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
32966
|
+
operationId: z132.string().uuid().optional(),
|
|
32784
32967
|
/** null RETIRA la corrección; cero afirma que no pautó. */
|
|
32785
|
-
amount:
|
|
32968
|
+
amount: z132.number().finite().min(0).nullable()
|
|
32786
32969
|
}).strict();
|
|
32787
|
-
var GetFinancesInput =
|
|
32788
|
-
month:
|
|
32789
|
-
operationId:
|
|
32970
|
+
var GetFinancesInput = z132.object({
|
|
32971
|
+
month: z132.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."),
|
|
32972
|
+
operationId: z132.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
|
|
32790
32973
|
}).strict();
|
|
32791
32974
|
function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
32792
32975
|
server.registerTool("get_product_control", {
|
|
@@ -32978,28 +33161,28 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
|
32978
33161
|
__name(registerProductControlTools, "registerProductControlTools");
|
|
32979
33162
|
|
|
32980
33163
|
// src/tools/market-study-estimate.ts
|
|
32981
|
-
import { z as
|
|
33164
|
+
import { z as z133 } from "zod";
|
|
32982
33165
|
var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
|
|
32983
|
-
var ProductTaskOutputEnum =
|
|
33166
|
+
var ProductTaskOutputEnum = z133.enum([
|
|
32984
33167
|
"landing",
|
|
32985
33168
|
"video",
|
|
32986
33169
|
"image"
|
|
32987
33170
|
]);
|
|
32988
|
-
var EstimateMarketStudyInput =
|
|
32989
|
-
kind:
|
|
33171
|
+
var EstimateMarketStudyInput = z133.object({
|
|
33172
|
+
kind: z133.enum([
|
|
32990
33173
|
"video",
|
|
32991
33174
|
"product_task"
|
|
32992
33175
|
]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
|
|
32993
|
-
videoAngleCount:
|
|
32994
|
-
durationSeconds:
|
|
33176
|
+
videoAngleCount: z133.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
|
|
33177
|
+
durationSeconds: z133.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
|
|
32995
33178
|
videoStructure: VideoStructureEnum.default("single_take"),
|
|
32996
33179
|
videoQuality: VideoQualityEnum.default("economy"),
|
|
32997
33180
|
videoResolution: VideoResolutionEnum.default("480p"),
|
|
32998
|
-
productImageCount:
|
|
33181
|
+
productImageCount: z133.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
|
|
32999
33182
|
outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
|
|
33000
|
-
generateAiMusic:
|
|
33183
|
+
generateAiMusic: z133.boolean().optional(),
|
|
33001
33184
|
generateAiEdit: AiEditRequestSchema.optional(),
|
|
33002
|
-
replicateWinnerWhenFound:
|
|
33185
|
+
replicateWinnerWhenFound: z133.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.")
|
|
33003
33186
|
}).strict();
|
|
33004
33187
|
function buildMarketStudyEstimateRequests(input) {
|
|
33005
33188
|
const quotesVideo = input.kind === "video" || (input.outputs ?? [
|