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