@productmaker/mcp 11.2.0 → 11.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/http.js +833 -789
- package/dist/stdio.js +822 -778
- package/package.json +1 -1
package/dist/http.js
CHANGED
|
@@ -7514,6 +7514,12 @@ var ResultAngle = Angle.extend({
|
|
|
7514
7514
|
});
|
|
7515
7515
|
var MVPResult = z39.object({
|
|
7516
7516
|
taskId: z39.string().uuid(),
|
|
7517
|
+
/** Read-only identity derived from validated persisted request context.
|
|
7518
|
+
* Optional for older APIs and content-only tasks; absence never implies a service. */
|
|
7519
|
+
subjectKind: z39.enum([
|
|
7520
|
+
"product",
|
|
7521
|
+
"service"
|
|
7522
|
+
]).optional(),
|
|
7517
7523
|
product: Product,
|
|
7518
7524
|
// READ contract, NOT a generation cap. The generator writes exactly 3 angles
|
|
7519
7525
|
// (`replaceAngles` renumbers positions 0..2), but a duplicated angles run
|
|
@@ -8314,6 +8320,10 @@ var VideoRegenerateEstimationOptions = z40.object({
|
|
|
8314
8320
|
sceneCount: z40.number().int().positive().optional()
|
|
8315
8321
|
});
|
|
8316
8322
|
var ImageCreativeEstimationOptions = z40.object({
|
|
8323
|
+
subject: z40.enum([
|
|
8324
|
+
"product",
|
|
8325
|
+
"service"
|
|
8326
|
+
]).optional(),
|
|
8317
8327
|
nVariants: z40.number().int().positive().optional(),
|
|
8318
8328
|
generateAdCopy: z40.boolean().optional(),
|
|
8319
8329
|
/** Literal model name (e.g. 'gpt-image/1.5', 'nano-banana-2'). Defaults to the premium ad-creative model. */
|
|
@@ -9211,6 +9221,7 @@ var VideoMixQaJobSchema = z46.object({
|
|
|
9211
9221
|
// jobId for retry uniqueness) but the worker only reads mixSceneTaskId.
|
|
9212
9222
|
externalId: z46.string().min(1).optional()
|
|
9213
9223
|
});
|
|
9224
|
+
var BrandExtractLocaleSchema = z46.string().regex(/^[A-Za-z]{2,3}(?:[-_][A-Za-z0-9]{2,8})?$/, "invalid locale");
|
|
9214
9225
|
var BrandExtractJobSchema = z46.object({
|
|
9215
9226
|
brandId: z46.string().uuid(),
|
|
9216
9227
|
// Generation is part of the durable paid-spend identity. Default 1 keeps
|
|
@@ -9226,7 +9237,10 @@ var BrandExtractJobSchema = z46.object({
|
|
|
9226
9237
|
"shopify_sync"
|
|
9227
9238
|
]).default("url_extract"),
|
|
9228
9239
|
shopifyShopId: z46.string().optional(),
|
|
9229
|
-
documents: z46.array(BrandExtractDocumentSchema).max(3).default([])
|
|
9240
|
+
documents: z46.array(BrandExtractDocumentSchema).max(3).default([]),
|
|
9241
|
+
// Requesting user's UI locale (BCP-47, e.g. "es", "en-US"). Fallback for the
|
|
9242
|
+
// brand kit's output language when the brand's own text is inconclusive.
|
|
9243
|
+
locale: BrandExtractLocaleSchema.optional()
|
|
9230
9244
|
});
|
|
9231
9245
|
|
|
9232
9246
|
// ../../packages/types/src/chat-parse.ts
|
|
@@ -21820,19 +21834,46 @@ var DropiFinancialSyncResultSchema = z103.object({
|
|
|
21820
21834
|
}))
|
|
21821
21835
|
});
|
|
21822
21836
|
|
|
21823
|
-
// ../../packages/types/src/service-
|
|
21837
|
+
// ../../packages/types/src/service-image.ts
|
|
21824
21838
|
import { z as z104 } from "zod";
|
|
21839
|
+
var ServiceImageIntentSchema = z104.enum([
|
|
21840
|
+
"user_brief",
|
|
21841
|
+
"delegate_to_ai"
|
|
21842
|
+
]);
|
|
21843
|
+
var ServiceImageInputSchema = z104.object({
|
|
21844
|
+
instruction: z104.string().trim().max(4e3).default(""),
|
|
21845
|
+
intent: ServiceImageIntentSchema.default("user_brief")
|
|
21846
|
+
}).strict().refine((value) => value.intent === "delegate_to_ai" || value.instruction.length > 0, {
|
|
21847
|
+
message: "Cu\xE9ntanos qu\xE9 servicio quieres promocionar.",
|
|
21848
|
+
path: [
|
|
21849
|
+
"instruction"
|
|
21850
|
+
]
|
|
21851
|
+
});
|
|
21852
|
+
var ServiceImageContextSchema = z104.object({
|
|
21853
|
+
kind: z104.literal("service_image"),
|
|
21854
|
+
version: z104.literal(1),
|
|
21855
|
+
instruction: z104.string().max(4e3),
|
|
21856
|
+
intent: ServiceImageIntentSchema,
|
|
21857
|
+
businessName: z104.string().max(300),
|
|
21858
|
+
description: z104.string().max(2e4),
|
|
21859
|
+
brandCard: z104.string().max(2e4),
|
|
21860
|
+
palette: z104.array(z104.string()).max(20),
|
|
21861
|
+
referenceKeys: z104.array(z104.string()).max(10)
|
|
21862
|
+
}).strict();
|
|
21863
|
+
|
|
21864
|
+
// ../../packages/types/src/service-website-capture.ts
|
|
21865
|
+
import { z as z105 } from "zod";
|
|
21825
21866
|
var WEBSITE_CAPTURE_MAX_RESEARCH_BYTES = 1024 * 1024;
|
|
21826
21867
|
var WEBSITE_CAPTURE_MAX_FILES = 100;
|
|
21827
21868
|
var WEBSITE_CAPTURE_MAX_FILE_BYTES = 8 * 1024 * 1024;
|
|
21828
21869
|
var WEBSITE_CAPTURE_MAX_BUNDLE_BYTES = 30 * 1024 * 1024;
|
|
21829
|
-
var WebsiteCaptureCauseSchema =
|
|
21870
|
+
var WebsiteCaptureCauseSchema = z105.enum([
|
|
21830
21871
|
"site_blocked",
|
|
21831
21872
|
"site_unreachable",
|
|
21832
21873
|
"not_enough_content",
|
|
21833
21874
|
"internal"
|
|
21834
21875
|
]);
|
|
21835
|
-
var WebsiteCaptureStatusSchema =
|
|
21876
|
+
var WebsiteCaptureStatusSchema = z105.enum([
|
|
21836
21877
|
"queued",
|
|
21837
21878
|
"capturing",
|
|
21838
21879
|
"ready",
|
|
@@ -21854,128 +21895,131 @@ function normalizeWebsiteCaptureUrl(value) {
|
|
|
21854
21895
|
}
|
|
21855
21896
|
}
|
|
21856
21897
|
__name(normalizeWebsiteCaptureUrl, "normalizeWebsiteCaptureUrl");
|
|
21857
|
-
var WebsiteCaptureRequestSchema =
|
|
21858
|
-
url:
|
|
21898
|
+
var WebsiteCaptureRequestSchema = z105.object({
|
|
21899
|
+
url: z105.string().trim().max(2048).url().refine((value) => normalizeWebsiteCaptureUrl(value) !== null, "Use an HTTP(S) URL without credentials").transform((value) => normalizeWebsiteCaptureUrl(value)),
|
|
21859
21900
|
language: MotionGraphicsLanguageSchema
|
|
21860
21901
|
}).strict();
|
|
21861
|
-
var WebsiteCaptureResponseSchema =
|
|
21862
|
-
captureId:
|
|
21902
|
+
var WebsiteCaptureResponseSchema = z105.object({
|
|
21903
|
+
captureId: z105.string().uuid(),
|
|
21863
21904
|
status: WebsiteCaptureStatusSchema,
|
|
21864
|
-
expiresAt:
|
|
21865
|
-
previewUrl:
|
|
21905
|
+
expiresAt: z105.string().datetime(),
|
|
21906
|
+
previewUrl: z105.string().url().optional(),
|
|
21866
21907
|
cause: WebsiteCaptureCauseSchema.optional()
|
|
21867
21908
|
});
|
|
21868
21909
|
var WebsiteCaptureJobSchema = WebsiteCaptureRequestSchema.extend({
|
|
21869
|
-
captureId:
|
|
21870
|
-
attempt:
|
|
21871
|
-
leaseUntil:
|
|
21910
|
+
captureId: z105.string().uuid(),
|
|
21911
|
+
attempt: z105.number().int().positive(),
|
|
21912
|
+
leaseUntil: z105.string().datetime()
|
|
21872
21913
|
});
|
|
21873
|
-
var WebsiteCaptureClaimResponseSchema =
|
|
21914
|
+
var WebsiteCaptureClaimResponseSchema = z105.object({
|
|
21874
21915
|
capture: WebsiteCaptureJobSchema.nullable()
|
|
21875
21916
|
});
|
|
21876
21917
|
var attempt = {
|
|
21877
|
-
attempt:
|
|
21918
|
+
attempt: z105.number().int().positive()
|
|
21878
21919
|
};
|
|
21879
|
-
var digest =
|
|
21880
|
-
var WebsiteCaptureUploadRequestSchema =
|
|
21920
|
+
var digest = z105.string().regex(/^[a-f0-9]{64}$/);
|
|
21921
|
+
var WebsiteCaptureUploadRequestSchema = z105.object({
|
|
21881
21922
|
...attempt,
|
|
21882
|
-
contentLength:
|
|
21923
|
+
contentLength: z105.number().int().positive().max(WEBSITE_CAPTURE_MAX_BUNDLE_BYTES),
|
|
21883
21924
|
sha256: digest
|
|
21884
21925
|
}).strict();
|
|
21885
|
-
var WebsiteCaptureDoneRequestSchema =
|
|
21926
|
+
var WebsiteCaptureDoneRequestSchema = z105.object({
|
|
21886
21927
|
...attempt,
|
|
21887
21928
|
sha256: digest
|
|
21888
21929
|
}).strict();
|
|
21889
|
-
var WebsiteCaptureFailedRequestSchema =
|
|
21930
|
+
var WebsiteCaptureFailedRequestSchema = z105.object({
|
|
21890
21931
|
...attempt,
|
|
21891
21932
|
cause: WebsiteCaptureCauseSchema
|
|
21892
21933
|
}).strict();
|
|
21893
|
-
var WebsiteCaptureBundleSchema =
|
|
21894
|
-
version:
|
|
21895
|
-
files:
|
|
21896
|
-
path:
|
|
21897
|
-
base64:
|
|
21934
|
+
var WebsiteCaptureBundleSchema = z105.object({
|
|
21935
|
+
version: z105.literal(1),
|
|
21936
|
+
files: z105.array(z105.object({
|
|
21937
|
+
path: z105.string().max(140).regex(/^research\/(?:page\.json|(?:desktop|mobile)-[1-9]\d*\.jpg|logo\.(?:png|svg)|image-[1-9]\d*\.(?:png|jpg|jpeg|webp|svg|avif)|font-[1-9]\d*\.(?:woff2?|ttf|otf))$/),
|
|
21938
|
+
base64: z105.string().max(Math.ceil(WEBSITE_CAPTURE_MAX_FILE_BYTES / 3) * 4).regex(/^[A-Za-z0-9+/]*={0,2}$/).refine((value) => value.length % 4 === 0),
|
|
21898
21939
|
sha256: digest
|
|
21899
21940
|
}).strict()).min(1).max(WEBSITE_CAPTURE_MAX_FILES)
|
|
21900
21941
|
}).strict().refine((bundle) => new Set(bundle.files.map((file) => file.path)).size === bundle.files.length, "Duplicate capture file");
|
|
21901
|
-
var WebsiteCaptureScreenshotSchema =
|
|
21902
|
-
file:
|
|
21903
|
-
scrollTop:
|
|
21904
|
-
});
|
|
21905
|
-
var WebsiteCaptureAccessSchema =
|
|
21906
|
-
publicContentText:
|
|
21907
|
-
passwordGate:
|
|
21908
|
-
challengeGate:
|
|
21909
|
-
blockingOverlay:
|
|
21910
|
-
|
|
21911
|
-
|
|
21912
|
-
|
|
21913
|
-
|
|
21914
|
-
|
|
21915
|
-
|
|
21916
|
-
|
|
21917
|
-
|
|
21918
|
-
|
|
21919
|
-
|
|
21920
|
-
|
|
21921
|
-
|
|
21922
|
-
|
|
21923
|
-
|
|
21924
|
-
|
|
21942
|
+
var WebsiteCaptureScreenshotSchema = z105.object({
|
|
21943
|
+
file: z105.string(),
|
|
21944
|
+
scrollTop: z105.number()
|
|
21945
|
+
});
|
|
21946
|
+
var WebsiteCaptureAccessSchema = z105.object({
|
|
21947
|
+
publicContentText: z105.string().max(8e3),
|
|
21948
|
+
passwordGate: z105.boolean(),
|
|
21949
|
+
challengeGate: z105.boolean(),
|
|
21950
|
+
blockingOverlay: z105.boolean(),
|
|
21951
|
+
// Decoded, substantial images visible outside access walls and page chrome.
|
|
21952
|
+
// Optional for compatibility with already captured text-led research.
|
|
21953
|
+
publicImageUrls: z105.array(z105.string().url().max(8192)).max(20).optional()
|
|
21954
|
+
});
|
|
21955
|
+
var WebsiteCaptureResearchSchema = z105.object({
|
|
21956
|
+
requestedUrl: z105.string().url(),
|
|
21957
|
+
capturedAt: z105.string().datetime(),
|
|
21958
|
+
locale: z105.string(),
|
|
21959
|
+
bodyTextTruncated: z105.boolean(),
|
|
21960
|
+
finalUrl: z105.string().url(),
|
|
21961
|
+
lang: z105.string().nullable(),
|
|
21962
|
+
title: z105.string(),
|
|
21963
|
+
description: z105.string(),
|
|
21964
|
+
openGraph: z105.object({
|
|
21965
|
+
title: z105.string(),
|
|
21966
|
+
description: z105.string(),
|
|
21967
|
+
image: z105.string(),
|
|
21968
|
+
siteName: z105.string()
|
|
21925
21969
|
}),
|
|
21926
|
-
themeColor:
|
|
21927
|
-
headings:
|
|
21928
|
-
h1:
|
|
21929
|
-
h2:
|
|
21930
|
-
h3:
|
|
21970
|
+
themeColor: z105.string(),
|
|
21971
|
+
headings: z105.object({
|
|
21972
|
+
h1: z105.array(z105.string()),
|
|
21973
|
+
h2: z105.array(z105.string()),
|
|
21974
|
+
h3: z105.array(z105.string())
|
|
21931
21975
|
}),
|
|
21932
|
-
callsToAction:
|
|
21933
|
-
listItems:
|
|
21934
|
-
bodyText:
|
|
21976
|
+
callsToAction: z105.array(z105.string()),
|
|
21977
|
+
listItems: z105.array(z105.string()),
|
|
21978
|
+
bodyText: z105.string(),
|
|
21935
21979
|
access: WebsiteCaptureAccessSchema.optional(),
|
|
21936
|
-
consent:
|
|
21937
|
-
pressed:
|
|
21938
|
-
removed:
|
|
21980
|
+
consent: z105.object({
|
|
21981
|
+
pressed: z105.string().nullable(),
|
|
21982
|
+
removed: z105.number().nonnegative()
|
|
21939
21983
|
}).optional(),
|
|
21940
|
-
overlaysDismissed:
|
|
21941
|
-
style:
|
|
21942
|
-
bodyBackground:
|
|
21943
|
-
bodyColor:
|
|
21944
|
-
bodyFont:
|
|
21945
|
-
headingFont:
|
|
21946
|
-
headingColor:
|
|
21947
|
-
actionColors:
|
|
21948
|
-
color:
|
|
21949
|
-
uses:
|
|
21984
|
+
overlaysDismissed: z105.number().int().nonnegative().optional(),
|
|
21985
|
+
style: z105.object({
|
|
21986
|
+
bodyBackground: z105.string(),
|
|
21987
|
+
bodyColor: z105.string(),
|
|
21988
|
+
bodyFont: z105.string(),
|
|
21989
|
+
headingFont: z105.string().nullable(),
|
|
21990
|
+
headingColor: z105.string().nullable(),
|
|
21991
|
+
actionColors: z105.array(z105.object({
|
|
21992
|
+
color: z105.string(),
|
|
21993
|
+
uses: z105.number()
|
|
21950
21994
|
}))
|
|
21951
21995
|
}),
|
|
21952
|
-
images:
|
|
21953
|
-
file:
|
|
21954
|
-
src:
|
|
21955
|
-
alt:
|
|
21956
|
-
width:
|
|
21957
|
-
height:
|
|
21958
|
-
isOpenGraph:
|
|
21996
|
+
images: z105.array(z105.object({
|
|
21997
|
+
file: z105.string(),
|
|
21998
|
+
src: z105.string(),
|
|
21999
|
+
alt: z105.string(),
|
|
22000
|
+
width: z105.number().nullable(),
|
|
22001
|
+
height: z105.number().nullable(),
|
|
22002
|
+
isOpenGraph: z105.boolean()
|
|
21959
22003
|
})),
|
|
21960
|
-
logo:
|
|
21961
|
-
file:
|
|
21962
|
-
svg:
|
|
21963
|
-
width:
|
|
21964
|
-
height:
|
|
22004
|
+
logo: z105.object({
|
|
22005
|
+
file: z105.literal("logo.png"),
|
|
22006
|
+
svg: z105.literal("logo.svg").optional(),
|
|
22007
|
+
width: z105.number(),
|
|
22008
|
+
height: z105.number()
|
|
21965
22009
|
}).nullable(),
|
|
21966
|
-
fonts:
|
|
21967
|
-
family:
|
|
21968
|
-
weight:
|
|
21969
|
-
style:
|
|
21970
|
-
unicodeRange:
|
|
21971
|
-
file:
|
|
22010
|
+
fonts: z105.array(z105.object({
|
|
22011
|
+
family: z105.string(),
|
|
22012
|
+
weight: z105.string(),
|
|
22013
|
+
style: z105.string(),
|
|
22014
|
+
unicodeRange: z105.string().nullable(),
|
|
22015
|
+
file: z105.string().optional()
|
|
21972
22016
|
}).transform((font) => ({
|
|
21973
22017
|
...font,
|
|
21974
22018
|
file: font.file
|
|
21975
22019
|
}))),
|
|
21976
|
-
screenshots:
|
|
21977
|
-
desktop:
|
|
21978
|
-
mobile:
|
|
22020
|
+
screenshots: z105.object({
|
|
22021
|
+
desktop: z105.array(WebsiteCaptureScreenshotSchema),
|
|
22022
|
+
mobile: z105.array(WebsiteCaptureScreenshotSchema)
|
|
21979
22023
|
})
|
|
21980
22024
|
});
|
|
21981
22025
|
|
|
@@ -22488,23 +22532,23 @@ import { InsufficientScopeError, InvalidTokenError } from "@modelcontextprotocol
|
|
|
22488
22532
|
import { createRemoteJWKSet as createRemoteJWKSet2, jwtVerify as jwtVerify2 } from "jose";
|
|
22489
22533
|
|
|
22490
22534
|
// src/auth/oauth-config.ts
|
|
22491
|
-
import { z as
|
|
22535
|
+
import { z as z106 } from "zod";
|
|
22492
22536
|
var MCP_RESOURCE = new URL("https://mcp.productmaker.app/mcp");
|
|
22493
22537
|
var MCP_SCOPE = "mcp:access";
|
|
22494
22538
|
var REFRESH_SCOPE = "offline_access";
|
|
22495
22539
|
var STATIC_CLIENT_ISSUER = new URL(MCP_RESOURCE.origin);
|
|
22496
|
-
var oauthEnvSchema =
|
|
22497
|
-
MCP_REMOTE_AUTH_MODE:
|
|
22498
|
-
MCP_AUTH0_ISSUER:
|
|
22499
|
-
MCP_AUTH0_AUDIENCE:
|
|
22540
|
+
var oauthEnvSchema = z106.object({
|
|
22541
|
+
MCP_REMOTE_AUTH_MODE: z106.literal("oauth"),
|
|
22542
|
+
MCP_AUTH0_ISSUER: z106.string().trim().min(1),
|
|
22543
|
+
MCP_AUTH0_AUDIENCE: z106.string().trim().refine((value) => value === MCP_RESOURCE.href, {
|
|
22500
22544
|
message: `must equal ${MCP_RESOURCE.href}`
|
|
22501
22545
|
}),
|
|
22502
|
-
MCP_AUTH0_CLIENT_ID:
|
|
22503
|
-
MCP_AUTH0_CLIENT_SECRET:
|
|
22504
|
-
PM_API_AUDIENCE:
|
|
22505
|
-
AUTH0_AUDIENCE:
|
|
22506
|
-
MCP_STATIC_CLIENT_ID:
|
|
22507
|
-
MCP_STATIC_CLIENT_SECRET:
|
|
22546
|
+
MCP_AUTH0_CLIENT_ID: z106.string().trim().min(1),
|
|
22547
|
+
MCP_AUTH0_CLIENT_SECRET: z106.string().trim().min(1),
|
|
22548
|
+
PM_API_AUDIENCE: z106.string().trim().min(1),
|
|
22549
|
+
AUTH0_AUDIENCE: z106.string().trim().min(1),
|
|
22550
|
+
MCP_STATIC_CLIENT_ID: z106.string().trim().min(1).optional(),
|
|
22551
|
+
MCP_STATIC_CLIENT_SECRET: z106.string().trim().min(1).optional()
|
|
22508
22552
|
});
|
|
22509
22553
|
function formatZodIssues(error) {
|
|
22510
22554
|
return error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ");
|
|
@@ -23658,7 +23702,7 @@ var ApiClient = class {
|
|
|
23658
23702
|
};
|
|
23659
23703
|
|
|
23660
23704
|
// src/index.ts
|
|
23661
|
-
var MCP_VERSION = "11.2.
|
|
23705
|
+
var MCP_VERSION = "11.2.2";
|
|
23662
23706
|
|
|
23663
23707
|
// src/meta-upload-app.ts
|
|
23664
23708
|
import { readFileSync } from "fs";
|
|
@@ -23730,7 +23774,7 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
|
|
|
23730
23774
|
__name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
|
|
23731
23775
|
|
|
23732
23776
|
// src/tools/tasks.ts
|
|
23733
|
-
import { z as
|
|
23777
|
+
import { z as z111 } from "zod";
|
|
23734
23778
|
|
|
23735
23779
|
// src/resolve-image.ts
|
|
23736
23780
|
import { lookup as dnsLookup } from "dns/promises";
|
|
@@ -24291,9 +24335,9 @@ async function resolveMediaRef(ref, opts) {
|
|
|
24291
24335
|
__name(resolveMediaRef, "resolveMediaRef");
|
|
24292
24336
|
|
|
24293
24337
|
// src/tools/shared.ts
|
|
24294
|
-
import { z as
|
|
24295
|
-
var Lang =
|
|
24296
|
-
var Country =
|
|
24338
|
+
import { z as z107 } from "zod";
|
|
24339
|
+
var Lang = z107.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);
|
|
24340
|
+
var Country = z107.string().min(2).max(3);
|
|
24297
24341
|
var LandingStrategyEnum = LandingStrategySchema;
|
|
24298
24342
|
var LandingImageFormatEnum = LandingImageFormatSchema;
|
|
24299
24343
|
var VideoPresetEnum = VideoPreset.extract([
|
|
@@ -24397,7 +24441,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
|
|
|
24397
24441
|
return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
|
|
24398
24442
|
}
|
|
24399
24443
|
__name(animationStyleApplies, "animationStyleApplies");
|
|
24400
|
-
var VideoTierEnum =
|
|
24444
|
+
var VideoTierEnum = z107.enum([
|
|
24401
24445
|
"basic"
|
|
24402
24446
|
]);
|
|
24403
24447
|
function resolveVideoTier(_tier) {
|
|
@@ -24455,10 +24499,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
|
|
|
24455
24499
|
var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
|
|
24456
24500
|
var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
|
|
24457
24501
|
var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
|
|
24458
|
-
var ImageRefSchema =
|
|
24459
|
-
url:
|
|
24460
|
-
path:
|
|
24461
|
-
assetId:
|
|
24502
|
+
var ImageRefSchema = z107.object({
|
|
24503
|
+
url: z107.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.'),
|
|
24504
|
+
path: z107.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`.'),
|
|
24505
|
+
assetId: z107.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.")
|
|
24462
24506
|
}).refine((v) => [
|
|
24463
24507
|
v.url,
|
|
24464
24508
|
v.path,
|
|
@@ -24466,11 +24510,11 @@ var ImageRefSchema = z106.object({
|
|
|
24466
24510
|
].filter(Boolean).length === 1, {
|
|
24467
24511
|
message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
|
|
24468
24512
|
});
|
|
24469
|
-
var ImagesInput =
|
|
24513
|
+
var ImagesInput = z107.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
|
|
24470
24514
|
const assetCount = images.filter((image) => Boolean(image.assetId)).length;
|
|
24471
24515
|
if (assetCount > 0 && assetCount !== images.length) {
|
|
24472
24516
|
ctx.addIssue({
|
|
24473
|
-
code:
|
|
24517
|
+
code: z107.ZodIssueCode.custom,
|
|
24474
24518
|
message: "all image entries must use assetId, or all must use URL/path sources"
|
|
24475
24519
|
});
|
|
24476
24520
|
}
|
|
@@ -24543,14 +24587,14 @@ async function submitCreative(api, opts) {
|
|
|
24543
24587
|
});
|
|
24544
24588
|
}
|
|
24545
24589
|
__name(submitCreative, "submitCreative");
|
|
24546
|
-
var ResearchTargetCountryEnum =
|
|
24590
|
+
var ResearchTargetCountryEnum = z107.enum([
|
|
24547
24591
|
"CO",
|
|
24548
24592
|
"MX",
|
|
24549
24593
|
"PE",
|
|
24550
24594
|
"EC",
|
|
24551
24595
|
"CL"
|
|
24552
24596
|
]);
|
|
24553
|
-
var ResearchCategoryEnum =
|
|
24597
|
+
var ResearchCategoryEnum = z107.enum([
|
|
24554
24598
|
"auto",
|
|
24555
24599
|
"automotive",
|
|
24556
24600
|
"kitchen",
|
|
@@ -25862,29 +25906,29 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
|
|
|
25862
25906
|
__name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
|
|
25863
25907
|
|
|
25864
25908
|
// src/tools/media-presentation.ts
|
|
25865
|
-
import { z as
|
|
25866
|
-
var HttpsPresentationUrlSchema =
|
|
25909
|
+
import { z as z108 } from "zod";
|
|
25910
|
+
var HttpsPresentationUrlSchema = z108.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
|
|
25867
25911
|
var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
|
|
25868
25912
|
const hostname = new URL(value).hostname.toLowerCase();
|
|
25869
25913
|
return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
|
|
25870
25914
|
}, "preview URL must be owned by ProductMaker");
|
|
25871
|
-
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) =>
|
|
25872
|
-
var PresentationImageSchema =
|
|
25873
|
-
kind:
|
|
25915
|
+
var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z108.number().int().positive().max(maximum), "positiveIntAtMost");
|
|
25916
|
+
var PresentationImageSchema = z108.object({
|
|
25917
|
+
kind: z108.literal("image"),
|
|
25874
25918
|
url: HttpsPresentationUrlSchema,
|
|
25875
|
-
mimeType:
|
|
25919
|
+
mimeType: z108.enum([
|
|
25876
25920
|
"image/jpeg",
|
|
25877
25921
|
"image/png"
|
|
25878
25922
|
]),
|
|
25879
25923
|
byteSize: positiveIntAtMost(5 * 1024 * 1024),
|
|
25880
25924
|
width: positiveIntAtMost(16384),
|
|
25881
25925
|
height: positiveIntAtMost(16384),
|
|
25882
|
-
alt:
|
|
25926
|
+
alt: z108.string().trim().min(1).max(240)
|
|
25883
25927
|
}).strict();
|
|
25884
25928
|
var McpMediaPresentationSchema = PresentationImageSchema;
|
|
25885
|
-
var GalleryImageSchema =
|
|
25929
|
+
var GalleryImageSchema = z108.object({
|
|
25886
25930
|
url: ProductMakerPreviewUrlSchema,
|
|
25887
|
-
alt:
|
|
25931
|
+
alt: z108.string().trim().min(1).max(240)
|
|
25888
25932
|
});
|
|
25889
25933
|
var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
25890
25934
|
async function imageBlocks(image, transport) {
|
|
@@ -25941,12 +25985,12 @@ async function buildMcpMediaPresentationContent(rawPresentation, transport = "ht
|
|
|
25941
25985
|
];
|
|
25942
25986
|
}
|
|
25943
25987
|
__name(buildMcpMediaPresentationContent, "buildMcpMediaPresentationContent");
|
|
25944
|
-
var OwnedImagePreviewSchema =
|
|
25988
|
+
var OwnedImagePreviewSchema = z108.object({
|
|
25945
25989
|
url: HttpsPresentationUrlSchema.refine((value) => {
|
|
25946
25990
|
const url = new URL(value);
|
|
25947
25991
|
return !url.username && !url.password && !isPrivateHost(url.hostname);
|
|
25948
25992
|
}, "Preview URL must be public HTTPS without credentials"),
|
|
25949
|
-
alt:
|
|
25993
|
+
alt: z108.string().trim().min(1).max(240)
|
|
25950
25994
|
});
|
|
25951
25995
|
async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
|
|
25952
25996
|
const preview2 = OwnedImagePreviewSchema.safeParse(rawPreview);
|
|
@@ -26029,7 +26073,7 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
|
|
|
26029
26073
|
__name(buildMcpImageGalleryContent, "buildMcpImageGalleryContent");
|
|
26030
26074
|
|
|
26031
26075
|
// src/tools/animated-video.ts
|
|
26032
|
-
import { z as
|
|
26076
|
+
import { z as z109 } from "zod";
|
|
26033
26077
|
|
|
26034
26078
|
// src/tools/paid-confirmation.ts
|
|
26035
26079
|
function describeMarketStudyChoice(enabled) {
|
|
@@ -26279,27 +26323,27 @@ function hookVariantsLabel(count) {
|
|
|
26279
26323
|
return count === 1 ? "1 versi\xF3n del gancho" : `${count} versiones del gancho`;
|
|
26280
26324
|
}
|
|
26281
26325
|
__name(hookVariantsLabel, "hookVariantsLabel");
|
|
26282
|
-
var DurationInput =
|
|
26283
|
-
var CreateAnimatedVideoInput =
|
|
26284
|
-
action:
|
|
26326
|
+
var DurationInput = z109.union(MOTION_GRAPHICS_DURATIONS.map((d) => z109.literal(d)));
|
|
26327
|
+
var CreateAnimatedVideoInput = z109.object({
|
|
26328
|
+
action: z109.enum([
|
|
26285
26329
|
"prepare",
|
|
26286
26330
|
"status",
|
|
26287
26331
|
"cancel",
|
|
26288
26332
|
"generate"
|
|
26289
26333
|
]).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."),
|
|
26290
|
-
websiteCaptureId:
|
|
26291
|
-
generationRequestId:
|
|
26292
|
-
confirmed:
|
|
26334
|
+
websiteCaptureId: z109.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
|
|
26335
|
+
generationRequestId: z109.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."),
|
|
26336
|
+
confirmed: z109.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."),
|
|
26293
26337
|
// Plain text, not `.url()`: users type «cal.com», and the web accepts it.
|
|
26294
26338
|
// normalizeWebAddress (shared with the web) adds https:// and refuses
|
|
26295
26339
|
// anything that is not a public http(s) address.
|
|
26296
|
-
landingUrl:
|
|
26340
|
+
landingUrl: z109.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."),
|
|
26297
26341
|
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.'),
|
|
26298
26342
|
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.`),
|
|
26299
26343
|
language: MotionGraphicsLanguageSchema.optional().describe('Idioma de los textos del video: "es", "en" o "pt".'),
|
|
26300
|
-
notes:
|
|
26344
|
+
notes: z109.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)."),
|
|
26301
26345
|
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.`),
|
|
26302
|
-
music:
|
|
26346
|
+
music: z109.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.")
|
|
26303
26347
|
}).strict();
|
|
26304
26348
|
function captureNextAction(capture) {
|
|
26305
26349
|
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.";
|
|
@@ -26332,43 +26376,43 @@ var FORMAT_LABELS = {
|
|
|
26332
26376
|
square: "cuadrado 1:1",
|
|
26333
26377
|
horizontal: "horizontal 16:9"
|
|
26334
26378
|
};
|
|
26335
|
-
var AnimatedVideoResultSchema =
|
|
26336
|
-
status:
|
|
26379
|
+
var AnimatedVideoResultSchema = z109.object({
|
|
26380
|
+
status: z109.enum([
|
|
26337
26381
|
"pending",
|
|
26338
26382
|
"done",
|
|
26339
26383
|
"error"
|
|
26340
26384
|
]),
|
|
26341
|
-
serviceMode:
|
|
26342
|
-
finalMp4Url:
|
|
26343
|
-
error:
|
|
26344
|
-
motionGraphics:
|
|
26385
|
+
serviceMode: z109.literal("motion_graphics"),
|
|
26386
|
+
finalMp4Url: z109.string().optional(),
|
|
26387
|
+
error: z109.string().optional(),
|
|
26388
|
+
motionGraphics: z109.object({
|
|
26345
26389
|
stage: MotionGraphicsStageSchema,
|
|
26346
26390
|
format: MotionGraphicsFormatSchema,
|
|
26347
|
-
durationSec:
|
|
26348
|
-
width:
|
|
26349
|
-
height:
|
|
26391
|
+
durationSec: z109.number(),
|
|
26392
|
+
width: z109.number().optional(),
|
|
26393
|
+
height: z109.number().optional(),
|
|
26350
26394
|
language: MotionGraphicsLanguageSchema.optional(),
|
|
26351
|
-
queuedAt:
|
|
26352
|
-
jobsAhead:
|
|
26353
|
-
stageStartedAt:
|
|
26354
|
-
renderProgress:
|
|
26395
|
+
queuedAt: z109.string().optional(),
|
|
26396
|
+
jobsAhead: z109.number().int().nonnegative().optional(),
|
|
26397
|
+
stageStartedAt: z109.string().optional(),
|
|
26398
|
+
renderProgress: z109.number().optional(),
|
|
26355
26399
|
// AI clip fields (absent on a video paid before clips, or from an API
|
|
26356
26400
|
// that predates them). Lenient: an unreadable value is dropped
|
|
26357
26401
|
// instead of hiding the status.
|
|
26358
|
-
clipCount:
|
|
26359
|
-
clipsUsed:
|
|
26360
|
-
clipPriceCents:
|
|
26361
|
-
clipsRefunded:
|
|
26402
|
+
clipCount: z109.number().int().nonnegative().optional().catch(void 0),
|
|
26403
|
+
clipsUsed: z109.number().int().nonnegative().optional().catch(void 0),
|
|
26404
|
+
clipPriceCents: z109.number().finite().nonnegative().optional().catch(void 0),
|
|
26405
|
+
clipsRefunded: z109.number().int().nonnegative().optional().catch(void 0),
|
|
26362
26406
|
// Hook versions (absent from an API or a video before them): the
|
|
26363
26407
|
// count ordered and, once done, the signed URLs of the EXTRA versions
|
|
26364
26408
|
// (hook 2, hook 3); `finalMp4Url` is hook 1.
|
|
26365
|
-
hookVariants:
|
|
26366
|
-
variantUrls:
|
|
26409
|
+
hookVariants: z109.number().int().min(1).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX).optional().catch(void 0),
|
|
26410
|
+
variantUrls: z109.array(z109.string().min(1)).max(MOTION_GRAPHICS_HOOK_VARIANTS_MAX - 1).optional().catch(void 0),
|
|
26367
26411
|
// Extra hook versions given back, as the task recorded it once the
|
|
26368
26412
|
// refunds landed (absent until then, and from an API before it).
|
|
26369
|
-
variantsRefunded:
|
|
26370
|
-
activity:
|
|
26371
|
-
previewUrl:
|
|
26413
|
+
variantsRefunded: z109.number().int().nonnegative().optional().catch(void 0),
|
|
26414
|
+
activity: z109.array(MotionGraphicsActivitySchema).optional().catch(void 0),
|
|
26415
|
+
previewUrl: z109.string().optional()
|
|
26372
26416
|
}).passthrough()
|
|
26373
26417
|
}).passthrough();
|
|
26374
26418
|
function parseAnimatedVideoResult(value) {
|
|
@@ -26624,10 +26668,10 @@ function registerAnimatedVideoTools(server, api) {
|
|
|
26624
26668
|
__name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
|
|
26625
26669
|
|
|
26626
26670
|
// src/tools/winning-product-image.ts
|
|
26627
|
-
import { z as
|
|
26628
|
-
var WinnerReferenceInput =
|
|
26629
|
-
runId:
|
|
26630
|
-
candidateSourceId:
|
|
26671
|
+
import { z as z110 } from "zod";
|
|
26672
|
+
var WinnerReferenceInput = z110.object({
|
|
26673
|
+
runId: z110.string().uuid(),
|
|
26674
|
+
candidateSourceId: z110.string().trim().min(1).max(160)
|
|
26631
26675
|
}).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
|
|
26632
26676
|
async function resolveWinnerImages(api, winnerReference, images) {
|
|
26633
26677
|
if (!winnerReference) return images;
|
|
@@ -26664,62 +26708,62 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
|
|
|
26664
26708
|
var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
|
|
26665
26709
|
var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
|
|
26666
26710
|
var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
|
|
26667
|
-
var CreateProductTaskInput =
|
|
26711
|
+
var CreateProductTaskInput = z111.object({
|
|
26668
26712
|
images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
|
|
26669
26713
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
26670
|
-
projectId:
|
|
26671
|
-
productUrl:
|
|
26714
|
+
projectId: z111.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
|
|
26715
|
+
productUrl: z111.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."),
|
|
26672
26716
|
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.'),
|
|
26673
26717
|
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.'),
|
|
26674
|
-
price:
|
|
26675
|
-
compareAtPrice:
|
|
26676
|
-
offer:
|
|
26677
|
-
paymentMethods:
|
|
26678
|
-
productContext:
|
|
26679
|
-
productLabel:
|
|
26718
|
+
price: z111.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.'),
|
|
26719
|
+
compareAtPrice: z111.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".'),
|
|
26720
|
+
offer: z111.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.'),
|
|
26721
|
+
paymentMethods: z111.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.'),
|
|
26722
|
+
productContext: z111.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."),
|
|
26723
|
+
productLabel: z111.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.'),
|
|
26680
26724
|
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.'),
|
|
26681
26725
|
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.'),
|
|
26682
|
-
durationSeconds:
|
|
26683
|
-
|
|
26684
|
-
|
|
26726
|
+
durationSeconds: z111.union([
|
|
26727
|
+
z111.literal(15),
|
|
26728
|
+
z111.literal(30)
|
|
26685
26729
|
]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
|
|
26686
|
-
pauseForAngleReview:
|
|
26687
|
-
aiDecidesAll:
|
|
26730
|
+
pauseForAngleReview: z111.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."),
|
|
26731
|
+
aiDecidesAll: z111.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."),
|
|
26688
26732
|
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.'),
|
|
26689
26733
|
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.'),
|
|
26690
26734
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
26691
26735
|
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).'),
|
|
26692
|
-
videoAngleCount:
|
|
26736
|
+
videoAngleCount: z111.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."),
|
|
26693
26737
|
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.'),
|
|
26694
|
-
outputs:
|
|
26738
|
+
outputs: z111.array(z111.enum([
|
|
26695
26739
|
"landing",
|
|
26696
26740
|
"video",
|
|
26697
26741
|
"image"
|
|
26698
26742
|
])).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}`),
|
|
26699
|
-
includeInitialLandingGif:
|
|
26700
|
-
competitorScanEnabled:
|
|
26743
|
+
includeInitialLandingGif: z111.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."),
|
|
26744
|
+
competitorScanEnabled: z111.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."),
|
|
26701
26745
|
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.'),
|
|
26702
|
-
replicateWinnerWhenFound:
|
|
26703
|
-
brandId:
|
|
26704
|
-
actorId:
|
|
26746
|
+
replicateWinnerWhenFound: z111.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."),
|
|
26747
|
+
brandId: z111.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."),
|
|
26748
|
+
actorId: z111.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."),
|
|
26705
26749
|
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.'),
|
|
26706
|
-
creativeDirection:
|
|
26707
|
-
headline:
|
|
26708
|
-
subheadline:
|
|
26750
|
+
creativeDirection: z111.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.'),
|
|
26751
|
+
headline: z111.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."),
|
|
26752
|
+
subheadline: z111.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."),
|
|
26709
26753
|
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".'),
|
|
26710
26754
|
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".')
|
|
26711
26755
|
}).strict();
|
|
26712
|
-
var CreateServiceVideoInput =
|
|
26713
|
-
landingUrl:
|
|
26714
|
-
additionalContext:
|
|
26756
|
+
var CreateServiceVideoInput = z111.object({
|
|
26757
|
+
landingUrl: z111.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
|
|
26758
|
+
additionalContext: z111.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
|
|
26715
26759
|
language: Lang.describe("Idioma del video: es, en o pt."),
|
|
26716
|
-
voiceId:
|
|
26717
|
-
brandId:
|
|
26718
|
-
reviewMode:
|
|
26760
|
+
voiceId: z111.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.'),
|
|
26761
|
+
brandId: z111.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
|
|
26762
|
+
reviewMode: z111.enum([
|
|
26719
26763
|
"automatic",
|
|
26720
26764
|
"guided"
|
|
26721
26765
|
]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
|
|
26722
|
-
videoPreset:
|
|
26766
|
+
videoPreset: z111.enum([
|
|
26723
26767
|
"auto",
|
|
26724
26768
|
"ugc_dynamic",
|
|
26725
26769
|
"ugc_how_to",
|
|
@@ -26729,128 +26773,128 @@ var CreateServiceVideoInput = z110.object({
|
|
|
26729
26773
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
|
|
26730
26774
|
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.')
|
|
26731
26775
|
}).strict();
|
|
26732
|
-
var GetTaskStatusInput =
|
|
26733
|
-
taskId:
|
|
26734
|
-
waitSeconds:
|
|
26776
|
+
var GetTaskStatusInput = z111.object({
|
|
26777
|
+
taskId: z111.string().min(1),
|
|
26778
|
+
waitSeconds: z111.number().int().min(0).max(120).optional()
|
|
26735
26779
|
});
|
|
26736
|
-
var ListTasksInput =
|
|
26737
|
-
limit:
|
|
26738
|
-
offset:
|
|
26739
|
-
search:
|
|
26780
|
+
var ListTasksInput = z111.object({
|
|
26781
|
+
limit: z111.number().int().min(1).max(50).optional(),
|
|
26782
|
+
offset: z111.number().int().min(0).optional(),
|
|
26783
|
+
search: z111.string().optional()
|
|
26740
26784
|
});
|
|
26741
26785
|
var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
|
|
26742
26786
|
var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
|
|
26743
|
-
var EditTaskDraftInput =
|
|
26744
|
-
taskId:
|
|
26745
|
-
angleIndex:
|
|
26746
|
-
angle:
|
|
26747
|
-
angle:
|
|
26748
|
-
buyerPersona:
|
|
26749
|
-
actor:
|
|
26750
|
-
actorId:
|
|
26751
|
-
gender:
|
|
26787
|
+
var EditTaskDraftInput = z111.object({
|
|
26788
|
+
taskId: z111.string().min(1),
|
|
26789
|
+
angleIndex: z111.number().int().min(0),
|
|
26790
|
+
angle: z111.object({
|
|
26791
|
+
angle: z111.string().min(1).max(480),
|
|
26792
|
+
buyerPersona: z111.string().min(1).max(360),
|
|
26793
|
+
actor: z111.string().min(1).max(360).optional(),
|
|
26794
|
+
actorId: z111.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."),
|
|
26795
|
+
gender: z111.enum([
|
|
26752
26796
|
"female",
|
|
26753
26797
|
"male"
|
|
26754
26798
|
]).optional(),
|
|
26755
|
-
scriptNotes:
|
|
26799
|
+
scriptNotes: z111.string().max(2e3).optional()
|
|
26756
26800
|
})
|
|
26757
26801
|
});
|
|
26758
|
-
var PendingActionPayload =
|
|
26759
|
-
|
|
26760
|
-
kind:
|
|
26802
|
+
var PendingActionPayload = z111.discriminatedUnion("kind", [
|
|
26803
|
+
z111.object({
|
|
26804
|
+
kind: z111.literal("product_reference_set_approval"),
|
|
26761
26805
|
scope: ProductReferenceScopeEnum.optional(),
|
|
26762
|
-
scopeKey:
|
|
26763
|
-
scopeSnapshotId:
|
|
26764
|
-
expectedScopeHash:
|
|
26806
|
+
scopeKey: z111.string().min(1).max(120).optional(),
|
|
26807
|
+
scopeSnapshotId: z111.string().uuid().optional(),
|
|
26808
|
+
expectedScopeHash: z111.string().min(1).max(128).optional(),
|
|
26765
26809
|
decision: ProductReferenceResolutionDecisionEnum,
|
|
26766
26810
|
reason: ProductReferenceRejectionReasonEnum.optional(),
|
|
26767
|
-
affectedRefKeys:
|
|
26768
|
-
affectedPhotoNumbers:
|
|
26769
|
-
recoveryAction:
|
|
26811
|
+
affectedRefKeys: z111.array(z111.string().min(1).max(200)).min(1).optional(),
|
|
26812
|
+
affectedPhotoNumbers: z111.array(z111.number().int().positive()).min(1).optional(),
|
|
26813
|
+
recoveryAction: z111.enum([
|
|
26770
26814
|
"remove",
|
|
26771
26815
|
"replace",
|
|
26772
26816
|
"upload",
|
|
26773
26817
|
"return_to_selection"
|
|
26774
26818
|
]).optional()
|
|
26775
26819
|
}),
|
|
26776
|
-
|
|
26777
|
-
kind:
|
|
26778
|
-
selectedPhotoNumbers:
|
|
26820
|
+
z111.object({
|
|
26821
|
+
kind: z111.literal("product_reference_confirmation"),
|
|
26822
|
+
selectedPhotoNumbers: z111.array(z111.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."),
|
|
26779
26823
|
userChoice: ProductReferenceUserChoiceEnum.optional(),
|
|
26780
|
-
confirmedProductNames:
|
|
26824
|
+
confirmedProductNames: z111.array(z111.string().min(1).max(120)).min(2).max(8).optional(),
|
|
26781
26825
|
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."),
|
|
26782
26826
|
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."),
|
|
26783
|
-
useMultiSceneShowcase:
|
|
26827
|
+
useMultiSceneShowcase: z111.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
|
|
26784
26828
|
}),
|
|
26785
|
-
|
|
26786
|
-
kind:
|
|
26829
|
+
z111.object({
|
|
26830
|
+
kind: z111.literal("angle_review_approval"),
|
|
26787
26831
|
// All edits are optional — empty action body just approves the
|
|
26788
26832
|
// backend-generated draft as-is. Field shapes mirror the angle-review
|
|
26789
26833
|
// request contracts in @packages/types/wizard.ts; the handler routes to
|
|
26790
26834
|
// the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
|
|
26791
|
-
customAngle:
|
|
26835
|
+
customAngle: z111.string().min(1).max(480).optional(),
|
|
26792
26836
|
// Keep the shared MCP action within the strictest downstream contract:
|
|
26793
26837
|
// autopilot/image resume endpoints cap these fields at 1500 characters.
|
|
26794
|
-
painPoints:
|
|
26795
|
-
benefits:
|
|
26838
|
+
painPoints: z111.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
26839
|
+
benefits: z111.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
|
|
26796
26840
|
// Same policy as the two fields above: the strictest downstream contract
|
|
26797
26841
|
// wins. The image endpoint caps each feature at 240 while landing/video
|
|
26798
26842
|
// accept 300, and this single action routes to whichever the task is — so
|
|
26799
26843
|
// accepting 300 here turns a 250-character feature on an image task into
|
|
26800
26844
|
// an opaque HTTP 400 after the model already believed it had been saved.
|
|
26801
|
-
features:
|
|
26802
|
-
buyerPersona:
|
|
26845
|
+
features: z111.array(z111.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
|
|
26846
|
+
buyerPersona: z111.string().min(1).max(360).optional(),
|
|
26803
26847
|
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.'),
|
|
26804
|
-
actor:
|
|
26805
|
-
actorId:
|
|
26806
|
-
creativeDirection:
|
|
26807
|
-
selectedAngleNumbers:
|
|
26808
|
-
angleEdits:
|
|
26809
|
-
angleNumber:
|
|
26810
|
-
narrativeSelection:
|
|
26848
|
+
actor: z111.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."),
|
|
26849
|
+
actorId: z111.string().max(120).nullable().optional(),
|
|
26850
|
+
creativeDirection: z111.string().max(2e3).optional(),
|
|
26851
|
+
selectedAngleNumbers: z111.array(z111.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."),
|
|
26852
|
+
angleEdits: z111.array(z111.object({
|
|
26853
|
+
angleNumber: z111.number().int().positive(),
|
|
26854
|
+
narrativeSelection: z111.enum([
|
|
26811
26855
|
"market",
|
|
26812
26856
|
"guided"
|
|
26813
26857
|
]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
|
|
26814
|
-
angle:
|
|
26815
|
-
buyerPersona:
|
|
26858
|
+
angle: z111.string().min(1).max(480).optional(),
|
|
26859
|
+
buyerPersona: z111.string().min(1).max(360).optional(),
|
|
26816
26860
|
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.'),
|
|
26817
|
-
actor:
|
|
26818
|
-
actorId:
|
|
26819
|
-
creativeDirection:
|
|
26861
|
+
actor: z111.string().min(1).max(360).optional(),
|
|
26862
|
+
actorId: z111.string().max(120).nullable().optional(),
|
|
26863
|
+
creativeDirection: z111.string().max(2e3).optional()
|
|
26820
26864
|
}).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)."),
|
|
26821
|
-
gapDurationSeconds:
|
|
26822
|
-
|
|
26823
|
-
|
|
26865
|
+
gapDurationSeconds: z111.union([
|
|
26866
|
+
z111.literal(15),
|
|
26867
|
+
z111.literal(30)
|
|
26824
26868
|
]).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.")
|
|
26825
26869
|
}),
|
|
26826
|
-
|
|
26827
|
-
kind:
|
|
26828
|
-
angleId:
|
|
26829
|
-
angleNumber:
|
|
26830
|
-
content:
|
|
26831
|
-
creativeDirection:
|
|
26832
|
-
actor:
|
|
26870
|
+
z111.object({
|
|
26871
|
+
kind: z111.literal("service_angle_approval"),
|
|
26872
|
+
angleId: z111.string().uuid().optional(),
|
|
26873
|
+
angleNumber: z111.number().int().positive().optional(),
|
|
26874
|
+
content: z111.string().min(1).max(480).optional(),
|
|
26875
|
+
creativeDirection: z111.string().min(1).max(1500).optional(),
|
|
26876
|
+
actor: z111.string().min(1).max(360).optional()
|
|
26833
26877
|
}),
|
|
26834
|
-
|
|
26835
|
-
kind:
|
|
26836
|
-
voiceovers:
|
|
26837
|
-
visualDirections:
|
|
26838
|
-
voiceoversByScene:
|
|
26839
|
-
visualDirectionsByScene:
|
|
26878
|
+
z111.object({
|
|
26879
|
+
kind: z111.literal("service_script_approval"),
|
|
26880
|
+
voiceovers: z111.record(z111.string(), z111.string().min(1).max(600)).optional(),
|
|
26881
|
+
visualDirections: z111.record(z111.string(), z111.string().min(1).max(1200)).optional(),
|
|
26882
|
+
voiceoversByScene: z111.record(z111.string(), z111.string().min(1).max(600)).optional(),
|
|
26883
|
+
visualDirectionsByScene: z111.record(z111.string(), z111.string().min(1).max(1200)).optional()
|
|
26840
26884
|
})
|
|
26841
26885
|
]);
|
|
26842
|
-
var ResolvePendingActionInput =
|
|
26843
|
-
taskId:
|
|
26886
|
+
var ResolvePendingActionInput = z111.object({
|
|
26887
|
+
taskId: z111.string().min(1),
|
|
26844
26888
|
action: PendingActionPayload
|
|
26845
26889
|
}).strict();
|
|
26846
26890
|
function resolveVariantConfirmVideoTier(action) {
|
|
26847
26891
|
return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
|
|
26848
26892
|
}
|
|
26849
26893
|
__name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
|
|
26850
|
-
var StatusForResolveSchema =
|
|
26894
|
+
var StatusForResolveSchema = z111.object({
|
|
26851
26895
|
// Metadata used to select the backend resume contract. Older API responses
|
|
26852
26896
|
// may omit these fields, so the resolver keeps the generic fallback.
|
|
26853
|
-
kind:
|
|
26897
|
+
kind: z111.enum([
|
|
26854
26898
|
"autopilot",
|
|
26855
26899
|
"video",
|
|
26856
26900
|
"image",
|
|
@@ -26858,18 +26902,18 @@ var StatusForResolveSchema = z110.object({
|
|
|
26858
26902
|
"mix",
|
|
26859
26903
|
"service"
|
|
26860
26904
|
]).optional(),
|
|
26861
|
-
selectedOutputs:
|
|
26905
|
+
selectedOutputs: z111.array(z111.enum([
|
|
26862
26906
|
"landing",
|
|
26863
26907
|
"video",
|
|
26864
26908
|
"image"
|
|
26865
26909
|
])).optional(),
|
|
26866
|
-
videoAngleCount:
|
|
26867
|
-
ugcFormat:
|
|
26910
|
+
videoAngleCount: z111.number().int().min(1).max(3).optional(),
|
|
26911
|
+
ugcFormat: z111.enum([
|
|
26868
26912
|
"single_8s",
|
|
26869
26913
|
"single_15s",
|
|
26870
26914
|
"double_30s"
|
|
26871
26915
|
]).optional(),
|
|
26872
|
-
videoStyle:
|
|
26916
|
+
videoStyle: z111.enum([
|
|
26873
26917
|
"ugc",
|
|
26874
26918
|
"cartoon_3d",
|
|
26875
26919
|
"product_only",
|
|
@@ -26879,13 +26923,13 @@ var StatusForResolveSchema = z110.object({
|
|
|
26879
26923
|
videoQuality: VideoQualityEnum.optional(),
|
|
26880
26924
|
videoRouteId: VideoRouteIdEnum.optional(),
|
|
26881
26925
|
videoModel: TaskVideoModelEnum.optional(),
|
|
26882
|
-
videoTier:
|
|
26926
|
+
videoTier: z111.enum([
|
|
26883
26927
|
"legacy",
|
|
26884
26928
|
"standard",
|
|
26885
26929
|
"pro",
|
|
26886
26930
|
"single_call"
|
|
26887
26931
|
]).optional(),
|
|
26888
|
-
videoResolution:
|
|
26932
|
+
videoResolution: z111.enum([
|
|
26889
26933
|
"480p",
|
|
26890
26934
|
"720p"
|
|
26891
26935
|
]).optional(),
|
|
@@ -26893,60 +26937,60 @@ var StatusForResolveSchema = z110.object({
|
|
|
26893
26937
|
// A task created before a narrative was blocked/hidden must still parse,
|
|
26894
26938
|
// or resolve_pending_action could never approve it.
|
|
26895
26939
|
narrativeStyle: NarrativeStyle.optional(),
|
|
26896
|
-
pauseForVideoScriptReview:
|
|
26897
|
-
pendingUserAction:
|
|
26898
|
-
kind:
|
|
26899
|
-
candidateGrouping:
|
|
26900
|
-
selectedImageUrls:
|
|
26901
|
-
proposedProductNames:
|
|
26940
|
+
pauseForVideoScriptReview: z111.boolean().optional(),
|
|
26941
|
+
pendingUserAction: z111.object({
|
|
26942
|
+
kind: z111.string(),
|
|
26943
|
+
candidateGrouping: z111.string().optional(),
|
|
26944
|
+
selectedImageUrls: z111.array(z111.string()).optional(),
|
|
26945
|
+
proposedProductNames: z111.array(z111.string()).optional(),
|
|
26902
26946
|
// Adaptive reference questions are server-owned. Echo only the evidence
|
|
26903
26947
|
// identity and the choices shown by the current snapshot; never accept a
|
|
26904
26948
|
// client-supplied reference set as authorization.
|
|
26905
|
-
options:
|
|
26906
|
-
mode:
|
|
26949
|
+
options: z111.array(ProductReferenceUserChoiceEnum).max(4).optional(),
|
|
26950
|
+
mode: z111.enum([
|
|
26907
26951
|
"question",
|
|
26908
26952
|
"visual_recovery"
|
|
26909
26953
|
]).optional(),
|
|
26910
26954
|
/** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
|
|
26911
|
-
canKeepSelection:
|
|
26912
|
-
decisionKey:
|
|
26913
|
-
questionOrdinal:
|
|
26914
|
-
questionCeiling:
|
|
26915
|
-
|
|
26916
|
-
|
|
26955
|
+
canKeepSelection: z111.boolean().optional(),
|
|
26956
|
+
decisionKey: z111.string().optional(),
|
|
26957
|
+
questionOrdinal: z111.number().int().min(1).max(5).optional(),
|
|
26958
|
+
questionCeiling: z111.union([
|
|
26959
|
+
z111.literal(3),
|
|
26960
|
+
z111.literal(5)
|
|
26917
26961
|
]).optional(),
|
|
26918
|
-
referenceEvidenceVersion:
|
|
26919
|
-
expectedEvidenceHash:
|
|
26920
|
-
question:
|
|
26921
|
-
prompt:
|
|
26922
|
-
helpText:
|
|
26923
|
-
options:
|
|
26962
|
+
referenceEvidenceVersion: z111.number().int().positive().optional(),
|
|
26963
|
+
expectedEvidenceHash: z111.string().optional(),
|
|
26964
|
+
question: z111.object({
|
|
26965
|
+
prompt: z111.string().min(1).max(240),
|
|
26966
|
+
helpText: z111.string().min(1).max(300).optional(),
|
|
26967
|
+
options: z111.array(z111.object({
|
|
26924
26968
|
value: ProductReferenceUserChoiceEnum,
|
|
26925
|
-
label:
|
|
26926
|
-
description:
|
|
26969
|
+
label: z111.string().min(1).max(120),
|
|
26970
|
+
description: z111.string().min(1).max(240).optional()
|
|
26927
26971
|
})).min(2).max(4)
|
|
26928
26972
|
}).optional(),
|
|
26929
26973
|
scope: ProductReferenceScopeEnum.optional(),
|
|
26930
|
-
scopeKey:
|
|
26931
|
-
scopeSnapshotId:
|
|
26932
|
-
scopeHash:
|
|
26933
|
-
baseReferenceSetHash:
|
|
26934
|
-
phase:
|
|
26974
|
+
scopeKey: z111.string().optional(),
|
|
26975
|
+
scopeSnapshotId: z111.string().uuid().optional(),
|
|
26976
|
+
scopeHash: z111.string().optional(),
|
|
26977
|
+
baseReferenceSetHash: z111.string().optional(),
|
|
26978
|
+
phase: z111.enum([
|
|
26935
26979
|
"preparation",
|
|
26936
26980
|
"final"
|
|
26937
26981
|
]).optional(),
|
|
26938
|
-
selectedRefKeys:
|
|
26939
|
-
allowedDecisions:
|
|
26940
|
-
previews:
|
|
26941
|
-
refKey:
|
|
26982
|
+
selectedRefKeys: z111.array(z111.string().min(1).max(200)).optional(),
|
|
26983
|
+
allowedDecisions: z111.array(ProductReferenceResolutionDecisionEnum).optional(),
|
|
26984
|
+
previews: z111.array(z111.object({
|
|
26985
|
+
refKey: z111.string().min(1).max(200)
|
|
26942
26986
|
}).passthrough()).optional(),
|
|
26943
|
-
customAngleDraft:
|
|
26944
|
-
painPointsDraft:
|
|
26945
|
-
benefitsDraft:
|
|
26946
|
-
featuresDraft:
|
|
26947
|
-
angleOptions:
|
|
26948
|
-
index:
|
|
26949
|
-
angle:
|
|
26987
|
+
customAngleDraft: z111.string().optional(),
|
|
26988
|
+
painPointsDraft: z111.string().optional(),
|
|
26989
|
+
benefitsDraft: z111.string().optional(),
|
|
26990
|
+
featuresDraft: z111.array(z111.string()).optional(),
|
|
26991
|
+
angleOptions: z111.array(z111.object({
|
|
26992
|
+
index: z111.number().int().nonnegative(),
|
|
26993
|
+
angle: z111.string().min(1)
|
|
26950
26994
|
}).passthrough()).min(1).max(5).optional(),
|
|
26951
26995
|
// Recommendation consumed only when the caller explicitly sends
|
|
26952
26996
|
// gapDurationSeconds: 30 in the angle approval action.
|
|
@@ -26956,17 +27000,17 @@ var StatusForResolveSchema = z110.object({
|
|
|
26956
27000
|
// keys. `actorId` (the saved custom actor the picker stored) was silently
|
|
26957
27001
|
// dropped here, so the approval handler below could not echo it back on the
|
|
26958
27002
|
// PATCH — the selection looked accepted and reached no render.
|
|
26959
|
-
angles:
|
|
26960
|
-
id:
|
|
26961
|
-
content:
|
|
26962
|
-
creativeDirection:
|
|
26963
|
-
actor:
|
|
26964
|
-
actorId:
|
|
27003
|
+
angles: z111.array(z111.object({
|
|
27004
|
+
id: z111.string().uuid(),
|
|
27005
|
+
content: z111.string(),
|
|
27006
|
+
creativeDirection: z111.string(),
|
|
27007
|
+
actor: z111.string(),
|
|
27008
|
+
actorId: z111.string().nullable().optional()
|
|
26965
27009
|
}).passthrough()).optional(),
|
|
26966
|
-
panels:
|
|
26967
|
-
beatId:
|
|
26968
|
-
voiceover:
|
|
26969
|
-
visualDirection:
|
|
27010
|
+
panels: z111.array(z111.object({
|
|
27011
|
+
beatId: z111.string(),
|
|
27012
|
+
voiceover: z111.string(),
|
|
27013
|
+
visualDirection: z111.string()
|
|
26970
27014
|
}).passthrough()).optional()
|
|
26971
27015
|
}).optional()
|
|
26972
27016
|
}).passthrough();
|
|
@@ -27318,8 +27362,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
27318
27362
|
server.registerTool("verify_landing_commerce", {
|
|
27319
27363
|
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.",
|
|
27320
27364
|
inputSchema: {
|
|
27321
|
-
taskId:
|
|
27322
|
-
editId:
|
|
27365
|
+
taskId: z111.string().uuid(),
|
|
27366
|
+
editId: z111.string().uuid()
|
|
27323
27367
|
},
|
|
27324
27368
|
annotations: OVERWRITES_EXTERNAL
|
|
27325
27369
|
}, async (input) => {
|
|
@@ -27959,7 +28003,7 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
|
|
|
27959
28003
|
__name(registerTaskTools, "registerTaskTools");
|
|
27960
28004
|
|
|
27961
28005
|
// src/tools/creatives.ts
|
|
27962
|
-
import { z as
|
|
28006
|
+
import { z as z112 } from "zod";
|
|
27963
28007
|
var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
|
|
27964
28008
|
var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
|
|
27965
28009
|
var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
|
|
@@ -27970,72 +28014,72 @@ var CreativeRefs = {
|
|
|
27970
28014
|
images: ImagesInput,
|
|
27971
28015
|
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.'),
|
|
27972
28016
|
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.'),
|
|
27973
|
-
price:
|
|
27974
|
-
offer:
|
|
27975
|
-
compareAtPrice:
|
|
27976
|
-
productContext:
|
|
27977
|
-
productLabel:
|
|
27978
|
-
buyerPersona:
|
|
27979
|
-
isCombo:
|
|
27980
|
-
competitorScanEnabled:
|
|
27981
|
-
brandId:
|
|
28017
|
+
price: z112.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.'),
|
|
28018
|
+
offer: z112.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.'),
|
|
28019
|
+
compareAtPrice: z112.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
|
|
28020
|
+
productContext: z112.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."),
|
|
28021
|
+
productLabel: z112.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.'),
|
|
28022
|
+
buyerPersona: z112.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.'),
|
|
28023
|
+
isCombo: z112.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
|
|
28024
|
+
competitorScanEnabled: z112.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."),
|
|
28025
|
+
brandId: z112.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.")
|
|
27982
28026
|
};
|
|
27983
|
-
var VideoPresenter =
|
|
27984
|
-
|
|
27985
|
-
mode:
|
|
28027
|
+
var VideoPresenter = z112.discriminatedUnion("mode", [
|
|
28028
|
+
z112.object({
|
|
28029
|
+
mode: z112.literal("none")
|
|
27986
28030
|
}).strict(),
|
|
27987
|
-
|
|
27988
|
-
mode:
|
|
27989
|
-
actorId:
|
|
28031
|
+
z112.object({
|
|
28032
|
+
mode: z112.literal("saved_actor"),
|
|
28033
|
+
actorId: z112.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
|
|
27990
28034
|
}).strict(),
|
|
27991
|
-
|
|
27992
|
-
mode:
|
|
27993
|
-
description:
|
|
28035
|
+
z112.object({
|
|
28036
|
+
mode: z112.literal("described"),
|
|
28037
|
+
description: z112.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
|
|
27994
28038
|
}).strict()
|
|
27995
28039
|
]);
|
|
27996
|
-
var VideoCreativeSetup =
|
|
27997
|
-
|
|
27998
|
-
mode:
|
|
28040
|
+
var VideoCreativeSetup = z112.discriminatedUnion("mode", [
|
|
28041
|
+
z112.object({
|
|
28042
|
+
mode: z112.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
|
|
27999
28043
|
}).strict(),
|
|
28000
|
-
|
|
28001
|
-
mode:
|
|
28044
|
+
z112.object({
|
|
28045
|
+
mode: z112.literal("guided"),
|
|
28002
28046
|
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.'),
|
|
28003
|
-
buyerPersona:
|
|
28047
|
+
buyerPersona: z112.string().trim().min(1).max(360),
|
|
28004
28048
|
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.'),
|
|
28005
28049
|
presenter: VideoPresenter,
|
|
28006
|
-
creativeDirection:
|
|
28050
|
+
creativeDirection: z112.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
|
|
28007
28051
|
}).strict()
|
|
28008
28052
|
]);
|
|
28009
|
-
var VideoInput =
|
|
28053
|
+
var VideoInput = z112.object({
|
|
28010
28054
|
images: CreativeRefs.images.optional(),
|
|
28011
28055
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
28012
|
-
title:
|
|
28013
|
-
primaryAngle:
|
|
28056
|
+
title: z112.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
|
|
28057
|
+
primaryAngle: z112.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".'),
|
|
28014
28058
|
language: CreativeRefs.language,
|
|
28015
28059
|
country: CreativeRefs.country,
|
|
28016
|
-
aspectRatio:
|
|
28060
|
+
aspectRatio: z112.enum([
|
|
28017
28061
|
"9:16",
|
|
28018
28062
|
"16:9",
|
|
28019
28063
|
"Auto"
|
|
28020
28064
|
]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
|
|
28021
28065
|
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.'),
|
|
28022
|
-
durationSeconds:
|
|
28023
|
-
videoAngleCount:
|
|
28066
|
+
durationSeconds: z112.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."),
|
|
28067
|
+
videoAngleCount: z112.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."),
|
|
28024
28068
|
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.'),
|
|
28025
28069
|
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."),
|
|
28026
28070
|
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.'),
|
|
28027
28071
|
videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
|
|
28028
28072
|
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.'),
|
|
28029
|
-
features:
|
|
28073
|
+
features: z112.array(z112.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
|
|
28030
28074
|
price: CreativeRefs.price,
|
|
28031
28075
|
offer: CreativeRefs.offer,
|
|
28032
28076
|
productContext: CreativeRefs.productContext,
|
|
28033
28077
|
productLabel: CreativeRefs.productLabel,
|
|
28034
|
-
cta:
|
|
28035
|
-
scriptNotes:
|
|
28078
|
+
cta: z112.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.'),
|
|
28079
|
+
scriptNotes: z112.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.'),
|
|
28036
28080
|
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.'),
|
|
28037
28081
|
competitorScanEnabled: CreativeRefs.competitorScanEnabled,
|
|
28038
|
-
replicateWinnerWhenFound:
|
|
28082
|
+
replicateWinnerWhenFound: z112.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."),
|
|
28039
28083
|
brandId: CreativeRefs.brandId
|
|
28040
28084
|
}).strict();
|
|
28041
28085
|
var FreeVideoQualityEnum = VideoQualityEnum;
|
|
@@ -28053,7 +28097,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
|
|
|
28053
28097
|
length: 29
|
|
28054
28098
|
}, (_, index) => index + 2)
|
|
28055
28099
|
};
|
|
28056
|
-
var FreeVideoModelIdEnum =
|
|
28100
|
+
var FreeVideoModelIdEnum = z112.enum([
|
|
28057
28101
|
"grok-imagine-video-1-5-preview",
|
|
28058
28102
|
"minimax-h3/reference-to-video",
|
|
28059
28103
|
"wan/3-0-video",
|
|
@@ -28064,66 +28108,66 @@ var FREE_SELECTABLE_MODEL_IDS = [
|
|
|
28064
28108
|
"minimax-h3/reference-to-video",
|
|
28065
28109
|
"wan/3-0-video"
|
|
28066
28110
|
];
|
|
28067
|
-
var FreeVideoInput =
|
|
28111
|
+
var FreeVideoInput = z112.object({
|
|
28068
28112
|
images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
|
|
28069
|
-
rawPrompt:
|
|
28113
|
+
rawPrompt: z112.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."),
|
|
28070
28114
|
language: CreativeRefs.language,
|
|
28071
28115
|
quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
|
|
28072
28116
|
// Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
|
|
28073
28117
|
// parsed ONLY so the handler can reject it with a message naming its
|
|
28074
28118
|
// replacement — dropping it silently would turn a caller's explicit
|
|
28075
28119
|
// Pro++ pick into a quiet fallback to Wan.
|
|
28076
|
-
freeProModel:
|
|
28120
|
+
freeProModel: z112.enum([
|
|
28077
28121
|
"wan",
|
|
28078
28122
|
"seedance"
|
|
28079
28123
|
]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
|
|
28080
28124
|
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.'),
|
|
28081
|
-
durationSeconds:
|
|
28125
|
+
durationSeconds: z112.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."),
|
|
28082
28126
|
videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
|
|
28083
|
-
generateAiMusic:
|
|
28127
|
+
generateAiMusic: z112.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.'),
|
|
28084
28128
|
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.'),
|
|
28085
|
-
addSubtitles:
|
|
28086
|
-
idempotencyKey:
|
|
28129
|
+
addSubtitles: z112.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
|
|
28130
|
+
idempotencyKey: z112.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.")
|
|
28087
28131
|
}).strict();
|
|
28088
28132
|
var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
|
|
28089
|
-
var ImageCreativeSetup =
|
|
28090
|
-
|
|
28091
|
-
mode:
|
|
28133
|
+
var ImageCreativeSetup = z112.discriminatedUnion("mode", [
|
|
28134
|
+
z112.object({
|
|
28135
|
+
mode: z112.literal("automatic")
|
|
28092
28136
|
}).strict(),
|
|
28093
|
-
|
|
28094
|
-
mode:
|
|
28095
|
-
creativeArchetype:
|
|
28137
|
+
z112.object({
|
|
28138
|
+
mode: z112.literal("guided"),
|
|
28139
|
+
creativeArchetype: z112.union([
|
|
28096
28140
|
ImageCreativeArchetypeEnum,
|
|
28097
|
-
|
|
28141
|
+
z112.literal("ai_decides")
|
|
28098
28142
|
]),
|
|
28099
|
-
visualTreatment:
|
|
28143
|
+
visualTreatment: z112.union([
|
|
28100
28144
|
ImageCreativeVisualTreatmentEnum,
|
|
28101
|
-
|
|
28145
|
+
z112.literal("ai_decides")
|
|
28102
28146
|
]),
|
|
28103
28147
|
aspectRatio: ImageCreativeAspectRatioEnum,
|
|
28104
|
-
nVariants:
|
|
28105
|
-
|
|
28106
|
-
|
|
28107
|
-
|
|
28108
|
-
|
|
28109
|
-
|
|
28148
|
+
nVariants: z112.union([
|
|
28149
|
+
z112.literal(1),
|
|
28150
|
+
z112.literal(2),
|
|
28151
|
+
z112.literal(3),
|
|
28152
|
+
z112.literal(4),
|
|
28153
|
+
z112.literal(6)
|
|
28110
28154
|
]),
|
|
28111
|
-
imageModel:
|
|
28112
|
-
styleMix:
|
|
28113
|
-
generateAdCopy:
|
|
28114
|
-
competitorScanEnabled:
|
|
28115
|
-
productContext:
|
|
28116
|
-
creativeDirection:
|
|
28117
|
-
brandColors:
|
|
28118
|
-
headline:
|
|
28119
|
-
subheadline:
|
|
28155
|
+
imageModel: z112.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.'),
|
|
28156
|
+
styleMix: z112.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
|
|
28157
|
+
generateAdCopy: z112.boolean(),
|
|
28158
|
+
competitorScanEnabled: z112.boolean(),
|
|
28159
|
+
productContext: z112.string().trim().min(1).max(3e3).nullable(),
|
|
28160
|
+
creativeDirection: z112.string().trim().min(1).max(500).nullable(),
|
|
28161
|
+
brandColors: z112.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.'),
|
|
28162
|
+
headline: z112.string().trim().min(1).max(120).nullable(),
|
|
28163
|
+
subheadline: z112.string().trim().min(1).max(160).nullable()
|
|
28120
28164
|
}).strict()
|
|
28121
28165
|
]).superRefine((setup, context) => {
|
|
28122
28166
|
if (setup.mode !== "guided") return;
|
|
28123
28167
|
const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
|
|
28124
28168
|
if (needsStyleMix && setup.styleMix === null) {
|
|
28125
28169
|
context.addIssue({
|
|
28126
|
-
code:
|
|
28170
|
+
code: z112.ZodIssueCode.custom,
|
|
28127
28171
|
path: [
|
|
28128
28172
|
"styleMix"
|
|
28129
28173
|
],
|
|
@@ -28132,7 +28176,7 @@ var ImageCreativeSetup = z111.discriminatedUnion("mode", [
|
|
|
28132
28176
|
}
|
|
28133
28177
|
if (!needsStyleMix && setup.styleMix !== null) {
|
|
28134
28178
|
context.addIssue({
|
|
28135
|
-
code:
|
|
28179
|
+
code: z112.ZodIssueCode.custom,
|
|
28136
28180
|
path: [
|
|
28137
28181
|
"styleMix"
|
|
28138
28182
|
],
|
|
@@ -28141,7 +28185,7 @@ var ImageCreativeSetup = z111.discriminatedUnion("mode", [
|
|
|
28141
28185
|
}
|
|
28142
28186
|
if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
|
|
28143
28187
|
context.addIssue({
|
|
28144
|
-
code:
|
|
28188
|
+
code: z112.ZodIssueCode.custom,
|
|
28145
28189
|
path: [
|
|
28146
28190
|
"aspectRatio"
|
|
28147
28191
|
],
|
|
@@ -28149,55 +28193,55 @@ var ImageCreativeSetup = z111.discriminatedUnion("mode", [
|
|
|
28149
28193
|
});
|
|
28150
28194
|
}
|
|
28151
28195
|
});
|
|
28152
|
-
var LandingCreativeSetup =
|
|
28153
|
-
|
|
28154
|
-
mode:
|
|
28196
|
+
var LandingCreativeSetup = z112.discriminatedUnion("mode", [
|
|
28197
|
+
z112.object({
|
|
28198
|
+
mode: z112.literal("automatic")
|
|
28155
28199
|
}).strict(),
|
|
28156
|
-
|
|
28157
|
-
mode:
|
|
28200
|
+
z112.object({
|
|
28201
|
+
mode: z112.literal("guided"),
|
|
28158
28202
|
landingStrategy: LandingStrategyEnum,
|
|
28159
28203
|
landingImageFormat: LandingImageFormatEnum,
|
|
28160
|
-
competitorScanEnabled:
|
|
28161
|
-
paymentMethods:
|
|
28162
|
-
productContext:
|
|
28163
|
-
creativeDirection:
|
|
28164
|
-
headline:
|
|
28165
|
-
subheadline:
|
|
28204
|
+
competitorScanEnabled: z112.boolean(),
|
|
28205
|
+
paymentMethods: z112.string().trim().min(1).max(240).nullable(),
|
|
28206
|
+
productContext: z112.string().trim().min(1).max(3e3).nullable(),
|
|
28207
|
+
creativeDirection: z112.string().trim().min(1).max(500).nullable(),
|
|
28208
|
+
headline: z112.string().trim().min(1).max(120).nullable(),
|
|
28209
|
+
subheadline: z112.string().trim().min(1).max(160).nullable()
|
|
28166
28210
|
}).strict()
|
|
28167
28211
|
]);
|
|
28168
|
-
var ImageInput =
|
|
28212
|
+
var ImageInput = z112.object({
|
|
28169
28213
|
images: CreativeRefs.images.optional(),
|
|
28170
28214
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
28171
|
-
productTitle:
|
|
28172
|
-
primaryAngle:
|
|
28215
|
+
productTitle: z112.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
|
|
28216
|
+
primaryAngle: z112.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.'),
|
|
28173
28217
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
28174
28218
|
language: CreativeRefs.language,
|
|
28175
28219
|
country: CreativeRefs.country,
|
|
28176
28220
|
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."),
|
|
28177
28221
|
imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
|
|
28178
|
-
features:
|
|
28222
|
+
features: z112.array(z112.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
|
|
28179
28223
|
price: CreativeRefs.price,
|
|
28180
|
-
omitPrice:
|
|
28224
|
+
omitPrice: z112.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."),
|
|
28181
28225
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
28182
28226
|
offer: CreativeRefs.offer,
|
|
28183
28227
|
productLabel: CreativeRefs.productLabel,
|
|
28184
28228
|
isCombo: CreativeRefs.isCombo,
|
|
28185
28229
|
brandId: CreativeRefs.brandId
|
|
28186
28230
|
});
|
|
28187
|
-
var EditImageCreativeInput =
|
|
28188
|
-
taskId:
|
|
28189
|
-
variantIndex:
|
|
28190
|
-
clientRequestId:
|
|
28191
|
-
instruction:
|
|
28231
|
+
var EditImageCreativeInput = z112.object({
|
|
28232
|
+
taskId: z112.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
|
|
28233
|
+
variantIndex: z112.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
|
|
28234
|
+
clientRequestId: z112.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."),
|
|
28235
|
+
instruction: z112.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".')
|
|
28192
28236
|
});
|
|
28193
|
-
var LandingInput =
|
|
28194
|
-
includeInitialLandingGif:
|
|
28237
|
+
var LandingInput = z112.object({
|
|
28238
|
+
includeInitialLandingGif: z112.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."),
|
|
28195
28239
|
images: CreativeRefs.images.optional(),
|
|
28196
28240
|
winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
|
|
28197
28241
|
language: CreativeRefs.language,
|
|
28198
28242
|
country: CreativeRefs.country,
|
|
28199
28243
|
creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
|
|
28200
|
-
salesAngle:
|
|
28244
|
+
salesAngle: z112.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.'),
|
|
28201
28245
|
buyerPersona: CreativeRefs.buyerPersona,
|
|
28202
28246
|
price: CreativeRefs.price,
|
|
28203
28247
|
compareAtPrice: CreativeRefs.compareAtPrice,
|
|
@@ -28479,8 +28523,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
28479
28523
|
server.registerTool("get_image_edit_status", {
|
|
28480
28524
|
description: imageEditStatusGuidance.summary,
|
|
28481
28525
|
inputSchema: {
|
|
28482
|
-
taskId:
|
|
28483
|
-
operationId:
|
|
28526
|
+
taskId: z112.string().uuid(),
|
|
28527
|
+
operationId: z112.string().uuid()
|
|
28484
28528
|
},
|
|
28485
28529
|
annotations: READS_INTERNAL
|
|
28486
28530
|
}, async (input) => {
|
|
@@ -28537,10 +28581,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
|
|
|
28537
28581
|
__name(registerCreativeTools, "registerCreativeTools");
|
|
28538
28582
|
|
|
28539
28583
|
// src/tools/creative-variants.ts
|
|
28540
|
-
import { z as
|
|
28584
|
+
import { z as z113 } from "zod";
|
|
28541
28585
|
var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
|
|
28542
28586
|
var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
|
|
28543
|
-
var LandingSectionKeyEnum =
|
|
28587
|
+
var LandingSectionKeyEnum = z113.enum([
|
|
28544
28588
|
"problem_hook",
|
|
28545
28589
|
"problem_cost",
|
|
28546
28590
|
"solution_mechanism",
|
|
@@ -28580,24 +28624,24 @@ var LandingSectionKeyEnum = z112.enum([
|
|
|
28580
28624
|
"lifestyle_fit",
|
|
28581
28625
|
"join_lifestyle"
|
|
28582
28626
|
]);
|
|
28583
|
-
var CreativeVariantKindEnum =
|
|
28627
|
+
var CreativeVariantKindEnum = z113.enum([
|
|
28584
28628
|
"video",
|
|
28585
28629
|
"image",
|
|
28586
28630
|
"landing"
|
|
28587
28631
|
]);
|
|
28588
|
-
var EstimateCreativeVariantInputBase =
|
|
28589
|
-
sourceTaskId:
|
|
28632
|
+
var EstimateCreativeVariantInputBase = z113.object({
|
|
28633
|
+
sourceTaskId: z113.string().uuid().describe("ID de la tarea original completada."),
|
|
28590
28634
|
kind: CreativeVariantKindEnum,
|
|
28591
28635
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
|
|
28592
28636
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
|
|
28593
|
-
nVariants:
|
|
28637
|
+
nVariants: z113.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
28594
28638
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
|
|
28595
|
-
instructions:
|
|
28639
|
+
instructions: z113.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.")
|
|
28596
28640
|
}).strict();
|
|
28597
28641
|
var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
28598
28642
|
if (input.kind === "video" && input.nVariants !== void 0) {
|
|
28599
28643
|
ctx.addIssue({
|
|
28600
|
-
code:
|
|
28644
|
+
code: z113.ZodIssueCode.custom,
|
|
28601
28645
|
path: [
|
|
28602
28646
|
"nVariants"
|
|
28603
28647
|
],
|
|
@@ -28607,7 +28651,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28607
28651
|
if (input.kind !== "video") {
|
|
28608
28652
|
if (input.videoPreset !== void 0) {
|
|
28609
28653
|
ctx.addIssue({
|
|
28610
|
-
code:
|
|
28654
|
+
code: z113.ZodIssueCode.custom,
|
|
28611
28655
|
path: [
|
|
28612
28656
|
"videoPreset"
|
|
28613
28657
|
],
|
|
@@ -28616,7 +28660,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28616
28660
|
}
|
|
28617
28661
|
if (input.videoResolution !== void 0) {
|
|
28618
28662
|
ctx.addIssue({
|
|
28619
|
-
code:
|
|
28663
|
+
code: z113.ZodIssueCode.custom,
|
|
28620
28664
|
path: [
|
|
28621
28665
|
"videoResolution"
|
|
28622
28666
|
],
|
|
@@ -28626,7 +28670,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28626
28670
|
}
|
|
28627
28671
|
if (input.kind !== "image" && input.nVariants !== void 0) {
|
|
28628
28672
|
ctx.addIssue({
|
|
28629
|
-
code:
|
|
28673
|
+
code: z113.ZodIssueCode.custom,
|
|
28630
28674
|
path: [
|
|
28631
28675
|
"nVariants"
|
|
28632
28676
|
],
|
|
@@ -28636,7 +28680,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28636
28680
|
if (input.kind !== "landing") {
|
|
28637
28681
|
if (input.sectionKey !== void 0) {
|
|
28638
28682
|
ctx.addIssue({
|
|
28639
|
-
code:
|
|
28683
|
+
code: z113.ZodIssueCode.custom,
|
|
28640
28684
|
path: [
|
|
28641
28685
|
"sectionKey"
|
|
28642
28686
|
],
|
|
@@ -28645,7 +28689,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28645
28689
|
}
|
|
28646
28690
|
if (input.instructions !== void 0) {
|
|
28647
28691
|
ctx.addIssue({
|
|
28648
|
-
code:
|
|
28692
|
+
code: z113.ZodIssueCode.custom,
|
|
28649
28693
|
path: [
|
|
28650
28694
|
"instructions"
|
|
28651
28695
|
],
|
|
@@ -28654,31 +28698,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
|
|
|
28654
28698
|
}
|
|
28655
28699
|
}
|
|
28656
28700
|
});
|
|
28657
|
-
var CreateCreativeVariantInputBase =
|
|
28658
|
-
sourceTaskId:
|
|
28701
|
+
var CreateCreativeVariantInputBase = z113.object({
|
|
28702
|
+
sourceTaskId: z113.string().uuid().describe("ID de la tarea original completada."),
|
|
28659
28703
|
kind: CreativeVariantKindEnum,
|
|
28660
|
-
confirm:
|
|
28661
|
-
clientRequestId:
|
|
28662
|
-
angle:
|
|
28663
|
-
buyerPersona:
|
|
28664
|
-
scriptNotes:
|
|
28665
|
-
creativeDirection:
|
|
28704
|
+
confirm: z113.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
|
|
28705
|
+
clientRequestId: z113.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."),
|
|
28706
|
+
angle: z113.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
|
|
28707
|
+
buyerPersona: z113.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
|
|
28708
|
+
scriptNotes: z113.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
|
|
28709
|
+
creativeDirection: z113.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
|
|
28666
28710
|
videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
|
|
28667
28711
|
videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
|
|
28668
|
-
generateAiMusic:
|
|
28669
|
-
nVariants:
|
|
28712
|
+
generateAiMusic: z113.boolean().optional().describe("Opcional para video."),
|
|
28713
|
+
nVariants: z113.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
|
|
28670
28714
|
imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
|
|
28671
28715
|
creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
|
|
28672
28716
|
visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
|
|
28673
28717
|
aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
|
|
28674
|
-
styleMix:
|
|
28718
|
+
styleMix: z113.boolean().optional().describe("Opcional para imagen."),
|
|
28675
28719
|
sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
|
|
28676
|
-
instructions:
|
|
28720
|
+
instructions: z113.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.")
|
|
28677
28721
|
}).strict();
|
|
28678
28722
|
var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
|
|
28679
28723
|
if ((input.kind === "video" || input.kind === "image") && !input.angle) {
|
|
28680
28724
|
ctx.addIssue({
|
|
28681
|
-
code:
|
|
28725
|
+
code: z113.ZodIssueCode.custom,
|
|
28682
28726
|
path: [
|
|
28683
28727
|
"angle"
|
|
28684
28728
|
],
|
|
@@ -28687,7 +28731,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
28687
28731
|
}
|
|
28688
28732
|
if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
|
|
28689
28733
|
ctx.addIssue({
|
|
28690
|
-
code:
|
|
28734
|
+
code: z113.ZodIssueCode.custom,
|
|
28691
28735
|
path: [
|
|
28692
28736
|
"instructions"
|
|
28693
28737
|
],
|
|
@@ -28733,7 +28777,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
|
|
|
28733
28777
|
for (const field of fieldsByKind[input.kind]) {
|
|
28734
28778
|
if (input[field] !== void 0) {
|
|
28735
28779
|
ctx.addIssue({
|
|
28736
|
-
code:
|
|
28780
|
+
code: z113.ZodIssueCode.custom,
|
|
28737
28781
|
path: [
|
|
28738
28782
|
field
|
|
28739
28783
|
],
|
|
@@ -28866,13 +28910,13 @@ function registerCreativeVariantTools(server, api) {
|
|
|
28866
28910
|
__name(registerCreativeVariantTools, "registerCreativeVariantTools");
|
|
28867
28911
|
|
|
28868
28912
|
// src/tools/script-review.ts
|
|
28869
|
-
import { z as
|
|
28913
|
+
import { z as z114 } from "zod";
|
|
28870
28914
|
var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
|
|
28871
28915
|
var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
|
|
28872
28916
|
var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
|
|
28873
|
-
var GetVideoScriptInput =
|
|
28874
|
-
taskId:
|
|
28875
|
-
angleKey:
|
|
28917
|
+
var GetVideoScriptInput = z114.object({
|
|
28918
|
+
taskId: z114.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
|
|
28919
|
+
angleKey: z114.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.')
|
|
28876
28920
|
}).strict();
|
|
28877
28921
|
var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
|
|
28878
28922
|
var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
|
|
@@ -28955,7 +28999,7 @@ function registerScriptReviewTools(server, api) {
|
|
|
28955
28999
|
__name(registerScriptReviewTools, "registerScriptReviewTools");
|
|
28956
29000
|
|
|
28957
29001
|
// src/tools/connections.ts
|
|
28958
|
-
import { z as
|
|
29002
|
+
import { z as z115 } from "zod";
|
|
28959
29003
|
var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
|
|
28960
29004
|
var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
|
|
28961
29005
|
var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
|
|
@@ -28964,7 +29008,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
|
|
|
28964
29008
|
function registerConnectionTools(server, api) {
|
|
28965
29009
|
server.registerTool("list_shopify_shops", {
|
|
28966
29010
|
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.",
|
|
28967
|
-
inputSchema:
|
|
29011
|
+
inputSchema: z115.object({}).shape,
|
|
28968
29012
|
annotations: READS_INTERNAL
|
|
28969
29013
|
}, async () => {
|
|
28970
29014
|
try {
|
|
@@ -28976,10 +29020,10 @@ function registerConnectionTools(server, api) {
|
|
|
28976
29020
|
});
|
|
28977
29021
|
server.registerTool("list_shopify_products", {
|
|
28978
29022
|
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.',
|
|
28979
|
-
inputSchema:
|
|
28980
|
-
shopDomain:
|
|
28981
|
-
query:
|
|
28982
|
-
taskId:
|
|
29023
|
+
inputSchema: z115.object({
|
|
29024
|
+
shopDomain: z115.string().min(3).max(120),
|
|
29025
|
+
query: z115.string().trim().max(120).optional(),
|
|
29026
|
+
taskId: z115.string().uuid().optional()
|
|
28983
29027
|
}).shape,
|
|
28984
29028
|
annotations: READS_EXTERNAL
|
|
28985
29029
|
}, async ({ shopDomain, query, taskId }) => {
|
|
@@ -28997,7 +29041,7 @@ function registerConnectionTools(server, api) {
|
|
|
28997
29041
|
});
|
|
28998
29042
|
server.registerTool("list_meta_ad_accounts", {
|
|
28999
29043
|
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.",
|
|
29000
|
-
inputSchema:
|
|
29044
|
+
inputSchema: z115.object({}).shape,
|
|
29001
29045
|
annotations: READS_EXTERNAL
|
|
29002
29046
|
}, async () => {
|
|
29003
29047
|
try {
|
|
@@ -29009,7 +29053,7 @@ function registerConnectionTools(server, api) {
|
|
|
29009
29053
|
});
|
|
29010
29054
|
server.registerTool("list_meta_destinations", {
|
|
29011
29055
|
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.",
|
|
29012
|
-
inputSchema:
|
|
29056
|
+
inputSchema: z115.object({}).shape,
|
|
29013
29057
|
annotations: READS_EXTERNAL,
|
|
29014
29058
|
_meta: {
|
|
29015
29059
|
"openai/widgetAccessible": true
|
|
@@ -29024,7 +29068,7 @@ function registerConnectionTools(server, api) {
|
|
|
29024
29068
|
});
|
|
29025
29069
|
server.registerTool("list_tiktok_advertisers", {
|
|
29026
29070
|
description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
|
|
29027
|
-
inputSchema:
|
|
29071
|
+
inputSchema: z115.object({}).shape,
|
|
29028
29072
|
annotations: READS_EXTERNAL
|
|
29029
29073
|
}, async () => {
|
|
29030
29074
|
try {
|
|
@@ -29038,7 +29082,7 @@ function registerConnectionTools(server, api) {
|
|
|
29038
29082
|
__name(registerConnectionTools, "registerConnectionTools");
|
|
29039
29083
|
|
|
29040
29084
|
// src/tools/actors.ts
|
|
29041
|
-
import { z as
|
|
29085
|
+
import { z as z116 } from "zod";
|
|
29042
29086
|
var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
|
|
29043
29087
|
var actorVoiceGuidance = {
|
|
29044
29088
|
capabilities: getProductMakerCapabilityModelGuidance("get_actor_voice_capabilities"),
|
|
@@ -29078,7 +29122,7 @@ function sanitizeVoiceResult(value) {
|
|
|
29078
29122
|
__name(sanitizeVoiceResult, "sanitizeVoiceResult");
|
|
29079
29123
|
function registerActorTools(server, api) {
|
|
29080
29124
|
const actor = {
|
|
29081
|
-
actorId:
|
|
29125
|
+
actorId: z116.string().min(1).max(64)
|
|
29082
29126
|
};
|
|
29083
29127
|
const safe = /* @__PURE__ */ __name(async (request) => {
|
|
29084
29128
|
try {
|
|
@@ -29107,8 +29151,8 @@ function registerActorTools(server, api) {
|
|
|
29107
29151
|
inputSchema: {
|
|
29108
29152
|
...actor,
|
|
29109
29153
|
draft: ActorVoiceDraftSchema,
|
|
29110
|
-
requestKey:
|
|
29111
|
-
acceptedQuoteId:
|
|
29154
|
+
requestKey: z116.string().trim().min(1).max(128),
|
|
29155
|
+
acceptedQuoteId: z116.string().trim().min(1).max(128)
|
|
29112
29156
|
},
|
|
29113
29157
|
annotations: CREATES_PAID
|
|
29114
29158
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews`, body)));
|
|
@@ -29116,7 +29160,7 @@ function registerActorTools(server, api) {
|
|
|
29116
29160
|
description: actorVoiceGuidance.get.summary,
|
|
29117
29161
|
inputSchema: {
|
|
29118
29162
|
...actor,
|
|
29119
|
-
candidateId:
|
|
29163
|
+
candidateId: z116.string().min(1).max(64)
|
|
29120
29164
|
},
|
|
29121
29165
|
annotations: READS_INTERNAL
|
|
29122
29166
|
}, async ({ actorId, candidateId }) => safe(api.getJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews/${encodeURIComponent(candidateId)}`)));
|
|
@@ -29124,15 +29168,15 @@ function registerActorTools(server, api) {
|
|
|
29124
29168
|
description: actorVoiceGuidance.approve.summary,
|
|
29125
29169
|
inputSchema: {
|
|
29126
29170
|
...actor,
|
|
29127
|
-
candidateId:
|
|
29128
|
-
expectedRevision:
|
|
29129
|
-
expectedApprovedRevision:
|
|
29171
|
+
candidateId: z116.string().min(1).max(64),
|
|
29172
|
+
expectedRevision: z116.number().int().positive(),
|
|
29173
|
+
expectedApprovedRevision: z116.number().int().positive().nullable().optional()
|
|
29130
29174
|
},
|
|
29131
29175
|
annotations: CREATES_INTERNAL
|
|
29132
29176
|
}, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/approve`, body)));
|
|
29133
29177
|
server.registerTool("list_actors", {
|
|
29134
29178
|
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.",
|
|
29135
|
-
inputSchema:
|
|
29179
|
+
inputSchema: z116.object({}).shape,
|
|
29136
29180
|
annotations: READS_INTERNAL
|
|
29137
29181
|
}, async () => {
|
|
29138
29182
|
try {
|
|
@@ -29165,7 +29209,7 @@ function registerActorTools(server, api) {
|
|
|
29165
29209
|
__name(registerActorTools, "registerActorTools");
|
|
29166
29210
|
|
|
29167
29211
|
// src/tools/publish.ts
|
|
29168
|
-
import { z as
|
|
29212
|
+
import { z as z117 } from "zod";
|
|
29169
29213
|
|
|
29170
29214
|
// src/tools/meta-publish-attempt-id.ts
|
|
29171
29215
|
var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
|
|
@@ -29204,40 +29248,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
|
|
|
29204
29248
|
var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
|
|
29205
29249
|
var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
|
|
29206
29250
|
var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
|
|
29207
|
-
var ShopifyInput =
|
|
29208
|
-
taskId:
|
|
29209
|
-
shopDomain:
|
|
29251
|
+
var ShopifyInput = z117.object({
|
|
29252
|
+
taskId: z117.string().min(1),
|
|
29253
|
+
shopDomain: z117.string().min(1),
|
|
29210
29254
|
/** Override: number of landing images to include. Default = ALL images the
|
|
29211
29255
|
* task generated (the MCP fetches /v1/results first to count). Bounded
|
|
29212
29256
|
* generously here; the backend validates each index against
|
|
29213
29257
|
* landing.images.length and rejects out-of-range. */
|
|
29214
|
-
numLandingImages:
|
|
29215
|
-
variantIndex:
|
|
29258
|
+
numLandingImages: z117.number().int().min(1).max(20).optional(),
|
|
29259
|
+
variantIndex: z117.number().int().min(0).optional(),
|
|
29216
29260
|
/** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
|
|
29217
29261
|
* When true, the landing renders variant-picker pills; when false, it ships
|
|
29218
29262
|
* a single-option product page. Defaults to false. */
|
|
29219
|
-
showVariantPicker:
|
|
29263
|
+
showVariantPicker: z117.boolean().optional(),
|
|
29220
29264
|
/** Default `auto` updates the product previously published for this task and
|
|
29221
29265
|
* shop. Use `existing` with targetProductId to choose another product, or
|
|
29222
29266
|
* `new` only when the user explicitly wants a duplicate/new listing. */
|
|
29223
|
-
publicationMode:
|
|
29267
|
+
publicationMode: z117.enum([
|
|
29224
29268
|
"auto",
|
|
29225
29269
|
"existing",
|
|
29226
29270
|
"new"
|
|
29227
29271
|
]).optional(),
|
|
29228
29272
|
/** Shopify product GID, numeric id, or admin product URL. Required when
|
|
29229
29273
|
* publicationMode is `existing`. */
|
|
29230
|
-
targetProductId:
|
|
29274
|
+
targetProductId: z117.string().trim().min(1).max(300).optional(),
|
|
29231
29275
|
/** Add an announcement bar text above add-to-cart (optional). */
|
|
29232
|
-
announcementBarEnabled:
|
|
29233
|
-
announcementBarText:
|
|
29276
|
+
announcementBarEnabled: z117.boolean().optional(),
|
|
29277
|
+
announcementBarText: z117.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
|
|
29234
29278
|
commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
|
|
29235
|
-
confirmed:
|
|
29279
|
+
confirmed: z117.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
|
|
29236
29280
|
});
|
|
29237
29281
|
var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
|
|
29238
29282
|
if (value.commerceCorrection && value.confirmed !== true) {
|
|
29239
29283
|
ctx.addIssue({
|
|
29240
|
-
code:
|
|
29284
|
+
code: z117.ZodIssueCode.custom,
|
|
29241
29285
|
path: [
|
|
29242
29286
|
"confirmed"
|
|
29243
29287
|
],
|
|
@@ -29246,7 +29290,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
29246
29290
|
}
|
|
29247
29291
|
if (value.announcementBarEnabled && !value.announcementBarText) {
|
|
29248
29292
|
ctx.addIssue({
|
|
29249
|
-
code:
|
|
29293
|
+
code: z117.ZodIssueCode.custom,
|
|
29250
29294
|
path: [
|
|
29251
29295
|
"announcementBarText"
|
|
29252
29296
|
],
|
|
@@ -29255,7 +29299,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
|
|
|
29255
29299
|
}
|
|
29256
29300
|
if (!value.announcementBarEnabled && value.announcementBarText) {
|
|
29257
29301
|
ctx.addIssue({
|
|
29258
|
-
code:
|
|
29302
|
+
code: z117.ZodIssueCode.custom,
|
|
29259
29303
|
path: [
|
|
29260
29304
|
"announcementBarText"
|
|
29261
29305
|
],
|
|
@@ -29269,91 +29313,91 @@ function parseShopifyInput(rawInput) {
|
|
|
29269
29313
|
return parsed.data;
|
|
29270
29314
|
}
|
|
29271
29315
|
__name(parseShopifyInput, "parseShopifyInput");
|
|
29272
|
-
var McpCampaignConfig =
|
|
29316
|
+
var McpCampaignConfig = z117.object({
|
|
29273
29317
|
/** ALWAYS in US dollars, whatever the ad account's currency is. ProductMaker
|
|
29274
29318
|
* converts to the account currency server-side. Do NOT pre-convert: on a COP
|
|
29275
29319
|
* account the user's "60.000 al día" is `dailyBudgetUsd: 15`, not 60000. */
|
|
29276
|
-
dailyBudgetUsd:
|
|
29320
|
+
dailyBudgetUsd: z117.number().positive().optional(),
|
|
29277
29321
|
/** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
|
|
29278
29322
|
* normalizes at validation). Meta accepts max 1 (single-country ad set).
|
|
29279
29323
|
* TikTok takes only the first entry. */
|
|
29280
|
-
targetCountries:
|
|
29281
|
-
campaignName:
|
|
29324
|
+
targetCountries: z117.array(CountryIso2Schema).max(1).optional(),
|
|
29325
|
+
campaignName: z117.string().trim().min(1).max(100).optional()
|
|
29282
29326
|
});
|
|
29283
29327
|
var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
|
|
29284
|
-
var MetaInput =
|
|
29285
|
-
taskId:
|
|
29328
|
+
var MetaInput = z117.object({
|
|
29329
|
+
taskId: z117.string().min(1),
|
|
29286
29330
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
29287
|
-
portfolioId:
|
|
29331
|
+
portfolioId: z117.string().trim().min(1),
|
|
29288
29332
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
29289
|
-
pageId:
|
|
29333
|
+
pageId: z117.string().trim().min(1),
|
|
29290
29334
|
adAccountId: McpAdAccountId,
|
|
29291
|
-
pixelId:
|
|
29292
|
-
landingUrl:
|
|
29335
|
+
pixelId: z117.string().min(1).optional(),
|
|
29336
|
+
landingUrl: z117.string().url().optional(),
|
|
29293
29337
|
/** Select which angles to publish by 0-based index. Omit to publish all
|
|
29294
29338
|
* successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
|
|
29295
|
-
angleIndexes:
|
|
29339
|
+
angleIndexes: z117.array(z117.number().int().nonnegative()).optional(),
|
|
29296
29340
|
campaignConfig: McpCampaignConfig.optional(),
|
|
29297
29341
|
/** Override the ad's primary text (body copy). If omitted, ProductMaker
|
|
29298
29342
|
* uses the auto-generated copy attached to the task. Capped at 500 chars
|
|
29299
29343
|
* (Meta's primary-text limit). */
|
|
29300
|
-
primaryText:
|
|
29344
|
+
primaryText: z117.string().trim().min(1).max(500).optional(),
|
|
29301
29345
|
/** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
|
|
29302
29346
|
* (wa.me) instead of a landing page. */
|
|
29303
|
-
phoneNumber:
|
|
29347
|
+
phoneNumber: z117.string().min(8).max(32).optional()
|
|
29304
29348
|
});
|
|
29305
|
-
var GroupedTaskSource =
|
|
29306
|
-
type:
|
|
29307
|
-
taskId:
|
|
29308
|
-
angleIndex:
|
|
29309
|
-
videoVariant:
|
|
29349
|
+
var GroupedTaskSource = z117.object({
|
|
29350
|
+
type: z117.literal("task"),
|
|
29351
|
+
taskId: z117.string().min(1),
|
|
29352
|
+
angleIndex: z117.number().int().min(0).optional(),
|
|
29353
|
+
videoVariant: z117.enum([
|
|
29310
29354
|
"with_subtitles",
|
|
29311
29355
|
"without_subtitles"
|
|
29312
29356
|
]).optional(),
|
|
29313
|
-
imageVariantIndex:
|
|
29314
|
-
});
|
|
29315
|
-
var GroupedMediaSource =
|
|
29316
|
-
type:
|
|
29317
|
-
url:
|
|
29318
|
-
path:
|
|
29319
|
-
thumbnailUrl:
|
|
29320
|
-
thumbnailPath:
|
|
29357
|
+
imageVariantIndex: z117.number().int().min(0).optional()
|
|
29358
|
+
});
|
|
29359
|
+
var GroupedMediaSource = z117.object({
|
|
29360
|
+
type: z117.literal("media"),
|
|
29361
|
+
url: z117.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
|
|
29362
|
+
path: z117.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".'),
|
|
29363
|
+
thumbnailUrl: z117.string().url().optional(),
|
|
29364
|
+
thumbnailPath: z117.string().min(1).optional()
|
|
29321
29365
|
}).refine((value) => Boolean(value.url) !== Boolean(value.path), {
|
|
29322
29366
|
message: "media source needs exactly one of `url` or `path`"
|
|
29323
29367
|
}).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
|
|
29324
29368
|
message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
|
|
29325
29369
|
});
|
|
29326
|
-
var GroupedUploadedAssetSource =
|
|
29327
|
-
type:
|
|
29370
|
+
var GroupedUploadedAssetSource = z117.object({
|
|
29371
|
+
type: z117.literal("asset"),
|
|
29328
29372
|
/** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
|
|
29329
|
-
assetId:
|
|
29330
|
-
thumbnailAssetId:
|
|
29373
|
+
assetId: z117.string().uuid(),
|
|
29374
|
+
thumbnailAssetId: z117.string().uuid().optional()
|
|
29331
29375
|
});
|
|
29332
|
-
var GroupedCreative =
|
|
29333
|
-
type:
|
|
29376
|
+
var GroupedCreative = z117.object({
|
|
29377
|
+
type: z117.enum([
|
|
29334
29378
|
"image",
|
|
29335
29379
|
"video"
|
|
29336
29380
|
]),
|
|
29337
|
-
source:
|
|
29381
|
+
source: z117.union([
|
|
29338
29382
|
GroupedTaskSource,
|
|
29339
29383
|
GroupedMediaSource,
|
|
29340
29384
|
GroupedUploadedAssetSource
|
|
29341
29385
|
]),
|
|
29342
|
-
title:
|
|
29343
|
-
description:
|
|
29386
|
+
title: z117.string().max(120).optional(),
|
|
29387
|
+
description: z117.string().max(500).optional(),
|
|
29344
29388
|
cta: MetaCtaType.optional(),
|
|
29345
|
-
creativeId:
|
|
29389
|
+
creativeId: z117.string().min(1).optional()
|
|
29346
29390
|
});
|
|
29347
|
-
var GroupedCampaignConfigBase =
|
|
29391
|
+
var GroupedCampaignConfigBase = z117.object({
|
|
29348
29392
|
campaignType: MetaCampaignType.default("sales"),
|
|
29349
29393
|
optimizationMode: MetaOptimizationMode.default("advantage_plus"),
|
|
29350
29394
|
budgetMode: MetaBudgetMode.optional(),
|
|
29351
|
-
campaignDailyBudget:
|
|
29352
|
-
adSets:
|
|
29353
|
-
tempId:
|
|
29354
|
-
name:
|
|
29355
|
-
dailyBudget:
|
|
29356
|
-
creativeIds:
|
|
29395
|
+
campaignDailyBudget: z117.number().int().positive().optional(),
|
|
29396
|
+
adSets: z117.array(z117.object({
|
|
29397
|
+
tempId: z117.string().min(1).max(80),
|
|
29398
|
+
name: z117.string().min(1).max(100),
|
|
29399
|
+
dailyBudget: z117.number().int().positive().optional(),
|
|
29400
|
+
creativeIds: z117.array(z117.string().min(1)).min(1)
|
|
29357
29401
|
})).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
|
|
29358
29402
|
/**
|
|
29359
29403
|
* Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
|
|
@@ -29361,17 +29405,17 @@ var GroupedCampaignConfigBase = z116.object({
|
|
|
29361
29405
|
* opaque `invalid_literal` and made the WhatsApp destination — supported by
|
|
29362
29406
|
* the API since #849 — unreachable from this tool.
|
|
29363
29407
|
*/
|
|
29364
|
-
destination:
|
|
29365
|
-
|
|
29366
|
-
type:
|
|
29367
|
-
landingUrl:
|
|
29408
|
+
destination: z117.discriminatedUnion("type", [
|
|
29409
|
+
z117.object({
|
|
29410
|
+
type: z117.literal("landing"),
|
|
29411
|
+
landingUrl: z117.string().url()
|
|
29368
29412
|
}),
|
|
29369
|
-
|
|
29370
|
-
type:
|
|
29371
|
-
phoneNumber:
|
|
29413
|
+
z117.object({
|
|
29414
|
+
type: z117.literal("whatsapp"),
|
|
29415
|
+
phoneNumber: z117.string().min(8).max(32)
|
|
29372
29416
|
})
|
|
29373
29417
|
]),
|
|
29374
|
-
saveAsDefault:
|
|
29418
|
+
saveAsDefault: z117.boolean().default(false),
|
|
29375
29419
|
budgetPolicy: MetaBudgetPolicy.optional()
|
|
29376
29420
|
});
|
|
29377
29421
|
function resolveBudgetMode(value) {
|
|
@@ -29385,7 +29429,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
29385
29429
|
const budgetMode = resolveBudgetMode(value);
|
|
29386
29430
|
if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
|
|
29387
29431
|
ctx.addIssue({
|
|
29388
|
-
code:
|
|
29432
|
+
code: z117.ZodIssueCode.custom,
|
|
29389
29433
|
path: [
|
|
29390
29434
|
"campaignDailyBudget"
|
|
29391
29435
|
],
|
|
@@ -29396,7 +29440,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
29396
29440
|
value.adSets.forEach((adSet, index) => {
|
|
29397
29441
|
if (adSet.dailyBudget === void 0) {
|
|
29398
29442
|
ctx.addIssue({
|
|
29399
|
-
code:
|
|
29443
|
+
code: z117.ZodIssueCode.custom,
|
|
29400
29444
|
path: [
|
|
29401
29445
|
"adSets",
|
|
29402
29446
|
index,
|
|
@@ -29411,28 +29455,28 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
|
|
|
29411
29455
|
...value,
|
|
29412
29456
|
budgetMode: resolveBudgetMode(value)
|
|
29413
29457
|
}));
|
|
29414
|
-
var PublishCreativesToMetaInputBase =
|
|
29415
|
-
creatives:
|
|
29458
|
+
var PublishCreativesToMetaInputBase = z117.object({
|
|
29459
|
+
creatives: z117.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
|
|
29416
29460
|
/** Exact Meta Business portfolio selected from `list_meta_destinations`. */
|
|
29417
|
-
portfolioId:
|
|
29461
|
+
portfolioId: z117.string().trim().min(1),
|
|
29418
29462
|
/** Exact Facebook Page selected from `list_meta_destinations`. */
|
|
29419
|
-
pageId:
|
|
29463
|
+
pageId: z117.string().trim().min(1),
|
|
29420
29464
|
adAccountId: McpAdAccountId,
|
|
29421
|
-
pixelId:
|
|
29465
|
+
pixelId: z117.string().min(1).optional(),
|
|
29422
29466
|
/** Required unless `campaignConfig.destination` is whatsapp — see the
|
|
29423
29467
|
* superRefine below. Mirrors the API's `FacebookCreateCampaignFromTasksBodySchema`. */
|
|
29424
|
-
landingUrl:
|
|
29468
|
+
landingUrl: z117.string().url().optional(),
|
|
29425
29469
|
/** ISO-2 code or resolvable country name — mirrors the API contract
|
|
29426
29470
|
* (CountryIso2Schema), which normalizes names to alpha-2 at validation. */
|
|
29427
29471
|
targetCountry: CountryIso2Schema,
|
|
29428
|
-
campaignName:
|
|
29472
|
+
campaignName: z117.string().trim().min(1).max(100),
|
|
29429
29473
|
campaignConfig: GroupedCampaignConfig.optional()
|
|
29430
29474
|
});
|
|
29431
29475
|
var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
|
|
29432
29476
|
const destination = value.campaignConfig?.destination;
|
|
29433
29477
|
if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl) {
|
|
29434
29478
|
ctx.addIssue({
|
|
29435
|
-
code:
|
|
29479
|
+
code: z117.ZodIssueCode.custom,
|
|
29436
29480
|
path: [
|
|
29437
29481
|
"landingUrl"
|
|
29438
29482
|
],
|
|
@@ -29441,7 +29485,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
29441
29485
|
}
|
|
29442
29486
|
if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
|
|
29443
29487
|
ctx.addIssue({
|
|
29444
|
-
code:
|
|
29488
|
+
code: z117.ZodIssueCode.custom,
|
|
29445
29489
|
path: [
|
|
29446
29490
|
"campaignConfig",
|
|
29447
29491
|
"destination",
|
|
@@ -29460,16 +29504,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
|
|
|
29460
29504
|
}
|
|
29461
29505
|
return value;
|
|
29462
29506
|
});
|
|
29463
|
-
var PresignUploadResponseSchema =
|
|
29464
|
-
uploadUrl:
|
|
29507
|
+
var PresignUploadResponseSchema = z117.object({
|
|
29508
|
+
uploadUrl: z117.string().url().refine((value) => {
|
|
29465
29509
|
const url = new URL(value);
|
|
29466
29510
|
return !url.username && !url.password && url.protocol === "https:";
|
|
29467
29511
|
}, "presigned upload URL must be HTTPS without embedded credentials"),
|
|
29468
|
-
publicUrl:
|
|
29512
|
+
publicUrl: z117.string().url().refine((value) => {
|
|
29469
29513
|
const url = new URL(value);
|
|
29470
29514
|
return !url.username && !url.password;
|
|
29471
29515
|
}, "public media URL must not contain embedded credentials"),
|
|
29472
|
-
stagingAssetId:
|
|
29516
|
+
stagingAssetId: z117.string().uuid()
|
|
29473
29517
|
});
|
|
29474
29518
|
async function uploadResolvedMedia(api, media, assetRole) {
|
|
29475
29519
|
if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
|
|
@@ -29494,16 +29538,16 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
|
|
|
29494
29538
|
return uploadResolvedMedia(api, media, assetRole);
|
|
29495
29539
|
}
|
|
29496
29540
|
__name(resolveAndUploadMedia, "resolveAndUploadMedia");
|
|
29497
|
-
var TikTokInput =
|
|
29498
|
-
taskId:
|
|
29499
|
-
advertiserId:
|
|
29500
|
-
pixelId:
|
|
29501
|
-
landingUrl:
|
|
29502
|
-
angleIndexes:
|
|
29541
|
+
var TikTokInput = z117.object({
|
|
29542
|
+
taskId: z117.string().min(1),
|
|
29543
|
+
advertiserId: z117.string().min(1),
|
|
29544
|
+
pixelId: z117.string().min(1).optional(),
|
|
29545
|
+
landingUrl: z117.string().url().optional(),
|
|
29546
|
+
angleIndexes: z117.array(z117.number().int().nonnegative()).optional(),
|
|
29503
29547
|
campaignConfig: McpCampaignConfig.optional(),
|
|
29504
29548
|
/** Override the ad's description (TikTok's body copy). If omitted,
|
|
29505
29549
|
* ProductMaker uses the auto-generated copy attached to the task. */
|
|
29506
|
-
primaryText:
|
|
29550
|
+
primaryText: z117.string().trim().min(1).max(500).optional()
|
|
29507
29551
|
});
|
|
29508
29552
|
function registerPublishTools(server, api, opts = {}) {
|
|
29509
29553
|
const transport = opts.transport ?? "http";
|
|
@@ -29855,39 +29899,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
|
|
|
29855
29899
|
|
|
29856
29900
|
// src/tools/meta-upload.ts
|
|
29857
29901
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
29858
|
-
import { z as
|
|
29902
|
+
import { z as z118 } from "zod";
|
|
29859
29903
|
var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
|
|
29860
|
-
var UploadSessionInputBase =
|
|
29861
|
-
mediaKind:
|
|
29904
|
+
var UploadSessionInputBase = z118.object({
|
|
29905
|
+
mediaKind: z118.enum([
|
|
29862
29906
|
"image",
|
|
29863
29907
|
"video",
|
|
29864
29908
|
"mixed"
|
|
29865
29909
|
]).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."),
|
|
29866
|
-
assetRole:
|
|
29910
|
+
assetRole: z118.enum([
|
|
29867
29911
|
"media",
|
|
29868
29912
|
"thumbnail"
|
|
29869
29913
|
]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
|
|
29870
|
-
uploadPurpose:
|
|
29914
|
+
uploadPurpose: z118.enum([
|
|
29871
29915
|
"product_reference",
|
|
29872
29916
|
"creative",
|
|
29873
29917
|
"generic"
|
|
29874
29918
|
]).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."),
|
|
29875
|
-
maxFiles:
|
|
29919
|
+
maxFiles: z118.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
|
|
29876
29920
|
});
|
|
29877
|
-
var OpenAiFileReference =
|
|
29878
|
-
download_url:
|
|
29879
|
-
file_id:
|
|
29880
|
-
mime_type:
|
|
29881
|
-
file_name:
|
|
29921
|
+
var OpenAiFileReference = z118.object({
|
|
29922
|
+
download_url: z118.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."),
|
|
29923
|
+
file_id: z118.string().min(1),
|
|
29924
|
+
mime_type: z118.string().min(1).optional(),
|
|
29925
|
+
file_name: z118.string().min(1).optional()
|
|
29882
29926
|
});
|
|
29883
29927
|
var UploadSessionToolInputShape = {
|
|
29884
29928
|
...UploadSessionInputBase.shape,
|
|
29885
|
-
files:
|
|
29929
|
+
files: z118.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.")
|
|
29886
29930
|
};
|
|
29887
|
-
var UploadSessionToolInput =
|
|
29931
|
+
var UploadSessionToolInput = z118.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
|
|
29888
29932
|
if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
|
|
29889
29933
|
ctx.addIssue({
|
|
29890
|
-
code:
|
|
29934
|
+
code: z118.ZodIssueCode.custom,
|
|
29891
29935
|
path: [
|
|
29892
29936
|
"mediaKind"
|
|
29893
29937
|
],
|
|
@@ -29896,7 +29940,7 @@ var UploadSessionToolInput = z117.object(UploadSessionToolInputShape).superRefin
|
|
|
29896
29940
|
}
|
|
29897
29941
|
if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
|
|
29898
29942
|
ctx.addIssue({
|
|
29899
|
-
code:
|
|
29943
|
+
code: z118.ZodIssueCode.custom,
|
|
29900
29944
|
path: [
|
|
29901
29945
|
"maxFiles"
|
|
29902
29946
|
],
|
|
@@ -29905,7 +29949,7 @@ var UploadSessionToolInput = z117.object(UploadSessionToolInputShape).superRefin
|
|
|
29905
29949
|
}
|
|
29906
29950
|
if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
|
|
29907
29951
|
ctx.addIssue({
|
|
29908
|
-
code:
|
|
29952
|
+
code: z118.ZodIssueCode.custom,
|
|
29909
29953
|
path: [
|
|
29910
29954
|
"maxFiles"
|
|
29911
29955
|
],
|
|
@@ -29913,38 +29957,38 @@ var UploadSessionToolInput = z117.object(UploadSessionToolInputShape).superRefin
|
|
|
29913
29957
|
});
|
|
29914
29958
|
}
|
|
29915
29959
|
});
|
|
29916
|
-
var UploadSessionResponse =
|
|
29917
|
-
sessionId:
|
|
29918
|
-
uploadPageUrl:
|
|
29919
|
-
mediaKind:
|
|
29960
|
+
var UploadSessionResponse = z118.object({
|
|
29961
|
+
sessionId: z118.string().uuid(),
|
|
29962
|
+
uploadPageUrl: z118.string().url(),
|
|
29963
|
+
mediaKind: z118.enum([
|
|
29920
29964
|
"image",
|
|
29921
29965
|
"video",
|
|
29922
29966
|
"mixed"
|
|
29923
29967
|
]),
|
|
29924
|
-
assetRole:
|
|
29968
|
+
assetRole: z118.enum([
|
|
29925
29969
|
"media",
|
|
29926
29970
|
"thumbnail"
|
|
29927
29971
|
]),
|
|
29928
|
-
maxFiles:
|
|
29929
|
-
expiresAt:
|
|
29972
|
+
maxFiles: z118.number().int().positive(),
|
|
29973
|
+
expiresAt: z118.string().datetime()
|
|
29930
29974
|
});
|
|
29931
|
-
var UploadStatusInput =
|
|
29932
|
-
sessionId:
|
|
29975
|
+
var UploadStatusInput = z118.object({
|
|
29976
|
+
sessionId: z118.string().uuid().describe("The sessionId returned by request_media_upload.")
|
|
29933
29977
|
});
|
|
29934
|
-
var UniversalUploadStatusResponse =
|
|
29935
|
-
|
|
29936
|
-
status:
|
|
29937
|
-
assets:
|
|
29978
|
+
var UniversalUploadStatusResponse = z118.discriminatedUnion("status", [
|
|
29979
|
+
z118.object({
|
|
29980
|
+
status: z118.literal("pending"),
|
|
29981
|
+
assets: z118.array(z118.never()).length(0)
|
|
29938
29982
|
}),
|
|
29939
|
-
|
|
29940
|
-
status:
|
|
29941
|
-
assets:
|
|
29942
|
-
assetId:
|
|
29943
|
-
mediaKind:
|
|
29983
|
+
z118.object({
|
|
29984
|
+
status: z118.literal("uploaded"),
|
|
29985
|
+
assets: z118.array(z118.object({
|
|
29986
|
+
assetId: z118.string().uuid(),
|
|
29987
|
+
mediaKind: z118.enum([
|
|
29944
29988
|
"image",
|
|
29945
29989
|
"video"
|
|
29946
29990
|
]),
|
|
29947
|
-
assetRole:
|
|
29991
|
+
assetRole: z118.enum([
|
|
29948
29992
|
"media",
|
|
29949
29993
|
"thumbnail"
|
|
29950
29994
|
])
|
|
@@ -29952,13 +29996,13 @@ var UniversalUploadStatusResponse = z117.discriminatedUnion("status", [
|
|
|
29952
29996
|
})
|
|
29953
29997
|
]);
|
|
29954
29998
|
var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
|
|
29955
|
-
uploadPurpose:
|
|
29999
|
+
uploadPurpose: z118.enum([
|
|
29956
30000
|
"product_reference",
|
|
29957
30001
|
"creative",
|
|
29958
30002
|
"generic"
|
|
29959
30003
|
]),
|
|
29960
|
-
checkToolName:
|
|
29961
|
-
resolveEndpoint:
|
|
30004
|
+
checkToolName: z118.literal("check_media_upload"),
|
|
30005
|
+
resolveEndpoint: z118.string().url()
|
|
29962
30006
|
});
|
|
29963
30007
|
function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
|
|
29964
30008
|
const url = new URL(uploadPageUrl);
|
|
@@ -30049,15 +30093,15 @@ function registerMediaUploadTools(server, api) {
|
|
|
30049
30093
|
__name(registerMediaUploadTools, "registerMediaUploadTools");
|
|
30050
30094
|
|
|
30051
30095
|
// src/tools/campaigns.ts
|
|
30052
|
-
import { z as
|
|
30096
|
+
import { z as z119 } from "zod";
|
|
30053
30097
|
var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
|
|
30054
30098
|
var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
|
|
30055
|
-
var MetaStatusInput =
|
|
30056
|
-
campaignId:
|
|
30099
|
+
var MetaStatusInput = z119.object({
|
|
30100
|
+
campaignId: z119.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
|
|
30057
30101
|
});
|
|
30058
|
-
var TikTokStatusInput =
|
|
30059
|
-
campaignId:
|
|
30060
|
-
advertiserId:
|
|
30102
|
+
var TikTokStatusInput = z119.object({
|
|
30103
|
+
campaignId: z119.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
|
|
30104
|
+
advertiserId: z119.string().min(1).describe("The same advertiserId used to publish the campaign.")
|
|
30061
30105
|
});
|
|
30062
30106
|
function registerCampaignTools(server, api) {
|
|
30063
30107
|
server.registerTool("get_meta_campaign_status", {
|
|
@@ -30162,10 +30206,10 @@ function renderTikTokStatusMarkdown(r) {
|
|
|
30162
30206
|
__name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
|
|
30163
30207
|
|
|
30164
30208
|
// ../../packages/product-economics/src/product-costing.ts
|
|
30165
|
-
import { z as
|
|
30209
|
+
import { z as z121 } from "zod";
|
|
30166
30210
|
|
|
30167
30211
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
30168
|
-
import { z as
|
|
30212
|
+
import { z as z120 } from "zod";
|
|
30169
30213
|
|
|
30170
30214
|
// ../../packages/product-economics/src/product-costing-shipping-references.json
|
|
30171
30215
|
var product_costing_shipping_references_default = {
|
|
@@ -30229,21 +30273,21 @@ var product_costing_shipping_references_default = {
|
|
|
30229
30273
|
};
|
|
30230
30274
|
|
|
30231
30275
|
// ../../packages/product-economics/src/product-costing-countries.ts
|
|
30232
|
-
var ShippingReferenceSchema =
|
|
30233
|
-
reference:
|
|
30234
|
-
min:
|
|
30235
|
-
max:
|
|
30236
|
-
updatedAt:
|
|
30237
|
-
confidence:
|
|
30276
|
+
var ShippingReferenceSchema = z120.object({
|
|
30277
|
+
reference: z120.number().positive(),
|
|
30278
|
+
min: z120.number().nonnegative(),
|
|
30279
|
+
max: z120.number().positive(),
|
|
30280
|
+
updatedAt: z120.string().date(),
|
|
30281
|
+
confidence: z120.enum([
|
|
30238
30282
|
"high",
|
|
30239
30283
|
"medium",
|
|
30240
30284
|
"medium-low"
|
|
30241
30285
|
]),
|
|
30242
|
-
sources:
|
|
30286
|
+
sources: z120.array(z120.string().url().startsWith("https://")).min(1).max(3)
|
|
30243
30287
|
}).superRefine(({ reference, min, max }, context) => {
|
|
30244
30288
|
if (min > reference || reference > max) {
|
|
30245
30289
|
context.addIssue({
|
|
30246
|
-
code:
|
|
30290
|
+
code: z120.ZodIssueCode.custom,
|
|
30247
30291
|
message: "shipping_reference_outside_range",
|
|
30248
30292
|
path: [
|
|
30249
30293
|
"reference"
|
|
@@ -30251,7 +30295,7 @@ var ShippingReferenceSchema = z119.object({
|
|
|
30251
30295
|
});
|
|
30252
30296
|
}
|
|
30253
30297
|
});
|
|
30254
|
-
var SHIPPING_REFERENCES =
|
|
30298
|
+
var SHIPPING_REFERENCES = z120.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
|
|
30255
30299
|
var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
|
|
30256
30300
|
var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
|
|
30257
30301
|
"MX",
|
|
@@ -30433,18 +30477,18 @@ function getProductCostingCountryName(country) {
|
|
|
30433
30477
|
__name(getProductCostingCountryName, "getProductCostingCountryName");
|
|
30434
30478
|
|
|
30435
30479
|
// ../../packages/product-economics/src/product-costing.ts
|
|
30436
|
-
var ProductCostingInputSchema =
|
|
30437
|
-
country:
|
|
30438
|
-
supplierCost:
|
|
30439
|
-
shippingCost:
|
|
30440
|
-
returnRate:
|
|
30441
|
-
cancellationRate:
|
|
30442
|
-
adsManagerCpa:
|
|
30443
|
-
desiredMargin:
|
|
30480
|
+
var ProductCostingInputSchema = z121.object({
|
|
30481
|
+
country: z121.string().refine(isProductCostingCountryCode, "unsupported_country"),
|
|
30482
|
+
supplierCost: z121.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
|
|
30483
|
+
shippingCost: z121.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
|
|
30484
|
+
returnRate: z121.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
30485
|
+
cancellationRate: z121.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
|
|
30486
|
+
adsManagerCpa: z121.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
|
|
30487
|
+
desiredMargin: z121.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
|
|
30444
30488
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
30445
30489
|
if (returnRate + cancellationRate >= 1) {
|
|
30446
30490
|
context.addIssue({
|
|
30447
|
-
code:
|
|
30491
|
+
code: z121.ZodIssueCode.custom,
|
|
30448
30492
|
message: "delivery_rate_positive",
|
|
30449
30493
|
path: [
|
|
30450
30494
|
"cancellationRate"
|
|
@@ -30541,15 +30585,15 @@ function calculateProductCosting(rawInput) {
|
|
|
30541
30585
|
__name(calculateProductCosting, "calculateProductCosting");
|
|
30542
30586
|
|
|
30543
30587
|
// src/tools/product-costing.ts
|
|
30544
|
-
import { z as
|
|
30588
|
+
import { z as z122 } from "zod";
|
|
30545
30589
|
var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
|
|
30546
|
-
var optionalAmount = /* @__PURE__ */ __name((description) =>
|
|
30547
|
-
var optionalPercent = /* @__PURE__ */ __name((description) =>
|
|
30548
|
-
var ProductCostingToolInput =
|
|
30549
|
-
country:
|
|
30590
|
+
var optionalAmount = /* @__PURE__ */ __name((description) => z122.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
|
|
30591
|
+
var optionalPercent = /* @__PURE__ */ __name((description) => z122.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
|
|
30592
|
+
var ProductCostingToolInput = z122.object({
|
|
30593
|
+
country: z122.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
30550
30594
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
30551
30595
|
}).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
|
|
30552
|
-
supplierCost:
|
|
30596
|
+
supplierCost: z122.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."),
|
|
30553
30597
|
supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
|
|
30554
30598
|
shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
|
|
30555
30599
|
shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
|
|
@@ -30712,7 +30756,7 @@ function formatPercent(value) {
|
|
|
30712
30756
|
__name(formatPercent, "formatPercent");
|
|
30713
30757
|
|
|
30714
30758
|
// src/tools/product-research.ts
|
|
30715
|
-
import { z as
|
|
30759
|
+
import { z as z123 } from "zod";
|
|
30716
30760
|
|
|
30717
30761
|
// src/tools/product-research-idempotency.ts
|
|
30718
30762
|
var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
|
|
@@ -31083,17 +31127,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
|
|
|
31083
31127
|
]);
|
|
31084
31128
|
var POLL_INTERVAL_MS = 5e3;
|
|
31085
31129
|
var MAX_WAIT_SECONDS = 120;
|
|
31086
|
-
var FindInput =
|
|
31130
|
+
var FindInput = z123.object({
|
|
31087
31131
|
targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
|
|
31088
31132
|
categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
|
|
31089
|
-
confirmed:
|
|
31090
|
-
waitSeconds:
|
|
31133
|
+
confirmed: z123.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
|
|
31134
|
+
waitSeconds: z123.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
|
|
31091
31135
|
});
|
|
31092
|
-
var GetInput =
|
|
31093
|
-
runId:
|
|
31136
|
+
var GetInput = z123.object({
|
|
31137
|
+
runId: z123.string().uuid().describe("ID del run devuelto por find_winning_products.")
|
|
31094
31138
|
});
|
|
31095
|
-
var ListInput =
|
|
31096
|
-
limit:
|
|
31139
|
+
var ListInput = z123.object({
|
|
31140
|
+
limit: z123.number().int().min(1).max(20).default(10)
|
|
31097
31141
|
});
|
|
31098
31142
|
function textResult(text2) {
|
|
31099
31143
|
return {
|
|
@@ -31232,17 +31276,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
|
|
|
31232
31276
|
__name(registerProductResearchTools, "registerProductResearchTools");
|
|
31233
31277
|
|
|
31234
31278
|
// src/tools/dropshipping-projects.ts
|
|
31235
|
-
import { z as
|
|
31279
|
+
import { z as z124 } from "zod";
|
|
31236
31280
|
var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
|
|
31237
31281
|
var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
|
|
31238
31282
|
var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
|
|
31239
|
-
var ProjectId =
|
|
31240
|
-
var DropshippingProjectStatus =
|
|
31283
|
+
var ProjectId = z124.string().uuid();
|
|
31284
|
+
var DropshippingProjectStatus = z124.enum([
|
|
31241
31285
|
"active",
|
|
31242
31286
|
"completed",
|
|
31243
31287
|
"archived"
|
|
31244
31288
|
]);
|
|
31245
|
-
var DropshippingProjectPhase =
|
|
31289
|
+
var DropshippingProjectPhase = z124.enum([
|
|
31246
31290
|
"research",
|
|
31247
31291
|
"costing",
|
|
31248
31292
|
"media",
|
|
@@ -31251,21 +31295,21 @@ var DropshippingProjectPhase = z123.enum([
|
|
|
31251
31295
|
"advertising",
|
|
31252
31296
|
"complete"
|
|
31253
31297
|
]);
|
|
31254
|
-
var DropshippingRewardMilestone =
|
|
31298
|
+
var DropshippingRewardMilestone = z124.enum([
|
|
31255
31299
|
"product_selected",
|
|
31256
31300
|
"costing_saved",
|
|
31257
31301
|
"product_media_ready",
|
|
31258
31302
|
"creatives_completed",
|
|
31259
31303
|
"campaign_created"
|
|
31260
31304
|
]);
|
|
31261
|
-
var TargetCountry =
|
|
31305
|
+
var TargetCountry = z124.enum([
|
|
31262
31306
|
"CO",
|
|
31263
31307
|
"MX",
|
|
31264
31308
|
"PE",
|
|
31265
31309
|
"EC",
|
|
31266
31310
|
"CL"
|
|
31267
31311
|
]);
|
|
31268
|
-
var ResearchCategory =
|
|
31312
|
+
var ResearchCategory = z124.enum([
|
|
31269
31313
|
"auto",
|
|
31270
31314
|
"automotive",
|
|
31271
31315
|
"kitchen",
|
|
@@ -31280,7 +31324,7 @@ var ResearchCategory = z123.enum([
|
|
|
31280
31324
|
"garden",
|
|
31281
31325
|
"cleaning"
|
|
31282
31326
|
]);
|
|
31283
|
-
var HttpUrl3 =
|
|
31327
|
+
var HttpUrl3 = z124.string().url().max(2e3).refine((value) => {
|
|
31284
31328
|
try {
|
|
31285
31329
|
return [
|
|
31286
31330
|
"http:",
|
|
@@ -31290,45 +31334,45 @@ var HttpUrl3 = z123.string().url().max(2e3).refine((value) => {
|
|
|
31290
31334
|
return false;
|
|
31291
31335
|
}
|
|
31292
31336
|
}, "URL must use HTTP(S)");
|
|
31293
|
-
var ResearchCandidateOrigin =
|
|
31294
|
-
type:
|
|
31337
|
+
var ResearchCandidateOrigin = z124.object({
|
|
31338
|
+
type: z124.literal("research_candidate"),
|
|
31295
31339
|
runId: ProjectId,
|
|
31296
|
-
candidateSourceId:
|
|
31340
|
+
candidateSourceId: z124.string().min(1).max(160)
|
|
31297
31341
|
});
|
|
31298
|
-
var TaskOrigin =
|
|
31299
|
-
type:
|
|
31342
|
+
var TaskOrigin = z124.object({
|
|
31343
|
+
type: z124.literal("task"),
|
|
31300
31344
|
taskId: ProjectId
|
|
31301
31345
|
});
|
|
31302
|
-
var ManualOrigin =
|
|
31303
|
-
type:
|
|
31346
|
+
var ManualOrigin = z124.object({
|
|
31347
|
+
type: z124.literal("manual"),
|
|
31304
31348
|
clientRequestId: ProjectId,
|
|
31305
|
-
country:
|
|
31349
|
+
country: z124.string().min(2).max(3).optional()
|
|
31306
31350
|
});
|
|
31307
|
-
var StartProjectInput =
|
|
31308
|
-
origin:
|
|
31351
|
+
var StartProjectInput = z124.object({
|
|
31352
|
+
origin: z124.discriminatedUnion("type", [
|
|
31309
31353
|
ResearchCandidateOrigin,
|
|
31310
31354
|
TaskOrigin,
|
|
31311
31355
|
ManualOrigin
|
|
31312
31356
|
]),
|
|
31313
|
-
productName:
|
|
31357
|
+
productName: z124.string().trim().min(1).max(240).optional(),
|
|
31314
31358
|
productUrl: HttpUrl3.optional(),
|
|
31315
|
-
country:
|
|
31316
|
-
languageCode:
|
|
31359
|
+
country: z124.string().min(2).max(3).optional(),
|
|
31360
|
+
languageCode: z124.string().min(2).max(16).optional()
|
|
31317
31361
|
}).strict();
|
|
31318
|
-
var CostProjectInput =
|
|
31362
|
+
var CostProjectInput = z124.object({
|
|
31319
31363
|
projectId: ProjectId,
|
|
31320
|
-
version:
|
|
31321
|
-
country:
|
|
31364
|
+
version: z124.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
|
|
31365
|
+
country: z124.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
|
|
31322
31366
|
message: "Pa\xEDs no soportado por ProductMaker."
|
|
31323
31367
|
}).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
|
|
31324
|
-
supplierCost:
|
|
31325
|
-
shippingCost:
|
|
31326
|
-
returnRate:
|
|
31327
|
-
cancellationRate:
|
|
31328
|
-
adsManagerCpa:
|
|
31329
|
-
desiredMargin:
|
|
31330
|
-
});
|
|
31331
|
-
var GuideInput =
|
|
31368
|
+
supplierCost: z124.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."),
|
|
31369
|
+
shippingCost: z124.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
|
|
31370
|
+
returnRate: z124.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."),
|
|
31371
|
+
cancellationRate: z124.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."),
|
|
31372
|
+
adsManagerCpa: z124.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
|
|
31373
|
+
desiredMargin: z124.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
|
|
31374
|
+
});
|
|
31375
|
+
var GuideInput = z124.object({
|
|
31332
31376
|
projectId: ProjectId.optional()
|
|
31333
31377
|
}).strict();
|
|
31334
31378
|
var NEXT_ACTION_KINDS = [
|
|
@@ -31346,29 +31390,29 @@ var NEXT_ACTION_KINDS = [
|
|
|
31346
31390
|
"repair_meta_campaign",
|
|
31347
31391
|
"review_paused_campaign"
|
|
31348
31392
|
];
|
|
31349
|
-
var DropshippingProjectNextAction =
|
|
31350
|
-
kind:
|
|
31351
|
-
href:
|
|
31393
|
+
var DropshippingProjectNextAction = z124.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z124.object({
|
|
31394
|
+
kind: z124.literal(kind),
|
|
31395
|
+
href: z124.string().min(1)
|
|
31352
31396
|
})));
|
|
31353
|
-
var CostingInputSchema =
|
|
31354
|
-
country:
|
|
31355
|
-
supplierCost:
|
|
31356
|
-
shippingCost:
|
|
31357
|
-
returnRate:
|
|
31358
|
-
cancellationRate:
|
|
31359
|
-
adsManagerCpa:
|
|
31360
|
-
desiredMargin:
|
|
31397
|
+
var CostingInputSchema = z124.object({
|
|
31398
|
+
country: z124.string().min(2).max(3),
|
|
31399
|
+
supplierCost: z124.number().finite().positive(),
|
|
31400
|
+
shippingCost: z124.number().finite().nonnegative(),
|
|
31401
|
+
returnRate: z124.number().finite().min(0).lt(1),
|
|
31402
|
+
cancellationRate: z124.number().finite().min(0).lt(1),
|
|
31403
|
+
adsManagerCpa: z124.number().finite().nonnegative(),
|
|
31404
|
+
desiredMargin: z124.number().finite().min(0).lt(1)
|
|
31361
31405
|
}).superRefine(({ returnRate, cancellationRate }, context) => {
|
|
31362
31406
|
if (returnRate + cancellationRate >= 1) context.addIssue({
|
|
31363
|
-
code:
|
|
31407
|
+
code: z124.ZodIssueCode.custom,
|
|
31364
31408
|
path: [
|
|
31365
31409
|
"cancellationRate"
|
|
31366
31410
|
]
|
|
31367
31411
|
});
|
|
31368
31412
|
});
|
|
31369
|
-
var FiniteCostingNumber =
|
|
31370
|
-
var CostingResultSchema =
|
|
31371
|
-
country:
|
|
31413
|
+
var FiniteCostingNumber = z124.number().finite();
|
|
31414
|
+
var CostingResultSchema = z124.object({
|
|
31415
|
+
country: z124.string().min(2).max(3),
|
|
31372
31416
|
deliveryRate: FiniteCostingNumber,
|
|
31373
31417
|
adjustedShippingCost: FiniteCostingNumber,
|
|
31374
31418
|
adjustedCpa: FiniteCostingNumber,
|
|
@@ -31381,45 +31425,45 @@ var CostingResultSchema = z123.object({
|
|
|
31381
31425
|
estimatedProfit: FiniteCostingNumber,
|
|
31382
31426
|
actualMargin: FiniteCostingNumber,
|
|
31383
31427
|
breakEvenAdsManagerCpa: FiniteCostingNumber,
|
|
31384
|
-
wasPriceAutoAdjusted:
|
|
31385
|
-
profitabilityStatus:
|
|
31386
|
-
});
|
|
31387
|
-
var RewardProgressSchema =
|
|
31388
|
-
campaignKey:
|
|
31389
|
-
totalCredits:
|
|
31390
|
-
earnedCredits:
|
|
31391
|
-
milestones:
|
|
31428
|
+
wasPriceAutoAdjusted: z124.boolean(),
|
|
31429
|
+
profitabilityStatus: z124.literal("healthy")
|
|
31430
|
+
});
|
|
31431
|
+
var RewardProgressSchema = z124.object({
|
|
31432
|
+
campaignKey: z124.literal("dropshipping-launch-v1"),
|
|
31433
|
+
totalCredits: z124.number().int().positive(),
|
|
31434
|
+
earnedCredits: z124.number().int().nonnegative(),
|
|
31435
|
+
milestones: z124.array(z124.object({
|
|
31392
31436
|
milestone: DropshippingRewardMilestone,
|
|
31393
|
-
credits:
|
|
31394
|
-
available:
|
|
31395
|
-
earned:
|
|
31437
|
+
credits: z124.number().int().positive(),
|
|
31438
|
+
available: z124.boolean().optional(),
|
|
31439
|
+
earned: z124.boolean(),
|
|
31396
31440
|
grantId: ProjectId.nullable(),
|
|
31397
|
-
grantedAt:
|
|
31441
|
+
grantedAt: z124.string().datetime().nullable()
|
|
31398
31442
|
})).length(DropshippingRewardMilestone.options.length)
|
|
31399
31443
|
});
|
|
31400
|
-
var ProjectResponseSchema =
|
|
31444
|
+
var ProjectResponseSchema = z124.object({
|
|
31401
31445
|
id: ProjectId,
|
|
31402
31446
|
taskId: ProjectId.nullable(),
|
|
31403
31447
|
status: DropshippingProjectStatus,
|
|
31404
|
-
originKey:
|
|
31448
|
+
originKey: z124.string().min(1),
|
|
31405
31449
|
researchRunId: ProjectId.nullable(),
|
|
31406
|
-
candidateSourceId:
|
|
31407
|
-
productName:
|
|
31450
|
+
candidateSourceId: z124.string().nullable(),
|
|
31451
|
+
productName: z124.string().nullable(),
|
|
31408
31452
|
productUrl: HttpUrl3.nullable(),
|
|
31409
31453
|
referenceImageUrl: HttpUrl3.nullable(),
|
|
31410
|
-
targetCountry:
|
|
31411
|
-
languageCode:
|
|
31412
|
-
hasReferenceImage:
|
|
31413
|
-
hasWinnerReferenceImage:
|
|
31454
|
+
targetCountry: z124.string().nullable(),
|
|
31455
|
+
languageCode: z124.string().nullable(),
|
|
31456
|
+
hasReferenceImage: z124.boolean(),
|
|
31457
|
+
hasWinnerReferenceImage: z124.boolean(),
|
|
31414
31458
|
costingInput: CostingInputSchema.nullable(),
|
|
31415
31459
|
costingResult: CostingResultSchema.nullable(),
|
|
31416
|
-
costingVersion:
|
|
31417
|
-
version:
|
|
31460
|
+
costingVersion: z124.number().int().positive().nullable(),
|
|
31461
|
+
version: z124.number().int().positive(),
|
|
31418
31462
|
phase: DropshippingProjectPhase,
|
|
31419
31463
|
nextAction: DropshippingProjectNextAction.nullable(),
|
|
31420
31464
|
rewards: RewardProgressSchema,
|
|
31421
|
-
createdAt:
|
|
31422
|
-
updatedAt:
|
|
31465
|
+
createdAt: z124.string().datetime(),
|
|
31466
|
+
updatedAt: z124.string().datetime()
|
|
31423
31467
|
}).passthrough();
|
|
31424
31468
|
var NEXT_ACTION_GUIDANCE = {
|
|
31425
31469
|
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.",
|
|
@@ -31539,58 +31583,58 @@ function registerDropshippingProjectTools(server, api) {
|
|
|
31539
31583
|
__name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
|
|
31540
31584
|
|
|
31541
31585
|
// src/tools/daily-control.ts
|
|
31542
|
-
import { z as
|
|
31586
|
+
import { z as z125 } from "zod";
|
|
31543
31587
|
var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
|
|
31544
31588
|
var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
|
|
31545
31589
|
var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
|
|
31546
|
-
var ProviderCampaignIdentifier =
|
|
31547
|
-
var DateOnly =
|
|
31548
|
-
var DailyControlInput =
|
|
31590
|
+
var ProviderCampaignIdentifier = z125.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
|
|
31591
|
+
var DateOnly = z125.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
31592
|
+
var DailyControlInput = z125.object({
|
|
31549
31593
|
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."),
|
|
31550
|
-
days:
|
|
31551
|
-
projectId:
|
|
31594
|
+
days: z125.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
31595
|
+
projectId: z125.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
|
|
31552
31596
|
}).strict();
|
|
31553
|
-
var LinkCampaignInput =
|
|
31554
|
-
projectId:
|
|
31555
|
-
provider:
|
|
31597
|
+
var LinkCampaignInput = z125.object({
|
|
31598
|
+
projectId: z125.string().uuid(),
|
|
31599
|
+
provider: z125.enum([
|
|
31556
31600
|
"meta",
|
|
31557
31601
|
"tiktok"
|
|
31558
31602
|
]),
|
|
31559
31603
|
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."),
|
|
31560
31604
|
campaignId: ProviderCampaignIdentifier
|
|
31561
31605
|
}).strict();
|
|
31562
|
-
var ReportReturnsInput =
|
|
31563
|
-
projectId:
|
|
31606
|
+
var ReportReturnsInput = z125.object({
|
|
31607
|
+
projectId: z125.string().uuid(),
|
|
31564
31608
|
date: DateOnly,
|
|
31565
|
-
returnedOrders:
|
|
31566
|
-
note:
|
|
31609
|
+
returnedOrders: z125.number().int().min(0).max(1e5),
|
|
31610
|
+
note: z125.string().trim().max(280).optional()
|
|
31567
31611
|
}).strict();
|
|
31568
|
-
var DailyControlStatusMirror = DailyControlStatusEnum.or(
|
|
31569
|
-
var DailyControlLightMirror = DailyControlLightEnum.or(
|
|
31570
|
-
var DailyControlSourceMirror = DailyControlSourceEnum.or(
|
|
31571
|
-
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(
|
|
31572
|
-
var DailyControlDayMirror =
|
|
31573
|
-
date:
|
|
31574
|
-
returnedOrders:
|
|
31612
|
+
var DailyControlStatusMirror = DailyControlStatusEnum.or(z125.string());
|
|
31613
|
+
var DailyControlLightMirror = DailyControlLightEnum.or(z125.string());
|
|
31614
|
+
var DailyControlSourceMirror = DailyControlSourceEnum.or(z125.string());
|
|
31615
|
+
var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z125.string());
|
|
31616
|
+
var DailyControlDayMirror = z125.object({
|
|
31617
|
+
date: z125.string(),
|
|
31618
|
+
returnedOrders: z125.number(),
|
|
31575
31619
|
returnedSource: DailyControlSourceMirror,
|
|
31576
31620
|
cancelledSource: DailyControlSourceMirror,
|
|
31577
|
-
hasEstimates:
|
|
31621
|
+
hasEstimates: z125.boolean(),
|
|
31578
31622
|
light: DailyControlLightMirror
|
|
31579
31623
|
}).passthrough();
|
|
31580
|
-
var DailyControlProductMirror =
|
|
31581
|
-
projectId:
|
|
31582
|
-
productName:
|
|
31624
|
+
var DailyControlProductMirror = z125.object({
|
|
31625
|
+
projectId: z125.string().uuid(),
|
|
31626
|
+
productName: z125.string().nullable(),
|
|
31583
31627
|
status: DailyControlStatusMirror,
|
|
31584
|
-
statusMessage:
|
|
31585
|
-
days:
|
|
31628
|
+
statusMessage: z125.string().nullable(),
|
|
31629
|
+
days: z125.array(DailyControlDayMirror),
|
|
31586
31630
|
verdict: DailyControlVerdictMirror.nullable(),
|
|
31587
|
-
rationale:
|
|
31631
|
+
rationale: z125.string().nullable()
|
|
31588
31632
|
}).passthrough();
|
|
31589
|
-
var DailyControlResponseMirror =
|
|
31590
|
-
since:
|
|
31591
|
-
until:
|
|
31592
|
-
products:
|
|
31593
|
-
archivedProjectSpend:
|
|
31633
|
+
var DailyControlResponseMirror = z125.object({
|
|
31634
|
+
since: z125.string(),
|
|
31635
|
+
until: z125.string(),
|
|
31636
|
+
products: z125.array(DailyControlProductMirror),
|
|
31637
|
+
archivedProjectSpend: z125.array(z125.unknown())
|
|
31594
31638
|
}).passthrough();
|
|
31595
31639
|
var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
|
|
31596
31640
|
function withWarnings(response) {
|
|
@@ -31665,7 +31709,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
|
|
|
31665
31709
|
// src/tools/product-control.ts
|
|
31666
31710
|
import { readFile, stat } from "fs/promises";
|
|
31667
31711
|
import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
|
|
31668
|
-
import { z as
|
|
31712
|
+
import { z as z126 } from "zod";
|
|
31669
31713
|
var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
|
|
31670
31714
|
var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
|
|
31671
31715
|
var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
|
|
@@ -31678,36 +31722,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
|
|
|
31678
31722
|
var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
|
|
31679
31723
|
var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
|
|
31680
31724
|
var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
|
|
31681
|
-
var DateOnly2 =
|
|
31725
|
+
var DateOnly2 = z126.string().regex(/^\d{4}-\d{2}-\d{2}$/);
|
|
31682
31726
|
var IMPORT_BATCH_MAX2 = 50;
|
|
31683
|
-
var ProductControlListInput =
|
|
31684
|
-
days:
|
|
31727
|
+
var ProductControlListInput = z126.object({
|
|
31728
|
+
days: z126.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
|
|
31685
31729
|
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."),
|
|
31686
|
-
shopDomain:
|
|
31730
|
+
shopDomain: z126.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
|
|
31687
31731
|
}).strict();
|
|
31688
|
-
var ImportableProductsInput =
|
|
31689
|
-
q:
|
|
31690
|
-
after:
|
|
31691
|
-
shopDomain:
|
|
31732
|
+
var ImportableProductsInput = z126.object({
|
|
31733
|
+
q: z126.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
|
|
31734
|
+
after: z126.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
|
|
31735
|
+
shopDomain: z126.string().min(1).optional()
|
|
31692
31736
|
}).strict();
|
|
31693
|
-
var ImportProductControlsInput =
|
|
31694
|
-
shopifyProductIds:
|
|
31737
|
+
var ImportProductControlsInput = z126.object({
|
|
31738
|
+
shopifyProductIds: z126.array(z126.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."),
|
|
31695
31739
|
// Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
|
|
31696
31740
|
// sin decir a cuál archivaría el producto bajo la tienda equivocada.
|
|
31697
|
-
shopDomain:
|
|
31741
|
+
shopDomain: z126.string().min(1)
|
|
31698
31742
|
}).strict();
|
|
31699
|
-
var SetProductCostingInput =
|
|
31700
|
-
shopDomain:
|
|
31701
|
-
shopifyProductId:
|
|
31702
|
-
targetCountry:
|
|
31703
|
-
supplierCost:
|
|
31704
|
-
shippingCost:
|
|
31705
|
-
returnRate:
|
|
31706
|
-
cancellationRate:
|
|
31743
|
+
var SetProductCostingInput = z126.object({
|
|
31744
|
+
shopDomain: z126.string().min(1),
|
|
31745
|
+
shopifyProductId: z126.string().min(1).max(64),
|
|
31746
|
+
targetCountry: z126.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
|
|
31747
|
+
supplierCost: z126.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
|
|
31748
|
+
shippingCost: z126.number().finite().nonnegative(),
|
|
31749
|
+
returnRate: z126.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
|
|
31750
|
+
cancellationRate: z126.number().finite().min(0).lt(1)
|
|
31707
31751
|
}).strict();
|
|
31708
|
-
var Count =
|
|
31709
|
-
var ReportProductCountsInput =
|
|
31710
|
-
productControlId:
|
|
31752
|
+
var Count = z126.number().int().min(0).max(1e5).nullable().optional();
|
|
31753
|
+
var ReportProductCountsInput = z126.object({
|
|
31754
|
+
productControlId: z126.string().uuid().describe("El identificador que devuelve get_product_control."),
|
|
31711
31755
|
date: DateOnly2,
|
|
31712
31756
|
orders: Count.describe("Pedidos que entraron ese d\xEDa."),
|
|
31713
31757
|
cancelledOrders: Count,
|
|
@@ -31717,36 +31761,36 @@ var ReportProductCountsInput = z125.object({
|
|
|
31717
31761
|
}).strict();
|
|
31718
31762
|
var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
|
|
31719
31763
|
var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
|
|
31720
|
-
var ImportOrdersFileInput =
|
|
31764
|
+
var ImportOrdersFileInput = z126.object({
|
|
31721
31765
|
/** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
|
|
31722
|
-
path:
|
|
31723
|
-
operationId:
|
|
31766
|
+
path: z126.string().min(1),
|
|
31767
|
+
operationId: z126.string().uuid().optional(),
|
|
31724
31768
|
/** Solo mirar: devuelve el resumen y no escribe nada. */
|
|
31725
|
-
dryRun:
|
|
31769
|
+
dryRun: z126.boolean().optional()
|
|
31726
31770
|
}).strict();
|
|
31727
|
-
var CreateOperationInput =
|
|
31728
|
-
countryCode:
|
|
31729
|
-
label:
|
|
31771
|
+
var CreateOperationInput = z126.object({
|
|
31772
|
+
countryCode: z126.string().length(2),
|
|
31773
|
+
label: z126.string().trim().min(1).max(60).optional()
|
|
31730
31774
|
}).strict();
|
|
31731
|
-
var MergeProductsInput =
|
|
31732
|
-
sourceId:
|
|
31733
|
-
targetId:
|
|
31775
|
+
var MergeProductsInput = z126.object({
|
|
31776
|
+
sourceId: z126.string().uuid(),
|
|
31777
|
+
targetId: z126.string().uuid()
|
|
31734
31778
|
}).strict();
|
|
31735
|
-
var SetMonthlyExpenseInput =
|
|
31736
|
-
month:
|
|
31779
|
+
var SetMonthlyExpenseInput = z126.object({
|
|
31780
|
+
month: z126.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
31737
31781
|
label: SaveMonthlyExpenseSchema.shape.label,
|
|
31738
|
-
amount:
|
|
31739
|
-
operationId:
|
|
31782
|
+
amount: z126.number().finite().min(0),
|
|
31783
|
+
operationId: z126.string().uuid().optional()
|
|
31740
31784
|
}).strict();
|
|
31741
|
-
var SetAdSpendInput =
|
|
31742
|
-
month:
|
|
31743
|
-
operationId:
|
|
31785
|
+
var SetAdSpendInput = z126.object({
|
|
31786
|
+
month: z126.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
|
|
31787
|
+
operationId: z126.string().uuid().optional(),
|
|
31744
31788
|
/** null RETIRA la corrección; cero afirma que no pautó. */
|
|
31745
|
-
amount:
|
|
31789
|
+
amount: z126.number().finite().min(0).nullable()
|
|
31746
31790
|
}).strict();
|
|
31747
|
-
var GetFinancesInput =
|
|
31748
|
-
month:
|
|
31749
|
-
operationId:
|
|
31791
|
+
var GetFinancesInput = z126.object({
|
|
31792
|
+
month: z126.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."),
|
|
31793
|
+
operationId: z126.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
|
|
31750
31794
|
}).strict();
|
|
31751
31795
|
function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
31752
31796
|
server.registerTool("get_product_control", {
|
|
@@ -31936,28 +31980,28 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
|
|
|
31936
31980
|
__name(registerProductControlTools, "registerProductControlTools");
|
|
31937
31981
|
|
|
31938
31982
|
// src/tools/market-study-estimate.ts
|
|
31939
|
-
import { z as
|
|
31983
|
+
import { z as z127 } from "zod";
|
|
31940
31984
|
var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
|
|
31941
|
-
var ProductTaskOutputEnum =
|
|
31985
|
+
var ProductTaskOutputEnum = z127.enum([
|
|
31942
31986
|
"landing",
|
|
31943
31987
|
"video",
|
|
31944
31988
|
"image"
|
|
31945
31989
|
]);
|
|
31946
|
-
var EstimateMarketStudyInput =
|
|
31947
|
-
kind:
|
|
31990
|
+
var EstimateMarketStudyInput = z127.object({
|
|
31991
|
+
kind: z127.enum([
|
|
31948
31992
|
"video",
|
|
31949
31993
|
"product_task"
|
|
31950
31994
|
]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
|
|
31951
|
-
videoAngleCount:
|
|
31952
|
-
durationSeconds:
|
|
31995
|
+
videoAngleCount: z127.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
|
|
31996
|
+
durationSeconds: z127.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
|
|
31953
31997
|
videoStructure: VideoStructureEnum.default("single_take"),
|
|
31954
31998
|
videoQuality: VideoQualityEnum.default("economy"),
|
|
31955
31999
|
videoResolution: VideoResolutionEnum.default("480p"),
|
|
31956
|
-
productImageCount:
|
|
32000
|
+
productImageCount: z127.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
|
|
31957
32001
|
outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
|
|
31958
|
-
generateAiMusic:
|
|
32002
|
+
generateAiMusic: z127.boolean().optional(),
|
|
31959
32003
|
generateAiEdit: AiEditRequestSchema.optional(),
|
|
31960
|
-
replicateWinnerWhenFound:
|
|
32004
|
+
replicateWinnerWhenFound: z127.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.")
|
|
31961
32005
|
}).strict();
|
|
31962
32006
|
function buildMarketStudyEstimateRequests(input) {
|
|
31963
32007
|
const quotesVideo = input.kind === "video" || (input.outputs ?? [
|